@rulemetric/cli 0.7.2 → 0.7.4

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 (547) hide show
  1. package/dist/base-command.js +1 -14
  2. package/dist/chunk-2TC6WCUT.js +34 -0
  3. package/dist/chunk-2UC3ULIG.js +1 -0
  4. package/dist/chunk-3AV3GTMP.js +1 -0
  5. package/dist/chunk-4Z5ECCJE.js +1 -0
  6. package/dist/chunk-5RBLIVBF.js +1 -0
  7. package/dist/chunk-67QCYUJU.js +1 -0
  8. package/dist/chunk-6QKI756T.js +2 -0
  9. package/dist/chunk-6V4WM73L.js +1 -0
  10. package/dist/chunk-6XEC6474.js +1 -0
  11. package/dist/chunk-72XLQE3X.js +2 -0
  12. package/dist/chunk-7DFNBRLY.js +61 -0
  13. package/dist/chunk-7XQ4VPLC.js +2 -0
  14. package/dist/chunk-AHRHCERJ.js +1 -0
  15. package/dist/chunk-ARNZQBMX.js +1 -0
  16. package/dist/chunk-CADKBP3D.js +58 -0
  17. package/dist/chunk-CDI5CCHU.js +1 -0
  18. package/dist/chunk-CNQ5DTNC.js +1 -0
  19. package/dist/chunk-CRAKDQ4H.js +1 -0
  20. package/dist/chunk-DNF4HDI6.js +14 -0
  21. package/dist/chunk-DSO2U4Y6.js +56 -0
  22. package/dist/chunk-DT4GKEP5.js +5 -0
  23. package/dist/chunk-DVN7GFJG.js +1 -0
  24. package/dist/chunk-E4SFUPYR.js +15 -0
  25. package/dist/chunk-EUHNCVJQ.js +33 -0
  26. package/dist/chunk-F2VP4B4J.js +1 -0
  27. package/dist/chunk-FEHM5OKW.js +1 -0
  28. package/dist/chunk-FHVBTDBM.js +69 -0
  29. package/dist/chunk-GBMF3TP6.js +1 -0
  30. package/dist/chunk-GY5IJ4RS.js +1 -0
  31. package/dist/chunk-HOHD5HY2.js +5 -0
  32. package/dist/chunk-HP2BUPGS.js +24 -0
  33. package/dist/{chunk-OQBBVTDG.js → chunk-I2DZGJRR.js} +6 -71
  34. package/dist/chunk-I4YJ7NTX.js +1 -0
  35. package/dist/chunk-IY5NXR3N.js +1 -0
  36. package/dist/chunk-IZTIYR5Q.js +2 -0
  37. package/dist/chunk-KKDHD4XA.js +2 -0
  38. package/dist/chunk-LQRYQE6Q.js +4 -0
  39. package/dist/chunk-M6AJDVCL.js +5 -0
  40. package/dist/chunk-MGHFDHHM.js +1 -0
  41. package/dist/chunk-ML36XQW7.js +1 -0
  42. package/dist/chunk-MODXEGCU.js +1 -0
  43. package/dist/chunk-MVM6OGAF.js +4 -0
  44. package/dist/chunk-N7ODX6PO.js +1 -0
  45. package/dist/chunk-NBTC5FNV.js +1 -0
  46. package/dist/chunk-NJ5UED3H.js +1 -0
  47. package/dist/chunk-NVKX36YN.js +3 -0
  48. package/dist/chunk-NVOTOQBA.js +1 -0
  49. package/dist/chunk-O7ZMHCMG.js +31 -0
  50. package/dist/chunk-OMXUK4M6.js +1 -0
  51. package/dist/chunk-PZS2KOU7.js +1 -0
  52. package/dist/chunk-RSKQRVPJ.js +1 -0
  53. package/dist/chunk-RTEATXTP.js +1 -0
  54. package/dist/chunk-RTWRHIKY.js +7 -0
  55. package/dist/chunk-RVO4HV3M.js +1 -0
  56. package/dist/chunk-SBILN45P.js +1 -0
  57. package/dist/chunk-SZ62CP55.js +1 -0
  58. package/dist/chunk-T3W5N3BP.js +2 -0
  59. package/dist/chunk-TDD7IOV2.js +1 -0
  60. package/dist/chunk-TIQ7DQ3M.js +1 -0
  61. package/dist/chunk-TU2AR6XO.js +1 -0
  62. package/dist/chunk-UF6US7VU.js +1 -0
  63. package/dist/chunk-V5QFOF4F.js +9 -0
  64. package/dist/chunk-V5U3E4BZ.js +1 -0
  65. package/dist/chunk-VAFAH6QL.js +1 -0
  66. package/dist/chunk-VMWY7KHH.js +1 -0
  67. package/dist/chunk-VUGRXM7R.js +1 -0
  68. package/dist/{chunk-XZXS2W24.js → chunk-VWEXKDWG.js} +10 -56
  69. package/dist/chunk-W2MV25SB.js +1 -0
  70. package/dist/chunk-WJ3H73G6.js +1 -0
  71. package/dist/chunk-WJUQBMTF.js +9 -0
  72. package/dist/chunk-WLVQJH4E.js +1 -0
  73. package/dist/chunk-WPJ2BND4.js +1 -0
  74. package/dist/chunk-WSCK4WNK.js +1 -0
  75. package/dist/chunk-Y65CSJFF.js +3 -0
  76. package/dist/chunk-ZL4MZMUK.js +34 -0
  77. package/dist/chunk-ZLLER3HP.js +1 -0
  78. package/dist/chunk-ZXF5NE54.js +1 -0
  79. package/dist/commands/antigravity/backfill.js +2 -136
  80. package/dist/commands/auth/create-key.js +1 -52
  81. package/dist/commands/auth/login.js +1 -85
  82. package/dist/commands/auth/logout.js +1 -29
  83. package/dist/commands/auth/revoke-key.js +1 -33
  84. package/dist/commands/auth/signup.js +1 -89
  85. package/dist/commands/auth/status.js +1 -42
  86. package/dist/commands/catalog/index.js +2 -52
  87. package/dist/commands/catalog/recommend.js +3 -43
  88. package/dist/commands/convert.js +1 -75
  89. package/dist/commands/converters.js +1 -54
  90. package/dist/commands/crons/list.js +1 -41
  91. package/dist/commands/crons/run.js +2 -76
  92. package/dist/commands/dashboard.js +1 -46
  93. package/dist/commands/diagnostics.js +1 -117
  94. package/dist/commands/eval-targets/create.js +1 -53
  95. package/dist/commands/eval-targets/list.js +1 -54
  96. package/dist/commands/evals/agent.js +3 -309
  97. package/dist/commands/evals/benchmark.js +6 -73
  98. package/dist/commands/evals/compare.js +13 -96
  99. package/dist/commands/evals/create.js +1 -67
  100. package/dist/commands/evals/optimize-description.js +25 -239
  101. package/dist/commands/evals/optimize.js +5 -211
  102. package/dist/commands/evals/run.js +3 -183
  103. package/dist/commands/gateway/ensure.js +1 -104
  104. package/dist/commands/hooks/emit-instructions.js +1 -25
  105. package/dist/commands/hooks/install.js +1 -442
  106. package/dist/commands/hooks/run.js +3 -81
  107. package/dist/commands/hooks/uninstall.js +2 -156
  108. package/dist/commands/import.js +1 -66
  109. package/dist/commands/instructions/create.js +1 -74
  110. package/dist/commands/instructions/delete.js +1 -55
  111. package/dist/commands/instructions/fork.js +1 -34
  112. package/dist/commands/instructions/get.js +1 -68
  113. package/dist/commands/instructions/list.js +1 -65
  114. package/dist/commands/instructions/promote.js +1 -42
  115. package/dist/commands/instructions/pull.js +1 -39
  116. package/dist/commands/instructions/upstream.js +1 -38
  117. package/dist/commands/instructions/versions.js +1 -53
  118. package/dist/commands/launcher.js +1 -40
  119. package/dist/commands/org/current.js +1 -77
  120. package/dist/commands/org/list.js +1 -52
  121. package/dist/commands/org/switch.js +1 -71
  122. package/dist/commands/packs/add-instruction.js +1 -37
  123. package/dist/commands/packs/apply.js +1 -39
  124. package/dist/commands/packs/create.js +1 -50
  125. package/dist/commands/packs/fork.js +1 -34
  126. package/dist/commands/packs/get.js +3 -56
  127. package/dist/commands/packs/list.js +1 -66
  128. package/dist/commands/packs/remove-instruction.js +1 -35
  129. package/dist/commands/proxy/env.js +3 -131
  130. package/dist/commands/proxy/logs.js +3 -85
  131. package/dist/commands/proxy/restart.js +1 -35
  132. package/dist/commands/proxy/setup.js +15 -454
  133. package/dist/commands/proxy/start.js +10 -333
  134. package/dist/commands/proxy/status.js +1 -78
  135. package/dist/commands/proxy/stop.js +1 -94
  136. package/dist/commands/research/backfill.js +1 -59
  137. package/dist/commands/research/tail-transcript.js +1 -70
  138. package/dist/commands/service/install.js +57 -781
  139. package/dist/commands/service/status.js +1 -180
  140. package/dist/commands/service/uninstall.js +1 -119
  141. package/dist/commands/sessions/analyze.js +3 -48
  142. package/dist/commands/sessions/end.js +2 -85
  143. package/dist/commands/sessions/import.js +1 -46
  144. package/dist/commands/sessions/list.js +1 -48
  145. package/dist/commands/sessions/start.js +3 -90
  146. package/dist/commands/setup.js +3 -150
  147. package/dist/commands/skills/export-approved.js +1 -46
  148. package/dist/commands/skills/install.js +4 -107
  149. package/dist/commands/skills/list.js +4 -65
  150. package/dist/commands/skills/publish.js +2 -98
  151. package/dist/commands/skills/search.js +3 -72
  152. package/dist/commands/skills/update.js +3 -55
  153. package/dist/commands/suggestions/accept.js +8 -84
  154. package/dist/commands/suggestions/dismiss.js +1 -45
  155. package/dist/commands/suggestions/list.js +1 -61
  156. package/dist/commands/suggestions/refresh.js +1 -27
  157. package/dist/cursor-T7AMCMKS.js +13 -0
  158. package/dist/dashboard/Dashboard.js +1 -243
  159. package/dist/dashboard/data.js +1 -15
  160. package/dist/dashboard/launcher/ActiveJobsList.js +1 -10
  161. package/dist/dashboard/launcher/LauncherOverlay.js +1 -16
  162. package/dist/dashboard/launcher/NewLaunchForm.js +1 -10
  163. package/dist/dashboard/launcher/api.js +1 -16
  164. package/dist/dashboard/launcher/tool-labels.js +1 -10
  165. package/dist/dashboard/launcher/types.js +0 -1
  166. package/dist/dashboard/launcher/useLaunchJobs.js +1 -11
  167. package/dist/dashboard/panels/friction.js +1 -10
  168. package/dist/dashboard/panels/insights.js +1 -10
  169. package/dist/dashboard/panels/instructions.js +1 -10
  170. package/dist/dashboard/panels/outcomes.js +1 -10
  171. package/dist/dashboard/panels/overview.js +1 -10
  172. package/dist/dashboard/panels/shared.js +1 -19
  173. package/dist/dashboard/types.js +1 -24
  174. package/dist/dist-FAVALJ5C.js +1 -0
  175. package/dist/index.js +1 -8
  176. package/dist/lib/active-org-refresh.js +1 -15
  177. package/dist/lib/active-org.js +1 -16
  178. package/dist/lib/agent-loop.js +1 -46
  179. package/dist/lib/antigravity-transcript.js +1 -22
  180. package/dist/lib/api-client.js +1 -23
  181. package/dist/lib/auth.js +1 -30
  182. package/dist/lib/capture-hosts.js +1 -8
  183. package/dist/lib/detect-languages.js +1 -8
  184. package/dist/lib/detect-tmux.js +1 -9
  185. package/dist/lib/diagnostics.js +1 -12
  186. package/dist/lib/editor-proxy-pins.js +1 -14
  187. package/dist/lib/ensure-api-key.js +1 -11
  188. package/dist/lib/eval-analyzer.js +1 -9
  189. package/dist/lib/eval-benchmark.js +1 -12
  190. package/dist/lib/eval-conversation-handler.js +1 -13
  191. package/dist/lib/eval-executor.js +1 -8
  192. package/dist/lib/eval-grader.js +1 -9
  193. package/dist/lib/eval-meta-judge.js +1 -9
  194. package/dist/lib/eval-trigger-tester.js +1 -11
  195. package/dist/lib/eval-worktree.js +1 -8
  196. package/dist/lib/gateway-entry.js +1 -61
  197. package/dist/lib/gateway-identity.js +1 -16
  198. package/dist/lib/gateway-lifecycle.js +1 -32
  199. package/dist/lib/gateway.js +1 -14
  200. package/dist/lib/handlers/cron-refresh-pricing.js +1 -0
  201. package/dist/lib/handlers/cron-refresh-skills.js +1 -8
  202. package/dist/lib/handlers/cron-suggest-instructions.js +1 -15
  203. package/dist/lib/handlers/process-announcement.js +1 -11
  204. package/dist/lib/handlers/process-changelog.js +1 -11
  205. package/dist/lib/handlers/process-conversation.js +1 -14
  206. package/dist/lib/handlers/process-eval.js +1 -15
  207. package/dist/lib/handlers/process-insights.js +1 -14
  208. package/dist/lib/handlers/process-launch.js +1 -16
  209. package/dist/lib/handlers/process-run-cleanup.js +1 -13
  210. package/dist/lib/handlers/process-send-message.js +1 -10
  211. package/dist/lib/handlers/process-session-goal.js +1 -11
  212. package/dist/lib/hooks-config.js +1 -81
  213. package/dist/lib/insights-prompts.js +1 -12
  214. package/dist/lib/instruction-snapshot.js +1 -8
  215. package/dist/lib/job-helpers.js +0 -1
  216. package/dist/lib/llm-client.js +1 -17
  217. package/dist/lib/manual-tasks-meta.js +1 -8
  218. package/dist/lib/manual-tasks.js +1 -79
  219. package/dist/lib/output.js +1 -12
  220. package/dist/lib/permanent-job-error.js +1 -10
  221. package/dist/lib/pid-identity.js +1 -14
  222. package/dist/lib/proxy-respawn.js +1 -12
  223. package/dist/lib/research-client.js +1 -12
  224. package/dist/lib/setup-steps.js +1 -33
  225. package/dist/lib/skills-loader.js +1 -8
  226. package/dist/lib/statusline-shim.js +1 -20
  227. package/dist/lib/telemetry.js +1 -16
  228. package/dist/lib/terminal-target-heartbeat.js +1 -15
  229. package/dist/lib/tmux.js +1 -16
  230. package/dist/lib/transcript-rate-limit-watcher.js +1 -22
  231. package/dist/lib/types.js +1 -8
  232. package/dist/lib/version-check.js +1 -12
  233. package/dist/lib/which.js +1 -8
  234. package/dist/lib/worktree.js +1 -17
  235. package/dist/opencode-QRJ3BH23.js +1 -0
  236. package/oclif.manifest.json +135 -135
  237. package/package.json +8 -7
  238. package/dist/base-command.js.map +0 -7
  239. package/dist/chunk-2HK7RGZB.js +0 -82
  240. package/dist/chunk-2HK7RGZB.js.map +0 -7
  241. package/dist/chunk-2ORJWTNZ.js +0 -307
  242. package/dist/chunk-2ORJWTNZ.js.map +0 -7
  243. package/dist/chunk-37LN5O7M.js +0 -59
  244. package/dist/chunk-37LN5O7M.js.map +0 -7
  245. package/dist/chunk-3S7223UR.js +0 -81
  246. package/dist/chunk-3S7223UR.js.map +0 -7
  247. package/dist/chunk-3TIMQ3O6.js +0 -96
  248. package/dist/chunk-3TIMQ3O6.js.map +0 -7
  249. package/dist/chunk-42GFSAJP.js +0 -32
  250. package/dist/chunk-42GFSAJP.js.map +0 -7
  251. package/dist/chunk-4BHDHHKL.js +0 -48
  252. package/dist/chunk-4BHDHHKL.js.map +0 -7
  253. package/dist/chunk-4D537GXE.js +0 -99
  254. package/dist/chunk-4D537GXE.js.map +0 -7
  255. package/dist/chunk-4LYCDS2N.js +0 -139
  256. package/dist/chunk-4LYCDS2N.js.map +0 -7
  257. package/dist/chunk-4SCZK7AL.js +0 -129
  258. package/dist/chunk-4SCZK7AL.js.map +0 -7
  259. package/dist/chunk-4XAWK6S2.js +0 -161
  260. package/dist/chunk-4XAWK6S2.js.map +0 -7
  261. package/dist/chunk-52WIYRZH.js +0 -73
  262. package/dist/chunk-52WIYRZH.js.map +0 -7
  263. package/dist/chunk-5BAOGNUH.js +0 -79
  264. package/dist/chunk-5BAOGNUH.js.map +0 -7
  265. package/dist/chunk-5EDMGK3W.js +0 -39
  266. package/dist/chunk-5EDMGK3W.js.map +0 -7
  267. package/dist/chunk-6NBS5XFS.js +0 -99
  268. package/dist/chunk-6NBS5XFS.js.map +0 -7
  269. package/dist/chunk-7DULPSFU.js +0 -299
  270. package/dist/chunk-7DULPSFU.js.map +0 -7
  271. package/dist/chunk-7LVVKQMZ.js +0 -98
  272. package/dist/chunk-7LVVKQMZ.js.map +0 -7
  273. package/dist/chunk-7NNFYWKK.js +0 -243
  274. package/dist/chunk-7NNFYWKK.js.map +0 -7
  275. package/dist/chunk-7NYKWN7U.js +0 -12
  276. package/dist/chunk-7NYKWN7U.js.map +0 -7
  277. package/dist/chunk-BO76WKJR.js +0 -42
  278. package/dist/chunk-BO76WKJR.js.map +0 -7
  279. package/dist/chunk-BRD5RUGM.js +0 -53
  280. package/dist/chunk-BRD5RUGM.js.map +0 -7
  281. package/dist/chunk-BT6Z6545.js +0 -43
  282. package/dist/chunk-BT6Z6545.js.map +0 -7
  283. package/dist/chunk-BZDKEQKU.js +0 -39
  284. package/dist/chunk-BZDKEQKU.js.map +0 -7
  285. package/dist/chunk-DGHWRQXL.js +0 -17
  286. package/dist/chunk-DGHWRQXL.js.map +0 -7
  287. package/dist/chunk-DNKSVWMD.js +0 -108
  288. package/dist/chunk-DNKSVWMD.js.map +0 -7
  289. package/dist/chunk-DQ3KELXD.js +0 -74
  290. package/dist/chunk-DQ3KELXD.js.map +0 -7
  291. package/dist/chunk-DUJSRBLP.js +0 -122
  292. package/dist/chunk-DUJSRBLP.js.map +0 -7
  293. package/dist/chunk-E3BIT53W.js +0 -154
  294. package/dist/chunk-E3BIT53W.js.map +0 -7
  295. package/dist/chunk-EARWG4EV.js +0 -22
  296. package/dist/chunk-EARWG4EV.js.map +0 -7
  297. package/dist/chunk-EI5BHWXA.js +0 -1662
  298. package/dist/chunk-EI5BHWXA.js.map +0 -7
  299. package/dist/chunk-EJ3YAFDP.js +0 -37
  300. package/dist/chunk-EJ3YAFDP.js.map +0 -7
  301. package/dist/chunk-EKJ2CABV.js +0 -76
  302. package/dist/chunk-EKJ2CABV.js.map +0 -7
  303. package/dist/chunk-EKP32DLN.js +0 -16
  304. package/dist/chunk-EKP32DLN.js.map +0 -7
  305. package/dist/chunk-EYPAAGN5.js +0 -51
  306. package/dist/chunk-EYPAAGN5.js.map +0 -7
  307. package/dist/chunk-F5N6CLJJ.js +0 -1995
  308. package/dist/chunk-F5N6CLJJ.js.map +0 -7
  309. package/dist/chunk-FZKLLNDS.js +0 -228
  310. package/dist/chunk-FZKLLNDS.js.map +0 -7
  311. package/dist/chunk-GIUBARWS.js +0 -99
  312. package/dist/chunk-GIUBARWS.js.map +0 -7
  313. package/dist/chunk-GQNJO2P2.js +0 -102
  314. package/dist/chunk-GQNJO2P2.js.map +0 -7
  315. package/dist/chunk-IJGF2ETG.js +0 -68
  316. package/dist/chunk-IJGF2ETG.js.map +0 -7
  317. package/dist/chunk-ILYDELUE.js +0 -46
  318. package/dist/chunk-ILYDELUE.js.map +0 -7
  319. package/dist/chunk-J6QFW4LD.js +0 -55
  320. package/dist/chunk-J6QFW4LD.js.map +0 -7
  321. package/dist/chunk-J7N3DLH6.js +0 -117
  322. package/dist/chunk-J7N3DLH6.js.map +0 -7
  323. package/dist/chunk-JFDWKLQC.js +0 -23
  324. package/dist/chunk-JFDWKLQC.js.map +0 -7
  325. package/dist/chunk-JULOLTZS.js +0 -61
  326. package/dist/chunk-JULOLTZS.js.map +0 -7
  327. package/dist/chunk-KJKBDQ4D.js +0 -220
  328. package/dist/chunk-KJKBDQ4D.js.map +0 -7
  329. package/dist/chunk-KRBQLMOP.js +0 -41
  330. package/dist/chunk-KRBQLMOP.js.map +0 -7
  331. package/dist/chunk-LXKPNATC.js +0 -624
  332. package/dist/chunk-LXKPNATC.js.map +0 -7
  333. package/dist/chunk-NSBPE2FW.js +0 -17
  334. package/dist/chunk-NSBPE2FW.js.map +0 -7
  335. package/dist/chunk-OK3I555A.js +0 -243
  336. package/dist/chunk-OK3I555A.js.map +0 -7
  337. package/dist/chunk-OKWCKCPE.js +0 -414
  338. package/dist/chunk-OKWCKCPE.js.map +0 -7
  339. package/dist/chunk-OO7JDFS4.js +0 -157
  340. package/dist/chunk-OO7JDFS4.js.map +0 -7
  341. package/dist/chunk-OQBBVTDG.js.map +0 -7
  342. package/dist/chunk-OQSQC7VB.js +0 -77
  343. package/dist/chunk-OQSQC7VB.js.map +0 -7
  344. package/dist/chunk-PED7L5GX.js +0 -92
  345. package/dist/chunk-PED7L5GX.js.map +0 -7
  346. package/dist/chunk-PMI56ED5.js +0 -167
  347. package/dist/chunk-PMI56ED5.js.map +0 -7
  348. package/dist/chunk-QJQS6TUN.js +0 -44
  349. package/dist/chunk-QJQS6TUN.js.map +0 -7
  350. package/dist/chunk-QN34TGD3.js +0 -83
  351. package/dist/chunk-QN34TGD3.js.map +0 -7
  352. package/dist/chunk-QSN77T7C.js +0 -250
  353. package/dist/chunk-QSN77T7C.js.map +0 -7
  354. package/dist/chunk-R56PH7YE.js +0 -78
  355. package/dist/chunk-R56PH7YE.js.map +0 -7
  356. package/dist/chunk-RH7NHVSK.js +0 -16
  357. package/dist/chunk-RH7NHVSK.js.map +0 -7
  358. package/dist/chunk-RMTT4KDY.js +0 -191
  359. package/dist/chunk-RMTT4KDY.js.map +0 -7
  360. package/dist/chunk-RQ2TMLKG.js +0 -142
  361. package/dist/chunk-RQ2TMLKG.js.map +0 -7
  362. package/dist/chunk-SO3T35U7.js +0 -80
  363. package/dist/chunk-SO3T35U7.js.map +0 -7
  364. package/dist/chunk-UKMLICWS.js +0 -51
  365. package/dist/chunk-UKMLICWS.js.map +0 -7
  366. package/dist/chunk-W2YERO7E.js +0 -170
  367. package/dist/chunk-W2YERO7E.js.map +0 -7
  368. package/dist/chunk-W53GKIZQ.js +0 -50
  369. package/dist/chunk-W53GKIZQ.js.map +0 -7
  370. package/dist/chunk-WA4MWYRW.js +0 -254
  371. package/dist/chunk-WA4MWYRW.js.map +0 -7
  372. package/dist/chunk-XC6M4CSW.js +0 -44
  373. package/dist/chunk-XC6M4CSW.js.map +0 -7
  374. package/dist/chunk-XK42ZBDE.js +0 -23
  375. package/dist/chunk-XK42ZBDE.js.map +0 -7
  376. package/dist/chunk-XUV6DDBF.js +0 -124
  377. package/dist/chunk-XUV6DDBF.js.map +0 -7
  378. package/dist/chunk-XZXS2W24.js.map +0 -7
  379. package/dist/chunk-Y3WD5CSW.js +0 -49
  380. package/dist/chunk-Y3WD5CSW.js.map +0 -7
  381. package/dist/chunk-Y4BJXXYV.js +0 -148
  382. package/dist/chunk-Y4BJXXYV.js.map +0 -7
  383. package/dist/chunk-YNIH3KMU.js +0 -121
  384. package/dist/chunk-YNIH3KMU.js.map +0 -7
  385. package/dist/chunk-YOBA3NAM.js +0 -55
  386. package/dist/chunk-YOBA3NAM.js.map +0 -7
  387. package/dist/chunk-ZUJBM6HE.js +0 -125
  388. package/dist/chunk-ZUJBM6HE.js.map +0 -7
  389. package/dist/commands/antigravity/backfill.js.map +0 -7
  390. package/dist/commands/auth/create-key.js.map +0 -7
  391. package/dist/commands/auth/login.js.map +0 -7
  392. package/dist/commands/auth/logout.js.map +0 -7
  393. package/dist/commands/auth/revoke-key.js.map +0 -7
  394. package/dist/commands/auth/signup.js.map +0 -7
  395. package/dist/commands/auth/status.js.map +0 -7
  396. package/dist/commands/catalog/index.js.map +0 -7
  397. package/dist/commands/catalog/recommend.js.map +0 -7
  398. package/dist/commands/convert.js.map +0 -7
  399. package/dist/commands/converters.js.map +0 -7
  400. package/dist/commands/crons/list.js.map +0 -7
  401. package/dist/commands/crons/run.js.map +0 -7
  402. package/dist/commands/dashboard.js.map +0 -7
  403. package/dist/commands/diagnostics.js.map +0 -7
  404. package/dist/commands/eval-targets/create.js.map +0 -7
  405. package/dist/commands/eval-targets/list.js.map +0 -7
  406. package/dist/commands/evals/agent.js.map +0 -7
  407. package/dist/commands/evals/benchmark.js.map +0 -7
  408. package/dist/commands/evals/compare.js.map +0 -7
  409. package/dist/commands/evals/create.js.map +0 -7
  410. package/dist/commands/evals/optimize-description.js.map +0 -7
  411. package/dist/commands/evals/optimize.js.map +0 -7
  412. package/dist/commands/evals/run.js.map +0 -7
  413. package/dist/commands/gateway/ensure.js.map +0 -7
  414. package/dist/commands/hooks/emit-instructions.js.map +0 -7
  415. package/dist/commands/hooks/install.js.map +0 -7
  416. package/dist/commands/hooks/run.js.map +0 -7
  417. package/dist/commands/hooks/uninstall.js.map +0 -7
  418. package/dist/commands/import.js.map +0 -7
  419. package/dist/commands/instructions/create.js.map +0 -7
  420. package/dist/commands/instructions/delete.js.map +0 -7
  421. package/dist/commands/instructions/fork.js.map +0 -7
  422. package/dist/commands/instructions/get.js.map +0 -7
  423. package/dist/commands/instructions/list.js.map +0 -7
  424. package/dist/commands/instructions/promote.js.map +0 -7
  425. package/dist/commands/instructions/pull.js.map +0 -7
  426. package/dist/commands/instructions/upstream.js.map +0 -7
  427. package/dist/commands/instructions/versions.js.map +0 -7
  428. package/dist/commands/launcher.js.map +0 -7
  429. package/dist/commands/org/current.js.map +0 -7
  430. package/dist/commands/org/list.js.map +0 -7
  431. package/dist/commands/org/switch.js.map +0 -7
  432. package/dist/commands/packs/add-instruction.js.map +0 -7
  433. package/dist/commands/packs/apply.js.map +0 -7
  434. package/dist/commands/packs/create.js.map +0 -7
  435. package/dist/commands/packs/fork.js.map +0 -7
  436. package/dist/commands/packs/get.js.map +0 -7
  437. package/dist/commands/packs/list.js.map +0 -7
  438. package/dist/commands/packs/remove-instruction.js.map +0 -7
  439. package/dist/commands/proxy/env.js.map +0 -7
  440. package/dist/commands/proxy/logs.js.map +0 -7
  441. package/dist/commands/proxy/restart.js.map +0 -7
  442. package/dist/commands/proxy/setup.js.map +0 -7
  443. package/dist/commands/proxy/start.js.map +0 -7
  444. package/dist/commands/proxy/status.js.map +0 -7
  445. package/dist/commands/proxy/stop.js.map +0 -7
  446. package/dist/commands/research/backfill.js.map +0 -7
  447. package/dist/commands/research/tail-transcript.js.map +0 -7
  448. package/dist/commands/service/install.js.map +0 -7
  449. package/dist/commands/service/status.js.map +0 -7
  450. package/dist/commands/service/uninstall.js.map +0 -7
  451. package/dist/commands/sessions/analyze.js.map +0 -7
  452. package/dist/commands/sessions/end.js.map +0 -7
  453. package/dist/commands/sessions/import.js.map +0 -7
  454. package/dist/commands/sessions/list.js.map +0 -7
  455. package/dist/commands/sessions/start.js.map +0 -7
  456. package/dist/commands/setup.js.map +0 -7
  457. package/dist/commands/skills/export-approved.js.map +0 -7
  458. package/dist/commands/skills/install.js.map +0 -7
  459. package/dist/commands/skills/list.js.map +0 -7
  460. package/dist/commands/skills/publish.js.map +0 -7
  461. package/dist/commands/skills/search.js.map +0 -7
  462. package/dist/commands/skills/update.js.map +0 -7
  463. package/dist/commands/suggestions/accept.js.map +0 -7
  464. package/dist/commands/suggestions/dismiss.js.map +0 -7
  465. package/dist/commands/suggestions/list.js.map +0 -7
  466. package/dist/commands/suggestions/refresh.js.map +0 -7
  467. package/dist/cursor-BGQJ4CWI.js +0 -134
  468. package/dist/cursor-BGQJ4CWI.js.map +0 -7
  469. package/dist/dashboard/Dashboard.js.map +0 -7
  470. package/dist/dashboard/data.js.map +0 -7
  471. package/dist/dashboard/launcher/ActiveJobsList.js.map +0 -7
  472. package/dist/dashboard/launcher/LauncherOverlay.js.map +0 -7
  473. package/dist/dashboard/launcher/NewLaunchForm.js.map +0 -7
  474. package/dist/dashboard/launcher/api.js.map +0 -7
  475. package/dist/dashboard/launcher/tool-labels.js.map +0 -7
  476. package/dist/dashboard/launcher/types.js.map +0 -7
  477. package/dist/dashboard/launcher/useLaunchJobs.js.map +0 -7
  478. package/dist/dashboard/panels/friction.js.map +0 -7
  479. package/dist/dashboard/panels/insights.js.map +0 -7
  480. package/dist/dashboard/panels/instructions.js.map +0 -7
  481. package/dist/dashboard/panels/outcomes.js.map +0 -7
  482. package/dist/dashboard/panels/overview.js.map +0 -7
  483. package/dist/dashboard/panels/shared.js.map +0 -7
  484. package/dist/dashboard/types.js.map +0 -7
  485. package/dist/dist-UNYP5PJR.js +0 -56
  486. package/dist/dist-UNYP5PJR.js.map +0 -7
  487. package/dist/index.js.map +0 -7
  488. package/dist/lib/active-org-refresh.js.map +0 -7
  489. package/dist/lib/active-org.js.map +0 -7
  490. package/dist/lib/agent-loop.js.map +0 -7
  491. package/dist/lib/antigravity-transcript.js.map +0 -7
  492. package/dist/lib/api-client.js.map +0 -7
  493. package/dist/lib/auth.js.map +0 -7
  494. package/dist/lib/capture-hosts.js.map +0 -7
  495. package/dist/lib/detect-languages.js.map +0 -7
  496. package/dist/lib/detect-tmux.js.map +0 -7
  497. package/dist/lib/diagnostics.js.map +0 -7
  498. package/dist/lib/editor-proxy-pins.js.map +0 -7
  499. package/dist/lib/ensure-api-key.js.map +0 -7
  500. package/dist/lib/eval-analyzer.js.map +0 -7
  501. package/dist/lib/eval-benchmark.js.map +0 -7
  502. package/dist/lib/eval-conversation-handler.js.map +0 -7
  503. package/dist/lib/eval-executor.js.map +0 -7
  504. package/dist/lib/eval-grader.js.map +0 -7
  505. package/dist/lib/eval-meta-judge.js.map +0 -7
  506. package/dist/lib/eval-trigger-tester.js.map +0 -7
  507. package/dist/lib/eval-worktree.js.map +0 -7
  508. package/dist/lib/gateway-entry.js.map +0 -7
  509. package/dist/lib/gateway-identity.js.map +0 -7
  510. package/dist/lib/gateway-lifecycle.js.map +0 -7
  511. package/dist/lib/gateway.js.map +0 -7
  512. package/dist/lib/handlers/cron-refresh-skills.js.map +0 -7
  513. package/dist/lib/handlers/cron-suggest-instructions.js.map +0 -7
  514. package/dist/lib/handlers/process-announcement.js.map +0 -7
  515. package/dist/lib/handlers/process-changelog.js.map +0 -7
  516. package/dist/lib/handlers/process-conversation.js.map +0 -7
  517. package/dist/lib/handlers/process-eval.js.map +0 -7
  518. package/dist/lib/handlers/process-insights.js.map +0 -7
  519. package/dist/lib/handlers/process-launch.js.map +0 -7
  520. package/dist/lib/handlers/process-run-cleanup.js.map +0 -7
  521. package/dist/lib/handlers/process-send-message.js.map +0 -7
  522. package/dist/lib/handlers/process-session-goal.js.map +0 -7
  523. package/dist/lib/hooks-config.js.map +0 -7
  524. package/dist/lib/insights-prompts.js.map +0 -7
  525. package/dist/lib/instruction-snapshot.js.map +0 -7
  526. package/dist/lib/job-helpers.js.map +0 -7
  527. package/dist/lib/llm-client.js.map +0 -7
  528. package/dist/lib/manual-tasks-meta.js.map +0 -7
  529. package/dist/lib/manual-tasks.js.map +0 -7
  530. package/dist/lib/output.js.map +0 -7
  531. package/dist/lib/permanent-job-error.js.map +0 -7
  532. package/dist/lib/pid-identity.js.map +0 -7
  533. package/dist/lib/proxy-respawn.js.map +0 -7
  534. package/dist/lib/research-client.js.map +0 -7
  535. package/dist/lib/setup-steps.js.map +0 -7
  536. package/dist/lib/skills-loader.js.map +0 -7
  537. package/dist/lib/statusline-shim.js.map +0 -7
  538. package/dist/lib/telemetry.js.map +0 -7
  539. package/dist/lib/terminal-target-heartbeat.js.map +0 -7
  540. package/dist/lib/tmux.js.map +0 -7
  541. package/dist/lib/transcript-rate-limit-watcher.js.map +0 -7
  542. package/dist/lib/types.js.map +0 -7
  543. package/dist/lib/version-check.js.map +0 -7
  544. package/dist/lib/which.js.map +0 -7
  545. package/dist/lib/worktree.js.map +0 -7
  546. package/dist/opencode-IQ7X5YMJ.js +0 -190
  547. package/dist/opencode-IQ7X5YMJ.js.map +0 -7
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/lib/eval-executor.ts"],
4
- "sourcesContent": ["import { spawn } from 'node:child_process';\n\nexport interface EvalExecutorOptions {\n prompt: string;\n targetContent?: string;\n systemPrompt?: string; // alias for targetContent (used by grader/meta-judge)\n workDir?: string;\n timeout?: number; // ms, default 120_000\n model?: string;\n}\n\nexport interface EvalExecutorResult {\n output: string;\n exitCode: number | null;\n durationMs: number;\n totalTokens: number;\n error?: string;\n}\n\n/**\n * Executes a prompt via `claude -p` and captures the output.\n * Optionally injects target content as a system prompt.\n */\nexport async function executeEval(options: EvalExecutorOptions): Promise<EvalExecutorResult> {\n const {\n prompt,\n targetContent,\n systemPrompt,\n workDir = process.cwd(),\n timeout = 120_000,\n model,\n } = options;\n\n const args = ['-p', prompt, '--output-format', 'json'];\n const sysPrompt = targetContent ?? systemPrompt;\n if (sysPrompt) {\n args.push('--system-prompt', sysPrompt);\n }\n if (model) {\n args.push('--model', model);\n }\n\n const startTime = Date.now();\n\n return new Promise<EvalExecutorResult>((resolve) => {\n // Remove CLAUDECODE flag so spawned claude doesn't think it's a nested session.\n // Remove HTTPS_PROXY so eval runs bypass the capture proxy \u2014 these are internal\n // infrastructure calls, not user sessions. Routing through the proxy creates\n // phantom sessions that pollute insights.\n const env = { ...process.env };\n delete env.CLAUDECODE;\n delete env.HTTPS_PROXY;\n\n const proc = spawn('claude', args, {\n cwd: workDir,\n env,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n let stderr = '';\n\n proc.stdout.on('data', (data: Buffer) => {\n stdout += data.toString();\n });\n\n proc.stderr.on('data', (data: Buffer) => {\n stderr += data.toString();\n });\n\n const timer = setTimeout(() => {\n proc.kill('SIGTERM');\n resolve({\n output: stdout,\n exitCode: null,\n durationMs: Date.now() - startTime,\n totalTokens: 0,\n error: `Timed out after ${timeout}ms`,\n });\n }, timeout);\n\n proc.on('close', (code) => {\n clearTimeout(timer);\n const durationMs = Date.now() - startTime;\n\n // Try to parse JSON output for token usage\n let totalTokens = 0;\n let output = stdout;\n try {\n const parsed = JSON.parse(stdout);\n output = parsed.result ?? parsed.content ?? stdout;\n totalTokens = parsed.usage?.total_tokens\n ?? ((parsed.usage?.input_tokens ?? 0) + (parsed.usage?.output_tokens ?? 0));\n } catch {\n // stdout wasn't JSON, use raw text\n }\n\n resolve({\n output,\n exitCode: code,\n durationMs,\n totalTokens,\n error: code !== 0 ? stderr || `Exit code ${code}` : undefined,\n });\n });\n\n proc.on('error', (err) => {\n clearTimeout(timer);\n resolve({\n output: '',\n exitCode: null,\n durationMs: Date.now() - startTime,\n totalTokens: 0,\n error: `Failed to spawn claude: ${err.message}`,\n });\n });\n });\n}\n"],
5
- "mappings": ";AAAA,SAAS,aAAa;AAuBtB,eAAsB,YAAY,SAA2D;AAC3F,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU,QAAQ,IAAI;AAAA,IACtB,UAAU;AAAA,IACV;AAAA,EACF,IAAI;AAEJ,QAAM,OAAO,CAAC,MAAM,QAAQ,mBAAmB,MAAM;AACrD,QAAM,YAAY,iBAAiB;AACnC,MAAI,WAAW;AACb,SAAK,KAAK,mBAAmB,SAAS;AAAA,EACxC;AACA,MAAI,OAAO;AACT,SAAK,KAAK,WAAW,KAAK;AAAA,EAC5B;AAEA,QAAM,YAAY,KAAK,IAAI;AAE3B,SAAO,IAAI,QAA4B,CAAC,YAAY;AAKlD,UAAM,MAAM,EAAE,GAAG,QAAQ,IAAI;AAC7B,WAAO,IAAI;AACX,WAAO,IAAI;AAEX,UAAM,OAAO,MAAM,UAAU,MAAM;AAAA,MACjC,KAAK;AAAA,MACL;AAAA,MACA,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,IAClC,CAAC;AAED,QAAI,SAAS;AACb,QAAI,SAAS;AAEb,SAAK,OAAO,GAAG,QAAQ,CAAC,SAAiB;AACvC,gBAAU,KAAK,SAAS;AAAA,IAC1B,CAAC;AAED,SAAK,OAAO,GAAG,QAAQ,CAAC,SAAiB;AACvC,gBAAU,KAAK,SAAS;AAAA,IAC1B,CAAC;AAED,UAAM,QAAQ,WAAW,MAAM;AAC7B,WAAK,KAAK,SAAS;AACnB,cAAQ;AAAA,QACN,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,aAAa;AAAA,QACb,OAAO,mBAAmB,OAAO;AAAA,MACnC,CAAC;AAAA,IACH,GAAG,OAAO;AAEV,SAAK,GAAG,SAAS,CAAC,SAAS;AACzB,mBAAa,KAAK;AAClB,YAAM,aAAa,KAAK,IAAI,IAAI;AAGhC,UAAI,cAAc;AAClB,UAAI,SAAS;AACb,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,MAAM;AAChC,iBAAS,OAAO,UAAU,OAAO,WAAW;AAC5C,sBAAc,OAAO,OAAO,iBACrB,OAAO,OAAO,gBAAgB,MAAM,OAAO,OAAO,iBAAiB;AAAA,MAC5E,QAAQ;AAAA,MAER;AAEA,cAAQ;AAAA,QACN;AAAA,QACA,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA,OAAO,SAAS,IAAI,UAAU,aAAa,IAAI,KAAK;AAAA,MACtD,CAAC;AAAA,IACH,CAAC;AAED,SAAK,GAAG,SAAS,CAAC,QAAQ;AACxB,mBAAa,KAAK;AAClB,cAAQ;AAAA,QACN,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB,aAAa;AAAA,QACb,OAAO,2BAA2B,IAAI,OAAO;AAAA,MAC/C,CAAC;AAAA,IACH,CAAC;AAAA,EACH,CAAC;AACH;",
6
- "names": []
7
- }
@@ -1,250 +0,0 @@
1
- // ../../packages/email/dist/templates/changelog-announcement.js
2
- var ACCENT = "#5b6cff";
3
- var TEXT_PRIMARY = "#1a1a1a";
4
- var TEXT_MUTED = "#666666";
5
- var BG_OUTER = "#f5f5f7";
6
- var BG_CARD = "#ffffff";
7
- var BORDER = "#e5e5e9";
8
- var SECTION_ORDER = [
9
- "Added",
10
- "Changed",
11
- "Fixed",
12
- "Removed",
13
- "Deprecated",
14
- "Security"
15
- ];
16
- function formatIsoDate(iso) {
17
- const months = [
18
- "January",
19
- "February",
20
- "March",
21
- "April",
22
- "May",
23
- "June",
24
- "July",
25
- "August",
26
- "September",
27
- "October",
28
- "November",
29
- "December"
30
- ];
31
- const [y, m, d] = iso.split("-").map((s) => parseInt(s, 10));
32
- if (!y || !m || !d || m < 1 || m > 12)
33
- return iso;
34
- return `${months[m - 1]} ${d}, ${y}`;
35
- }
36
- function escapeHtml(s) {
37
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
38
- }
39
- function orderedSections(sections) {
40
- const out = [];
41
- for (const name of SECTION_ORDER) {
42
- const items = sections[name];
43
- if (items && items.length > 0) {
44
- out.push({ name, items });
45
- }
46
- }
47
- return out;
48
- }
49
- function renderChangelogAnnouncement(input) {
50
- const { version, date, sections, unsubscribeUrl, productUrl, recipientName } = input;
51
- const formattedDate = formatIsoDate(date);
52
- const subject = `What's new in RuleMetric \u2014 ${formattedDate}`;
53
- const greeting = recipientName ? `Hi ${recipientName},` : "Hi there,";
54
- const ordered = orderedSections(sections);
55
- const year = (/* @__PURE__ */ new Date()).getUTCFullYear();
56
- const sectionsHtml = ordered.map(({ name, items }) => {
57
- const lis = items.map((it) => ` <li style="margin:0 0 6px 0;font-size:15px;line-height:1.5;color:${TEXT_PRIMARY};">${escapeHtml(it)}</li>`).join("\n");
58
- return ` <h3 style="margin:24px 0 8px 0;font-size:16px;line-height:1.3;font-weight:600;color:${TEXT_PRIMARY};">${name}</h3>
59
- <ul style="margin:0 0 8px 0;padding-left:20px;">
60
- ${lis}
61
- </ul>`;
62
- }).join("\n");
63
- const html = `<!doctype html>
64
- <html lang="en">
65
- <head>
66
- <meta charset="utf-8" />
67
- <meta name="viewport" content="width=device-width, initial-scale=1" />
68
- <title>${escapeHtml(subject)}</title>
69
- </head>
70
- <body style="margin:0;padding:0;background:${BG_OUTER};font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;color:${TEXT_PRIMARY};">
71
- <table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="background:${BG_OUTER};padding:32px 16px;">
72
- <tr>
73
- <td align="center">
74
- <table role="presentation" width="560" cellspacing="0" cellpadding="0" border="0" style="max-width:560px;background:${BG_CARD};border:1px solid ${BORDER};border-radius:8px;overflow:hidden;">
75
- <tr>
76
- <td style="padding:24px 32px 8px 32px;">
77
- <a href="${escapeHtml(productUrl)}" style="text-decoration:none;color:${ACCENT};font-size:14px;font-weight:600;">RuleMetric</a>
78
- </td>
79
- </tr>
80
- <tr>
81
- <td style="padding:8px 32px 8px 32px;">
82
- <h1 style="margin:0 0 8px 0;font-size:22px;line-height:1.3;font-weight:600;color:${TEXT_PRIMARY};">
83
- What's new \u2014 ${escapeHtml(formattedDate)}
84
- </h1>
85
- <p style="margin:0 0 8px 0;font-size:13px;line-height:1.5;color:${TEXT_MUTED};">
86
- Release ${escapeHtml(version)}
87
- </p>
88
- <p style="margin:16px 0 0 0;font-size:15px;line-height:1.5;color:${TEXT_PRIMARY};">
89
- ${escapeHtml(greeting)}
90
- </p>
91
- <p style="margin:8px 0 0 0;font-size:15px;line-height:1.5;color:${TEXT_PRIMARY};">
92
- Here's what shipped in the latest RuleMetric release.
93
- </p>
94
- </td>
95
- </tr>
96
- <tr>
97
- <td style="padding:0 32px 16px 32px;">
98
- ${sectionsHtml}
99
- </td>
100
- </tr>
101
- <tr>
102
- <td style="padding:16px 32px 24px 32px;border-top:1px solid ${BORDER};">
103
- <p style="margin:0 0 8px 0;font-size:12px;line-height:1.5;color:${TEXT_MUTED};">
104
- You're receiving this because you signed up for RuleMetric product updates. If you'd rather not hear about new releases, you can unsubscribe at any time.
105
- </p>
106
- <p style="margin:0 0 4px 0;font-size:12px;line-height:1.5;">
107
- <a href="${escapeHtml(unsubscribeUrl)}" style="color:${ACCENT};text-decoration:underline;">Unsubscribe</a>
108
- </p>
109
- <p style="margin:0 0 12px 0;font-size:12px;line-height:1.5;color:${TEXT_MUTED};word-break:break-all;">
110
- ${escapeHtml(unsubscribeUrl)}
111
- </p>
112
- <p style="margin:0;font-size:11px;line-height:1.5;color:${TEXT_MUTED};">
113
- RuleMetric \u2022 ${year}
114
- </p>
115
- </td>
116
- </tr>
117
- </table>
118
- </td>
119
- </tr>
120
- </table>
121
- </body>
122
- </html>`;
123
- const textLines = [
124
- `What's new in RuleMetric \u2014 ${formattedDate}`,
125
- `Release ${version}`,
126
- "",
127
- greeting,
128
- "",
129
- `Here's what shipped in the latest RuleMetric release.`,
130
- ""
131
- ];
132
- for (const { name, items } of ordered) {
133
- textLines.push(`${name}:`);
134
- for (const it of items) {
135
- textLines.push(` - ${it}`);
136
- }
137
- textLines.push("");
138
- }
139
- textLines.push("--", `You're receiving this because you signed up for RuleMetric product updates.`, `Unsubscribe: ${unsubscribeUrl}`, "", `RuleMetric \u2022 ${year}`);
140
- const text = textLines.join("\n");
141
- return { subject, html, text };
142
- }
143
-
144
- // ../../packages/email/dist/providers/noop.js
145
- import { randomBytes } from "node:crypto";
146
- async function sendNoopEmail(params) {
147
- const keyNote = params.idempotencyKey ? ` idempotencyKey=${params.idempotencyKey}` : "";
148
- process.stderr.write(`[email:noop] would send to=${params.to} subject=${JSON.stringify(params.subject)}${keyNote}
149
- `);
150
- return {
151
- id: `noop-${randomBytes(8).toString("hex")}`,
152
- provider: "noop"
153
- };
154
- }
155
-
156
- // ../../packages/email/dist/providers/resend.js
157
- var cachedClient = null;
158
- async function getClient() {
159
- if (cachedClient)
160
- return cachedClient;
161
- const apiKey = process.env.RESEND_API_KEY;
162
- if (!apiKey) {
163
- throw new Error("RESEND_API_KEY is not set");
164
- }
165
- const { Resend } = await import("resend");
166
- cachedClient = new Resend(apiKey);
167
- return cachedClient;
168
- }
169
- async function sendResendEmail(params) {
170
- const fromName = params.fromName ?? "RuleMetric";
171
- const fromEmail = process.env.RESEND_FROM_EMAIL ?? "onboarding@resend.dev";
172
- const from = `${fromName} <${fromEmail}>`;
173
- const client = await getClient();
174
- const options = params.idempotencyKey ? { idempotencyKey: params.idempotencyKey } : void 0;
175
- const result = await client.emails.send({
176
- from,
177
- to: params.to,
178
- subject: params.subject,
179
- html: params.html,
180
- text: params.text
181
- }, options);
182
- if (result.error) {
183
- throw new Error(`Resend send failed: ${result.error.message}`);
184
- }
185
- if (!result.data) {
186
- throw new Error("Resend send returned no data and no error");
187
- }
188
- return { id: result.data.id, provider: "resend" };
189
- }
190
-
191
- // ../../packages/email/dist/providers/smtp.js
192
- async function sendSmtpEmail(_params) {
193
- throw new Error("SMTP provider not implemented. Set RESEND_API_KEY to use Resend, or unset RULEMETRIC_EMAIL_PROVIDER to fall back to noop.");
194
- }
195
-
196
- // ../../packages/email/dist/index.js
197
- function selectEmailProvider() {
198
- const explicit = process.env.RULEMETRIC_EMAIL_PROVIDER;
199
- if (explicit === "resend" || explicit === "smtp" || explicit === "noop") {
200
- return explicit;
201
- }
202
- if (process.env.RESEND_API_KEY)
203
- return "resend";
204
- return "noop";
205
- }
206
- var RESERVED_TLDS = /* @__PURE__ */ new Set(["test", "example", "invalid", "localhost"]);
207
- var RESERVED_EXAMPLE_DOMAINS = /^example\.(com|net|org)$/;
208
- function isUndeliverableRecipient(to) {
209
- const addr = to.trim().toLowerCase();
210
- const at = addr.lastIndexOf("@");
211
- if (at < 0)
212
- return false;
213
- const domain = addr.slice(at + 1);
214
- if (!domain)
215
- return false;
216
- const tld = domain.slice(domain.lastIndexOf(".") + 1);
217
- if (RESERVED_TLDS.has(tld))
218
- return true;
219
- if (RESERVED_EXAMPLE_DOMAINS.test(domain))
220
- return true;
221
- return false;
222
- }
223
- var providerLogged = false;
224
- async function sendEmail(params) {
225
- const provider = selectEmailProvider();
226
- if (!providerLogged) {
227
- providerLogged = true;
228
- process.stderr.write(`[email] active provider: ${provider}
229
- `);
230
- }
231
- switch (provider) {
232
- case "resend":
233
- if (isUndeliverableRecipient(params.to)) {
234
- process.stderr.write(`[email] skipping real send to reserved/undeliverable address ${params.to} (RFC 2606/6761) \u2014 routed to noop to protect sender reputation
235
- `);
236
- return sendNoopEmail(params);
237
- }
238
- return sendResendEmail(params);
239
- case "smtp":
240
- return sendSmtpEmail(params);
241
- case "noop":
242
- return sendNoopEmail(params);
243
- }
244
- }
245
-
246
- export {
247
- renderChangelogAnnouncement,
248
- sendEmail
249
- };
250
- //# sourceMappingURL=chunk-QSN77T7C.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../../packages/email/src/templates/changelog-announcement.ts", "../../../packages/email/src/providers/noop.ts", "../../../packages/email/src/providers/resend.ts", "../../../packages/email/src/providers/smtp.ts", "../../../packages/email/src/index.ts"],
4
- "sourcesContent": ["// Product-announcement email template. Pure function \u2014 given a parsed\n// CHANGELOG entry, returns subject + html + text. No provider work, no\n// env reads, no IO.\n//\n// Design notes:\n// - Conventions mirror invitation.ts: inline styles only, viewport meta,\n// simple table layout, hand-rolled plain-text body, same colour palette.\n// - Section order is fixed (Added \u2192 Changed \u2192 Fixed \u2192 Removed \u2192\n// Deprecated \u2192 Security) regardless of insertion order in the input,\n// so a single deployment can't produce inconsistent ordering across\n// recipients.\n// - Footer carries the unsubscribe URL twice (styled link + raw text)\n// for CAN-SPAM compliance and because some clients suppress link\n// rendering.\n\nimport type { RenderedEmail } from './invitation.js';\n\nexport type ChangelogSectionName =\n | 'Added'\n | 'Changed'\n | 'Fixed'\n | 'Removed'\n | 'Deprecated'\n | 'Security';\n\nexport interface ChangelogAnnouncementInput {\n /** Verbatim version string from CHANGELOG, e.g. \"2026.06.05\". */\n version: string;\n /** ISO date YYYY-MM-DD. */\n date: string;\n /** Section name \u2192 array of bullet items. Items are plain text (no markdown). */\n sections: Partial<Record<ChangelogSectionName, string[]>>;\n /** Fully-qualified unsubscribe URL embedded in the footer. */\n unsubscribeUrl: string;\n /** Product home URL (e.g. https://rulemetric.com). For the header logo link. */\n productUrl: string;\n /** Optional recipient first name to personalize greeting; falls back to \"Hi there,\". */\n recipientName?: string;\n}\n\nconst ACCENT = '#5b6cff';\nconst TEXT_PRIMARY = '#1a1a1a';\nconst TEXT_MUTED = '#666666';\nconst BG_OUTER = '#f5f5f7';\nconst BG_CARD = '#ffffff';\nconst BORDER = '#e5e5e9';\n\n/** Documented render order for sections \u2014 applied regardless of input key order. */\nconst SECTION_ORDER: ChangelogSectionName[] = [\n 'Added',\n 'Changed',\n 'Fixed',\n 'Removed',\n 'Deprecated',\n 'Security',\n];\n\n/**\n * \"June 5, 2026\" \u2014 locale-independent format identical to invitation.ts.\n * Accepts an ISO YYYY-MM-DD string; parsed as UTC to avoid off-by-one in\n * recipient timezones west of the build server.\n */\nfunction formatIsoDate(iso: string): string {\n const months = [\n 'January', 'February', 'March', 'April', 'May', 'June',\n 'July', 'August', 'September', 'October', 'November', 'December',\n ];\n const [y, m, d] = iso.split('-').map((s) => parseInt(s, 10));\n // Defensive: if the input is malformed we still want a string. Fall back\n // to the raw ISO so the recipient at least sees something coherent.\n if (!y || !m || !d || m < 1 || m > 12) return iso;\n return `${months[m - 1]} ${d}, ${y}`;\n}\n\nfunction escapeHtml(s: string): string {\n return s\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#39;');\n}\n\n/** Returns sections in canonical order, dropping missing/empty ones. */\nfunction orderedSections(\n sections: ChangelogAnnouncementInput['sections'],\n): Array<{ name: ChangelogSectionName; items: string[] }> {\n const out: Array<{ name: ChangelogSectionName; items: string[] }> = [];\n for (const name of SECTION_ORDER) {\n const items = sections[name];\n if (items && items.length > 0) {\n out.push({ name, items });\n }\n }\n return out;\n}\n\nexport function renderChangelogAnnouncement(\n input: ChangelogAnnouncementInput,\n): RenderedEmail {\n const { version, date, sections, unsubscribeUrl, productUrl, recipientName } = input;\n\n const formattedDate = formatIsoDate(date);\n const subject = `What's new in RuleMetric \u2014 ${formattedDate}`;\n const greeting = recipientName ? `Hi ${recipientName},` : 'Hi there,';\n const ordered = orderedSections(sections);\n const year = new Date().getUTCFullYear();\n\n // \u2500\u2500 HTML sections \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const sectionsHtml = ordered\n .map(({ name, items }) => {\n const lis = items\n .map(\n (it) =>\n ` <li style=\"margin:0 0 6px 0;font-size:15px;line-height:1.5;color:${TEXT_PRIMARY};\">${escapeHtml(it)}</li>`,\n )\n .join('\\n');\n return ` <h3 style=\"margin:24px 0 8px 0;font-size:16px;line-height:1.3;font-weight:600;color:${TEXT_PRIMARY};\">${name}</h3>\n <ul style=\"margin:0 0 8px 0;padding-left:20px;\">\n${lis}\n </ul>`;\n })\n .join('\\n');\n\n // \u2500\u2500 HTML \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const html = `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>${escapeHtml(subject)}</title>\n </head>\n <body style=\"margin:0;padding:0;background:${BG_OUTER};font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;color:${TEXT_PRIMARY};\">\n <table role=\"presentation\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"background:${BG_OUTER};padding:32px 16px;\">\n <tr>\n <td align=\"center\">\n <table role=\"presentation\" width=\"560\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\" style=\"max-width:560px;background:${BG_CARD};border:1px solid ${BORDER};border-radius:8px;overflow:hidden;\">\n <tr>\n <td style=\"padding:24px 32px 8px 32px;\">\n <a href=\"${escapeHtml(productUrl)}\" style=\"text-decoration:none;color:${ACCENT};font-size:14px;font-weight:600;\">RuleMetric</a>\n </td>\n </tr>\n <tr>\n <td style=\"padding:8px 32px 8px 32px;\">\n <h1 style=\"margin:0 0 8px 0;font-size:22px;line-height:1.3;font-weight:600;color:${TEXT_PRIMARY};\">\n What's new \u2014 ${escapeHtml(formattedDate)}\n </h1>\n <p style=\"margin:0 0 8px 0;font-size:13px;line-height:1.5;color:${TEXT_MUTED};\">\n Release ${escapeHtml(version)}\n </p>\n <p style=\"margin:16px 0 0 0;font-size:15px;line-height:1.5;color:${TEXT_PRIMARY};\">\n ${escapeHtml(greeting)}\n </p>\n <p style=\"margin:8px 0 0 0;font-size:15px;line-height:1.5;color:${TEXT_PRIMARY};\">\n Here's what shipped in the latest RuleMetric release.\n </p>\n </td>\n </tr>\n <tr>\n <td style=\"padding:0 32px 16px 32px;\">\n${sectionsHtml}\n </td>\n </tr>\n <tr>\n <td style=\"padding:16px 32px 24px 32px;border-top:1px solid ${BORDER};\">\n <p style=\"margin:0 0 8px 0;font-size:12px;line-height:1.5;color:${TEXT_MUTED};\">\n You're receiving this because you signed up for RuleMetric product updates. If you'd rather not hear about new releases, you can unsubscribe at any time.\n </p>\n <p style=\"margin:0 0 4px 0;font-size:12px;line-height:1.5;\">\n <a href=\"${escapeHtml(unsubscribeUrl)}\" style=\"color:${ACCENT};text-decoration:underline;\">Unsubscribe</a>\n </p>\n <p style=\"margin:0 0 12px 0;font-size:12px;line-height:1.5;color:${TEXT_MUTED};word-break:break-all;\">\n ${escapeHtml(unsubscribeUrl)}\n </p>\n <p style=\"margin:0;font-size:11px;line-height:1.5;color:${TEXT_MUTED};\">\n RuleMetric \u2022 ${year}\n </p>\n </td>\n </tr>\n </table>\n </td>\n </tr>\n </table>\n </body>\n</html>`;\n\n // \u2500\u2500 Plain text \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const textLines: string[] = [\n `What's new in RuleMetric \u2014 ${formattedDate}`,\n `Release ${version}`,\n '',\n greeting,\n '',\n `Here's what shipped in the latest RuleMetric release.`,\n '',\n ];\n for (const { name, items } of ordered) {\n textLines.push(`${name}:`);\n for (const it of items) {\n textLines.push(` - ${it}`);\n }\n textLines.push('');\n }\n textLines.push(\n '--',\n `You're receiving this because you signed up for RuleMetric product updates.`,\n `Unsubscribe: ${unsubscribeUrl}`,\n '',\n `RuleMetric \u2022 ${year}`,\n );\n const text = textLines.join('\\n');\n\n return { subject, html, text };\n}\n", "// No-op email provider. Used in dev/test when no real email infrastructure\n// is configured. Logs the destination + subject to stderr so operators can\n// see that a send was requested, then returns a synthetic id. Never throws.\n//\n// This is intentionally the default \u2014 it lets the test suite run without\n// any email environment variables and lets local development work without\n// an email account. Switch to `resend` by setting RESEND_API_KEY, or force\n// noop explicitly with RULEMETRIC_EMAIL_PROVIDER=noop.\n\nimport { randomBytes } from 'node:crypto';\nimport type { SendEmailParams, SendEmailResult } from '../index.js';\n\nexport async function sendNoopEmail(params: SendEmailParams): Promise<SendEmailResult> {\n // Use stderr (same convention as the dev-mode invite log) so it doesn't\n // pollute stdout if a caller is parsing JSON from there.\n const keyNote = params.idempotencyKey ? ` idempotencyKey=${params.idempotencyKey}` : '';\n process.stderr.write(\n `[email:noop] would send to=${params.to} subject=${JSON.stringify(params.subject)}${keyNote}\\n`,\n );\n return {\n id: `noop-${randomBytes(8).toString('hex')}`,\n provider: 'noop',\n };\n}\n", "// Resend provider. Activated when RESEND_API_KEY is set. The Resend SDK is\n// imported lazily so that environments without `resend` installed (or where\n// the dependency hasn't been hoisted yet) don't crash at module-load time \u2014\n// only when a send is actually attempted via this provider.\n//\n// `from` is computed from RESEND_FROM_EMAIL (default: onboarding@resend.dev,\n// which works out of the box with a fresh Resend account for testing).\n\nimport type { SendEmailParams, SendEmailResult } from '../index.js';\n\nlet cachedClient: {\n emails: {\n send: (input: ResendSendInput, options?: ResendSendOptions) => Promise<ResendSendResult>;\n };\n} | null = null;\n\ninterface ResendSendInput {\n from: string;\n to: string | string[];\n subject: string;\n html: string;\n text: string;\n}\n\ninterface ResendSendOptions {\n idempotencyKey?: string;\n}\n\ninterface ResendSendResult {\n data: { id: string } | null;\n error: { message: string; name?: string } | null;\n}\n\nasync function getClient() {\n if (cachedClient) return cachedClient;\n const apiKey = process.env.RESEND_API_KEY;\n if (!apiKey) {\n throw new Error('RESEND_API_KEY is not set');\n }\n // Lazy ESM import. Resend ships ESM-compatible types in its modern releases.\n const { Resend } = (await import('resend')) as {\n Resend: new (key: string) => {\n emails: {\n send: (input: ResendSendInput, options?: ResendSendOptions) => Promise<ResendSendResult>;\n };\n };\n };\n cachedClient = new Resend(apiKey);\n return cachedClient;\n}\n\nexport async function sendResendEmail(\n params: SendEmailParams,\n): Promise<SendEmailResult> {\n const fromName = params.fromName ?? 'RuleMetric';\n const fromEmail = process.env.RESEND_FROM_EMAIL ?? 'onboarding@resend.dev';\n const from = `${fromName} <${fromEmail}>`;\n\n const client = await getClient();\n // Idempotency-Key is a request option in the Resend SDK (not a body field).\n // Resend caches responses keyed on (api_key, idempotency_key) for 24 hours \u2014\n // a duplicate send with the same key returns the original response.\n const options: ResendSendOptions | undefined = params.idempotencyKey\n ? { idempotencyKey: params.idempotencyKey }\n : undefined;\n const result = await client.emails.send(\n {\n from,\n to: params.to,\n subject: params.subject,\n html: params.html,\n text: params.text,\n },\n options,\n );\n\n if (result.error) {\n throw new Error(`Resend send failed: ${result.error.message}`);\n }\n if (!result.data) {\n throw new Error('Resend send returned no data and no error');\n }\n\n return { id: result.data.id, provider: 'resend' };\n}\n\n// For tests: reset the cached client so a fresh API key is picked up.\nexport function _resetResendClient() {\n cachedClient = null;\n}\n", "// SMTP provider \u2014 stub for now.\n//\n// We don't ship `nodemailer` yet. If you want SMTP-based delivery (e.g.\n// to use Supabase's project-level SMTP config), this is where it goes:\n// add `nodemailer` to package.json, parse SMTP_* env vars (or\n// SUPABASE_SMTP_*), build a transport, and call `transport.sendMail(...)`.\n//\n// Until that's wired, this stub throws \u2014 so selectEmailProvider() never\n// chooses 'smtp' unless a future env-var (`RULEMETRIC_EMAIL_PROVIDER=smtp`)\n// is explicitly set, in which case the caller will get a clear error\n// rather than silent failure.\n\nimport type { SendEmailParams, SendEmailResult } from '../index.js';\n\nexport async function sendSmtpEmail(\n _params: SendEmailParams,\n): Promise<SendEmailResult> {\n throw new Error(\n 'SMTP provider not implemented. Set RESEND_API_KEY to use Resend, or unset RULEMETRIC_EMAIL_PROVIDER to fall back to noop.',\n );\n}\n", "// @rulemetric/email \u2014 small abstraction over a transactional-email provider.\n//\n// At module load we DON'T pick a provider \u2014 we resolve it on the first call\n// to `sendEmail`. This is so tests can flip env vars (RESEND_API_KEY,\n// RULEMETRIC_EMAIL_PROVIDER) between cases and observe different behaviour\n// without juggling module imports.\n//\n// Provider selection (highest to lowest precedence):\n// 1. RULEMETRIC_EMAIL_PROVIDER env var ('resend' | 'smtp' | 'noop') \u2014 explicit.\n// 2. If RESEND_API_KEY is set \u2192 'resend'.\n// 3. Otherwise \u2192 'noop' (logs to stderr, returns synthetic id).\n//\n// `noop` is the default to keep the test suite from needing real email\n// infrastructure. Failures from real providers bubble up \u2014 the caller (e.g.\n// the invitation route) decides whether a delivery failure should fail the\n// request or just be logged.\n\nimport { sendNoopEmail } from './providers/noop.js';\nimport { sendResendEmail } from './providers/resend.js';\nimport { sendSmtpEmail } from './providers/smtp.js';\n\nexport interface SendEmailParams {\n to: string;\n subject: string;\n html: string;\n text: string;\n /** Display name for the From header. Defaults to 'RuleMetric'. */\n fromName?: string;\n /**\n * Provider-side idempotency key. When set, the provider deduplicates\n * concurrent / retried sends with the same key for a provider-defined\n * window (Resend: 24h). Required for safe-retry email pipelines \u2014\n * callers should derive this from a stable per-recipient row id\n * (e.g. `announcement_deliveries.id`), NOT a per-attempt nonce.\n */\n idempotencyKey?: string;\n}\n\nexport type EmailProvider = 'resend' | 'noop' | 'smtp';\n\nexport interface SendEmailResult {\n id: string;\n provider: EmailProvider;\n}\n\n/** Pure function \u2014 exported for testing. Reads `process.env` each call. */\nexport function selectEmailProvider(): EmailProvider {\n const explicit = process.env.RULEMETRIC_EMAIL_PROVIDER;\n if (explicit === 'resend' || explicit === 'smtp' || explicit === 'noop') {\n return explicit;\n }\n if (process.env.RESEND_API_KEY) return 'resend';\n return 'noop';\n}\n\n// Reserved TLDs that, per RFC 2606 (.test/.example/.invalid/.localhost +\n// example.com/net/org) and RFC 6761, are guaranteed never to resolve to a real\n// mailbox.\nconst RESERVED_TLDS = new Set(['test', 'example', 'invalid', 'localhost']);\nconst RESERVED_EXAMPLE_DOMAINS = /^example\\.(com|net|org)$/;\n\n/**\n * True when `to` addresses a reserved / structurally-undeliverable domain.\n *\n * Why this exists: our unit + e2e suites mint thousands of `*@rulemetric.test`\n * users. Handing those to a real provider (Resend) produces guaranteed HARD\n * BOUNCES, and a high bounce rate poisons the sending domain's reputation \u2014\n * which pushes legitimate transactional mail (password-reset links, invites)\n * into recipients' spam folders. An env-only guard\n * (`RULEMETRIC_EMAIL_PROVIDER=noop` in test) proved leaky: any runner that\n * forgets it (root vitest, CI with prod-like email secrets) sends for real.\n * This predicate makes the guard env-independent at the `sendEmail` boundary.\n *\n * Pure; exported for testing. Returns `false` for malformed input so the\n * provider remains responsible for address validation.\n */\nexport function isUndeliverableRecipient(to: string): boolean {\n const addr = to.trim().toLowerCase();\n const at = addr.lastIndexOf('@');\n if (at < 0) return false; // malformed \u2014 let the provider validate\n const domain = addr.slice(at + 1);\n if (!domain) return false;\n const tld = domain.slice(domain.lastIndexOf('.') + 1);\n if (RESERVED_TLDS.has(tld)) return true;\n if (RESERVED_EXAMPLE_DOMAINS.test(domain)) return true;\n return false;\n}\n\n// Track whether we've logged the active provider yet \u2014 log-once so dev/test\n// stderr doesn't get spammed.\nlet providerLogged = false;\n\nexport async function sendEmail(params: SendEmailParams): Promise<SendEmailResult> {\n const provider = selectEmailProvider();\n if (!providerLogged) {\n providerLogged = true;\n process.stderr.write(`[email] active provider: ${provider}\\n`);\n }\n switch (provider) {\n case 'resend':\n // Never hand a reserved/undeliverable address to the real provider \u2014 it\n // would hard-bounce and degrade domain reputation. Treat as a no-op\n // success (the address is undeliverable by definition, so callers that\n // only log failures behave identically).\n if (isUndeliverableRecipient(params.to)) {\n process.stderr.write(\n `[email] skipping real send to reserved/undeliverable address ` +\n `${params.to} (RFC 2606/6761) \u2014 routed to noop to protect sender reputation\\n`,\n );\n return sendNoopEmail(params);\n }\n return sendResendEmail(params);\n case 'smtp':\n // When a real SMTP sender is implemented here, apply the same\n // isUndeliverableRecipient() guard before dispatching.\n return sendSmtpEmail(params);\n case 'noop':\n return sendNoopEmail(params);\n }\n}\n\n/** Test helper: reset the provider-logged flag. */\nexport function _resetEmailLogState() {\n providerLogged = false;\n}\n\nexport { renderInvitation } from './templates/invitation.js';\nexport type { InvitationTemplateInput, RenderedEmail } from './templates/invitation.js';\nexport { renderChangelogAnnouncement } from './templates/changelog-announcement.js';\nexport type {\n ChangelogAnnouncementInput,\n ChangelogSectionName,\n} from './templates/changelog-announcement.js';\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
@@ -1,78 +0,0 @@
1
- // src/lib/version-check.ts
2
- import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
- import { homedir } from "node:os";
4
- import { join } from "node:path";
5
- var CONFIG_DIR = join(homedir(), ".config", "rulemetric");
6
- var CACHE_FILE = join(CONFIG_DIR, "version-check.json");
7
- var TTL_MS = 60 * 60 * 1e3;
8
- function readCache() {
9
- try {
10
- const data = JSON.parse(readFileSync(CACHE_FILE, "utf-8"));
11
- if (typeof data.latest === "string" && typeof data.fetchedAtMs === "number") {
12
- return data;
13
- }
14
- return null;
15
- } catch {
16
- return null;
17
- }
18
- }
19
- function writeCache(entry) {
20
- try {
21
- mkdirSync(CONFIG_DIR, { recursive: true });
22
- writeFileSync(CACHE_FILE, JSON.stringify(entry));
23
- } catch {
24
- }
25
- }
26
- function compareVersions(a, b) {
27
- const parse = (v) => v.split(".").map((n) => Number.parseInt(n, 10) || 0);
28
- const pa = parse(a);
29
- const pb = parse(b);
30
- const len = Math.max(pa.length, pb.length);
31
- for (let i = 0; i < len; i++) {
32
- const ai = pa[i] ?? 0;
33
- const bi = pb[i] ?? 0;
34
- if (ai < bi) return -1;
35
- if (ai > bi) return 1;
36
- }
37
- return 0;
38
- }
39
- function getApiUrl() {
40
- const env = process.env.RULEMETRIC_API_URL;
41
- if (env) return env.replace(/\/$/, "");
42
- return "https://rulemetric.com";
43
- }
44
- function refreshVersionCacheInBackground() {
45
- const cached = readCache();
46
- if (cached && Date.now() - cached.fetchedAtMs < TTL_MS) return;
47
- const controller = new AbortController();
48
- const timer = setTimeout(() => controller.abort(), 3e3);
49
- globalThis.fetch(`${getApiUrl()}/api/cli/latest-version`, { signal: controller.signal }).then(async (res) => {
50
- clearTimeout(timer);
51
- if (!res.ok) return;
52
- const data = await res.json();
53
- if (typeof data.latest !== "string") return;
54
- writeCache({ latest: data.latest, fetchedAtMs: Date.now() });
55
- }).catch(() => {
56
- clearTimeout(timer);
57
- });
58
- }
59
- function formatUpgradeBanner(currentVersion, latest) {
60
- if (compareVersions(latest, currentVersion) <= 0) return null;
61
- return [
62
- `RuleMetric ${latest} available (you're on ${currentVersion}).`,
63
- ` Upgrade: npm i -g @rulemetric/cli@latest`,
64
- ` Then: rulemetric hooks install (re-applies capture hooks for the new version)`
65
- ].join("\n");
66
- }
67
- function getUpgradeBanner(currentVersion) {
68
- const cached = readCache();
69
- if (!cached) return null;
70
- return formatUpgradeBanner(currentVersion, cached.latest);
71
- }
72
-
73
- export {
74
- refreshVersionCacheInBackground,
75
- formatUpgradeBanner,
76
- getUpgradeBanner
77
- };
78
- //# sourceMappingURL=chunk-R56PH7YE.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/lib/version-check.ts"],
4
- "sourcesContent": ["// CLI version-check banner. Every command kicks off an async fetch to\n// /api/cli/latest-version (cached for an hour) and prints a one-line\n// notice on the next invocation if the cached version is newer than the\n// currently-running CLI.\n//\n// Design notes:\n// - Fire-and-forget: we never block command execution on the network.\n// - Cache: ~/.config/rulemetric/version-check.json, TTL 1h. Stored on disk\n// so the check survives between CLI invocations (each invocation is a\n// fresh process \u2014 in-memory cache wouldn't help).\n// - \"Newer\" uses semver-naive numeric comparison split on dots \u2014 fine for\n// our 0.x line; tightening this is a follow-up if/when we adopt semver\n// pre-releases.\n// - The banner tells the user how to upgrade (`npm i -g @rulemetric/cli@latest`)\n// and to re-run `rulemetric hooks install` \u2014 capture behavior lives in what\n// install writes, so upgrading the package alone doesn't apply new hooks.\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\n\nconst CONFIG_DIR = join(homedir(), '.config', 'rulemetric');\nconst CACHE_FILE = join(CONFIG_DIR, 'version-check.json');\nconst TTL_MS = 60 * 60 * 1000; // 1h\n\ninterface CacheEntry {\n latest: string;\n fetchedAtMs: number;\n}\n\nfunction readCache(): CacheEntry | null {\n try {\n const data = JSON.parse(readFileSync(CACHE_FILE, 'utf-8')) as CacheEntry;\n if (typeof data.latest === 'string' && typeof data.fetchedAtMs === 'number') {\n return data;\n }\n return null;\n } catch {\n return null;\n }\n}\n\nfunction writeCache(entry: CacheEntry): void {\n try {\n mkdirSync(CONFIG_DIR, { recursive: true });\n writeFileSync(CACHE_FILE, JSON.stringify(entry));\n } catch {\n // Best-effort: a write failure just means we'll re-fetch next time.\n }\n}\n\nfunction compareVersions(a: string, b: string): number {\n const parse = (v: string) => v.split('.').map((n) => Number.parseInt(n, 10) || 0);\n const pa = parse(a);\n const pb = parse(b);\n const len = Math.max(pa.length, pb.length);\n for (let i = 0; i < len; i++) {\n const ai = pa[i] ?? 0;\n const bi = pb[i] ?? 0;\n if (ai < bi) return -1;\n if (ai > bi) return 1;\n }\n return 0;\n}\n\nfunction getApiUrl(): string {\n const env = process.env.RULEMETRIC_API_URL;\n if (env) return env.replace(/\\/$/, '');\n return 'https://rulemetric.com';\n}\n\n/**\n * Fetches latest version from the API in the background and refreshes the\n * cache if the entry is missing or older than TTL_MS. Never throws.\n */\nexport function refreshVersionCacheInBackground(): void {\n const cached = readCache();\n if (cached && Date.now() - cached.fetchedAtMs < TTL_MS) return;\n\n // Fire-and-forget \u2014 explicitly catch every failure mode so an unhandled\n // rejection can never reach the user. AbortController guards against\n // hanging connections (3s budget).\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), 3000);\n globalThis\n .fetch(`${getApiUrl()}/api/cli/latest-version`, { signal: controller.signal })\n .then(async (res) => {\n clearTimeout(timer);\n if (!res.ok) return;\n const data = (await res.json()) as { latest?: unknown };\n if (typeof data.latest !== 'string') return;\n writeCache({ latest: data.latest, fetchedAtMs: Date.now() });\n })\n .catch(() => {\n clearTimeout(timer);\n // Network error, timeout, malformed JSON \u2014 silently ignore. Banner\n // is purely a nicety; we never want it to surface failures.\n });\n}\n\n/**\n * Build the multi-line upgrade banner, or null when `latest` is not newer than\n * `current`. Pure (no disk/network) so it's unit-testable. Includes the upgrade\n * command AND the re-run-hooks-install reminder \u2014 capture behavior lives in what\n * `hooks install` *writes*, so upgrading the package alone doesn't apply it.\n */\nexport function formatUpgradeBanner(currentVersion: string, latest: string): string | null {\n if (compareVersions(latest, currentVersion) <= 0) return null;\n return [\n `RuleMetric ${latest} available (you're on ${currentVersion}).`,\n ` Upgrade: npm i -g @rulemetric/cli@latest`,\n ` Then: rulemetric hooks install (re-applies capture hooks for the new version)`,\n ].join('\\n');\n}\n\n/**\n * Returns the upgrade banner if a newer version is cached, else null.\n * Designed to be printed to stderr by the CLI's BaseCommand on launch.\n */\nexport function getUpgradeBanner(currentVersion: string): string | null {\n const cached = readCache();\n if (!cached) return null;\n return formatUpgradeBanner(currentVersion, cached.latest);\n}\n"],
5
- "mappings": ";AAgBA,SAAS,WAAW,cAAc,qBAAqB;AACvD,SAAS,eAAe;AACxB,SAAS,YAAY;AAErB,IAAM,aAAa,KAAK,QAAQ,GAAG,WAAW,YAAY;AAC1D,IAAM,aAAa,KAAK,YAAY,oBAAoB;AACxD,IAAM,SAAS,KAAK,KAAK;AAOzB,SAAS,YAA+B;AACtC,MAAI;AACF,UAAM,OAAO,KAAK,MAAM,aAAa,YAAY,OAAO,CAAC;AACzD,QAAI,OAAO,KAAK,WAAW,YAAY,OAAO,KAAK,gBAAgB,UAAU;AAC3E,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,WAAW,OAAyB;AAC3C,MAAI;AACF,cAAU,YAAY,EAAE,WAAW,KAAK,CAAC;AACzC,kBAAc,YAAY,KAAK,UAAU,KAAK,CAAC;AAAA,EACjD,QAAQ;AAAA,EAER;AACF;AAEA,SAAS,gBAAgB,GAAW,GAAmB;AACrD,QAAM,QAAQ,CAAC,MAAc,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,OAAO,SAAS,GAAG,EAAE,KAAK,CAAC;AAChF,QAAM,KAAK,MAAM,CAAC;AAClB,QAAM,KAAK,MAAM,CAAC;AAClB,QAAM,MAAM,KAAK,IAAI,GAAG,QAAQ,GAAG,MAAM;AACzC,WAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC5B,UAAM,KAAK,GAAG,CAAC,KAAK;AACpB,UAAM,KAAK,GAAG,CAAC,KAAK;AACpB,QAAI,KAAK,GAAI,QAAO;AACpB,QAAI,KAAK,GAAI,QAAO;AAAA,EACtB;AACA,SAAO;AACT;AAEA,SAAS,YAAoB;AAC3B,QAAM,MAAM,QAAQ,IAAI;AACxB,MAAI,IAAK,QAAO,IAAI,QAAQ,OAAO,EAAE;AACrC,SAAO;AACT;AAMO,SAAS,kCAAwC;AACtD,QAAM,SAAS,UAAU;AACzB,MAAI,UAAU,KAAK,IAAI,IAAI,OAAO,cAAc,OAAQ;AAKxD,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,QAAQ,WAAW,MAAM,WAAW,MAAM,GAAG,GAAI;AACvD,aACG,MAAM,GAAG,UAAU,CAAC,2BAA2B,EAAE,QAAQ,WAAW,OAAO,CAAC,EAC5E,KAAK,OAAO,QAAQ;AACnB,iBAAa,KAAK;AAClB,QAAI,CAAC,IAAI,GAAI;AACb,UAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,QAAI,OAAO,KAAK,WAAW,SAAU;AACrC,eAAW,EAAE,QAAQ,KAAK,QAAQ,aAAa,KAAK,IAAI,EAAE,CAAC;AAAA,EAC7D,CAAC,EACA,MAAM,MAAM;AACX,iBAAa,KAAK;AAAA,EAGpB,CAAC;AACL;AAQO,SAAS,oBAAoB,gBAAwB,QAA+B;AACzF,MAAI,gBAAgB,QAAQ,cAAc,KAAK,EAAG,QAAO;AACzD,SAAO;AAAA,IACL,cAAc,MAAM,yBAAyB,cAAc;AAAA,IAC3D;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAMO,SAAS,iBAAiB,gBAAuC;AACtE,QAAM,SAAS,UAAU;AACzB,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,oBAAoB,gBAAgB,OAAO,MAAM;AAC1D;",
6
- "names": []
7
- }
@@ -1,16 +0,0 @@
1
- // src/dashboard/launcher/tool-labels.ts
2
- var TOOL_LABELS = {
3
- claude_code: "Claude Code",
4
- codex: "Codex",
5
- aider: "Aider",
6
- generic: "Generic"
7
- };
8
- function toolLabel(tool) {
9
- return TOOL_LABELS[tool] ?? tool;
10
- }
11
-
12
- export {
13
- TOOL_LABELS,
14
- toolLabel
15
- };
16
- //# sourceMappingURL=chunk-RH7NHVSK.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/dashboard/launcher/tool-labels.ts"],
4
- "sourcesContent": ["export const TOOL_LABELS: Record<string, string> = {\n claude_code: 'Claude Code',\n codex: 'Codex',\n aider: 'Aider',\n generic: 'Generic',\n};\n\nexport function toolLabel(tool: string): string {\n return TOOL_LABELS[tool] ?? tool;\n}\n"],
5
- "mappings": ";AAAO,IAAM,cAAsC;AAAA,EACjD,aAAa;AAAA,EACb,OAAO;AAAA,EACP,OAAO;AAAA,EACP,SAAS;AACX;AAEO,SAAS,UAAU,MAAsB;AAC9C,SAAO,YAAY,IAAI,KAAK;AAC9B;",
6
- "names": []
7
- }
@@ -1,191 +0,0 @@
1
- import {
2
- PermanentJobError
3
- } from "./chunk-DGHWRQXL.js";
4
- import {
5
- judgeEvalQuality
6
- } from "./chunk-J7N3DLH6.js";
7
- import {
8
- createEvalWorktree
9
- } from "./chunk-52WIYRZH.js";
10
- import {
11
- gradeEvalOutput
12
- } from "./chunk-YNIH3KMU.js";
13
- import {
14
- executeEval
15
- } from "./chunk-QN34TGD3.js";
16
- import {
17
- apiGet,
18
- apiPatch,
19
- apiPost
20
- } from "./chunk-ZUJBM6HE.js";
21
-
22
- // src/lib/handlers/process-eval.ts
23
- async function processEval(payload, helpers) {
24
- const { mirrorId, evalTargetId, config } = payload;
25
- const log = (msg) => helpers.logger.info(msg);
26
- if (helpers.job.attempts > 1) {
27
- throw new PermanentJobError(
28
- `process_eval is not safe to retry (attempt ${helpers.job.attempts}). Re-trigger the eval run from the UI.`
29
- );
30
- }
31
- const target = await apiGet(`/api/eval-targets/${evalTargetId}`);
32
- const evalCases = await apiGet(`/api/eval-targets/${evalTargetId}/evals`);
33
- if (evalCases.length === 0) {
34
- throw new PermanentJobError("No evals defined for target");
35
- }
36
- const runsPerEval = config.runsPerEval ?? 1;
37
- const timeout = config.timeout ?? 12e4;
38
- const iteration = config.iteration ?? 1;
39
- const configurations = [
40
- { name: "with_target", content: target.content }
41
- ];
42
- if (!config.skipBaseline) {
43
- configurations.push({ name: "without_target" });
44
- }
45
- const workQueue = [];
46
- for (const eval_ of evalCases) {
47
- for (const cfg of configurations) {
48
- for (let run = 1; run <= runsPerEval; run++) {
49
- workQueue.push({ eval_, configuration: cfg.name, targetContent: cfg.content, runNumber: run });
50
- }
51
- }
52
- }
53
- const total = workQueue.length;
54
- let completed = 0;
55
- const concurrency = Math.min(config.parallel ?? 1, 4);
56
- await apiPatch(`/api/eval-jobs/${mirrorId}/progress`, {
57
- status: "running",
58
- progress: { total, completed: 0, current: null, message: `Starting ${total} eval runs (concurrency: ${concurrency})...` }
59
- });
60
- const results = [];
61
- async function processItem(item) {
62
- const label = `${item.configuration} \xB7 ${item.eval_.name} \xB7 run#${item.runNumber}`;
63
- log(`[${completed + 1}/${total}] ${label}`);
64
- const worktree = concurrency > 1 ? createEvalWorktree() : null;
65
- try {
66
- const execResult = await executeEval({
67
- prompt: item.eval_.prompt,
68
- targetContent: item.targetContent,
69
- workDir: worktree?.workDir,
70
- timeout,
71
- model: config.model
72
- });
73
- let grading = {};
74
- if (!config.skipGrading && item.eval_.expectations.length > 0 && !execResult.error) {
75
- const gradingResult = await gradeEvalOutput({
76
- prompt: item.eval_.prompt,
77
- output: execResult.output,
78
- expectations: item.eval_.expectations,
79
- model: config.graderModel ?? config.model,
80
- timeout
81
- });
82
- grading = gradingResult;
83
- }
84
- return {
85
- evalId: item.eval_.id,
86
- evalTargetId: target.id,
87
- evalTargetVersion: target.version,
88
- configuration: item.configuration,
89
- runNumber: item.runNumber,
90
- iteration,
91
- status: execResult.error ? "failed" : "completed",
92
- outputs: execResult.error ? { error: execResult.error } : { transcript: execResult.output },
93
- timing: { duration_ms: execResult.durationMs, total_tokens: execResult.totalTokens },
94
- grading,
95
- worktree: worktree?.isWorktree ? true : void 0
96
- };
97
- } finally {
98
- worktree?.cleanup();
99
- }
100
- }
101
- if (concurrency <= 1) {
102
- for (const item of workQueue) {
103
- const label = `${item.configuration} \xB7 ${item.eval_.name} \xB7 run#${item.runNumber}`;
104
- await apiPatch(`/api/eval-jobs/${mirrorId}/progress`, {
105
- status: "running",
106
- progress: { total, completed, current: label, message: `Executing ${label}...` }
107
- });
108
- const runResult = await processItem(item);
109
- await apiPost("/api/eval-runs", runResult);
110
- results.push(runResult);
111
- completed++;
112
- await apiPatch(`/api/eval-jobs/${mirrorId}/progress`, {
113
- status: "running",
114
- progress: { total, completed, current: label, message: `Completed ${label}` }
115
- });
116
- }
117
- } else {
118
- log(`Running ${total} evals with concurrency=${concurrency} (worktree isolation)`);
119
- for (let i = 0; i < workQueue.length; i += concurrency) {
120
- const batch = workQueue.slice(i, i + concurrency);
121
- const batchLabel = `batch ${Math.floor(i / concurrency) + 1}/${Math.ceil(workQueue.length / concurrency)}`;
122
- await apiPatch(`/api/eval-jobs/${mirrorId}/progress`, {
123
- status: "running",
124
- progress: { total, completed, current: batchLabel, message: `Executing ${batchLabel} (${batch.length} parallel)...` }
125
- });
126
- const batchResults = await Promise.all(batch.map(processItem));
127
- for (const runResult of batchResults) {
128
- await apiPost("/api/eval-runs", runResult);
129
- results.push(runResult);
130
- completed++;
131
- }
132
- await apiPatch(`/api/eval-jobs/${mirrorId}/progress`, {
133
- status: "running",
134
- progress: { total, completed, current: batchLabel, message: `Completed ${batchLabel}` }
135
- });
136
- }
137
- }
138
- const summary = buildSummary(results);
139
- let metaJudgement;
140
- if (!config.skipGrading && results.some((r) => r.grading && Object.keys(r.grading).length > 0)) {
141
- try {
142
- log(`Running meta-judge for job ${mirrorId}...`);
143
- const evalInputs = evalCases.map((e) => {
144
- const matchingResults = results.filter((r) => r.evalId === e.id && r.configuration === "with_target");
145
- const firstResult = matchingResults[0];
146
- return {
147
- evalName: e.name,
148
- prompt: e.prompt,
149
- expectations: e.expectations,
150
- grading: firstResult?.grading ? firstResult.grading : null,
151
- output: firstResult?.outputs?.transcript?.slice(0, 500)
152
- };
153
- });
154
- metaJudgement = await judgeEvalQuality({
155
- targetName: target.name,
156
- evalResults: evalInputs,
157
- model: config.graderModel ?? config.model,
158
- timeout: 6e4
159
- });
160
- log(`Meta-judge: quality=${metaJudgement.quality_score}/5, issues=${metaJudgement.issues.length}`);
161
- } catch (err) {
162
- log(`Meta-judge failed (non-fatal): ${err instanceof Error ? err.message : String(err)}`);
163
- }
164
- }
165
- const result = metaJudgement ? { ...summary, meta_judgement: metaJudgement } : summary;
166
- log(`Job ${mirrorId} completed: ${completed}/${total} runs`);
167
- await apiPatch(`/api/eval-jobs/${mirrorId}/state`, { result }).catch((err) => {
168
- log(`result persist failed: ${err instanceof Error ? err.message : String(err)}`);
169
- });
170
- return result;
171
- }
172
- function buildSummary(results) {
173
- const completed = results.filter((r) => r.status === "completed");
174
- const failed = results.filter((r) => r.status === "failed");
175
- const gradedRuns = completed.filter((r) => {
176
- const grading = r.grading;
177
- return grading && Object.keys(grading).length > 0;
178
- });
179
- const avgPassRate = gradedRuns.length > 0 ? gradedRuns.reduce((sum, r) => sum + (r.grading?.summary?.pass_rate ?? 0), 0) / gradedRuns.length : null;
180
- return {
181
- total: results.length,
182
- completed: completed.length,
183
- failed: failed.length,
184
- avgPassRate
185
- };
186
- }
187
-
188
- export {
189
- processEval
190
- };
191
- //# sourceMappingURL=chunk-RMTT4KDY.js.map