@planu/cli 0.43.1 → 0.45.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 (433) 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 +23 -2
  71. package/dist/config/registry-categories.json +20 -0
  72. package/dist/config/registry-stacks.json +16 -0
  73. package/dist/config/tool-groups.json +12 -1
  74. package/dist/engine/analyzer/analyze-project.d.ts +15 -0
  75. package/dist/engine/analyzer/analyze-project.d.ts.map +1 -0
  76. package/dist/engine/analyzer/analyze-project.js +101 -0
  77. package/dist/engine/analyzer/analyze-project.js.map +1 -0
  78. package/dist/engine/analyzer/completeness-checker.d.ts +6 -0
  79. package/dist/engine/analyzer/completeness-checker.d.ts.map +1 -0
  80. package/dist/engine/analyzer/completeness-checker.js +79 -0
  81. package/dist/engine/analyzer/completeness-checker.js.map +1 -0
  82. package/dist/engine/analyzer/db-engine.d.ts +9 -0
  83. package/dist/engine/analyzer/db-engine.d.ts.map +1 -0
  84. package/dist/engine/analyzer/db-engine.js +137 -0
  85. package/dist/engine/analyzer/db-engine.js.map +1 -0
  86. package/dist/engine/analyzer/detectors.d.ts +7 -0
  87. package/dist/engine/analyzer/detectors.d.ts.map +1 -0
  88. package/dist/engine/analyzer/detectors.js +234 -0
  89. package/dist/engine/analyzer/detectors.js.map +1 -0
  90. package/dist/engine/analyzer/env-setup.d.ts +6 -0
  91. package/dist/engine/analyzer/env-setup.d.ts.map +1 -0
  92. package/dist/engine/analyzer/env-setup.js +174 -0
  93. package/dist/engine/analyzer/env-setup.js.map +1 -0
  94. package/dist/engine/analyzer/index.d.ts +6 -0
  95. package/dist/engine/analyzer/index.d.ts.map +1 -0
  96. package/dist/engine/analyzer/index.js +8 -0
  97. package/dist/engine/analyzer/index.js.map +1 -0
  98. package/dist/engine/analyzer-db.d.ts +1 -8
  99. package/dist/engine/analyzer-db.d.ts.map +1 -1
  100. package/dist/engine/analyzer-db.js +3 -136
  101. package/dist/engine/analyzer-db.js.map +1 -1
  102. package/dist/engine/analyzer-detectors.d.ts +1 -6
  103. package/dist/engine/analyzer-detectors.d.ts.map +1 -1
  104. package/dist/engine/analyzer-detectors.js +3 -231
  105. package/dist/engine/analyzer-detectors.js.map +1 -1
  106. package/dist/engine/analyzer-env.d.ts +1 -5
  107. package/dist/engine/analyzer-env.d.ts.map +1 -1
  108. package/dist/engine/analyzer-env.js +3 -173
  109. package/dist/engine/analyzer-env.js.map +1 -1
  110. package/dist/engine/analyzer.d.ts +2 -18
  111. package/dist/engine/analyzer.d.ts.map +1 -1
  112. package/dist/engine/analyzer.js +4 -172
  113. package/dist/engine/analyzer.js.map +1 -1
  114. package/dist/engine/dashboard/data-loader.d.ts +16 -1
  115. package/dist/engine/dashboard/data-loader.d.ts.map +1 -1
  116. package/dist/engine/dashboard/data-loader.js +140 -2
  117. package/dist/engine/dashboard/data-loader.js.map +1 -1
  118. package/dist/engine/dashboard/index.d.ts +2 -0
  119. package/dist/engine/dashboard/index.d.ts.map +1 -1
  120. package/dist/engine/dashboard/index.js +2 -0
  121. package/dist/engine/dashboard/index.js.map +1 -1
  122. package/dist/engine/dashboard/kanban-logic.d.ts +31 -0
  123. package/dist/engine/dashboard/kanban-logic.d.ts.map +1 -0
  124. package/dist/engine/dashboard/kanban-logic.js +122 -0
  125. package/dist/engine/dashboard/kanban-logic.js.map +1 -0
  126. package/dist/engine/dashboard/routes.d.ts +2 -0
  127. package/dist/engine/dashboard/routes.d.ts.map +1 -1
  128. package/dist/engine/dashboard/routes.js +112 -23
  129. package/dist/engine/dashboard/routes.js.map +1 -1
  130. package/dist/engine/dashboard/server.d.ts +5 -0
  131. package/dist/engine/dashboard/server.d.ts.map +1 -1
  132. package/dist/engine/dashboard/server.js +48 -0
  133. package/dist/engine/dashboard/server.js.map +1 -1
  134. package/dist/engine/dashboard/spec-updater.d.ts +8 -0
  135. package/dist/engine/dashboard/spec-updater.d.ts.map +1 -0
  136. package/dist/engine/dashboard/spec-updater.js +37 -0
  137. package/dist/engine/dashboard/spec-updater.js.map +1 -0
  138. package/dist/engine/dashboard/templates-kanban.d.ts +6 -0
  139. package/dist/engine/dashboard/templates-kanban.d.ts.map +1 -0
  140. package/dist/engine/dashboard/templates-kanban.js +100 -0
  141. package/dist/engine/dashboard/templates-kanban.js.map +1 -0
  142. package/dist/engine/dashboard/templates-layout.d.ts +3 -3
  143. package/dist/engine/dashboard/templates-layout.d.ts.map +1 -1
  144. package/dist/engine/dashboard/templates-layout.js +167 -44
  145. package/dist/engine/dashboard/templates-layout.js.map +1 -1
  146. package/dist/engine/dashboard/templates-project.d.ts +1 -1
  147. package/dist/engine/dashboard/templates-project.d.ts.map +1 -1
  148. package/dist/engine/dashboard/templates-project.js +109 -3
  149. package/dist/engine/dashboard/templates-project.js.map +1 -1
  150. package/dist/engine/dashboard/templates.d.ts +1 -0
  151. package/dist/engine/dashboard/templates.d.ts.map +1 -1
  152. package/dist/engine/dashboard/templates.js +1 -0
  153. package/dist/engine/dashboard/templates.js.map +1 -1
  154. package/dist/engine/hooks/config-loader.d.ts +36 -0
  155. package/dist/engine/hooks/config-loader.d.ts.map +1 -0
  156. package/dist/engine/hooks/config-loader.js +142 -0
  157. package/dist/engine/hooks/config-loader.js.map +1 -0
  158. package/dist/engine/hooks/debouncer.d.ts +30 -0
  159. package/dist/engine/hooks/debouncer.d.ts.map +1 -0
  160. package/dist/engine/hooks/debouncer.js +124 -0
  161. package/dist/engine/hooks/debouncer.js.map +1 -0
  162. package/dist/engine/hooks/event-bus.d.ts +40 -0
  163. package/dist/engine/hooks/event-bus.d.ts.map +1 -0
  164. package/dist/engine/hooks/event-bus.js +83 -0
  165. package/dist/engine/hooks/event-bus.js.map +1 -0
  166. package/dist/engine/hooks/file-watcher.d.ts +48 -0
  167. package/dist/engine/hooks/file-watcher.d.ts.map +1 -0
  168. package/dist/engine/hooks/file-watcher.js +193 -0
  169. package/dist/engine/hooks/file-watcher.js.map +1 -0
  170. package/dist/engine/hooks/handlers/on-commit.d.ts +26 -0
  171. package/dist/engine/hooks/handlers/on-commit.d.ts.map +1 -0
  172. package/dist/engine/hooks/handlers/on-commit.js +198 -0
  173. package/dist/engine/hooks/handlers/on-commit.js.map +1 -0
  174. package/dist/engine/hooks/handlers/on-create.d.ts +8 -0
  175. package/dist/engine/hooks/handlers/on-create.d.ts.map +1 -0
  176. package/dist/engine/hooks/handlers/on-create.js +30 -0
  177. package/dist/engine/hooks/handlers/on-create.js.map +1 -0
  178. package/dist/engine/hooks/handlers/on-delete.d.ts +9 -0
  179. package/dist/engine/hooks/handlers/on-delete.d.ts.map +1 -0
  180. package/dist/engine/hooks/handlers/on-delete.js +33 -0
  181. package/dist/engine/hooks/handlers/on-delete.js.map +1 -0
  182. package/dist/engine/hooks/handlers/on-save.d.ts +29 -0
  183. package/dist/engine/hooks/handlers/on-save.d.ts.map +1 -0
  184. package/dist/engine/hooks/handlers/on-save.js +118 -0
  185. package/dist/engine/hooks/handlers/on-save.js.map +1 -0
  186. package/dist/engine/hooks/handlers/on-test-pass.d.ts +33 -0
  187. package/dist/engine/hooks/handlers/on-test-pass.d.ts.map +1 -0
  188. package/dist/engine/hooks/handlers/on-test-pass.js +103 -0
  189. package/dist/engine/hooks/handlers/on-test-pass.js.map +1 -0
  190. package/dist/engine/hooks/hook-engine.d.ts +50 -0
  191. package/dist/engine/hooks/hook-engine.d.ts.map +1 -0
  192. package/dist/engine/hooks/hook-engine.js +159 -0
  193. package/dist/engine/hooks/hook-engine.js.map +1 -0
  194. package/dist/engine/hooks/index.d.ts +10 -0
  195. package/dist/engine/hooks/index.d.ts.map +1 -1
  196. package/dist/engine/hooks/index.js +12 -0
  197. package/dist/engine/hooks/index.js.map +1 -1
  198. package/dist/engine/living-spec/annotation-parser.d.ts +18 -0
  199. package/dist/engine/living-spec/annotation-parser.d.ts.map +1 -0
  200. package/dist/engine/living-spec/annotation-parser.js +105 -0
  201. package/dist/engine/living-spec/annotation-parser.js.map +1 -0
  202. package/dist/engine/living-spec/auto-reconciler.d.ts +28 -0
  203. package/dist/engine/living-spec/auto-reconciler.d.ts.map +1 -0
  204. package/dist/engine/living-spec/auto-reconciler.js +103 -0
  205. package/dist/engine/living-spec/auto-reconciler.js.map +1 -0
  206. package/dist/engine/living-spec/bidirectional-sync.d.ts +26 -0
  207. package/dist/engine/living-spec/bidirectional-sync.d.ts.map +1 -0
  208. package/dist/engine/living-spec/bidirectional-sync.js +160 -0
  209. package/dist/engine/living-spec/bidirectional-sync.js.map +1 -0
  210. package/dist/engine/living-spec/dashboard-collector.d.ts +22 -0
  211. package/dist/engine/living-spec/dashboard-collector.d.ts.map +1 -0
  212. package/dist/engine/living-spec/dashboard-collector.js +97 -0
  213. package/dist/engine/living-spec/dashboard-collector.js.map +1 -0
  214. package/dist/engine/living-spec/drift-watcher.d.ts +15 -0
  215. package/dist/engine/living-spec/drift-watcher.d.ts.map +1 -0
  216. package/dist/engine/living-spec/drift-watcher.js +126 -0
  217. package/dist/engine/living-spec/drift-watcher.js.map +1 -0
  218. package/dist/engine/living-spec/hash-tracker.d.ts +24 -0
  219. package/dist/engine/living-spec/hash-tracker.d.ts.map +1 -0
  220. package/dist/engine/living-spec/hash-tracker.js +123 -0
  221. package/dist/engine/living-spec/hash-tracker.js.map +1 -0
  222. package/dist/engine/living-spec/index.d.ts +9 -0
  223. package/dist/engine/living-spec/index.d.ts.map +1 -0
  224. package/dist/engine/living-spec/index.js +10 -0
  225. package/dist/engine/living-spec/index.js.map +1 -0
  226. package/dist/engine/living-spec/signature-tracker.d.ts +18 -0
  227. package/dist/engine/living-spec/signature-tracker.d.ts.map +1 -0
  228. package/dist/engine/living-spec/signature-tracker.js +136 -0
  229. package/dist/engine/living-spec/signature-tracker.js.map +1 -0
  230. package/dist/engine/living-spec/test-coverage-correlator.d.ts +22 -0
  231. package/dist/engine/living-spec/test-coverage-correlator.d.ts.map +1 -0
  232. package/dist/engine/living-spec/test-coverage-correlator.js +130 -0
  233. package/dist/engine/living-spec/test-coverage-correlator.js.map +1 -0
  234. package/dist/engine/plugins/extensions/worker-extension.d.ts.map +1 -1
  235. package/dist/engine/plugins/extensions/worker-extension.js +3 -1
  236. package/dist/engine/plugins/extensions/worker-extension.js.map +1 -1
  237. package/dist/engine/safety/file-mutex.d.ts.map +1 -1
  238. package/dist/engine/safety/file-mutex.js +3 -0
  239. package/dist/engine/safety/file-mutex.js.map +1 -1
  240. package/dist/engine/spec-registry/adapter.d.ts +9 -0
  241. package/dist/engine/spec-registry/adapter.d.ts.map +1 -0
  242. package/dist/engine/spec-registry/adapter.js +303 -0
  243. package/dist/engine/spec-registry/adapter.js.map +1 -0
  244. package/dist/engine/spec-registry/client.d.ts +8 -0
  245. package/dist/engine/spec-registry/client.d.ts.map +1 -0
  246. package/dist/engine/spec-registry/client.js +194 -0
  247. package/dist/engine/spec-registry/client.js.map +1 -0
  248. package/dist/engine/spec-registry/index.d.ts +7 -0
  249. package/dist/engine/spec-registry/index.d.ts.map +1 -0
  250. package/dist/engine/spec-registry/index.js +7 -0
  251. package/dist/engine/spec-registry/index.js.map +1 -0
  252. package/dist/engine/spec-registry/packager.d.ts +24 -0
  253. package/dist/engine/spec-registry/packager.d.ts.map +1 -0
  254. package/dist/engine/spec-registry/packager.js +122 -0
  255. package/dist/engine/spec-registry/packager.js.map +1 -0
  256. package/dist/engine/spec-registry/scorer.d.ts +10 -0
  257. package/dist/engine/spec-registry/scorer.d.ts.map +1 -0
  258. package/dist/engine/spec-registry/scorer.js +151 -0
  259. package/dist/engine/spec-registry/scorer.js.map +1 -0
  260. package/dist/engine/spec-registry/validator.d.ts +11 -0
  261. package/dist/engine/spec-registry/validator.d.ts.map +1 -0
  262. package/dist/engine/spec-registry/validator.js +144 -0
  263. package/dist/engine/spec-registry/validator.js.map +1 -0
  264. package/dist/index.js +31 -0
  265. package/dist/index.js.map +1 -1
  266. package/dist/storage/hash-snapshot-store.d.ts +18 -0
  267. package/dist/storage/hash-snapshot-store.d.ts.map +1 -0
  268. package/dist/storage/hash-snapshot-store.js +43 -0
  269. package/dist/storage/hash-snapshot-store.js.map +1 -0
  270. package/dist/storage/index.d.ts +3 -0
  271. package/dist/storage/index.d.ts.map +1 -1
  272. package/dist/storage/index.js +3 -0
  273. package/dist/storage/index.js.map +1 -1
  274. package/dist/storage/living-dashboard-store.d.ts +10 -0
  275. package/dist/storage/living-dashboard-store.d.ts.map +1 -0
  276. package/dist/storage/living-dashboard-store.js +31 -0
  277. package/dist/storage/living-dashboard-store.js.map +1 -0
  278. package/dist/storage/sync-log-store.d.ts +26 -0
  279. package/dist/storage/sync-log-store.d.ts.map +1 -0
  280. package/dist/storage/sync-log-store.js +60 -0
  281. package/dist/storage/sync-log-store.js.map +1 -0
  282. package/dist/tools/auto-reconcile.d.ts +3 -0
  283. package/dist/tools/auto-reconcile.d.ts.map +1 -0
  284. package/dist/tools/auto-reconcile.js +81 -0
  285. package/dist/tools/auto-reconcile.js.map +1 -0
  286. package/dist/tools/challenge-spec/platform-challenge-scenarios-b2.d.ts.map +1 -1
  287. package/dist/tools/challenge-spec/platform-challenge-scenarios-b2.js +6 -0
  288. package/dist/tools/challenge-spec/platform-challenge-scenarios-b2.js.map +1 -1
  289. package/dist/tools/create-spec/spec-builder.js +2 -0
  290. package/dist/tools/create-spec/spec-builder.js.map +1 -1
  291. package/dist/tools/dashboard.d.ts.map +1 -1
  292. package/dist/tools/dashboard.js +20 -13
  293. package/dist/tools/dashboard.js.map +1 -1
  294. package/dist/tools/generate-annotations.d.ts +3 -0
  295. package/dist/tools/generate-annotations.d.ts.map +1 -0
  296. package/dist/tools/generate-annotations.js +70 -0
  297. package/dist/tools/generate-annotations.js.map +1 -0
  298. package/dist/tools/generate-execution-plan.d.ts.map +1 -1
  299. package/dist/tools/generate-execution-plan.js +1 -0
  300. package/dist/tools/generate-execution-plan.js.map +1 -1
  301. package/dist/tools/github-pr-handler.d.ts.map +1 -1
  302. package/dist/tools/github-pr-handler.js +1 -0
  303. package/dist/tools/github-pr-handler.js.map +1 -1
  304. package/dist/tools/github-review-handler.d.ts.map +1 -1
  305. package/dist/tools/github-review-handler.js +1 -0
  306. package/dist/tools/github-review-handler.js.map +1 -1
  307. package/dist/tools/ide-config-handler.d.ts.map +1 -1
  308. package/dist/tools/ide-config-handler.js +3 -0
  309. package/dist/tools/ide-config-handler.js.map +1 -1
  310. package/dist/tools/init-project/handler.d.ts.map +1 -1
  311. package/dist/tools/init-project/handler.js +0 -3
  312. package/dist/tools/init-project/handler.js.map +1 -1
  313. package/dist/tools/living-spec-coverage.d.ts +3 -0
  314. package/dist/tools/living-spec-coverage.d.ts.map +1 -0
  315. package/dist/tools/living-spec-coverage.js +100 -0
  316. package/dist/tools/living-spec-coverage.js.map +1 -0
  317. package/dist/tools/living-spec-watch.d.ts +4 -0
  318. package/dist/tools/living-spec-watch.d.ts.map +1 -0
  319. package/dist/tools/living-spec-watch.js +94 -0
  320. package/dist/tools/living-spec-watch.js.map +1 -0
  321. package/dist/tools/manage-plugins-handler.d.ts.map +1 -1
  322. package/dist/tools/manage-plugins-handler.js +2 -1
  323. package/dist/tools/manage-plugins-handler.js.map +1 -1
  324. package/dist/tools/orchestrate-distribution.d.ts.map +1 -1
  325. package/dist/tools/orchestrate-distribution.js +1 -0
  326. package/dist/tools/orchestrate-distribution.js.map +1 -1
  327. package/dist/tools/orchestrate-runtime.js +2 -0
  328. package/dist/tools/orchestrate-runtime.js.map +1 -1
  329. package/dist/tools/plan-team-distribution.d.ts.map +1 -1
  330. package/dist/tools/plan-team-distribution.js +2 -0
  331. package/dist/tools/plan-team-distribution.js.map +1 -1
  332. package/dist/tools/register-dashboard-tools.d.ts.map +1 -1
  333. package/dist/tools/register-dashboard-tools.js +5 -1
  334. package/dist/tools/register-dashboard-tools.js.map +1 -1
  335. package/dist/tools/register-hooks-tools.d.ts.map +1 -1
  336. package/dist/tools/register-hooks-tools.js +82 -1
  337. package/dist/tools/register-hooks-tools.js.map +1 -1
  338. package/dist/tools/register-living-spec-advanced-tools.d.ts +6 -0
  339. package/dist/tools/register-living-spec-advanced-tools.d.ts.map +1 -0
  340. package/dist/tools/register-living-spec-advanced-tools.js +113 -0
  341. package/dist/tools/register-living-spec-advanced-tools.js.map +1 -0
  342. package/dist/tools/register-living-spec-tools.d.ts +6 -0
  343. package/dist/tools/register-living-spec-tools.d.ts.map +1 -0
  344. package/dist/tools/register-living-spec-tools.js +67 -0
  345. package/dist/tools/register-living-spec-tools.js.map +1 -0
  346. package/dist/tools/register-spec-registry-tools.d.ts +3 -0
  347. package/dist/tools/register-spec-registry-tools.d.ts.map +1 -0
  348. package/dist/tools/register-spec-registry-tools.js +91 -0
  349. package/dist/tools/register-spec-registry-tools.js.map +1 -0
  350. package/dist/tools/registry/auth.d.ts +17 -0
  351. package/dist/tools/registry/auth.d.ts.map +1 -0
  352. package/dist/tools/registry/auth.js +132 -0
  353. package/dist/tools/registry/auth.js.map +1 -0
  354. package/dist/tools/registry/index.d.ts +5 -0
  355. package/dist/tools/registry/index.d.ts.map +1 -0
  356. package/dist/tools/registry/index.js +6 -0
  357. package/dist/tools/registry/index.js.map +1 -0
  358. package/dist/tools/registry/install.d.ts +7 -0
  359. package/dist/tools/registry/install.d.ts.map +1 -0
  360. package/dist/tools/registry/install.js +125 -0
  361. package/dist/tools/registry/install.js.map +1 -0
  362. package/dist/tools/registry/publish.d.ts +7 -0
  363. package/dist/tools/registry/publish.d.ts.map +1 -0
  364. package/dist/tools/registry/publish.js +96 -0
  365. package/dist/tools/registry/publish.js.map +1 -0
  366. package/dist/tools/registry/search.d.ts +7 -0
  367. package/dist/tools/registry/search.d.ts.map +1 -0
  368. package/dist/tools/registry/search.js +79 -0
  369. package/dist/tools/registry/search.js.map +1 -0
  370. package/dist/tools/resolve-sync-conflict.d.ts +3 -0
  371. package/dist/tools/resolve-sync-conflict.d.ts.map +1 -0
  372. package/dist/tools/resolve-sync-conflict.js +38 -0
  373. package/dist/tools/resolve-sync-conflict.js.map +1 -0
  374. package/dist/tools/schemas/index.d.ts +1 -0
  375. package/dist/tools/schemas/index.d.ts.map +1 -1
  376. package/dist/tools/schemas/index.js +1 -0
  377. package/dist/tools/schemas/index.js.map +1 -1
  378. package/dist/tools/schemas/spec-registry-schemas.d.ts +39 -0
  379. package/dist/tools/schemas/spec-registry-schemas.d.ts.map +1 -0
  380. package/dist/tools/schemas/spec-registry-schemas.js +72 -0
  381. package/dist/tools/schemas/spec-registry-schemas.js.map +1 -0
  382. package/dist/tools/snapshot-spec-hashes.d.ts +3 -0
  383. package/dist/tools/snapshot-spec-hashes.d.ts.map +1 -0
  384. package/dist/tools/snapshot-spec-hashes.js +100 -0
  385. package/dist/tools/snapshot-spec-hashes.js.map +1 -0
  386. package/dist/tools/spec-diff.d.ts +3 -0
  387. package/dist/tools/spec-diff.d.ts.map +1 -0
  388. package/dist/tools/spec-diff.js +58 -0
  389. package/dist/tools/spec-diff.js.map +1 -0
  390. package/dist/tools/start-hooks.d.ts +17 -0
  391. package/dist/tools/start-hooks.d.ts.map +1 -0
  392. package/dist/tools/start-hooks.js +209 -0
  393. package/dist/tools/start-hooks.js.map +1 -0
  394. package/dist/tools/sync-code-to-spec.d.ts +3 -0
  395. package/dist/tools/sync-code-to-spec.d.ts.map +1 -0
  396. package/dist/tools/sync-code-to-spec.js +51 -0
  397. package/dist/tools/sync-code-to-spec.js.map +1 -0
  398. package/dist/tools/sync-spec-to-code.d.ts +3 -0
  399. package/dist/tools/sync-spec-to-code.d.ts.map +1 -0
  400. package/dist/tools/sync-spec-to-code.js +58 -0
  401. package/dist/tools/sync-spec-to-code.js.map +1 -0
  402. package/dist/tools/validate-annotations.d.ts +3 -0
  403. package/dist/tools/validate-annotations.d.ts.map +1 -0
  404. package/dist/tools/validate-annotations.js +90 -0
  405. package/dist/tools/validate-annotations.js.map +1 -0
  406. package/dist/types/cli.d.ts +14 -0
  407. package/dist/types/cli.d.ts.map +1 -0
  408. package/dist/types/cli.js +3 -0
  409. package/dist/types/cli.js.map +1 -0
  410. package/dist/types/dashboard.d.ts +86 -1
  411. package/dist/types/dashboard.d.ts.map +1 -1
  412. package/dist/types/file-hooks.d.ts +230 -0
  413. package/dist/types/file-hooks.d.ts.map +1 -0
  414. package/dist/types/file-hooks.js +3 -0
  415. package/dist/types/file-hooks.js.map +1 -0
  416. package/dist/types/index.d.ts +4 -0
  417. package/dist/types/index.d.ts.map +1 -1
  418. package/dist/types/index.js +4 -0
  419. package/dist/types/index.js.map +1 -1
  420. package/dist/types/living-spec.d.ts +382 -0
  421. package/dist/types/living-spec.d.ts.map +1 -0
  422. package/dist/types/living-spec.js +3 -0
  423. package/dist/types/living-spec.js.map +1 -0
  424. package/dist/types/spec-registry.d.ts +194 -0
  425. package/dist/types/spec-registry.d.ts.map +1 -0
  426. package/dist/types/spec-registry.js +3 -0
  427. package/dist/types/spec-registry.js.map +1 -0
  428. package/package.json +1 -1
  429. package/src/config/hook-defaults.json +19 -0
  430. package/src/config/license-plans.json +23 -2
  431. package/src/config/registry-categories.json +20 -0
  432. package/src/config/registry-stacks.json +16 -0
  433. package/src/config/tool-groups.json +12 -1
@@ -0,0 +1,105 @@
1
+ // engine/living-spec/annotation-parser.ts — Parse @spec annotations from source code
2
+ // Supports: // @spec, # @spec, -- @spec, /* @spec */ (language-agnostic)
3
+ // Performance target: <100ms for 10,000-line files
4
+ import { readFile } from 'node:fs/promises';
5
+ import { join } from 'node:path';
6
+ import { glob } from 'glob';
7
+ const SOURCE_EXTS = '*.{ts,tsx,js,jsx,py,go,rs,java,kt,rb,php,vue,svelte,sql,lua,sh,bash,zsh}';
8
+ const IGNORE_DIRS = ['node_modules/**', 'dist/**', 'build/**', '.git/**', 'vendor/**'];
9
+ /**
10
+ * Regex that captures @spec annotations in any comment style.
11
+ * Groups: 1=specId, 2=criteria (optional, e.g. ":AC-1,AC-3"), 3=description (optional)
12
+ */
13
+ const ANNOTATION_REGEX = /(?:\/\/|#|--|\/\*)\s*@spec\s+(SPEC-\d+)(?::([A-Za-z0-9,-]+))?\s*(?:—\s*(.+?))?\s*(?:\*\/)?$/;
14
+ /**
15
+ * Parse a single line for a @spec annotation.
16
+ */
17
+ export function parseAnnotationLine(line, file, lineNumber) {
18
+ const match = ANNOTATION_REGEX.exec(line.trim());
19
+ if (!match?.[1]) {
20
+ return null;
21
+ }
22
+ const specId = match[1];
23
+ const criteriaStr = match[2] ?? '';
24
+ const description = match[3]?.trim() ?? '';
25
+ const criteria = parseCriteriaList(criteriaStr);
26
+ return {
27
+ specId,
28
+ criteria,
29
+ description,
30
+ file,
31
+ line: lineNumber,
32
+ raw: line.trim(),
33
+ };
34
+ }
35
+ /**
36
+ * Parse criteria string like "AC-1,AC-3,AC-5" into [1, 3, 5].
37
+ */
38
+ export function parseCriteriaList(criteriaStr) {
39
+ if (!criteriaStr) {
40
+ return [];
41
+ }
42
+ const parts = criteriaStr.split(',');
43
+ const result = [];
44
+ for (const part of parts) {
45
+ const cleaned = part.trim().replace(/^AC-/i, '');
46
+ const num = Number.parseInt(cleaned, 10);
47
+ if (!Number.isNaN(num) && num > 0) {
48
+ result.push(num);
49
+ }
50
+ }
51
+ return result;
52
+ }
53
+ /**
54
+ * Parse all @spec annotations from a file's content.
55
+ */
56
+ export function parseAnnotationsFromContent(content, file) {
57
+ const annotations = [];
58
+ const lines = content.split('\n');
59
+ for (let i = 0; i < lines.length; i++) {
60
+ const line = lines[i];
61
+ if (line === undefined) {
62
+ continue;
63
+ }
64
+ const annotation = parseAnnotationLine(line, file, i + 1);
65
+ if (annotation) {
66
+ annotations.push(annotation);
67
+ }
68
+ }
69
+ return annotations;
70
+ }
71
+ /**
72
+ * Parse all @spec annotations from a project directory.
73
+ */
74
+ export async function parseAnnotationsFromProject(projectPath, filterSpecId) {
75
+ const annotations = [];
76
+ let fileCount = 0;
77
+ let annotatedFileCount = 0;
78
+ const files = await glob(`**/${SOURCE_EXTS}`, {
79
+ cwd: projectPath,
80
+ nodir: true,
81
+ ignore: IGNORE_DIRS,
82
+ maxDepth: 8,
83
+ });
84
+ for (const file of files) {
85
+ fileCount++;
86
+ try {
87
+ const content = await readFile(join(projectPath, file), 'utf-8');
88
+ const fileAnnotations = parseAnnotationsFromContent(content, file);
89
+ if (fileAnnotations.length > 0) {
90
+ annotatedFileCount++;
91
+ if (filterSpecId) {
92
+ annotations.push(...fileAnnotations.filter((a) => a.specId === filterSpecId));
93
+ }
94
+ else {
95
+ annotations.push(...fileAnnotations);
96
+ }
97
+ }
98
+ }
99
+ catch {
100
+ // Skip unreadable files
101
+ }
102
+ }
103
+ return { annotations, fileCount, annotatedFileCount };
104
+ }
105
+ //# sourceMappingURL=annotation-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"annotation-parser.js","sourceRoot":"","sources":["../../../src/engine/living-spec/annotation-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { ReconcileLogEntry, ReconcileChangeClass, AutoReconcileResult } from '../../types/index.js';
2
+ /**
3
+ * Check if a spec is rate-limited for auto-reconciliation.
4
+ */
5
+ export declare function isRateLimited(specId: string): boolean;
6
+ /**
7
+ * Record that a spec was auto-reconciled (updates rate limit tracker).
8
+ */
9
+ export declare function recordReconcile(specId: string): void;
10
+ /**
11
+ * Clear rate limit for a spec (for testing).
12
+ */
13
+ export declare function clearRateLimit(specId: string): void;
14
+ /**
15
+ * Classify a change as safe or unsafe.
16
+ * Safe: completion % update, met/pending status flip, hash snapshot update, timestamp update.
17
+ * Unsafe: status downgrade, criterion removal, scope change.
18
+ */
19
+ export declare function classifyChange(changeType: string, description: string): ReconcileChangeClass;
20
+ /**
21
+ * Create a reconcile log entry.
22
+ */
23
+ export declare function createLogEntry(specId: string, changeType: ReconcileLogEntry['changeType'], description: string, previousValue: string, newValue: string): ReconcileLogEntry;
24
+ /**
25
+ * Build auto-reconcile result from changes, filtering by safety classification.
26
+ */
27
+ export declare function buildAutoReconcileResult(specId: string, changes: ReconcileLogEntry[]): AutoReconcileResult;
28
+ //# sourceMappingURL=auto-reconciler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-reconciler.d.ts","sourceRoot":"","sources":["../../../src/engine/living-spec/auto-reconciler.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,sBAAsB,CAAC;AAQ9B;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAMrD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAEpD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,oBAAoB,CAsB5F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,iBAAiB,CAAC,YAAY,CAAC,EAC3C,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,iBAAiB,CASnB;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,iBAAiB,EAAE,GAC3B,mBAAmB,CAkCrB"}
@@ -0,0 +1,103 @@
1
+ // engine/living-spec/auto-reconciler.ts — Auto-reconciliation engine for safe spec changes
2
+ // Classifies changes as safe/unsafe and applies only safe changes automatically.
3
+ // Rate-limited: max 1 auto-reconcile per spec per 5 minutes.
4
+ /** Rate limit: 5 minutes between auto-reconciles per spec. */
5
+ const RATE_LIMIT_MS = 5 * 60 * 1000;
6
+ /** In-memory rate limit tracker (spec -> last reconcile timestamp). */
7
+ const rateLimitMap = new Map();
8
+ /**
9
+ * Check if a spec is rate-limited for auto-reconciliation.
10
+ */
11
+ export function isRateLimited(specId) {
12
+ const lastTime = rateLimitMap.get(specId);
13
+ if (lastTime === undefined) {
14
+ return false;
15
+ }
16
+ return Date.now() - lastTime < RATE_LIMIT_MS;
17
+ }
18
+ /**
19
+ * Record that a spec was auto-reconciled (updates rate limit tracker).
20
+ */
21
+ export function recordReconcile(specId) {
22
+ rateLimitMap.set(specId, Date.now());
23
+ }
24
+ /**
25
+ * Clear rate limit for a spec (for testing).
26
+ */
27
+ export function clearRateLimit(specId) {
28
+ rateLimitMap.delete(specId);
29
+ }
30
+ /**
31
+ * Classify a change as safe or unsafe.
32
+ * Safe: completion % update, met/pending status flip, hash snapshot update, timestamp update.
33
+ * Unsafe: status downgrade, criterion removal, scope change.
34
+ */
35
+ export function classifyChange(changeType, description) {
36
+ // Check description for unsafe keywords FIRST (overrides type-based classification)
37
+ const lower = description.toLowerCase();
38
+ const unsafeKeywords = ['downgrade', 'remove', 'scope change', 'delete criterion'];
39
+ for (const keyword of unsafeKeywords) {
40
+ if (lower.includes(keyword)) {
41
+ return 'unsafe';
42
+ }
43
+ }
44
+ const safeTypes = new Set([
45
+ 'completion-update',
46
+ 'status-flip',
47
+ 'hash-update',
48
+ 'timestamp-update',
49
+ ]);
50
+ if (safeTypes.has(changeType)) {
51
+ return 'safe';
52
+ }
53
+ return 'unsafe';
54
+ }
55
+ /**
56
+ * Create a reconcile log entry.
57
+ */
58
+ export function createLogEntry(specId, changeType, description, previousValue, newValue) {
59
+ return {
60
+ timestamp: new Date().toISOString(),
61
+ changeType,
62
+ specId,
63
+ description,
64
+ previousValue,
65
+ newValue,
66
+ };
67
+ }
68
+ /**
69
+ * Build auto-reconcile result from changes, filtering by safety classification.
70
+ */
71
+ export function buildAutoReconcileResult(specId, changes) {
72
+ if (isRateLimited(specId)) {
73
+ return {
74
+ specId,
75
+ appliedChanges: [],
76
+ skippedUnsafe: [],
77
+ rateLimited: true,
78
+ reconciledAt: new Date().toISOString(),
79
+ };
80
+ }
81
+ const applied = [];
82
+ const skippedUnsafe = [];
83
+ for (const change of changes) {
84
+ const classification = classifyChange(change.changeType, change.description);
85
+ if (classification === 'safe') {
86
+ applied.push(change);
87
+ }
88
+ else {
89
+ skippedUnsafe.push(`${change.changeType}: ${change.description}`);
90
+ }
91
+ }
92
+ if (applied.length > 0) {
93
+ recordReconcile(specId);
94
+ }
95
+ return {
96
+ specId,
97
+ appliedChanges: applied,
98
+ skippedUnsafe,
99
+ rateLimited: false,
100
+ reconciledAt: new Date().toISOString(),
101
+ };
102
+ }
103
+ //# sourceMappingURL=auto-reconciler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-reconciler.js","sourceRoot":"","sources":["../../../src/engine/living-spec/auto-reconciler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { TodoComment, ProgressUpdate, SyncConflict, SyncLogEntry, SyncResult, SyncDirection, SpecAnnotation, CriterionInfo } from '../../types/index.js';
2
+ /**
3
+ * Generate TODO comments for pending criteria that lack annotations in code.
4
+ */
5
+ export declare function generateTodoComments(pendingCriteria: CriterionInfo[], existingAnnotations: SpecAnnotation[], defaultFile: string): TodoComment[];
6
+ /**
7
+ * Generate progress updates based on annotations found in code.
8
+ */
9
+ export declare function generateProgressUpdates(annotations: SpecAnnotation[], criteriaStatuses: Map<string, string>): ProgressUpdate[];
10
+ /**
11
+ * Detect conflicts between code state and spec state.
12
+ */
13
+ export declare function detectConflicts(annotations: SpecAnnotation[], criteriaStatuses: Map<string, string>, direction: SyncDirection): SyncConflict[];
14
+ /**
15
+ * Create a sync log entry.
16
+ */
17
+ export declare function createSyncLogEntry(direction: SyncDirection, specId: string, action: string, details: string): SyncLogEntry;
18
+ /**
19
+ * Build a spec-to-code sync result.
20
+ */
21
+ export declare function buildSpecToCodeResult(specId: string, todos: TodoComment[], conflicts: SyncConflict[]): SyncResult;
22
+ /**
23
+ * Build a code-to-spec sync result.
24
+ */
25
+ export declare function buildCodeToSpecResult(specId: string, updates: ProgressUpdate[], conflicts: SyncConflict[]): SyncResult;
26
+ //# sourceMappingURL=bidirectional-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bidirectional-sync.d.ts","sourceRoot":"","sources":["../../../src/engine/living-spec/bidirectional-sync.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,aAAa,EACb,cAAc,EACd,aAAa,EACd,MAAM,sBAAsB,CAAC;AAM9B;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,aAAa,EAAE,EAChC,mBAAmB,EAAE,cAAc,EAAE,EACrC,WAAW,EAAE,MAAM,GAClB,WAAW,EAAE,CA0Bf;AAMD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,cAAc,EAAE,EAC7B,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACpC,cAAc,EAAE,CA0BlB;AAMD;;GAEG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,cAAc,EAAE,EAC7B,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EACrC,SAAS,EAAE,aAAa,GACvB,YAAY,EAAE,CAmChB;AAMD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,aAAa,EACxB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,YAAY,CAQd;AAMD;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,WAAW,EAAE,EACpB,SAAS,EAAE,YAAY,EAAE,GACxB,UAAU,CA8BZ;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAc,EAAE,EACzB,SAAS,EAAE,YAAY,EAAE,GACxB,UAAU,CA8BZ"}
@@ -0,0 +1,160 @@
1
+ // engine/living-spec/bidirectional-sync.ts — AC-9: Bidirectional sync
2
+ // TODO comment generation, progress updates, conflict detection,
3
+ // sync log entries, and spec-to-code/code-to-spec result builders.
4
+ import { createHash } from 'node:crypto';
5
+ // ---------------------------------------------------------------------------
6
+ // TODO comment generation (spec-to-code)
7
+ // ---------------------------------------------------------------------------
8
+ /**
9
+ * Generate TODO comments for pending criteria that lack annotations in code.
10
+ */
11
+ export function generateTodoComments(pendingCriteria, existingAnnotations, defaultFile) {
12
+ const annotatedSet = new Set();
13
+ for (const ann of existingAnnotations) {
14
+ for (const c of ann.criteria) {
15
+ annotatedSet.add(`${ann.specId}:AC-${c}`);
16
+ }
17
+ }
18
+ const todos = [];
19
+ for (const criterion of pendingCriteria) {
20
+ const key = `${criterion.specId}:AC-${criterion.criterion}`;
21
+ if (annotatedSet.has(key)) {
22
+ continue;
23
+ }
24
+ todos.push({
25
+ file: defaultFile,
26
+ line: 1,
27
+ text: `TODO: @spec ${criterion.specId} AC-${criterion.criterion} — ${criterion.description}`,
28
+ specId: criterion.specId,
29
+ criterion: criterion.criterion,
30
+ });
31
+ }
32
+ return todos;
33
+ }
34
+ // ---------------------------------------------------------------------------
35
+ // Progress updates (code-to-spec)
36
+ // ---------------------------------------------------------------------------
37
+ /**
38
+ * Generate progress updates based on annotations found in code.
39
+ */
40
+ export function generateProgressUpdates(annotations, criteriaStatuses) {
41
+ const updates = [];
42
+ const seen = new Set();
43
+ for (const ann of annotations) {
44
+ for (const criterion of ann.criteria) {
45
+ const key = `${ann.specId}:AC-${criterion}`;
46
+ if (seen.has(key)) {
47
+ continue;
48
+ }
49
+ seen.add(key);
50
+ const currentStatus = criteriaStatuses.get(key) ?? 'pending';
51
+ if (currentStatus === 'pending') {
52
+ updates.push({
53
+ specId: ann.specId,
54
+ criterion,
55
+ previousStatus: 'pending',
56
+ newStatus: 'met',
57
+ reason: `Annotation found in ${ann.file}:${ann.line}`,
58
+ });
59
+ }
60
+ }
61
+ }
62
+ return updates;
63
+ }
64
+ // ---------------------------------------------------------------------------
65
+ // Conflict detection
66
+ // ---------------------------------------------------------------------------
67
+ /**
68
+ * Detect conflicts between code state and spec state.
69
+ */
70
+ export function detectConflicts(annotations, criteriaStatuses, direction) {
71
+ const conflicts = [];
72
+ const seen = new Set();
73
+ for (const ann of annotations) {
74
+ for (const criterion of ann.criteria) {
75
+ const key = `${ann.specId}:AC-${criterion}`;
76
+ if (seen.has(key)) {
77
+ continue;
78
+ }
79
+ seen.add(key);
80
+ const specStatus = criteriaStatuses.get(key) ?? 'pending';
81
+ if (specStatus === 'drift' || specStatus === 'regression') {
82
+ const id = createHash('sha256')
83
+ .update(`${key}:${direction}:${Date.now()}`)
84
+ .digest('hex')
85
+ .slice(0, 12);
86
+ conflicts.push({
87
+ id,
88
+ specId: ann.specId,
89
+ criterion,
90
+ direction,
91
+ description: `Criterion AC-${criterion} has annotation in code but spec status is "${specStatus}"`,
92
+ codeState: `annotated in ${ann.file}:${ann.line}`,
93
+ specState: specStatus,
94
+ detectedAt: new Date().toISOString(),
95
+ resolved: false,
96
+ });
97
+ }
98
+ }
99
+ }
100
+ return conflicts;
101
+ }
102
+ // ---------------------------------------------------------------------------
103
+ // Sync log entries
104
+ // ---------------------------------------------------------------------------
105
+ /**
106
+ * Create a sync log entry.
107
+ */
108
+ export function createSyncLogEntry(direction, specId, action, details) {
109
+ return {
110
+ timestamp: new Date().toISOString(),
111
+ direction,
112
+ specId,
113
+ action,
114
+ details,
115
+ };
116
+ }
117
+ // ---------------------------------------------------------------------------
118
+ // Result builders
119
+ // ---------------------------------------------------------------------------
120
+ /**
121
+ * Build a spec-to-code sync result.
122
+ */
123
+ export function buildSpecToCodeResult(specId, todos, conflicts) {
124
+ const logEntries = [
125
+ createSyncLogEntry('spec-to-code', specId, 'generate-todos', `Generated ${todos.length} TODO comment(s)`),
126
+ ];
127
+ if (conflicts.length > 0) {
128
+ logEntries.push(createSyncLogEntry('spec-to-code', specId, 'detect-conflicts', `Found ${conflicts.length} conflict(s)`));
129
+ }
130
+ return {
131
+ direction: 'spec-to-code',
132
+ specId,
133
+ todosGenerated: todos,
134
+ progressUpdates: [],
135
+ conflicts,
136
+ logEntries,
137
+ syncedAt: new Date().toISOString(),
138
+ };
139
+ }
140
+ /**
141
+ * Build a code-to-spec sync result.
142
+ */
143
+ export function buildCodeToSpecResult(specId, updates, conflicts) {
144
+ const logEntries = [
145
+ createSyncLogEntry('code-to-spec', specId, 'update-progress', `Generated ${updates.length} progress update(s)`),
146
+ ];
147
+ if (conflicts.length > 0) {
148
+ logEntries.push(createSyncLogEntry('code-to-spec', specId, 'detect-conflicts', `Found ${conflicts.length} conflict(s)`));
149
+ }
150
+ return {
151
+ direction: 'code-to-spec',
152
+ specId,
153
+ todosGenerated: [],
154
+ progressUpdates: updates,
155
+ conflicts,
156
+ logEntries,
157
+ syncedAt: new Date().toISOString(),
158
+ };
159
+ }
160
+ //# sourceMappingURL=bidirectional-sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bidirectional-sync.js","sourceRoot":"","sources":["../../../src/engine/living-spec/bidirectional-sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { DashboardSpecEntry, DashboardSpecInput, DashboardSummary, DashboardTrendPoint, SpecDiffRow, SpecHashSnapshot } from '../../types/index.js';
2
+ /**
3
+ * Collect dashboard entries from specs and their hash snapshots.
4
+ */
5
+ export declare function collectSpecEntries(specs: DashboardSpecInput[], hashSnapshots: Map<string, SpecHashSnapshot | null>): DashboardSpecEntry[];
6
+ /**
7
+ * Compute summary statistics from dashboard entries.
8
+ */
9
+ export declare function collectSummary(entries: DashboardSpecEntry[]): DashboardSummary;
10
+ /**
11
+ * Collect trend data points, capping at MAX_TREND_POINTS.
12
+ */
13
+ export declare function collectTrends(entries: DashboardSpecEntry[], history: DashboardTrendPoint[]): DashboardTrendPoint[];
14
+ /**
15
+ * Build diff rows comparing old and new hash snapshots.
16
+ */
17
+ export declare function buildSpecDiffRows(oldHashes: Map<string, string>, newHashes: Map<string, string>, specId: string): SpecDiffRow[];
18
+ /**
19
+ * Format diff rows as a Markdown table.
20
+ */
21
+ export declare function formatMarkdownDiff(rows: SpecDiffRow[]): string;
22
+ //# sourceMappingURL=dashboard-collector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-collector.d.ts","sourceRoot":"","sources":["../../../src/engine/living-spec/dashboard-collector.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,WAAW,EACX,gBAAgB,EACjB,MAAM,sBAAsB,CAAC;AAI9B;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,kBAAkB,EAAE,EAC3B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC,GAClD,kBAAkB,EAAE,CAetB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,kBAAkB,EAAE,GAAG,gBAAgB,CAiB9E;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,kBAAkB,EAAE,EAC7B,OAAO,EAAE,mBAAmB,EAAE,GAC7B,mBAAmB,EAAE,CAcvB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,MAAM,EAAE,MAAM,GACb,WAAW,EAAE,CAmBf;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,CAiB9D"}
@@ -0,0 +1,97 @@
1
+ // engine/living-spec/dashboard-collector.ts — AC-7: Dashboard data collection
2
+ // Collects spec entries, summaries, trends, and diff rows for living dashboards.
3
+ const MAX_TREND_POINTS = 30;
4
+ /**
5
+ * Collect dashboard entries from specs and their hash snapshots.
6
+ */
7
+ export function collectSpecEntries(specs, hashSnapshots) {
8
+ const now = new Date().toISOString();
9
+ return specs.map((spec) => {
10
+ const snapshot = hashSnapshots.get(spec.id);
11
+ const hasChanges = snapshot !== null && snapshot !== undefined;
12
+ return {
13
+ specId: spec.id,
14
+ status: spec.status,
15
+ completion: spec.completion,
16
+ driftDetected: hasChanges && snapshot.files.length > 0,
17
+ changedFileCount: hasChanges ? snapshot.files.length : 0,
18
+ signatureChangeCount: hasChanges ? snapshot.signatures.length : 0,
19
+ lastCheckedAt: hasChanges ? snapshot.createdAt : now,
20
+ };
21
+ });
22
+ }
23
+ /**
24
+ * Compute summary statistics from dashboard entries.
25
+ */
26
+ export function collectSummary(entries) {
27
+ const totalSpecs = entries.length;
28
+ const specsWithDrift = entries.filter((e) => e.driftDetected).length;
29
+ const averageCompletion = totalSpecs > 0 ? Math.round(entries.reduce((sum, e) => sum + e.completion, 0) / totalSpecs) : 0;
30
+ const driftPenalty = totalSpecs > 0 ? (specsWithDrift / totalSpecs) * 50 : 0;
31
+ const completionPenalty = (100 - averageCompletion) * 0.5;
32
+ const healthScore = Math.max(0, Math.round(100 - driftPenalty - completionPenalty));
33
+ return {
34
+ totalSpecs,
35
+ specsWithDrift,
36
+ averageCompletion,
37
+ healthScore,
38
+ generatedAt: new Date().toISOString(),
39
+ };
40
+ }
41
+ /**
42
+ * Collect trend data points, capping at MAX_TREND_POINTS.
43
+ */
44
+ export function collectTrends(entries, history) {
45
+ const summary = collectSummary(entries);
46
+ const newPoint = {
47
+ timestamp: new Date().toISOString(),
48
+ specsWithDrift: summary.specsWithDrift,
49
+ averageCompletion: summary.averageCompletion,
50
+ healthScore: summary.healthScore,
51
+ };
52
+ const updated = [...history, newPoint];
53
+ if (updated.length > MAX_TREND_POINTS) {
54
+ return updated.slice(updated.length - MAX_TREND_POINTS);
55
+ }
56
+ return updated;
57
+ }
58
+ /**
59
+ * Build diff rows comparing old and new hash snapshots.
60
+ */
61
+ export function buildSpecDiffRows(oldHashes, newHashes, specId) {
62
+ const rows = [];
63
+ for (const [file, oldHash] of oldHashes) {
64
+ const newHash = newHashes.get(file);
65
+ if (newHash === undefined) {
66
+ rows.push({ specId, file, previousHash: oldHash, currentHash: '', status: 'removed' });
67
+ }
68
+ else if (newHash !== oldHash) {
69
+ rows.push({ specId, file, previousHash: oldHash, currentHash: newHash, status: 'modified' });
70
+ }
71
+ }
72
+ for (const [file, newHash] of newHashes) {
73
+ if (!oldHashes.has(file)) {
74
+ rows.push({ specId, file, previousHash: '', currentHash: newHash, status: 'added' });
75
+ }
76
+ }
77
+ return rows;
78
+ }
79
+ /**
80
+ * Format diff rows as a Markdown table.
81
+ */
82
+ export function formatMarkdownDiff(rows) {
83
+ if (rows.length === 0) {
84
+ return 'No changes detected.';
85
+ }
86
+ const lines = [
87
+ '| Spec | File | Status | Previous Hash | Current Hash |',
88
+ '|------|------|--------|---------------|--------------|',
89
+ ];
90
+ for (const row of rows) {
91
+ const prev = row.previousHash ? row.previousHash.slice(0, 8) : '-';
92
+ const curr = row.currentHash ? row.currentHash.slice(0, 8) : '-';
93
+ lines.push(`| ${row.specId} | ${row.file} | ${row.status} | ${prev} | ${curr} |`);
94
+ }
95
+ return lines.join('\n');
96
+ }
97
+ //# sourceMappingURL=dashboard-collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-collector.js","sourceRoot":"","sources":["../../../src/engine/living-spec/dashboard-collector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { DriftWatcherOptions, DriftWatcherInstance } from '../../types/index.js';
2
+ /**
3
+ * Simple glob-to-regex converter for exclude patterns.
4
+ * Supports *, **, and ? wildcards without external deps.
5
+ */
6
+ export declare function globToRegex(pattern: string): RegExp;
7
+ /**
8
+ * Check if a file path matches any exclude pattern.
9
+ */
10
+ export declare function matchesExcludePattern(filePath: string, patterns: string[]): boolean;
11
+ /**
12
+ * Create a drift watcher with in-memory caching and configurable TTL.
13
+ */
14
+ export declare function createDriftWatcher(options: DriftWatcherOptions): DriftWatcherInstance;
15
+ //# sourceMappingURL=drift-watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drift-watcher.d.ts","sourceRoot":"","sources":["../../../src/engine/living-spec/drift-watcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,mBAAmB,EAGnB,oBAAoB,EAErB,MAAM,sBAAsB,CAAC;AAI9B;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA0BnD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAEnF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,oBAAoB,CAsFrF"}