@rulemetric/cli 0.7.4 → 0.7.6

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 (163) hide show
  1. package/README.md +10 -8
  2. package/dist/base-command.js +1 -1
  3. package/dist/{chunk-O7ZMHCMG.js → chunk-2JRDG4LJ.js} +14 -14
  4. package/dist/{chunk-HOHD5HY2.js → chunk-2XGMDWFF.js} +1 -1
  5. package/dist/{chunk-F2VP4B4J.js → chunk-32EEBARV.js} +1 -1
  6. package/dist/chunk-4L5CU7LH.js +1 -0
  7. package/dist/chunk-CPMKMB7S.js +1 -0
  8. package/dist/{chunk-VAFAH6QL.js → chunk-DCLWFGEA.js} +1 -1
  9. package/dist/{chunk-IY5NXR3N.js → chunk-DPFNJZUO.js} +1 -1
  10. package/dist/{chunk-7XQ4VPLC.js → chunk-EXJLLRZW.js} +1 -1
  11. package/dist/chunk-FLMBC5E4.js +1 -0
  12. package/dist/{chunk-T3W5N3BP.js → chunk-G6XGDHGC.js} +1 -1
  13. package/dist/chunk-GQJKQH3K.js +2 -0
  14. package/dist/{chunk-TIQ7DQ3M.js → chunk-H2ORWIEY.js} +1 -1
  15. package/dist/chunk-HS7X43XE.js +24 -0
  16. package/dist/{chunk-Y65CSJFF.js → chunk-JAPCCEKF.js} +1 -1
  17. package/dist/{chunk-V5QFOF4F.js → chunk-KAF3CYRW.js} +1 -1
  18. package/dist/{chunk-EUHNCVJQ.js → chunk-KV325CXF.js} +3 -3
  19. package/dist/{chunk-FHVBTDBM.js → chunk-N7TGRFVZ.js} +13 -12
  20. package/dist/{chunk-I4YJ7NTX.js → chunk-NEACEHQD.js} +1 -1
  21. package/dist/chunk-O2SDD2WW.js +1 -0
  22. package/dist/chunk-O6C2UGBY.js +7 -0
  23. package/dist/chunk-PPKPCXJD.js +4 -0
  24. package/dist/{chunk-VWEXKDWG.js → chunk-QFVGUZDO.js} +1 -1
  25. package/dist/{chunk-VMWY7KHH.js → chunk-RDET7CKR.js} +1 -1
  26. package/dist/chunk-RQ424GI6.js +5 -0
  27. package/dist/chunk-SYQWEAJR.js +1 -0
  28. package/dist/{chunk-PZS2KOU7.js → chunk-TIOKY2IA.js} +1 -1
  29. package/dist/chunk-TQMG647B.js +15 -0
  30. package/dist/{chunk-WJUQBMTF.js → chunk-U6ABMRT3.js} +1 -1
  31. package/dist/chunk-U6XEU573.js +1 -0
  32. package/dist/{chunk-CRAKDQ4H.js → chunk-V44SRRYR.js} +1 -1
  33. package/dist/{chunk-WPJ2BND4.js → chunk-VLOX6KOM.js} +1 -1
  34. package/dist/chunk-W2MOTOQE.js +1 -0
  35. package/dist/chunk-XICLXXRH.js +1 -0
  36. package/dist/{chunk-2UC3ULIG.js → chunk-XXDZJ6YI.js} +1 -1
  37. package/dist/{chunk-SBILN45P.js → chunk-ZR3MUNLS.js} +1 -1
  38. package/dist/commands/antigravity/backfill.js +1 -1
  39. package/dist/commands/auth/create-key.js +1 -1
  40. package/dist/commands/auth/login.js +1 -1
  41. package/dist/commands/auth/logout.js +1 -1
  42. package/dist/commands/auth/revoke-key.js +4 -1
  43. package/dist/commands/auth/signup.js +1 -1
  44. package/dist/commands/auth/status.js +1 -1
  45. package/dist/commands/catalog/index.js +1 -1
  46. package/dist/commands/catalog/recommend.js +1 -1
  47. package/dist/commands/convert.js +1 -1
  48. package/dist/commands/converters.js +1 -1
  49. package/dist/commands/crons/list.js +1 -1
  50. package/dist/commands/crons/run.js +1 -1
  51. package/dist/commands/dashboard.js +1 -1
  52. package/dist/commands/diagnostics.js +1 -1
  53. package/dist/commands/eval-targets/create.js +1 -1
  54. package/dist/commands/eval-targets/list.js +1 -1
  55. package/dist/commands/evals/agent.js +1 -1
  56. package/dist/commands/evals/benchmark.js +6 -6
  57. package/dist/commands/evals/compare.js +1 -1
  58. package/dist/commands/evals/create.js +1 -1
  59. package/dist/commands/evals/optimize-description.js +15 -15
  60. package/dist/commands/evals/optimize.js +5 -5
  61. package/dist/commands/evals/run.js +1 -1
  62. package/dist/commands/gateway/ensure.js +1 -1
  63. package/dist/commands/hooks/install.js +1 -1
  64. package/dist/commands/hooks/run.js +1 -1
  65. package/dist/commands/hooks/uninstall.js +1 -1
  66. package/dist/commands/import.js +1 -1
  67. package/dist/commands/instructions/create.js +1 -1
  68. package/dist/commands/instructions/delete.js +1 -1
  69. package/dist/commands/instructions/fork.js +1 -1
  70. package/dist/commands/instructions/get.js +1 -1
  71. package/dist/commands/instructions/list.js +1 -1
  72. package/dist/commands/instructions/promote.js +1 -1
  73. package/dist/commands/instructions/pull.js +1 -1
  74. package/dist/commands/instructions/upstream.js +1 -1
  75. package/dist/commands/instructions/versions.js +1 -1
  76. package/dist/commands/launcher.js +1 -1
  77. package/dist/commands/org/current.js +1 -1
  78. package/dist/commands/org/list.js +1 -1
  79. package/dist/commands/org/switch.js +1 -1
  80. package/dist/commands/packs/add-instruction.js +1 -1
  81. package/dist/commands/packs/apply.js +1 -1
  82. package/dist/commands/packs/create.js +1 -1
  83. package/dist/commands/packs/fork.js +1 -1
  84. package/dist/commands/packs/get.js +1 -1
  85. package/dist/commands/packs/list.js +1 -1
  86. package/dist/commands/packs/remove-instruction.js +1 -1
  87. package/dist/commands/proxy/env.js +1 -1
  88. package/dist/commands/proxy/logs.js +1 -1
  89. package/dist/commands/proxy/restart.js +1 -1
  90. package/dist/commands/proxy/setup.js +13 -11
  91. package/dist/commands/proxy/start.js +1 -1
  92. package/dist/commands/proxy/status.js +1 -1
  93. package/dist/commands/proxy/stop.js +1 -1
  94. package/dist/commands/research/backfill.js +1 -1
  95. package/dist/commands/research/tail-transcript.js +1 -1
  96. package/dist/commands/service/install.js +5 -5
  97. package/dist/commands/service/status.js +1 -1
  98. package/dist/commands/service/uninstall.js +1 -1
  99. package/dist/commands/sessions/analyze.js +1 -3
  100. package/dist/commands/sessions/end.js +2 -2
  101. package/dist/commands/sessions/import.js +1 -1
  102. package/dist/commands/sessions/list.js +1 -1
  103. package/dist/commands/sessions/start.js +1 -1
  104. package/dist/commands/setup.js +1 -1
  105. package/dist/commands/skills/export-approved.js +1 -1
  106. package/dist/commands/skills/install.js +1 -1
  107. package/dist/commands/skills/list.js +1 -1
  108. package/dist/commands/skills/publish.js +1 -1
  109. package/dist/commands/skills/search.js +1 -1
  110. package/dist/commands/skills/update.js +1 -1
  111. package/dist/commands/suggestions/accept.js +3 -3
  112. package/dist/commands/suggestions/dismiss.js +1 -1
  113. package/dist/commands/suggestions/list.js +2 -1
  114. package/dist/commands/suggestions/refresh.js +1 -1
  115. package/dist/dashboard/Dashboard.js +1 -1
  116. package/dist/dashboard/data.js +1 -1
  117. package/dist/dashboard/launcher/LauncherOverlay.js +1 -1
  118. package/dist/dashboard/launcher/api.js +1 -1
  119. package/dist/dashboard/launcher/useLaunchJobs.js +1 -1
  120. package/dist/dashboard/panels/insights.js +1 -1
  121. package/dist/lib/active-org-refresh.js +1 -1
  122. package/dist/lib/agent-loop.js +1 -1
  123. package/dist/lib/antigravity-transcript.js +1 -1
  124. package/dist/lib/api-client.js +1 -1
  125. package/dist/lib/auth.js +1 -1
  126. package/dist/lib/editor-proxy-pins.js +1 -1
  127. package/dist/lib/ensure-api-key.js +1 -1
  128. package/dist/lib/ensure-fresh-token.js +1 -0
  129. package/dist/lib/eval-benchmark.js +1 -1
  130. package/dist/lib/eval-conversation-handler.js +1 -1
  131. package/dist/lib/eval-trigger-tester.js +1 -1
  132. package/dist/lib/handlers/cron-refresh-pricing.js +1 -1
  133. package/dist/lib/handlers/cron-suggest-instructions.js +1 -1
  134. package/dist/lib/handlers/process-announcement.js +1 -1
  135. package/dist/lib/handlers/process-changelog.js +1 -1
  136. package/dist/lib/handlers/process-conversation.js +1 -1
  137. package/dist/lib/handlers/process-eval.js +1 -1
  138. package/dist/lib/handlers/process-insights.js +1 -1
  139. package/dist/lib/handlers/process-launch.js +1 -1
  140. package/dist/lib/handlers/process-run-cleanup.js +1 -1
  141. package/dist/lib/handlers/process-session-goal.js +1 -1
  142. package/dist/lib/hooks-config.js +1 -1
  143. package/dist/lib/insights-prompts.js +1 -1
  144. package/dist/lib/manual-tasks.js +1 -1
  145. package/dist/lib/research-client.js +1 -1
  146. package/dist/lib/setup-steps.js +1 -1
  147. package/dist/lib/telemetry.js +1 -1
  148. package/dist/lib/terminal-target-heartbeat.js +1 -1
  149. package/oclif.manifest.json +145 -167
  150. package/package.json +7 -6
  151. package/dist/chunk-72XLQE3X.js +0 -2
  152. package/dist/chunk-AHRHCERJ.js +0 -1
  153. package/dist/chunk-DT4GKEP5.js +0 -5
  154. package/dist/chunk-E4SFUPYR.js +0 -15
  155. package/dist/chunk-FEHM5OKW.js +0 -1
  156. package/dist/chunk-HP2BUPGS.js +0 -24
  157. package/dist/chunk-LQRYQE6Q.js +0 -4
  158. package/dist/chunk-M6AJDVCL.js +0 -5
  159. package/dist/chunk-ML36XQW7.js +0 -1
  160. package/dist/chunk-NVOTOQBA.js +0 -1
  161. package/dist/chunk-RTEATXTP.js +0 -1
  162. package/dist/chunk-RVO4HV3M.js +0 -1
  163. package/dist/chunk-WJ3H73G6.js +0 -1
@@ -1,4 +1,4 @@
1
- import{a as i}from"../../chunk-MGHFDHHM.js";import{a as u}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{d as a}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.js";import{a as p}from"../../chunk-ZLLER3HP.js";import{Args as c,Flags as v}from"@oclif/core";var m=class d extends u{static{p(this,"EvalCompareCommand")}static description="Blind A/B comparison between two eval target versions";static examples=["<%= config.bin %> evals compare <target-a> <target-b>"];static args={targetA:c.string({description:"First eval target ID",required:!0}),targetB:c.string({description:"Second eval target ID",required:!0})};static flags={model:v.string({description:"Model for execution and comparison"}),timeout:v.integer({description:"Timeout per eval in ms",default:12e4})};async run(){let{args:s,flags:e}=await this.parse(d);this.requireAuth();let[o,n]=await Promise.all([a(`/api/eval-targets/${s.targetA}`),a(`/api/eval-targets/${s.targetB}`)]),l=await a(`/api/eval-targets/${s.targetA}/evals`);l.length===0&&this.error("No evals found for target A. Create some first."),this.log(`Comparing "${o.name}" v${o.version} vs "${n.name}" v${n.version}`),this.log(`Running ${l.length} eval(s)...
1
+ import{a as i}from"../../chunk-MGHFDHHM.js";import{a as u}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{e as a}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as p}from"../../chunk-ZLLER3HP.js";import{Args as c,Flags as v}from"@oclif/core";var m=class d extends u{static{p(this,"EvalCompareCommand")}static description="Blind A/B comparison between two eval target versions";static examples=["<%= config.bin %> evals compare <target-a> <target-b>"];static args={targetA:c.string({description:"First eval target ID",required:!0}),targetB:c.string({description:"Second eval target ID",required:!0})};static flags={model:v.string({description:"Model for execution and comparison"}),timeout:v.integer({description:"Timeout per eval in ms",default:12e4})};async run(){let{args:s,flags:e}=await this.parse(d);this.requireAuth();let[o,n]=await Promise.all([a(`/api/eval-targets/${s.targetA}`),a(`/api/eval-targets/${s.targetB}`)]),l=await a(`/api/eval-targets/${s.targetA}/evals`);l.length===0&&this.error("No evals found for target A. Create some first."),this.log(`Comparing "${o.name}" v${o.version} vs "${n.name}" v${n.version}`),this.log(`Running ${l.length} eval(s)...
2
2
  `);let r=Math.random()>.5,h=r?n.content:o.content,f=r?o.content:n.content,A=r?n.name:o.name,w=r?o.name:n.name,g=[];for(let t of l){this.log(`[${t.name}] Running A...`);let b=await i({prompt:t.prompt,targetContent:h,timeout:e.timeout,model:e.model});this.log(`[${t.name}] Running B...`);let E=await i({prompt:t.prompt,targetContent:f,timeout:e.timeout,model:e.model});g.push({evalName:t.name,outputA:b.output,outputB:E.output})}this.log(`
3
3
  Running blind comparison...`);let B=g.map(t=>`
4
4
  ## Eval: ${t.evalName}
@@ -1 +1 @@
1
- import{a as m}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{e as i}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.js";import{a as l}from"../../chunk-ZLLER3HP.js";import{Args as g,Flags as r}from"@oclif/core";import{readFileSync as u}from"node:fs";var s=class d extends m{static{l(this,"EvalCreate")}static description="Create test cases (evals) for an eval target";static examples=['<%= config.bin %> evals create <target-id> --name "ts-check" --prompt "Write a function to add two numbers"',"<%= config.bin %> evals create <target-id> --from-file evals.json"];static args={targetId:g.string({description:"Eval target ID",required:!0})};static flags={name:r.string({char:"n",description:"Eval name"}),prompt:r.string({char:"p",description:"Test prompt"}),"expected-output":r.string({description:"Expected output description"}),expectations:r.string({char:"e",description:"Assertion (repeatable)",multiple:!0}),"from-file":r.string({description:"Bulk create from JSON file"})};async run(){let{args:o,flags:e}=await this.parse(d);if(this.requireAuth(),e["from-file"]){let a=JSON.parse(u(e["from-file"],"utf-8")),p=Array.isArray(a)?a:a.evals;for(let t of p){let c=await i(`/api/eval-targets/${o.targetId}/evals`,{name:t.name,prompt:t.prompt,expectedOutput:t.expectedOutput??"",expectations:t.expectations??[],files:t.files??[]});this.log(`Created eval: ${c.name} (${c.id})`)}this.log(`Created ${p.length} evals.`);return}(!e.name||!e.prompt)&&this.error("Provide --name and --prompt, or use --from-file for bulk creation");let n=await i(`/api/eval-targets/${o.targetId}/evals`,{name:e.name,prompt:e.prompt,expectedOutput:e["expected-output"]??"",expectations:e.expectations??[]});this.log(`Created eval: ${n.name} (${n.id})`)}};export{s as default};
1
+ import{a as c}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{f as i}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as m}from"../../chunk-ZLLER3HP.js";import{Args as f,Flags as r}from"@oclif/core";import{readFileSync as g}from"node:fs";var s=class d extends c{static{m(this,"EvalCreate")}static description="Create test cases (evals) for an eval target";static examples=['<%= config.bin %> evals create <target-id> --name "ts-check" --prompt "Write a function to add two numbers"',"<%= config.bin %> evals create <target-id> --from-file evals.json"];static args={targetId:f.string({description:"Eval target ID",required:!0})};static flags={name:r.string({char:"n",description:"Eval name"}),prompt:r.string({char:"p",description:"Test prompt"}),expectations:r.string({char:"e",description:"Assertion (repeatable)",multiple:!0}),"from-file":r.string({description:"Bulk create from JSON file"})};async run(){let{args:n,flags:e}=await this.parse(d);if(this.requireAuth(),e["from-file"]){let a=JSON.parse(g(e["from-file"],"utf-8")),p=Array.isArray(a)?a:a.evals;for(let t of p){let l=await i(`/api/eval-targets/${n.targetId}/evals`,{name:t.name,prompt:t.prompt,expectations:t.expectations??[],files:t.files??[]});this.log(`Created eval: ${l.name} (${l.id})`)}this.log(`Created ${p.length} evals.`);return}(!e.name||!e.prompt)&&this.error("Provide --name and --prompt, or use --from-file for bulk creation");let o=await i(`/api/eval-targets/${n.targetId}/evals`,{name:e.name,prompt:e.prompt,expectations:e.expectations??[]});this.log(`Created eval: ${o.name} (${o.id})`)}};export{s as default};
@@ -1,16 +1,16 @@
1
- import{a as O,b as S}from"../../chunk-EUHNCVJQ.js";import{a as w}from"../../chunk-MGHFDHHM.js";import{a as N}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{d as y,e as $,f as b}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.js";import{a as D}from"../../chunk-ZLLER3HP.js";import{Args as C,Flags as T}from"@oclif/core";var x=class k extends N{static{D(this,"EvalOptimizeDescriptionCommand")}static description="Optimize eval target description for better triggering accuracy";static examples=["<%= config.bin %> evals optimize-description <target-id>","<%= config.bin %> evals optimize-description <target-id> --queries 10"];static args={targetId:C.string({description:"Eval target ID",required:!0})};static flags={"max-iterations":T.integer({description:"Maximum optimization iterations",default:5}),model:T.string({description:"Model for trigger testing and improvement"}),queries:T.integer({description:"Number of trigger queries to generate",default:20}),"runs-per-query":T.integer({description:"Runs per query for reliability",default:3}),"poll-interval":T.integer({description:"Ms between approval polls",default:5e3}),timeout:T.integer({description:"Timeout per eval in ms",default:12e4})};async run(){let{args:i,flags:t}=await this.parse(k);this.requireAuth();let e=await y(`/api/eval-targets/${i.targetId}`);this.log(`Optimizing description for "${e.name}" v${e.version}`),this.log(`Current description: "${e.description}"`),this.log(""),this.log("Generating trigger queries...");let r=await this.generateTriggerQueries(e,t.queries,t),n=await $(`/api/eval-targets/${i.targetId}/trigger-evals`,{queries:r});this.log(`
2
- Generated ${r.length} trigger queries.`),this.log("Review and approve them at:"),this.log(` http://localhost:5174/eval-targets/${i.targetId}`),this.log(" (Triggers tab \u2192 click to review)"),this.log(`
3
- Waiting for approval...`);let a=!1;for(;!a;){await new Promise(h=>setTimeout(h,t["poll-interval"]));let d=(await y(`/api/eval-targets/${i.targetId}/trigger-evals?status=approved`)).find(h=>h.id===n.id);d&&(a=!0,r.length=0,r.push(...d.queries),this.log("Trigger queries approved!"))}let g=r.map((u,d)=>d).sort(()=>Math.random()-.5),p=Math.ceil(g.length*.6),s=g.slice(0,p),o=g.slice(p);await b(`/api/trigger-evals/${n.id}`,{trainIndices:s,testIndices:o});let c=s.map(u=>r[u]),I=o.map(u=>r[u]);this.log(`
4
- Split: ${c.length} train, ${I.length} test`);let m=e.description,v=m,q=0;for(let u=1;u<=t["max-iterations"];u++){this.log(`
5
- === Iteration ${u} ===`),this.log(`Description: "${m}"`),this.log("Testing train set...");let d=await this.testQuerySet(c,e,m,t),h=S(d);this.log(`Train accuracy: ${(h*100).toFixed(1)}%`),this.printTriggerResults(d),this.log("Testing test set...");let R=await this.testQuerySet(I,e,m,t),f=S(R);if(this.log(`Test accuracy: ${(f*100).toFixed(1)}%`),await $("/api/optimization-runs",{evalTargetId:e.id,type:"description",iteration:u,inputVersion:e.version,trainScore:h,testScore:f,analysis:{description:m,trainResults:d.map(l=>({query:l.query,shouldTrigger:l.shouldTrigger,didTrigger:l.didTrigger,correct:l.correct})),testResults:R.map(l=>({query:l.query,shouldTrigger:l.shouldTrigger,didTrigger:l.didTrigger,correct:l.correct}))},status:"completed"}),f>q&&(q=f,v=m),h>=1){this.log("Perfect train score. Stopping.");break}this.log("Generating improved description...");let Q=d.filter(l=>!l.correct);m=await this.improveDescription(e,m,Q,t)}this.log(`
6
- === Optimization Complete ===`),this.log(`Best test accuracy: ${(q*100).toFixed(1)}%`),this.log(`
7
- Before: "${e.description}"`),this.log(`After: "${v}"`),v!==e.description?(await b(`/api/eval-targets/${e.id}`,{description:v}),this.log(`
1
+ import{a as S,b as P,c as R}from"../../chunk-KV325CXF.js";import{a as b}from"../../chunk-MGHFDHHM.js";import{a as O}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{e as y,f as q,g as w}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as N}from"../../chunk-ZLLER3HP.js";import{Args as C,Flags as T}from"@oclif/core";var A=process.env.RULEMETRIC_WEB_URL??"https://rulemetric.com",k=30*6e4,I=class M extends O{static{N(this,"EvalOptimizeDescriptionCommand")}static description="Optimize eval target description for better triggering accuracy";static examples=["<%= config.bin %> evals optimize-description <target-id>","<%= config.bin %> evals optimize-description <target-id> --queries 10"];static args={targetId:C.string({description:"Eval target ID",required:!0})};static flags={"max-iterations":T.integer({description:"Maximum optimization iterations",default:5}),model:T.string({description:"Model for trigger testing and improvement"}),queries:T.integer({description:"Number of trigger queries to generate",default:20}),"runs-per-query":T.integer({description:"Runs per query for reliability",default:3}),"poll-interval":T.integer({description:"Ms between approval polls",default:5e3}),timeout:T.integer({description:"Timeout per eval in ms",default:12e4})};async run(){let{args:i,flags:t}=await this.parse(M);this.requireAuth();let e=await y(`/api/eval-targets/${i.targetId}`);this.log(`Optimizing description for "${e.name}" v${e.version}`),this.log(`Current description: "${e.description}"`),this.log(S),this.log(""),this.log("Generating trigger queries...");let r=await this.generateTriggerQueries(e,t.queries,t),a=await q(`/api/eval-targets/${i.targetId}/trigger-evals`,{queries:r}),g=`${A}/eval-targets/${i.targetId}`;this.log(`
2
+ Generated ${r.length} trigger queries.`),this.log("Review and approve them at:"),this.log(` ${g}`),this.log(" (Triggers tab \u2192 click to review)"),this.log(`
3
+ Waiting for approval...`);let u=Date.now(),d=!1;for(;!d;){Date.now()-u>k&&this.error(`Timed out after ${k/6e4} minutes waiting for approval. Approve the trigger set at ${g} (Triggers tab) and re-run this command.`),await new Promise(h=>setTimeout(h,t["poll-interval"]));let p=(await y(`/api/eval-targets/${i.targetId}/trigger-evals?status=approved`)).find(h=>h.id===a.id);p&&(d=!0,r.length=0,r.push(...p.queries),this.log("Trigger queries approved!"))}let n=r.map((c,p)=>p).sort(()=>Math.random()-.5),o=Math.ceil(n.length*.6),s=n.slice(0,o),x=n.slice(o);await w(`/api/trigger-evals/${a.id}`,{trainIndices:s,testIndices:x});let D=s.map(c=>r[c]),_=x.map(c=>r[c]);this.log(`
4
+ Split: ${D.length} train, ${_.length} test`);let m=e.description,v=m,$=0;for(let c=1;c<=t["max-iterations"];c++){this.log(`
5
+ === Iteration ${c} ===`),this.log(`Description: "${m}"`),this.log("Testing train set...");let p=await this.testQuerySet(D,e,m,t),h=R(p);this.log(`Train accuracy: ${(h*100).toFixed(1)}%`),this.printTriggerResults(p),this.log("Testing test set...");let E=await this.testQuerySet(_,e,m,t),f=R(E);if(this.log(`Test accuracy: ${(f*100).toFixed(1)}%`),await q("/api/optimization-runs",{evalTargetId:e.id,type:"description",iteration:c,inputVersion:e.version,trainScore:h,testScore:f,analysis:{description:m,trainResults:p.map(l=>({query:l.query,shouldTrigger:l.shouldTrigger,didTrigger:l.didTrigger,correct:l.correct})),testResults:E.map(l=>({query:l.query,shouldTrigger:l.shouldTrigger,didTrigger:l.didTrigger,correct:l.correct}))},status:"completed"}),f>$&&($=f,v=m),h>=1){this.log("Perfect train score. Stopping.");break}this.log("Generating improved description...");let Q=p.filter(l=>!l.correct);m=await this.improveDescription(e,m,Q,t)}this.log(`
6
+ === Optimization Complete ===`),this.log(`Best test accuracy: ${($*100).toFixed(1)}%`),this.log(S),this.log(`
7
+ Before: "${e.description}"`),this.log(`After: "${v}"`),v!==e.description?(await w(`/api/eval-targets/${e.id}`,{description:v}),this.log(`
8
8
  Description updated.`)):this.log(`
9
- No improvement found. Description unchanged.`)}async generateTriggerQueries(i,t,e){let r="";try{let s=await y("/api/sessions?limit=10");s.length>0&&(r=`
9
+ No improvement found. Description unchanged.`)}async generateTriggerQueries(i,t,e){let r="";try{let o=(await y("/api/sessions?limit=10")).map(s=>s.firstUserPrompt??s.lastMessagePreview??"").filter(s=>s.trim().length>0).slice(0,5);o.length>0&&(r=`
10
10
 
11
11
  Real user prompts from recent sessions (use as inspiration for realistic queries):
12
- `+s.slice(0,5).map(o=>`- Session ${o.id}`).join(`
13
- `))}catch{}let n=Math.ceil(t/2),a=t-n,g=`Generate ${t} trigger eval queries for a skill/instruction.
12
+ `+o.map(s=>`- ${s}`).join(`
13
+ `))}catch{}let a=Math.ceil(t/2),g=t-a,u=`Generate ${t} trigger eval queries for a skill/instruction.
14
14
 
15
15
  ## Skill Name
16
16
  ${i.name}
@@ -22,7 +22,7 @@ ${i.description}
22
22
  ${i.content.slice(0,1e3)}
23
23
  ${r}
24
24
 
25
- Generate ${n} should-trigger queries and ${a} should-not-trigger queries.
25
+ Generate ${a} should-trigger queries and ${g} should-not-trigger queries.
26
26
 
27
27
  Rules:
28
28
  - Queries must be realistic \u2014 what a real user would actually type
@@ -35,8 +35,8 @@ Respond with ONLY a valid JSON array:
35
35
  [
36
36
  {"query": "realistic user prompt...", "should_trigger": true},
37
37
  {"query": "another prompt...", "should_trigger": false}
38
- ]`,p=await w({prompt:g,timeout:e.timeout,model:e.model});try{let s=p.output.trim(),o=s.match(/```(?:json)?\s*([\s\S]*?)```/);o&&(s=o[1].trim());let c=s.match(/\[[\s\S]*\]/);return c&&(s=c[0]),JSON.parse(s)}catch{return[{query:`Help me use ${i.name}`,should_trigger:!0},{query:"Write a hello world program",should_trigger:!1}]}}async testQuerySet(i,t,e,r){let n=[];for(let a of i){let g=[];for(let o=0;o<r["runs-per-query"];o++){let c=await O({query:a.query,shouldTrigger:a.should_trigger,skillName:t.name,skillDescription:e,skillContent:t.content,model:r.model,timeout:r.timeout});g.push(c)}let s=g.filter(o=>o.didTrigger).length>r["runs-per-query"]/2;n.push({query:a.query,shouldTrigger:a.should_trigger,didTrigger:s,correct:s===a.should_trigger,confidence:g.reduce((o,c)=>o+c.confidence,0)/g.length,evidence:g[0].evidence})}return n}printTriggerResults(i){for(let t of i){let e=t.correct?"OK":"FAIL",r=t.shouldTrigger?"should trigger":"should NOT trigger",n=t.didTrigger?"triggered":"did NOT trigger";this.log(` [${e}] ${r} / ${n}: "${t.query.slice(0,60)}..."`)}}async improveDescription(i,t,e,r){let n=e.map(p=>`- ${p.shouldTrigger?"SHOULD trigger but DID NOT":"SHOULD NOT trigger but DID"}: "${p.query}"`).join(`
39
- `),a=`You are optimizing a skill description for better triggering accuracy.
38
+ ]`,d=await b({prompt:u,timeout:e.timeout,model:e.model});try{let n=d.output.trim(),o=n.match(/```(?:json)?\s*([\s\S]*?)```/);o&&(n=o[1].trim());let s=n.match(/\[[\s\S]*\]/);return s&&(n=s[0]),JSON.parse(n)}catch{return[{query:`Help me use ${i.name}`,should_trigger:!0},{query:"Write a hello world program",should_trigger:!1}]}}async testQuerySet(i,t,e,r){let a=[];for(let g of i){let u=[];for(let o=0;o<r["runs-per-query"];o++){let s=await P({query:g.query,shouldTrigger:g.should_trigger,skillName:t.name,skillDescription:e,skillContent:t.content,model:r.model,timeout:r.timeout});u.push(s)}let n=u.filter(o=>o.didTrigger).length>r["runs-per-query"]/2;a.push({query:g.query,shouldTrigger:g.should_trigger,didTrigger:n,correct:n===g.should_trigger,confidence:u.reduce((o,s)=>o+s.confidence,0)/u.length,evidence:u[0].evidence})}return a}printTriggerResults(i){for(let t of i){let e=t.correct?"OK":"FAIL",r=t.shouldTrigger?"should trigger":"should NOT trigger",a=t.didTrigger?"triggered":"did NOT trigger";this.log(` [${e}] ${r} / ${a}: "${t.query.slice(0,60)}..."`)}}async improveDescription(i,t,e,r){let a=e.map(d=>`- ${d.shouldTrigger?"SHOULD trigger but DID NOT":"SHOULD NOT trigger but DID"}: "${d.query}"`).join(`
39
+ `),g=`You are optimizing a skill description for better triggering accuracy.
40
40
 
41
41
  ## Skill Name
42
42
  ${i.name}
@@ -48,7 +48,7 @@ ${t}
48
48
  ${i.content.slice(0,500)}
49
49
 
50
50
  ## Failures
51
- ${n}
51
+ ${a}
52
52
 
53
53
  Propose an improved description that:
54
54
  - Fixes the trigger failures above
@@ -56,4 +56,4 @@ Propose an improved description that:
56
56
  - Uses specific keywords and contexts for when to trigger
57
57
  - Includes "Use PROACTIVELY" phrasing for important trigger contexts
58
58
 
59
- Respond with ONLY the new description text (no JSON, no explanation, just the description string).`;return(await w({prompt:a,timeout:r.timeout,model:r.model})).output.trim().replace(/^["']|["']$/g,"")}};export{x as default};
59
+ Respond with ONLY the new description text (no JSON, no explanation, just the description string).`;return(await b({prompt:g,timeout:r.timeout,model:r.model})).output.trim().replace(/^["']|["']$/g,"")}};export{I as default};
@@ -1,5 +1,5 @@
1
- import{a as A}from"../../chunk-DSO2U4Y6.js";import{a as k}from"../../chunk-CADKBP3D.js";import{a as I}from"../../chunk-MGHFDHHM.js";import{a as z}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{d as y,e as c,f as T}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.js";import{a as R}from"../../chunk-ZLLER3HP.js";import{Args as P,Flags as o}from"@oclif/core";var w=class N extends z{static{R(this,"EvalOptimizeCommand")}static description="Iteratively optimize eval target content using eval results as feedback";static examples=["<%= config.bin %> evals optimize <target-id>","<%= config.bin %> evals optimize <target-id> --auto --max-iterations 3"];static args={targetId:P.string({description:"Eval target ID",required:!0})};static flags={auto:o.boolean({description:"Skip interactive review, apply suggestions automatically",default:!1}),"max-iterations":o.integer({description:"Maximum optimization iterations",default:5}),threshold:o.string({description:"Stop if pass rate reaches this threshold (0-1)",default:"0.95"}),model:o.string({description:"Model for eval execution"}),"analyzer-model":o.string({description:"Model for analysis/suggestions"}),"runs-per-eval":o.integer({description:"Runs per eval per iteration",default:1}),parallel:o.integer({description:"Number of parallel eval executions",default:1}),timeout:o.integer({description:"Timeout per eval in ms",default:12e4})};async run(){let{args:l,flags:s}=await this.parse(N);this.requireAuth();let t=await y(`/api/eval-targets/${l.targetId}`),i=await y(`/api/eval-targets/${l.targetId}/evals`);i.length===0&&this.error("No evals found. Create some first with `rulemetric evals create`.");let e=[...i].sort(()=>Math.random()-.5),u=Math.ceil(e.length*.6),m=e.slice(0,u),v=e.slice(u);this.log(`Optimizing "${t.name}" v${t.version}`),this.log(`Evals: ${m.length} train, ${v.length} test`);let h=parseFloat(s.threshold);this.log(`Config: max ${s["max-iterations"]} iterations, threshold ${(h*100).toFixed(0)}%`),s.auto&&this.log("Mode: auto (no interactive review)"),this.log("");let $=t.version,f=0,x=0;for(let n=1;n<=s["max-iterations"];n++){this.log(`
2
- === Iteration ${n} ===`);let C=await c("/api/optimization-runs",{evalTargetId:t.id,type:"content",iteration:n,inputVersion:t.version,status:"running"});this.log("Running train evals...");let b=await this.runEvalsOnTarget(t,m,s),p=this.computePassRate(b);if(this.log(`Train pass rate: ${(p*100).toFixed(1)}%`),p>=h){this.log(`Train score ${(p*100).toFixed(1)}% >= threshold ${(h*100).toFixed(0)}%. Stopping.`);let a=await this.runEvalsOnTarget(t,v,s),E=this.computePassRate(a);this.log(`Final test score: ${(E*100).toFixed(1)}%`),await c("/api/optimization-runs",{evalTargetId:t.id,type:"content",iteration:n,inputVersion:t.version,trainScore:p,testScore:E,analysis:{reason:"threshold_reached"},status:"completed"});break}this.log("Analyzing results...");let F=b.map(a=>({evalName:a.evalName,prompt:a.prompt,expectations:a.expectations,grading:a.grading})),r=await A({content:t.content,evalResults:F,model:s["analyzer-model"]??s.model,timeout:s.timeout});this.log(`
3
- Assessment: ${r.overallAssessment}`),this.log(`Suggestions: ${r.suggestions.length}`);for(let a of r.suggestions)this.log(` - [${a.section}] ${a.reasoning}`);if(s.auto||(this.log(`
4
- Proposed changes above. Applying in auto mode would proceed automatically.`),this.log("(Interactive approval not yet implemented \u2014 use --auto for now)")),r.proposedContent===t.content){this.log("No changes proposed. Stopping."),await c("/api/optimization-runs",{evalTargetId:t.id,type:"content",iteration:n,inputVersion:t.version,trainScore:p,analysis:{reason:"no_changes"},status:"completed"});break}let g=await T(`/api/eval-targets/${t.id}`,{content:r.proposedContent});this.log(`Created v${g.version}`),this.log("Running test evals...");let S=await this.runEvalsOnTarget(g,v,s),d=this.computePassRate(S);if(this.log(`Test pass rate: ${(d*100).toFixed(1)}%`),await c("/api/optimization-runs",{evalTargetId:g.id,type:"content",iteration:n,inputVersion:t.version,outputVersion:g.version,trainScore:p,testScore:d,analysis:{suggestions:r.suggestions,overallAssessment:r.overallAssessment},status:"completed"}),d>f)f=d,$=g.version,x=0;else if(x++,x>=2){this.log("No improvement for 2 consecutive iterations. Stopping.");break}t=g}this.log(`
5
- === Optimization Complete ===`),this.log(`Best version: v${$} (test score: ${(f*100).toFixed(1)}%)`)}async runEvalsOnTarget(l,s,t){let i=[];for(let e of s){let u=await I({prompt:e.prompt,targetContent:l.content,timeout:t.timeout,model:t.model});if(u.error){i.push({evalName:e.name,prompt:e.prompt,expectations:e.expectations,grading:{}});continue}if(e.expectations.length>0){let m=await k({prompt:e.prompt,output:u.output,expectations:e.expectations,model:t.model,timeout:t.timeout});i.push({evalName:e.name,prompt:e.prompt,expectations:e.expectations,grading:m})}else i.push({evalName:e.name,prompt:e.prompt,expectations:e.expectations,grading:{}})}return i}computePassRate(l){let s=l.filter(i=>Object.keys(i.grading).length>0);if(s.length===0)return 0;let t=s.map(i=>i.grading.summary?.pass_rate??0);return t.reduce((i,e)=>i+e,0)/t.length}};export{w as default};
1
+ import{a as A}from"../../chunk-DSO2U4Y6.js";import{a as k}from"../../chunk-CADKBP3D.js";import{a as z}from"../../chunk-MGHFDHHM.js";import{a as I}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{e as y,f as m,g as R}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as b}from"../../chunk-ZLLER3HP.js";import{createInterface as C}from"node:readline/promises";import{Args as P,Flags as p}from"@oclif/core";var w=class N extends I{static{b(this,"EvalOptimizeCommand")}static description="Iteratively optimize eval target content using eval results as feedback";static examples=["<%= config.bin %> evals optimize <target-id>","<%= config.bin %> evals optimize <target-id> --auto --max-iterations 3"];static args={targetId:P.string({description:"Eval target ID",required:!0})};static flags={auto:p.boolean({description:"Skip interactive review, apply suggestions automatically",default:!1}),"max-iterations":p.integer({description:"Maximum optimization iterations",default:5}),threshold:p.string({description:"Stop if pass rate reaches this threshold (0-1)",default:"0.95"}),model:p.string({description:"Model for eval execution"}),"analyzer-model":p.string({description:"Model for analysis/suggestions"}),timeout:p.integer({description:"Timeout per eval in ms",default:12e4})};async run(){let{args:a,flags:e}=await this.parse(N);this.requireAuth();let t=await y(`/api/eval-targets/${a.targetId}`),i=await y(`/api/eval-targets/${a.targetId}/evals`);i.length===0&&this.error("No evals found. Create some first with `rulemetric evals create`.");let s=[...i].sort(()=>Math.random()-.5),g=Math.ceil(s.length*.6),u=s.slice(0,g),v=s.slice(g);this.log(`Optimizing "${t.name}" v${t.version}`),this.log(`Evals: ${u.length} train, ${v.length} test`);let h=parseFloat(e.threshold);this.log(`Config: max ${e["max-iterations"]} iterations, threshold ${(h*100).toFixed(0)}%`),e.auto&&this.log("Mode: auto (no interactive review)"),this.log("");let $=t.version,f=0,x=0;for(let r=1;r<=e["max-iterations"];r++){this.log(`
2
+ === Iteration ${r} ===`),this.log("Running train evals...");let T=await this.runEvalsOnTarget(t,u,e),l=this.computePassRate(T);if(this.log(`Train pass rate: ${(l*100).toFixed(1)}%`),l>=h){this.log(`Train score ${(l*100).toFixed(1)}% >= threshold ${(h*100).toFixed(0)}%. Stopping.`);let o=await this.runEvalsOnTarget(t,v,e),E=this.computePassRate(o);this.log(`Final test score: ${(E*100).toFixed(1)}%`),await m("/api/optimization-runs",{evalTargetId:t.id,type:"content",iteration:r,inputVersion:t.version,trainScore:l,testScore:E,analysis:{reason:"threshold_reached"},status:"completed"});break}this.log("Analyzing results...");let S=T.map(o=>({evalName:o.evalName,prompt:o.prompt,expectations:o.expectations,grading:o.grading})),n=await A({content:t.content,evalResults:S,model:e["analyzer-model"]??e.model,timeout:e.timeout});this.log(`
3
+ Assessment: ${n.overallAssessment}`),this.log(`Suggestions: ${n.suggestions.length}`);for(let o of n.suggestions)this.log(` - [${o.section}] ${o.reasoning}`);if(n.proposedContent===t.content){this.log("No changes proposed. Stopping."),await m("/api/optimization-runs",{evalTargetId:t.id,type:"content",iteration:r,inputVersion:t.version,trainScore:l,analysis:{reason:"no_changes"},status:"completed"});break}if(!e.auto&&!await this.confirm(`
4
+ Apply the proposed changes as a new version? [y/N] `)){this.log("Changes not applied. Stopping."),await m("/api/optimization-runs",{evalTargetId:t.id,type:"content",iteration:r,inputVersion:t.version,trainScore:l,analysis:{reason:"user_declined",suggestions:n.suggestions},status:"completed"});break}let c=await R(`/api/eval-targets/${t.id}`,{content:n.proposedContent});this.log(`Created v${c.version}`),this.log("Running test evals...");let F=await this.runEvalsOnTarget(c,v,e),d=this.computePassRate(F);if(this.log(`Test pass rate: ${(d*100).toFixed(1)}%`),await m("/api/optimization-runs",{evalTargetId:t.id,type:"content",iteration:r,inputVersion:t.version,outputVersion:c.version,trainScore:l,testScore:d,analysis:{suggestions:n.suggestions,overallAssessment:n.overallAssessment},status:"completed"}),d>f)f=d,$=c.version,x=0;else if(x++,x>=2){this.log("No improvement for 2 consecutive iterations. Stopping.");break}t=c}this.log(`
5
+ === Optimization Complete ===`),this.log(`Best version: v${$} (test score: ${(f*100).toFixed(1)}%)`)}async confirm(a){process.stdin.isTTY||this.error("Interactive approval requires a TTY. Re-run with --auto to apply changes without review.");let e=C({input:process.stdin,output:process.stdout});try{let t=await e.question(a);return/^y(es)?$/i.test(t.trim())}finally{e.close()}}async runEvalsOnTarget(a,e,t){let i=[];for(let s of e){let g=await z({prompt:s.prompt,targetContent:a.content,timeout:t.timeout,model:t.model});if(g.error){i.push({evalName:s.name,prompt:s.prompt,expectations:s.expectations,grading:{}});continue}if(s.expectations.length>0){let u=await k({prompt:s.prompt,output:g.output,expectations:s.expectations,model:t.model,timeout:t.timeout});i.push({evalName:s.name,prompt:s.prompt,expectations:s.expectations,grading:u})}else i.push({evalName:s.name,prompt:s.prompt,expectations:s.expectations,grading:{}})}return i}computePassRate(a){let e=a.filter(i=>Object.keys(i.grading).length>0);if(e.length===0)return 0;let t=e.map(i=>i.grading.summary?.pass_rate??0);return t.reduce((i,s)=>i+s,0)/t.length}};export{w as default};
@@ -1,3 +1,3 @@
1
- import{a as w}from"../../chunk-CADKBP3D.js";import{a as _}from"../../chunk-MGHFDHHM.js";import{a as R}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{d as h,e as k}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.js";import{a as $}from"../../chunk-ZLLER3HP.js";import{Args as T,Flags as c}from"@oclif/core";var b=class x extends R{static{$(this,"EvalRunCommand")}static description="Run evals against a target, optionally grade results, and post to API";static examples=["<%= config.bin %> evals run <target-id>","<%= config.bin %> evals run <target-id> --parallel 3 --runs-per-eval 2","<%= config.bin %> evals run <target-id> --skip-baseline --skip-grading"];static args={targetId:T.string({description:"Eval target ID",required:!0})};static flags={parallel:c.integer({description:"Number of parallel eval executions",default:1}),"runs-per-eval":c.integer({description:"Number of runs per eval for variance analysis",default:1}),iteration:c.integer({description:"Iteration number for tracking",default:1}),"skip-baseline":c.boolean({description:"Skip baseline (without_target) runs",default:!1}),"skip-grading":c.boolean({description:"Skip LLM grading step",default:!1}),model:c.string({description:"Model for eval execution (default: user configured)"}),"grader-model":c.string({description:"Model for grading (default: same as execution model)"}),timeout:c.integer({description:"Timeout per eval in ms",default:12e4})};async run(){let{args:f,flags:i}=await this.parse(x);this.requireAuth();let s=await h(`/api/eval-targets/${f.targetId}`),r=await h(`/api/eval-targets/${f.targetId}/evals`);r.length===0&&this.error(`No evals found for target "${s.name}". Create some with \`rulemetric evals create\`.`),this.log(`Running ${r.length} eval(s) for "${s.name}" v${s.version}`),this.log(`Config: ${i["runs-per-eval"]} run(s) per eval, parallel=${i.parallel}, iteration=${i.iteration}`),i["skip-baseline"]&&this.log("Skipping baseline runs"),i["skip-grading"]&&this.log("Skipping grading"),this.log("");let l=[{name:"with_target",content:s.content}];i["skip-baseline"]||l.push({name:"without_target"});let p=[];for(let e of r)for(let a of l)for(let n=1;n<=i["runs-per-eval"];n++)p.push({eval_:e,configuration:a.name,targetContent:a.content,runNumber:n});let o=[],g=i.parallel;for(let e=0;e<p.length;e+=g){let a=p.slice(e,e+g),n=await Promise.all(a.map(m=>this.executeAndGrade(m,s,i)));o.push(...n)}this.log(""),this.log("Posting results to API...");for(let e of o)await k("/api/eval-runs",e);this.log(""),this.log("=== Results Summary ===");for(let e of l){let a=o.filter(t=>t.configuration===e.name),n=a.filter(t=>t.status==="completed"),m=n.filter(t=>Object.keys(t.grading).length>0);if(this.log(`
1
+ import{a as w}from"../../chunk-CADKBP3D.js";import{a as _}from"../../chunk-MGHFDHHM.js";import{a as R}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{e as h,f as k}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as $}from"../../chunk-ZLLER3HP.js";import{Args as T,Flags as c}from"@oclif/core";var b=class x extends R{static{$(this,"EvalRunCommand")}static description="Run evals against a target, optionally grade results, and post to API";static examples=["<%= config.bin %> evals run <target-id>","<%= config.bin %> evals run <target-id> --parallel 3 --runs-per-eval 2","<%= config.bin %> evals run <target-id> --skip-baseline --skip-grading"];static args={targetId:T.string({description:"Eval target ID",required:!0})};static flags={parallel:c.integer({description:"Number of parallel eval executions",default:1}),"runs-per-eval":c.integer({description:"Number of runs per eval for variance analysis",default:1}),iteration:c.integer({description:"Iteration number for tracking",default:1}),"skip-baseline":c.boolean({description:"Skip baseline (without_target) runs",default:!1}),"skip-grading":c.boolean({description:"Skip LLM grading step",default:!1}),model:c.string({description:"Model for eval execution (default: user configured)"}),"grader-model":c.string({description:"Model for grading (default: same as execution model)"}),timeout:c.integer({description:"Timeout per eval in ms",default:12e4})};async run(){let{args:f,flags:i}=await this.parse(x);this.requireAuth();let s=await h(`/api/eval-targets/${f.targetId}`),r=await h(`/api/eval-targets/${f.targetId}/evals`);r.length===0&&this.error(`No evals found for target "${s.name}". Create some with \`rulemetric evals create\`.`),this.log(`Running ${r.length} eval(s) for "${s.name}" v${s.version}`),this.log(`Config: ${i["runs-per-eval"]} run(s) per eval, parallel=${i.parallel}, iteration=${i.iteration}`),i["skip-baseline"]&&this.log("Skipping baseline runs"),i["skip-grading"]&&this.log("Skipping grading"),this.log("");let l=[{name:"with_target",content:s.content}];i["skip-baseline"]||l.push({name:"without_target"});let p=[];for(let e of r)for(let a of l)for(let n=1;n<=i["runs-per-eval"];n++)p.push({eval_:e,configuration:a.name,targetContent:a.content,runNumber:n});let o=[],g=i.parallel;for(let e=0;e<p.length;e+=g){let a=p.slice(e,e+g),n=await Promise.all(a.map(m=>this.executeAndGrade(m,s,i)));o.push(...n)}this.log(""),this.log("Posting results to API...");for(let e of o)await k("/api/eval-runs",e);this.log(""),this.log("=== Results Summary ===");for(let e of l){let a=o.filter(t=>t.configuration===e.name),n=a.filter(t=>t.status==="completed"),m=n.filter(t=>Object.keys(t.grading).length>0);if(this.log(`
2
2
  ${e.name}:`),this.log(` Runs: ${n.length}/${a.length} completed`),m.length>0){let t=m.map(d=>d.grading.summary?.pass_rate??0),u=t.reduce((d,v)=>d+v,0)/t.length;this.log(` Avg pass_rate: ${(u*100).toFixed(1)}%`)}for(let t of a){let u=r.find(I=>I.id===t.evalId)?.name??t.evalId,d=t.grading.summary?.pass_rate,v=d!==void 0?` pass_rate=${(d*100).toFixed(0)}%`:"",y=t.timing.duration_ms?` ${(t.timing.duration_ms/1e3).toFixed(1)}s`:"";this.log(` [${t.status}] ${u} run#${t.runNumber}${v}${y}`)}}if(!i["skip-baseline"]&&o.length>0){let e=o.filter(n=>n.configuration==="with_target"&&Object.keys(n.grading).length>0),a=o.filter(n=>n.configuration==="without_target"&&Object.keys(n.grading).length>0);if(e.length>0&&a.length>0){let n=e.map(u=>u.grading.summary?.pass_rate??0).reduce((u,d)=>u+d,0)/e.length,m=a.map(u=>u.grading.summary?.pass_rate??0).reduce((u,d)=>u+d,0)/a.length,t=n-m;this.log(`
3
3
  Delta: ${t>0?"+":""}${(t*100).toFixed(1)}% (with_target vs without_target)`)}}}async executeAndGrade(f,i,s){let{eval_:r,configuration:l,targetContent:p,runNumber:o}=f;this.log(`[${l}] ${r.name} run#${o} \u2014 executing...`);let g=await _({prompt:r.prompt,targetContent:p,timeout:s.timeout,model:s.model});if(g.error)return this.log(`[${l}] ${r.name} run#${o} \u2014 FAILED: ${g.error}`),{evalId:r.id,evalTargetId:i.id,evalTargetVersion:i.version,configuration:l,runNumber:o,iteration:s.iteration,status:"failed",outputs:{error:g.error},timing:{duration_ms:g.durationMs,total_tokens:g.totalTokens},grading:{}};this.log(`[${l}] ${r.name} run#${o} \u2014 completed in ${(g.durationMs/1e3).toFixed(1)}s`);let e={};if(!s["skip-grading"]&&r.expectations.length>0){this.log(`[${l}] ${r.name} run#${o} \u2014 grading...`);let a=await w({prompt:r.prompt,output:g.output,expectations:r.expectations,model:s["grader-model"]??s.model,timeout:s.timeout});e=a;let n=a.summary.pass_rate;this.log(`[${l}] ${r.name} run#${o} \u2014 grading done: pass_rate=${(n*100).toFixed(0)}%`)}return{evalId:r.id,evalTargetId:i.id,evalTargetVersion:i.version,configuration:l,runNumber:o,iteration:s.iteration,status:"completed",outputs:{transcript:g.output},timing:{duration_ms:g.durationMs,total_tokens:g.totalTokens,total_duration_seconds:g.durationMs/1e3},grading:e}}};export{b as default};
@@ -1 +1 @@
1
- import{b as y,c as h}from"../../chunk-Y65CSJFF.js";import{B as l,E as g}from"../../chunk-O7ZMHCMG.js";import"../../chunk-I2DZGJRR.js";import{c as e,g as p,i as m,k as f}from"../../chunk-MVM6OGAF.js";import"../../chunk-KKDHD4XA.js";import{b as d,d as u}from"../../chunk-SZ62CP55.js";import{a as c}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.js";import{a}from"../../chunk-ZLLER3HP.js";import{spawn as S}from"node:child_process";import{existsSync as v,readFileSync as R,statSync as C,writeFileSync as M}from"node:fs";import{homedir as T}from"node:os";import{join as o}from"node:path";var s=o(T(),".config","rulemetric"),x=o(s,"proxy-addon.version"),_=o(s,"proxy.pid"),w=o(s,"proxy-drift-restart.at"),E=10*6e4,n=class P extends c{static{a(this,"GatewayEnsure")}static description="Ensure the gateway proxy is running (called by hooks, not for direct use)";static hidden=!0;async run(){await this.parse(P),this.maybeRestartStaleProxy();let t=await p(e);if(t.status==="ours-live"){let r=h(i=>{i==="vscode"?l(e):g(e)});r.length>0&&console.error(`[RuleMetric] Gateway healthy again \u2014 restored ${r.join(", ")} proxy settings.`);return}if(t.status==="foreign"){if(m())return;let r=y(e);console.error(`[RuleMetric] A non-RuleMetric process holds :${e} \u2014 cannot start gateway. `+(r.length>0?`Unpinned ${r.join(", ")} proxy settings so editors are not routed through it. `:"")+"Run `rulemetric diagnostics` if Claude Code HTTPS requests fail.");return}try{f(this.config.version)}catch(r){console.error(`[RuleMetric] Could not start gateway: ${r.message}`)}}maybeRestartStaleProxy(){try{if(!v(x))return;let t=R(x,"utf-8").trim();if(!t||t===this.config.version)return;let r=R(_,"utf-8").trim(),i=Number(r);if(!Number.isFinite(i)||!u(i,d))return;try{if(Date.now()-C(w).mtimeMs<E)return}catch{}M(w,new Date().toISOString()),S(process.execPath,[process.argv[1],"proxy","restart"],{detached:!0,stdio:"ignore"}).unref(),console.error(`[RuleMetric] Capture proxy is running CLI ${t} but ${this.config.version} is installed \u2014 restarting it in the background.`)}catch{}}};export{n as default};
1
+ import{b as y,c as h}from"../../chunk-JAPCCEKF.js";import{B as l,E as g}from"../../chunk-2JRDG4LJ.js";import"../../chunk-I2DZGJRR.js";import{c as e,g as p,i as m,k as f}from"../../chunk-MVM6OGAF.js";import"../../chunk-KKDHD4XA.js";import{b as d,d as u}from"../../chunk-SZ62CP55.js";import{a as c}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a}from"../../chunk-ZLLER3HP.js";import{spawn as S}from"node:child_process";import{existsSync as v,readFileSync as R,statSync as C,writeFileSync as M}from"node:fs";import{homedir as T}from"node:os";import{join as o}from"node:path";var s=o(T(),".config","rulemetric"),x=o(s,"proxy-addon.version"),_=o(s,"proxy.pid"),w=o(s,"proxy-drift-restart.at"),E=10*6e4,n=class P extends c{static{a(this,"GatewayEnsure")}static description="Ensure the gateway proxy is running (called by hooks, not for direct use)";static hidden=!0;async run(){await this.parse(P),this.maybeRestartStaleProxy();let t=await p(e);if(t.status==="ours-live"){let r=h(i=>{i==="vscode"?l(e):g(e)});r.length>0&&console.error(`[RuleMetric] Gateway healthy again \u2014 restored ${r.join(", ")} proxy settings.`);return}if(t.status==="foreign"){if(m())return;let r=y(e);console.error(`[RuleMetric] A non-RuleMetric process holds :${e} \u2014 cannot start gateway. `+(r.length>0?`Unpinned ${r.join(", ")} proxy settings so editors are not routed through it. `:"")+"Run `rulemetric diagnostics` if Claude Code HTTPS requests fail.");return}try{f(this.config.version)}catch(r){console.error(`[RuleMetric] Could not start gateway: ${r.message}`)}}maybeRestartStaleProxy(){try{if(!v(x))return;let t=R(x,"utf-8").trim();if(!t||t===this.config.version)return;let r=R(_,"utf-8").trim(),i=Number(r);if(!Number.isFinite(i)||!u(i,d))return;try{if(Date.now()-C(w).mtimeMs<E)return}catch{}M(w,new Date().toISOString()),S(process.execPath,[process.argv[1],"proxy","restart"],{detached:!0,stdio:"ignore"}).unref(),console.error(`[RuleMetric] Capture proxy is running CLI ${t} but ${this.config.version} is installed \u2014 restarting it in the background.`)}catch{}}};export{n as default};
@@ -1 +1 @@
1
- import{a as pt}from"../../chunk-6XEC6474.js";import{B as ut,E as dt,H as gt,I as ht,e as z,f as Q,g as Z,i as tt,j as et,k as st,n as ot,p as it,q as rt,r as at,u as nt,v as lt,y as ct}from"../../chunk-O7ZMHCMG.js";import{a as q,b as W,c as m,d as J,g as A}from"../../chunk-I2DZGJRR.js";import"../../chunk-N7ODX6PO.js";import{a as f}from"../../chunk-67QCYUJU.js";import{c as s,g as X,h as D,i as F,k as O,l as V}from"../../chunk-MVM6OGAF.js";import{e as B}from"../../chunk-KKDHD4XA.js";import"../../chunk-SZ62CP55.js";import{a as Y}from"../../chunk-AHRHCERJ.js";import{a as M}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import{c as N}from"../../chunk-CRAKDQ4H.js";import{b as L}from"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-TIQ7DQ3M.js";import{a as G}from"../../chunk-M6AJDVCL.js";import{a as v}from"../../chunk-ZLLER3HP.js";import{Flags as w}from"@oclif/core";import{execFileSync as ft,spawnSync as l}from"node:child_process";import{existsSync as c}from"node:fs";import{homedir as mt}from"node:os";import{join as _,dirname as Ct}from"node:path";function vt(){try{let d=ft("/bin/sh",["-c","command -v rulemetric"],{encoding:"utf-8"}).trim();if(d&&c(d))return Ct(d)}catch{}}v(vt,"resolveHookBinDir");function wt(){try{return ft("launchctl",["list","com.rulemetric.gateway"],{stdio:["ignore","pipe","pipe"]}),!0}catch{return!1}}v(wt,"isGatewayLaunchdManaged");var o=_(mt(),".mitmproxy","mitmproxy-ca-cert.pem"),R=class d extends M{static{v(this,"HooksInstall")}static description="Install session tracking hooks and context capture proxy for Claude Code";static examples=["<%= config.bin %> hooks install","<%= config.bin %> hooks install --global","<%= config.bin %> hooks install --no-proxy"];static flags={"no-proxy":w.boolean({default:!1,description:"Skip proxy/gateway configuration (hooks only)"}),"project-dir":w.string({description:"Project directory to install hooks in (defaults to cwd)"}),global:w.boolean({char:"g",default:!1,description:"Install hooks globally (~/.claude/settings.json) so all projects are tracked"}),"statusline-usage":w.boolean({default:!1,description:"Install the statusline shim so Claude Code pushes live rate_limits on every refresh (makes /usage rings update in real time without needing the proxy)"})};async run(){let{flags:i}=await this.parse(d),r=i.global,n=r?mt():i["project-dir"]??process.cwd(),x=_(n,".claude"),y=st(x,r),K=r?"settings.json":"settings.local.json",k=i["no-proxy"],P=!1,g=k?"no_proxy_flag":void 0,h=!1,S=[];r&&this.log(`Installing hooks globally \u2192 ${y}`);let{settings:a,recoveredBackup:$}=z(y);if($&&this.log(`[!!] ${y} was not valid JSON \u2014 backed it up to ${$} and continued with a fresh file.`),!r){let e=ot(_(x,"settings.json"),s);e.migrated&&(this.log("[OK] Moved RuleMetric machine-local state out of the shared .claude/settings.json (it now lives in .claude/settings.local.json)"),e.backupPath&&this.log(` Previous shared settings backed up \u2192 ${e.backupPath}`),e.removedStatusline&&c(q)&&!A(a)&&(a.statusLine=m))}let I=G();(I.accessToken||process.env.RULEMETRIC_ACCESS_TOKEN)&&!I.apiKey&&!process.env.RULEMETRIC_API_KEY&&await Y(this.log.bind(this),this.warn.bind(this),this.config.version);let yt=tt(a),C=vt();if(Z(a,C),this.log(yt?`[OK] Refreshed RuleMetric Claude Code session hooks \u2192 .claude/${K}`:`[OK] Installed RuleMetric Claude Code session hooks \u2192 .claude/${K}`),!k){let e=!!f("mitmdump");if(e||(this.log(""),this.log("[!!] mitmproxy not found \u2014 installing..."),S=["brew","pipx","uv"].filter(t=>!!f(t)),e=this.installMitmproxy(),e||(this.log("[!!] Could not install mitmproxy. Skipping proxy config."),this.log(" Install manually: pipx install mitmproxy"),this.log(" Then re-run: rulemetric hooks install"))),c(o))this.log("[OK] CA certificate found");else{this.log("[..] Generating CA certificate...");let t=f("mitmdump");t&&(l(t,["--set","listen_port=0","-q"],{timeout:5e3,stdio:"ignore"}),c(o)?this.log(`[OK] CA certificate generated at ${o}`):this.log("[!!] Could not generate CA cert"))}let u=c(o);u&&!this.isCACertTrusted()?(this.log("[..] Installing CA certificate into system trust store (requires admin)..."),h=this.trustCACert(),h?this.log("[OK] CA certificate trusted by system"):(this.log("[!!] Could not install CA cert automatically."),process.platform==="darwin"?this.log(` Run manually: sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ${o}`):process.platform==="linux"&&this.log(` Run manually: sudo cp ${o} /usr/local/share/ca-certificates/mitmproxy-ca.crt && sudo update-ca-certificates`))):u&&(this.log("[OK] CA certificate already trusted"),h=!0);let p=wt(),b=await X(s);if(p)this.log("[OK] Gateway managed by launchd (com.rulemetric.gateway)");else if(b.status==="ours-live")this.log("[OK] Gateway already running");else if(b.status==="foreign"&&F()){this.log("[..] Restarting gateway (running build predates the identity handshake)..."),V(),await new Promise(t=>setTimeout(t,500));try{let t=O(this.config.version);this.log(`[OK] Gateway restarted (PID ${t})`)}catch(t){this.log(`[!!] Could not restart gateway: ${t.message}`)}}else if(b.status!=="foreign")try{let t=O(this.config.version);this.log(`[OK] Gateway started (PID ${t})`)}catch(t){this.log(`[!!] Could not start gateway: ${t.message}`)}let j=await D(s,{timeoutMs:4e3});if(!u)g=e?"ca_not_generated":S.length===0?"no_package_manager":"mitmproxy_install_failed",this.log("[!!] No CA certificate \u2014 NOT setting HTTPS_PROXY (capture stays hooks-only)."),this.log(" Install mitmproxy, then re-run: rulemetric hooks install");else if(j.status==="foreign"&&!p){g="gateway_port_foreign";let t=B(s);this.log(`[!!] Port :${s} is held by a process that is NOT the RuleMetric gateway \u2014 NOT setting HTTPS_PROXY.`),this.log(t?` Holding the port: ${t}`:` Could not identify the holder (try: lsof -nP -iTCP:${s} -sTCP:LISTEN)`),this.log(" Capture still works via hooks. Free the port, then re-run: rulemetric hooks install")}else if(j.status==="dead")g="gateway_not_live",this.log(`[!!] Gateway is not answering on :${s} \u2014 NOT setting HTTPS_PROXY.`),this.log(" Capture still works via hooks. To enable deep (proxy) capture later:"),this.log(" rulemetric proxy start && rulemetric hooks install");else{let t=a.env??{};t.HTTPS_PROXY=`http://localhost:${s}`,t.NO_PROXY=et,c(o)&&(t.NODE_EXTRA_CA_CERTS=o),a.env=t,P=!0,this.log(`[OK] HTTPS_PROXY set to gateway on :${s} (verified live)`),nt(n,s,o)&&this.log("[OK] Cursor proxy configured \u2192 .cursor/settings.json"),lt(n,s,o)&&this.log("[OK] VS Code workspace proxy configured \u2192 .vscode/settings.json"),ut(s)&&this.log("[OK] VS Code user proxy configured \u2192 ~/Library/Application Support/Code/User/settings.json"),dt(s)&&this.log("[OK] Cursor user proxy configured \u2192 ~/Library/Application Support/Cursor/User/settings.json"),h?ct(s,o)&&this.log("[OK] HTTPS_PROXY set for GUI apps (launchctl + LaunchAgent)"):(g="ca_untrusted",this.log("[!!] CA not trusted \u2014 skipping machine-wide GUI proxy (would break native-app TLS)."),this.log(" Claude Code capture is unaffected. Trust the CA + re-run to enable cross-app capture."))}}if(!r){let e=it(n,C);e&&this.log(`[OK] Cursor hooks configured \u2192 ${e}`);let u=at(n,C);u&&this.log(`[OK] Copilot Agent hooks configured \u2192 ${u}`);let p=gt(n);p&&this.log(`[OK] Antigravity workspace hooks configured \u2192 ${p}`)}let E=ht();E&&this.log(`[OK] Antigravity user hooks configured \u2192 ${E}`);let H=rt(C);if(H&&this.log(`[OK] Cursor user hooks configured \u2192 ${H}`),i["statusline-usage"])if(A(a))this.log("[OK] Statusline shim already installed");else{let e=J(a);W(e),a.statusLine=m,e?this.log(`[OK] Statusline shim installed \u2192 ${m.command} (chains to: ${e})`):this.log(`[OK] Statusline shim installed \u2192 ${m.command}`),this.log(" Rate-limit rings will now update on Claude Code's statusline refresh cadence")}let{backupPath:U}=Q(y,a);U&&this.log(`[OK] Backed up previous settings \u2192 ${U}`),this.log(""),this.log("Setup complete! Next steps:"),r?(this.log(" 1. Install always-on API: rulemetric service install"),this.log(" 2. Start Claude Code in any project \u2014 all sessions tracked automatically"),this.log(""),this.log("The API service starts on login and restarts on crash.")):k?(this.log(" 1. Start Claude Code \u2014 sessions are captured by the hooks just installed"),this.log(""),this.log("No proxy means no mitmproxy / CA cert needed. The hooks capture full"),this.log("sessions on their own; re-run without --no-proxy to also capture system"),this.log("prompts for instruction-effectiveness linking.")):(this.log(" 1. Start Claude Code \u2014 sessions are captured by hooks immediately"),P?this.log(" 2. Full-depth capture is ON \u2014 the proxy is live on :"+s+"."):this.log(" 2. Enable full depth (proxy not yet live): rulemetric proxy start"),this.log(""),this.log("Hooks capture every session (lifecycle + transcript). The proxy adds the"),this.log("rendered system prompt (instruction-effectiveness linking) + cross-tool capture."),this.log(""),this.log("To capture traffic from other clients (Python, curl, etc.):"),this.log(' eval "$(rulemetric proxy env --all)"')),await L(),N("hooks_installed",{proxy:P,caTrusted:h,reason:g,installers:S,global:r},this.config.version);let T=await pt();this.log(""),T.available?this.log(`[OK] tmux found${T.version?` (v${T.version})`:""} \u2014 live send enabled`):this.log("[!!] tmux not found \u2014 live send will fall back to opening Terminal. Install with: brew install tmux")}installMitmproxy(){for(let[i,r]of[["pipx",["install","mitmproxy"]],["uv",["tool","install","mitmproxy"]],["brew",["install","mitmproxy"]]]){let n=f(i);if(n&&(this.log(` Installing via ${i}...`),l(n,[...r],{stdio:"inherit"}).status===0))return!0}return!1}isCACertTrusted(){return process.platform==="darwin"?l("security",["verify-cert","-c",o],{stdio:"pipe"}).status===0:process.platform==="linux"?c("/usr/local/share/ca-certificates/mitmproxy-ca.crt"):process.platform==="win32"?l("certutil",["-verify",o],{stdio:"pipe"}).status===0:!1}trustCACert(){return process.platform==="darwin"?l("sudo",["security","add-trusted-cert","-d","-r","trustRoot","-k","/Library/Keychains/System.keychain",o],{stdio:"inherit"}).status===0:process.platform==="linux"?l("sudo",["cp",o,"/usr/local/share/ca-certificates/mitmproxy-ca.crt"],{stdio:"inherit"}).status!==0?!1:l("sudo",["update-ca-certificates"],{stdio:"inherit"}).status===0:process.platform==="win32"?l("certutil",["-addstore","-f","Root",o],{stdio:"inherit"}).status===0:!1}};export{R as default};
1
+ import{a as pt}from"../../chunk-6XEC6474.js";import{B as ut,E as dt,H as gt,I as ht,e as z,f as Q,g as Z,i as tt,j as et,k as st,n as ot,p as it,q as rt,r as at,u as nt,v as lt,y as ct}from"../../chunk-2JRDG4LJ.js";import{a as q,b as W,c as m,d as J,g as A}from"../../chunk-I2DZGJRR.js";import"../../chunk-N7ODX6PO.js";import{a as f}from"../../chunk-67QCYUJU.js";import{c as s,g as X,h as D,i as F,k as O,l as V}from"../../chunk-MVM6OGAF.js";import{e as B}from"../../chunk-KKDHD4XA.js";import"../../chunk-SZ62CP55.js";import{a as Y}from"../../chunk-XICLXXRH.js";import{a as M}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import{c as N}from"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import{b as L}from"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-H2ORWIEY.js";import{a as G}from"../../chunk-O6C2UGBY.js";import{a as v}from"../../chunk-ZLLER3HP.js";import{Flags as w}from"@oclif/core";import{execFileSync as ft,spawnSync as l}from"node:child_process";import{existsSync as c}from"node:fs";import{homedir as mt}from"node:os";import{join as _,dirname as Ct}from"node:path";function vt(){try{let d=ft("/bin/sh",["-c","command -v rulemetric"],{encoding:"utf-8"}).trim();if(d&&c(d))return Ct(d)}catch{}}v(vt,"resolveHookBinDir");function wt(){try{return ft("launchctl",["list","com.rulemetric.gateway"],{stdio:["ignore","pipe","pipe"]}),!0}catch{return!1}}v(wt,"isGatewayLaunchdManaged");var o=_(mt(),".mitmproxy","mitmproxy-ca-cert.pem"),R=class d extends M{static{v(this,"HooksInstall")}static description="Install session tracking hooks and context capture proxy for Claude Code";static examples=["<%= config.bin %> hooks install","<%= config.bin %> hooks install --global","<%= config.bin %> hooks install --no-proxy"];static flags={"no-proxy":w.boolean({default:!1,description:"Skip proxy/gateway configuration (hooks only)"}),"project-dir":w.string({description:"Project directory to install hooks in (defaults to cwd)"}),global:w.boolean({char:"g",default:!1,description:"Install hooks globally (~/.claude/settings.json) so all projects are tracked"}),"statusline-usage":w.boolean({default:!1,description:"Install the statusline shim so Claude Code pushes live rate_limits on every refresh (makes /usage rings update in real time without needing the proxy)"})};async run(){let{flags:i}=await this.parse(d),r=i.global,n=r?mt():i["project-dir"]??process.cwd(),x=_(n,".claude"),y=st(x,r),K=r?"settings.json":"settings.local.json",k=i["no-proxy"],P=!1,g=k?"no_proxy_flag":void 0,h=!1,S=[];r&&this.log(`Installing hooks globally \u2192 ${y}`);let{settings:a,recoveredBackup:$}=z(y);if($&&this.log(`[!!] ${y} was not valid JSON \u2014 backed it up to ${$} and continued with a fresh file.`),!r){let e=ot(_(x,"settings.json"),s);e.migrated&&(this.log("[OK] Moved RuleMetric machine-local state out of the shared .claude/settings.json (it now lives in .claude/settings.local.json)"),e.backupPath&&this.log(` Previous shared settings backed up \u2192 ${e.backupPath}`),e.removedStatusline&&c(q)&&!A(a)&&(a.statusLine=m))}let I=G();(I.accessToken||process.env.RULEMETRIC_ACCESS_TOKEN)&&!I.apiKey&&!process.env.RULEMETRIC_API_KEY&&await Y(this.log.bind(this),this.warn.bind(this),this.config.version);let yt=tt(a),C=vt();if(Z(a,C),this.log(yt?`[OK] Refreshed RuleMetric Claude Code session hooks \u2192 .claude/${K}`:`[OK] Installed RuleMetric Claude Code session hooks \u2192 .claude/${K}`),!k){let e=!!f("mitmdump");if(e||(this.log(""),this.log("[!!] mitmproxy not found \u2014 installing..."),S=["brew","pipx","uv"].filter(t=>!!f(t)),e=this.installMitmproxy(),e||(this.log("[!!] Could not install mitmproxy. Skipping proxy config."),this.log(" Install manually: pipx install mitmproxy"),this.log(" Then re-run: rulemetric hooks install"))),c(o))this.log("[OK] CA certificate found");else{this.log("[..] Generating CA certificate...");let t=f("mitmdump");t&&(l(t,["--set","listen_port=0","-q"],{timeout:5e3,stdio:"ignore"}),c(o)?this.log(`[OK] CA certificate generated at ${o}`):this.log("[!!] Could not generate CA cert"))}let u=c(o);u&&!this.isCACertTrusted()?(this.log("[..] Installing CA certificate into system trust store (requires admin)..."),h=this.trustCACert(),h?this.log("[OK] CA certificate trusted by system"):(this.log("[!!] Could not install CA cert automatically."),process.platform==="darwin"?this.log(` Run manually: sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain ${o}`):process.platform==="linux"&&this.log(` Run manually: sudo cp ${o} /usr/local/share/ca-certificates/mitmproxy-ca.crt && sudo update-ca-certificates`))):u&&(this.log("[OK] CA certificate already trusted"),h=!0);let p=wt(),b=await X(s);if(p)this.log("[OK] Gateway managed by launchd (com.rulemetric.gateway)");else if(b.status==="ours-live")this.log("[OK] Gateway already running");else if(b.status==="foreign"&&F()){this.log("[..] Restarting gateway (running build predates the identity handshake)..."),V(),await new Promise(t=>setTimeout(t,500));try{let t=O(this.config.version);this.log(`[OK] Gateway restarted (PID ${t})`)}catch(t){this.log(`[!!] Could not restart gateway: ${t.message}`)}}else if(b.status!=="foreign")try{let t=O(this.config.version);this.log(`[OK] Gateway started (PID ${t})`)}catch(t){this.log(`[!!] Could not start gateway: ${t.message}`)}let j=await D(s,{timeoutMs:4e3});if(!u)g=e?"ca_not_generated":S.length===0?"no_package_manager":"mitmproxy_install_failed",this.log("[!!] No CA certificate \u2014 NOT setting HTTPS_PROXY (capture stays hooks-only)."),this.log(" Install mitmproxy, then re-run: rulemetric hooks install");else if(j.status==="foreign"&&!p){g="gateway_port_foreign";let t=B(s);this.log(`[!!] Port :${s} is held by a process that is NOT the RuleMetric gateway \u2014 NOT setting HTTPS_PROXY.`),this.log(t?` Holding the port: ${t}`:` Could not identify the holder (try: lsof -nP -iTCP:${s} -sTCP:LISTEN)`),this.log(" Capture still works via hooks. Free the port, then re-run: rulemetric hooks install")}else if(j.status==="dead")g="gateway_not_live",this.log(`[!!] Gateway is not answering on :${s} \u2014 NOT setting HTTPS_PROXY.`),this.log(" Capture still works via hooks. To enable deep (proxy) capture later:"),this.log(" rulemetric proxy start && rulemetric hooks install");else{let t=a.env??{};t.HTTPS_PROXY=`http://localhost:${s}`,t.NO_PROXY=et,c(o)&&(t.NODE_EXTRA_CA_CERTS=o),a.env=t,P=!0,this.log(`[OK] HTTPS_PROXY set to gateway on :${s} (verified live)`),nt(n,s,o)&&this.log("[OK] Cursor proxy configured \u2192 .cursor/settings.json"),lt(n,s,o)&&this.log("[OK] VS Code workspace proxy configured \u2192 .vscode/settings.json"),ut(s)&&this.log("[OK] VS Code user proxy configured \u2192 ~/Library/Application Support/Code/User/settings.json"),dt(s)&&this.log("[OK] Cursor user proxy configured \u2192 ~/Library/Application Support/Cursor/User/settings.json"),h?ct(s,o)&&this.log("[OK] HTTPS_PROXY set for GUI apps (launchctl + LaunchAgent)"):(g="ca_untrusted",this.log("[!!] CA not trusted \u2014 skipping machine-wide GUI proxy (would break native-app TLS)."),this.log(" Claude Code capture is unaffected. Trust the CA + re-run to enable cross-app capture."))}}if(!r){let e=it(n,C);e&&this.log(`[OK] Cursor hooks configured \u2192 ${e}`);let u=at(n,C);u&&this.log(`[OK] Copilot Agent hooks configured \u2192 ${u}`);let p=gt(n);p&&this.log(`[OK] Antigravity workspace hooks configured \u2192 ${p}`)}let E=ht();E&&this.log(`[OK] Antigravity user hooks configured \u2192 ${E}`);let H=rt(C);if(H&&this.log(`[OK] Cursor user hooks configured \u2192 ${H}`),i["statusline-usage"])if(A(a))this.log("[OK] Statusline shim already installed");else{let e=J(a);W(e),a.statusLine=m,e?this.log(`[OK] Statusline shim installed \u2192 ${m.command} (chains to: ${e})`):this.log(`[OK] Statusline shim installed \u2192 ${m.command}`),this.log(" Rate-limit rings will now update on Claude Code's statusline refresh cadence")}let{backupPath:U}=Q(y,a);U&&this.log(`[OK] Backed up previous settings \u2192 ${U}`),this.log(""),this.log("Setup complete! Next steps:"),r?(this.log(" 1. Install always-on API: rulemetric service install"),this.log(" 2. Start Claude Code in any project \u2014 all sessions tracked automatically"),this.log(""),this.log("The API service starts on login and restarts on crash.")):k?(this.log(" 1. Start Claude Code \u2014 sessions are captured by the hooks just installed"),this.log(""),this.log("No proxy means no mitmproxy / CA cert needed. The hooks capture full"),this.log("sessions on their own; re-run without --no-proxy to also capture system"),this.log("prompts for instruction-effectiveness linking.")):(this.log(" 1. Start Claude Code \u2014 sessions are captured by hooks immediately"),P?this.log(" 2. Full-depth capture is ON \u2014 the proxy is live on :"+s+"."):this.log(" 2. Enable full depth (proxy not yet live): rulemetric proxy start"),this.log(""),this.log("Hooks capture every session (lifecycle + transcript). The proxy adds the"),this.log("rendered system prompt (instruction-effectiveness linking) + cross-tool capture."),this.log(""),this.log("To capture traffic from other clients (Python, curl, etc.):"),this.log(' eval "$(rulemetric proxy env --all)"')),await L(),N("hooks_installed",{proxy:P,caTrusted:h,reason:g,installers:S,global:r},this.config.version);let T=await pt();this.log(""),T.available?this.log(`[OK] tmux found${T.version?` (v${T.version})`:""} \u2014 live send enabled`):this.log("[!!] tmux not found \u2014 live send will fall back to opening Terminal. Install with: brew install tmux")}installMitmproxy(){for(let[i,r]of[["pipx",["install","mitmproxy"]],["uv",["tool","install","mitmproxy"]],["brew",["install","mitmproxy"]]]){let n=f(i);if(n&&(this.log(` Installing via ${i}...`),l(n,[...r],{stdio:"inherit"}).status===0))return!0}return!1}isCACertTrusted(){return process.platform==="darwin"?l("security",["verify-cert","-c",o],{stdio:"pipe"}).status===0:process.platform==="linux"?c("/usr/local/share/ca-certificates/mitmproxy-ca.crt"):process.platform==="win32"?l("certutil",["-verify",o],{stdio:"pipe"}).status===0:!1}trustCACert(){return process.platform==="darwin"?l("sudo",["security","add-trusted-cert","-d","-r","trustRoot","-k","/Library/Keychains/System.keychain",o],{stdio:"inherit"}).status===0:process.platform==="linux"?l("sudo",["cp",o,"/usr/local/share/ca-certificates/mitmproxy-ca.crt"],{stdio:"inherit"}).status!==0?!1:l("sudo",["update-ca-certificates"],{stdio:"inherit"}).status===0:process.platform==="win32"?l("certutil",["-addstore","-f","Root",o],{stdio:"inherit"}).status===0:!1}};export{R as default};
@@ -1,3 +1,3 @@
1
- import{a as d}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.js";import{a as c}from"../../chunk-ZLLER3HP.js";import{Args as m}from"@oclif/core";import{execFileSync as u}from"node:child_process";import{existsSync as f}from"node:fs";import{join as h,delimiter as g}from"node:path";var l=["session-start","session-end","user-prompt","post-tool-use","assistant-response"],a=class p extends d{static{c(this,"HooksRun")}static description="Execute a hook script (called by AI tool hooks, not for direct use)";static hidden=!0;static args={hook:m.string({description:"Hook name to run",required:!0,options:[...l]})};async run(){let{args:r}=await this.parse(p),t=r.hook,{scriptsDir:e}=await import("@rulemetric/hooks/scripts-dir"),o=h(e,`${t}.sh`);f(o)||this.error(`Hook script not found: ${o}`);try{let s=await this.readStdin(),i=`${process.env.PATH??""}${g}${e}`;if(u("bash",[o],{input:s,stdio:["pipe","inherit","inherit"],timeout:t==="session-end"?3e4:1e4,env:{...process.env,PATH:i}}),process.env.RULEMETRIC_HOOK_TOOL==="antigravity"&&t==="post-tool-use")try{let{tailAntigravityTranscript:n}=await import("../../lib/antigravity-transcript.js");await n(s)}catch(n){process.stderr.write(`[antigravity-tailer] ${n.message}
1
+ import{a as d}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as c}from"../../chunk-ZLLER3HP.js";import{Args as m}from"@oclif/core";import{execFileSync as u}from"node:child_process";import{existsSync as f}from"node:fs";import{join as h,delimiter as g}from"node:path";var l=["session-start","session-end","user-prompt","post-tool-use","assistant-response"],a=class p extends d{static{c(this,"HooksRun")}static description="Execute a hook script (called by AI tool hooks, not for direct use)";static hidden=!0;static args={hook:m.string({description:"Hook name to run",required:!0,options:[...l]})};async run(){let{args:r}=await this.parse(p),t=r.hook,{scriptsDir:e}=await import("@rulemetric/hooks/scripts-dir"),o=h(e,`${t}.sh`);f(o)||this.error(`Hook script not found: ${o}`);try{let s=await this.readStdin(),i=`${process.env.PATH??""}${g}${e}`;if(u("bash",[o],{input:s,stdio:["pipe","inherit","inherit"],timeout:t==="session-end"?3e4:1e4,env:{...process.env,PATH:i}}),process.env.RULEMETRIC_HOOK_TOOL==="antigravity"&&t==="post-tool-use")try{let{tailAntigravityTranscript:n}=await import("../../lib/antigravity-transcript.js");await n(s)}catch(n){process.stderr.write(`[antigravity-tailer] ${n.message}
2
2
  `)}}catch(s){let i=s.status;process.env.RULEMETRIC_HOOK_DEBUG&&process.stderr.write(`[rulemetric hooks run ${t}] non-fatal exit ${i??"?"}: ${s.message??""}
3
3
  `)}}readStdin(){return new Promise(r=>{let t=[];process.stdin.on("data",e=>t.push(e)),process.stdin.on("end",()=>r(Buffer.concat(t).toString("utf-8"))),process.stdin.readableEnded&&r(Buffer.concat(t).toString("utf-8"))})}};export{a as default};
@@ -1,2 +1,2 @@
1
- import{C as x,F as k,J as C,K as S,o as h,s as p,t as g,w as v,x as y,z as R}from"../../chunk-O7ZMHCMG.js";import"../../chunk-I2DZGJRR.js";import{c as f,l as d}from"../../chunk-MVM6OGAF.js";import"../../chunk-KKDHD4XA.js";import"../../chunk-SZ62CP55.js";import{a}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.js";import{a as i}from"../../chunk-ZLLER3HP.js";import{existsSync as n,readFileSync as A,writeFileSync as j}from"node:fs";import{spawnSync as t}from"node:child_process";import{homedir as O}from"node:os";import{join as c}from"node:path";var r=c(O(),".mitmproxy","mitmproxy-ca-cert.pem");function N(){return n(r)?process.platform==="darwin"?t("sudo",["security","remove-trusted-cert","-d",r],{stdio:"inherit"}).status===0:process.platform==="linux"?t("sudo",["rm","-f","/usr/local/share/ca-certificates/mitmproxy-ca.crt"],{stdio:"inherit"}).status!==0?!1:t("sudo",["update-ca-certificates","--fresh"],{stdio:"inherit"}).status===0:process.platform==="win32"?t("certutil",["-delstore","Root","mitmproxy"],{stdio:"inherit"}).status===0:!1:!1}i(N,"untrustCACert");var u=class extends a{static{i(this,"HooksUninstall")}static description="Remove session tracking hooks from the current project";static examples=["<%= config.bin %> hooks uninstall"];async run(){let w=c(process.cwd(),".claude"),l=h(w,f);if(l.length===0){this.log("No .claude/settings.json or .claude/settings.local.json found \u2014 nothing to uninstall.");return}let e=!1,m=!1;for(let o of l)o.recoveredBackup&&this.log(`[!!] ${o.configPath} was not valid JSON \u2014 backed up to ${o.recoveredBackup}; continuing.`),o.removedHooks&&this.log(`Removed RuleMetric hooks from .claude/${o.fileName}`),o.removedProxyEnv&&(this.log(`Removed HTTPS_PROXY, NO_PROXY and NODE_EXTRA_CA_CERTS from .claude/${o.fileName}`),m=!0),o.removedStatusline&&this.log(`Removed RuleMetric statusline shim from .claude/${o.fileName}`),e=e||o.changed;e||this.log("No hooks or proxy config found \u2014 nothing to uninstall."),p(process.cwd())&&(this.log("Removed RuleMetric hooks from .cursor/hooks.json"),e=!0),g()&&(this.log("Removed RuleMetric hooks from ~/.cursor/hooks.json"),e=!0);let s=c(process.cwd(),".cursor","settings.json");if(n(s))try{let o=JSON.parse(A(s,"utf-8"));o["http.proxy"]?.includes("localhost")&&(delete o["http.proxy"],delete o["http.proxyStrictSSL"],j(s,JSON.stringify(o,null,2)+`
1
+ import{C as x,F as k,J as C,K as S,o as h,s as p,t as g,w as v,x as y,z as R}from"../../chunk-2JRDG4LJ.js";import"../../chunk-I2DZGJRR.js";import{c as f,l as d}from"../../chunk-MVM6OGAF.js";import"../../chunk-KKDHD4XA.js";import"../../chunk-SZ62CP55.js";import{a}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as i}from"../../chunk-ZLLER3HP.js";import{existsSync as n,readFileSync as A,writeFileSync as j}from"node:fs";import{spawnSync as t}from"node:child_process";import{homedir as O}from"node:os";import{join as c}from"node:path";var r=c(O(),".mitmproxy","mitmproxy-ca-cert.pem");function N(){return n(r)?process.platform==="darwin"?t("sudo",["security","remove-trusted-cert","-d",r],{stdio:"inherit"}).status===0:process.platform==="linux"?t("sudo",["rm","-f","/usr/local/share/ca-certificates/mitmproxy-ca.crt"],{stdio:"inherit"}).status!==0?!1:t("sudo",["update-ca-certificates","--fresh"],{stdio:"inherit"}).status===0:process.platform==="win32"?t("certutil",["-delstore","Root","mitmproxy"],{stdio:"inherit"}).status===0:!1:!1}i(N,"untrustCACert");var u=class extends a{static{i(this,"HooksUninstall")}static description="Remove session tracking hooks from the current project";static examples=["<%= config.bin %> hooks uninstall"];async run(){let w=c(process.cwd(),".claude"),l=h(w,f);if(l.length===0){this.log("No .claude/settings.json or .claude/settings.local.json found \u2014 nothing to uninstall.");return}let e=!1,m=!1;for(let o of l)o.recoveredBackup&&this.log(`[!!] ${o.configPath} was not valid JSON \u2014 backed up to ${o.recoveredBackup}; continuing.`),o.removedHooks&&this.log(`Removed RuleMetric hooks from .claude/${o.fileName}`),o.removedProxyEnv&&(this.log(`Removed HTTPS_PROXY, NO_PROXY and NODE_EXTRA_CA_CERTS from .claude/${o.fileName}`),m=!0),o.removedStatusline&&this.log(`Removed RuleMetric statusline shim from .claude/${o.fileName}`),e=e||o.changed;e||this.log("No hooks or proxy config found \u2014 nothing to uninstall."),p(process.cwd())&&(this.log("Removed RuleMetric hooks from .cursor/hooks.json"),e=!0),g()&&(this.log("Removed RuleMetric hooks from ~/.cursor/hooks.json"),e=!0);let s=c(process.cwd(),".cursor","settings.json");if(n(s))try{let o=JSON.parse(A(s,"utf-8"));o["http.proxy"]?.includes("localhost")&&(delete o["http.proxy"],delete o["http.proxyStrictSSL"],j(s,JSON.stringify(o,null,2)+`
2
2
  `),this.log("Removed proxy config from .cursor/settings.json"),e=!0)}catch{}y(process.cwd())&&(this.log("Removed RuleMetric hooks from .github/hooks/"),e=!0),C(process.cwd())&&(this.log("Removed RuleMetric block from .agents/hooks.json"),e=!0),S()&&(this.log("Removed RuleMetric block from ~/.gemini/config/hooks.json"),e=!0),v(process.cwd())&&(this.log("Removed proxy config from .vscode/settings.json"),e=!0),x()&&(this.log("Removed proxy config from VS Code user settings"),e=!0),k()&&(this.log("Removed proxy config from Cursor user settings"),e=!0),R()&&(this.log("Removed HTTPS_PROXY LaunchAgent"),e=!0),m&&n(r)&&(this.log("Removing the mitmproxy CA from the system trust store (requires sudo)..."),N()?this.log("[OK] mitmproxy CA untrusted."):(this.log("[!!] Could not untrust the CA automatically. Remove it manually:"),process.platform==="darwin"?this.log(` sudo security remove-trusted-cert -d ${r}`):process.platform==="linux"&&this.log(" sudo rm -f /usr/local/share/ca-certificates/mitmproxy-ca.crt && sudo update-ca-certificates --fresh"))),d()&&this.log("Gateway stopped.")}};export{u as default};
@@ -1 +1 @@
1
- import{a as p}from"../chunk-LQRYQE6Q.js";import"../chunk-IZTIYR5Q.js";import"../chunk-CRAKDQ4H.js";import"../chunk-WPJ2BND4.js";import"../chunk-3AV3GTMP.js";import{e as c}from"../chunk-TIQ7DQ3M.js";import"../chunk-M6AJDVCL.js";import{a}from"../chunk-ZLLER3HP.js";import*as o from"node:fs";import*as m from"node:path";import{Args as g,Flags as i}from"@oclif/core";var n=class f extends p{static{a(this,"Import")}static description="Import an existing config file as a RuleMetric instruction";static examples=["<%= config.bin %> import .cursorrules",'<%= config.bin %> import CLAUDE.md --format claude-md --name "My Rules"'];static args={file:g.string({description:"Path to file to import",required:!0})};static flags={format:i.string({description:"Source format (auto-detected if not provided)"}),name:i.string({char:"n",description:"Override instruction name"}),scope:i.string({char:"s",description:"Instruction scope",options:["org","team","project","personal"],default:"personal"}),"scope-ref":i.string({description:"Scope reference UUID"}),tags:i.string({char:"t",description:"Comma-separated tags"})};async run(){let{args:s,flags:t}=await this.parse(f);this.requireAuth(),o.existsSync(s.file)||this.error(`File not found: ${s.file}`);let d=o.readFileSync(s.file,"utf-8"),l=m.basename(s.file),r={content:d,filename:l,scope:t.scope};t.format&&(r.sourceFormat=t.format),t.name&&(r.name=t.name),t["scope-ref"]&&(r.scopeRef=t["scope-ref"]),t.tags&&(r.tags=t.tags.split(",").map(u=>u.trim()));let e=await c("/api/instructions/import",r);this.log(`Imported ${e.sourceFormat} as instruction: ${e.instruction.name} (${e.instruction.id})`),e.parseWarnings.length>0&&this.warn(`Warnings: ${e.parseWarnings.join(", ")}`)}};export{n as default};
1
+ import{a as p}from"../chunk-PPKPCXJD.js";import"../chunk-IZTIYR5Q.js";import"../chunk-V44SRRYR.js";import"../chunk-U6XEU573.js";import"../chunk-VLOX6KOM.js";import"../chunk-3AV3GTMP.js";import{f as c}from"../chunk-H2ORWIEY.js";import"../chunk-O6C2UGBY.js";import{a}from"../chunk-ZLLER3HP.js";import*as o from"node:fs";import*as m from"node:path";import{Args as g,Flags as i}from"@oclif/core";var n=class f extends p{static{a(this,"Import")}static description="Import an existing config file as a RuleMetric instruction";static examples=["<%= config.bin %> import .cursorrules",'<%= config.bin %> import CLAUDE.md --format claude-md --name "My Rules"'];static args={file:g.string({description:"Path to file to import",required:!0})};static flags={format:i.string({description:"Source format (auto-detected if not provided)"}),name:i.string({char:"n",description:"Override instruction name"}),scope:i.string({char:"s",description:"Instruction scope",options:["org","team","project","personal"],default:"personal"}),"scope-ref":i.string({description:"Scope reference UUID"}),tags:i.string({char:"t",description:"Comma-separated tags"})};async run(){let{args:s,flags:t}=await this.parse(f);this.requireAuth(),o.existsSync(s.file)||this.error(`File not found: ${s.file}`);let d=o.readFileSync(s.file,"utf-8"),l=m.basename(s.file),r={content:d,filename:l,scope:t.scope};t.format&&(r.sourceFormat=t.format),t.name&&(r.name=t.name),t["scope-ref"]&&(r.scopeRef=t["scope-ref"]),t.tags&&(r.tags=t.tags.split(",").map(u=>u.trim()));let e=await c("/api/instructions/import",r);this.log(`Imported ${e.sourceFormat} as instruction: ${e.instruction.name} (${e.instruction.id})`),e.parseWarnings.length>0&&this.warn(`Warnings: ${e.parseWarnings.join(", ")}`)}};export{n as default};
@@ -1 +1 @@
1
- import{a as d}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{e as p}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.js";import{a as f}from"../../chunk-ZLLER3HP.js";import*as r from"node:fs";import{Args as m,Flags as e}from"@oclif/core";var c=class u extends d{static{f(this,"InstructionsCreate")}static description="Create a new instruction";static examples=['<%= config.bin %> instructions create ./my-instruction.md --name "My Rules"','<%= config.bin %> instructions create ./rules.md -n "Rules" -s project'];static args={file:m.string({description:"Path to markdown file"})};static flags={name:e.string({char:"n",description:"Instruction name",required:!0}),description:e.string({char:"d",description:"Instruction description",required:!0}),scope:e.string({char:"s",description:"Instruction scope",options:["org","team","project","personal"],default:"personal"}),"scope-ref":e.string({description:"Scope reference UUID"}),tags:e.string({char:"t",description:"Comma-separated tags"})};async run(){let{args:i,flags:t}=await this.parse(u);this.requireAuth();let n;if(i.file)r.existsSync(i.file)||this.error(`File not found: ${i.file}`),n=r.readFileSync(i.file,"utf-8");else{this.log("No file provided. Paste content (Ctrl+D to finish):");let s=[];for await(let l of process.stdin)s.push(l);n=Buffer.concat(s).toString("utf-8")}let o={name:t.name,description:t.description,scope:t.scope,content:n};t["scope-ref"]&&(o.scopeRef=t["scope-ref"]),t.tags&&(o.tags=t.tags.split(",").map(s=>s.trim()));let a=await p("/api/instructions",o);this.log(`Created instruction: ${a.name} (${a.id})`)}};export{c as default};
1
+ import{a as p}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{f}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as d}from"../../chunk-ZLLER3HP.js";import*as s from"node:fs";import{Args as m,Flags as t}from"@oclif/core";var c=class u extends p{static{d(this,"InstructionsCreate")}static description="Create a new instruction";static examples=['<%= config.bin %> instructions create ./my-instruction.md --name "My Rules" --description "Team coding rules"','<%= config.bin %> instructions create ./rules.md -n "Rules" -d "Project rules" -s project'];static args={file:m.string({description:"Path to markdown file"})};static flags={name:t.string({char:"n",description:"Instruction name",required:!0}),description:t.string({char:"d",description:"Instruction description",required:!0}),scope:t.string({char:"s",description:"Instruction scope",options:["org","team","project","personal"],default:"personal"}),"scope-ref":t.string({description:"Scope reference UUID"}),tags:t.string({char:"t",description:"Comma-separated tags"})};async run(){let{args:i,flags:e}=await this.parse(u);this.requireAuth();let n;if(i.file)s.existsSync(i.file)||this.error(`File not found: ${i.file}`),n=s.readFileSync(i.file,"utf-8");else{this.log("No file provided. Paste content (Ctrl+D to finish):");let r=[];for await(let l of process.stdin)r.push(l);n=Buffer.concat(r).toString("utf-8")}let o={name:e.name,description:e.description,scope:e.scope,content:n};e["scope-ref"]&&(o.scopeRef=e["scope-ref"]),e.tags&&(o.tags=e.tags.split(",").map(r=>r.trim()));let a=await f("/api/instructions",o);this.log(`Created instruction: ${a.name} (${a.id})`)}};export{c as default};
@@ -1 +1 @@
1
- import{a}from"../../chunk-WLVQJH4E.js";import{a as s}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{d as r,h as n}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.js";import{a as o}from"../../chunk-ZLLER3HP.js";import{Args as f,Flags as p}from"@oclif/core";var t=class c extends s{static{o(this,"InstructionsDelete")}static description="Delete (archive) an instruction";static examples=["<%= config.bin %> instructions delete <id>","<%= config.bin %> instructions delete <id> --force"];static args={id:f.string({description:"Instruction ID",required:!0})};static flags={force:p.boolean({char:"f",description:"Skip confirmation prompt",default:!1})};async run(){let{args:i,flags:d}=await this.parse(c);this.requireAuth(),a(i.id,"instruction ID");let e=await r(`/api/instructions/${encodeURIComponent(i.id)}`);if(!d.force){let{confirm:m}=await import("@inquirer/prompts");if(!await m({message:`Are you sure you want to delete "${e.name}"?`,default:!1})){this.log("Cancelled.");return}}await n(`/api/instructions/${encodeURIComponent(i.id)}`),this.log(`Deleted instruction: ${e.name}`)}};export{t as default};
1
+ import{a}from"../../chunk-WLVQJH4E.js";import{a as s}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{e as r,i as n}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as o}from"../../chunk-ZLLER3HP.js";import{Args as f,Flags as p}from"@oclif/core";var t=class c extends s{static{o(this,"InstructionsDelete")}static description="Delete (archive) an instruction";static examples=["<%= config.bin %> instructions delete <id>","<%= config.bin %> instructions delete <id> --force"];static args={id:f.string({description:"Instruction ID",required:!0})};static flags={force:p.boolean({char:"f",description:"Skip confirmation prompt",default:!1})};async run(){let{args:i,flags:d}=await this.parse(c);this.requireAuth(),a(i.id,"instruction ID");let e=await r(`/api/instructions/${encodeURIComponent(i.id)}`);if(!d.force){let{confirm:m}=await import("@inquirer/prompts");if(!await m({message:`Are you sure you want to delete "${e.name}"?`,default:!1})){this.log("Cancelled.");return}}await n(`/api/instructions/${encodeURIComponent(i.id)}`),this.log(`Deleted instruction: ${e.name}`)}};export{t as default};
@@ -1 +1 @@
1
- import{a as s}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{e as o}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.js";import{a as t}from"../../chunk-ZLLER3HP.js";import{Args as a}from"@oclif/core";var i=class e extends s{static{t(this,"InstructionsFork")}static description="Fork an instruction to your personal scope";static examples=["<%= config.bin %> instructions fork <instruction-id>"];static args={id:a.string({description:"ID of the instruction to fork",required:!0})};async run(){let{args:n}=await this.parse(e);this.requireAuth();let r=await o(`/api/instructions/${n.id}/fork`,{});this.log(`Forked instruction: ${r.name} (${r.id})`)}};export{i as default};
1
+ import{a as s}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{f as o}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as t}from"../../chunk-ZLLER3HP.js";import{Args as a}from"@oclif/core";var i=class e extends s{static{t(this,"InstructionsFork")}static description="Fork an instruction to your personal scope";static examples=["<%= config.bin %> instructions fork <instruction-id>"];static args={id:a.string({description:"ID of the instruction to fork",required:!0})};async run(){let{args:n}=await this.parse(e);this.requireAuth();let r=await o(`/api/instructions/${n.id}/fork`,{});this.log(`Forked instruction: ${r.name} (${r.id})`)}};export{i as default};
@@ -1 +1 @@
1
- import{a as l}from"../../chunk-WLVQJH4E.js";import{a as i,c}from"../../chunk-W2MV25SB.js";import{a}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{d as n}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.js";import{a as e}from"../../chunk-ZLLER3HP.js";import{Args as g,Flags as m}from"@oclif/core";var o=class d extends a{static{e(this,"InstructionsGet")}static description="Get an instruction by ID";static examples=["<%= config.bin %> instructions get <id>","<%= config.bin %> instructions get <id> --format raw"];static enableJsonFlag=!0;static args={id:g.string({description:"Instruction ID",required:!0})};static flags={format:m.string({char:"f",description:"Output format",options:["yaml","json","raw"],default:"yaml"})};async run(){let{args:r,flags:s}=await this.parse(d);this.requireAuth(),l(r.id,"instruction ID");let t=await n(`/api/instructions/${encodeURIComponent(r.id)}`);return s.format==="json"?this.log(JSON.stringify(t,null,2)):s.format==="raw"?this.log(t.content):(this.log(`Name: ${t.name}`),this.log(`Description: ${t.description}`),this.log(`Scope: ${c(t.scope)}`),this.log(`Version: ${t.version}`),this.log(`Tags: ${(t.tags??[]).join(", ")||"(none)"}`),this.log(`Created: ${i(t.createdAt)}`),this.log(`Updated: ${i(t.updatedAt)}`),this.log(""),this.log("--- Content ---"),this.log(t.content)),t}};export{o as default};
1
+ import{a as l}from"../../chunk-WLVQJH4E.js";import{a as i,c}from"../../chunk-W2MV25SB.js";import{a}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{e as n}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.js";import{a as e}from"../../chunk-ZLLER3HP.js";import{Args as g,Flags as m}from"@oclif/core";var o=class d extends a{static{e(this,"InstructionsGet")}static description="Get an instruction by ID";static examples=["<%= config.bin %> instructions get <id>","<%= config.bin %> instructions get <id> --format raw"];static enableJsonFlag=!0;static args={id:g.string({description:"Instruction ID",required:!0})};static flags={format:m.string({char:"f",description:"Output format",options:["yaml","json","raw"],default:"yaml"})};async run(){let{args:r,flags:s}=await this.parse(d);this.requireAuth(),l(r.id,"instruction ID");let t=await n(`/api/instructions/${encodeURIComponent(r.id)}`);return s.format==="json"?this.log(JSON.stringify(t,null,2)):s.format==="raw"?this.log(t.content):(this.log(`Name: ${t.name}`),this.log(`Description: ${t.description}`),this.log(`Scope: ${c(t.scope)}`),this.log(`Version: ${t.version}`),this.log(`Tags: ${(t.tags??[]).join(", ")||"(none)"}`),this.log(`Created: ${i(t.createdAt)}`),this.log(`Updated: ${i(t.updatedAt)}`),this.log(""),this.log("--- Content ---"),this.log(t.content)),t}};export{o as default};
@@ -1 +1 @@
1
- import{a,b as n,c as m}from"../../chunk-W2MV25SB.js";import{a as s}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{d as i}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{e as i}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{e as i}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{f as i}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{e as s}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{f as s}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{d as s}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{e as s}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{d as n}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{e as n}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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-LQRYQE6Q.js";import"../chunk-IZTIYR5Q.js";import"../chunk-CRAKDQ4H.js";import"../chunk-WPJ2BND4.js";import"../chunk-3AV3GTMP.js";import"../chunk-TIQ7DQ3M.js";import"../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../chunk-IZTIYR5Q.js";import"../chunk-V44SRRYR.js";import"../chunk-U6XEU573.js";import"../chunk-VLOX6KOM.js";import"../chunk-3AV3GTMP.js";import"../chunk-H2ORWIEY.js";import"../chunk-O6C2UGBY.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{a as f}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import{a as c,b as t,c as l,d}from"../../chunk-3AV3GTMP.js";import{b as g,d as e}from"../../chunk-TIQ7DQ3M.js";import{g as a}from"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import{a as c,b as t,c as l,d}from"../../chunk-3AV3GTMP.js";import{b as g,e}from"../../chunk-H2ORWIEY.js";import{g as a}from"../../chunk-O6C2UGBY.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-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import{a as c}from"../../chunk-3AV3GTMP.js";import{d as g}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import{a as c}from"../../chunk-3AV3GTMP.js";import{e as g}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import{b as a,c as g}from"../../chunk-3AV3GTMP.js";import{d as s,g as e}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import{b as a,c as g}from"../../chunk-3AV3GTMP.js";import{e as s,h as e}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{e as s}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{f as s}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{e as i}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{f as i}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{e as n}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{f as n}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{e as o}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{f as o}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{d as e}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{e}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{d as a}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{e as a}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import{h as e}from"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import{i as e}from"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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{c as f}from"../../chunk-MVM6OGAF.js";import"../../chunk-KKDHD4XA.js";import"../../chunk-SZ62CP55.js";import{a as h}from"../../chunk-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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{c as f}from"../../chunk-MVM6OGAF.js";import"../../chunk-KKDHD4XA.js";import"../../chunk-SZ62CP55.js";import{a as h}from"../../chunk-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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-LQRYQE6Q.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-CRAKDQ4H.js";import"../../chunk-WPJ2BND4.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-TIQ7DQ3M.js";import"../../chunk-M6AJDVCL.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-PPKPCXJD.js";import"../../chunk-IZTIYR5Q.js";import"../../chunk-V44SRRYR.js";import"../../chunk-U6XEU573.js";import"../../chunk-VLOX6KOM.js";import"../../chunk-3AV3GTMP.js";import"../../chunk-H2ORWIEY.js";import"../../chunk-O6C2UGBY.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};