@planu/cli 0.43.1 → 0.44.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 (369) hide show
  1. package/dist/cli/colors.d.ts +14 -0
  2. package/dist/cli/colors.d.ts.map +1 -0
  3. package/dist/cli/colors.js +26 -0
  4. package/dist/cli/colors.js.map +1 -0
  5. package/dist/cli/commands/audit.d.ts +3 -0
  6. package/dist/cli/commands/audit.d.ts.map +1 -0
  7. package/dist/cli/commands/audit.js +38 -0
  8. package/dist/cli/commands/audit.js.map +1 -0
  9. package/dist/cli/commands/create.d.ts +3 -0
  10. package/dist/cli/commands/create.d.ts.map +1 -0
  11. package/dist/cli/commands/create.js +50 -0
  12. package/dist/cli/commands/create.js.map +1 -0
  13. package/dist/cli/commands/dashboard.d.ts +3 -0
  14. package/dist/cli/commands/dashboard.d.ts.map +1 -0
  15. package/dist/cli/commands/dashboard.js +29 -0
  16. package/dist/cli/commands/dashboard.js.map +1 -0
  17. package/dist/cli/commands/estimate.d.ts +3 -0
  18. package/dist/cli/commands/estimate.d.ts.map +1 -0
  19. package/dist/cli/commands/estimate.js +36 -0
  20. package/dist/cli/commands/estimate.js.map +1 -0
  21. package/dist/cli/commands/handoff.d.ts +3 -0
  22. package/dist/cli/commands/handoff.d.ts.map +1 -0
  23. package/dist/cli/commands/handoff.js +49 -0
  24. package/dist/cli/commands/handoff.js.map +1 -0
  25. package/dist/cli/commands/init.d.ts +3 -0
  26. package/dist/cli/commands/init.d.ts.map +1 -0
  27. package/dist/cli/commands/init.js +43 -0
  28. package/dist/cli/commands/init.js.map +1 -0
  29. package/dist/cli/commands/list.d.ts +3 -0
  30. package/dist/cli/commands/list.d.ts.map +1 -0
  31. package/dist/cli/commands/list.js +36 -0
  32. package/dist/cli/commands/list.js.map +1 -0
  33. package/dist/cli/commands/serve.d.ts +3 -0
  34. package/dist/cli/commands/serve.d.ts.map +1 -0
  35. package/dist/cli/commands/serve.js +34 -0
  36. package/dist/cli/commands/serve.js.map +1 -0
  37. package/dist/cli/commands/status.d.ts +3 -0
  38. package/dist/cli/commands/status.d.ts.map +1 -0
  39. package/dist/cli/commands/status.js +49 -0
  40. package/dist/cli/commands/status.js.map +1 -0
  41. package/dist/cli/commands/validate.d.ts +3 -0
  42. package/dist/cli/commands/validate.d.ts.map +1 -0
  43. package/dist/cli/commands/validate.js +36 -0
  44. package/dist/cli/commands/validate.js.map +1 -0
  45. package/dist/cli/commands/watch.d.ts +3 -0
  46. package/dist/cli/commands/watch.d.ts.map +1 -0
  47. package/dist/cli/commands/watch.js +156 -0
  48. package/dist/cli/commands/watch.js.map +1 -0
  49. package/dist/cli/formatter.d.ts +18 -0
  50. package/dist/cli/formatter.d.ts.map +1 -0
  51. package/dist/cli/formatter.js +78 -0
  52. package/dist/cli/formatter.js.map +1 -0
  53. package/dist/cli/index.d.ts +6 -0
  54. package/dist/cli/index.d.ts.map +1 -0
  55. package/dist/cli/index.js +7 -0
  56. package/dist/cli/index.js.map +1 -0
  57. package/dist/cli/interactive.d.ts +13 -0
  58. package/dist/cli/interactive.d.ts.map +1 -0
  59. package/dist/cli/interactive.js +42 -0
  60. package/dist/cli/interactive.js.map +1 -0
  61. package/dist/cli/project-detector.d.ts +6 -0
  62. package/dist/cli/project-detector.d.ts.map +1 -0
  63. package/dist/cli/project-detector.js +12 -0
  64. package/dist/cli/project-detector.js.map +1 -0
  65. package/dist/cli/router.d.ts +5 -0
  66. package/dist/cli/router.d.ts.map +1 -0
  67. package/dist/cli/router.js +104 -0
  68. package/dist/cli/router.js.map +1 -0
  69. package/dist/config/hook-defaults.json +19 -0
  70. package/dist/config/license-plans.json +16 -1
  71. package/dist/config/tool-groups.json +12 -1
  72. package/dist/engine/analyzer/analyze-project.d.ts +15 -0
  73. package/dist/engine/analyzer/analyze-project.d.ts.map +1 -0
  74. package/dist/engine/analyzer/analyze-project.js +101 -0
  75. package/dist/engine/analyzer/analyze-project.js.map +1 -0
  76. package/dist/engine/analyzer/completeness-checker.d.ts +6 -0
  77. package/dist/engine/analyzer/completeness-checker.d.ts.map +1 -0
  78. package/dist/engine/analyzer/completeness-checker.js +79 -0
  79. package/dist/engine/analyzer/completeness-checker.js.map +1 -0
  80. package/dist/engine/analyzer/db-engine.d.ts +9 -0
  81. package/dist/engine/analyzer/db-engine.d.ts.map +1 -0
  82. package/dist/engine/analyzer/db-engine.js +137 -0
  83. package/dist/engine/analyzer/db-engine.js.map +1 -0
  84. package/dist/engine/analyzer/detectors.d.ts +7 -0
  85. package/dist/engine/analyzer/detectors.d.ts.map +1 -0
  86. package/dist/engine/analyzer/detectors.js +234 -0
  87. package/dist/engine/analyzer/detectors.js.map +1 -0
  88. package/dist/engine/analyzer/env-setup.d.ts +6 -0
  89. package/dist/engine/analyzer/env-setup.d.ts.map +1 -0
  90. package/dist/engine/analyzer/env-setup.js +174 -0
  91. package/dist/engine/analyzer/env-setup.js.map +1 -0
  92. package/dist/engine/analyzer/index.d.ts +6 -0
  93. package/dist/engine/analyzer/index.d.ts.map +1 -0
  94. package/dist/engine/analyzer/index.js +8 -0
  95. package/dist/engine/analyzer/index.js.map +1 -0
  96. package/dist/engine/analyzer-db.d.ts +1 -8
  97. package/dist/engine/analyzer-db.d.ts.map +1 -1
  98. package/dist/engine/analyzer-db.js +3 -136
  99. package/dist/engine/analyzer-db.js.map +1 -1
  100. package/dist/engine/analyzer-detectors.d.ts +1 -6
  101. package/dist/engine/analyzer-detectors.d.ts.map +1 -1
  102. package/dist/engine/analyzer-detectors.js +3 -231
  103. package/dist/engine/analyzer-detectors.js.map +1 -1
  104. package/dist/engine/analyzer-env.d.ts +1 -5
  105. package/dist/engine/analyzer-env.d.ts.map +1 -1
  106. package/dist/engine/analyzer-env.js +3 -173
  107. package/dist/engine/analyzer-env.js.map +1 -1
  108. package/dist/engine/analyzer.d.ts +2 -18
  109. package/dist/engine/analyzer.d.ts.map +1 -1
  110. package/dist/engine/analyzer.js +4 -172
  111. package/dist/engine/analyzer.js.map +1 -1
  112. package/dist/engine/dashboard/data-loader.d.ts +16 -1
  113. package/dist/engine/dashboard/data-loader.d.ts.map +1 -1
  114. package/dist/engine/dashboard/data-loader.js +140 -2
  115. package/dist/engine/dashboard/data-loader.js.map +1 -1
  116. package/dist/engine/dashboard/index.d.ts +2 -0
  117. package/dist/engine/dashboard/index.d.ts.map +1 -1
  118. package/dist/engine/dashboard/index.js +2 -0
  119. package/dist/engine/dashboard/index.js.map +1 -1
  120. package/dist/engine/dashboard/kanban-logic.d.ts +31 -0
  121. package/dist/engine/dashboard/kanban-logic.d.ts.map +1 -0
  122. package/dist/engine/dashboard/kanban-logic.js +122 -0
  123. package/dist/engine/dashboard/kanban-logic.js.map +1 -0
  124. package/dist/engine/dashboard/routes.d.ts +2 -0
  125. package/dist/engine/dashboard/routes.d.ts.map +1 -1
  126. package/dist/engine/dashboard/routes.js +112 -23
  127. package/dist/engine/dashboard/routes.js.map +1 -1
  128. package/dist/engine/dashboard/server.d.ts +5 -0
  129. package/dist/engine/dashboard/server.d.ts.map +1 -1
  130. package/dist/engine/dashboard/server.js +48 -0
  131. package/dist/engine/dashboard/server.js.map +1 -1
  132. package/dist/engine/dashboard/spec-updater.d.ts +8 -0
  133. package/dist/engine/dashboard/spec-updater.d.ts.map +1 -0
  134. package/dist/engine/dashboard/spec-updater.js +37 -0
  135. package/dist/engine/dashboard/spec-updater.js.map +1 -0
  136. package/dist/engine/dashboard/templates-kanban.d.ts +6 -0
  137. package/dist/engine/dashboard/templates-kanban.d.ts.map +1 -0
  138. package/dist/engine/dashboard/templates-kanban.js +100 -0
  139. package/dist/engine/dashboard/templates-kanban.js.map +1 -0
  140. package/dist/engine/dashboard/templates-layout.d.ts +3 -3
  141. package/dist/engine/dashboard/templates-layout.d.ts.map +1 -1
  142. package/dist/engine/dashboard/templates-layout.js +167 -44
  143. package/dist/engine/dashboard/templates-layout.js.map +1 -1
  144. package/dist/engine/dashboard/templates-project.d.ts +1 -1
  145. package/dist/engine/dashboard/templates-project.d.ts.map +1 -1
  146. package/dist/engine/dashboard/templates-project.js +109 -3
  147. package/dist/engine/dashboard/templates-project.js.map +1 -1
  148. package/dist/engine/dashboard/templates.d.ts +1 -0
  149. package/dist/engine/dashboard/templates.d.ts.map +1 -1
  150. package/dist/engine/dashboard/templates.js +1 -0
  151. package/dist/engine/dashboard/templates.js.map +1 -1
  152. package/dist/engine/hooks/config-loader.d.ts +36 -0
  153. package/dist/engine/hooks/config-loader.d.ts.map +1 -0
  154. package/dist/engine/hooks/config-loader.js +142 -0
  155. package/dist/engine/hooks/config-loader.js.map +1 -0
  156. package/dist/engine/hooks/debouncer.d.ts +30 -0
  157. package/dist/engine/hooks/debouncer.d.ts.map +1 -0
  158. package/dist/engine/hooks/debouncer.js +124 -0
  159. package/dist/engine/hooks/debouncer.js.map +1 -0
  160. package/dist/engine/hooks/event-bus.d.ts +40 -0
  161. package/dist/engine/hooks/event-bus.d.ts.map +1 -0
  162. package/dist/engine/hooks/event-bus.js +83 -0
  163. package/dist/engine/hooks/event-bus.js.map +1 -0
  164. package/dist/engine/hooks/file-watcher.d.ts +48 -0
  165. package/dist/engine/hooks/file-watcher.d.ts.map +1 -0
  166. package/dist/engine/hooks/file-watcher.js +193 -0
  167. package/dist/engine/hooks/file-watcher.js.map +1 -0
  168. package/dist/engine/hooks/handlers/on-commit.d.ts +26 -0
  169. package/dist/engine/hooks/handlers/on-commit.d.ts.map +1 -0
  170. package/dist/engine/hooks/handlers/on-commit.js +198 -0
  171. package/dist/engine/hooks/handlers/on-commit.js.map +1 -0
  172. package/dist/engine/hooks/handlers/on-create.d.ts +8 -0
  173. package/dist/engine/hooks/handlers/on-create.d.ts.map +1 -0
  174. package/dist/engine/hooks/handlers/on-create.js +30 -0
  175. package/dist/engine/hooks/handlers/on-create.js.map +1 -0
  176. package/dist/engine/hooks/handlers/on-delete.d.ts +9 -0
  177. package/dist/engine/hooks/handlers/on-delete.d.ts.map +1 -0
  178. package/dist/engine/hooks/handlers/on-delete.js +33 -0
  179. package/dist/engine/hooks/handlers/on-delete.js.map +1 -0
  180. package/dist/engine/hooks/handlers/on-save.d.ts +29 -0
  181. package/dist/engine/hooks/handlers/on-save.d.ts.map +1 -0
  182. package/dist/engine/hooks/handlers/on-save.js +118 -0
  183. package/dist/engine/hooks/handlers/on-save.js.map +1 -0
  184. package/dist/engine/hooks/handlers/on-test-pass.d.ts +33 -0
  185. package/dist/engine/hooks/handlers/on-test-pass.d.ts.map +1 -0
  186. package/dist/engine/hooks/handlers/on-test-pass.js +103 -0
  187. package/dist/engine/hooks/handlers/on-test-pass.js.map +1 -0
  188. package/dist/engine/hooks/hook-engine.d.ts +50 -0
  189. package/dist/engine/hooks/hook-engine.d.ts.map +1 -0
  190. package/dist/engine/hooks/hook-engine.js +159 -0
  191. package/dist/engine/hooks/hook-engine.js.map +1 -0
  192. package/dist/engine/hooks/index.d.ts +10 -0
  193. package/dist/engine/hooks/index.d.ts.map +1 -1
  194. package/dist/engine/hooks/index.js +12 -0
  195. package/dist/engine/hooks/index.js.map +1 -1
  196. package/dist/engine/living-spec/annotation-parser.d.ts +18 -0
  197. package/dist/engine/living-spec/annotation-parser.d.ts.map +1 -0
  198. package/dist/engine/living-spec/annotation-parser.js +105 -0
  199. package/dist/engine/living-spec/annotation-parser.js.map +1 -0
  200. package/dist/engine/living-spec/auto-reconciler.d.ts +28 -0
  201. package/dist/engine/living-spec/auto-reconciler.d.ts.map +1 -0
  202. package/dist/engine/living-spec/auto-reconciler.js +103 -0
  203. package/dist/engine/living-spec/auto-reconciler.js.map +1 -0
  204. package/dist/engine/living-spec/bidirectional-sync.d.ts +26 -0
  205. package/dist/engine/living-spec/bidirectional-sync.d.ts.map +1 -0
  206. package/dist/engine/living-spec/bidirectional-sync.js +160 -0
  207. package/dist/engine/living-spec/bidirectional-sync.js.map +1 -0
  208. package/dist/engine/living-spec/dashboard-collector.d.ts +22 -0
  209. package/dist/engine/living-spec/dashboard-collector.d.ts.map +1 -0
  210. package/dist/engine/living-spec/dashboard-collector.js +97 -0
  211. package/dist/engine/living-spec/dashboard-collector.js.map +1 -0
  212. package/dist/engine/living-spec/drift-watcher.d.ts +15 -0
  213. package/dist/engine/living-spec/drift-watcher.d.ts.map +1 -0
  214. package/dist/engine/living-spec/drift-watcher.js +126 -0
  215. package/dist/engine/living-spec/drift-watcher.js.map +1 -0
  216. package/dist/engine/living-spec/hash-tracker.d.ts +24 -0
  217. package/dist/engine/living-spec/hash-tracker.d.ts.map +1 -0
  218. package/dist/engine/living-spec/hash-tracker.js +123 -0
  219. package/dist/engine/living-spec/hash-tracker.js.map +1 -0
  220. package/dist/engine/living-spec/index.d.ts +9 -0
  221. package/dist/engine/living-spec/index.d.ts.map +1 -0
  222. package/dist/engine/living-spec/index.js +10 -0
  223. package/dist/engine/living-spec/index.js.map +1 -0
  224. package/dist/engine/living-spec/signature-tracker.d.ts +18 -0
  225. package/dist/engine/living-spec/signature-tracker.d.ts.map +1 -0
  226. package/dist/engine/living-spec/signature-tracker.js +136 -0
  227. package/dist/engine/living-spec/signature-tracker.js.map +1 -0
  228. package/dist/engine/living-spec/test-coverage-correlator.d.ts +22 -0
  229. package/dist/engine/living-spec/test-coverage-correlator.d.ts.map +1 -0
  230. package/dist/engine/living-spec/test-coverage-correlator.js +130 -0
  231. package/dist/engine/living-spec/test-coverage-correlator.js.map +1 -0
  232. package/dist/engine/plugins/extensions/worker-extension.d.ts.map +1 -1
  233. package/dist/engine/plugins/extensions/worker-extension.js +3 -1
  234. package/dist/engine/plugins/extensions/worker-extension.js.map +1 -1
  235. package/dist/engine/safety/file-mutex.d.ts.map +1 -1
  236. package/dist/engine/safety/file-mutex.js +3 -0
  237. package/dist/engine/safety/file-mutex.js.map +1 -1
  238. package/dist/index.js +29 -0
  239. package/dist/index.js.map +1 -1
  240. package/dist/storage/hash-snapshot-store.d.ts +18 -0
  241. package/dist/storage/hash-snapshot-store.d.ts.map +1 -0
  242. package/dist/storage/hash-snapshot-store.js +43 -0
  243. package/dist/storage/hash-snapshot-store.js.map +1 -0
  244. package/dist/storage/index.d.ts +3 -0
  245. package/dist/storage/index.d.ts.map +1 -1
  246. package/dist/storage/index.js +3 -0
  247. package/dist/storage/index.js.map +1 -1
  248. package/dist/storage/living-dashboard-store.d.ts +10 -0
  249. package/dist/storage/living-dashboard-store.d.ts.map +1 -0
  250. package/dist/storage/living-dashboard-store.js +31 -0
  251. package/dist/storage/living-dashboard-store.js.map +1 -0
  252. package/dist/storage/sync-log-store.d.ts +26 -0
  253. package/dist/storage/sync-log-store.d.ts.map +1 -0
  254. package/dist/storage/sync-log-store.js +60 -0
  255. package/dist/storage/sync-log-store.js.map +1 -0
  256. package/dist/tools/auto-reconcile.d.ts +3 -0
  257. package/dist/tools/auto-reconcile.d.ts.map +1 -0
  258. package/dist/tools/auto-reconcile.js +81 -0
  259. package/dist/tools/auto-reconcile.js.map +1 -0
  260. package/dist/tools/challenge-spec/platform-challenge-scenarios-b2.d.ts.map +1 -1
  261. package/dist/tools/challenge-spec/platform-challenge-scenarios-b2.js +6 -0
  262. package/dist/tools/challenge-spec/platform-challenge-scenarios-b2.js.map +1 -1
  263. package/dist/tools/create-spec/spec-builder.js +2 -0
  264. package/dist/tools/create-spec/spec-builder.js.map +1 -1
  265. package/dist/tools/dashboard.d.ts.map +1 -1
  266. package/dist/tools/dashboard.js +20 -13
  267. package/dist/tools/dashboard.js.map +1 -1
  268. package/dist/tools/generate-annotations.d.ts +3 -0
  269. package/dist/tools/generate-annotations.d.ts.map +1 -0
  270. package/dist/tools/generate-annotations.js +70 -0
  271. package/dist/tools/generate-annotations.js.map +1 -0
  272. package/dist/tools/generate-execution-plan.d.ts.map +1 -1
  273. package/dist/tools/generate-execution-plan.js +1 -0
  274. package/dist/tools/generate-execution-plan.js.map +1 -1
  275. package/dist/tools/github-pr-handler.d.ts.map +1 -1
  276. package/dist/tools/github-pr-handler.js +1 -0
  277. package/dist/tools/github-pr-handler.js.map +1 -1
  278. package/dist/tools/github-review-handler.d.ts.map +1 -1
  279. package/dist/tools/github-review-handler.js +1 -0
  280. package/dist/tools/github-review-handler.js.map +1 -1
  281. package/dist/tools/ide-config-handler.d.ts.map +1 -1
  282. package/dist/tools/ide-config-handler.js +3 -0
  283. package/dist/tools/ide-config-handler.js.map +1 -1
  284. package/dist/tools/init-project/handler.d.ts.map +1 -1
  285. package/dist/tools/init-project/handler.js +0 -3
  286. package/dist/tools/init-project/handler.js.map +1 -1
  287. package/dist/tools/living-spec-coverage.d.ts +3 -0
  288. package/dist/tools/living-spec-coverage.d.ts.map +1 -0
  289. package/dist/tools/living-spec-coverage.js +100 -0
  290. package/dist/tools/living-spec-coverage.js.map +1 -0
  291. package/dist/tools/living-spec-watch.d.ts +4 -0
  292. package/dist/tools/living-spec-watch.d.ts.map +1 -0
  293. package/dist/tools/living-spec-watch.js +94 -0
  294. package/dist/tools/living-spec-watch.js.map +1 -0
  295. package/dist/tools/manage-plugins-handler.d.ts.map +1 -1
  296. package/dist/tools/manage-plugins-handler.js +2 -1
  297. package/dist/tools/manage-plugins-handler.js.map +1 -1
  298. package/dist/tools/orchestrate-distribution.d.ts.map +1 -1
  299. package/dist/tools/orchestrate-distribution.js +1 -0
  300. package/dist/tools/orchestrate-distribution.js.map +1 -1
  301. package/dist/tools/orchestrate-runtime.js +2 -0
  302. package/dist/tools/orchestrate-runtime.js.map +1 -1
  303. package/dist/tools/plan-team-distribution.d.ts.map +1 -1
  304. package/dist/tools/plan-team-distribution.js +2 -0
  305. package/dist/tools/plan-team-distribution.js.map +1 -1
  306. package/dist/tools/register-dashboard-tools.d.ts.map +1 -1
  307. package/dist/tools/register-dashboard-tools.js +5 -1
  308. package/dist/tools/register-dashboard-tools.js.map +1 -1
  309. package/dist/tools/register-hooks-tools.d.ts.map +1 -1
  310. package/dist/tools/register-hooks-tools.js +82 -1
  311. package/dist/tools/register-hooks-tools.js.map +1 -1
  312. package/dist/tools/register-living-spec-advanced-tools.d.ts +6 -0
  313. package/dist/tools/register-living-spec-advanced-tools.d.ts.map +1 -0
  314. package/dist/tools/register-living-spec-advanced-tools.js +113 -0
  315. package/dist/tools/register-living-spec-advanced-tools.js.map +1 -0
  316. package/dist/tools/register-living-spec-tools.d.ts +6 -0
  317. package/dist/tools/register-living-spec-tools.d.ts.map +1 -0
  318. package/dist/tools/register-living-spec-tools.js +67 -0
  319. package/dist/tools/register-living-spec-tools.js.map +1 -0
  320. package/dist/tools/resolve-sync-conflict.d.ts +3 -0
  321. package/dist/tools/resolve-sync-conflict.d.ts.map +1 -0
  322. package/dist/tools/resolve-sync-conflict.js +38 -0
  323. package/dist/tools/resolve-sync-conflict.js.map +1 -0
  324. package/dist/tools/snapshot-spec-hashes.d.ts +3 -0
  325. package/dist/tools/snapshot-spec-hashes.d.ts.map +1 -0
  326. package/dist/tools/snapshot-spec-hashes.js +100 -0
  327. package/dist/tools/snapshot-spec-hashes.js.map +1 -0
  328. package/dist/tools/spec-diff.d.ts +3 -0
  329. package/dist/tools/spec-diff.d.ts.map +1 -0
  330. package/dist/tools/spec-diff.js +58 -0
  331. package/dist/tools/spec-diff.js.map +1 -0
  332. package/dist/tools/start-hooks.d.ts +17 -0
  333. package/dist/tools/start-hooks.d.ts.map +1 -0
  334. package/dist/tools/start-hooks.js +209 -0
  335. package/dist/tools/start-hooks.js.map +1 -0
  336. package/dist/tools/sync-code-to-spec.d.ts +3 -0
  337. package/dist/tools/sync-code-to-spec.d.ts.map +1 -0
  338. package/dist/tools/sync-code-to-spec.js +51 -0
  339. package/dist/tools/sync-code-to-spec.js.map +1 -0
  340. package/dist/tools/sync-spec-to-code.d.ts +3 -0
  341. package/dist/tools/sync-spec-to-code.d.ts.map +1 -0
  342. package/dist/tools/sync-spec-to-code.js +58 -0
  343. package/dist/tools/sync-spec-to-code.js.map +1 -0
  344. package/dist/tools/validate-annotations.d.ts +3 -0
  345. package/dist/tools/validate-annotations.d.ts.map +1 -0
  346. package/dist/tools/validate-annotations.js +90 -0
  347. package/dist/tools/validate-annotations.js.map +1 -0
  348. package/dist/types/cli.d.ts +14 -0
  349. package/dist/types/cli.d.ts.map +1 -0
  350. package/dist/types/cli.js +3 -0
  351. package/dist/types/cli.js.map +1 -0
  352. package/dist/types/dashboard.d.ts +86 -1
  353. package/dist/types/dashboard.d.ts.map +1 -1
  354. package/dist/types/file-hooks.d.ts +230 -0
  355. package/dist/types/file-hooks.d.ts.map +1 -0
  356. package/dist/types/file-hooks.js +3 -0
  357. package/dist/types/file-hooks.js.map +1 -0
  358. package/dist/types/index.d.ts +3 -0
  359. package/dist/types/index.d.ts.map +1 -1
  360. package/dist/types/index.js +3 -0
  361. package/dist/types/index.js.map +1 -1
  362. package/dist/types/living-spec.d.ts +382 -0
  363. package/dist/types/living-spec.d.ts.map +1 -0
  364. package/dist/types/living-spec.js +3 -0
  365. package/dist/types/living-spec.js.map +1 -0
  366. package/package.json +1 -1
  367. package/src/config/hook-defaults.json +19 -0
  368. package/src/config/license-plans.json +16 -1
  369. package/src/config/tool-groups.json +12 -1
@@ -0,0 +1,67 @@
1
+ import { z } from 'zod';
2
+ import { safeLicensed } from './safe-handler.js';
3
+ import { handleValidateAnnotations } from './validate-annotations.js';
4
+ import { handleGenerateAnnotations } from './generate-annotations.js';
5
+ import { handleSnapshotSpecHashes } from './snapshot-spec-hashes.js';
6
+ import { handleAutoReconcile } from './auto-reconcile.js';
7
+ /**
8
+ * Registers living spec tools on the MCP server.
9
+ */
10
+ export function registerLivingSpecTools(server) {
11
+ // validate_annotations
12
+ server.registerTool('validate_annotations', {
13
+ description: 'Validate @spec annotations in source code. Checks that all annotated spec IDs exist and criteria numbers are valid. Use after adding annotations to verify correctness.',
14
+ annotations: { readOnlyHint: true },
15
+ inputSchema: {
16
+ projectId: z.string().max(500).describe('Project ID'),
17
+ projectPath: z
18
+ .string()
19
+ .max(4096)
20
+ .describe('Path to the project root directory'),
21
+ specId: z
22
+ .string()
23
+ .max(500)
24
+ .optional()
25
+ .describe('Optional spec ID to filter annotations for a specific spec'),
26
+ },
27
+ }, safeLicensed('validate_annotations', async (args) => handleValidateAnnotations(args)));
28
+ // generate_annotations
29
+ server.registerTool('generate_annotations', {
30
+ description: 'Suggest @spec annotations for unannotated source files. Uses living-spec-analyzer heuristics to match files to spec criteria and generates annotation comments to add.',
31
+ annotations: { readOnlyHint: true },
32
+ inputSchema: {
33
+ projectId: z.string().max(500).describe('Project ID'),
34
+ projectPath: z
35
+ .string()
36
+ .max(4096)
37
+ .describe('Path to the project root directory'),
38
+ specId: z.string().max(500).describe('Spec ID to generate annotations for'),
39
+ },
40
+ }, safeLicensed('generate_annotations', async (args) => handleGenerateAnnotations(args)));
41
+ // snapshot_spec_hashes
42
+ server.registerTool('snapshot_spec_hashes', {
43
+ description: 'Create or update a SHA-256 hash snapshot for a spec. Tracks file hashes and exported function signatures of all files referenced in the spec technical.md File Plan section. Used for drift detection.',
44
+ inputSchema: {
45
+ projectId: z.string().max(500).describe('Project ID'),
46
+ specId: z.string().max(500).describe('Spec ID to snapshot'),
47
+ },
48
+ }, safeLicensed('snapshot_spec_hashes', async (args) => handleSnapshotSpecHashes(args)));
49
+ // auto_reconcile
50
+ server.registerTool('auto_reconcile', {
51
+ description: 'Auto-reconcile specs after code changes. Applies safe changes automatically (completion %, status flip, hash update, timestamp). Unsafe changes (status downgrade, criterion removal) are skipped and require manual approval. Rate-limited: max 1 per spec per 5 minutes.',
52
+ inputSchema: {
53
+ projectId: z.string().max(500).describe('Project ID'),
54
+ specId: z
55
+ .string()
56
+ .max(500)
57
+ .optional()
58
+ .describe('Specific spec ID to reconcile (if omitted, finds affected specs from changedFiles)'),
59
+ changedFiles: z
60
+ .array(z.string().max(4096))
61
+ .max(1000)
62
+ .optional()
63
+ .describe('List of changed file paths to find affected specs'),
64
+ },
65
+ }, safeLicensed('auto_reconcile', async (args) => handleAutoReconcile(args)));
66
+ }
67
+ //# sourceMappingURL=register-living-spec-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register-living-spec-tools.js","sourceRoot":"","sources":["../../src/tools/register-living-spec-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { ResolveSyncConflictInput, ToolResult } from '../types/index.js';
2
+ export declare function handleResolveSyncConflict(args: ResolveSyncConflictInput): Promise<ToolResult>;
3
+ //# sourceMappingURL=resolve-sync-conflict.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-sync-conflict.d.ts","sourceRoot":"","sources":["../../src/tools/resolve-sync-conflict.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,wBAAwB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE9E,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,UAAU,CAAC,CAoDrB"}
@@ -0,0 +1,38 @@
1
+ // tools/resolve-sync-conflict.ts — resolve_sync_conflict handler
2
+ import { syncLogStore } from '../storage/index.js';
3
+ import { createSyncLogEntry } from '../engine/living-spec/index.js';
4
+ export async function handleResolveSyncConflict(args) {
5
+ const { projectId, conflictId, resolution, manualResolution } = args;
6
+ const resolutionText = resolution === 'manual'
7
+ ? (manualResolution ?? 'Manual resolution (no details provided)')
8
+ : `Auto-resolved: ${resolution}`;
9
+ const conflict = await syncLogStore.resolveConflict(projectId, conflictId, resolutionText);
10
+ if (!conflict) {
11
+ return {
12
+ content: [
13
+ {
14
+ type: 'text',
15
+ text: JSON.stringify({
16
+ message: `Conflict ${conflictId} not found. Use sync_spec_to_code or sync_code_to_spec to detect conflicts first.`,
17
+ }, null, 2),
18
+ },
19
+ ],
20
+ isError: true,
21
+ };
22
+ }
23
+ // Log the resolution
24
+ const logEntry = createSyncLogEntry(conflict.direction, conflict.specId, 'resolve-conflict', `Resolved conflict ${conflictId}: ${resolutionText}`);
25
+ await syncLogStore.appendSyncLog(projectId, [logEntry]);
26
+ return {
27
+ content: [
28
+ {
29
+ type: 'text',
30
+ text: JSON.stringify({
31
+ conflict,
32
+ message: `Conflict ${conflictId} resolved: ${resolutionText}`,
33
+ }, null, 2),
34
+ },
35
+ ],
36
+ };
37
+ }
38
+ //# sourceMappingURL=resolve-sync-conflict.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-sync-conflict.js","sourceRoot":"","sources":["../../src/tools/resolve-sync-conflict.ts"],"names":[],"mappings":"AAAA,iEAAiE;AAEjE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,IAA8B;IAE9B,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC;IAErE,MAAM,cAAc,GAClB,UAAU,KAAK,QAAQ;QACrB,CAAC,CAAC,CAAC,gBAAgB,IAAI,yCAAyC,CAAC;QACjE,CAAC,CAAC,kBAAkB,UAAU,EAAE,CAAC;IAErC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,eAAe,CAAC,SAAS,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC;IAE3F,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;wBACE,OAAO,EAAE,YAAY,UAAU,mFAAmF;qBACnH,EACD,IAAI,EACJ,CAAC,CACF;iBACF;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,qBAAqB;IACrB,MAAM,QAAQ,GAAG,kBAAkB,CACjC,QAAQ,CAAC,SAAS,EAClB,QAAQ,CAAC,MAAM,EACf,kBAAkB,EAClB,qBAAqB,UAAU,KAAK,cAAc,EAAE,CACrD,CAAC;IACF,MAAM,YAAY,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAExD,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,QAAQ;oBACR,OAAO,EAAE,YAAY,UAAU,cAAc,cAAc,EAAE;iBAC9D,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { SnapshotSpecHashesInput, ToolResult } from '../types/index.js';
2
+ export declare function handleSnapshotSpecHashes(args: SnapshotSpecHashesInput): Promise<ToolResult>;
3
+ //# sourceMappingURL=snapshot-spec-hashes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-spec-hashes.d.ts","sourceRoot":"","sources":["../../src/tools/snapshot-spec-hashes.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,uBAAuB,EAAoB,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG/F,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,UAAU,CAAC,CA6GrB"}
@@ -0,0 +1,100 @@
1
+ // tools/snapshot-spec-hashes.ts — Create/update hash snapshots for a spec
2
+ // Tracks file hashes and function signatures of files referenced in technical.md
3
+ import { readFile } from 'node:fs/promises';
4
+ import { specStore, knowledgeStore, hashSnapshotStore } from '../storage/index.js';
5
+ import { createFileHashEntries, extractFilePlanPaths, extractSignaturesFromFiles, diffFileHashes, diffSignatures, } from '../engine/living-spec/index.js';
6
+ import { stripFrontmatter } from '../engine/frontmatter-parser.js';
7
+ export async function handleSnapshotSpecHashes(args) {
8
+ const { projectId, specId } = args;
9
+ // 1. Load spec
10
+ const spec = await specStore.getSpec(projectId, specId);
11
+ if (!spec) {
12
+ return {
13
+ content: [{ type: 'text', text: `Spec ${specId} not found` }],
14
+ isError: true,
15
+ };
16
+ }
17
+ // 2. Load project path
18
+ const knowledge = await knowledgeStore.getKnowledge(projectId);
19
+ if (!knowledge?.projectPath) {
20
+ return {
21
+ content: [{ type: 'text', text: 'Project not found. Run init_project first.' }],
22
+ isError: true,
23
+ };
24
+ }
25
+ const projectPath = knowledge.projectPath;
26
+ // 3. Extract file paths from technical.md File Plan section
27
+ let filePaths;
28
+ try {
29
+ const rawContent = await readFile(spec.technicalPath, 'utf-8');
30
+ const content = stripFrontmatter(rawContent);
31
+ filePaths = extractFilePlanPaths(content);
32
+ }
33
+ catch {
34
+ return {
35
+ content: [
36
+ {
37
+ type: 'text',
38
+ text: `Could not read technical.md for ${specId}. Ensure it exists at ${spec.technicalPath}`,
39
+ },
40
+ ],
41
+ isError: true,
42
+ };
43
+ }
44
+ if (filePaths.length === 0) {
45
+ return {
46
+ content: [
47
+ {
48
+ type: 'text',
49
+ text: `No file paths found in technical.md File Plan section for ${specId}. Add files in a markdown table or list.`,
50
+ },
51
+ ],
52
+ };
53
+ }
54
+ // 4. Create hash entries and extract signatures
55
+ const files = await createFileHashEntries(projectPath, filePaths);
56
+ const signatures = await extractSignaturesFromFiles(projectPath, filePaths);
57
+ // 5. Load previous snapshot for comparison
58
+ const previousSnapshot = await hashSnapshotStore.getSnapshot(projectId, specId);
59
+ // 6. Save new snapshot
60
+ const newSnapshot = {
61
+ specId,
62
+ createdAt: new Date().toISOString(),
63
+ files,
64
+ signatures,
65
+ };
66
+ await hashSnapshotStore.saveSnapshot(projectId, specId, newSnapshot);
67
+ // 7. Generate diff report if previous snapshot exists
68
+ let diffReport = null;
69
+ if (previousSnapshot) {
70
+ const fileDiffs = await diffFileHashes(projectPath, previousSnapshot, filePaths);
71
+ const sigChanges = diffSignatures(previousSnapshot.signatures, signatures);
72
+ diffReport = {
73
+ changedFiles: fileDiffs.length,
74
+ signatureChanges: sigChanges.length,
75
+ details: {
76
+ files: fileDiffs,
77
+ signatures: sigChanges,
78
+ },
79
+ };
80
+ }
81
+ return {
82
+ content: [
83
+ {
84
+ type: 'text',
85
+ text: JSON.stringify({
86
+ specId,
87
+ filesTracked: files.length,
88
+ signaturesTracked: signatures.length,
89
+ totalPathsInPlan: filePaths.length,
90
+ missingFiles: filePaths.length - files.length,
91
+ ...(diffReport ? { diff: diffReport } : {}),
92
+ message: previousSnapshot
93
+ ? `Hash snapshot updated for ${specId}. ${String(diffReport?.changedFiles ?? 0)} file(s) changed.`
94
+ : `Initial hash snapshot created for ${specId}.`,
95
+ }, null, 2),
96
+ },
97
+ ],
98
+ };
99
+ }
100
+ //# sourceMappingURL=snapshot-spec-hashes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-spec-hashes.js","sourceRoot":"","sources":["../../src/tools/snapshot-spec-hashes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { SpecDiffInput, ToolResult } from '../types/index.js';
2
+ export declare function handleSpecDiff(args: SpecDiffInput): Promise<ToolResult>;
3
+ //# sourceMappingURL=spec-diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-diff.d.ts","sourceRoot":"","sources":["../../src/tools/spec-diff.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEnE,wBAAsB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CAiE7E"}
@@ -0,0 +1,58 @@
1
+ // tools/spec-diff.ts — spec_diff handler
2
+ import { hashSnapshotStore, specStore } from '../storage/index.js';
3
+ import { buildSpecDiffRows, formatMarkdownDiff } from '../engine/living-spec/index.js';
4
+ export async function handleSpecDiff(args) {
5
+ const { projectId, specId } = args;
6
+ // If specId provided, diff that spec; otherwise diff all specs
7
+ const specIds = [];
8
+ if (specId) {
9
+ specIds.push(specId);
10
+ }
11
+ else {
12
+ const allSpecs = await specStore.listSpecs(projectId);
13
+ specIds.push(...allSpecs.map((s) => s.id));
14
+ }
15
+ if (specIds.length === 0) {
16
+ return {
17
+ content: [
18
+ {
19
+ type: 'text',
20
+ text: JSON.stringify({ message: 'No specs found for this project' }, null, 2),
21
+ },
22
+ ],
23
+ };
24
+ }
25
+ const allRows = [];
26
+ for (const sid of specIds) {
27
+ const snapshot = await hashSnapshotStore.getSnapshot(projectId, sid);
28
+ if (!snapshot) {
29
+ continue;
30
+ }
31
+ // Build hash maps from snapshot
32
+ const oldHashes = new Map();
33
+ for (const f of snapshot.files) {
34
+ oldHashes.set(f.file, f.hash);
35
+ }
36
+ // For diff, we compare stored snapshot with current (re-use stored as "old")
37
+ const newHashes = new Map(oldHashes);
38
+ const rows = buildSpecDiffRows(oldHashes, newHashes, sid);
39
+ allRows.push(...rows);
40
+ }
41
+ const markdown = formatMarkdownDiff(allRows);
42
+ return {
43
+ content: [
44
+ {
45
+ type: 'text',
46
+ text: JSON.stringify({
47
+ specCount: specIds.length,
48
+ diffRows: allRows.length,
49
+ markdown,
50
+ message: allRows.length > 0
51
+ ? `Found ${allRows.length} change(s) across ${specIds.length} spec(s)`
52
+ : `No changes detected across ${specIds.length} spec(s)`,
53
+ }, null, 2),
54
+ },
55
+ ],
56
+ };
57
+ }
58
+ //# sourceMappingURL=spec-diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec-diff.js","sourceRoot":"","sources":["../../src/tools/spec-diff.ts"],"names":[],"mappings":"AAAA,yCAAyC;AAEzC,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGvF,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAmB;IACtD,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAEnC,+DAA+D;IAC/D,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;SAAM,CAAC;QACN,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,iCAAiC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;iBAC9E;aACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC;IACnB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QACrE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,SAAS;QACX,CAAC;QAED,gCAAgC;QAChC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC5C,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YAC/B,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC;QAED,6EAA6E;QAC7E,MAAM,SAAS,GAAG,IAAI,GAAG,CAAiB,SAAS,CAAC,CAAC;QACrD,MAAM,IAAI,GAAG,iBAAiB,CAAC,SAAS,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IACxB,CAAC;IAED,MAAM,QAAQ,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAE7C,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,SAAS,EAAE,OAAO,CAAC,MAAM;oBACzB,QAAQ,EAAE,OAAO,CAAC,MAAM;oBACxB,QAAQ;oBACR,OAAO,EACL,OAAO,CAAC,MAAM,GAAG,CAAC;wBAChB,CAAC,CAAC,SAAS,OAAO,CAAC,MAAM,qBAAqB,OAAO,CAAC,MAAM,UAAU;wBACtE,CAAC,CAAC,8BAA8B,OAAO,CAAC,MAAM,UAAU;iBAC7D,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { ToolResult } from '../types/index.js';
2
+ import type { StartHooksInput, StopHooksInput, ConfigureHooksInput } from '../types/file-hooks.js';
3
+ import { HookEngine } from '../engine/hooks/hook-engine.js';
4
+ import { FileWatcher } from '../engine/hooks/file-watcher.js';
5
+ /**
6
+ * Get the current engine instance (for testing/internal use).
7
+ */
8
+ export declare function getEngineInstance(): HookEngine | null;
9
+ /**
10
+ * Get the current watcher instance (for testing/internal use).
11
+ */
12
+ export declare function getWatcherInstance(): FileWatcher | null;
13
+ export declare function handleStartHooks(args: StartHooksInput): Promise<ToolResult>;
14
+ export declare function handleStopHooks(_args: StopHooksInput): Promise<ToolResult>;
15
+ export declare function handleHookStatus(): Promise<ToolResult>;
16
+ export declare function handleConfigureHooks(args: ConfigureHooksInput): Promise<ToolResult>;
17
+ //# sourceMappingURL=start-hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start-hooks.d.ts","sourceRoot":"","sources":["../../src/tools/start-hooks.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAGV,eAAe,EACf,cAAc,EACd,mBAAmB,EACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAa9D;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,UAAU,GAAG,IAAI,CAErD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,WAAW,GAAG,IAAI,CAEvD;AAMD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CA0FjF;AAuBD,wBAAsB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAuBhF;AAMD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,UAAU,CAAC,CAqC5D;AAMD,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CA0CzF"}
@@ -0,0 +1,209 @@
1
+ // tools/start-hooks.ts — Start file watcher + hook engine (SPEC-130)
2
+ import { HookEngine } from '../engine/hooks/hook-engine.js';
3
+ import { EventBus } from '../engine/hooks/event-bus.js';
4
+ import { FileWatcher } from '../engine/hooks/file-watcher.js';
5
+ import { ConfigLoader } from '../engine/hooks/config-loader.js';
6
+ import { Debouncer } from '../engine/hooks/debouncer.js';
7
+ // ---------------------------------------------------------------------------
8
+ // Singleton state
9
+ // ---------------------------------------------------------------------------
10
+ let engineInstance = null;
11
+ let watcherInstance = null;
12
+ let debouncerInstance = null;
13
+ let configLoaderInstance = null;
14
+ /**
15
+ * Get the current engine instance (for testing/internal use).
16
+ */
17
+ export function getEngineInstance() {
18
+ return engineInstance;
19
+ }
20
+ /**
21
+ * Get the current watcher instance (for testing/internal use).
22
+ */
23
+ export function getWatcherInstance() {
24
+ return watcherInstance;
25
+ }
26
+ // ---------------------------------------------------------------------------
27
+ // Start hooks
28
+ // ---------------------------------------------------------------------------
29
+ export async function handleStartHooks(args) {
30
+ // Idempotent — if already running, return status
31
+ if (engineInstance?.status().running) {
32
+ const status = engineInstance.status();
33
+ return {
34
+ content: [
35
+ {
36
+ type: 'text',
37
+ text: JSON.stringify({
38
+ message: 'Hook engine already running',
39
+ ...status,
40
+ }, null, 2),
41
+ },
42
+ ],
43
+ };
44
+ }
45
+ const projectPath = args.projectPath;
46
+ const enabledHooks = args.hooks ?? ['on-save', 'on-create', 'on-delete'];
47
+ // Load config
48
+ configLoaderInstance = new ConfigLoader(projectPath);
49
+ const config = await configLoaderInstance.load();
50
+ // Create event bus and engine
51
+ const eventBus = new EventBus();
52
+ engineInstance = new HookEngine(eventBus);
53
+ // Create file watcher
54
+ watcherInstance = new FileWatcher({
55
+ rootDir: projectPath,
56
+ include: config.hooks['on-save']?.include,
57
+ exclude: config.hooks['on-save']?.exclude,
58
+ });
59
+ // Create debouncer
60
+ debouncerInstance = new Debouncer((event) => {
61
+ const hookType = mapEventToHookType(event);
62
+ if (hookType && enabledHooks.includes(hookType)) {
63
+ void engineInstance?.dispatch(event, hookType);
64
+ }
65
+ }, {
66
+ debounceMs: config.debounceMs,
67
+ rateLimitPerFileMs: config.rateLimitPerFileMs,
68
+ });
69
+ // Wire watcher -> debouncer
70
+ watcherInstance.on('change', (event) => {
71
+ eventBus.emitEvent('file:change', {
72
+ path: event.path,
73
+ type: event.type,
74
+ timestamp: event.timestamp,
75
+ });
76
+ debouncerInstance?.push(event);
77
+ });
78
+ // Start watching config for live reload
79
+ configLoaderInstance.startWatching();
80
+ // Start engine and watcher
81
+ engineInstance.start();
82
+ watcherInstance.start();
83
+ return {
84
+ content: [
85
+ {
86
+ type: 'text',
87
+ text: JSON.stringify({
88
+ message: 'Hook engine started',
89
+ projectPath,
90
+ enabledHooks,
91
+ config: {
92
+ debounceMs: config.debounceMs,
93
+ rateLimitPerFileMs: config.rateLimitPerFileMs,
94
+ },
95
+ }, null, 2),
96
+ },
97
+ ],
98
+ };
99
+ }
100
+ // ---------------------------------------------------------------------------
101
+ // Helpers
102
+ // ---------------------------------------------------------------------------
103
+ function mapEventToHookType(event) {
104
+ switch (event.type) {
105
+ case 'modify':
106
+ return 'on-save';
107
+ case 'create':
108
+ return 'on-create';
109
+ case 'delete':
110
+ return 'on-delete';
111
+ default:
112
+ return null;
113
+ }
114
+ }
115
+ // ---------------------------------------------------------------------------
116
+ // Stop hooks
117
+ // ---------------------------------------------------------------------------
118
+ export async function handleStopHooks(_args) {
119
+ await Promise.resolve(); // Ensure async for safeLicensed wrapper
120
+ if (!engineInstance) {
121
+ return {
122
+ content: [{ type: 'text', text: JSON.stringify({ message: 'Hook engine not running' }) }],
123
+ };
124
+ }
125
+ engineInstance.stop();
126
+ watcherInstance?.close();
127
+ debouncerInstance?.dispose();
128
+ configLoaderInstance?.close();
129
+ const message = 'Hook engine stopped and resources cleaned up';
130
+ engineInstance = null;
131
+ watcherInstance = null;
132
+ debouncerInstance = null;
133
+ configLoaderInstance = null;
134
+ return {
135
+ content: [{ type: 'text', text: JSON.stringify({ message }) }],
136
+ };
137
+ }
138
+ // ---------------------------------------------------------------------------
139
+ // Hook status
140
+ // ---------------------------------------------------------------------------
141
+ export async function handleHookStatus() {
142
+ await Promise.resolve(); // Ensure async for safeLicensed wrapper
143
+ if (!engineInstance) {
144
+ return {
145
+ content: [
146
+ {
147
+ type: 'text',
148
+ text: JSON.stringify({
149
+ running: false,
150
+ activeHooks: [],
151
+ pendingEvents: 0,
152
+ telemetry: {},
153
+ eventHistory: 0,
154
+ }),
155
+ },
156
+ ],
157
+ };
158
+ }
159
+ const status = engineInstance.status();
160
+ const eventBus = engineInstance.getEventBus();
161
+ return {
162
+ content: [
163
+ {
164
+ type: 'text',
165
+ text: JSON.stringify({
166
+ ...status,
167
+ eventHistory: eventBus.getFullHistory().length,
168
+ }, null, 2),
169
+ },
170
+ ],
171
+ };
172
+ }
173
+ // ---------------------------------------------------------------------------
174
+ // Configure hooks
175
+ // ---------------------------------------------------------------------------
176
+ export async function handleConfigureHooks(args) {
177
+ if (!configLoaderInstance) {
178
+ // Not running — just load and report current config
179
+ const loader = new ConfigLoader(args.projectPath);
180
+ const config = await loader.load();
181
+ loader.close();
182
+ return {
183
+ content: [
184
+ {
185
+ type: 'text',
186
+ text: JSON.stringify({
187
+ message: 'Hook engine not running. Current config:',
188
+ config,
189
+ }, null, 2),
190
+ },
191
+ ],
192
+ };
193
+ }
194
+ // Reload config
195
+ const config = await configLoaderInstance.load();
196
+ return {
197
+ content: [
198
+ {
199
+ type: 'text',
200
+ text: JSON.stringify({
201
+ message: 'Configuration reloaded',
202
+ config,
203
+ engineRunning: engineInstance?.status().running ?? false,
204
+ }, null, 2),
205
+ },
206
+ ],
207
+ };
208
+ }
209
+ //# sourceMappingURL=start-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start-hooks.js","sourceRoot":"","sources":["../../src/tools/start-hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { SyncCodeToSpecInput, ToolResult } from '../types/index.js';
2
+ export declare function handleSyncCodeToSpec(args: SyncCodeToSpecInput): Promise<ToolResult>;
3
+ //# sourceMappingURL=sync-code-to-spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-code-to-spec.d.ts","sourceRoot":"","sources":["../../src/tools/sync-code-to-spec.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEzE,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAyDzF"}
@@ -0,0 +1,51 @@
1
+ // tools/sync-code-to-spec.ts — sync_code_to_spec handler
2
+ import { specStore, syncLogStore } from '../storage/index.js';
3
+ import { generateProgressUpdates, detectConflicts, buildCodeToSpecResult, parseAnnotationsFromProject, } from '../engine/living-spec/index.js';
4
+ import { extractCriteria } from '../engine/validator/extractors.js';
5
+ export async function handleSyncCodeToSpec(args) {
6
+ const { projectId, specId, projectPath } = args;
7
+ // 1. Load spec
8
+ const spec = await specStore.getSpec(projectId, specId);
9
+ if (!spec) {
10
+ return {
11
+ content: [
12
+ {
13
+ type: 'text',
14
+ text: JSON.stringify({ message: `Spec ${specId} not found` }, null, 2),
15
+ },
16
+ ],
17
+ isError: true,
18
+ };
19
+ }
20
+ // 2. Parse annotations from code
21
+ const parseResult = await parseAnnotationsFromProject(projectPath, specId);
22
+ // 3. Build criteria status map (default: pending)
23
+ const criteriaList = await extractCriteria(spec);
24
+ const statusMap = new Map();
25
+ for (let i = 0; i < criteriaList.length; i++) {
26
+ statusMap.set(`${specId}:AC-${i + 1}`, 'pending');
27
+ }
28
+ // 4. Generate progress updates
29
+ const updates = generateProgressUpdates(parseResult.annotations, statusMap);
30
+ // 5. Detect conflicts
31
+ const conflicts = detectConflicts(parseResult.annotations, statusMap, 'code-to-spec');
32
+ // 6. Build result
33
+ const result = buildCodeToSpecResult(specId, updates, conflicts);
34
+ // 7. Persist
35
+ await syncLogStore.appendSyncLog(projectId, result.logEntries);
36
+ if (conflicts.length > 0) {
37
+ await syncLogStore.addConflicts(projectId, conflicts);
38
+ }
39
+ return {
40
+ content: [
41
+ {
42
+ type: 'text',
43
+ text: JSON.stringify({
44
+ ...result,
45
+ message: `Code-to-spec sync: ${updates.length} progress update(s), ${conflicts.length} conflict(s)`,
46
+ }, null, 2),
47
+ },
48
+ ],
49
+ };
50
+ }
51
+ //# sourceMappingURL=sync-code-to-spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-code-to-spec.js","sourceRoot":"","sources":["../../src/tools/sync-code-to-spec.ts"],"names":[],"mappings":"AAAA,yDAAyD;AAEzD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EACL,uBAAuB,EACvB,eAAe,EACf,qBAAqB,EACrB,2BAA2B,GAC5B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAGpE,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAyB;IAClE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IAEhD,eAAe;IACf,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACxD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,QAAQ,MAAM,YAAY,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;iBACvE;aACF;YACD,OAAO,EAAE,IAAI;SACd,CAAC;IACJ,CAAC;IAED,iCAAiC;IACjC,MAAM,WAAW,GAAG,MAAM,2BAA2B,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAE3E,kDAAkD;IAClD,MAAM,YAAY,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,SAAS,CAAC,GAAG,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IACpD,CAAC;IAED,+BAA+B;IAC/B,MAAM,OAAO,GAAG,uBAAuB,CAAC,WAAW,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAE5E,sBAAsB;IACtB,MAAM,SAAS,GAAG,eAAe,CAAC,WAAW,CAAC,WAAW,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;IAEtF,kBAAkB;IAClB,MAAM,MAAM,GAAG,qBAAqB,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAEjE,aAAa;IACb,MAAM,YAAY,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAC/D,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,YAAY,CAAC,YAAY,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACxD,CAAC;IAED,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;oBACE,GAAG,MAAM;oBACT,OAAO,EAAE,sBAAsB,OAAO,CAAC,MAAM,wBAAwB,SAAS,CAAC,MAAM,cAAc;iBACpG,EACD,IAAI,EACJ,CAAC,CACF;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { SyncSpecToCodeInput, ToolResult } from '../types/index.js';
2
+ export declare function handleSyncSpecToCode(args: SyncSpecToCodeInput): Promise<ToolResult>;
3
+ //# sourceMappingURL=sync-spec-to-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-spec-to-code.d.ts","sourceRoot":"","sources":["../../src/tools/sync-spec-to-code.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAiB,MAAM,mBAAmB,CAAC;AAExF,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAgEzF"}