@planu/cli 0.43.0 → 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 (399) 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/docs-site-generator/spec-renderer.d.ts.map +1 -1
  153. package/dist/engine/docs-site-generator/spec-renderer.js +2 -1
  154. package/dist/engine/docs-site-generator/spec-renderer.js.map +1 -1
  155. package/dist/engine/execution-plan/agent-execution-plan.d.ts.map +1 -1
  156. package/dist/engine/execution-plan/agent-execution-plan.js +2 -0
  157. package/dist/engine/execution-plan/agent-execution-plan.js.map +1 -1
  158. package/dist/engine/hooks/config-loader.d.ts +36 -0
  159. package/dist/engine/hooks/config-loader.d.ts.map +1 -0
  160. package/dist/engine/hooks/config-loader.js +142 -0
  161. package/dist/engine/hooks/config-loader.js.map +1 -0
  162. package/dist/engine/hooks/debouncer.d.ts +30 -0
  163. package/dist/engine/hooks/debouncer.d.ts.map +1 -0
  164. package/dist/engine/hooks/debouncer.js +124 -0
  165. package/dist/engine/hooks/debouncer.js.map +1 -0
  166. package/dist/engine/hooks/event-bus.d.ts +40 -0
  167. package/dist/engine/hooks/event-bus.d.ts.map +1 -0
  168. package/dist/engine/hooks/event-bus.js +83 -0
  169. package/dist/engine/hooks/event-bus.js.map +1 -0
  170. package/dist/engine/hooks/file-watcher.d.ts +48 -0
  171. package/dist/engine/hooks/file-watcher.d.ts.map +1 -0
  172. package/dist/engine/hooks/file-watcher.js +193 -0
  173. package/dist/engine/hooks/file-watcher.js.map +1 -0
  174. package/dist/engine/hooks/handlers/on-commit.d.ts +26 -0
  175. package/dist/engine/hooks/handlers/on-commit.d.ts.map +1 -0
  176. package/dist/engine/hooks/handlers/on-commit.js +198 -0
  177. package/dist/engine/hooks/handlers/on-commit.js.map +1 -0
  178. package/dist/engine/hooks/handlers/on-create.d.ts +8 -0
  179. package/dist/engine/hooks/handlers/on-create.d.ts.map +1 -0
  180. package/dist/engine/hooks/handlers/on-create.js +30 -0
  181. package/dist/engine/hooks/handlers/on-create.js.map +1 -0
  182. package/dist/engine/hooks/handlers/on-delete.d.ts +9 -0
  183. package/dist/engine/hooks/handlers/on-delete.d.ts.map +1 -0
  184. package/dist/engine/hooks/handlers/on-delete.js +33 -0
  185. package/dist/engine/hooks/handlers/on-delete.js.map +1 -0
  186. package/dist/engine/hooks/handlers/on-save.d.ts +29 -0
  187. package/dist/engine/hooks/handlers/on-save.d.ts.map +1 -0
  188. package/dist/engine/hooks/handlers/on-save.js +118 -0
  189. package/dist/engine/hooks/handlers/on-save.js.map +1 -0
  190. package/dist/engine/hooks/handlers/on-test-pass.d.ts +33 -0
  191. package/dist/engine/hooks/handlers/on-test-pass.d.ts.map +1 -0
  192. package/dist/engine/hooks/handlers/on-test-pass.js +103 -0
  193. package/dist/engine/hooks/handlers/on-test-pass.js.map +1 -0
  194. package/dist/engine/hooks/hook-engine.d.ts +50 -0
  195. package/dist/engine/hooks/hook-engine.d.ts.map +1 -0
  196. package/dist/engine/hooks/hook-engine.js +159 -0
  197. package/dist/engine/hooks/hook-engine.js.map +1 -0
  198. package/dist/engine/hooks/index.d.ts +10 -0
  199. package/dist/engine/hooks/index.d.ts.map +1 -1
  200. package/dist/engine/hooks/index.js +12 -0
  201. package/dist/engine/hooks/index.js.map +1 -1
  202. package/dist/engine/living-spec/annotation-parser.d.ts +18 -0
  203. package/dist/engine/living-spec/annotation-parser.d.ts.map +1 -0
  204. package/dist/engine/living-spec/annotation-parser.js +105 -0
  205. package/dist/engine/living-spec/annotation-parser.js.map +1 -0
  206. package/dist/engine/living-spec/auto-reconciler.d.ts +28 -0
  207. package/dist/engine/living-spec/auto-reconciler.d.ts.map +1 -0
  208. package/dist/engine/living-spec/auto-reconciler.js +103 -0
  209. package/dist/engine/living-spec/auto-reconciler.js.map +1 -0
  210. package/dist/engine/living-spec/bidirectional-sync.d.ts +26 -0
  211. package/dist/engine/living-spec/bidirectional-sync.d.ts.map +1 -0
  212. package/dist/engine/living-spec/bidirectional-sync.js +160 -0
  213. package/dist/engine/living-spec/bidirectional-sync.js.map +1 -0
  214. package/dist/engine/living-spec/dashboard-collector.d.ts +22 -0
  215. package/dist/engine/living-spec/dashboard-collector.d.ts.map +1 -0
  216. package/dist/engine/living-spec/dashboard-collector.js +97 -0
  217. package/dist/engine/living-spec/dashboard-collector.js.map +1 -0
  218. package/dist/engine/living-spec/drift-watcher.d.ts +15 -0
  219. package/dist/engine/living-spec/drift-watcher.d.ts.map +1 -0
  220. package/dist/engine/living-spec/drift-watcher.js +126 -0
  221. package/dist/engine/living-spec/drift-watcher.js.map +1 -0
  222. package/dist/engine/living-spec/hash-tracker.d.ts +24 -0
  223. package/dist/engine/living-spec/hash-tracker.d.ts.map +1 -0
  224. package/dist/engine/living-spec/hash-tracker.js +123 -0
  225. package/dist/engine/living-spec/hash-tracker.js.map +1 -0
  226. package/dist/engine/living-spec/index.d.ts +9 -0
  227. package/dist/engine/living-spec/index.d.ts.map +1 -0
  228. package/dist/engine/living-spec/index.js +10 -0
  229. package/dist/engine/living-spec/index.js.map +1 -0
  230. package/dist/engine/living-spec/signature-tracker.d.ts +18 -0
  231. package/dist/engine/living-spec/signature-tracker.d.ts.map +1 -0
  232. package/dist/engine/living-spec/signature-tracker.js +136 -0
  233. package/dist/engine/living-spec/signature-tracker.js.map +1 -0
  234. package/dist/engine/living-spec/test-coverage-correlator.d.ts +22 -0
  235. package/dist/engine/living-spec/test-coverage-correlator.d.ts.map +1 -0
  236. package/dist/engine/living-spec/test-coverage-correlator.js +130 -0
  237. package/dist/engine/living-spec/test-coverage-correlator.js.map +1 -0
  238. package/dist/engine/llm-providers/cost-tracker.d.ts.map +1 -1
  239. package/dist/engine/llm-providers/cost-tracker.js +1 -0
  240. package/dist/engine/llm-providers/cost-tracker.js.map +1 -1
  241. package/dist/engine/llm-providers/load-balancer.d.ts.map +1 -1
  242. package/dist/engine/llm-providers/load-balancer.js +3 -0
  243. package/dist/engine/llm-providers/load-balancer.js.map +1 -1
  244. package/dist/engine/plugins/extensions/tool-extension.d.ts.map +1 -1
  245. package/dist/engine/plugins/extensions/tool-extension.js +1 -0
  246. package/dist/engine/plugins/extensions/tool-extension.js.map +1 -1
  247. package/dist/engine/plugins/extensions/worker-extension.d.ts.map +1 -1
  248. package/dist/engine/plugins/extensions/worker-extension.js +3 -1
  249. package/dist/engine/plugins/extensions/worker-extension.js.map +1 -1
  250. package/dist/engine/plugins/loader.d.ts.map +1 -1
  251. package/dist/engine/plugins/loader.js +3 -0
  252. package/dist/engine/plugins/loader.js.map +1 -1
  253. package/dist/engine/safety/file-mutex.d.ts.map +1 -1
  254. package/dist/engine/safety/file-mutex.js +3 -0
  255. package/dist/engine/safety/file-mutex.js.map +1 -1
  256. package/dist/engine/safety/health-monitor.d.ts.map +1 -1
  257. package/dist/engine/safety/health-monitor.js +3 -0
  258. package/dist/engine/safety/health-monitor.js.map +1 -1
  259. package/dist/engine/safety/transaction.d.ts.map +1 -1
  260. package/dist/engine/safety/transaction.js +3 -0
  261. package/dist/engine/safety/transaction.js.map +1 -1
  262. package/dist/engine/spec-templates/custom-loader.d.ts.map +1 -1
  263. package/dist/engine/spec-templates/custom-loader.js +1 -0
  264. package/dist/engine/spec-templates/custom-loader.js.map +1 -1
  265. package/dist/index.js +29 -0
  266. package/dist/index.js.map +1 -1
  267. package/dist/storage/hash-snapshot-store.d.ts +18 -0
  268. package/dist/storage/hash-snapshot-store.d.ts.map +1 -0
  269. package/dist/storage/hash-snapshot-store.js +43 -0
  270. package/dist/storage/hash-snapshot-store.js.map +1 -0
  271. package/dist/storage/index.d.ts +3 -0
  272. package/dist/storage/index.d.ts.map +1 -1
  273. package/dist/storage/index.js +3 -0
  274. package/dist/storage/index.js.map +1 -1
  275. package/dist/storage/living-dashboard-store.d.ts +10 -0
  276. package/dist/storage/living-dashboard-store.d.ts.map +1 -0
  277. package/dist/storage/living-dashboard-store.js +31 -0
  278. package/dist/storage/living-dashboard-store.js.map +1 -0
  279. package/dist/storage/sync-log-store.d.ts +26 -0
  280. package/dist/storage/sync-log-store.d.ts.map +1 -0
  281. package/dist/storage/sync-log-store.js +60 -0
  282. package/dist/storage/sync-log-store.js.map +1 -0
  283. package/dist/tools/auto-reconcile.d.ts +3 -0
  284. package/dist/tools/auto-reconcile.d.ts.map +1 -0
  285. package/dist/tools/auto-reconcile.js +81 -0
  286. package/dist/tools/auto-reconcile.js.map +1 -0
  287. package/dist/tools/challenge-spec/platform-challenge-scenarios-b2.d.ts.map +1 -1
  288. package/dist/tools/challenge-spec/platform-challenge-scenarios-b2.js +6 -0
  289. package/dist/tools/challenge-spec/platform-challenge-scenarios-b2.js.map +1 -1
  290. package/dist/tools/create-spec/spec-builder.js +2 -0
  291. package/dist/tools/create-spec/spec-builder.js.map +1 -1
  292. package/dist/tools/dashboard.d.ts.map +1 -1
  293. package/dist/tools/dashboard.js +20 -13
  294. package/dist/tools/dashboard.js.map +1 -1
  295. package/dist/tools/generate-annotations.d.ts +3 -0
  296. package/dist/tools/generate-annotations.d.ts.map +1 -0
  297. package/dist/tools/generate-annotations.js +70 -0
  298. package/dist/tools/generate-annotations.js.map +1 -0
  299. package/dist/tools/generate-execution-plan.d.ts.map +1 -1
  300. package/dist/tools/generate-execution-plan.js +1 -0
  301. package/dist/tools/generate-execution-plan.js.map +1 -1
  302. package/dist/tools/github-pr-handler.d.ts.map +1 -1
  303. package/dist/tools/github-pr-handler.js +1 -0
  304. package/dist/tools/github-pr-handler.js.map +1 -1
  305. package/dist/tools/github-review-handler.d.ts.map +1 -1
  306. package/dist/tools/github-review-handler.js +1 -0
  307. package/dist/tools/github-review-handler.js.map +1 -1
  308. package/dist/tools/ide-config-handler.d.ts.map +1 -1
  309. package/dist/tools/ide-config-handler.js +3 -0
  310. package/dist/tools/ide-config-handler.js.map +1 -1
  311. package/dist/tools/init-project/handler.d.ts.map +1 -1
  312. package/dist/tools/init-project/handler.js +0 -3
  313. package/dist/tools/init-project/handler.js.map +1 -1
  314. package/dist/tools/living-spec-coverage.d.ts +3 -0
  315. package/dist/tools/living-spec-coverage.d.ts.map +1 -0
  316. package/dist/tools/living-spec-coverage.js +100 -0
  317. package/dist/tools/living-spec-coverage.js.map +1 -0
  318. package/dist/tools/living-spec-watch.d.ts +4 -0
  319. package/dist/tools/living-spec-watch.d.ts.map +1 -0
  320. package/dist/tools/living-spec-watch.js +94 -0
  321. package/dist/tools/living-spec-watch.js.map +1 -0
  322. package/dist/tools/manage-plugins-handler.d.ts.map +1 -1
  323. package/dist/tools/manage-plugins-handler.js +2 -1
  324. package/dist/tools/manage-plugins-handler.js.map +1 -1
  325. package/dist/tools/orchestrate-distribution.d.ts.map +1 -1
  326. package/dist/tools/orchestrate-distribution.js +1 -0
  327. package/dist/tools/orchestrate-distribution.js.map +1 -1
  328. package/dist/tools/orchestrate-runtime.js +2 -0
  329. package/dist/tools/orchestrate-runtime.js.map +1 -1
  330. package/dist/tools/plan-team-distribution.d.ts.map +1 -1
  331. package/dist/tools/plan-team-distribution.js +2 -0
  332. package/dist/tools/plan-team-distribution.js.map +1 -1
  333. package/dist/tools/register-dashboard-tools.d.ts.map +1 -1
  334. package/dist/tools/register-dashboard-tools.js +5 -1
  335. package/dist/tools/register-dashboard-tools.js.map +1 -1
  336. package/dist/tools/register-hooks-tools.d.ts.map +1 -1
  337. package/dist/tools/register-hooks-tools.js +82 -1
  338. package/dist/tools/register-hooks-tools.js.map +1 -1
  339. package/dist/tools/register-living-spec-advanced-tools.d.ts +6 -0
  340. package/dist/tools/register-living-spec-advanced-tools.d.ts.map +1 -0
  341. package/dist/tools/register-living-spec-advanced-tools.js +113 -0
  342. package/dist/tools/register-living-spec-advanced-tools.js.map +1 -0
  343. package/dist/tools/register-living-spec-tools.d.ts +6 -0
  344. package/dist/tools/register-living-spec-tools.d.ts.map +1 -0
  345. package/dist/tools/register-living-spec-tools.js +67 -0
  346. package/dist/tools/register-living-spec-tools.js.map +1 -0
  347. package/dist/tools/resolve-sync-conflict.d.ts +3 -0
  348. package/dist/tools/resolve-sync-conflict.d.ts.map +1 -0
  349. package/dist/tools/resolve-sync-conflict.js +38 -0
  350. package/dist/tools/resolve-sync-conflict.js.map +1 -0
  351. package/dist/tools/snapshot-spec-hashes.d.ts +3 -0
  352. package/dist/tools/snapshot-spec-hashes.d.ts.map +1 -0
  353. package/dist/tools/snapshot-spec-hashes.js +100 -0
  354. package/dist/tools/snapshot-spec-hashes.js.map +1 -0
  355. package/dist/tools/spec-diff.d.ts +3 -0
  356. package/dist/tools/spec-diff.d.ts.map +1 -0
  357. package/dist/tools/spec-diff.js +58 -0
  358. package/dist/tools/spec-diff.js.map +1 -0
  359. package/dist/tools/start-hooks.d.ts +17 -0
  360. package/dist/tools/start-hooks.d.ts.map +1 -0
  361. package/dist/tools/start-hooks.js +209 -0
  362. package/dist/tools/start-hooks.js.map +1 -0
  363. package/dist/tools/suggest-tooling/catalog-loader.d.ts.map +1 -1
  364. package/dist/tools/suggest-tooling/catalog-loader.js +1 -0
  365. package/dist/tools/suggest-tooling/catalog-loader.js.map +1 -1
  366. package/dist/tools/sync-code-to-spec.d.ts +3 -0
  367. package/dist/tools/sync-code-to-spec.d.ts.map +1 -0
  368. package/dist/tools/sync-code-to-spec.js +51 -0
  369. package/dist/tools/sync-code-to-spec.js.map +1 -0
  370. package/dist/tools/sync-spec-to-code.d.ts +3 -0
  371. package/dist/tools/sync-spec-to-code.d.ts.map +1 -0
  372. package/dist/tools/sync-spec-to-code.js +58 -0
  373. package/dist/tools/sync-spec-to-code.js.map +1 -0
  374. package/dist/tools/validate-annotations.d.ts +3 -0
  375. package/dist/tools/validate-annotations.d.ts.map +1 -0
  376. package/dist/tools/validate-annotations.js +90 -0
  377. package/dist/tools/validate-annotations.js.map +1 -0
  378. package/dist/types/cli.d.ts +14 -0
  379. package/dist/types/cli.d.ts.map +1 -0
  380. package/dist/types/cli.js +3 -0
  381. package/dist/types/cli.js.map +1 -0
  382. package/dist/types/dashboard.d.ts +86 -1
  383. package/dist/types/dashboard.d.ts.map +1 -1
  384. package/dist/types/file-hooks.d.ts +230 -0
  385. package/dist/types/file-hooks.d.ts.map +1 -0
  386. package/dist/types/file-hooks.js +3 -0
  387. package/dist/types/file-hooks.js.map +1 -0
  388. package/dist/types/index.d.ts +3 -0
  389. package/dist/types/index.d.ts.map +1 -1
  390. package/dist/types/index.js +3 -0
  391. package/dist/types/index.js.map +1 -1
  392. package/dist/types/living-spec.d.ts +382 -0
  393. package/dist/types/living-spec.d.ts.map +1 -0
  394. package/dist/types/living-spec.js +3 -0
  395. package/dist/types/living-spec.js.map +1 -0
  396. package/package.json +1 -1
  397. package/src/config/hook-defaults.json +19 -0
  398. package/src/config/license-plans.json +16 -1
  399. package/src/config/tool-groups.json +12 -1
@@ -3,7 +3,7 @@ import { renderMarkdown } from './markdown-renderer.js';
3
3
  export function renderSpecPage(spec, specContent, technicalContent) {
4
4
  const tagsHtml = spec.tags.length > 0
5
5
  ? spec.tags.map((t) => `<span class="tag">${t}</span>`).join(' ')
6
- : '<span class="tag">none</span>';
6
+ : /* v8 ignore next -- empty tags fallback, specs typically have tags */ '<span class="tag">none</span>';
7
7
  return `<div class="spec-page">
8
8
  <header class="spec-header">
9
9
  <h1>${spec.id}: ${spec.title}</h1>
@@ -38,6 +38,7 @@ export function renderSpecPage(spec, specContent, technicalContent) {
38
38
  function groupByCategory(specs) {
39
39
  const groups = {};
40
40
  for (const spec of specs) {
41
+ /* v8 ignore next -- specs always have a category in practice */
41
42
  const cat = spec.category || '_general';
42
43
  const list = groups[cat];
43
44
  if (list) {
@@ -1 +1 @@
1
- {"version":3,"file":"spec-renderer.js","sourceRoot":"","sources":["../../../src/engine/docs-site-generator/spec-renderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,UAAU,cAAc,CAC5B,IAAoB,EACpB,WAAmB,EACnB,gBAAwB;IAExB,MAAM,QAAQ,GACZ,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QAClB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QACjE,CAAC,CAAC,+BAA+B,CAAC;IAEtC,OAAO;;UAEC,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,KAAK;MAC1B,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;MAC9B,iBAAiB,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC;;;;;;;YAOlD,cAAc,CAAC,WAAW,CAAC;;;;YAI3B,cAAc,CAAC,gBAAgB,CAAC;;;;;;;2BAOjB,IAAI,CAAC,IAAI;+BACL,IAAI,CAAC,QAAQ;2BACjB,QAAQ;+BACJ,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;;;;OAIjF,CAAC;AACR,CAAC;AAED,SAAS,eAAe,CAAC,KAAuB;IAC9C,MAAM,MAAM,GAAqC,EAAE,CAAC;IACpD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC;QACxC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAuB;IACrD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,oEAAoE,CAAC;IAC9E,CAAC;IAED,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;SACrC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE,EAAE;QACjC,MAAM,KAAK,GAAG,aAAa;aACxB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACZ,MAAM,UAAU,GAAG,GAAG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC;YAC5D,OAAO,+CAA+C,UAAU;iBACzD,IAAI,CAAC,IAAI;kBACR,IAAI,CAAC,EAAE,cAAc,IAAI,CAAC,KAAK;UACvC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;UAC9B,iBAAiB,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC;;WAEvD,CAAC;QACJ,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,OAAO;UACH,QAAQ;EAChB,KAAK;aACM,CAAC;IACV,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO;EACP,QAAQ;OACH,CAAC;AACR,CAAC"}
1
+ {"version":3,"file":"spec-renderer.js","sourceRoot":"","sources":["../../../src/engine/docs-site-generator/spec-renderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,MAAM,UAAU,cAAc,CAC5B,IAAoB,EACpB,WAAmB,EACnB,gBAAwB;IAExB,MAAM,QAAQ,GACZ,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;QAClB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QACjE,CAAC,CAAC,sEAAsE,CAAC,+BAA+B,CAAC;IAE7G,OAAO;;UAEC,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,KAAK;MAC1B,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;MAC9B,iBAAiB,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC;;;;;;;YAOlD,cAAc,CAAC,WAAW,CAAC;;;;YAI3B,cAAc,CAAC,gBAAgB,CAAC;;;;;;;2BAOjB,IAAI,CAAC,IAAI;+BACL,IAAI,CAAC,QAAQ;2BACjB,QAAQ;+BACJ,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC;;;;OAIjF,CAAC;AACR,CAAC;AAED,SAAS,eAAe,CAAC,KAAuB;IAC9C,MAAM,MAAM,GAAqC,EAAE,CAAC;IACpD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,gEAAgE;QAChE,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC;QACxC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAuB;IACrD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,oEAAoE,CAAC;IAC9E,CAAC;IAED,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;SACrC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE,EAAE;QACjC,MAAM,KAAK,GAAG,aAAa;aACxB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YACZ,MAAM,UAAU,GAAG,GAAG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,CAAC;YAC5D,OAAO,+CAA+C,UAAU;iBACzD,IAAI,CAAC,IAAI;kBACR,IAAI,CAAC,EAAE,cAAc,IAAI,CAAC,KAAK;UACvC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;UAC9B,iBAAiB,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC;;WAEvD,CAAC;QACJ,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,OAAO;UACH,QAAQ;EAChB,KAAK;aACM,CAAC;IACV,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO;EACP,QAAQ;OACH,CAAC;AACR,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"agent-execution-plan.d.ts","sourceRoot":"","sources":["../../../src/engine/execution-plan/agent-execution-plan.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAgC,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEvF,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAMxF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,gBAAgB,GAAG,cAAc,EAAE,CA8B3F"}
1
+ {"version":3,"file":"agent-execution-plan.d.ts","sourceRoot":"","sources":["../../../src/engine/execution-plan/agent-execution-plan.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAgC,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEvF,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAMxF;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,gBAAgB,GAAG,cAAc,EAAE,CAgC3F"}
@@ -32,11 +32,13 @@ export function generateAgentPlan(spec, knowledge) {
32
32
  const phaseBoundaries = [0, 2, 4, 5, 6, 7, 8];
33
33
  const phases = [];
34
34
  for (let i = 0; i < phaseNames.length; i++) {
35
+ /* v8 ignore next 2 -- nullish fallbacks are defensive, arrays always have values */
35
36
  const start = phaseBoundaries[i] ?? 0;
36
37
  const end = phaseBoundaries[i + 1] ?? steps.length;
37
38
  const phaseSteps = steps.slice(start, end);
38
39
  if (phaseSteps.length > 0) {
39
40
  phases.push({
41
+ /* v8 ignore next -- phaseNames[i] always defined within loop bounds */
40
42
  name: phaseNames[i] ?? `Phase ${i + 1}`,
41
43
  steps: phaseSteps,
42
44
  });
@@ -1 +1 @@
1
- {"version":3,"file":"agent-execution-plan.js","sourceRoot":"","sources":["../../../src/engine/execution-plan/agent-execution-plan.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,+DAA+D;AAC/D,+FAA+F;AAG/F,OAAO,EAAE,4BAA4B,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEvF,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAU,EAAE,SAA2B;IAC7E,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,YAAY,GAAG,CAAC,mBAAmB,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC7F,OAAO,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAU,EAAE,SAA2B;IACvE,MAAM,KAAK,GAAG,4BAA4B,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;IAE/D,MAAM,UAAU,GAAG;QACjB,YAAY;QACZ,mBAAmB;QACnB,qBAAqB;QACrB,SAAS;QACT,YAAY;QACZ,YAAY;KACb,CAAC;IAEF,mEAAmE;IACnE,MAAM,eAAe,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAqB,EAAE,CAAC;IAEpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC;QACnD,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAE3C,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE;gBACvC,KAAK,EAAE,UAAU;aAClB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"agent-execution-plan.js","sourceRoot":"","sources":["../../../src/engine/execution-plan/agent-execution-plan.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,+DAA+D;AAC/D,+FAA+F;AAG/F,OAAO,EAAE,4BAA4B,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEvF,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAU,EAAE,SAA2B;IAC7E,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,YAAY,GAAG,CAAC,mBAAmB,EAAE,cAAc,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;IAC7F,OAAO,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAChG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAU,EAAE,SAA2B;IACvE,MAAM,KAAK,GAAG,4BAA4B,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;IAE/D,MAAM,UAAU,GAAG;QACjB,YAAY;QACZ,mBAAmB;QACnB,qBAAqB;QACrB,SAAS;QACT,YAAY;QACZ,YAAY;KACb,CAAC;IAEF,mEAAmE;IACnE,MAAM,eAAe,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAqB,EAAE,CAAC;IAEpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,oFAAoF;QACpF,MAAM,KAAK,GAAG,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,GAAG,GAAG,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC;QACnD,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAE3C,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC;gBACV,uEAAuE;gBACvE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE;gBACvC,KAAK,EAAE,UAAU;aAClB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { FileHookConfig, FileHookTypeConfig, ConfigChangeCallback } from '../../types/file-hooks.js';
2
+ export declare class ConfigLoader {
3
+ private config;
4
+ private readonly projectRoot;
5
+ private watcher;
6
+ private changeCallbacks;
7
+ constructor(projectRoot: string);
8
+ /**
9
+ * Load config from `.planu/hooks.json` or `planu.json`.
10
+ * Falls back to defaults if file missing or invalid.
11
+ */
12
+ load(): Promise<FileHookConfig>;
13
+ /**
14
+ * Get current config (synchronous, must call load() first).
15
+ */
16
+ getConfig(): FileHookConfig;
17
+ /**
18
+ * Get config for a specific hook type.
19
+ */
20
+ getHookConfig(hookType: string): FileHookTypeConfig | undefined;
21
+ /**
22
+ * Start watching config files for live reload.
23
+ */
24
+ startWatching(): void;
25
+ /**
26
+ * Register a callback for config changes.
27
+ */
28
+ onChange(callback: ConfigChangeCallback): void;
29
+ /**
30
+ * Stop watching and clean up.
31
+ */
32
+ close(): void;
33
+ private reloadConfig;
34
+ private readJsonFile;
35
+ }
36
+ //# sourceMappingURL=config-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../../src/engine/hooks/config-loader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACrB,MAAM,2BAA2B,CAAC;AAoCnC,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,eAAe,CAA8B;gBAEzC,WAAW,EAAE,MAAM;IAK/B;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,cAAc,CAAC;IAgCrC;;OAEG;IACH,SAAS,IAAI,cAAc;IAI3B;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAI/D;;OAEG;IACH,aAAa,IAAI,IAAI;IAcrB;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAI9C;;OAEG;IACH,KAAK,IAAI,IAAI;YAYC,YAAY;YAWZ,YAAY;CAQ3B"}
@@ -0,0 +1,142 @@
1
+ // engine/hooks/config-loader.ts — Load & validate hook config with live reload (SPEC-129)
2
+ import { watch as fsWatch } from 'node:fs';
3
+ import { readFile } from 'node:fs/promises';
4
+ import { join } from 'node:path';
5
+ import { z } from 'zod';
6
+ // ---------------------------------------------------------------------------
7
+ // Default config (matches hook-defaults.json)
8
+ // ---------------------------------------------------------------------------
9
+ import hookDefaults from '../../config/hook-defaults.json' with { type: 'json' };
10
+ // ---------------------------------------------------------------------------
11
+ // Zod schemas
12
+ // ---------------------------------------------------------------------------
13
+ const hookTypeConfigSchema = z.object({
14
+ enabled: z.boolean().default(true),
15
+ include: z.array(z.string()).optional(),
16
+ exclude: z.array(z.string()).optional(),
17
+ });
18
+ const fileHookConfigSchema = z.object({
19
+ enabled: z.boolean().default(true),
20
+ debounceMs: z.number().min(50).max(10_000).default(300),
21
+ rateLimitPerFileMs: z.number().min(1000).max(60_000).default(5000),
22
+ hooks: z.record(z.string(), hookTypeConfigSchema).default({}),
23
+ });
24
+ // ---------------------------------------------------------------------------
25
+ // Config file paths
26
+ // ---------------------------------------------------------------------------
27
+ const HOOKS_JSON = '.planu/hooks.json';
28
+ const PLANU_JSON = 'planu.json';
29
+ // ---------------------------------------------------------------------------
30
+ // ConfigLoader
31
+ // ---------------------------------------------------------------------------
32
+ export class ConfigLoader {
33
+ config;
34
+ projectRoot;
35
+ watcher = null;
36
+ changeCallbacks = [];
37
+ constructor(projectRoot) {
38
+ this.projectRoot = projectRoot;
39
+ this.config = hookDefaults;
40
+ }
41
+ /**
42
+ * Load config from `.planu/hooks.json` or `planu.json`.
43
+ * Falls back to defaults if file missing or invalid.
44
+ */
45
+ async load() {
46
+ // Try .planu/hooks.json first
47
+ let raw = await this.readJsonFile(join(this.projectRoot, HOOKS_JSON));
48
+ // Try planu.json -> hooks key
49
+ if (!raw) {
50
+ const planuJson = await this.readJsonFile(join(this.projectRoot, PLANU_JSON));
51
+ if (planuJson &&
52
+ typeof planuJson === 'object' &&
53
+ 'hooks' in planuJson) {
54
+ raw = planuJson.hooks;
55
+ }
56
+ }
57
+ if (raw) {
58
+ const parsed = fileHookConfigSchema.safeParse(raw);
59
+ if (parsed.success) {
60
+ this.config = parsed.data;
61
+ }
62
+ else {
63
+ const messages = parsed.error.issues.map((i) => i.message).join(', ');
64
+ console.warn(`[hooks] Invalid hook config, using defaults: ${messages}`);
65
+ this.config = hookDefaults;
66
+ }
67
+ }
68
+ else {
69
+ this.config = hookDefaults;
70
+ }
71
+ return this.config;
72
+ }
73
+ /**
74
+ * Get current config (synchronous, must call load() first).
75
+ */
76
+ getConfig() {
77
+ return this.config;
78
+ }
79
+ /**
80
+ * Get config for a specific hook type.
81
+ */
82
+ getHookConfig(hookType) {
83
+ return this.config.hooks[hookType];
84
+ }
85
+ /**
86
+ * Start watching config files for live reload.
87
+ */
88
+ startWatching() {
89
+ const hooksJsonPath = join(this.projectRoot, HOOKS_JSON);
90
+ try {
91
+ this.watcher = fsWatch(hooksJsonPath, () => {
92
+ void this.reloadConfig();
93
+ });
94
+ this.watcher.on('error', () => {
95
+ // Ignore watch errors — config just won't live-reload
96
+ });
97
+ }
98
+ catch {
99
+ // File doesn't exist yet — that's fine
100
+ }
101
+ }
102
+ /**
103
+ * Register a callback for config changes.
104
+ */
105
+ onChange(callback) {
106
+ this.changeCallbacks.push(callback);
107
+ }
108
+ /**
109
+ * Stop watching and clean up.
110
+ */
111
+ close() {
112
+ if (this.watcher) {
113
+ this.watcher.close();
114
+ this.watcher = null;
115
+ }
116
+ this.changeCallbacks = [];
117
+ }
118
+ // ---------------------------------------------------------------------------
119
+ // Private
120
+ // ---------------------------------------------------------------------------
121
+ async reloadConfig() {
122
+ try {
123
+ await this.load();
124
+ for (const cb of this.changeCallbacks) {
125
+ cb(this.config);
126
+ }
127
+ }
128
+ catch {
129
+ // Ignore reload errors — keep previous config
130
+ }
131
+ }
132
+ async readJsonFile(filePath) {
133
+ try {
134
+ const data = await readFile(filePath, 'utf-8');
135
+ return JSON.parse(data);
136
+ }
137
+ catch {
138
+ return null;
139
+ }
140
+ }
141
+ }
142
+ //# sourceMappingURL=config-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../../src/engine/hooks/config-loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import type { WatcherEvent, DebouncerConfig, DebouncedCallback } from '../../types/file-hooks.js';
2
+ export declare class Debouncer {
3
+ private readonly config;
4
+ /** Pending debounce timers per file path */
5
+ private readonly pendingTimers;
6
+ /** Pending event per file (latest wins) */
7
+ private readonly pendingEvents;
8
+ /** Rate limit buckets per file path */
9
+ private readonly fileBuckets;
10
+ /** Rate limit buckets per spec ID */
11
+ private readonly specBuckets;
12
+ private readonly callback;
13
+ constructor(callback: DebouncedCallback, config?: Partial<DebouncerConfig>);
14
+ /**
15
+ * Feed a raw watcher event. The debouncer will coalesce rapid events
16
+ * and apply rate limiting before invoking the callback.
17
+ */
18
+ push(event: WatcherEvent): void;
19
+ /**
20
+ * Check spec-level rate limit for auto-reconcile.
21
+ * Returns true if allowed, false if rate-limited.
22
+ */
23
+ checkSpecRateLimit(specId: string): boolean;
24
+ /**
25
+ * Cancel all pending timers and clear state.
26
+ */
27
+ dispose(): void;
28
+ private tryEmit;
29
+ }
30
+ //# sourceMappingURL=debouncer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debouncer.d.ts","sourceRoot":"","sources":["../../../src/engine/hooks/debouncer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,YAAY,EAEZ,eAAe,EACf,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AA4CnC,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,4CAA4C;IAC5C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoD;IAClF,2CAA2C;IAC3C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAmC;IACjE,uCAAuC;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;IAC9D,qCAAqC;IACrC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;IAC9D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoB;gBAEjC,QAAQ,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAK1E;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAyB/B;;;OAGG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAU3C;;OAEG;IACH,OAAO,IAAI,IAAI;IAcf,OAAO,CAAC,OAAO;CAkBhB"}
@@ -0,0 +1,124 @@
1
+ // engine/hooks/debouncer.ts — Debounce + rate limit for file events (SPEC-129)
2
+ // 300ms debounce per file, global rate limit per file per 5s,
3
+ // per-spec rate limit per 5 min. Token bucket algorithm.
4
+ // ---------------------------------------------------------------------------
5
+ // Token Bucket helpers
6
+ // ---------------------------------------------------------------------------
7
+ function createBucket(capacity, refillIntervalMs) {
8
+ return {
9
+ tokens: capacity,
10
+ lastRefill: Date.now(),
11
+ capacity,
12
+ refillIntervalMs,
13
+ };
14
+ }
15
+ function tryConsume(bucket, now) {
16
+ // Refill tokens based on elapsed time
17
+ const elapsed = now - bucket.lastRefill;
18
+ const tokensToAdd = Math.floor(elapsed / bucket.refillIntervalMs);
19
+ if (tokensToAdd > 0) {
20
+ const updated = {
21
+ ...bucket,
22
+ tokens: Math.min(bucket.capacity, bucket.tokens + tokensToAdd),
23
+ lastRefill: now,
24
+ };
25
+ Object.assign(bucket, updated);
26
+ }
27
+ if (bucket.tokens > 0) {
28
+ Object.assign(bucket, { tokens: bucket.tokens - 1 });
29
+ return true;
30
+ }
31
+ return false;
32
+ }
33
+ // ---------------------------------------------------------------------------
34
+ // Debouncer
35
+ // ---------------------------------------------------------------------------
36
+ const DEFAULT_CONFIG = {
37
+ debounceMs: 300,
38
+ rateLimitPerFileMs: 5000,
39
+ rateLimitPerSpecMs: 300_000,
40
+ };
41
+ export class Debouncer {
42
+ config;
43
+ /** Pending debounce timers per file path */
44
+ pendingTimers = new Map();
45
+ /** Pending event per file (latest wins) */
46
+ pendingEvents = new Map();
47
+ /** Rate limit buckets per file path */
48
+ fileBuckets = new Map();
49
+ /** Rate limit buckets per spec ID */
50
+ specBuckets = new Map();
51
+ callback;
52
+ constructor(callback, config) {
53
+ this.callback = callback;
54
+ this.config = { ...DEFAULT_CONFIG, ...config };
55
+ }
56
+ /**
57
+ * Feed a raw watcher event. The debouncer will coalesce rapid events
58
+ * and apply rate limiting before invoking the callback.
59
+ */
60
+ push(event) {
61
+ const key = event.path;
62
+ // Store the latest event (coalescing — last wins)
63
+ this.pendingEvents.set(key, event);
64
+ // Clear existing timer for this path
65
+ const existing = this.pendingTimers.get(key);
66
+ if (existing !== undefined) {
67
+ clearTimeout(existing);
68
+ }
69
+ // Set new debounce timer
70
+ const timer = setTimeout(() => {
71
+ this.pendingTimers.delete(key);
72
+ const latest = this.pendingEvents.get(key);
73
+ this.pendingEvents.delete(key);
74
+ if (latest) {
75
+ this.tryEmit(latest);
76
+ }
77
+ }, this.config.debounceMs);
78
+ this.pendingTimers.set(key, timer);
79
+ }
80
+ /**
81
+ * Check spec-level rate limit for auto-reconcile.
82
+ * Returns true if allowed, false if rate-limited.
83
+ */
84
+ checkSpecRateLimit(specId) {
85
+ const now = Date.now();
86
+ let bucket = this.specBuckets.get(specId);
87
+ if (!bucket) {
88
+ bucket = createBucket(1, this.config.rateLimitPerSpecMs);
89
+ this.specBuckets.set(specId, bucket);
90
+ }
91
+ return tryConsume(bucket, now);
92
+ }
93
+ /**
94
+ * Cancel all pending timers and clear state.
95
+ */
96
+ dispose() {
97
+ for (const timer of this.pendingTimers.values()) {
98
+ clearTimeout(timer);
99
+ }
100
+ this.pendingTimers.clear();
101
+ this.pendingEvents.clear();
102
+ this.fileBuckets.clear();
103
+ this.specBuckets.clear();
104
+ }
105
+ // ---------------------------------------------------------------------------
106
+ // Private
107
+ // ---------------------------------------------------------------------------
108
+ tryEmit(event) {
109
+ const now = Date.now();
110
+ const key = event.path;
111
+ // File-level rate limit
112
+ let bucket = this.fileBuckets.get(key);
113
+ if (!bucket) {
114
+ bucket = createBucket(1, this.config.rateLimitPerFileMs);
115
+ this.fileBuckets.set(key, bucket);
116
+ }
117
+ if (!tryConsume(bucket, now)) {
118
+ // Rate limited — drop the event
119
+ return;
120
+ }
121
+ this.callback(event);
122
+ }
123
+ }
124
+ //# sourceMappingURL=debouncer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debouncer.js","sourceRoot":"","sources":["../../../src/engine/hooks/debouncer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { EventBusEvent } from '../../types/file-hooks.js';
3
+ /**
4
+ * Typed event bus extending EventEmitter.
5
+ * Provides typed events with discriminated unions, filtering,
6
+ * event history (FIFO, last 100), and meta-events.
7
+ */
8
+ export declare class EventBus extends EventEmitter {
9
+ private readonly history;
10
+ private idCounter;
11
+ constructor();
12
+ /**
13
+ * Emit a typed event. Automatically adds to history and fires meta-events.
14
+ */
15
+ emitEvent(type: EventBusEvent['type'], data: Record<string, unknown>): EventBusEvent;
16
+ /**
17
+ * Subscribe to events of a specific type.
18
+ */
19
+ onEvent(type: EventBusEvent['type'] | '*', listener: (event: EventBusEvent) => void): this;
20
+ /**
21
+ * Subscribe to events once.
22
+ */
23
+ onceEvent(type: EventBusEvent['type'] | '*', listener: (event: EventBusEvent) => void): this;
24
+ /**
25
+ * Get filtered event history.
26
+ */
27
+ getHistory(filter?: {
28
+ type?: EventBusEvent['type'];
29
+ filePattern?: string;
30
+ }): EventBusEvent[];
31
+ /**
32
+ * Get all events in history (readonly).
33
+ */
34
+ getFullHistory(): readonly EventBusEvent[];
35
+ /**
36
+ * Clear history.
37
+ */
38
+ clearHistory(): void;
39
+ }
40
+ //# sourceMappingURL=event-bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../../src/engine/hooks/event-bus.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAY/D;;;;GAIG;AACH,qBAAa,QAAS,SAAQ,YAAY;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,SAAS,CAAK;;IAOtB;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa;IAoBpF;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI;IAI1F;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,GAAG,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,IAAI;IAI5F;;OAEG;IACH,UAAU,CAAC,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,aAAa,EAAE;IAkB5F;;OAEG;IACH,cAAc,IAAI,SAAS,aAAa,EAAE;IAI1C;;OAEG;IACH,YAAY,IAAI,IAAI;CAGrB"}
@@ -0,0 +1,83 @@
1
+ // engine/hooks/event-bus.ts — Typed event bus with history (SPEC-130)
2
+ import { EventEmitter } from 'node:events';
3
+ // ---------------------------------------------------------------------------
4
+ // Constants
5
+ // ---------------------------------------------------------------------------
6
+ const MAX_HISTORY = 100;
7
+ // ---------------------------------------------------------------------------
8
+ // EventBus
9
+ // ---------------------------------------------------------------------------
10
+ /**
11
+ * Typed event bus extending EventEmitter.
12
+ * Provides typed events with discriminated unions, filtering,
13
+ * event history (FIFO, last 100), and meta-events.
14
+ */
15
+ export class EventBus extends EventEmitter {
16
+ history = [];
17
+ idCounter = 0;
18
+ constructor() {
19
+ super();
20
+ this.setMaxListeners(50);
21
+ }
22
+ /**
23
+ * Emit a typed event. Automatically adds to history and fires meta-events.
24
+ */
25
+ emitEvent(type, data) {
26
+ const event = {
27
+ id: `evt-${String(++this.idCounter)}-${Date.now()}`,
28
+ type,
29
+ timestamp: Date.now(),
30
+ data,
31
+ };
32
+ // FIFO eviction
33
+ if (this.history.length >= MAX_HISTORY) {
34
+ this.history.shift();
35
+ }
36
+ this.history.push(event);
37
+ this.emit(type, event);
38
+ this.emit('*', event);
39
+ return event;
40
+ }
41
+ /**
42
+ * Subscribe to events of a specific type.
43
+ */
44
+ onEvent(type, listener) {
45
+ return this.on(type, listener);
46
+ }
47
+ /**
48
+ * Subscribe to events once.
49
+ */
50
+ onceEvent(type, listener) {
51
+ return this.once(type, listener);
52
+ }
53
+ /**
54
+ * Get filtered event history.
55
+ */
56
+ getHistory(filter) {
57
+ let result = [...this.history];
58
+ if (filter?.type) {
59
+ result = result.filter((e) => e.type === filter.type);
60
+ }
61
+ if (filter?.filePattern) {
62
+ const regex = new RegExp(filter.filePattern);
63
+ result = result.filter((e) => {
64
+ const path = e.data.path;
65
+ return typeof path === 'string' && regex.test(path);
66
+ });
67
+ }
68
+ return result;
69
+ }
70
+ /**
71
+ * Get all events in history (readonly).
72
+ */
73
+ getFullHistory() {
74
+ return this.history;
75
+ }
76
+ /**
77
+ * Clear history.
78
+ */
79
+ clearHistory() {
80
+ this.history.length = 0;
81
+ }
82
+ }
83
+ //# sourceMappingURL=event-bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-bus.js","sourceRoot":"","sources":["../../../src/engine/hooks/event-bus.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,8EAA8E;AAC9E,YAAY;AACZ,8EAA8E;AAE9E,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB,8EAA8E;AAC9E,WAAW;AACX,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,OAAO,QAAS,SAAQ,YAAY;IACvB,OAAO,GAAoB,EAAE,CAAC;IACvC,SAAS,GAAG,CAAC,CAAC;IAEtB;QACE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,IAA2B,EAAE,IAA6B;QAClE,MAAM,KAAK,GAAkB;YAC3B,EAAE,EAAE,OAAO,MAAM,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE;YACnD,IAAI;YACJ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,IAAI;SACL,CAAC;QAEF,gBAAgB;QAChB,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,WAAW,EAAE,CAAC;YACvC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAEtB,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,IAAiC,EAAE,QAAwC;QACjF,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,IAAiC,EAAE,QAAwC;QACnF,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,MAA+D;QACxE,IAAI,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QAE/B,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC;YACjB,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC;QACxD,CAAC;QAED,IAAI,MAAM,EAAE,WAAW,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAC7C,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;gBAC3B,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;gBACzB,OAAO,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtD,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,YAAY;QACV,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1B,CAAC;CACF"}
@@ -0,0 +1,48 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { FileWatcherOptions } from '../../types/file-hooks.js';
3
+ /**
4
+ * Convert a glob pattern to a RegExp. Supports:
5
+ * - `**` matches any path segment (including nested)
6
+ * - `*` matches any characters except path separator
7
+ * - `?` matches a single character
8
+ */
9
+ export declare function globToRegex(pattern: string): RegExp;
10
+ /**
11
+ * Test whether `filePath` matches a glob pattern.
12
+ */
13
+ export declare function matchesGlobPattern(filePath: string, pattern: string): boolean;
14
+ /**
15
+ * Returns true if filePath matches any include pattern
16
+ * and does not match any exclude pattern.
17
+ */
18
+ export declare function matchesPatterns(filePath: string, include?: string[], exclude?: string[]): boolean;
19
+ export declare class FileWatcher extends EventEmitter {
20
+ private watcher;
21
+ private readonly rootDir;
22
+ private readonly include;
23
+ private readonly exclude;
24
+ /** Track known files to distinguish create vs modify */
25
+ private readonly knownFiles;
26
+ private closed;
27
+ constructor(options: FileWatcherOptions);
28
+ /**
29
+ * Start watching. Emits 'change' events with WatcherEvent payloads.
30
+ * Emits 'error' on watch failure — never throws.
31
+ */
32
+ start(): void;
33
+ /**
34
+ * Mark a file as known (pre-existing). Call this for initial file scan.
35
+ */
36
+ addKnownFile(relPath: string): void;
37
+ /**
38
+ * Mark multiple files as known.
39
+ */
40
+ addKnownFiles(paths: string[]): void;
41
+ /**
42
+ * Graceful shutdown: release all handles.
43
+ */
44
+ close(): void;
45
+ private handleFsEvent;
46
+ private determineEventType;
47
+ }
48
+ //# sourceMappingURL=file-watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-watcher.d.ts","sourceRoot":"","sources":["../../../src/engine/hooks/file-watcher.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,KAAK,EAAkC,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAMpG;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA6BnD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAG7E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAYjG;AAYD,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,OAAO,CAA0B;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAW;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAW;IACnC,wDAAwD;IACxD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,kBAAkB;IAOvC;;;OAGG;IACH,KAAK,IAAI,IAAI;IAqBb;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAInC;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAMpC;;OAEG;IACH,KAAK,IAAI,IAAI;YAaC,aAAa;YA4Bb,kBAAkB;CAoBjC"}