@rulemetric/cli 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (416) hide show
  1. package/bin/dev.js +3 -0
  2. package/bin/run.js +3 -0
  3. package/dist/base-command.d.ts +12 -0
  4. package/dist/base-command.d.ts.map +1 -0
  5. package/dist/base-command.js +37 -0
  6. package/dist/base-command.js.map +1 -0
  7. package/dist/commands/auth/create-key.d.ts +11 -0
  8. package/dist/commands/auth/create-key.d.ts.map +1 -0
  9. package/dist/commands/auth/create-key.js +34 -0
  10. package/dist/commands/auth/create-key.js.map +1 -0
  11. package/dist/commands/auth/login.d.ts +11 -0
  12. package/dist/commands/auth/login.d.ts.map +1 -0
  13. package/dist/commands/auth/login.js +40 -0
  14. package/dist/commands/auth/login.js.map +1 -0
  15. package/dist/commands/auth/logout.d.ts +7 -0
  16. package/dist/commands/auth/logout.d.ts.map +1 -0
  17. package/dist/commands/auth/logout.js +13 -0
  18. package/dist/commands/auth/logout.js.map +1 -0
  19. package/dist/commands/auth/revoke-key.d.ts +10 -0
  20. package/dist/commands/auth/revoke-key.d.ts.map +1 -0
  21. package/dist/commands/auth/revoke-key.js +18 -0
  22. package/dist/commands/auth/revoke-key.js.map +1 -0
  23. package/dist/commands/auth/status.d.ts +7 -0
  24. package/dist/commands/auth/status.d.ts.map +1 -0
  25. package/dist/commands/auth/status.js +23 -0
  26. package/dist/commands/auth/status.js.map +1 -0
  27. package/dist/commands/catalog/index.d.ts +11 -0
  28. package/dist/commands/catalog/index.d.ts.map +1 -0
  29. package/dist/commands/catalog/index.js +35 -0
  30. package/dist/commands/catalog/index.js.map +1 -0
  31. package/dist/commands/catalog/recommend.d.ts +9 -0
  32. package/dist/commands/catalog/recommend.d.ts.map +1 -0
  33. package/dist/commands/catalog/recommend.js +27 -0
  34. package/dist/commands/catalog/recommend.js.map +1 -0
  35. package/dist/commands/convert.d.ts +15 -0
  36. package/dist/commands/convert.d.ts.map +1 -0
  37. package/dist/commands/convert.js +55 -0
  38. package/dist/commands/convert.js.map +1 -0
  39. package/dist/commands/converters.d.ts +12 -0
  40. package/dist/commands/converters.d.ts.map +1 -0
  41. package/dist/commands/converters.js +39 -0
  42. package/dist/commands/converters.js.map +1 -0
  43. package/dist/commands/dashboard.d.ts +10 -0
  44. package/dist/commands/dashboard.d.ts.map +1 -0
  45. package/dist/commands/dashboard.js +24 -0
  46. package/dist/commands/dashboard.js.map +1 -0
  47. package/dist/commands/eval-targets/create.d.ts +14 -0
  48. package/dist/commands/eval-targets/create.d.ts.map +1 -0
  49. package/dist/commands/eval-targets/create.js +40 -0
  50. package/dist/commands/eval-targets/create.js.map +1 -0
  51. package/dist/commands/eval-targets/list.d.ts +10 -0
  52. package/dist/commands/eval-targets/list.d.ts.map +1 -0
  53. package/dist/commands/eval-targets/list.js +36 -0
  54. package/dist/commands/eval-targets/list.js.map +1 -0
  55. package/dist/commands/evals/benchmark.d.ts +13 -0
  56. package/dist/commands/evals/benchmark.d.ts.map +1 -0
  57. package/dist/commands/evals/benchmark.js +53 -0
  58. package/dist/commands/evals/benchmark.js.map +1 -0
  59. package/dist/commands/evals/compare.d.ts +15 -0
  60. package/dist/commands/evals/compare.d.ts.map +1 -0
  61. package/dist/commands/evals/compare.js +101 -0
  62. package/dist/commands/evals/compare.js.map +1 -0
  63. package/dist/commands/evals/create.d.ts +17 -0
  64. package/dist/commands/evals/create.d.ts.map +1 -0
  65. package/dist/commands/evals/create.js +52 -0
  66. package/dist/commands/evals/create.js.map +1 -0
  67. package/dist/commands/evals/listen.d.ts +11 -0
  68. package/dist/commands/evals/listen.d.ts.map +1 -0
  69. package/dist/commands/evals/listen.js +54 -0
  70. package/dist/commands/evals/listen.js.map +1 -0
  71. package/dist/commands/evals/optimize-description.d.ts +22 -0
  72. package/dist/commands/evals/optimize-description.d.ts.map +1 -0
  73. package/dist/commands/evals/optimize-description.js +269 -0
  74. package/dist/commands/evals/optimize-description.js.map +1 -0
  75. package/dist/commands/evals/optimize.d.ts +22 -0
  76. package/dist/commands/evals/optimize.d.ts.map +1 -0
  77. package/dist/commands/evals/optimize.js +200 -0
  78. package/dist/commands/evals/optimize.js.map +1 -0
  79. package/dist/commands/evals/run.d.ts +21 -0
  80. package/dist/commands/evals/run.d.ts.map +1 -0
  81. package/dist/commands/evals/run.js +168 -0
  82. package/dist/commands/evals/run.js.map +1 -0
  83. package/dist/commands/gateway/ensure.d.ts +7 -0
  84. package/dist/commands/gateway/ensure.d.ts.map +1 -0
  85. package/dist/commands/gateway/ensure.js +20 -0
  86. package/dist/commands/gateway/ensure.js.map +1 -0
  87. package/dist/commands/hooks/install.d.ts +16 -0
  88. package/dist/commands/hooks/install.d.ts.map +1 -0
  89. package/dist/commands/hooks/install.js +248 -0
  90. package/dist/commands/hooks/install.js.map +1 -0
  91. package/dist/commands/hooks/run.d.ts +11 -0
  92. package/dist/commands/hooks/run.d.ts.map +1 -0
  93. package/dist/commands/hooks/run.js +56 -0
  94. package/dist/commands/hooks/run.js.map +1 -0
  95. package/dist/commands/hooks/uninstall.d.ts +7 -0
  96. package/dist/commands/hooks/uninstall.d.ts.map +1 -0
  97. package/dist/commands/hooks/uninstall.js +88 -0
  98. package/dist/commands/hooks/uninstall.js.map +1 -0
  99. package/dist/commands/import.d.ts +17 -0
  100. package/dist/commands/import.d.ts.map +1 -0
  101. package/dist/commands/import.js +55 -0
  102. package/dist/commands/import.js.map +1 -0
  103. package/dist/commands/insights/sync.d.ts +17 -0
  104. package/dist/commands/insights/sync.d.ts.map +1 -0
  105. package/dist/commands/insights/sync.js +477 -0
  106. package/dist/commands/insights/sync.js.map +1 -0
  107. package/dist/commands/instructions/create.d.ts +17 -0
  108. package/dist/commands/instructions/create.d.ts.map +1 -0
  109. package/dist/commands/instructions/create.js +60 -0
  110. package/dist/commands/instructions/create.js.map +1 -0
  111. package/dist/commands/instructions/delete.d.ts +13 -0
  112. package/dist/commands/instructions/delete.d.ts.map +1 -0
  113. package/dist/commands/instructions/delete.js +37 -0
  114. package/dist/commands/instructions/delete.js.map +1 -0
  115. package/dist/commands/instructions/fork.d.ts +10 -0
  116. package/dist/commands/instructions/fork.d.ts.map +1 -0
  117. package/dist/commands/instructions/fork.js +19 -0
  118. package/dist/commands/instructions/fork.js.map +1 -0
  119. package/dist/commands/instructions/get.d.ts +15 -0
  120. package/dist/commands/instructions/get.d.ts.map +1 -0
  121. package/dist/commands/instructions/get.js +50 -0
  122. package/dist/commands/instructions/get.js.map +1 -0
  123. package/dist/commands/instructions/list.d.ts +12 -0
  124. package/dist/commands/instructions/list.d.ts.map +1 -0
  125. package/dist/commands/instructions/list.js +47 -0
  126. package/dist/commands/instructions/list.js.map +1 -0
  127. package/dist/commands/instructions/promote.d.ts +14 -0
  128. package/dist/commands/instructions/promote.d.ts.map +1 -0
  129. package/dist/commands/instructions/promote.js +27 -0
  130. package/dist/commands/instructions/promote.js.map +1 -0
  131. package/dist/commands/instructions/pull.d.ts +9 -0
  132. package/dist/commands/instructions/pull.d.ts.map +1 -0
  133. package/dist/commands/instructions/pull.js +22 -0
  134. package/dist/commands/instructions/pull.js.map +1 -0
  135. package/dist/commands/instructions/upstream.d.ts +9 -0
  136. package/dist/commands/instructions/upstream.d.ts.map +1 -0
  137. package/dist/commands/instructions/upstream.js +22 -0
  138. package/dist/commands/instructions/upstream.js.map +1 -0
  139. package/dist/commands/instructions/versions.d.ts +12 -0
  140. package/dist/commands/instructions/versions.d.ts.map +1 -0
  141. package/dist/commands/instructions/versions.js +34 -0
  142. package/dist/commands/instructions/versions.js.map +1 -0
  143. package/dist/commands/packs/add-instruction.d.ts +11 -0
  144. package/dist/commands/packs/add-instruction.d.ts.map +1 -0
  145. package/dist/commands/packs/add-instruction.js +22 -0
  146. package/dist/commands/packs/add-instruction.js.map +1 -0
  147. package/dist/commands/packs/apply.d.ts +13 -0
  148. package/dist/commands/packs/apply.d.ts.map +1 -0
  149. package/dist/commands/packs/apply.js +24 -0
  150. package/dist/commands/packs/apply.js.map +1 -0
  151. package/dist/commands/packs/create.d.ts +13 -0
  152. package/dist/commands/packs/create.d.ts.map +1 -0
  153. package/dist/commands/packs/create.js +35 -0
  154. package/dist/commands/packs/create.js.map +1 -0
  155. package/dist/commands/packs/fork.d.ts +10 -0
  156. package/dist/commands/packs/fork.d.ts.map +1 -0
  157. package/dist/commands/packs/fork.js +19 -0
  158. package/dist/commands/packs/fork.js.map +1 -0
  159. package/dist/commands/packs/get.d.ts +10 -0
  160. package/dist/commands/packs/get.d.ts.map +1 -0
  161. package/dist/commands/packs/get.js +36 -0
  162. package/dist/commands/packs/get.js.map +1 -0
  163. package/dist/commands/packs/list.d.ts +22 -0
  164. package/dist/commands/packs/list.d.ts.map +1 -0
  165. package/dist/commands/packs/list.js +48 -0
  166. package/dist/commands/packs/list.js.map +1 -0
  167. package/dist/commands/packs/remove-instruction.d.ts +11 -0
  168. package/dist/commands/packs/remove-instruction.d.ts.map +1 -0
  169. package/dist/commands/packs/remove-instruction.js +20 -0
  170. package/dist/commands/packs/remove-instruction.js.map +1 -0
  171. package/dist/commands/proxy/env.d.ts +14 -0
  172. package/dist/commands/proxy/env.d.ts.map +1 -0
  173. package/dist/commands/proxy/env.js +118 -0
  174. package/dist/commands/proxy/env.js.map +1 -0
  175. package/dist/commands/proxy/logs.d.ts +11 -0
  176. package/dist/commands/proxy/logs.d.ts.map +1 -0
  177. package/dist/commands/proxy/logs.js +75 -0
  178. package/dist/commands/proxy/logs.js.map +1 -0
  179. package/dist/commands/proxy/setup.d.ts +23 -0
  180. package/dist/commands/proxy/setup.d.ts.map +1 -0
  181. package/dist/commands/proxy/setup.js +391 -0
  182. package/dist/commands/proxy/setup.js.map +1 -0
  183. package/dist/commands/proxy/start.d.ts +17 -0
  184. package/dist/commands/proxy/start.d.ts.map +1 -0
  185. package/dist/commands/proxy/start.js +306 -0
  186. package/dist/commands/proxy/start.js.map +1 -0
  187. package/dist/commands/proxy/status.d.ts +7 -0
  188. package/dist/commands/proxy/status.d.ts.map +1 -0
  189. package/dist/commands/proxy/status.js +65 -0
  190. package/dist/commands/proxy/status.js.map +1 -0
  191. package/dist/commands/proxy/stop.d.ts +8 -0
  192. package/dist/commands/proxy/stop.d.ts.map +1 -0
  193. package/dist/commands/proxy/stop.js +77 -0
  194. package/dist/commands/proxy/stop.js.map +1 -0
  195. package/dist/commands/service/install.d.ts +17 -0
  196. package/dist/commands/service/install.d.ts.map +1 -0
  197. package/dist/commands/service/install.js +383 -0
  198. package/dist/commands/service/install.js.map +1 -0
  199. package/dist/commands/service/install.test.d.ts +2 -0
  200. package/dist/commands/service/install.test.d.ts.map +1 -0
  201. package/dist/commands/service/install.test.js +345 -0
  202. package/dist/commands/service/install.test.js.map +1 -0
  203. package/dist/commands/service/status.d.ts +6 -0
  204. package/dist/commands/service/status.d.ts.map +1 -0
  205. package/dist/commands/service/status.js +112 -0
  206. package/dist/commands/service/status.js.map +1 -0
  207. package/dist/commands/service/uninstall.d.ts +6 -0
  208. package/dist/commands/service/uninstall.d.ts.map +1 -0
  209. package/dist/commands/service/uninstall.js +84 -0
  210. package/dist/commands/service/uninstall.js.map +1 -0
  211. package/dist/commands/sessions/analyze.d.ts +10 -0
  212. package/dist/commands/sessions/analyze.d.ts.map +1 -0
  213. package/dist/commands/sessions/analyze.js +26 -0
  214. package/dist/commands/sessions/analyze.js.map +1 -0
  215. package/dist/commands/sessions/end.d.ts +9 -0
  216. package/dist/commands/sessions/end.d.ts.map +1 -0
  217. package/dist/commands/sessions/end.js +82 -0
  218. package/dist/commands/sessions/end.js.map +1 -0
  219. package/dist/commands/sessions/import.d.ts +13 -0
  220. package/dist/commands/sessions/import.d.ts.map +1 -0
  221. package/dist/commands/sessions/import.js +28 -0
  222. package/dist/commands/sessions/import.js.map +1 -0
  223. package/dist/commands/sessions/list.d.ts +11 -0
  224. package/dist/commands/sessions/list.d.ts.map +1 -0
  225. package/dist/commands/sessions/list.js +34 -0
  226. package/dist/commands/sessions/list.js.map +1 -0
  227. package/dist/commands/sessions/start.d.ts +11 -0
  228. package/dist/commands/sessions/start.d.ts.map +1 -0
  229. package/dist/commands/sessions/start.js +83 -0
  230. package/dist/commands/sessions/start.js.map +1 -0
  231. package/dist/commands/skills/install.d.ts +15 -0
  232. package/dist/commands/skills/install.d.ts.map +1 -0
  233. package/dist/commands/skills/install.js +91 -0
  234. package/dist/commands/skills/install.js.map +1 -0
  235. package/dist/commands/skills/list.d.ts +11 -0
  236. package/dist/commands/skills/list.d.ts.map +1 -0
  237. package/dist/commands/skills/list.js +47 -0
  238. package/dist/commands/skills/list.js.map +1 -0
  239. package/dist/commands/skills/search.d.ts +17 -0
  240. package/dist/commands/skills/search.d.ts.map +1 -0
  241. package/dist/commands/skills/search.js +56 -0
  242. package/dist/commands/skills/search.js.map +1 -0
  243. package/dist/commands/skills/update.d.ts +7 -0
  244. package/dist/commands/skills/update.d.ts.map +1 -0
  245. package/dist/commands/skills/update.js +30 -0
  246. package/dist/commands/skills/update.js.map +1 -0
  247. package/dist/dashboard/Dashboard.d.ts +3 -0
  248. package/dist/dashboard/Dashboard.d.ts.map +1 -0
  249. package/dist/dashboard/Dashboard.js +132 -0
  250. package/dist/dashboard/Dashboard.js.map +1 -0
  251. package/dist/dashboard/data.d.ts +11 -0
  252. package/dist/dashboard/data.d.ts.map +1 -0
  253. package/dist/dashboard/data.js +137 -0
  254. package/dist/dashboard/data.js.map +1 -0
  255. package/dist/dashboard/panels/friction.d.ts +7 -0
  256. package/dist/dashboard/panels/friction.d.ts.map +1 -0
  257. package/dist/dashboard/panels/friction.js +22 -0
  258. package/dist/dashboard/panels/friction.js.map +1 -0
  259. package/dist/dashboard/panels/insights.d.ts +8 -0
  260. package/dist/dashboard/panels/insights.d.ts.map +1 -0
  261. package/dist/dashboard/panels/insights.js +109 -0
  262. package/dist/dashboard/panels/insights.js.map +1 -0
  263. package/dist/dashboard/panels/instructions.d.ts +9 -0
  264. package/dist/dashboard/panels/instructions.d.ts.map +1 -0
  265. package/dist/dashboard/panels/instructions.js +17 -0
  266. package/dist/dashboard/panels/instructions.js.map +1 -0
  267. package/dist/dashboard/panels/outcomes.d.ts +7 -0
  268. package/dist/dashboard/panels/outcomes.d.ts.map +1 -0
  269. package/dist/dashboard/panels/outcomes.js +29 -0
  270. package/dist/dashboard/panels/outcomes.js.map +1 -0
  271. package/dist/dashboard/panels/overview.d.ts +8 -0
  272. package/dist/dashboard/panels/overview.d.ts.map +1 -0
  273. package/dist/dashboard/panels/overview.js +20 -0
  274. package/dist/dashboard/panels/overview.js.map +1 -0
  275. package/dist/dashboard/panels/shared.d.ts +17 -0
  276. package/dist/dashboard/panels/shared.d.ts.map +1 -0
  277. package/dist/dashboard/panels/shared.js +62 -0
  278. package/dist/dashboard/panels/shared.js.map +1 -0
  279. package/dist/dashboard/types.d.ts +80 -0
  280. package/dist/dashboard/types.d.ts.map +1 -0
  281. package/dist/dashboard/types.js +27 -0
  282. package/dist/dashboard/types.js.map +1 -0
  283. package/dist/index.d.ts +2 -0
  284. package/dist/index.d.ts.map +1 -0
  285. package/dist/index.js +2 -0
  286. package/dist/index.js.map +1 -0
  287. package/dist/lib/api-client.d.ts +17 -0
  288. package/dist/lib/api-client.d.ts.map +1 -0
  289. package/dist/lib/api-client.js +92 -0
  290. package/dist/lib/api-client.js.map +1 -0
  291. package/dist/lib/api-client.test.d.ts +2 -0
  292. package/dist/lib/api-client.test.d.ts.map +1 -0
  293. package/dist/lib/api-client.test.js +161 -0
  294. package/dist/lib/api-client.test.js.map +1 -0
  295. package/dist/lib/auth.d.ts +27 -0
  296. package/dist/lib/auth.d.ts.map +1 -0
  297. package/dist/lib/auth.js +137 -0
  298. package/dist/lib/auth.js.map +1 -0
  299. package/dist/lib/auth.test.d.ts +2 -0
  300. package/dist/lib/auth.test.d.ts.map +1 -0
  301. package/dist/lib/auth.test.js +110 -0
  302. package/dist/lib/auth.test.js.map +1 -0
  303. package/dist/lib/eval-analyzer.d.ts +23 -0
  304. package/dist/lib/eval-analyzer.d.ts.map +1 -0
  305. package/dist/lib/eval-analyzer.js +89 -0
  306. package/dist/lib/eval-analyzer.js.map +1 -0
  307. package/dist/lib/eval-benchmark.d.ts +17 -0
  308. package/dist/lib/eval-benchmark.d.ts.map +1 -0
  309. package/dist/lib/eval-benchmark.js +92 -0
  310. package/dist/lib/eval-benchmark.js.map +1 -0
  311. package/dist/lib/eval-conversation-handler.d.ts +9 -0
  312. package/dist/lib/eval-conversation-handler.d.ts.map +1 -0
  313. package/dist/lib/eval-conversation-handler.js +200 -0
  314. package/dist/lib/eval-conversation-handler.js.map +1 -0
  315. package/dist/lib/eval-executor.d.ts +21 -0
  316. package/dist/lib/eval-executor.d.ts.map +1 -0
  317. package/dist/lib/eval-executor.js +80 -0
  318. package/dist/lib/eval-executor.js.map +1 -0
  319. package/dist/lib/eval-executor.test.d.ts +2 -0
  320. package/dist/lib/eval-executor.test.d.ts.map +1 -0
  321. package/dist/lib/eval-executor.test.js +8 -0
  322. package/dist/lib/eval-executor.test.js.map +1 -0
  323. package/dist/lib/eval-grader.d.ts +38 -0
  324. package/dist/lib/eval-grader.d.ts.map +1 -0
  325. package/dist/lib/eval-grader.js +123 -0
  326. package/dist/lib/eval-grader.js.map +1 -0
  327. package/dist/lib/eval-grader.test.d.ts +2 -0
  328. package/dist/lib/eval-grader.test.d.ts.map +1 -0
  329. package/dist/lib/eval-grader.test.js +8 -0
  330. package/dist/lib/eval-grader.test.js.map +1 -0
  331. package/dist/lib/eval-meta-judge.d.ts +28 -0
  332. package/dist/lib/eval-meta-judge.d.ts.map +1 -0
  333. package/dist/lib/eval-meta-judge.js +116 -0
  334. package/dist/lib/eval-meta-judge.js.map +1 -0
  335. package/dist/lib/eval-trigger-tester.d.ts +19 -0
  336. package/dist/lib/eval-trigger-tester.d.ts.map +1 -0
  337. package/dist/lib/eval-trigger-tester.js +96 -0
  338. package/dist/lib/eval-trigger-tester.js.map +1 -0
  339. package/dist/lib/eval-worker.d.ts +12 -0
  340. package/dist/lib/eval-worker.d.ts.map +1 -0
  341. package/dist/lib/eval-worker.js +395 -0
  342. package/dist/lib/eval-worker.js.map +1 -0
  343. package/dist/lib/eval-worktree.d.ts +11 -0
  344. package/dist/lib/eval-worktree.d.ts.map +1 -0
  345. package/dist/lib/eval-worktree.js +87 -0
  346. package/dist/lib/eval-worktree.js.map +1 -0
  347. package/dist/lib/eval-worktree.test.d.ts +2 -0
  348. package/dist/lib/eval-worktree.test.d.ts.map +1 -0
  349. package/dist/lib/eval-worktree.test.js +68 -0
  350. package/dist/lib/eval-worktree.test.js.map +1 -0
  351. package/dist/lib/gateway-entry.d.ts +3 -0
  352. package/dist/lib/gateway-entry.d.ts.map +1 -0
  353. package/dist/lib/gateway-entry.js +19 -0
  354. package/dist/lib/gateway-entry.js.map +1 -0
  355. package/dist/lib/gateway-lifecycle.d.ts +9 -0
  356. package/dist/lib/gateway-lifecycle.d.ts.map +1 -0
  357. package/dist/lib/gateway-lifecycle.js +86 -0
  358. package/dist/lib/gateway-lifecycle.js.map +1 -0
  359. package/dist/lib/gateway.d.ts +12 -0
  360. package/dist/lib/gateway.d.ts.map +1 -0
  361. package/dist/lib/gateway.js +150 -0
  362. package/dist/lib/gateway.js.map +1 -0
  363. package/dist/lib/hooks-config.d.ts +95 -0
  364. package/dist/lib/hooks-config.d.ts.map +1 -0
  365. package/dist/lib/hooks-config.js +416 -0
  366. package/dist/lib/hooks-config.js.map +1 -0
  367. package/dist/lib/hooks-config.test.d.ts +2 -0
  368. package/dist/lib/hooks-config.test.d.ts.map +1 -0
  369. package/dist/lib/hooks-config.test.js +231 -0
  370. package/dist/lib/hooks-config.test.js.map +1 -0
  371. package/dist/lib/insights-prompts.d.ts +13 -0
  372. package/dist/lib/insights-prompts.d.ts.map +1 -0
  373. package/dist/lib/insights-prompts.js +145 -0
  374. package/dist/lib/insights-prompts.js.map +1 -0
  375. package/dist/lib/insights-worker.d.ts +10 -0
  376. package/dist/lib/insights-worker.d.ts.map +1 -0
  377. package/dist/lib/insights-worker.js +329 -0
  378. package/dist/lib/insights-worker.js.map +1 -0
  379. package/dist/lib/llm-client.d.ts +26 -0
  380. package/dist/lib/llm-client.d.ts.map +1 -0
  381. package/dist/lib/llm-client.js +142 -0
  382. package/dist/lib/llm-client.js.map +1 -0
  383. package/dist/lib/llm-client.test.d.ts +2 -0
  384. package/dist/lib/llm-client.test.d.ts.map +1 -0
  385. package/dist/lib/llm-client.test.js +62 -0
  386. package/dist/lib/llm-client.test.js.map +1 -0
  387. package/dist/lib/output.d.ts +4 -0
  388. package/dist/lib/output.d.ts.map +1 -0
  389. package/dist/lib/output.js +36 -0
  390. package/dist/lib/output.js.map +1 -0
  391. package/dist/lib/output.test.d.ts +2 -0
  392. package/dist/lib/output.test.d.ts.map +1 -0
  393. package/dist/lib/output.test.js +71 -0
  394. package/dist/lib/output.test.js.map +1 -0
  395. package/dist/lib/provider-aggregator.d.ts +24 -0
  396. package/dist/lib/provider-aggregator.d.ts.map +1 -0
  397. package/dist/lib/provider-aggregator.js +57 -0
  398. package/dist/lib/provider-aggregator.js.map +1 -0
  399. package/dist/lib/provider-aggregator.test.d.ts +2 -0
  400. package/dist/lib/provider-aggregator.test.d.ts.map +1 -0
  401. package/dist/lib/provider-aggregator.test.js +103 -0
  402. package/dist/lib/provider-aggregator.test.js.map +1 -0
  403. package/dist/lib/skills-loader.d.ts +6 -0
  404. package/dist/lib/skills-loader.d.ts.map +1 -0
  405. package/dist/lib/skills-loader.js +51 -0
  406. package/dist/lib/skills-loader.js.map +1 -0
  407. package/dist/lib/types.d.ts +48 -0
  408. package/dist/lib/types.d.ts.map +1 -0
  409. package/dist/lib/types.js +7 -0
  410. package/dist/lib/types.js.map +1 -0
  411. package/dist/test-helpers.d.ts +58 -0
  412. package/dist/test-helpers.d.ts.map +1 -0
  413. package/dist/test-helpers.js +58 -0
  414. package/dist/test-helpers.js.map +1 -0
  415. package/oclif.manifest.json +3197 -0
  416. package/package.json +76 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-config.d.ts","sourceRoot":"","sources":["../../src/lib/hooks-config.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,QAAQ,GAAG,eAAe,CAAC;AAEtE;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,EAAE,CAYxE;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,MAAM,CAqBlD;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,CAkBnD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA+CnE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcpE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAyC9D;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAc1G;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAoB1G;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CA6BpE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAQ/D;AAYD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CA6CnF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAmBhD;AAgBD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAmBvE;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,OAAO,CAcrD"}
@@ -0,0 +1,416 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ /**
6
+ * Detect which AI coding tools are installed in the project by checking
7
+ * for their config directories.
8
+ */
9
+ export function detectInstalledTools(projectPath) {
10
+ const tools = ['claude_code'];
11
+ if (existsSync(join(projectPath, '.cursor'))) {
12
+ tools.push('cursor');
13
+ }
14
+ if (existsSync(join(projectPath, '.github'))) {
15
+ tools.push('copilot_agent');
16
+ }
17
+ return tools;
18
+ }
19
+ /**
20
+ * Generate Cursor hooks config object.
21
+ *
22
+ * Cursor uses event names like beforeSubmitPrompt, afterFileEdit, etc.
23
+ * Each event maps to an array of hook objects with a `command` field.
24
+ */
25
+ export function generateCursorHooksConfig() {
26
+ return {
27
+ version: 1,
28
+ hooks: {
29
+ beforeSubmitPrompt: [
30
+ { command: 'rulemetric hooks run user-prompt' },
31
+ ],
32
+ afterFileEdit: [
33
+ { command: 'rulemetric hooks run post-tool-use' },
34
+ ],
35
+ beforeShellExecution: [
36
+ { command: 'rulemetric hooks run post-tool-use' },
37
+ ],
38
+ beforeMCPExecution: [
39
+ { command: 'rulemetric hooks run post-tool-use' },
40
+ ],
41
+ stop: [
42
+ { command: 'rulemetric hooks run session-end' },
43
+ ],
44
+ },
45
+ };
46
+ }
47
+ /**
48
+ * Generate Copilot Agent hooks config object.
49
+ *
50
+ * Copilot uses event names like sessionStart, userPromptSubmitted, etc.
51
+ * Each event maps to an array of hook objects with `type` and `bash` fields.
52
+ */
53
+ export function generateCopilotHooksConfig() {
54
+ return {
55
+ version: 1,
56
+ hooks: {
57
+ sessionStart: [
58
+ { type: 'command', bash: 'rulemetric hooks run session-start' },
59
+ ],
60
+ userPromptSubmitted: [
61
+ { type: 'command', bash: 'rulemetric hooks run user-prompt' },
62
+ ],
63
+ postToolUse: [
64
+ { type: 'command', bash: 'rulemetric hooks run post-tool-use' },
65
+ ],
66
+ sessionEnd: [
67
+ { type: 'command', bash: 'rulemetric hooks run session-end' },
68
+ ],
69
+ },
70
+ };
71
+ }
72
+ /**
73
+ * Write Cursor hooks config to `.cursor/hooks.json`.
74
+ * Merges with existing config — appends rulemetric hooks without duplicating.
75
+ * Returns the config file path, or null if `.cursor/` doesn't exist.
76
+ */
77
+ export function writeCursorHooks(projectPath) {
78
+ const cursorDir = join(projectPath, '.cursor');
79
+ if (!existsSync(cursorDir)) {
80
+ return null;
81
+ }
82
+ const configPath = join(cursorDir, 'hooks.json');
83
+ const generated = generateCursorHooksConfig();
84
+ // Read existing config if present
85
+ let existing = {};
86
+ if (existsSync(configPath)) {
87
+ try {
88
+ existing = JSON.parse(readFileSync(configPath, 'utf-8'));
89
+ }
90
+ catch {
91
+ existing = {};
92
+ }
93
+ }
94
+ const merged = { ...(existing.hooks ?? {}) };
95
+ for (const [event, hooks] of Object.entries(generated.hooks)) {
96
+ const current = merged[event] ?? [];
97
+ // Check if any existing hook already contains 'rulemetric'
98
+ const hasRulemetric = current.some((h) => typeof h === 'object' &&
99
+ h !== null &&
100
+ 'command' in h &&
101
+ typeof h.command === 'string' &&
102
+ h.command.includes('rulemetric'));
103
+ if (!hasRulemetric) {
104
+ merged[event] = [...current, ...hooks];
105
+ }
106
+ }
107
+ const result = {
108
+ version: existing.version ?? generated.version,
109
+ hooks: merged,
110
+ };
111
+ writeFileSync(configPath, JSON.stringify(result, null, 2) + '\n');
112
+ return configPath;
113
+ }
114
+ /**
115
+ * Write Copilot Agent hooks config to `.github/hooks/rulemetric.json`.
116
+ * Creates the hooks directory if needed.
117
+ * Returns the config file path, or null if `.github/` doesn't exist.
118
+ */
119
+ export function writeCopilotHooks(projectPath) {
120
+ const githubDir = join(projectPath, '.github');
121
+ if (!existsSync(githubDir)) {
122
+ return null;
123
+ }
124
+ const hooksDir = join(githubDir, 'hooks');
125
+ mkdirSync(hooksDir, { recursive: true });
126
+ const configPath = join(hooksDir, 'rulemetric.json');
127
+ const config = generateCopilotHooksConfig();
128
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
129
+ return configPath;
130
+ }
131
+ /**
132
+ * Remove rulemetric hooks from `.cursor/hooks.json`.
133
+ * Preserves other hooks and removes empty event arrays.
134
+ * Returns true if changes were made.
135
+ */
136
+ export function removeCursorHooks(projectPath) {
137
+ const configPath = join(projectPath, '.cursor', 'hooks.json');
138
+ if (!existsSync(configPath)) {
139
+ return false;
140
+ }
141
+ let config;
142
+ try {
143
+ config = JSON.parse(readFileSync(configPath, 'utf-8'));
144
+ }
145
+ catch {
146
+ return false;
147
+ }
148
+ if (!config.hooks) {
149
+ return false;
150
+ }
151
+ let changed = false;
152
+ for (const [event, hooks] of Object.entries(config.hooks)) {
153
+ const filtered = hooks.filter((h) => {
154
+ if (typeof h !== 'object' || h === null || !('command' in h))
155
+ return true;
156
+ const cmd = h.command;
157
+ if (typeof cmd === 'string' && cmd.includes('rulemetric')) {
158
+ changed = true;
159
+ return false;
160
+ }
161
+ return true;
162
+ });
163
+ if (filtered.length === 0) {
164
+ delete config.hooks[event];
165
+ }
166
+ else {
167
+ config.hooks[event] = filtered;
168
+ }
169
+ }
170
+ if (changed) {
171
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
172
+ }
173
+ return changed;
174
+ }
175
+ /**
176
+ * Write Cursor proxy config to `.cursor/settings.json`.
177
+ * Sets `http.proxy` and `http.proxyStrictSSL` while preserving existing settings.
178
+ * Returns true if `.cursor/` exists and config was written, false otherwise.
179
+ */
180
+ export function writeCursorProxyConfig(projectPath, gatewayPort, certPath) {
181
+ const cursorDir = join(projectPath, '.cursor');
182
+ if (!existsSync(cursorDir))
183
+ return false;
184
+ const settingsPath = join(cursorDir, 'settings.json');
185
+ let settings = {};
186
+ if (existsSync(settingsPath)) {
187
+ try {
188
+ settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
189
+ }
190
+ catch { /* empty */ }
191
+ }
192
+ settings['http.proxy'] = `http://localhost:${gatewayPort}`;
193
+ settings['http.proxyStrictSSL'] = existsSync(certPath);
194
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
195
+ return true;
196
+ }
197
+ /**
198
+ * Write VS Code proxy config to `.vscode/settings.json` for Copilot capture.
199
+ * Sets `http.proxy`, `http.proxyStrictSSL`, and Copilot-specific override
200
+ * while preserving existing settings.
201
+ * Returns true if config was written, false if `.vscode/` doesn't exist.
202
+ */
203
+ export function writeVSCodeProxyConfig(projectPath, gatewayPort, certPath) {
204
+ const vscodeDir = join(projectPath, '.vscode');
205
+ mkdirSync(vscodeDir, { recursive: true });
206
+ const settingsPath = join(vscodeDir, 'settings.json');
207
+ let settings = {};
208
+ if (existsSync(settingsPath)) {
209
+ try {
210
+ settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
211
+ }
212
+ catch { /* empty */ }
213
+ }
214
+ settings['http.proxy'] = `http://localhost:${gatewayPort}`;
215
+ settings['http.proxyStrictSSL'] = existsSync(certPath);
216
+ // Copilot-specific override for surgical proxy targeting
217
+ const copilotAdvanced = (settings['github.copilot.advanced'] ?? {});
218
+ copilotAdvanced['debug.overrideProxyUrl'] = `http://localhost:${gatewayPort}`;
219
+ settings['github.copilot.advanced'] = copilotAdvanced;
220
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
221
+ return true;
222
+ }
223
+ /**
224
+ * Remove VS Code proxy config from `.vscode/settings.json`.
225
+ * Removes `http.proxy`, `http.proxyStrictSSL`, and Copilot proxy override.
226
+ * Returns true if changes were made.
227
+ */
228
+ export function removeVSCodeProxyConfig(projectPath) {
229
+ const settingsPath = join(projectPath, '.vscode', 'settings.json');
230
+ if (!existsSync(settingsPath))
231
+ return false;
232
+ let settings;
233
+ try {
234
+ settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
235
+ }
236
+ catch {
237
+ return false;
238
+ }
239
+ let changed = false;
240
+ if (settings['http.proxy']) {
241
+ delete settings['http.proxy'];
242
+ delete settings['http.proxyStrictSSL'];
243
+ changed = true;
244
+ }
245
+ const copilotAdvanced = settings['github.copilot.advanced'];
246
+ if (copilotAdvanced?.['debug.overrideProxyUrl']) {
247
+ delete copilotAdvanced['debug.overrideProxyUrl'];
248
+ if (Object.keys(copilotAdvanced).length === 0) {
249
+ delete settings['github.copilot.advanced'];
250
+ }
251
+ changed = true;
252
+ }
253
+ if (changed) {
254
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
255
+ }
256
+ return changed;
257
+ }
258
+ /**
259
+ * Remove Copilot Agent hooks by deleting `.github/hooks/rulemetric.json`.
260
+ * Returns true if the file was removed.
261
+ */
262
+ export function removeCopilotHooks(projectPath) {
263
+ const configPath = join(projectPath, '.github', 'hooks', 'rulemetric.json');
264
+ if (!existsSync(configPath)) {
265
+ return false;
266
+ }
267
+ unlinkSync(configPath);
268
+ return true;
269
+ }
270
+ // ---------------------------------------------------------------------------
271
+ // macOS LaunchAgent for GUI app env vars (HTTPS_PROXY, NODE_EXTRA_CA_CERTS)
272
+ // ---------------------------------------------------------------------------
273
+ const LAUNCH_AGENT_LABEL = 'com.rulemetric.env';
274
+ function getLaunchAgentPath() {
275
+ return join(homedir(), 'Library', 'LaunchAgents', `${LAUNCH_AGENT_LABEL}.plist`);
276
+ }
277
+ /**
278
+ * Set HTTPS_PROXY and NODE_EXTRA_CA_CERTS for all GUI apps on macOS.
279
+ *
280
+ * Two layers:
281
+ * 1. `launchctl setenv` — immediate effect for newly launched apps
282
+ * 2. LaunchAgent plist — persists across reboots
283
+ *
284
+ * This ensures VS Code / Copilot / Cursor route LLM traffic through the
285
+ * gateway even when launched from Dock or Spotlight (not a terminal).
286
+ *
287
+ * References:
288
+ * - anthropics/claude-code#30318 (same pattern for Claude Desktop)
289
+ * - Snyk IDE docs recommend launchctl setenv for macOS
290
+ * - Apple QA1067 (archived) — original env var mechanism removed in 10.10
291
+ */
292
+ export function installMacOSProxyEnv(gatewayPort, certPath) {
293
+ if (process.platform !== 'darwin')
294
+ return false;
295
+ const proxyUrl = `http://localhost:${gatewayPort}`;
296
+ // Layer 1: immediate effect via launchctl setenv
297
+ try {
298
+ execSync(`launchctl setenv HTTPS_PROXY ${proxyUrl}`, { stdio: 'pipe' });
299
+ if (existsSync(certPath)) {
300
+ execSync(`launchctl setenv NODE_EXTRA_CA_CERTS ${certPath}`, { stdio: 'pipe' });
301
+ }
302
+ }
303
+ catch {
304
+ return false;
305
+ }
306
+ // Layer 2: LaunchAgent plist for persistence across reboots
307
+ const plistPath = getLaunchAgentPath();
308
+ const agentsDir = join(homedir(), 'Library', 'LaunchAgents');
309
+ mkdirSync(agentsDir, { recursive: true });
310
+ const certLine = existsSync(certPath)
311
+ ? `launchctl setenv NODE_EXTRA_CA_CERTS ${certPath};`
312
+ : '';
313
+ const plist = `<?xml version="1.0" encoding="UTF-8"?>
314
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
315
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
316
+ <plist version="1.0">
317
+ <dict>
318
+ <key>Label</key>
319
+ <string>${LAUNCH_AGENT_LABEL}</string>
320
+ <key>ProgramArguments</key>
321
+ <array>
322
+ <string>/bin/sh</string>
323
+ <string>-c</string>
324
+ <string>launchctl setenv HTTPS_PROXY ${proxyUrl};${certLine}</string>
325
+ </array>
326
+ <key>RunAtLoad</key>
327
+ <true/>
328
+ </dict>
329
+ </plist>
330
+ `;
331
+ writeFileSync(plistPath, plist);
332
+ return true;
333
+ }
334
+ /**
335
+ * Remove the RuleMetric LaunchAgent and unset env vars.
336
+ */
337
+ export function uninstallMacOSProxyEnv() {
338
+ if (process.platform !== 'darwin')
339
+ return false;
340
+ let changed = false;
341
+ // Unset env vars for current session
342
+ try {
343
+ execSync('launchctl unsetenv HTTPS_PROXY', { stdio: 'pipe' });
344
+ execSync('launchctl unsetenv NODE_EXTRA_CA_CERTS', { stdio: 'pipe' });
345
+ }
346
+ catch { /* may not be set */ }
347
+ // Remove LaunchAgent plist
348
+ const plistPath = getLaunchAgentPath();
349
+ if (existsSync(plistPath)) {
350
+ unlinkSync(plistPath);
351
+ changed = true;
352
+ }
353
+ return changed;
354
+ }
355
+ // ---------------------------------------------------------------------------
356
+ // VS Code user-level proxy settings
357
+ // ---------------------------------------------------------------------------
358
+ function getVSCodeUserSettingsPath() {
359
+ if (process.platform === 'darwin') {
360
+ return join(homedir(), 'Library', 'Application Support', 'Code', 'User', 'settings.json');
361
+ }
362
+ if (process.platform === 'win32') {
363
+ return join(process.env.APPDATA ?? '', 'Code', 'User', 'settings.json');
364
+ }
365
+ return join(homedir(), '.config', 'Code', 'User', 'settings.json');
366
+ }
367
+ /**
368
+ * Set http.proxy in VS Code user settings (not workspace).
369
+ *
370
+ * Workspace-level http.proxy is silently ignored because VS Code restricts
371
+ * it to APPLICATION scope (microsoft/vscode#236932). User-level settings
372
+ * are the only reliable way to configure http.proxy.
373
+ */
374
+ export function writeVSCodeUserProxyConfig(gatewayPort) {
375
+ const settingsPath = getVSCodeUserSettingsPath();
376
+ if (!existsSync(join(settingsPath, '..')))
377
+ return false;
378
+ let settings = {};
379
+ if (existsSync(settingsPath)) {
380
+ try {
381
+ settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
382
+ }
383
+ catch { /* empty */ }
384
+ }
385
+ // Only set if not already configured by the user
386
+ if (settings['http.proxy'] && !settings['http.proxy'].includes('localhost')) {
387
+ return false; // user has a custom proxy, don't overwrite
388
+ }
389
+ settings['http.proxy'] = `http://localhost:${gatewayPort}`;
390
+ settings['http.proxyStrictSSL'] = false;
391
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
392
+ return true;
393
+ }
394
+ /**
395
+ * Remove RuleMetric proxy config from VS Code user settings.
396
+ */
397
+ export function removeVSCodeUserProxyConfig() {
398
+ const settingsPath = getVSCodeUserSettingsPath();
399
+ if (!existsSync(settingsPath))
400
+ return false;
401
+ let settings;
402
+ try {
403
+ settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
404
+ }
405
+ catch {
406
+ return false;
407
+ }
408
+ const proxy = settings['http.proxy'];
409
+ if (!proxy?.includes('localhost'))
410
+ return false;
411
+ delete settings['http.proxy'];
412
+ delete settings['http.proxyStrictSSL'];
413
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
414
+ return true;
415
+ }
416
+ //# sourceMappingURL=hooks-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-config.js","sourceRoot":"","sources":["../../src/lib/hooks-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAmB;IACtD,MAAM,KAAK,GAAmB,CAAC,aAAa,CAAC,CAAC;IAE9C,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvB,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAC9B,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB;IACvC,OAAO;QACL,OAAO,EAAE,CAAC;QACV,KAAK,EAAE;YACL,kBAAkB,EAAE;gBAClB,EAAE,OAAO,EAAE,kCAAkC,EAAE;aAChD;YACD,aAAa,EAAE;gBACb,EAAE,OAAO,EAAE,oCAAoC,EAAE;aAClD;YACD,oBAAoB,EAAE;gBACpB,EAAE,OAAO,EAAE,oCAAoC,EAAE;aAClD;YACD,kBAAkB,EAAE;gBAClB,EAAE,OAAO,EAAE,oCAAoC,EAAE;aAClD;YACD,IAAI,EAAE;gBACJ,EAAE,OAAO,EAAE,kCAAkC,EAAE;aAChD;SACF;KACF,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B;IACxC,OAAO;QACL,OAAO,EAAE,CAAC;QACV,KAAK,EAAE;YACL,YAAY,EAAE;gBACZ,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,oCAAoC,EAAE;aAChE;YACD,mBAAmB,EAAE;gBACnB,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,kCAAkC,EAAE;aAC9D;YACD,WAAW,EAAE;gBACX,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,oCAAoC,EAAE;aAChE;YACD,UAAU,EAAE;gBACV,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,kCAAkC,EAAE;aAC9D;SACF;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAmB;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAC/C,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,yBAAyB,EAG1C,CAAC;IAEF,kCAAkC;IAClC,IAAI,QAAQ,GAA4D,EAAE,CAAC;IAC3E,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,GAAG,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAA8B,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;IAExE,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QAC7D,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACpC,2DAA2D;QAC3D,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAChC,CAAC,CAAU,EAAE,EAAE,CACb,OAAO,CAAC,KAAK,QAAQ;YACrB,CAAC,KAAK,IAAI;YACV,SAAS,IAAI,CAAC;YACd,OAAQ,CAAyB,CAAC,OAAO,KAAK,QAAQ;YACrD,CAAyB,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAC5D,CAAC;QACF,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,EAAE,GAAG,KAAK,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG;QACb,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,SAAS,CAAC,OAAO;QAC9C,KAAK,EAAE,MAAM;KACd,CAAC;IAEF,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAClE,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAC/C,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC1C,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEzC,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,0BAA0B,EAAE,CAAC;IAE5C,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAClE,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;IAC9D,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,MAA+D,CAAC;IACpE,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1D,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAU,EAAE,EAAE;YAC3C,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC1E,MAAM,GAAG,GAAI,CAAyB,CAAC,OAAO,CAAC;YAC/C,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC1D,OAAO,GAAG,IAAI,CAAC;gBACf,OAAO,KAAK,CAAC;YACf,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;QACjC,CAAC;IACH,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,WAAmB,EAAE,WAAmB,EAAE,QAAgB;IAC/F,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAC/C,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,KAAK,CAAC;IAEzC,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IACtD,IAAI,QAAQ,GAA4B,EAAE,CAAC;IAC3C,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;IAC3F,CAAC;IAED,QAAQ,CAAC,YAAY,CAAC,GAAG,oBAAoB,WAAW,EAAE,CAAC;IAC3D,QAAQ,CAAC,qBAAqB,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IACvD,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACtE,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,WAAmB,EAAE,WAAmB,EAAE,QAAgB;IAC/F,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAC/C,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1C,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IACtD,IAAI,QAAQ,GAA4B,EAAE,CAAC;IAC3C,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;IAC3F,CAAC;IAED,QAAQ,CAAC,YAAY,CAAC,GAAG,oBAAoB,WAAW,EAAE,CAAC;IAC3D,QAAQ,CAAC,qBAAqB,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAEvD,yDAAyD;IACzD,MAAM,eAAe,GAAG,CAAC,QAAQ,CAAC,yBAAyB,CAAC,IAAI,EAAE,CAA4B,CAAC;IAC/F,eAAe,CAAC,wBAAwB,CAAC,GAAG,oBAAoB,WAAW,EAAE,CAAC;IAC9E,QAAQ,CAAC,yBAAyB,CAAC,GAAG,eAAe,CAAC;IAEtD,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACtE,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,WAAmB;IACzD,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;IACnE,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5C,IAAI,QAAiC,CAAC;IACtC,IAAI,CAAC;QAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;IAE3F,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,IAAI,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC9B,OAAO,QAAQ,CAAC,qBAAqB,CAAC,CAAC;QACvC,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,MAAM,eAAe,GAAG,QAAQ,CAAC,yBAAyB,CAAwC,CAAC;IACnG,IAAI,eAAe,EAAE,CAAC,wBAAwB,CAAC,EAAE,CAAC;QAChD,OAAO,eAAe,CAAC,wBAAwB,CAAC,CAAC;QACjD,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9C,OAAO,QAAQ,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IACpD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC;IAC5E,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,UAAU,CAAC,UAAU,CAAC,CAAC;IACvB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,4EAA4E;AAC5E,8EAA8E;AAE9E,MAAM,kBAAkB,GAAG,oBAAoB,CAAC;AAEhD,SAAS,kBAAkB;IACzB,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,GAAG,kBAAkB,QAAQ,CAAC,CAAC;AACnF,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAmB,EAAE,QAAgB;IACxE,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAEhD,MAAM,QAAQ,GAAG,oBAAoB,WAAW,EAAE,CAAC;IAEnD,iDAAiD;IACjD,IAAI,CAAC;QACH,QAAQ,CAAC,gCAAgC,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACxE,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzB,QAAQ,CAAC,wCAAwC,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IAED,4DAA4D;IAC5D,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;IAC7D,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1C,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC;QACnC,CAAC,CAAC,wCAAwC,QAAQ,GAAG;QACrD,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,KAAK,GAAG;;;;;;YAMJ,kBAAkB;;;;;2CAKa,QAAQ,IAAI,QAAQ;;;;;;CAM9D,CAAC;IAEA,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAChC,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB;IACpC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAEhD,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,qCAAqC;IACrC,IAAI,CAAC;QACH,QAAQ,CAAC,gCAAgC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9D,QAAQ,CAAC,wCAAwC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAEhC,2BAA2B;IAC3B,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;IACvC,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,UAAU,CAAC,SAAS,CAAC,CAAC;QACtB,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,8EAA8E;AAC9E,oCAAoC;AACpC,8EAA8E;AAE9E,SAAS,yBAAyB;IAChC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;IAC5F,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;AACrE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B,CAAC,WAAmB;IAC5D,MAAM,YAAY,GAAG,yBAAyB,EAAE,CAAC;IACjD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAExD,IAAI,QAAQ,GAA4B,EAAE,CAAC;IAC3C,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,WAAW,CAAC,CAAC;IAC3F,CAAC;IAED,iDAAiD;IACjD,IAAI,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAE,QAAQ,CAAC,YAAY,CAAY,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QACxF,OAAO,KAAK,CAAC,CAAC,2CAA2C;IAC3D,CAAC;IAED,QAAQ,CAAC,YAAY,CAAC,GAAG,oBAAoB,WAAW,EAAE,CAAC;IAC3D,QAAQ,CAAC,qBAAqB,CAAC,GAAG,KAAK,CAAC;IAExC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACtE,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,2BAA2B;IACzC,MAAM,YAAY,GAAG,yBAAyB,EAAE,CAAC;IACjD,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,KAAK,CAAC;IAE5C,IAAI,QAAiC,CAAC;IACtC,IAAI,CAAC;QAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;IAE3F,MAAM,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAuB,CAAC;IAC3D,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC;QAAE,OAAO,KAAK,CAAC;IAEhD,OAAO,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC9B,OAAO,QAAQ,CAAC,qBAAqB,CAAC,CAAC;IACvC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACtE,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=hooks-config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks-config.test.d.ts","sourceRoot":"","sources":["../../src/lib/hooks-config.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,231 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, rmSync, existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { tmpdir } from 'node:os';
5
+ import { detectInstalledTools, generateCursorHooksConfig, generateCopilotHooksConfig, writeCursorHooks, writeCopilotHooks, writeCursorProxyConfig, removeCursorHooks, removeCopilotHooks, } from './hooks-config.js';
6
+ let tempDir;
7
+ beforeEach(() => {
8
+ tempDir = mkdtempSync(join(tmpdir(), 'hooks-config-test-'));
9
+ });
10
+ afterEach(() => {
11
+ rmSync(tempDir, { recursive: true, force: true });
12
+ });
13
+ describe('detectInstalledTools', () => {
14
+ it('always includes claude_code', () => {
15
+ const tools = detectInstalledTools(tempDir);
16
+ expect(tools).toContain('claude_code');
17
+ });
18
+ it('detects cursor when .cursor/ exists', () => {
19
+ mkdirSync(join(tempDir, '.cursor'));
20
+ const tools = detectInstalledTools(tempDir);
21
+ expect(tools).toContain('cursor');
22
+ });
23
+ it('detects copilot_agent when .github/ exists', () => {
24
+ mkdirSync(join(tempDir, '.github'));
25
+ const tools = detectInstalledTools(tempDir);
26
+ expect(tools).toContain('copilot_agent');
27
+ });
28
+ it('does not detect cursor or copilot when dirs are absent', () => {
29
+ const tools = detectInstalledTools(tempDir);
30
+ expect(tools).toEqual(['claude_code']);
31
+ });
32
+ });
33
+ describe('generateCursorHooksConfig', () => {
34
+ it('returns correct structure with version and hooks', () => {
35
+ const config = generateCursorHooksConfig();
36
+ expect(config.version).toBe(1);
37
+ expect(config.hooks).toBeDefined();
38
+ });
39
+ it('all hook commands contain "rulemetric hooks run"', () => {
40
+ const config = generateCursorHooksConfig();
41
+ for (const [, hooks] of Object.entries(config.hooks)) {
42
+ for (const hook of hooks) {
43
+ expect(hook.command).toContain('rulemetric hooks run');
44
+ }
45
+ }
46
+ });
47
+ it('includes all expected event names', () => {
48
+ const config = generateCursorHooksConfig();
49
+ expect(Object.keys(config.hooks)).toEqual(expect.arrayContaining([
50
+ 'beforeSubmitPrompt',
51
+ 'afterFileEdit',
52
+ 'beforeShellExecution',
53
+ 'beforeMCPExecution',
54
+ 'stop',
55
+ ]));
56
+ });
57
+ });
58
+ describe('generateCopilotHooksConfig', () => {
59
+ it('returns correct structure with version and hooks', () => {
60
+ const config = generateCopilotHooksConfig();
61
+ expect(config.version).toBe(1);
62
+ expect(config.hooks).toBeDefined();
63
+ });
64
+ it('all hook bash commands contain "rulemetric hooks run"', () => {
65
+ const config = generateCopilotHooksConfig();
66
+ for (const [, hooks] of Object.entries(config.hooks)) {
67
+ for (const hook of hooks) {
68
+ expect(hook.bash).toContain('rulemetric hooks run');
69
+ expect(hook.type).toBe('command');
70
+ }
71
+ }
72
+ });
73
+ it('includes all expected event names', () => {
74
+ const config = generateCopilotHooksConfig();
75
+ expect(Object.keys(config.hooks)).toEqual(expect.arrayContaining([
76
+ 'sessionStart',
77
+ 'userPromptSubmitted',
78
+ 'postToolUse',
79
+ 'sessionEnd',
80
+ ]));
81
+ });
82
+ });
83
+ describe('writeCursorHooks', () => {
84
+ it('returns null when .cursor/ does not exist', () => {
85
+ expect(writeCursorHooks(tempDir)).toBeNull();
86
+ });
87
+ it('writes config and returns file path', () => {
88
+ mkdirSync(join(tempDir, '.cursor'));
89
+ const result = writeCursorHooks(tempDir);
90
+ expect(result).toBe(join(tempDir, '.cursor', 'hooks.json'));
91
+ expect(existsSync(result)).toBe(true);
92
+ const written = JSON.parse(readFileSync(result, 'utf-8'));
93
+ expect(written.version).toBe(1);
94
+ expect(written.hooks.beforeSubmitPrompt).toBeDefined();
95
+ });
96
+ it('merges with existing config without duplicating', () => {
97
+ const cursorDir = join(tempDir, '.cursor');
98
+ mkdirSync(cursorDir);
99
+ // Write existing config with a custom hook
100
+ const existing = {
101
+ version: 1,
102
+ hooks: {
103
+ beforeSubmitPrompt: [{ command: 'my-custom-tool' }],
104
+ },
105
+ };
106
+ writeFileSync(join(cursorDir, 'hooks.json'), JSON.stringify(existing));
107
+ // First install
108
+ writeCursorHooks(tempDir);
109
+ // Second install (should not duplicate)
110
+ writeCursorHooks(tempDir);
111
+ const config = JSON.parse(readFileSync(join(cursorDir, 'hooks.json'), 'utf-8'));
112
+ const promptHooks = config.hooks.beforeSubmitPrompt;
113
+ // Should have the custom hook + one rulemetric hook (not two)
114
+ const rulemetricHooks = promptHooks.filter((h) => h.command.includes('rulemetric'));
115
+ expect(rulemetricHooks).toHaveLength(1);
116
+ expect(promptHooks).toHaveLength(2); // custom + rulemetric
117
+ });
118
+ it('preserves existing hooks from other tools', () => {
119
+ const cursorDir = join(tempDir, '.cursor');
120
+ mkdirSync(cursorDir);
121
+ const existing = {
122
+ version: 1,
123
+ hooks: {
124
+ beforeSubmitPrompt: [{ command: 'other-tool run lint' }],
125
+ customEvent: [{ command: 'something-else' }],
126
+ },
127
+ };
128
+ writeFileSync(join(cursorDir, 'hooks.json'), JSON.stringify(existing));
129
+ writeCursorHooks(tempDir);
130
+ const config = JSON.parse(readFileSync(join(cursorDir, 'hooks.json'), 'utf-8'));
131
+ expect(config.hooks.customEvent).toEqual([{ command: 'something-else' }]);
132
+ expect(config.hooks.beforeSubmitPrompt).toHaveLength(2);
133
+ });
134
+ });
135
+ describe('writeCopilotHooks', () => {
136
+ it('returns null when .github/ does not exist', () => {
137
+ expect(writeCopilotHooks(tempDir)).toBeNull();
138
+ });
139
+ it('writes config and creates hooks dir', () => {
140
+ mkdirSync(join(tempDir, '.github'));
141
+ const result = writeCopilotHooks(tempDir);
142
+ expect(result).toBe(join(tempDir, '.github', 'hooks', 'rulemetric.json'));
143
+ expect(existsSync(result)).toBe(true);
144
+ const written = JSON.parse(readFileSync(result, 'utf-8'));
145
+ expect(written.version).toBe(1);
146
+ expect(written.hooks.sessionStart).toBeDefined();
147
+ });
148
+ it('creates .github/hooks/ directory if missing', () => {
149
+ mkdirSync(join(tempDir, '.github'));
150
+ const hooksDir = join(tempDir, '.github', 'hooks');
151
+ expect(existsSync(hooksDir)).toBe(false);
152
+ writeCopilotHooks(tempDir);
153
+ expect(existsSync(hooksDir)).toBe(true);
154
+ });
155
+ });
156
+ describe('writeCursorProxyConfig', () => {
157
+ it('writes http.proxy to .cursor/settings.json', () => {
158
+ mkdirSync(join(tempDir, '.cursor'));
159
+ const result = writeCursorProxyConfig(tempDir, 8787, '/nonexistent/cert.pem');
160
+ expect(result).toBe(true);
161
+ const settings = JSON.parse(readFileSync(join(tempDir, '.cursor', 'settings.json'), 'utf-8'));
162
+ expect(settings['http.proxy']).toBe('http://localhost:8787');
163
+ expect(settings['http.proxyStrictSSL']).toBe(false); // cert doesn't exist
164
+ });
165
+ it('preserves existing Cursor settings', () => {
166
+ mkdirSync(join(tempDir, '.cursor'));
167
+ writeFileSync(join(tempDir, '.cursor', 'settings.json'), JSON.stringify({ 'editor.fontSize': 14 }));
168
+ writeCursorProxyConfig(tempDir, 8787, '/nonexistent/cert.pem');
169
+ const settings = JSON.parse(readFileSync(join(tempDir, '.cursor', 'settings.json'), 'utf-8'));
170
+ expect(settings['editor.fontSize']).toBe(14);
171
+ expect(settings['http.proxy']).toBe('http://localhost:8787');
172
+ });
173
+ it('returns false when .cursor/ does not exist', () => {
174
+ expect(writeCursorProxyConfig(tempDir, 8787, '/cert.pem')).toBe(false);
175
+ });
176
+ });
177
+ describe('removeCursorHooks', () => {
178
+ it('returns false when no .cursor/hooks.json exists', () => {
179
+ expect(removeCursorHooks(tempDir)).toBe(false);
180
+ });
181
+ it('removes rulemetric entries and preserves others', () => {
182
+ const cursorDir = join(tempDir, '.cursor');
183
+ mkdirSync(cursorDir);
184
+ const config = {
185
+ version: 1,
186
+ hooks: {
187
+ beforeSubmitPrompt: [
188
+ { command: 'other-tool lint' },
189
+ { command: 'rulemetric hooks run user-prompt' },
190
+ ],
191
+ stop: [{ command: 'rulemetric hooks run session-end' }],
192
+ },
193
+ };
194
+ writeFileSync(join(cursorDir, 'hooks.json'), JSON.stringify(config));
195
+ const result = removeCursorHooks(tempDir);
196
+ expect(result).toBe(true);
197
+ const updated = JSON.parse(readFileSync(join(cursorDir, 'hooks.json'), 'utf-8'));
198
+ // beforeSubmitPrompt should only have the other-tool entry
199
+ expect(updated.hooks.beforeSubmitPrompt).toEqual([{ command: 'other-tool lint' }]);
200
+ // stop should be removed entirely (was only rulemetric)
201
+ expect(updated.hooks.stop).toBeUndefined();
202
+ });
203
+ it('returns false when no rulemetric hooks are present', () => {
204
+ const cursorDir = join(tempDir, '.cursor');
205
+ mkdirSync(cursorDir);
206
+ const config = {
207
+ version: 1,
208
+ hooks: {
209
+ beforeSubmitPrompt: [{ command: 'other-tool lint' }],
210
+ },
211
+ };
212
+ writeFileSync(join(cursorDir, 'hooks.json'), JSON.stringify(config));
213
+ expect(removeCursorHooks(tempDir)).toBe(false);
214
+ });
215
+ });
216
+ describe('removeCopilotHooks', () => {
217
+ it('returns false when rulemetric.json does not exist', () => {
218
+ expect(removeCopilotHooks(tempDir)).toBe(false);
219
+ });
220
+ it('deletes rulemetric.json and returns true', () => {
221
+ const hooksDir = join(tempDir, '.github', 'hooks');
222
+ mkdirSync(hooksDir, { recursive: true });
223
+ const configPath = join(hooksDir, 'rulemetric.json');
224
+ writeFileSync(configPath, '{}');
225
+ expect(existsSync(configPath)).toBe(true);
226
+ const result = removeCopilotHooks(tempDir);
227
+ expect(result).toBe(true);
228
+ expect(existsSync(configPath)).toBe(false);
229
+ });
230
+ });
231
+ //# sourceMappingURL=hooks-config.test.js.map