@a-company/paradigm 5.10.0 → 5.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (409) hide show
  1. package/dist/accept-orchestration-IUAWQZUN.js +18 -0
  2. package/dist/add-P76GEMGF.js +8 -0
  3. package/dist/agent-UUTYOFTH.js +33 -0
  4. package/dist/agent-loader-EPXURMO7.js +2 -0
  5. package/dist/agent-loader-PYGPX6D2.js +2 -0
  6. package/dist/agent-state-KSQ3S7OB.js +2 -0
  7. package/dist/agents-suggest-HYTFMQD3.js +10 -0
  8. package/dist/aggregate-W66DM3GA.js +10 -0
  9. package/dist/ambient-HYZR42NX.js +35 -0
  10. package/dist/assess-UFPYEJKP.js +9 -0
  11. package/dist/auto-RHJXOZFL.js +14 -0
  12. package/dist/beacon-5QVYV5DF.js +13 -0
  13. package/dist/calibration-OLJYB5HN.js +7 -0
  14. package/dist/check-THVGY4R5.js +14 -0
  15. package/dist/chunk-22ISTMKI.js +31 -0
  16. package/dist/chunk-2QO33NYK.js +3 -0
  17. package/dist/chunk-33LKBMVK.js +134 -0
  18. package/dist/chunk-4QADCWPU.js +7 -0
  19. package/dist/chunk-4TXOVRWD.js +3 -0
  20. package/dist/chunk-4UJ4NIEQ.js +4 -0
  21. package/dist/chunk-4ZGGWZ32.js +3 -0
  22. package/dist/chunk-5TAVYPOV.js +2 -0
  23. package/dist/chunk-6EX37L4Q.js +8 -0
  24. package/dist/chunk-AD5TAD2A.js +5 -0
  25. package/dist/chunk-AGVAHVUA.js +2 -0
  26. package/dist/chunk-AO7ZSRME.js +13 -0
  27. package/dist/chunk-BFD3GFRK.js +2 -0
  28. package/dist/chunk-D34YFK4M.js +6 -0
  29. package/dist/chunk-DVZWCXB6.js +2 -0
  30. package/dist/chunk-EKZDFEJW.js +2 -0
  31. package/dist/chunk-ET5XJTSX.js +2 -0
  32. package/dist/chunk-FYDRENK7.js +3 -0
  33. package/dist/chunk-HMQ5BHP2.js +743 -0
  34. package/dist/chunk-HXKWL3VK.js +29 -0
  35. package/dist/chunk-IZSBGW6E.js +2 -0
  36. package/dist/chunk-J32OPJEX.js +2 -0
  37. package/dist/chunk-JBDMCRPP.js +7 -0
  38. package/dist/chunk-JIXHEBGK.js +7 -0
  39. package/dist/chunk-JNSJVCTU.js +2 -0
  40. package/dist/chunk-JQKKVAAN.js +2 -0
  41. package/dist/chunk-KLBH26PA.js +429 -0
  42. package/dist/chunk-L6K5HNDL.js +24 -0
  43. package/dist/chunk-LKAT7IAK.js +2 -0
  44. package/dist/chunk-M4UMM6DC.js +5 -0
  45. package/dist/chunk-NKYNHSA5.js +424 -0
  46. package/dist/chunk-NW6OKHE6.js +5 -0
  47. package/dist/chunk-NXRVR37G.js +60 -0
  48. package/dist/chunk-ODVKPZZ4.js +2 -0
  49. package/dist/chunk-PUBB7LIT.js +5 -0
  50. package/dist/chunk-Q2J542ST.js +2 -0
  51. package/dist/chunk-QGZRM6ZB.js +2 -0
  52. package/dist/chunk-QNZEG7IT.js +13 -0
  53. package/dist/chunk-QT2LKB3P.js +7 -0
  54. package/dist/chunk-RVRARWSY.js +9 -0
  55. package/dist/chunk-T6IDXUUA.js +2 -0
  56. package/dist/chunk-TYWB5IQJ.js +3 -0
  57. package/dist/chunk-UIKLE3WD.js +2 -0
  58. package/dist/chunk-V7K6CQVX.js +111 -0
  59. package/dist/chunk-VCKKJDLP.js +8 -0
  60. package/dist/chunk-VG7FN2TU.js +4 -0
  61. package/dist/chunk-W5IWDW4Y.js +16 -0
  62. package/dist/chunk-W7C6FFMO.js +8 -0
  63. package/dist/chunk-WESTEMIM.js +10 -0
  64. package/dist/chunk-WR6D3SC6.js +5 -0
  65. package/dist/chunk-WS2N27RX.js +3 -0
  66. package/dist/chunk-XMAV5AG6.js +2 -0
  67. package/dist/chunk-XROULIQN.js +2 -0
  68. package/dist/chunk-XUFYOXOU.js +3 -0
  69. package/dist/chunk-Y4XFVDZC.js +3 -0
  70. package/dist/chunk-Y6KXTQBG.js +2 -0
  71. package/dist/{chunk-GTR2TBIJ.js → chunk-Z2UZUCY6.js} +237 -1047
  72. package/dist/chunk-Z34K6GY2.js +8 -0
  73. package/dist/claude-4LR3LJQZ.js +13 -0
  74. package/dist/claude-cli-UP6HGH7C.js +6 -0
  75. package/dist/claude-code-RLJ4GX77.js +11 -0
  76. package/dist/claude-code-teams-R37HJY3Y.js +29 -0
  77. package/dist/commands-LMUD5L6R.js +455 -0
  78. package/dist/compliance-GZ7UAOG3.js +6 -0
  79. package/dist/conductor-Y5IXELTL.js +4 -0
  80. package/dist/config-schema-HR7LDEQ6.js +2 -0
  81. package/dist/constellation-CG7C4WFE.js +13 -0
  82. package/dist/context-audit-RSSRX6XC.js +6 -0
  83. package/dist/cost-IDNVMAEV.js +10 -0
  84. package/dist/cost-PK4KIF7R.js +2 -0
  85. package/dist/cursor-cli-QKF7Z6M2.js +4 -0
  86. package/dist/cursorrules-U5O4G5T4.js +14 -0
  87. package/dist/decision-loader-2XPZE4EZ.js +2 -0
  88. package/dist/delete-P5VULXR4.js +14 -0
  89. package/dist/diff-RTFUKJHF.js +9 -0
  90. package/dist/discipline-H7LDI6NT.js +2 -0
  91. package/dist/dist-3ZCH25SG.js +2 -0
  92. package/dist/dist-KGRCLBJP-2QAPFYNF.js +39 -0
  93. package/dist/dist-R3RWD35F.js +2 -0
  94. package/dist/dist-VGFSP3XM.js +2 -0
  95. package/dist/dist-VXCZWVVJ.js +2 -0
  96. package/dist/dist-W3XCATBJ.js +2 -0
  97. package/dist/docs-EDQ2STFK.js +2 -0
  98. package/dist/docs-RXPN6CK7.js +12 -0
  99. package/dist/doctor-2T2QL6VM.js +2 -0
  100. package/dist/drift-ILZE5BFJ.js +13 -0
  101. package/dist/echo-UPTQUEDU.js +46 -0
  102. package/dist/edit-GUU3HBVW.js +9 -0
  103. package/dist/event-Y3VXC2RV.js +3 -0
  104. package/dist/explain-files-3GPZUETV.js +4 -0
  105. package/dist/export-CV5KCTPS.js +2 -0
  106. package/dist/flow-S3RQ4YPY.js +11 -0
  107. package/dist/global-C44FW4G2.js +13 -0
  108. package/dist/graduate-3BBSC27A.js +5 -0
  109. package/dist/graph-CNDE5TAT.js +2 -0
  110. package/dist/graph-server-COZR5C3Z.js +14 -0
  111. package/dist/habits-4J2KRYUL.js +42 -0
  112. package/dist/history-UW454SDP.js +12 -0
  113. package/dist/hooks-XH52VGOU.js +2 -0
  114. package/dist/index.js +15 -1039
  115. package/dist/init-24MAQJFM.js +2 -0
  116. package/dist/integrity-UYDOOJDP.js +7 -0
  117. package/dist/integrity-checker-DHGMZQDG.js +2 -0
  118. package/dist/journal-loader-GLH7XFTK.js +2 -0
  119. package/dist/lint-IGKE6UPS.js +26 -0
  120. package/dist/list-5IUGP3ZB.js +7 -0
  121. package/dist/list-YKIQNKGB.js +6 -0
  122. package/dist/lore-loader-RVQI5GXL.js +2 -0
  123. package/dist/lore-loader-XY5MZRR2.js +2 -0
  124. package/dist/lore-server-FC2GMDLT.js +14 -0
  125. package/dist/manual-RXSPSFLL.js +20 -0
  126. package/dist/mcp.js +93 -20484
  127. package/dist/migrate-X5OMAFAQ.js +59 -0
  128. package/dist/migrate-assessments-GEI5WMI2.js +4 -0
  129. package/dist/model-discovery-HMB3YI4L.js +2 -0
  130. package/dist/nomination-engine-XF7TWPAP.js +2 -0
  131. package/dist/notebook-PE3JSYZI.js +11 -0
  132. package/dist/notebook-loader-CENTDDUJ.js +2 -0
  133. package/dist/orchestrate-35HBQ3O3.js +8 -0
  134. package/dist/peers-P2KXU7ZK.js +5 -0
  135. package/dist/persona-STQWZH5P.js +29 -0
  136. package/dist/pipeline-MZUITRVN.js +4 -0
  137. package/dist/platform-server-2KXHGHFV.js +25 -0
  138. package/dist/plugin-update-checker-M7PW434O.js +2 -0
  139. package/dist/portal-check-3JVNLOEP.js +8 -0
  140. package/dist/portal-compliance-2UG4VKWH.js +2 -0
  141. package/dist/probe-5L5BQDGE.js +6 -0
  142. package/dist/project-type-SURTOIG7.js +2 -0
  143. package/dist/promote-NJQDZBZA.js +8 -0
  144. package/dist/providers-4PXMWA7V.js +8 -0
  145. package/dist/quiz-FE5UGAY2.js +10 -0
  146. package/dist/record-YXPB34MY.js +6 -0
  147. package/dist/reindex-PGDQSM42.js +2 -0
  148. package/dist/remember-MJRNTXYS.js +14 -0
  149. package/dist/retag-N5XF3KXP.js +6 -0
  150. package/dist/review-6UAH6V3R.js +11 -0
  151. package/dist/review-77QI6VOC.js +6 -0
  152. package/dist/ripple-ZGDITCGB.js +10 -0
  153. package/dist/roster-FLRZ5J42.js +2 -0
  154. package/dist/sentinel-HYAZ3CO5.js +19 -0
  155. package/dist/sentinel-bridge-VR357PKL.js +2 -0
  156. package/dist/sentinel-mcp.js +38 -3808
  157. package/dist/sentinel.js +1 -34
  158. package/dist/serve-JE6UF5P2.js +8 -0
  159. package/dist/serve-L52ZUTU6.js +10 -0
  160. package/dist/serve-OY6XYL7F.js +12 -0
  161. package/dist/server-2MNROHF6.js +7 -0
  162. package/dist/server-4YNUIK4W.js +8 -0
  163. package/dist/session-tracker-SKOMBDOW.js +2 -0
  164. package/dist/session-work-log-3MNUDEZ6.js +2 -0
  165. package/dist/session-work-log-J2H5OZBR.js +2 -0
  166. package/dist/setup-3F5IK7MO.js +31 -0
  167. package/dist/setup-KPIMRZ4Q.js +2 -0
  168. package/dist/shift-6GCNH666.js +11 -0
  169. package/dist/show-BOAVWZPZ.js +7 -0
  170. package/dist/show-PJ5LFLIL.js +5 -0
  171. package/dist/snapshot-L2G56RPL.js +8 -0
  172. package/dist/spawn-UH5RENSE.js +12 -0
  173. package/dist/status-77M3SDIF.js +8 -0
  174. package/dist/status-A37ECYNJ.js +6 -0
  175. package/dist/summary-ZJLQ6KHB.js +7 -0
  176. package/dist/sweep-HU74OPVW.js +17 -0
  177. package/dist/switch-CTW4PDGI.js +17 -0
  178. package/dist/symphony-3QMBGCZY.js +2 -0
  179. package/dist/symphony-QI63XL62.js +53 -0
  180. package/dist/symphony-loader-XACVV2E3.js +2 -0
  181. package/dist/symphony-peers-U4KHMKGI.js +2 -0
  182. package/dist/symphony-peers-X5NGWXFP.js +2 -0
  183. package/dist/symphony-relay-5GY5JIPT.js +3 -0
  184. package/dist/sync-QRDSFETO.js +2 -0
  185. package/dist/sync-llms-HL5PPW3M.js +15 -0
  186. package/dist/task-loader-NZFDTUQ5.js +2 -0
  187. package/dist/team-WGERKGNP.js +2 -0
  188. package/dist/test-BQJMS4Y2.js +111 -0
  189. package/dist/thread-HFXK65D4.js +41 -0
  190. package/dist/timeline-K3ZFKJ3R.js +6 -0
  191. package/dist/triage-FCWOZASE.js +18 -0
  192. package/dist/tutorial-UC6YQMNN.js +305 -0
  193. package/dist/university-content/courses/.purpose +74 -5
  194. package/dist/university-content/courses/para-701.json +807 -0
  195. package/dist/university-content/plsat/.purpose +3 -2
  196. package/dist/university-ui/assets/{index-BjewBB6s.js → index-CGFJczb1.js} +2 -2
  197. package/dist/university-ui/assets/{index-BjewBB6s.js.map → index-CGFJczb1.js.map} +1 -1
  198. package/dist/university-ui/index.html +1 -1
  199. package/dist/upgrade-B4IOLZYK.js +53 -0
  200. package/dist/validate-C6SMKGYD.js +9 -0
  201. package/dist/validate-LSCDOLBO.js +13 -0
  202. package/dist/validate-VZXTJHGO.js +6 -0
  203. package/dist/watch-LRM5XD46.js +8 -0
  204. package/dist/watch-PZCCUP6K.js +9 -0
  205. package/dist/wisdom-XZ3QKPNP.js +7 -0
  206. package/dist/work-log-loader-DL5GZ2BQ.js +2 -0
  207. package/dist/workspace-2ODL5WLY.js +2 -0
  208. package/package.json +1 -1
  209. package/platform-ui/dist/assets/AmbientSection-DqQ2mfCO.js +1 -0
  210. package/platform-ui/dist/assets/{CanvasSection-DwPTRdIN.js → CanvasSection-DLW0s-Bu.js} +1 -1
  211. package/platform-ui/dist/assets/{DocsSection-BJc_ws4I.js → DocsSection-BQ9Hi51g.js} +1 -1
  212. package/platform-ui/dist/assets/{GitSection-DhqBo1xc.js → GitSection-QQeUX6o3.js} +1 -1
  213. package/platform-ui/dist/assets/{GraphSection-D9fhVnZ0.js → GraphSection-0c9C-w7K.js} +2 -2
  214. package/platform-ui/dist/assets/{GraphSection-BlgXTl53.css → GraphSection-Bbs2a8sC.css} +1 -1
  215. package/platform-ui/dist/assets/LoreSection--t56kCj2.js +1 -0
  216. package/platform-ui/dist/assets/LoreSection-qnmm3o4y.css +1 -0
  217. package/platform-ui/dist/assets/SentinelSection-C4OoME9U.js +1 -0
  218. package/platform-ui/dist/assets/{SymphonySection-BRoBaUSS.js → SymphonySection-B-rvsLxq.js} +1 -1
  219. package/platform-ui/dist/assets/TeamSection-CBFmNEEo.js +1 -0
  220. package/platform-ui/dist/assets/index-Bxp0TVaf.css +1 -0
  221. package/platform-ui/dist/assets/index-DPpOdAtC.js +57 -0
  222. package/platform-ui/dist/index.html +2 -2
  223. package/dist/accept-orchestration-UQLM7PTQ.js +0 -189
  224. package/dist/add-FZRKEGH4.js +0 -81
  225. package/dist/agent-WERIO2XV.js +0 -523
  226. package/dist/agent-loader-TFIANSF4.js +0 -44
  227. package/dist/agent-state-S5DAWPTF.js +0 -24
  228. package/dist/agents-suggest-DNSYJ6IA.js +0 -83
  229. package/dist/aggregate-H57K7PNV.js +0 -88
  230. package/dist/assess-4WVXZLZQ.js +0 -68
  231. package/dist/auto-QFS5NHQU.js +0 -504
  232. package/dist/beacon-KXZXYQHX.js +0 -251
  233. package/dist/calibration-V46G7JTY.js +0 -135
  234. package/dist/check-OWAIWV23.js +0 -175
  235. package/dist/chunk-2IO7JAG2.js +0 -148
  236. package/dist/chunk-2T6BTYBN.js +0 -712
  237. package/dist/chunk-36TKPM5Z.js +0 -400
  238. package/dist/chunk-45MUDW6E.js +0 -804
  239. package/dist/chunk-4BLYIB7J.js +0 -5701
  240. package/dist/chunk-4L3UTYQX.js +0 -677
  241. package/dist/chunk-4NCFWYGG.js +0 -110
  242. package/dist/chunk-54LTTQBH.js +0 -138
  243. package/dist/chunk-5EWAQHFY.js +0 -269
  244. package/dist/chunk-5JGJACDU.js +0 -37
  245. package/dist/chunk-5OUOLN6M.js +0 -659
  246. package/dist/chunk-5VKJBNJL.js +0 -444
  247. package/dist/chunk-6N3JTACN.js +0 -2260
  248. package/dist/chunk-6QC3YGB6.js +0 -114
  249. package/dist/chunk-7N7GSU6K.js +0 -34
  250. package/dist/chunk-ABVQGRF7.js +0 -268
  251. package/dist/chunk-CL7JSK52.js +0 -129
  252. package/dist/chunk-CSD7IHSN.js +0 -152
  253. package/dist/chunk-EDOAWN7J.js +0 -717
  254. package/dist/chunk-EKGMAM62.js +0 -525
  255. package/dist/chunk-EZ3GOCYC.js +0 -132
  256. package/dist/chunk-F3BCHPYT.js +0 -143
  257. package/dist/chunk-FKJUBQU3.js +0 -3081
  258. package/dist/chunk-GT5QGC2H.js +0 -253
  259. package/dist/chunk-GZDFVP2N.js +0 -540
  260. package/dist/chunk-IRKUEJVW.js +0 -405
  261. package/dist/chunk-J2JEQRT3.js +0 -164
  262. package/dist/chunk-JASGXLK3.js +0 -679
  263. package/dist/chunk-KVDYJLTC.js +0 -121
  264. package/dist/chunk-L27I3CPZ.js +0 -357
  265. package/dist/chunk-LHLIAYQ3.js +0 -185
  266. package/dist/chunk-MCMOGQMU.js +0 -145
  267. package/dist/chunk-NQKQG45G.js +0 -688
  268. package/dist/chunk-PBHIFAL4.js +0 -259
  269. package/dist/chunk-PDX44BCA.js +0 -11
  270. package/dist/chunk-PMXRGPRQ.js +0 -305
  271. package/dist/chunk-RAB5IKPR.js +0 -487
  272. package/dist/chunk-RJE5G7WO.js +0 -590
  273. package/dist/chunk-RTHA3XRE.js +0 -880
  274. package/dist/chunk-S2HO5MLR.js +0 -621
  275. package/dist/chunk-S3ORKP3V.js +0 -716
  276. package/dist/chunk-TAIJOFOE.js +0 -124
  277. package/dist/chunk-TXESEO7Y.js +0 -245
  278. package/dist/chunk-UPLDI7CN.js +0 -1334
  279. package/dist/chunk-VL67H5IC.js +0 -506
  280. package/dist/chunk-VPPK3SY4.js +0 -1136
  281. package/dist/chunk-YMDLDELF.js +0 -314
  282. package/dist/chunk-YO6DVTL7.js +0 -99
  283. package/dist/chunk-YRZ5RPEB.js +0 -1561
  284. package/dist/chunk-ZDHLG5VP.js +0 -5676
  285. package/dist/chunk-ZGUAAVMA.js +0 -756
  286. package/dist/chunk-ZSYVKSY6.js +0 -2602
  287. package/dist/claude-FRRWJSTJ.js +0 -362
  288. package/dist/claude-cli-XJLK2X4L.js +0 -276
  289. package/dist/claude-code-HTBA4XRB.js +0 -126
  290. package/dist/claude-code-teams-T4SP24MD.js +0 -199
  291. package/dist/commands-5N4ILTPH.js +0 -5859
  292. package/dist/conductor-CQVGTEQN.js +0 -161
  293. package/dist/config-schema-EA4XALGG.js +0 -154
  294. package/dist/constellation-A26CCGQS.js +0 -225
  295. package/dist/context-audit-RLO3ETRP.js +0 -682
  296. package/dist/cost-BGM32XJU.js +0 -93
  297. package/dist/cost-VI46A4XL.js +0 -174
  298. package/dist/cursor-cli-JVEZGHWQ.js +0 -269
  299. package/dist/cursorrules-HLIKJJZT.js +0 -84
  300. package/dist/decision-loader-WWCLIQPJ.js +0 -20
  301. package/dist/delete-KBRPQLPC.js +0 -56
  302. package/dist/diff-D4X53HAC.js +0 -126
  303. package/dist/discipline-FA4OZXIS.js +0 -24
  304. package/dist/dist-34NA5RS5.js +0 -74
  305. package/dist/dist-5QE2BB2B-5S3T6Y3T.js +0 -6919
  306. package/dist/dist-77JDTVAY.js +0 -62
  307. package/dist/dist-OGTSAZ55.js +0 -1358
  308. package/dist/dist-QK4SQAK7.js +0 -64
  309. package/dist/dist-TA6LSC2Q.js +0 -20
  310. package/dist/docs-PBZB7LYP.js +0 -89
  311. package/dist/docs-QIYKO3BR.js +0 -155
  312. package/dist/doctor-ULBOHEIC.js +0 -11
  313. package/dist/drift-R5NRKFHI.js +0 -251
  314. package/dist/echo-O2LY7CC2.js +0 -248
  315. package/dist/edit-R2HNLMOG.js +0 -63
  316. package/dist/event-25OJKDCE.js +0 -31
  317. package/dist/export-IWVL7XLF.js +0 -38
  318. package/dist/flow-CRRVV3O3.js +0 -185
  319. package/dist/global-3NG5JXUB.js +0 -136
  320. package/dist/graduate-USAWGBJM.js +0 -160
  321. package/dist/graph-VHUMAAS6.js +0 -12
  322. package/dist/graph-server-YL22VBBN.js +0 -116
  323. package/dist/habits-OL5NGPXO.js +0 -1405
  324. package/dist/history-WOWC573W.js +0 -277
  325. package/dist/hooks-HFWSCGPV.js +0 -12
  326. package/dist/integrity-IHO4FZTS.js +0 -194
  327. package/dist/integrity-checker-PSKJA5SB.js +0 -12
  328. package/dist/journal-loader-5EYSBFFY.js +0 -18
  329. package/dist/lint-K6CJGGPH.js +0 -456
  330. package/dist/list-4YK7QKFF.js +0 -57
  331. package/dist/list-ENR7Q4CR.js +0 -56
  332. package/dist/lore-loader-7NO6N6FT.js +0 -26
  333. package/dist/lore-server-UNJY5KC3.js +0 -118
  334. package/dist/manual-G6FISID5.js +0 -204
  335. package/dist/migrate-LS45DNEV.js +0 -889
  336. package/dist/migrate-assessments-RGH4O6IX.js +0 -97
  337. package/dist/model-discovery-D2H3VBGC.js +0 -8
  338. package/dist/nomination-engine-RV5CNO5B.js +0 -42
  339. package/dist/notebook-YWIYGEHV.js +0 -155
  340. package/dist/orchestrate-JLILBBJE.js +0 -324
  341. package/dist/peers-DEOUIZM6.js +0 -82
  342. package/dist/persona-UHAHIVST.js +0 -390
  343. package/dist/pipeline-L4HCSBGN.js +0 -263
  344. package/dist/platform-server-H5YO3DQD.js +0 -1475
  345. package/dist/plugin-update-checker-KRRSGXMV.js +0 -12
  346. package/dist/portal-check-NPYGII2D.js +0 -42
  347. package/dist/portal-compliance-J7DGAPFX.js +0 -18
  348. package/dist/probe-MHL5HQZ2.js +0 -167
  349. package/dist/promote-F6ZYZZAL.js +0 -182
  350. package/dist/providers-GK7PB2OL.js +0 -104
  351. package/dist/quiz-M66SC7F7.js +0 -99
  352. package/dist/record-RA4WR2BO.js +0 -49
  353. package/dist/reindex-5LTD53ZC.js +0 -16
  354. package/dist/remember-HBWJ655S.js +0 -77
  355. package/dist/retag-3OLCVDEQ.js +0 -62
  356. package/dist/review-27ATYTD2.js +0 -33
  357. package/dist/review-57QMURZV.js +0 -334
  358. package/dist/ripple-JPBXP5I3.js +0 -215
  359. package/dist/sentinel-4XIG4STA.js +0 -63
  360. package/dist/sentinel-bridge-MDUXTQRL.js +0 -109
  361. package/dist/serve-CAH3PHE7.js +0 -33
  362. package/dist/serve-INL7SNBK.js +0 -36
  363. package/dist/serve-KBSE36PL.js +0 -49
  364. package/dist/server-54SKYFFY.js +0 -1647
  365. package/dist/server-XUOIO7E6.js +0 -338
  366. package/dist/session-tracker-C4BMD5WG.js +0 -13
  367. package/dist/session-work-log-MZ47OAPB.js +0 -20
  368. package/dist/setup-EDS27WUR.js +0 -25
  369. package/dist/setup-KO5AFC4K.js +0 -296
  370. package/dist/shift-D2JOHHBF.js +0 -668
  371. package/dist/show-5PV5KFJE.js +0 -176
  372. package/dist/show-NQKYX6WQ.js +0 -82
  373. package/dist/snapshot-BK4RBPCG.js +0 -62
  374. package/dist/spawn-RCHNXDHE.js +0 -196
  375. package/dist/status-WGIAQODY.js +0 -71
  376. package/dist/summary-NIRABMF5.js +0 -140
  377. package/dist/sweep-QMHNSIY5.js +0 -934
  378. package/dist/switch-6EJPZDIA.js +0 -232
  379. package/dist/symphony-4OCY36AI.js +0 -791
  380. package/dist/symphony-B75X2MME.js +0 -326
  381. package/dist/symphony-loader-UZGON56V.js +0 -90
  382. package/dist/symphony-peers-2ZQYLRNI.js +0 -34
  383. package/dist/symphony-peers-OL7F6M5S.js +0 -121
  384. package/dist/symphony-relay-UJYUXN65.js +0 -710
  385. package/dist/sync-VEHUH4OA.js +0 -11
  386. package/dist/sync-llms-YHCFIE6X.js +0 -166
  387. package/dist/task-loader-LDYWQSLM.js +0 -20
  388. package/dist/team-O5MIIFMA.js +0 -34
  389. package/dist/test-566CP5KC.js +0 -1017
  390. package/dist/thread-N754I4D5.js +0 -274
  391. package/dist/timeline-M3CICQFE.js +0 -112
  392. package/dist/triage-HHYGT3HY.js +0 -671
  393. package/dist/tutorial-KD22SUNO.js +0 -666
  394. package/dist/upgrade-H5PF32BW.js +0 -551
  395. package/dist/validate-CNKEKO6A.js +0 -134
  396. package/dist/validate-MB5ULIHS.js +0 -39
  397. package/dist/validate-QH3LADM6.js +0 -64
  398. package/dist/watch-2TKP5PVL.js +0 -199
  399. package/dist/watch-ZF4ML6CD.js +0 -111
  400. package/dist/wisdom-AATMGNFA.js +0 -319
  401. package/dist/work-log-loader-5L45XNYZ.js +0 -14
  402. package/dist/workspace-6E6OSRNU.js +0 -21
  403. package/platform-ui/dist/assets/AmbientSection-WtHfNedO.js +0 -1
  404. package/platform-ui/dist/assets/LoreSection-C3EixkjW.css +0 -1
  405. package/platform-ui/dist/assets/LoreSection-CwDDHrz9.js +0 -1
  406. package/platform-ui/dist/assets/SentinelSection-Cl7e5oZ6.js +0 -1
  407. package/platform-ui/dist/assets/TeamSection-CqSIMrKz.js +0 -1
  408. package/platform-ui/dist/assets/index-CfpZFjea.css +0 -1
  409. package/platform-ui/dist/assets/index-F0KL9xrN.js +0 -57
@@ -1,14 +1,5 @@
1
1
  #!/usr/bin/env node
2
-
3
- // src/commands/hooks/index.ts
4
- import * as fs from "fs";
5
- import * as path from "path";
6
- import * as os from "os";
7
- import { execSync } from "child_process";
8
- import chalk from "chalk";
9
-
10
- // src/commands/hooks/generated-hooks.ts
11
- var COMMON_HOOK = `#!/bin/sh
2
+ import*as e from'fs';import*as r from'path';import*as E from'os';import {execSync}from'child_process';import o from'chalk';var C=`#!/bin/sh
12
3
  # paradigm-common.sh \u2014 Shared compliance checks for Paradigm stop hooks
13
4
  # Sourced by claude-code-stop.sh and cursor-stop.sh
14
5
  #
@@ -35,10 +26,10 @@ var COMMON_HOOK = `#!/bin/sh
35
26
  # 5. Per-directory .purpose freshness (tracked via .pending-review)
36
27
  # 6. Aspect coverage advisory
37
28
  # 7. Lore entry expected for significant sessions (3+ source files)
38
- # 8. Blocking habits not satisfied (from paradigm_habits_check)
29
+ # 8. Blocking habits not satisfied (from unified compliance-check)
39
30
  # 9. Purpose-required patterns from config.yaml
40
- # 10. Aspect drift detection with auto-heal
41
- # 11. Portal gate implementation compliance
31
+ # 10. Aspect drift detection with auto-heal (from unified compliance-check)
32
+ # 11. Portal gate implementation compliance (from unified compliance-check)
42
33
 
43
34
  VIOLATIONS=""
44
35
  VIOLATION_COUNT=0
@@ -46,9 +37,24 @@ AUTO_FIXED=""
46
37
  AUTO_FIX_COUNT=0
47
38
  PARADIGM_AUTO_FIX="\${PARADIGM_AUTO_FIX:-0}"
48
39
 
40
+ # --- Cache .purpose file paths (avoid repeated find scans) ---
41
+ PURPOSE_CACHE=".paradigm/.purpose-paths"
42
+ if [ -f "$PURPOSE_CACHE" ]; then
43
+ PURPOSE_PATHS=$(cat "$PURPOSE_CACHE")
44
+ else
45
+ PURPOSE_PATHS=$(find . -name ".purpose" -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null)
46
+ if [ -n "$PURPOSE_PATHS" ]; then
47
+ echo "$PURPOSE_PATHS" > "$PURPOSE_CACHE"
48
+ fi
49
+ fi
50
+
49
51
  # --- Check 1: Source files modified without .purpose updates ---
52
+ # Instead of counting total source files globally, check per-directory:
53
+ # only flag directories where source files were modified but no .purpose
54
+ # exists in that directory's ancestor chain OR the covering .purpose was not updated.
50
55
  SOURCE_COUNT=0
51
56
  PARADIGM_COUNT=0
57
+ UNCOVERED_SOURCE_DIRS=""
52
58
 
53
59
  for file in $MODIFIED; do
54
60
  case "$file" in
@@ -58,13 +64,54 @@ for file in $MODIFIED; do
58
64
  *.md|*.lock|*.log|.gitignore|.env*|*.json) ;;
59
65
  *)
60
66
  SOURCE_COUNT=$((SOURCE_COUNT + 1))
67
+ # Check if this file's directory has a covering .purpose that was modified
68
+ src_dir=$(dirname "$file")
69
+ covering=""
70
+ walk_dir="$src_dir"
71
+ while [ "$walk_dir" != "." ] && [ "$walk_dir" != "" ]; do
72
+ if [ -f "$walk_dir/.purpose" ]; then
73
+ covering="$walk_dir/.purpose"
74
+ break
75
+ fi
76
+ walk_dir=$(dirname "$walk_dir")
77
+ done
78
+ if [ -z "$covering" ] && [ -f ".purpose" ]; then
79
+ covering=".purpose"
80
+ fi
81
+ # If there IS a covering .purpose, check if it was modified too
82
+ if [ -n "$covering" ]; then
83
+ purpose_was_modified=false
84
+ for mod_file in $MODIFIED; do
85
+ if [ "$mod_file" = "$covering" ]; then
86
+ purpose_was_modified=true
87
+ break
88
+ fi
89
+ done
90
+ if [ "$purpose_was_modified" = false ]; then
91
+ # Deduplicate by directory
92
+ case "$UNCOVERED_SOURCE_DIRS" in
93
+ *"$src_dir"*) ;;
94
+ *) UNCOVERED_SOURCE_DIRS="$UNCOVERED_SOURCE_DIRS $src_dir" ;;
95
+ esac
96
+ fi
97
+ else
98
+ # No .purpose at all \u2014 already caught by Check 2
99
+ :
100
+ fi
61
101
  ;;
62
102
  esac
63
103
  done
64
104
 
65
- if [ "$SOURCE_COUNT" -gt 1 ] && [ "$PARADIGM_COUNT" -eq 0 ]; then
105
+ # Only flag if there are uncovered directories AND zero paradigm files were touched
106
+ if [ -n "$UNCOVERED_SOURCE_DIRS" ] && [ "$PARADIGM_COUNT" -eq 0 ]; then
107
+ # Count uncovered dirs
108
+ UNCOVERED_DIR_COUNT=0
109
+ for _d in $UNCOVERED_SOURCE_DIRS; do
110
+ UNCOVERED_DIR_COUNT=$((UNCOVERED_DIR_COUNT + 1))
111
+ done
66
112
  VIOLATIONS="$VIOLATIONS
67
- - You modified $SOURCE_COUNT source files but 0 paradigm files (.purpose/portal.yaml).
113
+ - You modified source files in $UNCOVERED_DIR_COUNT director(ies) without updating their .purpose files:
114
+ $UNCOVERED_SOURCE_DIRS
68
115
  Update the nearest .purpose file for each modified code area."
69
116
  VIOLATION_COUNT=$((VIOLATION_COUNT + 1))
70
117
  fi
@@ -132,12 +179,29 @@ if [ -f "portal.yaml" ] || echo "$MODIFIED" | grep -q "portal.yaml"; then
132
179
  : # portal.yaml exists or was modified \u2014 OK
133
180
  else
134
181
  # Check if any modified files contain route-like patterns
182
+ # Skip: test/spec/fixture files, markdown, and comment-only matches
135
183
  ROUTE_FILES=""
136
184
  for file in $MODIFIED; do
185
+ # Skip test, spec, and fixture files entirely
186
+ case "$file" in
187
+ *test*|*spec*|*fixture*|*__tests__*|*__mocks__*|*.test.*|*.spec.*) continue ;;
188
+ esac
137
189
  case "$file" in
138
190
  *.ts|*.js|*.tsx|*.jsx|*.py|*.rs|*.go)
139
191
  if [ -f "$file" ]; then
140
- if grep -qE '\\.(get|post|put|patch|delete)\\s*\\(|router\\.|app\\.(get|post|put|delete)|@(Get|Post|Put|Delete)|#\\[actix_web::(get|post)' "$file" 2>/dev/null; then
192
+ # Grep for route patterns, then filter out comment lines and description strings
193
+ ROUTE_MATCH=$(grep -nE '\\.(get|post|put|patch|delete)\\s*\\(|router\\.|app\\.(get|post|put|delete)|@(Get|Post|Put|Delete)|#\\[actix_web::(get|post)' "$file" 2>/dev/null \\
194
+ | grep -v '^\\s*[0-9]*:\\s*//' \\
195
+ | grep -v '^\\s*[0-9]*:\\s*\\*' \\
196
+ | grep -v '^\\s*[0-9]*:\\s*#' \\
197
+ | grep -v '^\\s*[0-9]*:\\s*<!--' \\
198
+ | grep -v 'description:' \\
199
+ | grep -v 'summary:' \\
200
+ | grep -v 'comment:' \\
201
+ | grep -v '@example' \\
202
+ | grep -v '@see' \\
203
+ || true)
204
+ if [ -n "$ROUTE_MATCH" ]; then
141
205
  ROUTE_FILES="$ROUTE_FILES $file"
142
206
  fi
143
207
  fi
@@ -155,7 +219,7 @@ else
155
219
  fi
156
220
 
157
221
  # --- Check 4: Aspect anchor files that no longer exist ---
158
- for purpose_file in $(find . -name ".purpose" -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null); do
222
+ for purpose_file in $PURPOSE_PATHS; do
159
223
  if grep -q "anchors:" "$purpose_file" 2>/dev/null; then
160
224
  purpose_dir=$(dirname "$purpose_file")
161
225
  in_anchors=false
@@ -183,9 +247,22 @@ for purpose_file in $(find . -name ".purpose" -not -path "*/node_modules/*" -not
183
247
  done
184
248
 
185
249
  # --- Check 5: Per-directory .purpose freshness ---
250
+ # Uses .pending-review if available, plus a git-based fallback that cross-references
251
+ # modified source files against .purpose modification times.
186
252
  PENDING_FILE=".paradigm/.pending-review"
253
+ STALE_PURPOSES=""
254
+
255
+ # Helper: record a stale .purpose (deduplicating)
256
+ _record_stale_purpose() {
257
+ _cov="$1"
258
+ case "$STALE_PURPOSES" in
259
+ *"$_cov"*) ;;
260
+ *) STALE_PURPOSES="$STALE_PURPOSES $_cov" ;;
261
+ esac
262
+ }
263
+
264
+ # Strategy A: Use .pending-review tracking file if present
187
265
  if [ -f "$PENDING_FILE" ]; then
188
- STALE_PURPOSES=""
189
266
  while IFS= read -r tracked_file; do
190
267
  [ -z "$tracked_file" ] && continue
191
268
  # Find covering .purpose for this tracked file
@@ -204,28 +281,65 @@ if [ -f "$PENDING_FILE" ]; then
204
281
  # Check if covering .purpose was also modified
205
282
  if [ -n "$covering_purpose" ]; then
206
283
  if ! echo "$MODIFIED" | grep -qxF "$covering_purpose"; then
207
- # Deduplicate
208
- case "$STALE_PURPOSES" in
209
- *"$covering_purpose"*) ;;
210
- *) STALE_PURPOSES="$STALE_PURPOSES $covering_purpose" ;;
211
- esac
284
+ _record_stale_purpose "$covering_purpose"
212
285
  fi
213
286
  fi
214
287
  done < "$PENDING_FILE"
288
+ fi
215
289
 
216
- if [ -n "$STALE_PURPOSES" ]; then
217
- VIOLATIONS="$VIOLATIONS
290
+ # Strategy B: Git-based fallback \u2014 for each modified source file, check whether
291
+ # its covering .purpose was modified more recently (by filesystem mtime).
292
+ # This catches cases where .pending-review is missing or out of sync.
293
+ for file in $MODIFIED; do
294
+ case "$file" in
295
+ .paradigm/*|*.md|*.lock|*.log|.gitignore|.env*|*.json|*.purpose|portal.yaml) continue ;;
296
+ esac
297
+ [ -f "$file" ] || continue
298
+
299
+ # Find covering .purpose
300
+ check_dir=$(dirname "$file")
301
+ covering_purpose=""
302
+ while [ "$check_dir" != "." ] && [ "$check_dir" != "" ]; do
303
+ if [ -f "$check_dir/.purpose" ]; then
304
+ covering_purpose="$check_dir/.purpose"
305
+ break
306
+ fi
307
+ check_dir=$(dirname "$check_dir")
308
+ done
309
+ if [ -z "$covering_purpose" ] && [ -f ".purpose" ]; then
310
+ covering_purpose=".purpose"
311
+ fi
312
+ [ -n "$covering_purpose" ] || continue
313
+
314
+ # Skip if .purpose was in the modified list (already updated this session)
315
+ echo "$MODIFIED" | grep -qxF "$covering_purpose" && continue
316
+
317
+ # Compare modification times: if source file is newer than .purpose, it's stale
318
+ if [ -f "$covering_purpose" ]; then
319
+ # Use portable stat-based mtime comparison (works on macOS + Linux)
320
+ if command -v stat >/dev/null 2>&1; then
321
+ # macOS stat: -f %m gives epoch seconds; Linux stat: -c %Y
322
+ src_mtime=$(stat -f %m "$file" 2>/dev/null || stat -c %Y "$file" 2>/dev/null || echo "0")
323
+ purpose_mtime=$(stat -f %m "$covering_purpose" 2>/dev/null || stat -c %Y "$covering_purpose" 2>/dev/null || echo "0")
324
+ if [ "$src_mtime" -gt "$purpose_mtime" ] 2>/dev/null; then
325
+ _record_stale_purpose "$covering_purpose"
326
+ fi
327
+ fi
328
+ fi
329
+ done
330
+
331
+ if [ -n "$STALE_PURPOSES" ]; then
332
+ VIOLATIONS="$VIOLATIONS
218
333
  - These .purpose files cover modified source code but were NOT updated:
219
334
  $STALE_PURPOSES
220
335
  Update each with: #components, ~aspects (with anchors), !signals, \\$flows, ^gates."
221
- VIOLATION_COUNT=$((VIOLATION_COUNT + 1))
222
- fi
336
+ VIOLATION_COUNT=$((VIOLATION_COUNT + 1))
223
337
  fi
224
338
 
225
339
  # --- Check 6: Aspect coverage advisory ---
226
340
  ADVISORY=""
227
341
  HAS_ASPECTS=false
228
- for purpose_file in $(find . -name ".purpose" -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null); do
342
+ for purpose_file in $PURPOSE_PATHS; do
229
343
  if grep -qE '^\\s*~' "$purpose_file" 2>/dev/null; then
230
344
  HAS_ASPECTS=true
231
345
  break
@@ -320,21 +434,64 @@ LOREEOF
320
434
  fi
321
435
  fi
322
436
 
323
- # --- Auto-evaluate on-stop habits via CLI ---
437
+ # --- Checks 8, 10, 11: Unified compliance check (single Node.js process) ---
438
+ # Replaces 3 separate subprocess calls (habits check, drift check, portal check)
439
+ # with a single \`paradigm compliance-check\` invocation.
440
+ COMPLIANCE_RESULT=""
324
441
  if command -v paradigm >/dev/null 2>&1; then
325
- paradigm habits check --trigger on-stop --record --json 2>/dev/null || true
442
+ COMPLIANCE_RESULT=$(paradigm compliance-check --json --auto-heal --learn --trigger on-stop 2>/dev/null) || true
326
443
  elif command -v npx >/dev/null 2>&1; then
327
- npx paradigm habits check --trigger on-stop --record --json 2>/dev/null || true
444
+ COMPLIANCE_RESULT=$(npx paradigm compliance-check --json --auto-heal --learn --trigger on-stop 2>/dev/null) || true
328
445
  fi
329
446
 
330
- # --- Check 8: Blocking habits ---
331
- if [ -f ".paradigm/.habits-blocking" ]; then
332
- HABITS_BLOCKING=$(cat ".paradigm/.habits-blocking")
333
- VIOLATIONS="$VIOLATIONS
447
+ if [ -n "$COMPLIANCE_RESULT" ]; then
448
+ # --- Check 8: Blocking habits (from unified result) ---
449
+ # The compliance-check command writes .habits-blocking marker internally
450
+ if [ -f ".paradigm/.habits-blocking" ]; then
451
+ HABITS_BLOCKING=$(cat ".paradigm/.habits-blocking")
452
+ VIOLATIONS="$VIOLATIONS
334
453
  - Blocking habit(s) not satisfied:
335
454
  $HABITS_BLOCKING
336
455
  Call paradigm_habits_check with trigger=\\"on-stop\\" after fixing the above."
337
- VIOLATION_COUNT=$((VIOLATION_COUNT + 1))
456
+ VIOLATION_COUNT=$((VIOLATION_COUNT + 1))
457
+ fi
458
+
459
+ # --- Check 10: Aspect drift (from unified result) ---
460
+ DRIFTED_COUNT=$(echo "$COMPLIANCE_RESULT" | grep -o '"driftedCount":[0-9]*' | sed 's/.*://')
461
+ HEALED_COUNT=$(echo "$COMPLIANCE_RESULT" | grep -o '"healedCount":[0-9]*' | sed 's/.*://')
462
+
463
+ if [ -n "$HEALED_COUNT" ] && [ "$HEALED_COUNT" -gt 0 ] 2>/dev/null; then
464
+ echo "[paradigm] Auto-healed $HEALED_COUNT shifted anchor(s)." >&2
465
+ fi
466
+
467
+ if [ -n "$DRIFTED_COUNT" ] && [ "$DRIFTED_COUNT" -gt 0 ] 2>/dev/null; then
468
+ VIOLATIONS="$VIOLATIONS
469
+ - $DRIFTED_COUNT aspect anchor(s) have drifted (content genuinely changed).
470
+ Run paradigm_aspect_check to review. Update anchors in .purpose files."
471
+ VIOLATION_COUNT=$((VIOLATION_COUNT + 1))
472
+ fi
473
+
474
+ # --- Check 11: Portal gate compliance (from unified result) ---
475
+ UNDECLARED=$(echo "$COMPLIANCE_RESULT" | grep -o '"usedButUndeclaredCount":[0-9]*' | sed 's/.*://')
476
+
477
+ if [ -n "$UNDECLARED" ] && [ "$UNDECLARED" -gt 0 ] 2>/dev/null; then
478
+ UNDECLARED_LIST=$(echo "$COMPLIANCE_RESULT" | grep -o '"usedButUndeclared":\\[[^]]*\\]' | sed 's/.*\\[//;s/\\].*//;s/"//g')
479
+ VIOLATIONS="$VIOLATIONS
480
+ - $UNDECLARED gate(s) used in code but not declared in portal.yaml:
481
+ $UNDECLARED_LIST
482
+ Add them to portal.yaml or use paradigm_portal_add_gate."
483
+ VIOLATION_COUNT=$((VIOLATION_COUNT + 1))
484
+ fi
485
+ else
486
+ # Fallback: check habits blocking marker even if compliance-check unavailable
487
+ if [ -f ".paradigm/.habits-blocking" ]; then
488
+ HABITS_BLOCKING=$(cat ".paradigm/.habits-blocking")
489
+ VIOLATIONS="$VIOLATIONS
490
+ - Blocking habit(s) not satisfied:
491
+ $HABITS_BLOCKING
492
+ Call paradigm_habits_check with trigger=\\"on-stop\\" after fixing the above."
493
+ VIOLATION_COUNT=$((VIOLATION_COUNT + 1))
494
+ fi
338
495
  fi
339
496
 
340
497
  # --- Check 9: Purpose-required patterns from config.yaml ---
@@ -435,55 +592,6 @@ PURPOSEEOF
435
592
  fi
436
593
  fi
437
594
 
438
- # --- Check 10: Aspect drift detection with auto-heal ---
439
- if [ -f ".paradigm/aspect-graph.db" ]; then
440
- DRIFT_RESULT=""
441
- if command -v paradigm >/dev/null 2>&1; then
442
- DRIFT_RESULT=$(paradigm drift check --json --auto-heal 2>/dev/null) || true
443
- elif command -v npx >/dev/null 2>&1; then
444
- DRIFT_RESULT=$(npx paradigm drift check --json --auto-heal 2>/dev/null) || true
445
- fi
446
-
447
- if [ -n "$DRIFT_RESULT" ]; then
448
- DRIFTED_COUNT=$(echo "$DRIFT_RESULT" | grep -o '"driftedCount":[0-9]*' | sed 's/.*://')
449
- HEALED_COUNT=$(echo "$DRIFT_RESULT" | grep -o '"healedCount":[0-9]*' | sed 's/.*://')
450
-
451
- if [ -n "$HEALED_COUNT" ] && [ "$HEALED_COUNT" -gt 0 ] 2>/dev/null; then
452
- echo "[paradigm] Auto-healed $HEALED_COUNT shifted anchor(s)." >&2
453
- fi
454
-
455
- if [ -n "$DRIFTED_COUNT" ] && [ "$DRIFTED_COUNT" -gt 0 ] 2>/dev/null; then
456
- VIOLATIONS="$VIOLATIONS
457
- - $DRIFTED_COUNT aspect anchor(s) have drifted (content genuinely changed).
458
- Run paradigm_aspect_check to review. Update anchors in .purpose files."
459
- VIOLATION_COUNT=$((VIOLATION_COUNT + 1))
460
- fi
461
- fi
462
- fi
463
-
464
- # --- Check 11: Portal gate implementation compliance ---
465
- if [ -f "portal.yaml" ]; then
466
- PORTAL_RESULT=""
467
- if command -v paradigm >/dev/null 2>&1; then
468
- PORTAL_RESULT=$(paradigm portal check --json 2>/dev/null) || true
469
- elif command -v npx >/dev/null 2>&1; then
470
- PORTAL_RESULT=$(npx paradigm portal check --json 2>/dev/null) || true
471
- fi
472
-
473
- if [ -n "$PORTAL_RESULT" ]; then
474
- UNDECLARED=$(echo "$PORTAL_RESULT" | grep -o '"usedButUndeclaredCount":[0-9]*' | sed 's/.*://')
475
-
476
- if [ -n "$UNDECLARED" ] && [ "$UNDECLARED" -gt 0 ] 2>/dev/null; then
477
- UNDECLARED_LIST=$(echo "$PORTAL_RESULT" | grep -o '"usedButUndeclared":\\[[^]]*\\]' | sed 's/.*\\[//;s/\\].*//;s/"//g')
478
- VIOLATIONS="$VIOLATIONS
479
- - $UNDECLARED gate(s) used in code but not declared in portal.yaml:
480
- $UNDECLARED_LIST
481
- Add them to portal.yaml or use paradigm_portal_add_gate."
482
- VIOLATION_COUNT=$((VIOLATION_COUNT + 1))
483
- fi
484
- fi
485
- fi
486
-
487
595
  # --- Check 12: Graduation failure tracking ---
488
596
  # When violations occur for graduated habits, record failures for auto-demotion.
489
597
  if [ "$VIOLATION_COUNT" -gt 0 ] && [ -f ".paradigm/graduation.yaml" ]; then
@@ -531,8 +639,7 @@ if [ "$VIOLATION_COUNT" -gt 0 ] && [ -f ".paradigm/graduation.yaml" ]; then
531
639
  fi
532
640
  done
533
641
  fi
534
- `;
535
- var CLAUDE_CODE_STOP_HOOK = `#!/bin/sh
642
+ `,R=`#!/bin/sh
536
643
  # Paradigm Claude Code Stop Hook (v2)
537
644
  # Validates paradigm compliance before allowing the agent to finish.
538
645
  # Installed by: paradigm hooks install --claude-code
@@ -585,7 +692,8 @@ fi
585
692
 
586
693
  # --- Final verdict ---
587
694
  if [ "$VIOLATION_COUNT" -gt 0 ]; then
588
- # Emit compliance-violation event (fire-and-forget)
695
+ # Emit compliance-violation event (fire-and-forget, backgrounded)
696
+ # NOTE: Could be absorbed into compliance-check command in a future iteration.
589
697
  if command -v paradigm >/dev/null 2>&1; then
590
698
  paradigm event emit --type compliance-violation --source stop-hook --severity error --context "Stop hook: $VIOLATION_COUNT violation(s)" &
591
699
  fi
@@ -618,6 +726,7 @@ if [ -n "$ADVISORY" ]; then
618
726
  fi
619
727
 
620
728
  # Auto-demote graduated habits with 3+ failures
729
+ # NOTE: Could be absorbed into compliance-check command in a future iteration.
621
730
  if [ -d ".paradigm/.graduation-failures" ]; then
622
731
  for fail_file in .paradigm/.graduation-failures/*; do
623
732
  [ -f "$fail_file" ] || continue
@@ -637,144 +746,14 @@ fi
637
746
  rm -f ".paradigm/.pending-review"
638
747
  rm -f ".paradigm/.habits-blocking"
639
748
  rm -f ".paradigm/.session-started"
749
+ rm -f ".paradigm/.purpose-paths"
640
750
 
641
751
  exit 0
642
- `;
643
- var CLAUDE_CODE_POSTWRITE_HOOK = `#!/bin/sh
644
- # Paradigm Claude Code PostToolUse Hook (v2)
645
- # Fires after Edit/Write tool calls.
646
- # Tracks modified source files in .paradigm/.pending-review
647
- # and outputs compliance reminders.
648
- # Installed by: paradigm hooks install --claude-code
649
- #
650
- # Hook type: PostToolUse (matcher: Edit,Write)
651
- # Exit 0 always (never blocks \u2014 advisory only)
652
- #
653
- # NOTE: stdin JSON can be 8KB+ (tool_response includes full file contents).
654
- # Using echo "$INPUT" | jq corrupts the JSON via shell string handling.
655
- # Fix: write stdin to temp file, use jq < file for all extractions.
656
-
657
- # Save stdin to temp file \u2014 avoids echo corruption on large JSON
658
- TMPINPUT=$(mktemp)
659
- trap 'rm -f "$TMPINPUT"' EXIT
660
- cat > "$TMPINPUT"
661
-
662
- # Extract the file path from tool_input
663
- if command -v jq >/dev/null 2>&1; then
664
- FILE_PATH=$(jq -r '.tool_input.file_path // .tool_input.filePath // empty' < "$TMPINPUT" 2>/dev/null)
665
- else
666
- FILE_PATH=$(grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' "$TMPINPUT" | head -1 | sed 's/.*"file_path"[[:space:]]*:[[:space:]]*"//' | sed 's/"$//')
667
- if [ -z "$FILE_PATH" ]; then
668
- FILE_PATH=$(grep -o '"filePath"[[:space:]]*:[[:space:]]*"[^"]*"' "$TMPINPUT" | head -1 | sed 's/.*"filePath"[[:space:]]*:[[:space:]]*"//' | sed 's/"$//')
669
- fi
670
- fi
671
-
672
- if [ -z "$FILE_PATH" ]; then
673
- exit 0
674
- fi
675
-
676
- # Extract cwd from input
677
- if command -v jq >/dev/null 2>&1; then
678
- CWD=$(jq -r '.cwd // empty' < "$TMPINPUT" 2>/dev/null)
679
- else
680
- CWD=$(grep -o '"cwd"[[:space:]]*:[[:space:]]*"[^"]*"' "$TMPINPUT" | sed 's/.*"cwd"[[:space:]]*:[[:space:]]*"//' | sed 's/"$//')
681
- fi
682
- if [ -n "$CWD" ]; then
683
- cd "$CWD" || exit 0
684
- fi
685
-
686
- # Skip non-source files
687
- case "$FILE_PATH" in
688
- *.purpose|portal.yaml|*.md|*.lock|*.log|*.json|*.yaml|*.yml|.gitignore|.env*) exit 0 ;;
689
- esac
690
-
691
- # Skip .paradigm, .claude, and .cursor directories
692
- case "$FILE_PATH" in
693
- */.paradigm/*|.paradigm/*|*/.claude/*|.claude/*|*/.cursor/*|.cursor/*) exit 0 ;;
694
- esac
695
-
696
- # Not a paradigm project \u2014 pass
697
- if [ ! -d ".paradigm" ]; then
698
- exit 0
699
- fi
700
-
701
- # Pseudo-session-start: first edit of session emits one-time guidance
702
- if [ ! -f ".paradigm/.session-started" ]; then
703
- PREV_PENDING=$(cat .paradigm/.pending-review 2>/dev/null | wc -l | tr -d ' ')
704
- if [ "$PREV_PENDING" -gt 0 ] 2>/dev/null; then
705
- echo "[paradigm] Session started. $PREV_PENDING uncovered edit(s) from last session." >&2
706
- fi
707
- touch ".paradigm/.session-started"
708
- fi
709
-
710
- # Convert to relative path (strip project root prefix)
711
- PROJECT_ROOT="$(pwd)"
712
- REL_PATH="$FILE_PATH"
713
- case "$FILE_PATH" in
714
- "$PROJECT_ROOT"/*) REL_PATH=$(echo "$FILE_PATH" | sed "s|^$PROJECT_ROOT/||") ;;
715
- esac
716
-
717
- # If still absolute, file is outside project \u2014 skip
718
- case "$REL_PATH" in
719
- /*) exit 0 ;;
720
- esac
721
-
722
- # Emit file-modified event (fire-and-forget)
723
- if command -v paradigm >/dev/null 2>&1; then
724
- paradigm event emit --type file-modified --source post-write-hook --path "$REL_PATH" &
725
- fi
726
-
727
- # Track: append to .paradigm/.pending-review (deduplicated)
728
- PENDING_FILE=".paradigm/.pending-review"
729
- if [ -f "$PENDING_FILE" ]; then
730
- if ! grep -qxF "$REL_PATH" "$PENDING_FILE" 2>/dev/null; then
731
- echo "$REL_PATH" >> "$PENDING_FILE"
732
- fi
733
- else
734
- echo "$REL_PATH" > "$PENDING_FILE"
735
- fi
736
-
737
- # Count pending files
738
- PENDING_COUNT=$(wc -l < "$PENDING_FILE" | tr -d ' ')
739
-
740
- # Walk up from the file's directory to find a .purpose file
741
- dir=$(dirname "$REL_PATH")
742
- found_purpose=""
743
-
744
- while [ "$dir" != "." ] && [ "$dir" != "/" ] && [ "$dir" != "" ]; do
745
- if [ -f "$dir/.purpose" ]; then
746
- found_purpose="$dir/.purpose"
747
- break
748
- fi
749
- dir=$(dirname "$dir")
750
- done
751
-
752
- # Check root .purpose
753
- if [ -z "$found_purpose" ] && [ -f ".purpose" ]; then
754
- found_purpose=".purpose"
755
- fi
756
-
757
- if [ -z "$found_purpose" ]; then
758
- file_dir=$(dirname "$REL_PATH")
759
- echo "" >&2
760
- echo "[paradigm] No .purpose file covers $file_dir/" >&2
761
- echo " Create one: paradigm_purpose_init + paradigm_purpose_add_component" >&2
762
- echo " $PENDING_COUNT file(s) pending review. The stop hook WILL BLOCK." >&2
763
- elif [ "$PENDING_COUNT" -gt 0 ] && [ "$((PENDING_COUNT % 3))" -eq 0 ]; then
764
- echo "" >&2
765
- echo "[paradigm] $PENDING_COUNT source file(s) modified. Update $found_purpose:" >&2
766
- echo " -> #components, ~aspects (with anchors), !signals, \\$flows, ^gates" >&2
767
- echo " The stop hook WILL BLOCK if .purpose files aren't updated." >&2
768
- fi
769
-
770
- # Context budget heuristic: suggest handoff check at high edit counts
771
- if [ "$PENDING_COUNT" -ge 30 ]; then
772
- echo "[paradigm] ~$PENDING_COUNT edits this session. Consider preparing handoff." >&2
773
- fi
774
-
752
+ `,U=`#!/bin/sh
753
+ # Legacy afterFileEdit hook \u2014 replaced by paradigm-posttooluse.sh (postToolUse)
754
+ # Kept as a no-op because Claude Code expects the file to exist.
775
755
  exit 0
776
- `;
777
- var CLAUDE_CODE_PRECOMMIT_HOOK = `#!/bin/sh
756
+ `,A=`#!/bin/sh
778
757
  # Paradigm Claude Code Pre-Commit Hook
779
758
  # Intercepts git commit Bash calls and auto-rebuilds the index.
780
759
  # Installed by: paradigm hooks install --claude-code
@@ -819,8 +798,7 @@ done
819
798
 
820
799
  # Never block \u2014 exit 0
821
800
  exit 0
822
- `;
823
- var CURSOR_SESSION_START_HOOK = `#!/bin/sh
801
+ `,P=`#!/bin/sh
824
802
  # Paradigm Cursor Session Start Hook
825
803
  # Fires before the agent does anything \u2014 injects additional_context
826
804
  # that acts as a deterministic system prompt (not subject to context compaction).
@@ -920,8 +898,7 @@ fi
920
898
  printf '{"additional_context":"%s","continue":true}\\n' "$CONTEXT"
921
899
 
922
900
  exit 0
923
- `;
924
- var CURSOR_STOP_HOOK = `#!/bin/sh
901
+ `,v=`#!/bin/sh
925
902
  # Paradigm Cursor Stop Hook (v2)
926
903
  # Validates paradigm compliance before allowing the agent to finish.
927
904
  # Installed by: paradigm hooks install --cursor
@@ -1050,104 +1027,14 @@ rm -f ".paradigm/.pending-review"
1050
1027
  rm -f ".paradigm/.habits-blocking"
1051
1028
  rm -f ".paradigm/.stop-hook-active"
1052
1029
  rm -f ".paradigm/.session-started"
1030
+ rm -f ".paradigm/.purpose-paths"
1053
1031
 
1054
1032
  exit 0
1055
- `;
1056
- var CURSOR_POSTWRITE_HOOK = `#!/bin/sh
1057
- # Paradigm Cursor PostWrite Hook (v2) \u2014 LEGACY
1058
- # Fires after file edits via Cursor's afterFileEdit hook type.
1059
- # Installed by: paradigm hooks install --cursor
1060
- #
1061
- # IMPORTANT: Cursor ignores all output (stdout + stderr) from afterFileEdit hooks.
1062
- # This hook's advisory messages are INVISIBLE to the agent. The postToolUse hook
1063
- # (cursor-posttooluse.sh) is now the primary advisory mechanism.
1064
- #
1065
- # This hook is kept for backward compatibility and background file tracking only.
1066
- # Both preToolUse and stop hooks depend on the .pending-review file this writes.
1067
- #
1068
- # Hook type: afterFileEdit
1069
- # Exit 0 always (never blocks \u2014 advisory only)
1070
-
1071
- # Read JSON from stdin (hook input)
1072
- INPUT=$(cat)
1073
-
1074
- # Extract file path from Cursor's afterFileEdit input
1075
- if command -v jq >/dev/null 2>&1; then
1076
- FILE_PATH=$(echo "$INPUT" | jq -r '.file // .filePath // empty' 2>/dev/null)
1077
- else
1078
- FILE_PATH=$(echo "$INPUT" | grep -o '"file"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"file"[[:space:]]*:[[:space:]]*"//' | sed 's/"$//')
1079
- if [ -z "$FILE_PATH" ]; then
1080
- FILE_PATH=$(echo "$INPUT" | grep -o '"filePath"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"filePath"[[:space:]]*:[[:space:]]*"//' | sed 's/"$//')
1081
- fi
1082
- fi
1083
-
1084
- if [ -z "$FILE_PATH" ]; then
1085
- exit 0
1086
- fi
1087
-
1088
- # Skip non-source files
1089
- case "$FILE_PATH" in
1090
- *.purpose|portal.yaml|*.md|*.lock|*.log|*.json|*.yaml|*.yml|.gitignore|.env*) exit 0 ;;
1091
- esac
1092
-
1093
- # Skip .paradigm, .claude, and .cursor directories
1094
- case "$FILE_PATH" in
1095
- */.paradigm/*|.paradigm/*|*/.claude/*|.claude/*|*/.cursor/*|.cursor/*) exit 0 ;;
1096
- esac
1097
-
1098
- # Not a paradigm project \u2014 pass
1099
- if [ ! -d ".paradigm" ]; then
1100
- exit 0
1101
- fi
1102
-
1103
- # Convert to relative path (strip project root prefix)
1104
- PROJECT_ROOT="$(pwd)"
1105
- REL_PATH="$FILE_PATH"
1106
- case "$FILE_PATH" in
1107
- "$PROJECT_ROOT"/*) REL_PATH=$(echo "$FILE_PATH" | sed "s|^$PROJECT_ROOT/||") ;;
1108
- esac
1109
-
1110
- # If still absolute, file is outside project \u2014 skip
1111
- case "$REL_PATH" in
1112
- /*) exit 0 ;;
1113
- esac
1114
-
1115
- # Track: append to .paradigm/.pending-review (deduplicated)
1116
- PENDING_FILE=".paradigm/.pending-review"
1117
- if [ -f "$PENDING_FILE" ]; then
1118
- if ! grep -qxF "$REL_PATH" "$PENDING_FILE" 2>/dev/null; then
1119
- echo "$REL_PATH" >> "$PENDING_FILE"
1120
- fi
1121
- else
1122
- echo "$REL_PATH" > "$PENDING_FILE"
1123
- fi
1124
-
1125
- # Count pending files
1126
- PENDING_COUNT=$(wc -l < "$PENDING_FILE" | tr -d ' ')
1127
-
1128
- # Walk up from the file's directory to find a .purpose file
1129
- dir=$(dirname "$REL_PATH")
1130
- found_purpose=""
1131
-
1132
- while [ "$dir" != "." ] && [ "$dir" != "/" ] && [ "$dir" != "" ]; do
1133
- if [ -f "$dir/.purpose" ]; then
1134
- found_purpose="$dir/.purpose"
1135
- break
1136
- fi
1137
- dir=$(dirname "$dir")
1138
- done
1139
-
1140
- # Check root .purpose
1141
- if [ -z "$found_purpose" ] && [ -f ".purpose" ]; then
1142
- found_purpose=".purpose"
1143
- fi
1144
-
1145
- # NOTE: No stderr output here \u2014 Cursor ignores afterFileEdit output.
1146
- # Advisory messages are handled by cursor-posttooluse.sh (postToolUse hook).
1147
-
1033
+ `,D=`#!/bin/sh
1034
+ # Legacy afterFileEdit hook \u2014 replaced by paradigm-posttooluse.sh (postToolUse)
1035
+ # Kept as a no-op because Cursor expects the file to exist.
1148
1036
  exit 0
1149
- `;
1150
- var CURSOR_PRECOMMIT_HOOK = `#!/bin/sh
1037
+ `,b=`#!/bin/sh
1151
1038
  # Paradigm Cursor Pre-Commit Hook
1152
1039
  # Intercepts git commit shell executions and auto-rebuilds the index.
1153
1040
  # Installed by: paradigm hooks install --cursor
@@ -1192,8 +1079,7 @@ done
1192
1079
 
1193
1080
  # Never block \u2014 exit 0
1194
1081
  exit 0
1195
- `;
1196
- var CURSOR_PRETOOLUSE_HOOK = `#!/bin/sh
1082
+ `,L=`#!/bin/sh
1197
1083
  # Paradigm Cursor PreToolUse Hook \u2014 Graduated Blocking
1198
1084
  # Fires BEFORE the agent calls Edit or Write.
1199
1085
  # Uses graduated enforcement based on uncovered source edits.
@@ -1338,8 +1224,7 @@ else
1338
1224
  echo " Then retry your edit." >&2
1339
1225
  exit 2
1340
1226
  fi
1341
- `;
1342
- var CURSOR_POSTTOOLUSE_HOOK = `#!/bin/sh
1227
+ `,w=`#!/bin/sh
1343
1228
  # Paradigm Cursor PostToolUse Hook \u2014 Advisory Feedback
1344
1229
  # Fires AFTER the agent calls Edit or Write.
1345
1230
  # Tracks modified source files and outputs advisory the agent can see.
@@ -1463,165 +1348,9 @@ if [ "$PENDING_COUNT" -ge 30 ]; then
1463
1348
  fi
1464
1349
 
1465
1350
  exit 0
1466
- `;
1467
-
1468
- // src/commands/hooks/index.ts
1469
- function isParadigmPluginActive() {
1470
- try {
1471
- const globalSettingsPath = path.join(os.homedir(), ".claude", "settings.json");
1472
- if (!fs.existsSync(globalSettingsPath)) return { active: false };
1473
- const settings = JSON.parse(fs.readFileSync(globalSettingsPath, "utf8"));
1474
- const enabled = settings.enabledPlugins?.["paradigm@a-paradigm"];
1475
- if (!enabled) return { active: false };
1476
- const cacheBase = path.join(os.homedir(), ".claude", "plugins", "cache", "a-paradigm", "paradigm");
1477
- if (!fs.existsSync(cacheBase)) return { active: false };
1478
- const versions = fs.readdirSync(cacheBase).filter((d) => fs.statSync(path.join(cacheBase, d)).isDirectory()).sort().reverse();
1479
- if (versions.length === 0) return { active: false };
1480
- const latestCache = path.join(cacheBase, versions[0]);
1481
- const hooksJson = path.join(latestCache, "hooks", "hooks.json");
1482
- if (!fs.existsSync(hooksJson)) return { active: false };
1483
- return { active: true, cacheVersion: versions[0] };
1484
- } catch {
1485
- return { active: false };
1486
- }
1487
- }
1488
- function checkPluginVersionCompatibility() {
1489
- try {
1490
- const pluginInfo = isParadigmPluginActive();
1491
- if (!pluginInfo.active || !pluginInfo.cacheVersion) {
1492
- return { compatible: true };
1493
- }
1494
- const hooksJsonPath = path.join(
1495
- os.homedir(),
1496
- ".claude",
1497
- "plugins",
1498
- "cache",
1499
- "a-paradigm",
1500
- "paradigm",
1501
- pluginInfo.cacheVersion,
1502
- "hooks.json"
1503
- );
1504
- if (!fs.existsSync(hooksJsonPath)) {
1505
- return { compatible: true };
1506
- }
1507
- const hooksData = JSON.parse(fs.readFileSync(hooksJsonPath, "utf8"));
1508
- const compatibleVersions = hooksData.compatibleVersions;
1509
- if (!compatibleVersions) {
1510
- return { compatible: true };
1511
- }
1512
- const currentVersion = getCurrentParadigmVersion();
1513
- if (!currentVersion) {
1514
- return { compatible: true };
1515
- }
1516
- const parts = compatibleVersions.split(/\s+/);
1517
- for (const part of parts) {
1518
- const match = part.match(/^(>=?|<=?)\s*(\d+\.\d+\.\d+)/);
1519
- if (!match) continue;
1520
- const [, op, ver] = match;
1521
- const cmp = compareVersions(currentVersion, ver);
1522
- if (op === ">=" && cmp < 0) return { compatible: false, message: `Plugin requires paradigm ${compatibleVersions}, current: ${currentVersion}` };
1523
- if (op === ">" && cmp <= 0) return { compatible: false, message: `Plugin requires paradigm ${compatibleVersions}, current: ${currentVersion}` };
1524
- if (op === "<=" && cmp > 0) return { compatible: false, message: `Plugin requires paradigm ${compatibleVersions}, current: ${currentVersion}` };
1525
- if (op === "<" && cmp >= 0) return { compatible: false, message: `Plugin requires paradigm ${compatibleVersions}, current: ${currentVersion}` };
1526
- }
1527
- return { compatible: true };
1528
- } catch {
1529
- return { compatible: true };
1530
- }
1531
- }
1532
- function getCurrentParadigmVersion() {
1533
- try {
1534
- const pkgPath = path.join(path.dirname(new URL(import.meta.url).pathname), "..", "..", "package.json");
1535
- const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
1536
- return pkg.version || null;
1537
- } catch {
1538
- return null;
1539
- }
1540
- }
1541
- function compareVersions(a, b) {
1542
- const pa = a.split(".").map(Number);
1543
- const pb = b.split(".").map(Number);
1544
- for (let i = 0; i < 3; i++) {
1545
- if ((pa[i] || 0) < (pb[i] || 0)) return -1;
1546
- if ((pa[i] || 0) > (pb[i] || 0)) return 1;
1547
- }
1548
- return 0;
1549
- }
1550
- function cleanupProjectClaudeCodeHooks(rootDir) {
1551
- const removed = [];
1552
- const claudeHooksDir = path.join(rootDir, ".claude", "hooks");
1553
- if (fs.existsSync(claudeHooksDir)) {
1554
- for (const hookName of ["paradigm-common.sh", "paradigm-stop.sh", "paradigm-precommit.sh", "paradigm-postwrite.sh"]) {
1555
- const hookPath = path.join(claudeHooksDir, hookName);
1556
- if (fs.existsSync(hookPath)) {
1557
- fs.unlinkSync(hookPath);
1558
- removed.push(hookName);
1559
- }
1560
- }
1561
- try {
1562
- const remaining = fs.readdirSync(claudeHooksDir);
1563
- if (remaining.length === 0) {
1564
- fs.rmdirSync(claudeHooksDir);
1565
- }
1566
- } catch {
1567
- }
1568
- }
1569
- const settingsPath = path.join(rootDir, ".claude", "settings.json");
1570
- if (fs.existsSync(settingsPath)) {
1571
- try {
1572
- const settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
1573
- const hooks = settings.hooks;
1574
- if (hooks) {
1575
- let modified = false;
1576
- for (const [key, arr] of Object.entries(hooks)) {
1577
- if (!Array.isArray(arr)) continue;
1578
- const filtered = arr.filter(
1579
- (h) => !JSON.stringify(h).includes("paradigm-")
1580
- );
1581
- if (filtered.length !== arr.length) {
1582
- modified = true;
1583
- if (filtered.length === 0) {
1584
- delete hooks[key];
1585
- } else {
1586
- hooks[key] = filtered;
1587
- }
1588
- }
1589
- }
1590
- if (modified) {
1591
- if (Object.keys(hooks).length === 0) {
1592
- delete settings.hooks;
1593
- } else {
1594
- settings.hooks = hooks;
1595
- }
1596
- fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
1597
- removed.push("settings.json hooks");
1598
- }
1599
- }
1600
- } catch {
1601
- }
1602
- }
1603
- return { cleaned: removed.length > 0, removed };
1604
- }
1605
- function validateBashSyntax(scriptContent, scriptName) {
1606
- try {
1607
- const tmpPath = path.join(os.tmpdir(), `paradigm-hook-validate-${Date.now()}.sh`);
1608
- fs.writeFileSync(tmpPath, scriptContent, "utf8");
1609
- try {
1610
- execSync(`bash -n "${tmpPath}" 2>&1`, { encoding: "utf-8" });
1611
- return null;
1612
- } catch (err) {
1613
- return `${scriptName}: bash syntax error \u2014 ${err.message?.split("\n")[0] || "unknown error"}`;
1614
- } finally {
1615
- try {
1616
- fs.unlinkSync(tmpPath);
1617
- } catch {
1618
- }
1619
- }
1620
- } catch {
1621
- return null;
1622
- }
1623
- }
1624
- var POST_COMMIT_HOOK = `#!/bin/sh
1351
+ `;function x(){try{let i=r.join(E.homedir(),".claude","settings.json");if(!e.existsSync(i))return {active:!1};if(!JSON.parse(e.readFileSync(i,"utf8")).enabledPlugins?.["paradigm@a-paradigm"])return {active:!1};let d=r.join(E.homedir(),".claude","plugins","cache","a-paradigm","paradigm");if(!e.existsSync(d))return {active:!1};let a=e.readdirSync(d).filter(s=>e.statSync(r.join(d,s)).isDirectory()).sort().reverse();if(a.length===0)return {active:!1};let p=r.join(d,a[0]),l=r.join(p,"hooks","hooks.json");return e.existsSync(l)?{active:!0,cacheVersion:a[0]}:{active:!1}}catch{return {active:false}}}function X(){try{let i=x();if(!i.active||!i.cacheVersion)return {compatible:!0};let h=r.join(E.homedir(),".claude","plugins","cache","a-paradigm","paradigm",i.cacheVersion,"hooks.json");if(!e.existsSync(h))return {compatible:!0};let d=JSON.parse(e.readFileSync(h,"utf8")).compatibleVersions;if(!d)return {compatible:!0};let a=W();if(!a)return {compatible:!0};let p=d.split(/\s+/);for(let l of p){let s=l.match(/^(>=?|<=?)\s*(\d+\.\d+\.\d+)/);if(!s)continue;let[,t,n]=s,f=Y(a,n);if(t===">="&&f<0)return {compatible:!1,message:`Plugin requires paradigm ${d}, current: ${a}`};if(t===">"&&f<=0)return {compatible:!1,message:`Plugin requires paradigm ${d}, current: ${a}`};if(t==="<="&&f>0)return {compatible:!1,message:`Plugin requires paradigm ${d}, current: ${a}`};if(t==="<"&&f>=0)return {compatible:!1,message:`Plugin requires paradigm ${d}, current: ${a}`}}return {compatible:!0}}catch{return {compatible:true}}}function W(){try{let i=r.join(r.dirname(new URL(import.meta.url).pathname),"..","..","package.json");return JSON.parse(e.readFileSync(i,"utf8")).version||null}catch{return null}}function Y(i,h){let c=i.split(".").map(Number),d=h.split(".").map(Number);for(let a=0;a<3;a++){if((c[a]||0)<(d[a]||0))return -1;if((c[a]||0)>(d[a]||0))return 1}return 0}function J(i){let h=[],c=r.join(i,".claude","hooks");if(e.existsSync(c)){for(let a of ["paradigm-common.sh","paradigm-stop.sh","paradigm-precommit.sh","paradigm-postwrite.sh"]){let p=r.join(c,a);e.existsSync(p)&&(e.unlinkSync(p),h.push(a));}try{e.readdirSync(c).length===0&&e.rmdirSync(c);}catch{}}let d=r.join(i,".claude","settings.json");if(e.existsSync(d))try{let a=JSON.parse(e.readFileSync(d,"utf8")),p=a.hooks;if(p){let l=!1;for(let[s,t]of Object.entries(p)){if(!Array.isArray(t))continue;let n=t.filter(f=>!JSON.stringify(f).includes("paradigm-"));n.length!==t.length&&(l=!0,n.length===0?delete p[s]:p[s]=n);}l&&(Object.keys(p).length===0?delete a.hooks:a.hooks=p,e.writeFileSync(d,JSON.stringify(a,null,2)+`
1352
+ `,"utf8"),h.push("settings.json hooks"));}}catch{}return {cleaned:h.length>0,removed:h}}function q(i,h){try{let c=r.join(E.tmpdir(),`paradigm-hook-validate-${Date.now()}.sh`);e.writeFileSync(c,i,"utf8");try{return execSync(`bash -n "${c}" 2>&1`,{encoding:"utf-8"}),null}catch(d){return `${h}: bash syntax error \u2014 ${d.message?.split(`
1353
+ `)[0]||"unknown error"}`}finally{try{e.unlinkSync(c);}catch{}}}catch{return null}}var H=`#!/bin/sh
1625
1354
  # Paradigm post-commit hook - captures history from commits
1626
1355
  # Installed by: paradigm hooks install
1627
1356
 
@@ -1705,8 +1434,7 @@ if [ -n "$SYMBOLS" ] && [ -d ".paradigm/history" ]; then
1705
1434
 
1706
1435
  echo "[paradigm] History entry $ID recorded"
1707
1436
  fi
1708
- `;
1709
- var PRE_PUSH_HOOK = `#!/bin/sh
1437
+ `,j=`#!/bin/sh
1710
1438
  # Paradigm pre-push hook - reindex history before pushing
1711
1439
  # Installed by: paradigm hooks install
1712
1440
 
@@ -1714,563 +1442,25 @@ if [ -d ".paradigm/history" ] && [ -f ".paradigm/history/log.jsonl" ]; then
1714
1442
  echo "[paradigm] Reindexing history..."
1715
1443
  npx paradigm history reindex 2>/dev/null || true
1716
1444
  fi
1717
- `;
1718
- async function hooksInstallCommand(options = {}) {
1719
- const rootDir = process.cwd();
1720
- const dryRun = options.dryRun || false;
1721
- if (dryRun) {
1722
- console.log(chalk.cyan("\n [dry-run] Showing what would be installed:\n"));
1723
- }
1724
- const onlyClaudeCode = options.claudeCode && !options.postCommit && !options.prePush && !options.cursor;
1725
- const onlyCursor = options.cursor && !options.postCommit && !options.prePush && !options.claudeCode;
1726
- if (!dryRun) {
1727
- const scriptsToValidate = [
1728
- { name: "post-commit", content: POST_COMMIT_HOOK },
1729
- { name: "pre-push", content: PRE_PUSH_HOOK },
1730
- { name: "paradigm-common", content: COMMON_HOOK },
1731
- { name: "claude-code-stop", content: CLAUDE_CODE_STOP_HOOK },
1732
- { name: "claude-code-precommit", content: CLAUDE_CODE_PRECOMMIT_HOOK },
1733
- { name: "claude-code-postwrite", content: CLAUDE_CODE_POSTWRITE_HOOK },
1734
- { name: "cursor-session-start", content: CURSOR_SESSION_START_HOOK },
1735
- { name: "cursor-stop", content: CURSOR_STOP_HOOK },
1736
- { name: "cursor-precommit", content: CURSOR_PRECOMMIT_HOOK },
1737
- { name: "cursor-postwrite", content: CURSOR_POSTWRITE_HOOK },
1738
- { name: "cursor-pretooluse", content: CURSOR_PRETOOLUSE_HOOK },
1739
- { name: "cursor-posttooluse", content: CURSOR_POSTTOOLUSE_HOOK }
1740
- ];
1741
- for (const script of scriptsToValidate) {
1742
- const err = validateBashSyntax(script.content, script.name);
1743
- if (err) {
1744
- console.log(chalk.red(`Hook syntax error: ${err}`));
1745
- console.log(chalk.gray("Aborting installation. Fix the hook script and try again."));
1746
- return;
1747
- }
1748
- }
1749
- }
1750
- const compat = checkPluginVersionCompatibility();
1751
- if (!compat.compatible) {
1752
- console.log(chalk.yellow(`
1753
- \u26A0 ${compat.message}`));
1754
- console.log(chalk.gray(" Hook installation will continue, but behavior may differ from plugin expectations.\n"));
1755
- }
1756
- if (!onlyClaudeCode && !onlyCursor) {
1757
- const gitDir = path.join(rootDir, ".git");
1758
- if (!fs.existsSync(gitDir)) {
1759
- console.log(chalk.red("Not a git repository."));
1760
- return;
1761
- }
1762
- const hooksDir = path.join(gitDir, "hooks");
1763
- const installAllGit = !options.postCommit && !options.prePush && !options.claudeCode;
1764
- const installed = [];
1765
- if (installAllGit || options.postCommit) {
1766
- const hookPath = path.join(hooksDir, "post-commit");
1767
- if (dryRun) {
1768
- const action = fs.existsSync(hookPath) && !options.force ? "skip (exists)" : "install";
1769
- console.log(chalk.gray(` post-commit: ${action} \u2192 ${hookPath}`));
1770
- } else {
1771
- if (fs.existsSync(hookPath) && !options.force) {
1772
- const content = fs.readFileSync(hookPath, "utf8");
1773
- if (!content.includes("paradigm")) {
1774
- console.log(chalk.yellow("post-commit hook exists. Use --force to overwrite."));
1775
- } else {
1776
- console.log(chalk.gray("post-commit hook already installed by paradigm"));
1777
- }
1778
- } else {
1779
- fs.mkdirSync(hooksDir, { recursive: true });
1780
- fs.writeFileSync(hookPath, POST_COMMIT_HOOK);
1781
- fs.chmodSync(hookPath, "755");
1782
- installed.push("post-commit");
1783
- }
1784
- }
1785
- }
1786
- if (installAllGit || options.prePush) {
1787
- const hookPath = path.join(hooksDir, "pre-push");
1788
- if (dryRun) {
1789
- const action = fs.existsSync(hookPath) && !options.force ? "skip (exists)" : "install";
1790
- console.log(chalk.gray(` pre-push: ${action} \u2192 ${hookPath}`));
1791
- } else {
1792
- if (fs.existsSync(hookPath) && !options.force) {
1793
- const content = fs.readFileSync(hookPath, "utf8");
1794
- if (!content.includes("paradigm")) {
1795
- console.log(chalk.yellow("pre-push hook exists. Use --force to overwrite."));
1796
- } else {
1797
- console.log(chalk.gray("pre-push hook already installed by paradigm"));
1798
- }
1799
- } else {
1800
- fs.mkdirSync(hooksDir, { recursive: true });
1801
- fs.writeFileSync(hookPath, PRE_PUSH_HOOK);
1802
- fs.chmodSync(hookPath, "755");
1803
- installed.push("pre-push");
1804
- }
1805
- }
1806
- }
1807
- if (!dryRun && installed.length > 0) {
1808
- console.log(chalk.green(`Git hooks installed: ${installed.join(", ")}`));
1809
- }
1810
- const historyDir = path.join(rootDir, ".paradigm/history");
1811
- if (!fs.existsSync(historyDir) && !dryRun) {
1812
- console.log(chalk.gray("Tip: Run `paradigm history init` to initialize history tracking"));
1813
- }
1814
- }
1815
- const installAll = !options.postCommit && !options.prePush && !options.claudeCode && !options.cursor;
1816
- if (installAll || options.claudeCode) {
1817
- if (dryRun) {
1818
- console.log(chalk.gray(" Claude Code hooks: would install paradigm-stop.sh, paradigm-precommit.sh, paradigm-postwrite.sh"));
1819
- console.log(chalk.gray(` \u2192 ${path.join(rootDir, ".claude", "hooks")}/`));
1820
- console.log(chalk.gray(" \u2192 Update .claude/settings.json with hook configuration"));
1821
- } else {
1822
- await installClaudeCodeHooks(rootDir, options.force);
1823
- }
1824
- }
1825
- if (installAll || options.cursor) {
1826
- if (dryRun) {
1827
- console.log(chalk.gray(" Cursor hooks: would install paradigm-session-start.sh, paradigm-stop.sh, paradigm-precommit.sh, paradigm-postwrite.sh, paradigm-pretooluse.sh, paradigm-posttooluse.sh"));
1828
- console.log(chalk.gray(` \u2192 ${path.join(rootDir, ".cursor", "hooks")}/`));
1829
- console.log(chalk.gray(" \u2192 Update .cursor/hooks.json"));
1830
- } else {
1831
- await installCursorHooks(rootDir, options.force);
1832
- }
1833
- }
1834
- if (dryRun) {
1835
- console.log(chalk.cyan("\n [dry-run] No changes made.\n"));
1836
- }
1837
- }
1838
- async function installClaudeCodeHooks(rootDir, force) {
1839
- const plugin = isParadigmPluginActive();
1840
- if (plugin.active) {
1841
- console.log(chalk.cyan(` Paradigm plugin v${plugin.cacheVersion} is active \u2014 hooks are managed by the plugin.`));
1842
- const { cleaned, removed } = cleanupProjectClaudeCodeHooks(rootDir);
1843
- if (cleaned) {
1844
- console.log(chalk.green(` Cleaned up stale project hooks: ${removed.join(", ")}`));
1845
- } else {
1846
- console.log(chalk.gray(" No stale project hooks to clean up."));
1847
- }
1848
- console.log(chalk.gray(" Plugin hooks auto-update with each session \u2014 no manual install needed."));
1849
- return;
1850
- }
1851
- const claudeHooksDir = path.join(rootDir, ".claude", "hooks");
1852
- fs.mkdirSync(claudeHooksDir, { recursive: true });
1853
- const installed = [];
1854
- const commonPath = path.join(claudeHooksDir, "paradigm-common.sh");
1855
- fs.writeFileSync(commonPath, COMMON_HOOK, "utf8");
1856
- fs.chmodSync(commonPath, "755");
1857
- const hookScripts = [
1858
- { name: "paradigm-stop.sh", content: CLAUDE_CODE_STOP_HOOK },
1859
- { name: "paradigm-precommit.sh", content: CLAUDE_CODE_PRECOMMIT_HOOK },
1860
- { name: "paradigm-postwrite.sh", content: CLAUDE_CODE_POSTWRITE_HOOK }
1861
- ];
1862
- for (const hook of hookScripts) {
1863
- const destPath = path.join(claudeHooksDir, hook.name);
1864
- if (fs.existsSync(destPath) && !force) {
1865
- console.log(chalk.gray(` ${hook.name}: already installed`));
1866
- continue;
1867
- }
1868
- fs.writeFileSync(destPath, hook.content, "utf8");
1869
- fs.chmodSync(destPath, "755");
1870
- installed.push(hook.name);
1871
- }
1872
- const settingsPath = path.join(rootDir, ".claude", "settings.json");
1873
- let settings = {};
1874
- if (fs.existsSync(settingsPath)) {
1875
- try {
1876
- settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
1877
- } catch {
1878
- }
1879
- }
1880
- const hooks = settings.hooks || {};
1881
- const stopHookEntry = {
1882
- hooks: [{
1883
- type: "command",
1884
- command: `bash "$CLAUDE_PROJECT_DIR/.claude/hooks/paradigm-stop.sh"`,
1885
- timeout: 10
1886
- }]
1887
- };
1888
- const preCommitHookEntry = {
1889
- matcher: "Bash",
1890
- hooks: [{
1891
- type: "command",
1892
- command: `bash "$CLAUDE_PROJECT_DIR/.claude/hooks/paradigm-precommit.sh"`,
1893
- timeout: 30
1894
- }]
1895
- };
1896
- const stopHooks = hooks.Stop || [];
1897
- const hasParadigmStop = stopHooks.some(
1898
- (h) => JSON.stringify(h).includes("paradigm-stop.sh")
1899
- );
1900
- if (!hasParadigmStop) {
1901
- stopHooks.push(stopHookEntry);
1902
- }
1903
- hooks.Stop = stopHooks;
1904
- const preToolUseHooks = hooks.PreToolUse || [];
1905
- const hasParadigmPrecommit = preToolUseHooks.some(
1906
- (h) => JSON.stringify(h).includes("paradigm-precommit.sh")
1907
- );
1908
- if (!hasParadigmPrecommit) {
1909
- preToolUseHooks.push(preCommitHookEntry);
1910
- }
1911
- hooks.PreToolUse = preToolUseHooks;
1912
- const postWriteHookEntry = {
1913
- matcher: "Edit,Write",
1914
- hooks: [{
1915
- type: "command",
1916
- command: `bash "$CLAUDE_PROJECT_DIR/.claude/hooks/paradigm-postwrite.sh"`,
1917
- timeout: 5
1918
- }]
1919
- };
1920
- const postToolUseHooks = hooks.PostToolUse || [];
1921
- const hasParadigmPostwrite = postToolUseHooks.some(
1922
- (h) => JSON.stringify(h).includes("paradigm-postwrite.sh")
1923
- );
1924
- if (!hasParadigmPostwrite) {
1925
- postToolUseHooks.push(postWriteHookEntry);
1926
- }
1927
- hooks.PostToolUse = postToolUseHooks;
1928
- settings.hooks = hooks;
1929
- fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
1930
- if (installed.length > 0) {
1931
- console.log(chalk.green(`Claude Code hooks installed: ${installed.join(", ")}`));
1932
- }
1933
- console.log(chalk.green("Claude Code settings.json updated with hook configuration"));
1934
- }
1935
- async function installCursorHooks(rootDir, force) {
1936
- const cursorHooksDir = path.join(rootDir, ".cursor", "hooks");
1937
- fs.mkdirSync(cursorHooksDir, { recursive: true });
1938
- const installed = [];
1939
- const cursorCommonPath = path.join(cursorHooksDir, "paradigm-common.sh");
1940
- fs.writeFileSync(cursorCommonPath, COMMON_HOOK, "utf8");
1941
- fs.chmodSync(cursorCommonPath, "755");
1942
- const hookScripts = [
1943
- { name: "paradigm-session-start.sh", content: CURSOR_SESSION_START_HOOK },
1944
- { name: "paradigm-stop.sh", content: CURSOR_STOP_HOOK },
1945
- { name: "paradigm-precommit.sh", content: CURSOR_PRECOMMIT_HOOK },
1946
- { name: "paradigm-postwrite.sh", content: CURSOR_POSTWRITE_HOOK },
1947
- { name: "paradigm-pretooluse.sh", content: CURSOR_PRETOOLUSE_HOOK },
1948
- { name: "paradigm-posttooluse.sh", content: CURSOR_POSTTOOLUSE_HOOK }
1949
- ];
1950
- for (const hook of hookScripts) {
1951
- const destPath = path.join(cursorHooksDir, hook.name);
1952
- if (fs.existsSync(destPath) && !force) {
1953
- console.log(chalk.gray(` ${hook.name}: already installed (Cursor)`));
1954
- continue;
1955
- }
1956
- fs.writeFileSync(destPath, hook.content, "utf8");
1957
- fs.chmodSync(destPath, "755");
1958
- installed.push(hook.name);
1959
- }
1960
- const hooksJsonPath = path.join(rootDir, ".cursor", "hooks.json");
1961
- let hooksConfig = {};
1962
- if (fs.existsSync(hooksJsonPath)) {
1963
- try {
1964
- hooksConfig = JSON.parse(fs.readFileSync(hooksJsonPath, "utf8"));
1965
- } catch {
1966
- }
1967
- }
1968
- hooksConfig.version = 1;
1969
- const hooks = hooksConfig.hooks || {};
1970
- const paradigmSessionStartEntry = {
1971
- command: ".cursor/hooks/paradigm-session-start.sh",
1972
- timeout: 5
1973
- };
1974
- const paradigmStopEntry = {
1975
- command: ".cursor/hooks/paradigm-stop.sh",
1976
- timeout: 10,
1977
- loop_limit: 3
1978
- };
1979
- const paradigmPostwriteEntry = {
1980
- command: ".cursor/hooks/paradigm-postwrite.sh",
1981
- timeout: 5
1982
- };
1983
- const paradigmPrecommitEntry = {
1984
- command: ".cursor/hooks/paradigm-precommit.sh",
1985
- matcher: "git commit",
1986
- timeout: 30
1987
- };
1988
- const sessionStartHooks = hooks.sessionStart || [];
1989
- const hasParadigmSessionStart = sessionStartHooks.some(
1990
- (h) => JSON.stringify(h).includes("paradigm-session-start.sh")
1991
- );
1992
- if (!hasParadigmSessionStart) {
1993
- sessionStartHooks.push(paradigmSessionStartEntry);
1994
- }
1995
- hooks.sessionStart = sessionStartHooks;
1996
- const stopHooks = hooks.stop || [];
1997
- const hasParadigmStop = stopHooks.some(
1998
- (h) => JSON.stringify(h).includes("paradigm-stop.sh")
1999
- );
2000
- if (!hasParadigmStop) {
2001
- stopHooks.push(paradigmStopEntry);
2002
- }
2003
- hooks.stop = stopHooks;
2004
- const afterFileEditHooks = hooks.afterFileEdit || [];
2005
- const hasParadigmPostwrite = afterFileEditHooks.some(
2006
- (h) => JSON.stringify(h).includes("paradigm-postwrite.sh")
2007
- );
2008
- if (!hasParadigmPostwrite) {
2009
- afterFileEditHooks.push(paradigmPostwriteEntry);
2010
- }
2011
- hooks.afterFileEdit = afterFileEditHooks;
2012
- const paradigmPretoolUseEntry = {
2013
- command: ".cursor/hooks/paradigm-pretooluse.sh",
2014
- matcher: "Edit|Write",
2015
- timeout: 5
2016
- };
2017
- const preToolUseHooks = hooks.preToolUse || [];
2018
- const hasParadigmPretoolUse = preToolUseHooks.some(
2019
- (h) => JSON.stringify(h).includes("paradigm-pretooluse.sh")
2020
- );
2021
- if (!hasParadigmPretoolUse) {
2022
- preToolUseHooks.push(paradigmPretoolUseEntry);
2023
- }
2024
- hooks.preToolUse = preToolUseHooks;
2025
- const paradigmPosttoolUseEntry = {
2026
- command: ".cursor/hooks/paradigm-posttooluse.sh",
2027
- matcher: "Edit|Write",
2028
- timeout: 5
2029
- };
2030
- const postToolUseHooks = hooks.postToolUse || [];
2031
- const hasParadigmPosttoolUse = postToolUseHooks.some(
2032
- (h) => JSON.stringify(h).includes("paradigm-posttooluse.sh")
2033
- );
2034
- if (!hasParadigmPosttoolUse) {
2035
- postToolUseHooks.push(paradigmPosttoolUseEntry);
2036
- }
2037
- hooks.postToolUse = postToolUseHooks;
2038
- const beforeShellHooks = hooks.beforeShellExecution || [];
2039
- const hasParadigmPrecommit = beforeShellHooks.some(
2040
- (h) => JSON.stringify(h).includes("paradigm-precommit.sh")
2041
- );
2042
- if (!hasParadigmPrecommit) {
2043
- beforeShellHooks.push(paradigmPrecommitEntry);
2044
- }
2045
- hooks.beforeShellExecution = beforeShellHooks;
2046
- hooksConfig.hooks = hooks;
2047
- fs.writeFileSync(hooksJsonPath, JSON.stringify(hooksConfig, null, 2) + "\n", "utf8");
2048
- if (installed.length > 0) {
2049
- console.log(chalk.green(`Cursor hooks installed: ${installed.join(", ")}`));
2050
- }
2051
- console.log(chalk.green("Cursor hooks.json updated with hook configuration"));
2052
- }
2053
- async function hooksUninstallCommand(options = {}) {
2054
- const rootDir = process.cwd();
2055
- const dryRun = options.dryRun || false;
2056
- if (dryRun) {
2057
- console.log(chalk.cyan("\n [dry-run] Showing what would be removed:\n"));
2058
- }
2059
- if (!options.cursor) {
2060
- const gitDir = path.join(rootDir, ".git");
2061
- if (!fs.existsSync(gitDir)) {
2062
- console.log(chalk.red("Not a git repository."));
2063
- return;
2064
- }
2065
- const hooksDir = path.join(gitDir, "hooks");
2066
- const removed = [];
2067
- for (const hookName of ["post-commit", "pre-push"]) {
2068
- const hookPath = path.join(hooksDir, hookName);
2069
- if (fs.existsSync(hookPath)) {
2070
- const content = fs.readFileSync(hookPath, "utf8");
2071
- if (content.includes("paradigm")) {
2072
- if (dryRun) {
2073
- console.log(chalk.gray(` Would remove: ${hookPath}`));
2074
- } else {
2075
- fs.unlinkSync(hookPath);
2076
- }
2077
- removed.push(hookName);
2078
- }
2079
- }
2080
- }
2081
- if (!dryRun) {
2082
- if (removed.length > 0) {
2083
- console.log(chalk.green(`Git hooks removed: ${removed.join(", ")}`));
2084
- } else {
2085
- console.log(chalk.gray("No paradigm git hooks found to remove"));
2086
- }
2087
- } else if (removed.length === 0) {
2088
- console.log(chalk.gray(" No paradigm git hooks to remove"));
2089
- }
2090
- }
2091
- if (options.cursor) {
2092
- const cursorHooksDir = path.join(rootDir, ".cursor", "hooks");
2093
- const cursorRemoved = [];
2094
- for (const hookName of ["paradigm-session-start.sh", "paradigm-stop.sh", "paradigm-precommit.sh", "paradigm-postwrite.sh", "paradigm-pretooluse.sh", "paradigm-posttooluse.sh"]) {
2095
- const hookPath = path.join(cursorHooksDir, hookName);
2096
- if (fs.existsSync(hookPath)) {
2097
- if (dryRun) {
2098
- console.log(chalk.gray(` Would remove: ${hookPath}`));
2099
- } else {
2100
- fs.unlinkSync(hookPath);
2101
- }
2102
- cursorRemoved.push(hookName);
2103
- }
2104
- }
2105
- const hooksJsonPath = path.join(rootDir, ".cursor", "hooks.json");
2106
- if (fs.existsSync(hooksJsonPath)) {
2107
- if (dryRun) {
2108
- console.log(chalk.gray(` Would clean paradigm entries from: ${hooksJsonPath}`));
2109
- } else {
2110
- try {
2111
- const hooksConfig = JSON.parse(fs.readFileSync(hooksJsonPath, "utf8"));
2112
- const hooks = hooksConfig.hooks || {};
2113
- for (const key of ["sessionStart", "stop", "afterFileEdit", "beforeShellExecution", "preToolUse", "postToolUse"]) {
2114
- if (Array.isArray(hooks[key])) {
2115
- hooks[key] = hooks[key].filter(
2116
- (h) => !JSON.stringify(h).includes("paradigm-")
2117
- );
2118
- if (hooks[key].length === 0) {
2119
- delete hooks[key];
2120
- }
2121
- }
2122
- }
2123
- hooksConfig.hooks = hooks;
2124
- fs.writeFileSync(hooksJsonPath, JSON.stringify(hooksConfig, null, 2) + "\n", "utf8");
2125
- } catch {
2126
- }
2127
- }
2128
- }
2129
- if (!dryRun) {
2130
- if (cursorRemoved.length > 0) {
2131
- console.log(chalk.green(`Cursor hooks removed: ${cursorRemoved.join(", ")}`));
2132
- } else {
2133
- console.log(chalk.gray("No paradigm Cursor hooks found to remove"));
2134
- }
2135
- } else if (cursorRemoved.length === 0) {
2136
- console.log(chalk.gray(" No paradigm Cursor hooks to remove"));
2137
- }
2138
- }
2139
- if (dryRun) {
2140
- console.log(chalk.cyan("\n [dry-run] No changes made.\n"));
2141
- }
2142
- }
2143
- async function hooksStatusCommand() {
2144
- const rootDir = process.cwd();
2145
- const gitDir = path.join(rootDir, ".git");
2146
- if (fs.existsSync(gitDir)) {
2147
- console.log(chalk.magenta("\n Git Hooks Status\n"));
2148
- const hooksDir = path.join(gitDir, "hooks");
2149
- const hooks = ["post-commit", "pre-push"];
2150
- for (const hookName of hooks) {
2151
- const hookPath = path.join(hooksDir, hookName);
2152
- if (fs.existsSync(hookPath)) {
2153
- const content = fs.readFileSync(hookPath, "utf8");
2154
- if (content.includes("paradigm")) {
2155
- console.log(chalk.green(` ${hookName}: installed (paradigm)`));
2156
- } else {
2157
- console.log(chalk.yellow(` ${hookName}: exists (other)`));
2158
- }
2159
- } else {
2160
- console.log(chalk.gray(` ${hookName}: not installed`));
2161
- }
2162
- }
2163
- console.log();
2164
- const historyDir = path.join(rootDir, ".paradigm/history");
2165
- if (fs.existsSync(historyDir)) {
2166
- const logPath = path.join(historyDir, "log.jsonl");
2167
- if (fs.existsSync(logPath)) {
2168
- const content = fs.readFileSync(logPath, "utf8");
2169
- const count = content.split("\n").filter((l) => l.trim()).length;
2170
- console.log(chalk.white(` History entries: ${count}`));
2171
- }
2172
- } else {
2173
- console.log(chalk.gray(" History: not initialized"));
2174
- console.log(chalk.gray(" Run `paradigm history init` to enable"));
2175
- }
2176
- } else {
2177
- console.log(chalk.gray("\n Not a git repository (git hooks N/A)\n"));
2178
- }
2179
- console.log(chalk.magenta(" Claude Code Hooks Status\n"));
2180
- const plugin = isParadigmPluginActive();
2181
- if (plugin.active) {
2182
- console.log(chalk.cyan(` Plugin: paradigm v${plugin.cacheVersion} (active)`));
2183
- console.log(chalk.green(" Hooks are managed by the plugin \u2014 auto-updates with each session."));
2184
- const claudeHooksDir = path.join(rootDir, ".claude", "hooks");
2185
- const staleHooks = [];
2186
- for (const hookName of ["paradigm-common.sh", "paradigm-stop.sh", "paradigm-precommit.sh", "paradigm-postwrite.sh"]) {
2187
- if (fs.existsSync(path.join(claudeHooksDir, hookName))) {
2188
- staleHooks.push(hookName);
2189
- }
2190
- }
2191
- const settingsPath = path.join(rootDir, ".claude", "settings.json");
2192
- let hasProjectHookEntries = false;
2193
- if (fs.existsSync(settingsPath)) {
2194
- try {
2195
- const settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
2196
- hasProjectHookEntries = JSON.stringify(settings.hooks || {}).includes("paradigm-");
2197
- } catch {
2198
- }
2199
- }
2200
- if (staleHooks.length > 0 || hasProjectHookEntries) {
2201
- console.log(chalk.yellow(` WARNING: Stale project hooks detected (${staleHooks.join(", ")}${hasProjectHookEntries ? ", settings.json entries" : ""})`));
2202
- console.log(chalk.yellow(" These shadow the plugin hooks and may run outdated logic."));
2203
- console.log(chalk.gray(" Run `paradigm hooks install --claude-code` to clean them up."));
2204
- }
2205
- } else {
2206
- console.log(chalk.gray(" Plugin: not active (using project-level hooks)"));
2207
- const claudeHooksDir = path.join(rootDir, ".claude", "hooks");
2208
- const claudeHooks = ["paradigm-stop.sh", "paradigm-precommit.sh", "paradigm-postwrite.sh"];
2209
- for (const hookName of claudeHooks) {
2210
- const hookPath = path.join(claudeHooksDir, hookName);
2211
- if (fs.existsSync(hookPath)) {
2212
- console.log(chalk.green(` ${hookName}: installed`));
2213
- } else {
2214
- console.log(chalk.gray(` ${hookName}: not installed`));
2215
- }
2216
- }
2217
- const settingsPath = path.join(rootDir, ".claude", "settings.json");
2218
- if (fs.existsSync(settingsPath)) {
2219
- try {
2220
- const settings = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
2221
- const hooks = settings.hooks || {};
2222
- const hasStop = JSON.stringify(hooks.Stop || []).includes("paradigm-stop.sh");
2223
- const hasPrecommit = JSON.stringify(hooks.PreToolUse || []).includes("paradigm-precommit.sh");
2224
- const hasPostwrite = JSON.stringify(hooks.PostToolUse || []).includes("paradigm-postwrite.sh");
2225
- console.log(chalk.gray(` settings.json Stop hook: ${hasStop ? "configured" : "missing"}`));
2226
- console.log(chalk.gray(` settings.json PreToolUse hook: ${hasPrecommit ? "configured" : "missing"}`));
2227
- console.log(chalk.gray(` settings.json PostToolUse hook: ${hasPostwrite ? "configured" : "missing"}`));
2228
- } catch {
2229
- console.log(chalk.yellow(" settings.json: parse error"));
2230
- }
2231
- } else {
2232
- console.log(chalk.gray(" settings.json: not found"));
2233
- }
2234
- }
2235
- console.log(chalk.magenta("\n Cursor Hooks Status\n"));
2236
- const cursorHooksDir = path.join(rootDir, ".cursor", "hooks");
2237
- const cursorHooks = ["paradigm-session-start.sh", "paradigm-stop.sh", "paradigm-precommit.sh", "paradigm-postwrite.sh", "paradigm-pretooluse.sh", "paradigm-posttooluse.sh"];
2238
- for (const hookName of cursorHooks) {
2239
- const hookPath = path.join(cursorHooksDir, hookName);
2240
- if (fs.existsSync(hookPath)) {
2241
- console.log(chalk.green(` ${hookName}: installed`));
2242
- } else {
2243
- console.log(chalk.gray(` ${hookName}: not installed`));
2244
- }
2245
- }
2246
- const cursorHooksJsonPath = path.join(rootDir, ".cursor", "hooks.json");
2247
- if (fs.existsSync(cursorHooksJsonPath)) {
2248
- try {
2249
- const hooksJson = JSON.parse(fs.readFileSync(cursorHooksJsonPath, "utf8"));
2250
- const hooks = hooksJson.hooks || {};
2251
- const hasSessionStart = JSON.stringify(hooks.sessionStart || []).includes("paradigm-session-start.sh");
2252
- const hasStop = JSON.stringify(hooks.stop || []).includes("paradigm-stop.sh");
2253
- const hasPostwrite = JSON.stringify(hooks.afterFileEdit || []).includes("paradigm-postwrite.sh");
2254
- const hasPrecommit = JSON.stringify(hooks.beforeShellExecution || []).includes("paradigm-precommit.sh");
2255
- const hasPretoolUse = JSON.stringify(hooks.preToolUse || []).includes("paradigm-pretooluse.sh");
2256
- const hasPosttoolUse = JSON.stringify(hooks.postToolUse || []).includes("paradigm-posttooluse.sh");
2257
- console.log(chalk.gray(` hooks.json sessionStart: ${hasSessionStart ? "configured" : "missing"}`));
2258
- console.log(chalk.gray(` hooks.json stop: ${hasStop ? "configured" : "missing"}`));
2259
- console.log(chalk.gray(` hooks.json afterFileEdit: ${hasPostwrite ? "configured" : "missing"}`));
2260
- console.log(chalk.gray(` hooks.json preToolUse: ${hasPretoolUse ? "configured" : "missing"}`));
2261
- console.log(chalk.gray(` hooks.json postToolUse: ${hasPosttoolUse ? "configured" : "missing"}`));
2262
- console.log(chalk.gray(` hooks.json beforeShellExecution: ${hasPrecommit ? "configured" : "missing"}`));
2263
- } catch {
2264
- console.log(chalk.yellow(" hooks.json: parse error"));
2265
- }
2266
- } else {
2267
- console.log(chalk.gray(" hooks.json: not found"));
2268
- }
2269
- console.log();
2270
- }
2271
-
2272
- export {
2273
- hooksInstallCommand,
2274
- hooksUninstallCommand,
2275
- hooksStatusCommand
2276
- };
1445
+ `;async function te(i={}){let h=process.cwd(),c=i.dryRun||false;c&&console.log(o.cyan(`
1446
+ [dry-run] Showing what would be installed:
1447
+ `));let d=i.claudeCode&&!i.postCommit&&!i.prePush&&!i.cursor,a=i.cursor&&!i.postCommit&&!i.prePush&&!i.claudeCode;if(!c){let s=[{name:"post-commit",content:H},{name:"pre-push",content:j},{name:"paradigm-common",content:C},{name:"claude-code-stop",content:R},{name:"claude-code-precommit",content:A},{name:"claude-code-postwrite",content:U},{name:"cursor-session-start",content:P},{name:"cursor-stop",content:v},{name:"cursor-precommit",content:b},{name:"cursor-postwrite",content:D},{name:"cursor-pretooluse",content:L},{name:"cursor-posttooluse",content:w}];for(let t of s){let n=q(t.content,t.name);if(n){console.log(o.red(`Hook syntax error: ${n}`)),console.log(o.gray("Aborting installation. Fix the hook script and try again."));return}}}let p=X();if(p.compatible||(console.log(o.yellow(`
1448
+ \u26A0 ${p.message}`)),console.log(o.gray(` Hook installation will continue, but behavior may differ from plugin expectations.
1449
+ `))),!d&&!a){let s=r.join(h,".git");if(!e.existsSync(s)){console.log(o.red("Not a git repository."));return}let t=r.join(s,"hooks"),n=!i.postCommit&&!i.prePush&&!i.claudeCode,f=[];if(n||i.postCommit){let u=r.join(t,"post-commit");if(c){let g=e.existsSync(u)&&!i.force?"skip (exists)":"install";console.log(o.gray(` post-commit: ${g} \u2192 ${u}`));}else e.existsSync(u)&&!i.force?e.readFileSync(u,"utf8").includes("paradigm")?console.log(o.gray("post-commit hook already installed by paradigm")):console.log(o.yellow("post-commit hook exists. Use --force to overwrite.")):(e.mkdirSync(t,{recursive:true}),e.writeFileSync(u,H),e.chmodSync(u,"755"),f.push("post-commit"));}if(n||i.prePush){let u=r.join(t,"pre-push");if(c){let g=e.existsSync(u)&&!i.force?"skip (exists)":"install";console.log(o.gray(` pre-push: ${g} \u2192 ${u}`));}else e.existsSync(u)&&!i.force?e.readFileSync(u,"utf8").includes("paradigm")?console.log(o.gray("pre-push hook already installed by paradigm")):console.log(o.yellow("pre-push hook exists. Use --force to overwrite.")):(e.mkdirSync(t,{recursive:true}),e.writeFileSync(u,j),e.chmodSync(u,"755"),f.push("pre-push"));}!c&&f.length>0&&console.log(o.green(`Git hooks installed: ${f.join(", ")}`));let _=r.join(h,".paradigm/history");!e.existsSync(_)&&!c&&console.log(o.gray("Tip: Run `paradigm history init` to initialize history tracking"));}let l=!i.postCommit&&!i.prePush&&!i.claudeCode&&!i.cursor;(l||i.claudeCode)&&(c?(console.log(o.gray(" Claude Code hooks: would install paradigm-stop.sh, paradigm-precommit.sh, paradigm-postwrite.sh")),console.log(o.gray(` \u2192 ${r.join(h,".claude","hooks")}/`)),console.log(o.gray(" \u2192 Update .claude/settings.json with hook configuration"))):await B(h,i.force)),(l||i.cursor)&&(c?(console.log(o.gray(" Cursor hooks: would install paradigm-session-start.sh, paradigm-stop.sh, paradigm-precommit.sh, paradigm-postwrite.sh, paradigm-pretooluse.sh, paradigm-posttooluse.sh")),console.log(o.gray(` \u2192 ${r.join(h,".cursor","hooks")}/`)),console.log(o.gray(" \u2192 Update .cursor/hooks.json"))):await K(h,i.force)),c&&console.log(o.cyan(`
1450
+ [dry-run] No changes made.
1451
+ `));}async function B(i,h){let c=x();if(c.active){console.log(o.cyan(` Paradigm plugin v${c.cacheVersion} is active \u2014 hooks are managed by the plugin.`));let{cleaned:O,removed:$}=J(i);console.log(O?o.green(` Cleaned up stale project hooks: ${$.join(", ")}`):o.gray(" No stale project hooks to clean up.")),console.log(o.gray(" Plugin hooks auto-update with each session \u2014 no manual install needed."));return}let d=r.join(i,".claude","hooks");e.mkdirSync(d,{recursive:true});let a=[],p=r.join(d,"paradigm-common.sh");e.writeFileSync(p,C,"utf8"),e.chmodSync(p,"755");let l=[{name:"paradigm-stop.sh",content:R},{name:"paradigm-precommit.sh",content:A},{name:"paradigm-postwrite.sh",content:U}];for(let O of l){let $=r.join(d,O.name);if(e.existsSync($)&&!h){console.log(o.gray(` ${O.name}: already installed`));continue}e.writeFileSync($,O.content,"utf8"),e.chmodSync($,"755"),a.push(O.name);}let s=r.join(i,".claude","settings.json"),t={};if(e.existsSync(s))try{t=JSON.parse(e.readFileSync(s,"utf8"));}catch{}let n=t.hooks||{},f={hooks:[{type:"command",command:'bash "$CLAUDE_PROJECT_DIR/.claude/hooks/paradigm-stop.sh"',timeout:10}]},_={matcher:"Bash",hooks:[{type:"command",command:'bash "$CLAUDE_PROJECT_DIR/.claude/hooks/paradigm-precommit.sh"',timeout:30}]},u=n.Stop||[];u.some(O=>JSON.stringify(O).includes("paradigm-stop.sh"))||u.push(f),n.Stop=u;let S=n.PreToolUse||[];S.some(O=>JSON.stringify(O).includes("paradigm-precommit.sh"))||S.push(_),n.PreToolUse=S;let F={matcher:"Edit,Write",hooks:[{type:"command",command:'bash "$CLAUDE_PROJECT_DIR/.claude/hooks/paradigm-postwrite.sh"',timeout:5}]},T=n.PostToolUse||[];T.some(O=>JSON.stringify(O).includes("paradigm-postwrite.sh"))||T.push(F),n.PostToolUse=T,t.hooks=n,e.writeFileSync(s,JSON.stringify(t,null,2)+`
1452
+ `,"utf8"),a.length>0&&console.log(o.green(`Claude Code hooks installed: ${a.join(", ")}`)),console.log(o.green("Claude Code settings.json updated with hook configuration"));}async function K(i,h){let c=r.join(i,".cursor","hooks");e.mkdirSync(c,{recursive:true});let d=[],a=r.join(c,"paradigm-common.sh");e.writeFileSync(a,C,"utf8"),e.chmodSync(a,"755");let p=[{name:"paradigm-session-start.sh",content:P},{name:"paradigm-stop.sh",content:v},{name:"paradigm-precommit.sh",content:b},{name:"paradigm-postwrite.sh",content:D},{name:"paradigm-pretooluse.sh",content:L},{name:"paradigm-posttooluse.sh",content:w}];for(let m of p){let k=r.join(c,m.name);if(e.existsSync(k)&&!h){console.log(o.gray(` ${m.name}: already installed (Cursor)`));continue}e.writeFileSync(k,m.content,"utf8"),e.chmodSync(k,"755"),d.push(m.name);}let l=r.join(i,".cursor","hooks.json"),s={};if(e.existsSync(l))try{s=JSON.parse(e.readFileSync(l,"utf8"));}catch{}s.version=1;let t=s.hooks||{},n={command:".cursor/hooks/paradigm-session-start.sh",timeout:5},f={command:".cursor/hooks/paradigm-stop.sh",timeout:10,loop_limit:3},_={command:".cursor/hooks/paradigm-postwrite.sh",timeout:5},u={command:".cursor/hooks/paradigm-precommit.sh",matcher:"git commit",timeout:30},g=t.sessionStart||[];g.some(m=>JSON.stringify(m).includes("paradigm-session-start.sh"))||g.push(n),t.sessionStart=g;let I=t.stop||[];I.some(m=>JSON.stringify(m).includes("paradigm-stop.sh"))||I.push(f),t.stop=I;let T=t.afterFileEdit||[];T.some(m=>JSON.stringify(m).includes("paradigm-postwrite.sh"))||T.push(_),t.afterFileEdit=T;let O={command:".cursor/hooks/paradigm-pretooluse.sh",matcher:"Edit|Write",timeout:5},$=t.preToolUse||[];$.some(m=>JSON.stringify(m).includes("paradigm-pretooluse.sh"))||$.push(O),t.preToolUse=$;let V={command:".cursor/hooks/paradigm-posttooluse.sh",matcher:"Edit|Write",timeout:5},y=t.postToolUse||[];y.some(m=>JSON.stringify(m).includes("paradigm-posttooluse.sh"))||y.push(V),t.postToolUse=y;let N=t.beforeShellExecution||[];N.some(m=>JSON.stringify(m).includes("paradigm-precommit.sh"))||N.push(u),t.beforeShellExecution=N,s.hooks=t,e.writeFileSync(l,JSON.stringify(s,null,2)+`
1453
+ `,"utf8"),d.length>0&&console.log(o.green(`Cursor hooks installed: ${d.join(", ")}`)),console.log(o.green("Cursor hooks.json updated with hook configuration"));}async function re(i={}){let h=process.cwd(),c=i.dryRun||false;if(c&&console.log(o.cyan(`
1454
+ [dry-run] Showing what would be removed:
1455
+ `)),!i.cursor){let d=r.join(h,".git");if(!e.existsSync(d)){console.log(o.red("Not a git repository."));return}let a=r.join(d,"hooks"),p=[];for(let l of ["post-commit","pre-push"]){let s=r.join(a,l);e.existsSync(s)&&e.readFileSync(s,"utf8").includes("paradigm")&&(c?console.log(o.gray(` Would remove: ${s}`)):e.unlinkSync(s),p.push(l));}c?p.length===0&&console.log(o.gray(" No paradigm git hooks to remove")):p.length>0?console.log(o.green(`Git hooks removed: ${p.join(", ")}`)):console.log(o.gray("No paradigm git hooks found to remove"));}if(i.cursor){let d=r.join(h,".cursor","hooks"),a=[];for(let l of ["paradigm-session-start.sh","paradigm-stop.sh","paradigm-precommit.sh","paradigm-postwrite.sh","paradigm-pretooluse.sh","paradigm-posttooluse.sh"]){let s=r.join(d,l);e.existsSync(s)&&(c?console.log(o.gray(` Would remove: ${s}`)):e.unlinkSync(s),a.push(l));}let p=r.join(h,".cursor","hooks.json");if(e.existsSync(p))if(c)console.log(o.gray(` Would clean paradigm entries from: ${p}`));else try{let l=JSON.parse(e.readFileSync(p,"utf8")),s=l.hooks||{};for(let t of ["sessionStart","stop","afterFileEdit","beforeShellExecution","preToolUse","postToolUse"])Array.isArray(s[t])&&(s[t]=s[t].filter(n=>!JSON.stringify(n).includes("paradigm-")),s[t].length===0&&delete s[t]);l.hooks=s,e.writeFileSync(p,JSON.stringify(l,null,2)+`
1456
+ `,"utf8");}catch{}c?a.length===0&&console.log(o.gray(" No paradigm Cursor hooks to remove")):a.length>0?console.log(o.green(`Cursor hooks removed: ${a.join(", ")}`)):console.log(o.gray("No paradigm Cursor hooks found to remove"));}c&&console.log(o.cyan(`
1457
+ [dry-run] No changes made.
1458
+ `));}async function ae(){let i=process.cwd(),h=r.join(i,".git");if(e.existsSync(h)){console.log(o.magenta(`
1459
+ Git Hooks Status
1460
+ `));let l=r.join(h,"hooks"),s=["post-commit","pre-push"];for(let n of s){let f=r.join(l,n);e.existsSync(f)?e.readFileSync(f,"utf8").includes("paradigm")?console.log(o.green(` ${n}: installed (paradigm)`)):console.log(o.yellow(` ${n}: exists (other)`)):console.log(o.gray(` ${n}: not installed`));}console.log();let t=r.join(i,".paradigm/history");if(e.existsSync(t)){let n=r.join(t,"log.jsonl");if(e.existsSync(n)){let _=e.readFileSync(n,"utf8").split(`
1461
+ `).filter(u=>u.trim()).length;console.log(o.white(` History entries: ${_}`));}}else console.log(o.gray(" History: not initialized")),console.log(o.gray(" Run `paradigm history init` to enable"));}else console.log(o.gray(`
1462
+ Not a git repository (git hooks N/A)
1463
+ `));console.log(o.magenta(` Claude Code Hooks Status
1464
+ `));let c=x();if(c.active){console.log(o.cyan(` Plugin: paradigm v${c.cacheVersion} (active)`)),console.log(o.green(" Hooks are managed by the plugin \u2014 auto-updates with each session."));let l=r.join(i,".claude","hooks"),s=[];for(let f of ["paradigm-common.sh","paradigm-stop.sh","paradigm-precommit.sh","paradigm-postwrite.sh"])e.existsSync(r.join(l,f))&&s.push(f);let t=r.join(i,".claude","settings.json"),n=false;if(e.existsSync(t))try{let f=JSON.parse(e.readFileSync(t,"utf8"));n=JSON.stringify(f.hooks||{}).includes("paradigm-");}catch{}(s.length>0||n)&&(console.log(o.yellow(` WARNING: Stale project hooks detected (${s.join(", ")}${n?", settings.json entries":""})`)),console.log(o.yellow(" These shadow the plugin hooks and may run outdated logic.")),console.log(o.gray(" Run `paradigm hooks install --claude-code` to clean them up.")));}else {console.log(o.gray(" Plugin: not active (using project-level hooks)"));let l=r.join(i,".claude","hooks"),s=["paradigm-stop.sh","paradigm-precommit.sh","paradigm-postwrite.sh"];for(let n of s){let f=r.join(l,n);e.existsSync(f)?console.log(o.green(` ${n}: installed`)):console.log(o.gray(` ${n}: not installed`));}let t=r.join(i,".claude","settings.json");if(e.existsSync(t))try{let f=JSON.parse(e.readFileSync(t,"utf8")).hooks||{},_=JSON.stringify(f.Stop||[]).includes("paradigm-stop.sh"),u=JSON.stringify(f.PreToolUse||[]).includes("paradigm-precommit.sh"),g=JSON.stringify(f.PostToolUse||[]).includes("paradigm-postwrite.sh");console.log(o.gray(` settings.json Stop hook: ${_?"configured":"missing"}`)),console.log(o.gray(` settings.json PreToolUse hook: ${u?"configured":"missing"}`)),console.log(o.gray(` settings.json PostToolUse hook: ${g?"configured":"missing"}`));}catch{console.log(o.yellow(" settings.json: parse error"));}else console.log(o.gray(" settings.json: not found"));}console.log(o.magenta(`
1465
+ Cursor Hooks Status
1466
+ `));let d=r.join(i,".cursor","hooks"),a=["paradigm-session-start.sh","paradigm-stop.sh","paradigm-precommit.sh","paradigm-postwrite.sh","paradigm-pretooluse.sh","paradigm-posttooluse.sh"];for(let l of a){let s=r.join(d,l);e.existsSync(s)?console.log(o.green(` ${l}: installed`)):console.log(o.gray(` ${l}: not installed`));}let p=r.join(i,".cursor","hooks.json");if(e.existsSync(p))try{let s=JSON.parse(e.readFileSync(p,"utf8")).hooks||{},t=JSON.stringify(s.sessionStart||[]).includes("paradigm-session-start.sh"),n=JSON.stringify(s.stop||[]).includes("paradigm-stop.sh"),f=JSON.stringify(s.afterFileEdit||[]).includes("paradigm-postwrite.sh"),_=JSON.stringify(s.beforeShellExecution||[]).includes("paradigm-precommit.sh"),u=JSON.stringify(s.preToolUse||[]).includes("paradigm-pretooluse.sh"),g=JSON.stringify(s.postToolUse||[]).includes("paradigm-posttooluse.sh");console.log(o.gray(` hooks.json sessionStart: ${t?"configured":"missing"}`)),console.log(o.gray(` hooks.json stop: ${n?"configured":"missing"}`)),console.log(o.gray(` hooks.json afterFileEdit: ${f?"configured":"missing"}`)),console.log(o.gray(` hooks.json preToolUse: ${u?"configured":"missing"}`)),console.log(o.gray(` hooks.json postToolUse: ${g?"configured":"missing"}`)),console.log(o.gray(` hooks.json beforeShellExecution: ${_?"configured":"missing"}`));}catch{console.log(o.yellow(" hooks.json: parse error"));}else console.log(o.gray(" hooks.json: not found"));console.log();}export{te as a,re as b,ae as c};