@sienklogic/plan-build-run 2.19.0 → 2.19.2

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 (951) hide show
  1. package/CHANGELOG.md +1287 -303
  2. package/CLAUDE.md +74 -39
  3. package/LICENSE +2 -1
  4. package/README.md +412 -177
  5. package/bin/install.js +2752 -0
  6. package/dashboard/bin/cli.cjs +96 -0
  7. package/dashboard/bin/stop.cjs +129 -0
  8. package/dashboard/eslint.config.js +37 -0
  9. package/dashboard/index.html +20 -0
  10. package/dashboard/package.json +27 -25
  11. package/dashboard/server/index.js +151 -0
  12. package/dashboard/server/lib/frontmatter.js +92 -0
  13. package/dashboard/server/middleware/static.js +35 -0
  14. package/dashboard/server/package.json +16 -0
  15. package/dashboard/server/routes/agents.js +234 -0
  16. package/dashboard/server/routes/config.js +64 -0
  17. package/dashboard/server/routes/health.js +98 -0
  18. package/dashboard/server/routes/incidents.js +78 -0
  19. package/dashboard/server/routes/intel.js +69 -0
  20. package/dashboard/server/routes/memory.js +107 -0
  21. package/dashboard/server/routes/planning.js +234 -0
  22. package/dashboard/server/routes/progress.js +77 -0
  23. package/dashboard/server/routes/projects.js +36 -0
  24. package/dashboard/server/routes/requirements.js +40 -0
  25. package/dashboard/server/routes/roadmap.js +69 -0
  26. package/dashboard/server/routes/sessions.js +70 -0
  27. package/dashboard/server/routes/status.js +25 -0
  28. package/dashboard/server/routes/telemetry.js +233 -0
  29. package/dashboard/server/services/file-watcher.js +105 -0
  30. package/dashboard/server/services/planning-reader.js +727 -0
  31. package/dashboard/server/test/cli.test.js +34 -0
  32. package/dashboard/server/test/frontmatter.test.js +104 -0
  33. package/dashboard/server/test/isolation.test.js +32 -0
  34. package/dashboard/server/test/planning-reader.test.js +151 -0
  35. package/dashboard/server/test/routes.test.js +91 -0
  36. package/dashboard/server/test/ws.test.js +81 -0
  37. package/dashboard/server/ws.js +96 -0
  38. package/dashboard/src/App.jsx +165 -0
  39. package/dashboard/src/components/charts/BudgetBars.jsx +42 -0
  40. package/dashboard/src/components/charts/ContextRadar.jsx +34 -0
  41. package/dashboard/src/components/charts/PhaseDonut.jsx +66 -0
  42. package/dashboard/src/components/charts/SuccessTrend.jsx +45 -0
  43. package/dashboard/src/components/charts/TokenChart.jsx +55 -0
  44. package/dashboard/src/components/charts/index.js +5 -0
  45. package/dashboard/src/components/config/CfgSection.jsx +93 -0
  46. package/dashboard/src/components/layout/Header.jsx +89 -0
  47. package/dashboard/src/components/layout/ProjectSwitcher.jsx +160 -0
  48. package/dashboard/src/components/layout/Sidebar.jsx +161 -0
  49. package/dashboard/src/components/ui/AutoModeBanner.jsx +138 -0
  50. package/dashboard/src/components/ui/BackButton.jsx +27 -0
  51. package/dashboard/src/components/ui/Badge.jsx +27 -0
  52. package/dashboard/src/components/ui/Card.jsx +23 -0
  53. package/dashboard/src/components/ui/ChartTooltip.jsx +48 -0
  54. package/dashboard/src/components/ui/CheckpointBox.jsx +110 -0
  55. package/dashboard/src/components/ui/CodeBlock.jsx +27 -0
  56. package/dashboard/src/components/ui/ConfidenceBadge.jsx +20 -0
  57. package/dashboard/src/components/ui/ConfirmModal.jsx +161 -0
  58. package/dashboard/src/components/ui/ConnectionBanner.jsx +60 -0
  59. package/dashboard/src/components/ui/ErrorBoundary.jsx +106 -0
  60. package/dashboard/src/components/ui/ErrorBox.jsx +107 -0
  61. package/dashboard/src/components/ui/KeyValue.jsx +33 -0
  62. package/dashboard/src/components/ui/LoadingSkeleton.jsx +84 -0
  63. package/dashboard/src/components/ui/MetricCard.jsx +58 -0
  64. package/dashboard/src/components/ui/NextUpBlock.jsx +92 -0
  65. package/dashboard/src/components/ui/NumberInput.jsx +44 -0
  66. package/dashboard/src/components/ui/PBRBanner.jsx +47 -0
  67. package/dashboard/src/components/ui/PipelineView.jsx +130 -0
  68. package/dashboard/src/components/ui/ProgressBar.jsx +28 -0
  69. package/dashboard/src/components/ui/ProgressDisplay.jsx +47 -0
  70. package/dashboard/src/components/ui/QualityGateBadge.jsx +15 -0
  71. package/dashboard/src/components/ui/SectionTitle.jsx +35 -0
  72. package/dashboard/src/components/ui/SelectInput.jsx +45 -0
  73. package/dashboard/src/components/ui/StatusDot.jsx +51 -0
  74. package/dashboard/src/components/ui/StatusSymbol.jsx +49 -0
  75. package/dashboard/src/components/ui/TabBar.jsx +41 -0
  76. package/dashboard/src/components/ui/TextInput.jsx +42 -0
  77. package/dashboard/src/components/ui/Toast.jsx +117 -0
  78. package/dashboard/src/components/ui/Toggle.jsx +70 -0
  79. package/dashboard/src/components/ui/index.js +29 -0
  80. package/dashboard/src/hooks/useDocumentTitle.js +16 -0
  81. package/dashboard/src/hooks/useFetch.js +50 -0
  82. package/dashboard/src/hooks/useToast.jsx +43 -0
  83. package/dashboard/src/hooks/useWebSocket.js +103 -0
  84. package/dashboard/src/lib/api.js +112 -0
  85. package/dashboard/src/lib/configSchema.js +189 -0
  86. package/dashboard/src/lib/constants.js +22 -0
  87. package/dashboard/src/main.jsx +15 -0
  88. package/dashboard/src/pages/AgentsPage.jsx +191 -0
  89. package/dashboard/src/pages/ConfigPage.jsx +298 -0
  90. package/dashboard/src/pages/HooksPage.jsx +412 -0
  91. package/dashboard/src/pages/IncidentsPage.jsx +135 -0
  92. package/dashboard/src/pages/IntelPage.jsx +193 -0
  93. package/dashboard/src/pages/LiveFeed.jsx +274 -0
  94. package/dashboard/src/pages/MemoryPage.jsx +107 -0
  95. package/dashboard/src/pages/OnboardingPage.jsx +117 -0
  96. package/dashboard/src/pages/Overview.jsx +360 -0
  97. package/dashboard/src/pages/PhaseDetailView.jsx +216 -0
  98. package/dashboard/src/pages/PlanningPage.jsx +181 -0
  99. package/dashboard/src/pages/ProgressPage.jsx +249 -0
  100. package/dashboard/src/pages/ResearchPage.jsx +129 -0
  101. package/dashboard/src/pages/RoadmapPage.jsx +251 -0
  102. package/dashboard/src/pages/SessionsPage.jsx +117 -0
  103. package/dashboard/src/pages/Telemetry.jsx +166 -0
  104. package/dashboard/src/pages/planning/DecisionsTab.jsx +153 -0
  105. package/dashboard/src/pages/planning/FilesTab.jsx +420 -0
  106. package/dashboard/src/pages/planning/MilestoneDetail.jsx +319 -0
  107. package/dashboard/src/pages/planning/MilestonesTab.jsx +151 -0
  108. package/dashboard/src/pages/planning/NotesTab.jsx +251 -0
  109. package/dashboard/src/pages/planning/PhasesTab.jsx +218 -0
  110. package/dashboard/src/pages/planning/QuickTab.jsx +50 -0
  111. package/dashboard/src/pages/planning/ResearchTab.jsx +103 -0
  112. package/dashboard/src/pages/planning/TodosTab.jsx +297 -0
  113. package/dashboard/src/theme/ThemeProvider.jsx +38 -0
  114. package/dashboard/src/theme/tokens.js +17 -0
  115. package/dashboard/tests/components/ConfirmModal.test.jsx +179 -0
  116. package/dashboard/tests/components/ConnectionBanner.test.jsx +37 -0
  117. package/dashboard/tests/components/ErrorBoundary.test.jsx +59 -0
  118. package/dashboard/tests/components/LoadingSkeleton.test.jsx +46 -0
  119. package/dashboard/tests/components/ToastContainer.test.jsx +47 -0
  120. package/dashboard/tests/components/Toggle.test.jsx +61 -0
  121. package/dashboard/tests/hooks/useFetch.test.jsx +77 -0
  122. package/dashboard/tests/hooks/useToast.test.jsx +78 -0
  123. package/dashboard/tests/hooks/useWebSocket.test.jsx +128 -0
  124. package/dashboard/tests/pages/ConfigPage.test.jsx +199 -0
  125. package/dashboard/tests/pages/PlanningPage.test.jsx +119 -0
  126. package/dashboard/tests/pages/planning/FilesTab.test.jsx +198 -0
  127. package/dashboard/tests/pages/planning/NotesTab.test.jsx +178 -0
  128. package/dashboard/tests/pages/planning/TodosTab.test.jsx +188 -0
  129. package/dashboard/tests/performance.test.jsx +46 -0
  130. package/dashboard/tests/routes/config.test.js +98 -0
  131. package/dashboard/tests/routes/health.test.js +40 -0
  132. package/dashboard/tests/routes/planning.test.js +112 -0
  133. package/dashboard/tests/routes/roadmap.test.js +91 -0
  134. package/dashboard/tests/routes/status.test.js +131 -0
  135. package/dashboard/tests/server/planning-reader.test.js +153 -0
  136. package/dashboard/tests/setup.js +7 -0
  137. package/dashboard/vite.config.js +41 -0
  138. package/package.json +55 -40
  139. package/plan-build-run/bin/config-schema.json +1298 -0
  140. package/plugins/pbr/.claude-plugin/plugin.json +1 -1
  141. package/plugins/pbr/CLAUDE.md +19 -0
  142. package/plugins/pbr/UI-CONSISTENCY-GAPS.md +1 -1
  143. package/plugins/pbr/agents/advisor-researcher.md +101 -0
  144. package/plugins/pbr/agents/audit.md +205 -89
  145. package/plugins/pbr/agents/codebase-mapper.md +158 -23
  146. package/plugins/pbr/agents/debugger.md +212 -34
  147. package/plugins/pbr/agents/dev-sync.md +206 -0
  148. package/plugins/pbr/agents/executor.md +717 -39
  149. package/plugins/pbr/agents/general.md +71 -6
  150. package/plugins/pbr/agents/integration-checker.md +146 -30
  151. package/plugins/pbr/agents/intel-updater.md +332 -0
  152. package/plugins/pbr/agents/nyquist-auditor.md +253 -0
  153. package/plugins/pbr/agents/plan-checker.md +265 -65
  154. package/plugins/pbr/agents/planner.md +440 -42
  155. package/plugins/pbr/agents/researcher.md +219 -36
  156. package/plugins/pbr/agents/roadmapper.md +397 -0
  157. package/plugins/pbr/agents/synthesizer.md +166 -26
  158. package/plugins/pbr/agents/ui-checker.md +203 -0
  159. package/plugins/pbr/agents/ui-researcher.md +224 -0
  160. package/plugins/pbr/agents/verifier.md +495 -47
  161. package/plugins/pbr/commands/add-phase.md +75 -0
  162. package/plugins/pbr/commands/add-todo.md +8 -0
  163. package/plugins/pbr/commands/audit-fix.md +5 -0
  164. package/plugins/pbr/commands/audit-milestone.md +8 -0
  165. package/plugins/pbr/commands/autonomous.md +5 -0
  166. package/plugins/pbr/commands/backlog.md +6 -0
  167. package/plugins/pbr/commands/check-todos.md +8 -0
  168. package/plugins/pbr/commands/complete-milestone.md +8 -0
  169. package/plugins/pbr/commands/config.md +1 -1
  170. package/plugins/pbr/commands/discuss-phase.md +6 -0
  171. package/plugins/pbr/commands/do.md +5 -0
  172. package/plugins/pbr/commands/execute-phase.md +6 -0
  173. package/plugins/pbr/commands/fast.md +6 -0
  174. package/plugins/pbr/commands/forensics.md +6 -0
  175. package/plugins/pbr/commands/import.md +1 -1
  176. package/plugins/pbr/commands/insert-phase.md +65 -0
  177. package/plugins/pbr/commands/intel.md +5 -0
  178. package/plugins/pbr/commands/join-discord.md +11 -0
  179. package/plugins/pbr/commands/list-phase-assumptions.md +5 -0
  180. package/plugins/pbr/commands/map-codebase.md +6 -0
  181. package/plugins/pbr/commands/milestone-summary.md +6 -0
  182. package/plugins/pbr/commands/new-milestone.md +8 -0
  183. package/plugins/pbr/commands/new-project.md +6 -0
  184. package/plugins/pbr/commands/pause-work.md +5 -0
  185. package/plugins/pbr/commands/plan-milestone-gaps.md +7 -0
  186. package/plugins/pbr/commands/plan-phase.md +6 -0
  187. package/plugins/pbr/commands/plant-seed.md +6 -0
  188. package/plugins/pbr/commands/profile-user.md +5 -0
  189. package/plugins/pbr/commands/profile.md +5 -0
  190. package/plugins/pbr/commands/progress.md +6 -0
  191. package/plugins/pbr/commands/quick.md +1 -1
  192. package/plugins/pbr/commands/reapply-patches.md +47 -0
  193. package/plugins/pbr/commands/release.md +6 -0
  194. package/plugins/pbr/commands/remove-phase.md +66 -0
  195. package/plugins/pbr/commands/research-phase.md +59 -0
  196. package/plugins/pbr/commands/resume-work.md +5 -0
  197. package/plugins/pbr/commands/seed.md +6 -0
  198. package/plugins/pbr/commands/session-report.md +5 -0
  199. package/plugins/pbr/commands/set-profile.md +6 -0
  200. package/plugins/pbr/commands/settings.md +5 -0
  201. package/plugins/pbr/commands/setup.md +1 -1
  202. package/plugins/pbr/commands/ship.md +5 -0
  203. package/plugins/pbr/commands/stats.md +6 -0
  204. package/plugins/pbr/commands/test.md +5 -0
  205. package/plugins/pbr/commands/thread.md +6 -0
  206. package/plugins/pbr/commands/todo.md +1 -1
  207. package/plugins/pbr/commands/ui-phase.md +5 -0
  208. package/plugins/pbr/commands/ui-review.md +5 -0
  209. package/plugins/pbr/commands/undo.md +5 -0
  210. package/plugins/pbr/commands/update.md +37 -0
  211. package/plugins/pbr/commands/validate-phase.md +5 -0
  212. package/plugins/pbr/commands/verify-work.md +6 -0
  213. package/plugins/pbr/dashboard/package-lock.json +6 -0
  214. package/plugins/pbr/dist/architecture-guard.js +59 -0
  215. package/plugins/pbr/dist/audit-dimensions.js +556 -0
  216. package/plugins/pbr/dist/auto-continue.js +277 -0
  217. package/plugins/pbr/dist/block-skill-self-read.js +124 -0
  218. package/plugins/pbr/dist/check-agent-state-write.js +63 -0
  219. package/plugins/pbr/dist/check-config-change.js +155 -0
  220. package/plugins/pbr/dist/check-cross-plugin-sync.js +93 -0
  221. package/plugins/pbr/dist/check-dangerous-commands.js +193 -0
  222. package/plugins/pbr/dist/check-direct-state-write.js +37 -0
  223. package/plugins/pbr/dist/check-doc-sprawl.js +102 -0
  224. package/plugins/pbr/dist/check-phase-boundary.js +191 -0
  225. package/plugins/pbr/dist/check-plan-format.js +209 -0
  226. package/plugins/pbr/dist/check-read-first.js +345 -0
  227. package/plugins/pbr/dist/check-roadmap-sync.js +507 -0
  228. package/plugins/pbr/dist/check-skill-workflow.js +354 -0
  229. package/plugins/pbr/dist/check-state-sync.js +658 -0
  230. package/plugins/pbr/dist/check-subagent-output.js +396 -0
  231. package/plugins/pbr/dist/check-summary-gate.js +188 -0
  232. package/plugins/pbr/dist/context-bridge.js +425 -0
  233. package/plugins/pbr/dist/context-budget-check.js +442 -0
  234. package/plugins/pbr/dist/context-quality.js +271 -0
  235. package/plugins/pbr/dist/enforce-context-budget.js +138 -0
  236. package/plugins/pbr/dist/enforce-pbr-workflow.js +277 -0
  237. package/plugins/pbr/dist/event-handler.js +202 -0
  238. package/plugins/pbr/dist/event-logger.js +125 -0
  239. package/plugins/pbr/dist/feedback-loop.js +155 -0
  240. package/plugins/pbr/dist/graph-update.js +422 -0
  241. package/plugins/pbr/dist/hook-logger.js +114 -0
  242. package/plugins/pbr/dist/hook-server-client.js +361 -0
  243. package/plugins/pbr/dist/hook-server.js +658 -0
  244. package/plugins/pbr/dist/hooks-schema.json +87 -0
  245. package/plugins/pbr/dist/instructions-loaded.js +173 -0
  246. package/plugins/pbr/dist/intercept-plan-mode.js +81 -0
  247. package/plugins/pbr/dist/log-notification.js +131 -0
  248. package/plugins/pbr/dist/log-subagent.js +349 -0
  249. package/plugins/pbr/dist/log-tool-failure.js +140 -0
  250. package/plugins/pbr/dist/milestone-learnings.js +519 -0
  251. package/plugins/pbr/dist/pbr-tools.js +1961 -0
  252. package/plugins/pbr/dist/post-bash-triage.js +96 -0
  253. package/plugins/pbr/dist/post-compact.js +135 -0
  254. package/plugins/pbr/dist/post-hoc.js +237 -0
  255. package/plugins/pbr/dist/post-write-dispatch.js +243 -0
  256. package/plugins/pbr/dist/post-write-quality.js +208 -0
  257. package/plugins/pbr/dist/pre-bash-dispatch.js +212 -0
  258. package/plugins/pbr/dist/pre-skill-dispatch.js +114 -0
  259. package/plugins/pbr/dist/pre-task-dispatch.js +269 -0
  260. package/plugins/pbr/dist/pre-write-dispatch.js +234 -0
  261. package/plugins/pbr/dist/progress-tracker.js +173 -0
  262. package/plugins/pbr/dist/prompt-guard.js +114 -0
  263. package/plugins/pbr/dist/prompt-routing.js +209 -0
  264. package/plugins/pbr/dist/quick-status.js +179 -0
  265. package/plugins/pbr/dist/record-incident.js +37 -0
  266. package/plugins/pbr/dist/run-hook.js +144 -0
  267. package/plugins/pbr/dist/session-cleanup.js +653 -0
  268. package/plugins/pbr/dist/session-tracker.js +124 -0
  269. package/plugins/pbr/dist/status-line.js +849 -0
  270. package/plugins/pbr/dist/suggest-compact.js +307 -0
  271. package/plugins/pbr/dist/sync-context-to-claude.js +100 -0
  272. package/plugins/pbr/dist/task-completed.js +206 -0
  273. package/plugins/pbr/dist/track-context-budget.js +432 -0
  274. package/plugins/pbr/dist/track-user-gates.js +88 -0
  275. package/plugins/pbr/dist/trust-tracker.js +193 -0
  276. package/plugins/pbr/dist/validate-commit.js +215 -0
  277. package/plugins/pbr/dist/validate-skill-args.js +222 -0
  278. package/plugins/pbr/dist/validate-task.js +271 -0
  279. package/plugins/pbr/dist/worktree-create.js +144 -0
  280. package/plugins/pbr/dist/worktree-remove.js +147 -0
  281. package/plugins/pbr/hooks/hooks.json +143 -60
  282. package/plugins/pbr/references/agent-contracts.md +39 -8
  283. package/plugins/pbr/references/agent-teams.md +3 -3
  284. package/plugins/pbr/references/archive/checkpoints.md +189 -0
  285. package/plugins/pbr/references/archive/context-quality-tiers.md +45 -0
  286. package/plugins/pbr/references/archive/hook-ordering.md +89 -0
  287. package/plugins/pbr/references/archive/limitations.md +106 -0
  288. package/plugins/pbr/references/archive/pbr-rules.md +194 -0
  289. package/plugins/pbr/references/archive/pbr-tools-cli.md +415 -0
  290. package/plugins/pbr/references/archive/pretooluse-jsonl-behavior.md +58 -0
  291. package/plugins/pbr/references/archive/signal-files.md +41 -0
  292. package/plugins/pbr/references/archive/tmux-setup.md +288 -0
  293. package/plugins/pbr/references/archive/verification-matrix.md +34 -0
  294. package/plugins/pbr/references/archive/verification-patterns.md +277 -0
  295. package/plugins/pbr/references/archive/worktree-sparse-checkout.md +86 -0
  296. package/plugins/pbr/references/checkpoints.md +723 -104
  297. package/plugins/pbr/references/config-reference.md +376 -10
  298. package/plugins/pbr/references/continuation-format.md +1 -0
  299. package/plugins/pbr/references/decimal-phase-calculation.md +65 -0
  300. package/plugins/pbr/references/deviation-rules.md +12 -0
  301. package/plugins/pbr/references/git-integration.md +110 -27
  302. package/plugins/pbr/references/git-planning-commit.md +35 -0
  303. package/plugins/pbr/references/model-profile-resolution.md +34 -0
  304. package/plugins/pbr/references/model-profiles.md +90 -7
  305. package/plugins/pbr/references/model-selection.md +1 -1
  306. package/plugins/pbr/references/node-repair.md +48 -0
  307. package/plugins/pbr/references/plan-authoring.md +65 -0
  308. package/plugins/pbr/references/plan-format.md +161 -10
  309. package/plugins/pbr/references/questioning.md +138 -49
  310. package/plugins/pbr/references/reading-verification.md +4 -4
  311. package/plugins/pbr/references/tdd.md +263 -0
  312. package/plugins/pbr/references/ui-brand.md +449 -0
  313. package/plugins/pbr/references/verification-overrides.md +39 -0
  314. package/plugins/pbr/references/verification-patterns.md +529 -113
  315. package/plugins/pbr/scripts/architecture-guard.js +59 -0
  316. package/plugins/pbr/scripts/audit-checks/behavioral-compliance.js +2098 -0
  317. package/plugins/pbr/scripts/audit-checks/error-analysis.js +989 -0
  318. package/plugins/pbr/scripts/audit-checks/feature-verification.js +723 -0
  319. package/plugins/pbr/scripts/audit-checks/index.js +433 -0
  320. package/plugins/pbr/scripts/audit-checks/infrastructure.js +816 -0
  321. package/plugins/pbr/scripts/audit-checks/quality-metrics.js +452 -0
  322. package/plugins/pbr/scripts/audit-checks/session-quality.js +980 -0
  323. package/plugins/pbr/scripts/audit-checks/si-agent-hook-config-checks.js +396 -0
  324. package/plugins/pbr/scripts/audit-checks/si-cross-cutting-checks.js +272 -0
  325. package/plugins/pbr/scripts/audit-checks/si-skill-checks.js +424 -0
  326. package/plugins/pbr/scripts/audit-checks/workflow-compliance.js +1175 -0
  327. package/plugins/pbr/scripts/audit-dimensions.js +556 -0
  328. package/plugins/pbr/scripts/auto-continue.js +192 -31
  329. package/plugins/pbr/scripts/block-skill-self-read.js +124 -0
  330. package/plugins/pbr/scripts/check-agent-state-write.js +63 -0
  331. package/plugins/pbr/scripts/check-config-change.js +155 -0
  332. package/plugins/pbr/scripts/check-cross-plugin-sync.js +93 -0
  333. package/plugins/pbr/scripts/check-dangerous-commands.js +18 -5
  334. package/plugins/pbr/scripts/check-direct-state-write.js +37 -0
  335. package/plugins/pbr/scripts/check-phase-boundary.js +3 -8
  336. package/plugins/pbr/scripts/check-plan-format.js +135 -278
  337. package/plugins/pbr/scripts/check-read-first.js +345 -0
  338. package/plugins/pbr/scripts/check-roadmap-sync.js +182 -21
  339. package/plugins/pbr/scripts/check-skill-workflow.js +24 -27
  340. package/plugins/pbr/scripts/check-state-sync.js +339 -215
  341. package/plugins/pbr/scripts/check-subagent-output.js +281 -275
  342. package/plugins/pbr/scripts/check-summary-gate.js +5 -15
  343. package/plugins/pbr/scripts/config-schema.json +1134 -95
  344. package/plugins/pbr/scripts/context-bridge.js +425 -0
  345. package/plugins/pbr/scripts/context-budget-check.js +169 -14
  346. package/plugins/pbr/scripts/context-quality.js +271 -0
  347. package/plugins/pbr/scripts/enforce-context-budget.js +138 -0
  348. package/plugins/pbr/scripts/enforce-pbr-workflow.js +277 -0
  349. package/plugins/pbr/scripts/event-handler.js +127 -87
  350. package/plugins/pbr/scripts/event-logger.js +58 -25
  351. package/plugins/pbr/scripts/feedback-loop.js +155 -0
  352. package/plugins/pbr/scripts/graph-update.js +422 -0
  353. package/plugins/pbr/scripts/hook-logger.js +69 -35
  354. package/plugins/pbr/scripts/hook-server-client.js +361 -0
  355. package/plugins/pbr/scripts/hook-server.js +658 -0
  356. package/plugins/pbr/scripts/hooks-schema.json +13 -5
  357. package/plugins/pbr/scripts/instructions-loaded.js +173 -0
  358. package/plugins/pbr/scripts/intent-router.cjs +147 -0
  359. package/plugins/pbr/scripts/intercept-plan-mode.js +52 -18
  360. package/plugins/pbr/scripts/lib/alternatives.js +203 -0
  361. package/plugins/pbr/scripts/lib/audit.js +65 -0
  362. package/plugins/pbr/scripts/lib/auto-cleanup.js +221 -0
  363. package/plugins/pbr/scripts/lib/auto-verify.js +103 -0
  364. package/plugins/pbr/scripts/lib/build.js +719 -0
  365. package/plugins/pbr/scripts/lib/ci-fix-loop.js +228 -0
  366. package/plugins/pbr/scripts/lib/commands.js +483 -0
  367. package/plugins/pbr/scripts/lib/compound.js +216 -0
  368. package/plugins/pbr/scripts/lib/config.js +1308 -0
  369. package/plugins/pbr/scripts/lib/context.js +254 -0
  370. package/plugins/pbr/scripts/lib/contextual-help.js +183 -0
  371. package/plugins/pbr/scripts/lib/convention-detector.js +413 -0
  372. package/plugins/pbr/scripts/lib/core.js +1569 -0
  373. package/plugins/pbr/scripts/lib/dashboard-launch.js +364 -0
  374. package/plugins/pbr/scripts/lib/data-hygiene.js +179 -0
  375. package/plugins/pbr/scripts/lib/decision-extraction.js +183 -0
  376. package/plugins/pbr/scripts/lib/decisions.js +194 -0
  377. package/plugins/pbr/scripts/lib/dependency-break.js +147 -0
  378. package/plugins/pbr/scripts/lib/format-validators.js +1025 -0
  379. package/plugins/pbr/scripts/lib/frontmatter.js +302 -0
  380. package/plugins/pbr/scripts/lib/gates/advisories.js +129 -0
  381. package/plugins/pbr/scripts/lib/gates/build-dependency.js +115 -0
  382. package/plugins/pbr/scripts/lib/gates/build-executor.js +104 -0
  383. package/plugins/pbr/scripts/lib/gates/doc-existence.js +46 -0
  384. package/plugins/pbr/scripts/lib/gates/helpers.js +93 -0
  385. package/plugins/pbr/scripts/lib/gates/inline-execution.js +185 -0
  386. package/plugins/pbr/scripts/lib/gates/milestone-complete.js +136 -0
  387. package/plugins/pbr/scripts/lib/gates/milestone-summary.js +119 -0
  388. package/plugins/pbr/scripts/lib/gates/multi-phase-loader.js +147 -0
  389. package/plugins/pbr/scripts/lib/gates/plan-executor.js +36 -0
  390. package/plugins/pbr/scripts/lib/gates/plan-validation.js +114 -0
  391. package/plugins/pbr/scripts/lib/gates/quick-executor.js +76 -0
  392. package/plugins/pbr/scripts/lib/gates/review-planner.js +61 -0
  393. package/plugins/pbr/scripts/lib/gates/review-verifier.js +69 -0
  394. package/plugins/pbr/scripts/lib/gates/rich-agent-context.js +137 -0
  395. package/plugins/pbr/scripts/lib/gates/user-confirmation.js +93 -0
  396. package/plugins/pbr/scripts/lib/graph-cli.js +89 -0
  397. package/plugins/pbr/scripts/lib/graph.js +553 -0
  398. package/plugins/pbr/scripts/lib/health-checks.js +107 -0
  399. package/plugins/pbr/scripts/lib/health-phase06.js +120 -0
  400. package/plugins/pbr/scripts/lib/health.js +132 -0
  401. package/plugins/pbr/scripts/lib/help.js +100 -0
  402. package/plugins/pbr/scripts/lib/history.js +150 -0
  403. package/plugins/pbr/scripts/lib/impact-analysis.js +319 -0
  404. package/plugins/pbr/scripts/lib/incidents.js +190 -0
  405. package/plugins/pbr/scripts/lib/init.js +643 -0
  406. package/plugins/pbr/scripts/lib/insights-parser.js +320 -0
  407. package/plugins/pbr/scripts/lib/intel.js +653 -0
  408. package/plugins/pbr/scripts/lib/learnings.js +511 -0
  409. package/plugins/pbr/scripts/lib/migrate.js +298 -0
  410. package/plugins/pbr/scripts/lib/milestone.js +306 -0
  411. package/plugins/pbr/scripts/lib/negative-knowledge.js +194 -0
  412. package/plugins/pbr/scripts/lib/notification-throttle.js +141 -0
  413. package/plugins/pbr/scripts/lib/onboarding-generator.js +288 -0
  414. package/plugins/pbr/scripts/lib/parse-args.js +134 -0
  415. package/plugins/pbr/scripts/lib/pattern-routing.js +55 -0
  416. package/plugins/pbr/scripts/lib/patterns.js +272 -0
  417. package/plugins/pbr/scripts/lib/perf.js +190 -0
  418. package/plugins/pbr/scripts/lib/phase.js +1025 -0
  419. package/plugins/pbr/scripts/lib/pid-lock.js +154 -0
  420. package/plugins/pbr/scripts/lib/post-hoc.js +160 -0
  421. package/plugins/pbr/scripts/lib/pre-commit-checks.js +220 -0
  422. package/plugins/pbr/scripts/lib/pre-research.js +126 -0
  423. package/plugins/pbr/scripts/lib/preview.js +174 -0
  424. package/plugins/pbr/scripts/lib/progress-visualization.js +296 -0
  425. package/plugins/pbr/scripts/lib/quick-init.js +131 -0
  426. package/plugins/pbr/scripts/lib/reference.js +236 -0
  427. package/plugins/pbr/scripts/lib/requirements.js +153 -0
  428. package/plugins/pbr/scripts/lib/resolve-root.js +66 -0
  429. package/plugins/pbr/scripts/lib/reverse-spec.js +259 -0
  430. package/plugins/pbr/scripts/lib/roadmap.js +1089 -0
  431. package/plugins/pbr/scripts/lib/security-scan.js +200 -0
  432. package/plugins/pbr/scripts/lib/session-briefing.js +895 -0
  433. package/plugins/pbr/scripts/lib/skill-section.js +99 -0
  434. package/plugins/pbr/scripts/lib/smart-next-task.js +198 -0
  435. package/plugins/pbr/scripts/lib/snapshot-manager.js +232 -0
  436. package/plugins/pbr/scripts/lib/spec-diff.js +209 -0
  437. package/plugins/pbr/scripts/lib/spec-engine.js +189 -0
  438. package/plugins/pbr/scripts/lib/spot-check.js +539 -0
  439. package/plugins/pbr/scripts/lib/state-queue.js +171 -0
  440. package/plugins/pbr/scripts/lib/state.js +1082 -0
  441. package/plugins/pbr/scripts/lib/status-render.js +511 -0
  442. package/plugins/pbr/scripts/lib/step-verify.js +149 -0
  443. package/plugins/pbr/scripts/lib/subagent-validators.js +1059 -0
  444. package/plugins/pbr/scripts/lib/suggest-next.js +435 -0
  445. package/plugins/pbr/scripts/lib/tech-debt-scanner.js +116 -0
  446. package/plugins/pbr/scripts/lib/templates.js +362 -0
  447. package/plugins/pbr/scripts/lib/test-selection.js +163 -0
  448. package/plugins/pbr/scripts/lib/todo.js +300 -0
  449. package/plugins/pbr/scripts/lib/verify.js +1483 -0
  450. package/plugins/pbr/scripts/log-notification.js +131 -0
  451. package/plugins/pbr/scripts/log-subagent.js +203 -18
  452. package/plugins/pbr/scripts/log-tool-failure.js +60 -8
  453. package/plugins/pbr/scripts/milestone-learnings.js +519 -0
  454. package/plugins/pbr/scripts/package.json +1 -1
  455. package/plugins/pbr/scripts/pbr-tools.js +1754 -1171
  456. package/plugins/pbr/scripts/post-bash-triage.js +96 -0
  457. package/plugins/pbr/scripts/post-compact.js +135 -0
  458. package/plugins/pbr/scripts/post-hoc.js +237 -0
  459. package/plugins/pbr/scripts/post-write-dispatch.js +201 -31
  460. package/plugins/pbr/scripts/post-write-quality.js +4 -3
  461. package/plugins/pbr/scripts/pre-bash-dispatch.js +147 -51
  462. package/plugins/pbr/scripts/pre-skill-dispatch.js +114 -0
  463. package/plugins/pbr/scripts/pre-task-dispatch.js +269 -0
  464. package/plugins/pbr/scripts/pre-write-dispatch.js +170 -73
  465. package/plugins/pbr/scripts/progress-tracker.js +122 -310
  466. package/plugins/pbr/scripts/prompt-guard.js +114 -0
  467. package/plugins/pbr/scripts/prompt-routing.js +209 -0
  468. package/plugins/pbr/scripts/quick-status.js +179 -0
  469. package/plugins/pbr/scripts/record-incident.js +37 -0
  470. package/plugins/pbr/scripts/risk-classifier.cjs +123 -0
  471. package/plugins/pbr/scripts/run-hook.js +62 -10
  472. package/plugins/pbr/scripts/session-cleanup.js +428 -29
  473. package/plugins/pbr/scripts/session-tracker.js +124 -0
  474. package/plugins/pbr/scripts/status-line.js +593 -32
  475. package/plugins/pbr/scripts/suggest-compact.js +201 -13
  476. package/plugins/pbr/scripts/sync-context-to-claude.js +100 -0
  477. package/plugins/pbr/scripts/task-completed.js +165 -4
  478. package/plugins/pbr/scripts/test/config.test.js +126 -0
  479. package/plugins/pbr/scripts/test/cross-platform.test.js +131 -0
  480. package/plugins/pbr/scripts/test/fixtures/config.json +20 -0
  481. package/plugins/pbr/scripts/test/fixtures/plan.md +54 -0
  482. package/plugins/pbr/scripts/test/fixtures/project.md +30 -0
  483. package/plugins/pbr/scripts/test/fixtures/roadmap.md +55 -0
  484. package/plugins/pbr/scripts/test/fixtures/state.md +60 -0
  485. package/plugins/pbr/scripts/test/fixtures/summary.md +35 -0
  486. package/plugins/pbr/scripts/test/fixtures.test.js +184 -0
  487. package/plugins/pbr/scripts/test/phase.test.js +142 -0
  488. package/plugins/pbr/scripts/test/roadmap.test.js +96 -0
  489. package/plugins/pbr/scripts/test/state.test.js +155 -0
  490. package/plugins/pbr/scripts/track-context-budget.js +368 -99
  491. package/plugins/pbr/scripts/track-user-gates.js +88 -0
  492. package/plugins/pbr/scripts/trust-tracker.js +193 -0
  493. package/plugins/pbr/scripts/validate-commit.js +41 -26
  494. package/plugins/pbr/scripts/validate-skill-args.js +87 -15
  495. package/plugins/pbr/scripts/validate-task.js +83 -627
  496. package/plugins/pbr/scripts/worktree-create.js +144 -0
  497. package/plugins/pbr/scripts/worktree-remove.js +147 -0
  498. package/plugins/pbr/skills/audit/SKILL.md +195 -24
  499. package/plugins/pbr/skills/audit-fix/SKILL.md +326 -0
  500. package/plugins/pbr/skills/autonomous/SKILL.md +545 -0
  501. package/plugins/pbr/skills/backlog/SKILL.md +56 -0
  502. package/plugins/pbr/skills/begin/SKILL.md +508 -153
  503. package/plugins/pbr/skills/begin/templates/STATE.md.tmpl +1 -2
  504. package/plugins/pbr/skills/begin/templates/config.json.tmpl +411 -36
  505. package/plugins/pbr/skills/begin/templates/researcher-prompt.md.tmpl +28 -0
  506. package/plugins/pbr/skills/begin/templates/roadmap-prompt.md.tmpl +28 -3
  507. package/plugins/pbr/skills/begin/templates/synthesis-prompt.md.tmpl +33 -5
  508. package/plugins/pbr/skills/build/SKILL.md +1040 -354
  509. package/plugins/pbr/skills/build/templates/continuation-prompt.md.tmpl +26 -0
  510. package/plugins/pbr/skills/build/templates/executor-prompt.md.tmpl +77 -0
  511. package/plugins/pbr/skills/build/templates/inline-verifier-prompt.md.tmpl +33 -0
  512. package/plugins/pbr/skills/config/SKILL.md +112 -9
  513. package/plugins/pbr/skills/continue/SKILL.md +113 -33
  514. package/plugins/pbr/skills/dashboard/SKILL.md +21 -9
  515. package/plugins/pbr/skills/debug/SKILL.md +70 -12
  516. package/plugins/pbr/skills/debug/templates/continuation-prompt.md.tmpl +12 -1
  517. package/plugins/pbr/skills/debug/templates/initial-investigation-prompt.md.tmpl +12 -5
  518. package/plugins/pbr/skills/discuss/SKILL.md +206 -25
  519. package/plugins/pbr/skills/discuss/templates/CONTEXT.md.tmpl +21 -1
  520. package/plugins/pbr/skills/do/SKILL.md +119 -24
  521. package/plugins/pbr/skills/explore/SKILL.md +95 -20
  522. package/plugins/pbr/skills/fast/SKILL.md +94 -0
  523. package/plugins/pbr/skills/forensics/SKILL.md +144 -0
  524. package/plugins/pbr/skills/health/SKILL.md +35 -117
  525. package/plugins/pbr/skills/help/SKILL.md +84 -101
  526. package/plugins/pbr/skills/import/SKILL.md +332 -13
  527. package/plugins/pbr/skills/intel/SKILL.md +131 -0
  528. package/plugins/pbr/skills/list-phase-assumptions/SKILL.md +231 -0
  529. package/plugins/pbr/skills/milestone/SKILL.md +421 -263
  530. package/plugins/pbr/skills/milestone/templates/audit-output.md.tmpl +76 -0
  531. package/plugins/pbr/skills/milestone/templates/complete-output.md.tmpl +32 -0
  532. package/plugins/pbr/skills/milestone/templates/edge-cases.md +54 -0
  533. package/plugins/pbr/skills/milestone/templates/gaps-output.md.tmpl +25 -0
  534. package/plugins/pbr/skills/milestone/templates/integration-checker-prompt.md.tmpl +25 -0
  535. package/plugins/pbr/skills/milestone/templates/new-output.md.tmpl +29 -0
  536. package/plugins/pbr/skills/milestone-summary/SKILL.md +86 -0
  537. package/plugins/pbr/skills/note/SKILL.md +20 -4
  538. package/plugins/pbr/skills/pause/SKILL.md +54 -14
  539. package/plugins/pbr/skills/pause/templates/continue-here.md.tmpl +33 -52
  540. package/plugins/pbr/skills/plan/SKILL.md +526 -280
  541. package/plugins/pbr/skills/plan/templates/checker-prompt.md.tmpl +5 -2
  542. package/plugins/pbr/skills/plan/templates/completion-output.md.tmpl +27 -0
  543. package/plugins/pbr/skills/plan/templates/planner-prompt.md.tmpl +27 -1
  544. package/plugins/pbr/skills/plan/templates/revision-prompt.md.tmpl +21 -5
  545. package/plugins/pbr/skills/profile/SKILL.md +185 -0
  546. package/plugins/pbr/skills/profile-user/SKILL.md +227 -0
  547. package/plugins/pbr/skills/quick/SKILL.md +435 -100
  548. package/plugins/pbr/skills/release/SKILL.md +206 -0
  549. package/plugins/pbr/skills/resume/SKILL.md +170 -46
  550. package/plugins/pbr/skills/review/SKILL.md +217 -164
  551. package/plugins/pbr/skills/review/templates/verifier-prompt.md.tmpl +7 -0
  552. package/plugins/pbr/skills/scan/SKILL.md +152 -106
  553. package/plugins/pbr/skills/scan/templates/mapper-prompt.md.tmpl +5 -56
  554. package/plugins/pbr/skills/seed/SKILL.md +87 -0
  555. package/plugins/pbr/skills/session-report/SKILL.md +130 -0
  556. package/plugins/pbr/skills/setup/SKILL.md +150 -202
  557. package/plugins/pbr/skills/shared/agent-context-enrichment.md +21 -0
  558. package/plugins/pbr/skills/shared/agent-type-resolution.md +32 -0
  559. package/plugins/pbr/skills/shared/commit-planning-docs.md +8 -0
  560. package/plugins/pbr/skills/shared/context-budget.md +66 -1
  561. package/plugins/pbr/skills/shared/context-loader-task.md +18 -11
  562. package/plugins/pbr/skills/shared/digest-select.md +2 -2
  563. package/plugins/pbr/skills/shared/domain-probes.md +1 -1
  564. package/plugins/pbr/skills/shared/error-reporting.md +38 -60
  565. package/plugins/pbr/skills/shared/gate-prompts.md +4 -2
  566. package/plugins/pbr/skills/shared/memory-capture.md +48 -0
  567. package/plugins/pbr/skills/shared/phase-argument-parsing.md +4 -4
  568. package/plugins/pbr/skills/shared/revision-loop.md +24 -6
  569. package/plugins/pbr/skills/shared/state-update.md +49 -56
  570. package/plugins/pbr/skills/shared/universal-anti-patterns.md +27 -4
  571. package/plugins/pbr/skills/ship/SKILL.md +155 -0
  572. package/plugins/pbr/skills/stats/SKILL.md +80 -0
  573. package/plugins/pbr/skills/status/SKILL.md +185 -119
  574. package/plugins/pbr/skills/test/SKILL.md +254 -0
  575. package/plugins/pbr/skills/thread/SKILL.md +73 -0
  576. package/plugins/pbr/skills/todo/SKILL.md +28 -72
  577. package/plugins/pbr/skills/ui-phase/SKILL.md +180 -0
  578. package/plugins/pbr/skills/ui-review/SKILL.md +206 -0
  579. package/plugins/pbr/skills/undo/SKILL.md +221 -0
  580. package/plugins/pbr/skills/validate-phase/SKILL.md +362 -0
  581. package/plugins/pbr/templates/CONTEXT.md.tmpl +45 -20
  582. package/plugins/pbr/templates/DISCOVERY.md.tmpl +29 -0
  583. package/plugins/pbr/templates/DISCUSSION-LOG.md.tmpl +49 -0
  584. package/plugins/pbr/templates/HANDOFF.json.tmpl +30 -0
  585. package/plugins/pbr/templates/INTEGRATION-REPORT.md.tmpl +18 -2
  586. package/plugins/pbr/templates/MILESTONE-AUDIT.md.tmpl +44 -0
  587. package/plugins/pbr/templates/PROJECT.md.tmpl +126 -0
  588. package/plugins/pbr/templates/REQUIREMENTS.md.tmpl +96 -0
  589. package/plugins/pbr/templates/RETROSPECTIVE.md.tmpl +43 -0
  590. package/plugins/pbr/templates/ROADMAP.md.tmpl +108 -14
  591. package/plugins/pbr/templates/SUMMARY-complex.md.tmpl +133 -0
  592. package/plugins/pbr/templates/SUMMARY-minimal.md.tmpl +55 -0
  593. package/plugins/pbr/templates/SUMMARY.md.tmpl +21 -0
  594. package/plugins/pbr/templates/UAT.md.tmpl +94 -0
  595. package/plugins/pbr/templates/UI-SPEC.md.tmpl +144 -0
  596. package/plugins/pbr/templates/VALIDATION.md.tmpl +94 -0
  597. package/plugins/pbr/templates/VERIFICATION-DETAIL.md.tmpl +49 -13
  598. package/plugins/pbr/templates/project-CONTEXT.md.tmpl +59 -0
  599. package/plugins/pbr/templates/research-outputs/ARCHITECTURE.md.tmpl +91 -0
  600. package/plugins/pbr/templates/research-outputs/FEATURES.md.tmpl +64 -0
  601. package/plugins/pbr/templates/research-outputs/PITFALLS.md.tmpl +50 -0
  602. package/plugins/pbr/templates/research-outputs/STACK.md.tmpl +63 -0
  603. package/plugins/pbr/templates/research-outputs/SUMMARY.md.tmpl +98 -0
  604. package/scripts/build-hooks.js +61 -0
  605. package/scripts/check-ci.js +100 -0
  606. package/scripts/clean-changelog.js +364 -0
  607. package/scripts/generate-derivatives.js +581 -0
  608. package/scripts/posttest.js +93 -0
  609. package/scripts/release.js +262 -0
  610. package/scripts/run-tests.cjs +29 -0
  611. package/scripts/test-wrapper.js +43 -0
  612. package/dashboard/bin/cli.js +0 -25
  613. package/dashboard/public/css/layout.css +0 -704
  614. package/dashboard/public/css/status-colors.css +0 -98
  615. package/dashboard/public/css/tokens.css +0 -59
  616. package/dashboard/public/js/htmx-title.js +0 -5
  617. package/dashboard/public/js/sidebar-toggle.js +0 -34
  618. package/dashboard/public/js/sse-client.js +0 -100
  619. package/dashboard/public/js/theme-toggle.js +0 -46
  620. package/dashboard/src/app.js +0 -91
  621. package/dashboard/src/middleware/current-phase.js +0 -24
  622. package/dashboard/src/middleware/errorHandler.js +0 -52
  623. package/dashboard/src/middleware/notFoundHandler.js +0 -9
  624. package/dashboard/src/repositories/planning.repository.js +0 -130
  625. package/dashboard/src/routes/events.routes.js +0 -45
  626. package/dashboard/src/routes/index.routes.js +0 -35
  627. package/dashboard/src/routes/pages.routes.js +0 -426
  628. package/dashboard/src/server.js +0 -42
  629. package/dashboard/src/services/analytics.service.js +0 -141
  630. package/dashboard/src/services/dashboard.service.js +0 -309
  631. package/dashboard/src/services/milestone.service.js +0 -222
  632. package/dashboard/src/services/notes.service.js +0 -50
  633. package/dashboard/src/services/phase.service.js +0 -232
  634. package/dashboard/src/services/project.service.js +0 -57
  635. package/dashboard/src/services/roadmap.service.js +0 -258
  636. package/dashboard/src/services/sse.service.js +0 -58
  637. package/dashboard/src/services/todo.service.js +0 -272
  638. package/dashboard/src/services/watcher.service.js +0 -48
  639. package/dashboard/src/utils/cache.js +0 -55
  640. package/dashboard/src/views/analytics.ejs +0 -5
  641. package/dashboard/src/views/coming-soon.ejs +0 -11
  642. package/dashboard/src/views/dependencies.ejs +0 -5
  643. package/dashboard/src/views/error.ejs +0 -20
  644. package/dashboard/src/views/index.ejs +0 -5
  645. package/dashboard/src/views/milestone-detail.ejs +0 -5
  646. package/dashboard/src/views/milestones.ejs +0 -5
  647. package/dashboard/src/views/notes.ejs +0 -5
  648. package/dashboard/src/views/partials/analytics-content.ejs +0 -90
  649. package/dashboard/src/views/partials/breadcrumbs.ejs +0 -14
  650. package/dashboard/src/views/partials/dashboard-content.ejs +0 -84
  651. package/dashboard/src/views/partials/dependencies-content.ejs +0 -48
  652. package/dashboard/src/views/partials/empty-state.ejs +0 -7
  653. package/dashboard/src/views/partials/footer.ejs +0 -3
  654. package/dashboard/src/views/partials/head.ejs +0 -30
  655. package/dashboard/src/views/partials/header.ejs +0 -21
  656. package/dashboard/src/views/partials/layout-bottom.ejs +0 -43
  657. package/dashboard/src/views/partials/layout-top.ejs +0 -16
  658. package/dashboard/src/views/partials/milestone-detail-content.ejs +0 -20
  659. package/dashboard/src/views/partials/milestones-content.ejs +0 -88
  660. package/dashboard/src/views/partials/notes-content.ejs +0 -23
  661. package/dashboard/src/views/partials/phase-content.ejs +0 -193
  662. package/dashboard/src/views/partials/phase-doc-content.ejs +0 -38
  663. package/dashboard/src/views/partials/phases-content.ejs +0 -124
  664. package/dashboard/src/views/partials/roadmap-content.ejs +0 -180
  665. package/dashboard/src/views/partials/sidebar.ejs +0 -99
  666. package/dashboard/src/views/partials/todo-create-content.ejs +0 -54
  667. package/dashboard/src/views/partials/todo-detail-content.ejs +0 -42
  668. package/dashboard/src/views/partials/todos-content.ejs +0 -97
  669. package/dashboard/src/views/phase-detail.ejs +0 -5
  670. package/dashboard/src/views/phase-doc.ejs +0 -5
  671. package/dashboard/src/views/phases.ejs +0 -5
  672. package/dashboard/src/views/roadmap.ejs +0 -5
  673. package/dashboard/src/views/todo-create.ejs +0 -5
  674. package/dashboard/src/views/todo-detail.ejs +0 -5
  675. package/dashboard/src/views/todos.ejs +0 -5
  676. package/plugins/copilot-pbr/CHANGELOG.md +0 -19
  677. package/plugins/copilot-pbr/README.md +0 -139
  678. package/plugins/copilot-pbr/agents/audit.agent.md +0 -113
  679. package/plugins/copilot-pbr/agents/codebase-mapper.agent.md +0 -151
  680. package/plugins/copilot-pbr/agents/debugger.agent.md +0 -182
  681. package/plugins/copilot-pbr/agents/executor.agent.md +0 -267
  682. package/plugins/copilot-pbr/agents/general.agent.md +0 -88
  683. package/plugins/copilot-pbr/agents/integration-checker.agent.md +0 -119
  684. package/plugins/copilot-pbr/agents/plan-checker.agent.md +0 -208
  685. package/plugins/copilot-pbr/agents/planner.agent.md +0 -238
  686. package/plugins/copilot-pbr/agents/researcher.agent.md +0 -186
  687. package/plugins/copilot-pbr/agents/synthesizer.agent.md +0 -126
  688. package/plugins/copilot-pbr/agents/verifier.agent.md +0 -228
  689. package/plugins/copilot-pbr/hooks/hooks.json +0 -156
  690. package/plugins/copilot-pbr/plugin.json +0 -30
  691. package/plugins/copilot-pbr/references/agent-anti-patterns.md +0 -25
  692. package/plugins/copilot-pbr/references/agent-contracts.md +0 -297
  693. package/plugins/copilot-pbr/references/agent-interactions.md +0 -135
  694. package/plugins/copilot-pbr/references/agent-teams.md +0 -55
  695. package/plugins/copilot-pbr/references/checkpoints.md +0 -158
  696. package/plugins/copilot-pbr/references/common-bug-patterns.md +0 -14
  697. package/plugins/copilot-pbr/references/config-reference.md +0 -442
  698. package/plugins/copilot-pbr/references/continuation-format.md +0 -213
  699. package/plugins/copilot-pbr/references/deviation-rules.md +0 -113
  700. package/plugins/copilot-pbr/references/git-integration.md +0 -227
  701. package/plugins/copilot-pbr/references/integration-patterns.md +0 -118
  702. package/plugins/copilot-pbr/references/model-profiles.md +0 -100
  703. package/plugins/copilot-pbr/references/model-selection.md +0 -32
  704. package/plugins/copilot-pbr/references/pbr-rules.md +0 -195
  705. package/plugins/copilot-pbr/references/pbr-tools-cli.md +0 -285
  706. package/plugins/copilot-pbr/references/plan-authoring.md +0 -182
  707. package/plugins/copilot-pbr/references/plan-format.md +0 -288
  708. package/plugins/copilot-pbr/references/planning-config.md +0 -214
  709. package/plugins/copilot-pbr/references/questioning.md +0 -215
  710. package/plugins/copilot-pbr/references/reading-verification.md +0 -128
  711. package/plugins/copilot-pbr/references/stub-patterns.md +0 -161
  712. package/plugins/copilot-pbr/references/subagent-coordination.md +0 -120
  713. package/plugins/copilot-pbr/references/ui-formatting.md +0 -444
  714. package/plugins/copilot-pbr/references/verification-patterns.md +0 -199
  715. package/plugins/copilot-pbr/references/wave-execution.md +0 -96
  716. package/plugins/copilot-pbr/rules/pbr-workflow.mdc +0 -48
  717. package/plugins/copilot-pbr/setup.ps1 +0 -93
  718. package/plugins/copilot-pbr/setup.sh +0 -93
  719. package/plugins/copilot-pbr/skills/audit/SKILL.md +0 -330
  720. package/plugins/copilot-pbr/skills/begin/SKILL.md +0 -589
  721. package/plugins/copilot-pbr/skills/begin/templates/PROJECT.md.tmpl +0 -34
  722. package/plugins/copilot-pbr/skills/begin/templates/REQUIREMENTS.md.tmpl +0 -19
  723. package/plugins/copilot-pbr/skills/begin/templates/STATE.md.tmpl +0 -50
  724. package/plugins/copilot-pbr/skills/begin/templates/config.json.tmpl +0 -64
  725. package/plugins/copilot-pbr/skills/begin/templates/researcher-prompt.md.tmpl +0 -20
  726. package/plugins/copilot-pbr/skills/begin/templates/roadmap-prompt.md.tmpl +0 -31
  727. package/plugins/copilot-pbr/skills/begin/templates/synthesis-prompt.md.tmpl +0 -17
  728. package/plugins/copilot-pbr/skills/build/SKILL.md +0 -960
  729. package/plugins/copilot-pbr/skills/config/SKILL.md +0 -250
  730. package/plugins/copilot-pbr/skills/continue/SKILL.md +0 -159
  731. package/plugins/copilot-pbr/skills/dashboard/SKILL.md +0 -43
  732. package/plugins/copilot-pbr/skills/debug/SKILL.md +0 -508
  733. package/plugins/copilot-pbr/skills/debug/templates/continuation-prompt.md.tmpl +0 -17
  734. package/plugins/copilot-pbr/skills/debug/templates/initial-investigation-prompt.md.tmpl +0 -28
  735. package/plugins/copilot-pbr/skills/discuss/SKILL.md +0 -353
  736. package/plugins/copilot-pbr/skills/discuss/templates/CONTEXT.md.tmpl +0 -62
  737. package/plugins/copilot-pbr/skills/discuss/templates/decision-categories.md +0 -10
  738. package/plugins/copilot-pbr/skills/do/SKILL.md +0 -66
  739. package/plugins/copilot-pbr/skills/explore/SKILL.md +0 -373
  740. package/plugins/copilot-pbr/skills/health/SKILL.md +0 -283
  741. package/plugins/copilot-pbr/skills/health/templates/check-pattern.md.tmpl +0 -31
  742. package/plugins/copilot-pbr/skills/health/templates/output-format.md.tmpl +0 -64
  743. package/plugins/copilot-pbr/skills/help/SKILL.md +0 -170
  744. package/plugins/copilot-pbr/skills/import/SKILL.md +0 -502
  745. package/plugins/copilot-pbr/skills/milestone/SKILL.md +0 -745
  746. package/plugins/copilot-pbr/skills/milestone/templates/audit-report.md.tmpl +0 -49
  747. package/plugins/copilot-pbr/skills/milestone/templates/stats-file.md.tmpl +0 -31
  748. package/plugins/copilot-pbr/skills/note/SKILL.md +0 -213
  749. package/plugins/copilot-pbr/skills/pause/SKILL.md +0 -247
  750. package/plugins/copilot-pbr/skills/pause/templates/continue-here.md.tmpl +0 -72
  751. package/plugins/copilot-pbr/skills/plan/SKILL.md +0 -662
  752. package/plugins/copilot-pbr/skills/plan/templates/checker-prompt.md.tmpl +0 -22
  753. package/plugins/copilot-pbr/skills/plan/templates/gap-closure-prompt.md.tmpl +0 -33
  754. package/plugins/copilot-pbr/skills/plan/templates/planner-prompt.md.tmpl +0 -39
  755. package/plugins/copilot-pbr/skills/plan/templates/researcher-prompt.md.tmpl +0 -20
  756. package/plugins/copilot-pbr/skills/plan/templates/revision-prompt.md.tmpl +0 -24
  757. package/plugins/copilot-pbr/skills/quick/SKILL.md +0 -376
  758. package/plugins/copilot-pbr/skills/resume/SKILL.md +0 -399
  759. package/plugins/copilot-pbr/skills/review/SKILL.md +0 -653
  760. package/plugins/copilot-pbr/skills/review/templates/debugger-prompt.md.tmpl +0 -61
  761. package/plugins/copilot-pbr/skills/review/templates/gap-planner-prompt.md.tmpl +0 -41
  762. package/plugins/copilot-pbr/skills/review/templates/verifier-prompt.md.tmpl +0 -116
  763. package/plugins/copilot-pbr/skills/scan/SKILL.md +0 -299
  764. package/plugins/copilot-pbr/skills/scan/templates/mapper-prompt.md.tmpl +0 -202
  765. package/plugins/copilot-pbr/skills/setup/SKILL.md +0 -296
  766. package/plugins/copilot-pbr/skills/shared/commit-planning-docs.md +0 -36
  767. package/plugins/copilot-pbr/skills/shared/config-loading.md +0 -103
  768. package/plugins/copilot-pbr/skills/shared/context-budget.md +0 -41
  769. package/plugins/copilot-pbr/skills/shared/context-loader-task.md +0 -87
  770. package/plugins/copilot-pbr/skills/shared/digest-select.md +0 -80
  771. package/plugins/copilot-pbr/skills/shared/domain-probes.md +0 -126
  772. package/plugins/copilot-pbr/skills/shared/error-reporting.md +0 -81
  773. package/plugins/copilot-pbr/skills/shared/gate-prompts.md +0 -389
  774. package/plugins/copilot-pbr/skills/shared/phase-argument-parsing.md +0 -46
  775. package/plugins/copilot-pbr/skills/shared/progress-display.md +0 -53
  776. package/plugins/copilot-pbr/skills/shared/revision-loop.md +0 -82
  777. package/plugins/copilot-pbr/skills/shared/state-loading.md +0 -63
  778. package/plugins/copilot-pbr/skills/shared/state-update.md +0 -162
  779. package/plugins/copilot-pbr/skills/shared/universal-anti-patterns.md +0 -38
  780. package/plugins/copilot-pbr/skills/status/SKILL.md +0 -362
  781. package/plugins/copilot-pbr/skills/statusline/SKILL.md +0 -149
  782. package/plugins/copilot-pbr/skills/todo/SKILL.md +0 -279
  783. package/plugins/copilot-pbr/templates/CONTEXT.md.tmpl +0 -53
  784. package/plugins/copilot-pbr/templates/INTEGRATION-REPORT.md.tmpl +0 -152
  785. package/plugins/copilot-pbr/templates/RESEARCH-SUMMARY.md.tmpl +0 -98
  786. package/plugins/copilot-pbr/templates/ROADMAP.md.tmpl +0 -41
  787. package/plugins/copilot-pbr/templates/SUMMARY.md.tmpl +0 -82
  788. package/plugins/copilot-pbr/templates/VERIFICATION-DETAIL.md.tmpl +0 -117
  789. package/plugins/copilot-pbr/templates/codebase/ARCHITECTURE.md.tmpl +0 -98
  790. package/plugins/copilot-pbr/templates/codebase/CONCERNS.md.tmpl +0 -93
  791. package/plugins/copilot-pbr/templates/codebase/CONVENTIONS.md.tmpl +0 -104
  792. package/plugins/copilot-pbr/templates/codebase/INTEGRATIONS.md.tmpl +0 -78
  793. package/plugins/copilot-pbr/templates/codebase/STACK.md.tmpl +0 -78
  794. package/plugins/copilot-pbr/templates/codebase/STRUCTURE.md.tmpl +0 -80
  795. package/plugins/copilot-pbr/templates/codebase/TESTING.md.tmpl +0 -107
  796. package/plugins/copilot-pbr/templates/continue-here.md.tmpl +0 -74
  797. package/plugins/copilot-pbr/templates/prompt-partials/phase-project-context.md.tmpl +0 -38
  798. package/plugins/copilot-pbr/templates/research/ARCHITECTURE.md.tmpl +0 -124
  799. package/plugins/copilot-pbr/templates/research/STACK.md.tmpl +0 -71
  800. package/plugins/copilot-pbr/templates/research/SUMMARY.md.tmpl +0 -112
  801. package/plugins/copilot-pbr/templates/research-outputs/phase-research.md.tmpl +0 -81
  802. package/plugins/copilot-pbr/templates/research-outputs/project-research.md.tmpl +0 -99
  803. package/plugins/copilot-pbr/templates/research-outputs/synthesis.md.tmpl +0 -36
  804. package/plugins/cursor-pbr/.cursor-plugin/plugin.json +0 -32
  805. package/plugins/cursor-pbr/CHANGELOG.md +0 -15
  806. package/plugins/cursor-pbr/README.md +0 -123
  807. package/plugins/cursor-pbr/agents/audit.md +0 -178
  808. package/plugins/cursor-pbr/agents/codebase-mapper.md +0 -150
  809. package/plugins/cursor-pbr/agents/debugger.md +0 -181
  810. package/plugins/cursor-pbr/agents/executor.md +0 -266
  811. package/plugins/cursor-pbr/agents/general.md +0 -87
  812. package/plugins/cursor-pbr/agents/integration-checker.md +0 -118
  813. package/plugins/cursor-pbr/agents/plan-checker.md +0 -207
  814. package/plugins/cursor-pbr/agents/planner.md +0 -237
  815. package/plugins/cursor-pbr/agents/researcher.md +0 -185
  816. package/plugins/cursor-pbr/agents/synthesizer.md +0 -125
  817. package/plugins/cursor-pbr/agents/verifier.md +0 -227
  818. package/plugins/cursor-pbr/assets/.gitkeep +0 -0
  819. package/plugins/cursor-pbr/assets/logo.svg +0 -21
  820. package/plugins/cursor-pbr/hooks/hooks.json +0 -213
  821. package/plugins/cursor-pbr/references/agent-anti-patterns.md +0 -25
  822. package/plugins/cursor-pbr/references/agent-contracts.md +0 -297
  823. package/plugins/cursor-pbr/references/agent-interactions.md +0 -135
  824. package/plugins/cursor-pbr/references/agent-teams.md +0 -55
  825. package/plugins/cursor-pbr/references/checkpoints.md +0 -158
  826. package/plugins/cursor-pbr/references/common-bug-patterns.md +0 -14
  827. package/plugins/cursor-pbr/references/config-reference.md +0 -442
  828. package/plugins/cursor-pbr/references/continuation-format.md +0 -213
  829. package/plugins/cursor-pbr/references/deviation-rules.md +0 -113
  830. package/plugins/cursor-pbr/references/git-integration.md +0 -227
  831. package/plugins/cursor-pbr/references/integration-patterns.md +0 -118
  832. package/plugins/cursor-pbr/references/model-profiles.md +0 -100
  833. package/plugins/cursor-pbr/references/model-selection.md +0 -32
  834. package/plugins/cursor-pbr/references/pbr-rules.md +0 -195
  835. package/plugins/cursor-pbr/references/pbr-tools-cli.md +0 -285
  836. package/plugins/cursor-pbr/references/plan-authoring.md +0 -182
  837. package/plugins/cursor-pbr/references/plan-format.md +0 -288
  838. package/plugins/cursor-pbr/references/planning-config.md +0 -214
  839. package/plugins/cursor-pbr/references/questioning.md +0 -215
  840. package/plugins/cursor-pbr/references/reading-verification.md +0 -128
  841. package/plugins/cursor-pbr/references/stub-patterns.md +0 -161
  842. package/plugins/cursor-pbr/references/subagent-coordination.md +0 -120
  843. package/plugins/cursor-pbr/references/ui-formatting.md +0 -444
  844. package/plugins/cursor-pbr/references/verification-patterns.md +0 -199
  845. package/plugins/cursor-pbr/references/wave-execution.md +0 -96
  846. package/plugins/cursor-pbr/rules/pbr-workflow.mdc +0 -48
  847. package/plugins/cursor-pbr/setup.ps1 +0 -78
  848. package/plugins/cursor-pbr/setup.sh +0 -83
  849. package/plugins/cursor-pbr/skills/audit/SKILL.md +0 -331
  850. package/plugins/cursor-pbr/skills/begin/SKILL.md +0 -589
  851. package/plugins/cursor-pbr/skills/begin/templates/PROJECT.md.tmpl +0 -34
  852. package/plugins/cursor-pbr/skills/begin/templates/REQUIREMENTS.md.tmpl +0 -19
  853. package/plugins/cursor-pbr/skills/begin/templates/STATE.md.tmpl +0 -50
  854. package/plugins/cursor-pbr/skills/begin/templates/config.json.tmpl +0 -64
  855. package/plugins/cursor-pbr/skills/begin/templates/researcher-prompt.md.tmpl +0 -20
  856. package/plugins/cursor-pbr/skills/begin/templates/roadmap-prompt.md.tmpl +0 -31
  857. package/plugins/cursor-pbr/skills/begin/templates/synthesis-prompt.md.tmpl +0 -17
  858. package/plugins/cursor-pbr/skills/build/SKILL.md +0 -961
  859. package/plugins/cursor-pbr/skills/config/SKILL.md +0 -252
  860. package/plugins/cursor-pbr/skills/continue/SKILL.md +0 -159
  861. package/plugins/cursor-pbr/skills/dashboard/SKILL.md +0 -44
  862. package/plugins/cursor-pbr/skills/debug/SKILL.md +0 -512
  863. package/plugins/cursor-pbr/skills/debug/templates/continuation-prompt.md.tmpl +0 -17
  864. package/plugins/cursor-pbr/skills/debug/templates/initial-investigation-prompt.md.tmpl +0 -28
  865. package/plugins/cursor-pbr/skills/discuss/SKILL.md +0 -354
  866. package/plugins/cursor-pbr/skills/discuss/templates/CONTEXT.md.tmpl +0 -62
  867. package/plugins/cursor-pbr/skills/discuss/templates/decision-categories.md +0 -10
  868. package/plugins/cursor-pbr/skills/do/SKILL.md +0 -67
  869. package/plugins/cursor-pbr/skills/explore/SKILL.md +0 -376
  870. package/plugins/cursor-pbr/skills/health/SKILL.md +0 -283
  871. package/plugins/cursor-pbr/skills/health/templates/check-pattern.md.tmpl +0 -31
  872. package/plugins/cursor-pbr/skills/health/templates/output-format.md.tmpl +0 -64
  873. package/plugins/cursor-pbr/skills/help/SKILL.md +0 -170
  874. package/plugins/cursor-pbr/skills/import/SKILL.md +0 -505
  875. package/plugins/cursor-pbr/skills/milestone/SKILL.md +0 -746
  876. package/plugins/cursor-pbr/skills/milestone/templates/audit-report.md.tmpl +0 -49
  877. package/plugins/cursor-pbr/skills/milestone/templates/stats-file.md.tmpl +0 -31
  878. package/plugins/cursor-pbr/skills/note/SKILL.md +0 -214
  879. package/plugins/cursor-pbr/skills/pause/SKILL.md +0 -248
  880. package/plugins/cursor-pbr/skills/pause/templates/continue-here.md.tmpl +0 -72
  881. package/plugins/cursor-pbr/skills/plan/SKILL.md +0 -663
  882. package/plugins/cursor-pbr/skills/plan/templates/checker-prompt.md.tmpl +0 -22
  883. package/plugins/cursor-pbr/skills/plan/templates/gap-closure-prompt.md.tmpl +0 -33
  884. package/plugins/cursor-pbr/skills/plan/templates/planner-prompt.md.tmpl +0 -39
  885. package/plugins/cursor-pbr/skills/plan/templates/researcher-prompt.md.tmpl +0 -20
  886. package/plugins/cursor-pbr/skills/plan/templates/revision-prompt.md.tmpl +0 -24
  887. package/plugins/cursor-pbr/skills/quick/SKILL.md +0 -376
  888. package/plugins/cursor-pbr/skills/resume/SKILL.md +0 -399
  889. package/plugins/cursor-pbr/skills/review/SKILL.md +0 -654
  890. package/plugins/cursor-pbr/skills/review/templates/debugger-prompt.md.tmpl +0 -61
  891. package/plugins/cursor-pbr/skills/review/templates/gap-planner-prompt.md.tmpl +0 -41
  892. package/plugins/cursor-pbr/skills/review/templates/verifier-prompt.md.tmpl +0 -116
  893. package/plugins/cursor-pbr/skills/scan/SKILL.md +0 -300
  894. package/plugins/cursor-pbr/skills/scan/templates/mapper-prompt.md.tmpl +0 -202
  895. package/plugins/cursor-pbr/skills/setup/SKILL.md +0 -296
  896. package/plugins/cursor-pbr/skills/shared/commit-planning-docs.md +0 -36
  897. package/plugins/cursor-pbr/skills/shared/config-loading.md +0 -103
  898. package/plugins/cursor-pbr/skills/shared/context-budget.md +0 -41
  899. package/plugins/cursor-pbr/skills/shared/context-loader-task.md +0 -87
  900. package/plugins/cursor-pbr/skills/shared/digest-select.md +0 -80
  901. package/plugins/cursor-pbr/skills/shared/domain-probes.md +0 -126
  902. package/plugins/cursor-pbr/skills/shared/error-reporting.md +0 -81
  903. package/plugins/cursor-pbr/skills/shared/gate-prompts.md +0 -389
  904. package/plugins/cursor-pbr/skills/shared/phase-argument-parsing.md +0 -46
  905. package/plugins/cursor-pbr/skills/shared/progress-display.md +0 -53
  906. package/plugins/cursor-pbr/skills/shared/revision-loop.md +0 -82
  907. package/plugins/cursor-pbr/skills/shared/state-loading.md +0 -63
  908. package/plugins/cursor-pbr/skills/shared/state-update.md +0 -162
  909. package/plugins/cursor-pbr/skills/shared/universal-anti-patterns.md +0 -38
  910. package/plugins/cursor-pbr/skills/status/SKILL.md +0 -362
  911. package/plugins/cursor-pbr/skills/statusline/SKILL.md +0 -150
  912. package/plugins/cursor-pbr/skills/todo/SKILL.md +0 -280
  913. package/plugins/cursor-pbr/templates/CONTEXT.md.tmpl +0 -53
  914. package/plugins/cursor-pbr/templates/INTEGRATION-REPORT.md.tmpl +0 -152
  915. package/plugins/cursor-pbr/templates/RESEARCH-SUMMARY.md.tmpl +0 -98
  916. package/plugins/cursor-pbr/templates/ROADMAP.md.tmpl +0 -41
  917. package/plugins/cursor-pbr/templates/SUMMARY.md.tmpl +0 -82
  918. package/plugins/cursor-pbr/templates/VERIFICATION-DETAIL.md.tmpl +0 -117
  919. package/plugins/cursor-pbr/templates/codebase/ARCHITECTURE.md.tmpl +0 -98
  920. package/plugins/cursor-pbr/templates/codebase/CONCERNS.md.tmpl +0 -93
  921. package/plugins/cursor-pbr/templates/codebase/CONVENTIONS.md.tmpl +0 -104
  922. package/plugins/cursor-pbr/templates/codebase/INTEGRATIONS.md.tmpl +0 -78
  923. package/plugins/cursor-pbr/templates/codebase/STACK.md.tmpl +0 -78
  924. package/plugins/cursor-pbr/templates/codebase/STRUCTURE.md.tmpl +0 -80
  925. package/plugins/cursor-pbr/templates/codebase/TESTING.md.tmpl +0 -107
  926. package/plugins/cursor-pbr/templates/continue-here.md.tmpl +0 -74
  927. package/plugins/cursor-pbr/templates/prompt-partials/phase-project-context.md.tmpl +0 -38
  928. package/plugins/cursor-pbr/templates/research/ARCHITECTURE.md.tmpl +0 -124
  929. package/plugins/cursor-pbr/templates/research/STACK.md.tmpl +0 -71
  930. package/plugins/cursor-pbr/templates/research/SUMMARY.md.tmpl +0 -112
  931. package/plugins/cursor-pbr/templates/research-outputs/phase-research.md.tmpl +0 -81
  932. package/plugins/cursor-pbr/templates/research-outputs/project-research.md.tmpl +0 -99
  933. package/plugins/cursor-pbr/templates/research-outputs/synthesis.md.tmpl +0 -36
  934. package/plugins/pbr/references/agent-interactions.md +0 -134
  935. package/plugins/pbr/references/pbr-rules.md +0 -194
  936. package/plugins/pbr/references/pbr-tools-cli.md +0 -285
  937. package/plugins/pbr/references/planning-config.md +0 -213
  938. package/plugins/pbr/references/subagent-coordination.md +0 -119
  939. package/plugins/pbr/references/ui-formatting.md +0 -444
  940. package/plugins/pbr/scripts/validate-plugin-structure.js +0 -183
  941. package/plugins/pbr/skills/milestone/templates/audit-report.md.tmpl +0 -48
  942. package/plugins/pbr/skills/shared/progress-display.md +0 -53
  943. package/plugins/pbr/skills/shared/state-loading.md +0 -62
  944. package/plugins/pbr/templates/RESEARCH-SUMMARY.md.tmpl +0 -97
  945. package/plugins/pbr/templates/research/ARCHITECTURE.md.tmpl +0 -124
  946. package/plugins/pbr/templates/research/STACK.md.tmpl +0 -71
  947. package/plugins/pbr/templates/research/SUMMARY.md.tmpl +0 -112
  948. package/plugins/pbr/templates/research-outputs/phase-research.md.tmpl +0 -81
  949. package/plugins/pbr/templates/research-outputs/project-research.md.tmpl +0 -99
  950. package/plugins/pbr/templates/research-outputs/synthesis.md.tmpl +0 -36
  951. /package/plugins/pbr/references/{agent-anti-patterns.md → archive/agent-anti-patterns.md} +0 -0
@@ -0,0 +1,1961 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * pbr-tools.js — Structured JSON state operations for Plan-Build-Run skills.
5
+ *
6
+ * Thin dispatcher that imports from lib/ modules. All core logic lives in:
7
+ * lib/core.js — Foundation utilities (parsers, file ops, constants)
8
+ * lib/config.js — Config loading, validation, depth profiles
9
+ * lib/state.js — STATE.md operations (load, update, patch, advance)
10
+ * lib/roadmap.js — ROADMAP.md operations (parse, update status/plans)
11
+ * lib/phase.js — Phase operations (add, remove, list, info, plan-index)
12
+ * lib/init.js — Compound init commands (execute-phase, plan-phase, etc.)
13
+ * lib/history.js — History operations (append to STATE.md ## History, load with HISTORY.md fallback)
14
+ *
15
+ * Skills call this via:
16
+ * node ${CLAUDE_PLUGIN_ROOT}/scripts/pbr-tools.js <command> [args]
17
+ *
18
+ * Commands:
19
+ * state load — Full project state as JSON
20
+ * state check-progress — Recalculate progress from filesystem
21
+ * state update <f> <v> — Atomically update a STATE.md field
22
+ * config validate — Validate config.json against schema
23
+ * config get <dot.path> — Read a config value by dot-path key
24
+ * intel query <term> — Search intel files for a term
25
+ * intel status — Report staleness of each intel file
26
+ * intel diff — Show changes since last refresh snapshot
27
+ * requirements mark-complete <ids> — Mark comma-separated REQ-IDs as complete
28
+ * plan-index <phase> — Plan inventory for a phase, grouped by wave
29
+ * frontmatter <filepath> — Parse .md file's YAML frontmatter → JSON
30
+ * must-haves <phase> — Collect all must-haves from phase plans → JSON
31
+ * phase-info <phase> — Comprehensive single-phase status → JSON
32
+ * roadmap update-status <phase> <status> — Update phase status in ROADMAP.md
33
+ * roadmap update-plans <phase> <complete> <total> — Update phase plans in ROADMAP.md
34
+ * roadmap reconcile — Reconcile ROADMAP statuses against disk state
35
+ * roadmap get-phase <N> — Get comprehensive phase info JSON (alias for phase-info)
36
+ * roadmap append-phase [--goal "..."] [--name "..."] [--depends-on N] — Append a new phase to the roadmap
37
+ * history append <type> <title> [body] — Append record to STATE.md ## History (fallback: HISTORY.md)
38
+ * history load — Load history records as JSON (STATE.md first, HISTORY.md fallback)
39
+ * todo list [--theme X] [--status Y] — List todos as JSON (default: pending)
40
+ * todo get <NNN> — Get a specific todo by number
41
+ * todo add <title> [--priority P] [--theme T] — Add a new todo
42
+ * todo done <NNN> — Mark a todo as complete
43
+ * auto-cleanup --phase N | --milestone vN — Auto-close todos and archive notes matching phase/milestone deliverables
44
+ * state reconcile — Detect and repair STATE.md/ROADMAP.md desync
45
+ * state backup — Create timestamped backup of STATE.md and ROADMAP.md
46
+ * phase add <slug> [--after N] [--goal "..."] [--depends-on N] — Add phase with ROADMAP.md integration
47
+ * phase remove <N> — Remove an empty phase directory (with renumbering)
48
+ * phase list [--status S] [--before N] — List phase directories with optional status/before filters
49
+ * phase complete <N> — Mark phase N complete, advance STATE.md to next phase
50
+ * phase insert <N> <slug> [--goal "..."] [--depends-on N] — Insert phase at position N, renumber subsequent
51
+ * phase commits-for <N> — Read .phase-manifest.json for phase N, output commits JSON. Falls back to git log
52
+ * phase first-last-commit <N> — Output { first, last } commit hashes from manifest or git log
53
+ * compound init-phase <N> <slug> [--goal "..."] [--depends-on N] — Atomically create phase dir + STATE + ROADMAP
54
+ * compound complete-phase <N> — Atomically validate SUMMARY + update STATE + ROADMAP
55
+ * compound init-milestone <version> [--name "..."] [--phases "N-M"] — Atomically create milestone archive structure
56
+ * learnings ingest <json-file> — Ingest a learning entry into global store
57
+ * learnings query [--tags X] [--min-confidence Y] [--stack S] [--type T] — Query learnings
58
+ * learnings check-thresholds — Check deferral trigger conditions
59
+ * learnings copy-global <path> <proj> — Copy cross_project LEARNINGS.md to ~/.claude/pbr-knowledge/
60
+ * learnings query-global [--tags X] [--project P] — Query global knowledge files
61
+ * data status — Freshness report for research/, intel/, codebase/ directories
62
+ * data prune --before <ISO-date> [--dry-run] — Archive stale research/codebase files
63
+ * nk record --title "..." --category "..." --files "f1,f2" --tried "..." --failed "..." — Record negative knowledge entry
64
+ * nk list [--category X] [--phase X] [--status X] — List negative knowledge entries
65
+ * nk resolve <slug> — Mark a negative knowledge entry as resolved
66
+ * hooks perf [--last N] [--json] — Show P50/P95/P99 hook performance report from hooks-*.jsonl
67
+ * spot-check <phaseSlug> <planId> — Verify SUMMARY, key_files, and commits exist for a plan
68
+ * staleness-check <phase-slug> — Check if phase plans are stale vs dependencies
69
+ * summary-gate <phase-slug> <plan-id> — Verify SUMMARY.md exists, non-empty, valid frontmatter
70
+ * checkpoint init <phase-slug> [--plans "id1,id2"] — Initialize checkpoint manifest
71
+ * checkpoint update <phase-slug> --wave N --resolved id [--sha hash] — Update manifest
72
+ * seeds match <phase-slug> <phase-number> — Find matching seed files for a phase
73
+ * session get <key> — Read a key from .planning/.session.json
74
+ * session set <key> <value> — Write a key to .planning/.session.json
75
+ * session clear [key] — Delete .session.json or set key to null
76
+ * session dump — Print entire .session.json content
77
+ * skill-section <skill> <section> — Extract a section from a skill's SKILL.md → JSON
78
+ * skill-section --list <skill> — List all headings in a skill → JSON
79
+ * step-verify [skill] [step] [checklist-json] — Validate per-step completion checklist → JSON
80
+ * build-preview [phase-slug] — Preview what /pbr:execute-phase would do for a phase → JSON
81
+ * claim acquire <phase-slug> --session-id <id> --skill <name> — Acquire phase claim
82
+ * claim release <phase-slug> --session-id <id> — Release phase claim
83
+ * claim list — List all active phase claims
84
+ * suggest-alternatives phase-not-found [slug] — List available phases for unknown slug → JSON
85
+ * suggest-alternatives missing-prereq [phase] — List missing prerequisites for a phase → JSON
86
+ * suggest-alternatives config-invalid [field] [val] — List valid values for invalid config field → JSON
87
+ * help — List all skills with name, description, tools, argument-hint → JSON
88
+ * skill-metadata <name> — Get metadata for a single skill → JSON
89
+ *
90
+ * Environment: PBR_PROJECT_ROOT — Override project root directory (used when hooks fire from subagent cwd)
91
+ */
92
+
93
+ const fs = require('fs');
94
+ const path = require('path');
95
+
96
+ // --- Import lib modules ---
97
+ const {
98
+ KNOWN_AGENTS,
99
+ VALID_STATUS_TRANSITIONS,
100
+ validateStatusTransition,
101
+ output,
102
+ error,
103
+ parseYamlFrontmatter,
104
+ parseMustHaves,
105
+ findFiles,
106
+ tailLines,
107
+ countMustHaves,
108
+ determinePhaseStatus,
109
+ atomicWrite,
110
+ lockedFileUpdate,
111
+ writeActiveSkill,
112
+ sessionLoad,
113
+ sessionSave,
114
+ SESSION_ALLOWED_KEYS,
115
+ STALE_SESSION_MS,
116
+ resolveSessionPath,
117
+ acquireClaim,
118
+ releaseClaim,
119
+ releaseSessionClaims: _releaseSessionClaims,
120
+ listClaims: _listClaims
121
+ } = require('./lib/core');
122
+
123
+ const {
124
+ configLoad: _configLoad,
125
+ configClearCache: _configClearCache,
126
+ configValidate: _configValidate,
127
+ configFormat: _configFormat,
128
+ configWrite: _configWrite,
129
+ resolveDepthProfile,
130
+ DEPTH_PROFILE_DEFAULTS,
131
+ loadUserDefaults,
132
+ saveUserDefaults,
133
+ mergeUserDefaults,
134
+ USER_DEFAULTS_PATH
135
+ } = require('./lib/config');
136
+
137
+ const {
138
+ parseStateMd,
139
+ updateFrontmatterField,
140
+ stateLoad: _stateLoad,
141
+ stateCheckProgress: _stateCheckProgress,
142
+ stateUpdate: _stateUpdate,
143
+ statePatch: _statePatch,
144
+ stateAdvancePlan: _stateAdvancePlan,
145
+ stateRecordMetric: _stateRecordMetric,
146
+ stateRecordActivity: _stateRecordActivity,
147
+ stateUpdateProgress: _stateUpdateProgress
148
+ } = require('./lib/state');
149
+
150
+ const {
151
+ stateReconcile: _stateReconcile,
152
+ stateBackup: _stateBackup
153
+ } = require('./lib/state');
154
+
155
+ const {
156
+ parseRoadmapMd,
157
+ findRoadmapRow,
158
+ updateTableRow,
159
+ roadmapUpdateStatus: _roadmapUpdateStatus,
160
+ roadmapUpdatePlans: _roadmapUpdatePlans,
161
+ roadmapAnalyze: _roadmapAnalyze,
162
+ roadmapAppendPhase: _roadmapAppendPhase,
163
+ roadmapRemovePhase: _roadmapRemovePhase,
164
+ roadmapRenumberPhases: _roadmapRenumberPhases,
165
+ roadmapInsertPhase: _roadmapInsertPhase,
166
+ reconcileRoadmapStatuses: _reconcileRoadmapStatuses
167
+ } = require('./lib/roadmap');
168
+
169
+ const {
170
+ frontmatter: _frontmatter,
171
+ planIndex: _planIndex,
172
+ mustHavesCollect: _mustHavesCollect,
173
+ phaseInfo: _phaseInfo,
174
+ phaseAdd: _phaseAdd,
175
+ phaseRemove: _phaseRemove,
176
+ phaseList: _phaseList,
177
+ milestoneStats: _milestoneStats,
178
+ phaseComplete: _phaseComplete,
179
+ phaseInsert: _phaseInsert,
180
+ phaseNextNumber: _phaseNextNumber
181
+ } = require('./lib/phase');
182
+
183
+ const {
184
+ compoundInitPhase: _compoundInitPhase,
185
+ compoundCompletePhase: _compoundCompletePhase,
186
+ compoundInitMilestone: _compoundInitMilestone
187
+ } = require('./lib/compound');
188
+
189
+ const {
190
+ initExecutePhase: _initExecutePhase,
191
+ initPlanPhase: _initPlanPhase,
192
+ initQuick: _initQuick,
193
+ initVerifyWork: _initVerifyWork,
194
+ initResume: _initResume,
195
+ initProgress: _initProgress,
196
+ initStateBundle: _initStateBundle,
197
+ initContinue: _initContinue,
198
+ initMilestone: _initMilestone,
199
+ initBegin: _initBegin,
200
+ initStatus: _initStatus,
201
+ initMapCodebase: _initMapCodebase
202
+ } = require('./lib/init');
203
+
204
+ const {
205
+ historyAppend: _historyAppend,
206
+ historyLoad: _historyLoad
207
+ } = require('./lib/history');
208
+
209
+ const {
210
+ todoList: _todoList,
211
+ todoGet: _todoGet,
212
+ todoAdd: _todoAdd,
213
+ todoDone: _todoDone
214
+ } = require('./lib/todo');
215
+
216
+ const {
217
+ autoCloseTodos: _autoCloseTodos,
218
+ autoArchiveNotes: _autoArchiveNotes
219
+ } = require('./lib/auto-cleanup');
220
+
221
+ const {
222
+ applyMigrations: _applyMigrations
223
+ } = require('./lib/migrate');
224
+
225
+ const {
226
+ verifySpotCheck: _verifySpotCheck
227
+ } = require('./lib/spot-check');
228
+
229
+ const {
230
+ cmdVerifySummary: _cmdVerifySummary,
231
+ cmdVerifyPlanStructure: _cmdVerifyPlanStructure,
232
+ cmdVerifyPhaseCompleteness: _cmdVerifyPhaseCompleteness,
233
+ cmdVerifyArtifacts: _cmdVerifyArtifacts,
234
+ cmdVerifyKeyLinks: _cmdVerifyKeyLinks,
235
+ cmdVerifyCommits: _cmdVerifyCommits,
236
+ cmdVerifyReferences: _cmdVerifyReferences,
237
+ } = require('./lib/verify');
238
+
239
+ const {
240
+ learningsIngest: _learningsIngest,
241
+ learningsQuery: _learningsQuery,
242
+ checkDeferralThresholds: _checkDeferralThresholds,
243
+ copyToGlobal: _copyToGlobal,
244
+ queryGlobal: _queryGlobal
245
+ } = require('./lib/learnings');
246
+
247
+ // insights-parser.js CLI subcommand removed as dead (plan 140-01)
248
+
249
+ const {
250
+ referenceGet: _referenceGet
251
+ } = require('./lib/reference');
252
+
253
+ const {
254
+ skillSection: _skillSection,
255
+ listAvailableSkills: _listAvailableSkills
256
+ } = require('./lib/skill-section');
257
+
258
+ const {
259
+ helpList: _helpList,
260
+ skillMetadata: _skillMetadata
261
+ } = require('./lib/help');
262
+
263
+ const {
264
+ stepVerify: _stepVerify
265
+ } = require('./lib/step-verify');
266
+
267
+ const {
268
+ buildPreview: _buildPreview
269
+ } = require('./lib/preview');
270
+
271
+ const {
272
+ contextTriage: _contextTriage
273
+ } = require('./lib/context');
274
+
275
+ const {
276
+ phaseAlternatives: _phaseAlternatives,
277
+ prerequisiteAlternatives: _prereqAlternatives,
278
+ configAlternatives: _configAlternatives
279
+ } = require('./lib/alternatives');
280
+
281
+ const {
282
+ stalenessCheck: _stalenessCheck,
283
+ summaryGate: _summaryGate,
284
+ checkpointInit: _checkpointInit,
285
+ checkpointUpdate: _checkpointUpdate,
286
+ seedsMatch: _seedsMatch,
287
+ ciPoll: _ciPoll,
288
+ rollback: _rollback
289
+ } = require('./lib/build');
290
+
291
+ const {
292
+ parseJestOutput: _parseJestOutput,
293
+ parseLintOutput: _parseLintOutput,
294
+ autoFixLint: _autoFixLint,
295
+ runCiFixLoop: _runCiFixLoop
296
+ } = require('./lib/ci-fix-loop');
297
+
298
+ const {
299
+ statusRender: _statusRender
300
+ } = require('./lib/status-render');
301
+
302
+ const {
303
+ suggestNext: _suggestNext
304
+ } = require('./lib/suggest-next');
305
+
306
+ const {
307
+ quickStatus: _quickStatus
308
+ } = require('./quick-status');
309
+
310
+ const {
311
+ dataStatus: _dataStatus,
312
+ dataPrune: _dataPrune
313
+ } = require('./lib/data-hygiene');
314
+
315
+ // incidents.js lib retained (used by error-analysis.js, record-incident.js, dashboard)
316
+ // but CLI subcommands removed as dead (plan 140-01)
317
+
318
+ // --- Module-level state (for backwards compatibility) ---
319
+
320
+ let cwd = process.env.PBR_PROJECT_ROOT || process.cwd();
321
+ // MSYS path bridging: Git Bash on Windows can produce /d/Repos/... paths
322
+ // that Node.js cannot resolve. Convert to D:\Repos\... form.
323
+ const _msysCwdMatch = cwd.match(/^\/([a-zA-Z])\/(.*)/);
324
+ if (_msysCwdMatch) cwd = _msysCwdMatch[1] + ':' + path.sep + _msysCwdMatch[2].replace(/\//g, path.sep);
325
+ let planningDir = path.join(cwd, '.planning');
326
+
327
+ // --- Wrapper functions that pass planningDir to lib modules ---
328
+ // These preserve the original function signatures (no planningDir param)
329
+ // so existing callers (hook scripts, tests) continue to work.
330
+
331
+ function configLoad(dir) {
332
+ return _configLoad(dir || planningDir);
333
+ }
334
+
335
+ function configClearCache() {
336
+ _configClearCache();
337
+ cwd = process.env.PBR_PROJECT_ROOT || process.cwd();
338
+ const _msysResetMatch = cwd.match(/^\/([a-zA-Z])\/(.*)/);
339
+ if (_msysResetMatch) cwd = _msysResetMatch[1] + ':' + path.sep + _msysResetMatch[2].replace(/\//g, path.sep);
340
+ planningDir = path.join(cwd, '.planning');
341
+ }
342
+
343
+ function configValidate(preloadedConfig) {
344
+ return _configValidate(preloadedConfig, planningDir);
345
+ }
346
+
347
+ function stateLoad() {
348
+ return _stateLoad(planningDir);
349
+ }
350
+
351
+ function stateCheckProgress() {
352
+ return _stateCheckProgress(planningDir);
353
+ }
354
+
355
+ function stateUpdate(field, value) {
356
+ return _stateUpdate(field, value, planningDir);
357
+ }
358
+
359
+ function statePatch(jsonStr) {
360
+ return _statePatch(jsonStr, planningDir);
361
+ }
362
+
363
+ function stateAdvancePlan() {
364
+ return _stateAdvancePlan(planningDir);
365
+ }
366
+
367
+ function stateRecordMetric(metricArgs) {
368
+ return _stateRecordMetric(metricArgs, planningDir);
369
+ }
370
+
371
+ function stateRecordActivity(description) {
372
+ return _stateRecordActivity(description, planningDir);
373
+ }
374
+
375
+ function stateUpdateProgress() {
376
+ return _stateUpdateProgress(planningDir);
377
+ }
378
+
379
+ function stateReconcile() {
380
+ return _stateReconcile(planningDir);
381
+ }
382
+
383
+ function stateBackup() {
384
+ return _stateBackup(planningDir);
385
+ }
386
+
387
+ function roadmapAnalyze() {
388
+ return _roadmapAnalyze(planningDir);
389
+ }
390
+
391
+ function roadmapUpdateStatus(phaseNum, newStatus) {
392
+ return _roadmapUpdateStatus(phaseNum, newStatus, planningDir);
393
+ }
394
+
395
+ function roadmapUpdatePlans(phaseNum, complete, total) {
396
+ return _roadmapUpdatePlans(phaseNum, complete, total, planningDir);
397
+ }
398
+
399
+ function roadmapReconcile() {
400
+ return _reconcileRoadmapStatuses(planningDir);
401
+ }
402
+
403
+ function frontmatter(filePath) {
404
+ return _frontmatter(filePath);
405
+ }
406
+
407
+ function planIndex(phaseNum) {
408
+ return _planIndex(phaseNum, planningDir);
409
+ }
410
+
411
+ function mustHavesCollect(phaseNum) {
412
+ return _mustHavesCollect(phaseNum, planningDir);
413
+ }
414
+
415
+ function phaseInfo(phaseNum) {
416
+ return _phaseInfo(phaseNum, planningDir);
417
+ }
418
+
419
+ function phaseAdd(slug, afterPhase, options) {
420
+ return _phaseAdd(slug, afterPhase, planningDir, options);
421
+ }
422
+
423
+ function phaseRemove(phaseNum) {
424
+ return _phaseRemove(phaseNum, planningDir);
425
+ }
426
+
427
+ function phaseList(opts) {
428
+ return _phaseList(planningDir, opts);
429
+ }
430
+
431
+ function phaseNextNumber() {
432
+ return _phaseNextNumber(planningDir);
433
+ }
434
+
435
+ function phaseComplete(phaseNum) {
436
+ return _phaseComplete(phaseNum, planningDir);
437
+ }
438
+
439
+ function phaseInsert(position, slug, options) {
440
+ return _phaseInsert(position, slug, planningDir, options);
441
+ }
442
+
443
+ function milestoneStats(version) {
444
+ return _milestoneStats(version, planningDir);
445
+ }
446
+
447
+ function compoundInitPhase(phaseNum, slug, opts) {
448
+ return _compoundInitPhase(phaseNum, slug, planningDir, opts);
449
+ }
450
+
451
+ function compoundCompletePhase(phaseNum) {
452
+ return _compoundCompletePhase(phaseNum, planningDir);
453
+ }
454
+
455
+ function compoundInitMilestone(version, opts) {
456
+ return _compoundInitMilestone(version, planningDir, opts);
457
+ }
458
+
459
+ function initExecutePhase(phaseNum, overridePlanningDir, overrideModel) {
460
+ return _initExecutePhase(phaseNum, overridePlanningDir || planningDir, overrideModel);
461
+ }
462
+
463
+ function initPlanPhase(phaseNum, overridePlanningDir, overrideModel) {
464
+ return _initPlanPhase(phaseNum, overridePlanningDir || planningDir, overrideModel);
465
+ }
466
+
467
+ function initQuick(description) {
468
+ return _initQuick(description, planningDir);
469
+ }
470
+
471
+ function initVerifyWork(phaseNum, overridePlanningDir, overrideModel) {
472
+ return _initVerifyWork(phaseNum, overridePlanningDir || planningDir, overrideModel);
473
+ }
474
+
475
+ function initResume() {
476
+ return _initResume(planningDir);
477
+ }
478
+
479
+ function initProgress() {
480
+ return _initProgress(planningDir);
481
+ }
482
+
483
+ function initContinue() {
484
+ return _initContinue(planningDir);
485
+ }
486
+
487
+ function initMilestone() {
488
+ return _initMilestone(planningDir);
489
+ }
490
+
491
+ function initBegin() {
492
+ return _initBegin(planningDir);
493
+ }
494
+
495
+ function initStatus() {
496
+ return _initStatus(planningDir);
497
+ }
498
+
499
+ function initMapCodebase() {
500
+ return _initMapCodebase(planningDir);
501
+ }
502
+
503
+ function stateBundle(phaseNum) {
504
+ return _initStateBundle(phaseNum, planningDir);
505
+ }
506
+
507
+ function historyAppend(entry, dir) {
508
+ return _historyAppend(entry, dir || planningDir);
509
+ }
510
+
511
+ function historyLoad(dir) {
512
+ return _historyLoad(dir || planningDir);
513
+ }
514
+
515
+ function todoList(opts) {
516
+ return _todoList(planningDir, opts);
517
+ }
518
+
519
+ function todoGet(num) {
520
+ return _todoGet(planningDir, num);
521
+ }
522
+
523
+ function todoAdd(title, opts) {
524
+ return _todoAdd(planningDir, title, opts);
525
+ }
526
+
527
+ function todoDone(num) {
528
+ return _todoDone(planningDir, num);
529
+ }
530
+
531
+ function autoCloseTodos(context) {
532
+ return _autoCloseTodos(planningDir, context);
533
+ }
534
+
535
+ function autoArchiveNotes(context) {
536
+ return _autoArchiveNotes(planningDir, context);
537
+ }
538
+
539
+ function intelQuery(term) {
540
+ const { intelQuery: _intelQuery } = require('./lib/intel');
541
+ return _intelQuery(term, planningDir);
542
+ }
543
+
544
+ function intelStatus() {
545
+ const { intelStatus: _intelStatus } = require('./lib/intel');
546
+ return _intelStatus(planningDir);
547
+ }
548
+
549
+ function intelDiff() {
550
+ const { intelDiff: _intelDiff } = require('./lib/intel');
551
+ return _intelDiff(planningDir);
552
+ }
553
+
554
+ function requirementsMarkComplete(ids) {
555
+ const { updateRequirementStatus } = require('./lib/requirements');
556
+ return updateRequirementStatus(planningDir, ids, 'done');
557
+ }
558
+
559
+ function roadmapAppendPhase(phaseNum, name, goal, dependsOn) {
560
+ return _roadmapAppendPhase(planningDir, phaseNum, name, goal, dependsOn);
561
+ }
562
+
563
+ function dataStatus() {
564
+ return _dataStatus(planningDir);
565
+ }
566
+
567
+ function dataPrune(options) {
568
+ return _dataPrune(planningDir, options);
569
+ }
570
+
571
+ function migrate(options) {
572
+ return _applyMigrations(planningDir, options);
573
+ }
574
+
575
+
576
+ function verifySpotCheck(type, dirPath) {
577
+ return _verifySpotCheck(type, dirPath);
578
+ }
579
+
580
+ function referenceGet(name, options) {
581
+ // Resolve plugin root — try CLAUDE_PLUGIN_ROOT env, then walk up from __dirname
582
+ const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT || path.resolve(__dirname, '..');
583
+ // Fix MSYS paths on Windows (same pattern as run-hook.js)
584
+ let root = pluginRoot;
585
+ const msysMatch = root.match(/^\/([a-zA-Z])\/(.*)/);
586
+ if (msysMatch) root = msysMatch[1] + ':' + path.sep + msysMatch[2];
587
+ return _referenceGet(name, options, root);
588
+ }
589
+
590
+ function resolvePluginRoot() {
591
+ // Resolve plugin root — try CLAUDE_PLUGIN_ROOT env, then walk up from __dirname
592
+ const pluginRoot = process.env.CLAUDE_PLUGIN_ROOT || path.resolve(__dirname, '..');
593
+ // Fix MSYS paths on Windows (same pattern as run-hook.js)
594
+ let root = pluginRoot;
595
+ const msysMatch = root.match(/^\/([a-zA-Z])\/(.*)/);
596
+ if (msysMatch) root = msysMatch[1] + ':' + path.sep + msysMatch[2];
597
+ return root;
598
+ }
599
+
600
+ function skillSectionGet(skillName, sectionQuery) {
601
+ return _skillSection(skillName, sectionQuery, resolvePluginRoot());
602
+ }
603
+
604
+ function listSkillHeadings(skillName) {
605
+ const { listHeadings } = require('./lib/reference');
606
+ const root = resolvePluginRoot();
607
+ const skillPath = require('path').join(root, 'skills', skillName, 'SKILL.md');
608
+ if (!require('fs').existsSync(skillPath)) {
609
+ return { error: `Skill not found: ${skillName}`, available: _listAvailableSkills(root) };
610
+ }
611
+ const content = require('fs').readFileSync(skillPath, 'utf8');
612
+ return { skill: skillName, headings: listHeadings(content) };
613
+ }
614
+
615
+ function contextTriage(options) {
616
+ return _contextTriage(options, planningDir);
617
+ }
618
+
619
+ function stalenessCheck(phaseSlug) { return _stalenessCheck(phaseSlug, planningDir); }
620
+ function summaryGate(phaseSlug, planId) { return _summaryGate(phaseSlug, planId, planningDir); }
621
+ function checkpointInit(phaseSlug, plans) { return _checkpointInit(phaseSlug, plans, planningDir); }
622
+ function checkpointUpdate(phaseSlug, opts) { return _checkpointUpdate(phaseSlug, opts, planningDir); }
623
+ function seedsMatch(phaseSlug, phaseNum) { return _seedsMatch(phaseSlug, phaseNum, planningDir); }
624
+ function ciPoll(runId, timeoutSecs) { return _ciPoll(runId, timeoutSecs, planningDir); }
625
+ function ciFix(options) { return _runCiFixLoop({ ...options, cwd: path.resolve('.') }); }
626
+ function rollbackPlan(manifestPath) { return _rollback(manifestPath, planningDir); }
627
+
628
+ function helpListCmd() {
629
+ const root = resolvePluginRoot();
630
+ return _helpList(root);
631
+ }
632
+ function skillMetadataCmd(skillName) {
633
+ const root = resolvePluginRoot();
634
+ return _skillMetadata(skillName, root);
635
+ }
636
+
637
+ function quickStatus() { return _quickStatus(planningDir); }
638
+
639
+ /**
640
+ * Build cleanup context from phase SUMMARY files and git log.
641
+ * @param {string} phaseNum - Phase number (e.g. "38")
642
+ * @returns {{ phaseName: string, phaseNum: string, keyFiles: string[], commitMessages: string[], summaryDescriptions: string[] }}
643
+ */
644
+ function buildCleanupContext(phaseNum) {
645
+ const padded = String(phaseNum).padStart(2, '0');
646
+ const phasesDir = path.join(planningDir, 'phases');
647
+ if (!fs.existsSync(phasesDir)) throw new Error('No phases directory found');
648
+
649
+ const phaseDir = fs.readdirSync(phasesDir).find(d => d.startsWith(padded + '-'));
650
+ if (!phaseDir) throw new Error(`Phase ${phaseNum} directory not found`);
651
+
652
+ const phaseName = phaseDir.replace(/^\d+-/, '').replace(/-/g, ' ');
653
+ const phaseDirPath = path.join(phasesDir, phaseDir);
654
+
655
+ // Collect key_files and descriptions from all SUMMARY files
656
+ const keyFiles = [];
657
+ const summaryDescriptions = [];
658
+ const summaryFiles = fs.readdirSync(phaseDirPath).filter(f => /^SUMMARY/i.test(f) && f.endsWith('.md'));
659
+ for (const sf of summaryFiles) {
660
+ try {
661
+ const content = fs.readFileSync(path.join(phaseDirPath, sf), 'utf8');
662
+ const fm = parseYamlFrontmatter(content);
663
+ if (fm.key_files && Array.isArray(fm.key_files)) {
664
+ keyFiles.push(...fm.key_files.map(kf => typeof kf === 'string' ? kf.split(':')[0].trim() : ''));
665
+ }
666
+ if (fm.provides && Array.isArray(fm.provides)) {
667
+ summaryDescriptions.push(...fm.provides);
668
+ }
669
+ } catch (_e) { /* skip unreadable summaries */ }
670
+ }
671
+
672
+ // Get recent commit messages
673
+ let commitMessages = [];
674
+ try {
675
+ const { execSync } = require('child_process');
676
+ const log = execSync('git log --oneline -20', { encoding: 'utf8', cwd: path.join(planningDir, '..') });
677
+ commitMessages = log.split('\n').filter(l => l.trim()).map(l => {
678
+ const parts = l.match(/^[0-9a-f]+\s+(.*)/);
679
+ return parts ? parts[1] : '';
680
+ }).filter(Boolean);
681
+ } catch (_e) { /* git not available */ }
682
+
683
+ return { phaseName, phaseNum: String(phaseNum), keyFiles, commitMessages, summaryDescriptions };
684
+ }
685
+
686
+ // --- Phase commit query functions ---
687
+
688
+ /**
689
+ * Read .phase-manifest.json for phase N, output JSON array of commits.
690
+ * Falls back to git log if no manifest exists.
691
+ */
692
+ function _phaseCommitsFor(phaseNum) {
693
+ const padded = String(phaseNum).padStart(2, '0');
694
+ const phasesDir = path.join(planningDir, 'phases');
695
+ if (!fs.existsSync(phasesDir)) return { error: 'No phases directory found' };
696
+
697
+ const phaseDir = fs.readdirSync(phasesDir).find(d => d.startsWith(padded + '-'));
698
+ if (!phaseDir) return { error: `Phase ${phaseNum} directory not found` };
699
+
700
+ const manifestPath = path.join(phasesDir, phaseDir, '.phase-manifest.json');
701
+ if (fs.existsSync(manifestPath)) {
702
+ try {
703
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
704
+ return { source: 'manifest', commits: manifest.commits || [] };
705
+ } catch (_e) { /* fall through to git log */ }
706
+ }
707
+
708
+ // Fallback: scan git log for commits matching this phase scope
709
+ try {
710
+ const { execSync } = require('child_process');
711
+ const log = execSync('git log --oneline --no-merges -100', { encoding: 'utf8' });
712
+ const phasePattern = new RegExp(`\\((${padded}-|phase.*${phaseNum})`, 'i');
713
+ const commits = log.split('\n')
714
+ .filter(l => l.trim() && phasePattern.test(l))
715
+ .map(l => {
716
+ const parts = l.match(/^([0-9a-f]+)\s+(.*)/);
717
+ return parts ? { hash: parts[1], message: parts[2] } : null;
718
+ })
719
+ .filter(Boolean);
720
+ return { source: 'git_log', commits };
721
+ } catch (_e) {
722
+ return { error: 'Could not read git log', commits: [] };
723
+ }
724
+ }
725
+
726
+ /**
727
+ * Output { first, last } commit hashes from phase manifest or git log.
728
+ */
729
+ function _phaseFirstLastCommit(phaseNum) {
730
+ const result = _phaseCommitsFor(phaseNum);
731
+ if (result.error && !result.commits) return result;
732
+ const commits = result.commits || [];
733
+ return {
734
+ source: result.source,
735
+ first: commits.length > 0 ? commits[0].hash : null,
736
+ last: commits.length > 0 ? commits[commits.length - 1].hash : null,
737
+ total: commits.length
738
+ };
739
+ }
740
+
741
+ // --- Claim wrapper functions ---
742
+
743
+ function claimAcquire(phaseSlug, sessionId, skill) {
744
+ const phaseDir = path.join(planningDir, 'phases', phaseSlug);
745
+ if (!fs.existsSync(phaseDir)) return { error: `Phase directory not found: ${phaseSlug}` };
746
+ return acquireClaim(planningDir, phaseDir, sessionId, skill);
747
+ }
748
+
749
+ function claimRelease(phaseSlug, sessionId) {
750
+ const phaseDir = path.join(planningDir, 'phases', phaseSlug);
751
+ if (!fs.existsSync(phaseDir)) return { error: `Phase directory not found: ${phaseSlug}` };
752
+ return releaseClaim(planningDir, phaseDir, sessionId);
753
+ }
754
+
755
+ function claimList() {
756
+ return _listClaims(planningDir);
757
+ }
758
+
759
+ // --- validateProject stays here (cross-cutting across modules) ---
760
+
761
+ /**
762
+ * Comprehensive .planning/ integrity check.
763
+ * Returns { valid, errors, warnings, checks } — errors mean workflow should not proceed.
764
+ */
765
+ function validateProject() {
766
+ const checks = [];
767
+ const errors = [];
768
+ const warnings = [];
769
+
770
+ // 1. .planning/ directory exists
771
+ if (!fs.existsSync(planningDir)) {
772
+ return { valid: false, errors: ['.planning/ directory not found'], warnings: [], checks: ['directory_exists: FAIL'] };
773
+ }
774
+ checks.push('directory_exists: PASS');
775
+
776
+ // 2. config.json exists and is valid
777
+ const config = configLoad();
778
+ if (!config) {
779
+ errors.push('config.json missing or invalid JSON');
780
+ checks.push('config_valid: FAIL');
781
+ } else {
782
+ const configResult = configValidate(config);
783
+ if (!configResult.valid) {
784
+ errors.push(...configResult.errors.map(e => 'config: ' + e));
785
+ }
786
+ warnings.push(...(configResult.warnings || []).map(w => 'config: ' + w));
787
+ checks.push('config_valid: ' + (configResult.valid ? 'PASS' : 'FAIL'));
788
+ }
789
+
790
+ // 3. STATE.md exists and has valid frontmatter
791
+ const statePath = path.join(planningDir, 'STATE.md');
792
+ if (!fs.existsSync(statePath)) {
793
+ errors.push('STATE.md not found');
794
+ checks.push('state_exists: FAIL');
795
+ } else {
796
+ try {
797
+ const stateContent = fs.readFileSync(statePath, 'utf8');
798
+ const fm = parseYamlFrontmatter(stateContent);
799
+ if (!fm || !fm.current_phase) {
800
+ warnings.push('STATE.md frontmatter missing current_phase');
801
+ checks.push('state_frontmatter: WARN');
802
+ } else {
803
+ checks.push('state_frontmatter: PASS');
804
+ }
805
+ } catch (e) {
806
+ errors.push('STATE.md unreadable: ' + e.message);
807
+ checks.push('state_readable: FAIL');
808
+ }
809
+ }
810
+
811
+ // 4. ROADMAP.md exists
812
+ const roadmapPath = path.join(planningDir, 'ROADMAP.md');
813
+ if (!fs.existsSync(roadmapPath)) {
814
+ warnings.push('ROADMAP.md not found (may be a new project)');
815
+ checks.push('roadmap_exists: WARN');
816
+ } else {
817
+ checks.push('roadmap_exists: PASS');
818
+ }
819
+
820
+ // 5. Phase directory matches STATE.md current_phase
821
+ try {
822
+ if (fs.existsSync(statePath)) {
823
+ const stateContent = fs.readFileSync(statePath, 'utf8');
824
+ const fm = parseYamlFrontmatter(stateContent);
825
+ if (fm && fm.current_phase) {
826
+ const phaseNum = String(fm.current_phase).padStart(2, '0');
827
+ const phasesDir = path.join(planningDir, 'phases');
828
+ if (fs.existsSync(phasesDir)) {
829
+ const dirs = fs.readdirSync(phasesDir).filter(d => d.startsWith(phaseNum + '-'));
830
+ if (dirs.length === 0) {
831
+ warnings.push(`Phase directory for current_phase ${fm.current_phase} not found in .planning/phases/`);
832
+ checks.push('phase_directory: WARN');
833
+ } else {
834
+ checks.push('phase_directory: PASS');
835
+ }
836
+ }
837
+ }
838
+ }
839
+ } catch (_e) { /* best effort */ }
840
+
841
+ // 6. No stale .active-skill (>2 hours old)
842
+ const activeSkillPath = path.join(planningDir, '.active-skill');
843
+ if (fs.existsSync(activeSkillPath)) {
844
+ try {
845
+ const stat = fs.statSync(activeSkillPath);
846
+ const ageMs = Date.now() - stat.mtimeMs;
847
+ if (ageMs > 2 * 60 * 60 * 1000) {
848
+ const ageHours = Math.round(ageMs / (60 * 60 * 1000));
849
+ warnings.push(`.active-skill is ${ageHours}h old — may be stale from a crashed session`);
850
+ checks.push('active_skill_fresh: WARN');
851
+ } else {
852
+ checks.push('active_skill_fresh: PASS');
853
+ }
854
+ } catch (_e) { checks.push('active_skill_fresh: SKIP'); }
855
+ } else {
856
+ checks.push('active_skill_fresh: SKIP');
857
+ }
858
+
859
+ // 7. No .tmp files left from atomic writes
860
+ try {
861
+ const tmpFiles = fs.readdirSync(planningDir).filter(f => f.endsWith('.tmp.' + process.pid) || f.match(/\.tmp\.\d+$/));
862
+ if (tmpFiles.length > 0) {
863
+ warnings.push(`Found ${tmpFiles.length} leftover temp files in .planning/: ${tmpFiles.join(', ')}`);
864
+ checks.push('no_temp_files: WARN');
865
+ } else {
866
+ checks.push('no_temp_files: PASS');
867
+ }
868
+ } catch (_e) { /* best effort */ }
869
+
870
+ // 8. Session directory scan — count active, flag stale
871
+ const sessionsResult = { count: 0, active: [], stale: [] };
872
+ const sessionsDir = path.join(planningDir, '.sessions');
873
+ try {
874
+ if (fs.existsSync(sessionsDir)) {
875
+ const entries = fs.readdirSync(sessionsDir, { withFileTypes: true });
876
+ for (const entry of entries) {
877
+ if (!entry.isDirectory()) continue;
878
+ sessionsResult.count++;
879
+ sessionsResult.active.push(entry.name);
880
+
881
+ // Check for staleness via meta.json
882
+ const metaPath = path.join(sessionsDir, entry.name, 'meta.json');
883
+ try {
884
+ const meta = JSON.parse(fs.readFileSync(metaPath, 'utf8'));
885
+ const ageMs = Date.now() - new Date(meta.created).getTime();
886
+ if (ageMs > STALE_SESSION_MS) {
887
+ sessionsResult.stale.push(entry.name);
888
+ }
889
+ } catch (_metaErr) {
890
+ // Fall back to directory mtime
891
+ try {
892
+ const stats = fs.statSync(path.join(sessionsDir, entry.name));
893
+ const ageMs = Date.now() - stats.mtimeMs;
894
+ if (ageMs > STALE_SESSION_MS) {
895
+ sessionsResult.stale.push(entry.name);
896
+ }
897
+ } catch (_statErr) { /* skip */ }
898
+ }
899
+ }
900
+
901
+ if (sessionsResult.stale.length > 0) {
902
+ warnings.push(`${sessionsResult.stale.length} stale session(s) found: ${sessionsResult.stale.join(', ')}. Run cleanStaleSessions to remove.`);
903
+ checks.push('sessions_stale: WARN');
904
+ } else {
905
+ checks.push('sessions_stale: PASS');
906
+ }
907
+
908
+ // Check for singleton .active-skill coexisting with session-scoped ones
909
+ if (fs.existsSync(path.join(planningDir, '.active-skill'))) {
910
+ let hasSessionSkill = false;
911
+ for (const sid of sessionsResult.active) {
912
+ if (fs.existsSync(path.join(sessionsDir, sid, '.active-skill'))) {
913
+ hasSessionSkill = true;
914
+ break;
915
+ }
916
+ }
917
+ if (hasSessionSkill) {
918
+ warnings.push('.active-skill exists at both singleton and session-scoped paths — possible migration artifact. Consider removing the singleton .planning/.active-skill.');
919
+ checks.push('active_skill_dual: WARN');
920
+ }
921
+ }
922
+ }
923
+ } catch (_e) { /* best effort */ }
924
+
925
+ return {
926
+ valid: errors.length === 0,
927
+ errors,
928
+ warnings,
929
+ checks,
930
+ sessions: sessionsResult
931
+ };
932
+ }
933
+
934
+ // --- Spec subcommand handler ---
935
+
936
+ /**
937
+ * Handle spec subcommands: parse, diff, reverse, impact.
938
+ * @param {string[]} args - raw CLI args (args[0] is 'spec', args[1] is subcommand)
939
+ * @param {string} pDir - planningDir
940
+ * @param {string} projectRoot - cwd
941
+ * @param {Function} outputFn - output function
942
+ * @param {Function} errorFn - error function
943
+ */
944
+ function handleSpec(args, pDir, projectRoot, outputFn, errorFn) {
945
+ const subcommand = args[1];
946
+
947
+ // Parse common flags
948
+ const formatIdx = args.indexOf('--format');
949
+ const format = formatIdx !== -1 ? args[formatIdx + 1] : 'json';
950
+ const projectRootIdx = args.indexOf('--project-root');
951
+ const effectiveRoot = projectRootIdx !== -1 ? args[projectRootIdx + 1] : projectRoot;
952
+
953
+ // Load config for feature toggle checks
954
+ let config = {};
955
+ try {
956
+ const configPath = path.join(pDir, 'config.json');
957
+ if (fs.existsSync(configPath)) {
958
+ config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
959
+ }
960
+ } catch (_e) {
961
+ // Config unreadable — use defaults
962
+ }
963
+ const features = config.features || {};
964
+
965
+ // Audit log helper
966
+ function writeAuditLog(cmd, featureName, status, fileCount) {
967
+ try {
968
+ const logDir = path.join(pDir, 'logs');
969
+ if (fs.existsSync(logDir)) {
970
+ const logFile = path.join(logDir, 'spec-engine.jsonl');
971
+ const entry = JSON.stringify({
972
+ ts: new Date().toISOString(),
973
+ cmd: `spec.${cmd}`,
974
+ feature: featureName,
975
+ status,
976
+ files: fileCount || 0,
977
+ });
978
+ fs.appendFileSync(logFile, entry + '\n', 'utf-8');
979
+ }
980
+ } catch (_e2) {
981
+ // No-op if log dir missing or unwritable
982
+ }
983
+ }
984
+
985
+ if (!subcommand || subcommand === '--help' || subcommand === 'help') {
986
+ const usageText = [
987
+ 'Usage: spec <subcommand> [args] [--format json|markdown]',
988
+ '',
989
+ 'Subcommands:',
990
+ ' parse <plan-file> Parse PLAN.md into structured JSON',
991
+ ' diff <file-a> <file-b> Semantic diff between two PLAN.md versions',
992
+ ' reverse <file...> Generate spec from source files',
993
+ ' impact <file...> Predict impact of changed files',
994
+ '',
995
+ 'Flags:',
996
+ ' --format json|markdown Output format (default: json)',
997
+ ' --project-root <path> Project root for impact analysis',
998
+ ].join('\n');
999
+ outputFn(null, true, usageText);
1000
+ return;
1001
+ }
1002
+
1003
+ if (subcommand === 'parse') {
1004
+ const planFile = args[2];
1005
+ if (!planFile) { errorFn('Usage: spec parse <plan-file>'); return; }
1006
+ const { parsePlanToSpec } = require('./lib/spec-engine');
1007
+ let content;
1008
+ try {
1009
+ content = fs.readFileSync(planFile, 'utf-8');
1010
+ } catch (e) {
1011
+ errorFn(`Cannot read file: ${planFile}: ${e.message}`);
1012
+ return;
1013
+ }
1014
+ const spec = parsePlanToSpec(content);
1015
+ writeAuditLog('parse', 'machine_executable_plans', 'ok', 1);
1016
+ outputFn({ frontmatter: spec.frontmatter, tasks: spec.tasks });
1017
+ return;
1018
+ }
1019
+
1020
+ if (subcommand === 'diff') {
1021
+ if (features.spec_diffing === false) {
1022
+ outputFn({ error: 'Feature disabled. Enable features.spec_diffing in config.json' });
1023
+ return;
1024
+ }
1025
+ const fileA = args[2];
1026
+ const fileB = args[3];
1027
+ if (!fileA || !fileB) { errorFn('Usage: spec diff <file-a> <file-b>'); return; }
1028
+ const { diffPlanFiles, formatDiff } = require('./lib/spec-diff');
1029
+ let contentA, contentB;
1030
+ try {
1031
+ contentA = fs.readFileSync(fileA, 'utf-8');
1032
+ contentB = fs.readFileSync(fileB, 'utf-8');
1033
+ } catch (e) {
1034
+ errorFn(`Cannot read file: ${e.message}`);
1035
+ return;
1036
+ }
1037
+ const diff = diffPlanFiles(contentA, contentB);
1038
+ writeAuditLog('diff', 'spec_diffing', 'ok', 2);
1039
+ if (format === 'markdown') {
1040
+ outputFn(null, true, formatDiff(diff, 'markdown'));
1041
+ } else {
1042
+ outputFn(diff);
1043
+ }
1044
+ return;
1045
+ }
1046
+
1047
+ if (subcommand === 'reverse') {
1048
+ if (features.reverse_spec === false) {
1049
+ outputFn({ error: 'Feature disabled. Enable features.reverse_spec in config.json' });
1050
+ return;
1051
+ }
1052
+ const files = [];
1053
+ for (let i = 2; i < args.length; i++) {
1054
+ if (!args[i].startsWith('--')) files.push(args[i]);
1055
+ }
1056
+ if (files.length === 0) { errorFn('Usage: spec reverse <file...>'); return; }
1057
+ const { generateReverseSpec } = require('./lib/reverse-spec');
1058
+ const { serializeSpec } = require('./lib/spec-engine');
1059
+ const spec = generateReverseSpec(files, { readFile: (p) => fs.readFileSync(p, 'utf-8') });
1060
+ writeAuditLog('reverse', 'reverse_spec', 'ok', files.length);
1061
+ if (format === 'markdown') {
1062
+ outputFn(null, true, serializeSpec(spec));
1063
+ } else {
1064
+ outputFn(spec);
1065
+ }
1066
+ return;
1067
+ }
1068
+
1069
+ if (subcommand === 'impact') {
1070
+ if (features.predictive_impact === false) {
1071
+ outputFn({ error: 'Feature disabled. Enable features.predictive_impact in config.json' });
1072
+ return;
1073
+ }
1074
+ const files = [];
1075
+ for (let i = 2; i < args.length; i++) {
1076
+ if (!args[i].startsWith('--') && args[i - 1] !== '--project-root') files.push(args[i]);
1077
+ }
1078
+ if (files.length === 0) { errorFn('Usage: spec impact <file...>'); return; }
1079
+ const { analyzeImpact } = require('./lib/impact-analysis');
1080
+ const report = analyzeImpact(files, effectiveRoot);
1081
+ writeAuditLog('impact', 'predictive_impact', 'ok', files.length);
1082
+ outputFn(report);
1083
+ return;
1084
+ }
1085
+
1086
+ errorFn(`Unknown spec subcommand: ${subcommand}\nAvailable: parse, diff, reverse, impact`);
1087
+ }
1088
+
1089
+ // --- CLI entry point ---
1090
+
1091
+ async function main() {
1092
+ const args = process.argv.slice(2);
1093
+ const command = args[0];
1094
+ const subcommand = args[1];
1095
+
1096
+ try {
1097
+ if (command === 'state' && subcommand === 'load') {
1098
+ output(stateLoad());
1099
+ } else if (command === 'state' && subcommand === 'check-progress') {
1100
+ output(stateCheckProgress());
1101
+ } else if (command === 'state' && subcommand === 'update') {
1102
+ const field = args[2];
1103
+ const value = args[3];
1104
+ if (!field || value === undefined) {
1105
+ error('Usage: pbr-tools.js state update <field> <value>\nFields: current_phase, status, plans_complete, last_activity, progress_percent, phase_slug, last_command, blockers');
1106
+ }
1107
+ output(stateUpdate(field, value));
1108
+ } else if (command === 'config' && subcommand === 'validate') {
1109
+ output(configValidate());
1110
+ } else if (command === 'validate' && subcommand === 'health') {
1111
+ const { getAllPhase10Checks } = require('./lib/health-checks');
1112
+ const checks = getAllPhase10Checks(planningDir);
1113
+ output({ phase10: checks, timestamp: new Date().toISOString() });
1114
+ } else if (command === 'config' && subcommand === 'load-defaults') {
1115
+ const defaults = loadUserDefaults();
1116
+ output(defaults || { exists: false, path: USER_DEFAULTS_PATH });
1117
+ } else if (command === 'config' && subcommand === 'save-defaults') {
1118
+ const config = configLoad();
1119
+ if (!config) error('No config.json found. Run /pbr:setup first.');
1120
+ output(saveUserDefaults(config));
1121
+ } else if (command === 'config' && subcommand === 'format') {
1122
+ const config = configLoad();
1123
+ if (!config) error('No config.json found.');
1124
+ _configWrite(planningDir, config);
1125
+ output({ formatted: true, path: path.join(planningDir, 'config.json') });
1126
+ } else if (command === 'config' && subcommand === 'resolve-depth') {
1127
+ const dir = args[2] || undefined;
1128
+ const config = configLoad(dir);
1129
+ output(resolveDepthProfile(config));
1130
+ } else if (command === 'config' && subcommand === 'get') {
1131
+ const key = args[2];
1132
+ if (!key) { error('Usage: config get <dot.path.key>'); }
1133
+ const cfg = configLoad();
1134
+ if (!cfg) { error('No config.json found'); }
1135
+ const parts = key.split('.');
1136
+ let val = cfg;
1137
+ for (const p of parts) {
1138
+ if (val == null || typeof val !== 'object') { val = undefined; break; }
1139
+ val = val[p];
1140
+ }
1141
+ if (val === undefined) { error(`Config key not found: ${key}`); }
1142
+ output(typeof val === 'object' ? val : { value: val });
1143
+
1144
+ } else if (command === 'intel') {
1145
+ const subCmd = args[1];
1146
+ if (subCmd === 'query') {
1147
+ const term = args[2];
1148
+ if (!term) { error('Usage: intel query <term>'); }
1149
+ output(intelQuery(term));
1150
+ } else if (subCmd === 'status') {
1151
+ output(intelStatus());
1152
+ } else if (subCmd === 'diff') {
1153
+ output(intelDiff());
1154
+ } else {
1155
+ error('Usage: intel <query|status|diff>');
1156
+ }
1157
+
1158
+ } else if (command === 'requirements' && subcommand === 'mark-complete') {
1159
+ const ids = args[2];
1160
+ if (!ids) { error('Usage: requirements mark-complete <comma-separated-REQ-IDs>'); }
1161
+ const idList = ids.split(',').map(s => s.trim());
1162
+ output(requirementsMarkComplete(idList));
1163
+
1164
+ } else if (command === 'plan-index') {
1165
+ const phase = args[1];
1166
+ if (!phase) {
1167
+ error('Usage: pbr-tools.js plan-index <phase-number>');
1168
+ }
1169
+ output(planIndex(phase));
1170
+ } else if (command === 'frontmatter') {
1171
+ const filePath = args[1];
1172
+ if (!filePath) {
1173
+ error('Usage: pbr-tools.js frontmatter <filepath>');
1174
+ }
1175
+ output(frontmatter(filePath));
1176
+ } else if (command === 'must-haves') {
1177
+ const phase = args[1];
1178
+ if (!phase) {
1179
+ error('Usage: pbr-tools.js must-haves <phase-number>');
1180
+ }
1181
+ output(mustHavesCollect(phase));
1182
+ } else if (command === 'phase-info') {
1183
+ const phase = args[1];
1184
+ if (!phase) {
1185
+ error('Usage: pbr-tools.js phase-info <phase-number>');
1186
+ }
1187
+ output(phaseInfo(phase));
1188
+ } else if (command === 'roadmap' && subcommand === 'update-status') {
1189
+ const phase = args[2];
1190
+ const status = args[3];
1191
+ if (!phase || !status) {
1192
+ error('Usage: pbr-tools.js roadmap update-status <phase-number> <status>');
1193
+ }
1194
+ output(roadmapUpdateStatus(phase, status));
1195
+ } else if (command === 'roadmap' && subcommand === 'update-plans') {
1196
+ const phase = args[2];
1197
+ const complete = args[3];
1198
+ const total = args[4];
1199
+ if (!phase || complete === undefined || total === undefined) {
1200
+ error('Usage: pbr-tools.js roadmap update-plans <phase-number> <complete> <total>');
1201
+ }
1202
+ output(roadmapUpdatePlans(phase, complete, total));
1203
+ } else if (command === 'roadmap' && subcommand === 'analyze') {
1204
+ output(roadmapAnalyze());
1205
+ } else if (command === 'roadmap' && subcommand === 'reconcile') {
1206
+ const result = roadmapReconcile();
1207
+ if (result.fixed > 0) {
1208
+ process.stderr.write(`Reconciled ${result.fixed} ROADMAP entries\n`);
1209
+ for (const m of result.mismatches) {
1210
+ process.stderr.write(` Phase ${m.phase}: ${m.from} -> ${m.to}\n`);
1211
+ }
1212
+ } else {
1213
+ process.stderr.write('ROADMAP statuses are consistent\n');
1214
+ }
1215
+ output(result);
1216
+ } else if (command === 'roadmap' && subcommand === 'get-phase') {
1217
+ const phaseNum = args[2];
1218
+ if (!phaseNum) { error('Usage: roadmap get-phase <phase_num>'); }
1219
+ output(phaseInfo(phaseNum));
1220
+ } else if (command === 'roadmap' && subcommand === 'append-phase') {
1221
+ const goalIdx = args.indexOf('--goal');
1222
+ const goal = goalIdx >= 0 ? args[goalIdx + 1] : args[2] || '';
1223
+ const nameIdx = args.indexOf('--name');
1224
+ const name = nameIdx >= 0 ? args[nameIdx + 1] : '';
1225
+ const depIdx = args.indexOf('--depends-on');
1226
+ const dependsOn = depIdx >= 0 ? args[depIdx + 1] : null;
1227
+ const analysis = roadmapAnalyze();
1228
+ const maxPhase = analysis.phases ? Math.max(...analysis.phases.map(p => p.num || 0), 0) : 0;
1229
+ const nextNum = maxPhase + 1;
1230
+ output(roadmapAppendPhase(nextNum, name || goal, goal, dependsOn));
1231
+
1232
+ } else if (command === 'history' && subcommand === 'append') {
1233
+ const type = args[2]; // 'milestone' or 'phase'
1234
+ const title = args[3];
1235
+ const body = args[4] || '';
1236
+ if (!type || !title) {
1237
+ error('Usage: pbr-tools.js history append <milestone|phase> <title> [body]');
1238
+ }
1239
+ output(historyAppend({ type, title, body }));
1240
+ } else if (command === 'history' && subcommand === 'load') {
1241
+ output(historyLoad());
1242
+ } else if (command === 'event') {
1243
+ const category = args[1];
1244
+ const event = args[2];
1245
+ let details = {};
1246
+ if (args[3]) {
1247
+ try { details = JSON.parse(args[3]); } catch (_e) { details = { raw: args[3] }; }
1248
+ }
1249
+ if (!category || !event) {
1250
+ error('Usage: pbr-tools.js event <category> <event> [JSON-details]');
1251
+ }
1252
+ const { logEvent } = require('./event-logger');
1253
+ logEvent(category, event, details);
1254
+ output({ logged: true, category, event });
1255
+ // --- Compound init commands ---
1256
+ } else if (command === "init" && subcommand === "execute-phase") {
1257
+ const phase = args[2];
1258
+ if (!phase) error("Usage: pbr-tools.js init execute-phase <phase-number>");
1259
+ output(initExecutePhase(phase));
1260
+ } else if (command === "init" && subcommand === "plan-phase") {
1261
+ const phase = args[2];
1262
+ if (!phase) error("Usage: pbr-tools.js init plan-phase <phase-number>");
1263
+ output(initPlanPhase(phase));
1264
+ } else if (command === "init" && subcommand === "quick") {
1265
+ const desc = args.slice(2).join(" ") || "";
1266
+ output(initQuick(desc));
1267
+ } else if (command === "init" && subcommand === "verify-work") {
1268
+ const phase = args[2];
1269
+ if (!phase) error("Usage: pbr-tools.js init verify-work <phase-number>");
1270
+ output(initVerifyWork(phase));
1271
+ } else if (command === "init" && subcommand === "resume") {
1272
+ output(initResume());
1273
+ } else if (command === "init" && subcommand === "progress") {
1274
+ output(initProgress());
1275
+ } else if (command === "init" && subcommand === "continue") {
1276
+ output(initContinue());
1277
+ } else if (command === "init" && subcommand === "milestone") {
1278
+ output(initMilestone());
1279
+ } else if (command === "init" && subcommand === "begin") {
1280
+ output(initBegin());
1281
+ } else if (command === "init" && subcommand === "status") {
1282
+ output(initStatus());
1283
+ } else if (command === "init" && subcommand === "map-codebase") {
1284
+ output(initMapCodebase());
1285
+ } else if (command === 'state-bundle') {
1286
+ const phaseNum = args[1];
1287
+ if (!phaseNum) error('Usage: pbr-tools.js state-bundle <phase-number>');
1288
+ output(stateBundle(phaseNum));
1289
+ // --- State patch/advance/metric ---
1290
+ } else if (command === "state" && subcommand === "patch") {
1291
+ const jsonStr = args[2];
1292
+ if (!jsonStr) error("Usage: pbr-tools.js state patch JSON");
1293
+ output(statePatch(jsonStr));
1294
+ } else if (command === "state" && subcommand === "advance-plan") {
1295
+ output(stateAdvancePlan());
1296
+ } else if (command === "state" && subcommand === "record-metric") {
1297
+ output(stateRecordMetric(args.slice(2)));
1298
+ } else if (command === "state" && subcommand === "record-activity") {
1299
+ const description = args.slice(2).join(' ');
1300
+ if (!description) error("Usage: pbr-tools.js state record-activity <description>");
1301
+ output(stateRecordActivity(description));
1302
+ } else if (command === "state" && subcommand === "update-progress") {
1303
+ output(stateUpdateProgress());
1304
+ } else if (command === 'state' && subcommand === 'reconcile') {
1305
+ output(stateReconcile());
1306
+ } else if (command === 'state' && subcommand === 'backup') {
1307
+ output(stateBackup());
1308
+ } else if (command === 'state' && subcommand === 'enqueue') {
1309
+ const field = args[2];
1310
+ const value = args[3];
1311
+ if (!field || value === undefined) { error('Usage: state enqueue <field> <value>'); }
1312
+ const { stateEnqueue } = require('./lib/state-queue');
1313
+ output(stateEnqueue(field, value, planningDir));
1314
+ } else if (command === 'state' && subcommand === 'drain') {
1315
+ const { stateDrain } = require('./lib/state-queue');
1316
+ output(stateDrain(planningDir));
1317
+ } else if (command === 'phase' && subcommand === 'add') {
1318
+ const slug = args[2];
1319
+ if (!slug) { error('Usage: phase add <slug> [--after N] [--goal "..."] [--depends-on N]'); }
1320
+ const afterIdx = args.indexOf('--after');
1321
+ const afterPhase = afterIdx !== -1 ? args[afterIdx + 1] : null;
1322
+ const goalIdx = args.indexOf('--goal');
1323
+ const goal = goalIdx !== -1 ? args[goalIdx + 1] : null;
1324
+ const depIdx = args.indexOf('--depends-on');
1325
+ const dependsOn = depIdx !== -1 ? args[depIdx + 1] : null;
1326
+ const addOpts = {};
1327
+ if (goal) addOpts.goal = goal;
1328
+ if (dependsOn) addOpts.dependsOn = dependsOn;
1329
+ output(phaseAdd(slug, afterPhase, Object.keys(addOpts).length > 0 ? addOpts : undefined));
1330
+ } else if (command === 'phase' && subcommand === 'remove') {
1331
+ const phaseNum = args[2];
1332
+ if (!phaseNum) { error('Usage: phase remove <phase_num>'); }
1333
+ output(phaseRemove(phaseNum));
1334
+ } else if (command === 'phase' && subcommand === 'list') {
1335
+ const statusIdx = args.indexOf('--status');
1336
+ const beforeIdx = args.indexOf('--before');
1337
+ const listOpts = {};
1338
+ if (statusIdx >= 0) listOpts.status = args[statusIdx + 1];
1339
+ if (beforeIdx >= 0) listOpts.before = args[beforeIdx + 1];
1340
+ output(phaseList(listOpts));
1341
+ } else if (command === 'phase' && subcommand === 'next-number') {
1342
+ output(phaseNextNumber());
1343
+ } else if (command === 'phase' && subcommand === 'complete') {
1344
+ const phaseNum = args[2];
1345
+ if (!phaseNum) { error('Usage: phase complete <phase_num>'); }
1346
+ output(phaseComplete(phaseNum));
1347
+ } else if (command === 'phase' && subcommand === 'insert') {
1348
+ const position = args[2];
1349
+ const slug = args[3];
1350
+ if (!position || !slug) { error('Usage: phase insert <N> <slug> [--goal "..."] [--depends-on N]'); }
1351
+ const goalIdx = args.indexOf('--goal');
1352
+ const goal = goalIdx !== -1 ? args[goalIdx + 1] : null;
1353
+ const depIdx = args.indexOf('--depends-on');
1354
+ const dependsOn = depIdx !== -1 ? args[depIdx + 1] : null;
1355
+ const insertOpts = {};
1356
+ if (goal) insertOpts.goal = goal;
1357
+ if (dependsOn) insertOpts.dependsOn = dependsOn;
1358
+ output(phaseInsert(parseInt(position, 10), slug, Object.keys(insertOpts).length > 0 ? insertOpts : undefined));
1359
+ } else if (command === 'phase' && subcommand === 'commits-for') {
1360
+ const phaseNum = args[2];
1361
+ if (!phaseNum) { error('Usage: phase commits-for <N>'); }
1362
+ output(_phaseCommitsFor(phaseNum));
1363
+ } else if (command === 'phase' && subcommand === 'first-last-commit') {
1364
+ const phaseNum = args[2];
1365
+ if (!phaseNum) { error('Usage: phase first-last-commit <N>'); }
1366
+ output(_phaseFirstLastCommit(phaseNum));
1367
+ } else if (command === 'compound' && subcommand === 'init-phase') {
1368
+ const phaseNum = args[2];
1369
+ const slug = args[3];
1370
+ if (!phaseNum || !slug) error('Usage: compound init-phase <N> <slug> [--goal "..."] [--depends-on N]');
1371
+ const goalIdx = args.indexOf('--goal');
1372
+ const goal = goalIdx !== -1 ? args[goalIdx + 1] : null;
1373
+ const depIdx = args.indexOf('--depends-on');
1374
+ const dependsOn = depIdx !== -1 ? args[depIdx + 1] : null;
1375
+ output(compoundInitPhase(phaseNum, slug, { goal, dependsOn }));
1376
+ } else if (command === 'compound' && subcommand === 'complete-phase') {
1377
+ const phaseNum = args[2];
1378
+ if (!phaseNum) error('Usage: compound complete-phase <N>');
1379
+ output(compoundCompletePhase(phaseNum));
1380
+ } else if (command === 'compound' && subcommand === 'init-milestone') {
1381
+ const version = args[2];
1382
+ if (!version) error('Usage: compound init-milestone <version> [--name "..."] [--phases "N-M"]');
1383
+ const nameIdx = args.indexOf('--name');
1384
+ const name = nameIdx !== -1 ? args[nameIdx + 1] : null;
1385
+ const phasesIdx = args.indexOf('--phases');
1386
+ const phases = phasesIdx !== -1 ? args[phasesIdx + 1] : null;
1387
+ output(compoundInitMilestone(version, { name, phases }));
1388
+ } else if (command === 'todo' && subcommand === 'list') {
1389
+ const opts = {};
1390
+ const themeIdx = args.indexOf('--theme');
1391
+ if (themeIdx !== -1 && args[themeIdx + 1]) opts.theme = args[themeIdx + 1];
1392
+ const statusIdx = args.indexOf('--status');
1393
+ if (statusIdx !== -1 && args[statusIdx + 1]) opts.status = args[statusIdx + 1];
1394
+ output(todoList(opts));
1395
+ } else if (command === 'todo' && subcommand === 'get') {
1396
+ const num = args[2];
1397
+ if (!num) error('Usage: pbr-tools.js todo get <NNN>');
1398
+ output(todoGet(num));
1399
+ } else if (command === 'todo' && subcommand === 'add') {
1400
+ const titleParts = [];
1401
+ const opts = {};
1402
+ // Parse: todo add <title words...> [--priority P1] [--theme security] [--source cli]
1403
+ for (let i = 2; i < args.length; i++) {
1404
+ if (args[i] === '--priority' && args[i + 1]) { opts.priority = args[++i]; }
1405
+ else if (args[i] === '--theme' && args[i + 1]) { opts.theme = args[++i]; }
1406
+ else if (args[i] === '--source' && args[i + 1]) { opts.source = args[++i]; }
1407
+ else { titleParts.push(args[i]); }
1408
+ }
1409
+ const title = titleParts.join(' ');
1410
+ if (!title) error('Usage: pbr-tools.js todo add <title> [--priority P1|P2|P3] [--theme <theme>]');
1411
+ output(todoAdd(title, opts));
1412
+ } else if (command === 'todo' && subcommand === 'done') {
1413
+ const num = args[2];
1414
+ if (!num) error('Usage: pbr-tools.js todo done <NNN>');
1415
+ output(todoDone(num));
1416
+ } else if (command === 'auto-cleanup') {
1417
+ const phaseFlag = args.indexOf('--phase');
1418
+ const milestoneFlag = args.indexOf('--milestone');
1419
+ if (phaseFlag !== -1 && args[phaseFlag + 1]) {
1420
+ const phaseNum = args[phaseFlag + 1];
1421
+ const context = buildCleanupContext(phaseNum);
1422
+ const todoResult = autoCloseTodos(context);
1423
+ const noteResult = autoArchiveNotes(context);
1424
+ output({ phase: phaseNum, todos: todoResult, notes: noteResult });
1425
+ } else if (milestoneFlag !== -1 && args[milestoneFlag + 1]) {
1426
+ const version = args[milestoneFlag + 1];
1427
+ // Parse ROADMAP.md to find phases in this milestone
1428
+ const roadmapPath = path.join(planningDir, 'ROADMAP.md');
1429
+ if (!fs.existsSync(roadmapPath)) { error('ROADMAP.md not found'); }
1430
+ const roadmap = fs.readFileSync(roadmapPath, 'utf8');
1431
+ const milestoneMatch = roadmap.match(new RegExp('Milestone.*' + version.replace(/\./g, '\\.') + '[\\s\\S]*?Phases:\\s*(\\d+)\\s*-\\s*(\\d+)'));
1432
+ if (!milestoneMatch) { error('Milestone ' + version + ' not found in ROADMAP.md'); }
1433
+ const startPhase = parseInt(milestoneMatch[1]);
1434
+ const endPhase = parseInt(milestoneMatch[2]);
1435
+ const allResults = { milestone: version, phases: [] };
1436
+ for (let p = startPhase; p <= endPhase; p++) {
1437
+ try {
1438
+ const ctx = buildCleanupContext(String(p));
1439
+ const todoRes = autoCloseTodos(ctx);
1440
+ const noteRes = autoArchiveNotes(ctx);
1441
+ allResults.phases.push({ phase: p, todos: todoRes, notes: noteRes });
1442
+ } catch (_e) { /* skip phases without SUMMARY */ }
1443
+ }
1444
+ output(allResults);
1445
+ } else {
1446
+ error('Usage: auto-cleanup --phase N | --milestone vN');
1447
+ }
1448
+ } else if (command === 'migrate') {
1449
+ const dryRun = args.includes('--dry-run');
1450
+ const force = args.includes('--force');
1451
+ const result = await migrate({ dryRun, force });
1452
+ output(result);
1453
+ } else if (command === 'learnings') {
1454
+ const subCmd = args[1];
1455
+
1456
+ if (subCmd === 'ingest') {
1457
+ // learnings ingest <json-file-path>
1458
+ const jsonFile = args[2];
1459
+ if (!jsonFile) { error('Usage: learnings ingest <json-file>'); process.exit(1); }
1460
+ const raw = fs.readFileSync(jsonFile, 'utf8');
1461
+ const entry = JSON.parse(raw);
1462
+ const result = _learningsIngest(entry);
1463
+ output(result);
1464
+
1465
+ } else if (subCmd === 'query') {
1466
+ // learnings query [--tags tag1,tag2] [--min-confidence low|medium|high] [--stack react] [--type tech-pattern]
1467
+ const filters = {};
1468
+ for (let i = 2; i < args.length; i++) {
1469
+ if (args[i] === '--tags' && args[i + 1]) { filters.tags = args[++i].split(',').map(t => t.trim()); }
1470
+ else if (args[i] === '--min-confidence' && args[i + 1]) { filters.minConfidence = args[++i]; }
1471
+ else if (args[i] === '--stack' && args[i + 1]) { filters.stack = args[++i]; }
1472
+ else if (args[i] === '--type' && args[i + 1]) { filters.type = args[++i]; }
1473
+ }
1474
+ const results = _learningsQuery(filters);
1475
+ output(results);
1476
+
1477
+ } else if (subCmd === 'check-thresholds') {
1478
+ // learnings check-thresholds — for progress-tracker to call
1479
+ const triggered = _checkDeferralThresholds();
1480
+ output(triggered);
1481
+
1482
+ } else if (subCmd === 'copy-global') {
1483
+ const filePath = args[2];
1484
+ const projectName = args[3];
1485
+ if (!filePath || !projectName) { error('Usage: learnings copy-global <learnings-md-path> <project-name>'); process.exit(1); }
1486
+ output(_copyToGlobal(filePath, projectName));
1487
+
1488
+ } else if (subCmd === 'query-global') {
1489
+ const filters = {};
1490
+ for (let i = 2; i < args.length; i++) {
1491
+ if (args[i] === '--tags' && args[i + 1]) { filters.tags = args[++i].split(',').map(t => t.trim()); }
1492
+ else if (args[i] === '--project' && args[i + 1]) { filters.project = args[++i]; }
1493
+ }
1494
+ output(_queryGlobal(filters));
1495
+
1496
+ } else {
1497
+ error('Usage: learnings <ingest|query|check-thresholds|copy-global|query-global>');
1498
+ process.exit(1);
1499
+ }
1500
+ } else if (command === 'verify' && subcommand === 'spot-check') {
1501
+ const scType = args[2];
1502
+ const scPath = args[3];
1503
+ if (!scType || !scPath) { error('Usage: verify spot-check <type> <path> (types: plan, summary, verification, quick)'); }
1504
+ const result = verifySpotCheck(scType, scPath);
1505
+ if (result.error) { process.stdout.write(JSON.stringify(result, null, 2) + '\n'); process.exit(1); }
1506
+ output(result);
1507
+
1508
+ } else if (command === 'verify' && subcommand === 'summary') {
1509
+ const spath = args[2];
1510
+ const cfIdx = args.indexOf('--check-files');
1511
+ const cf = cfIdx !== -1 ? parseInt(args[cfIdx + 1], 10) : 2;
1512
+ if (!spath) { error('Usage: verify summary <path> [--check-files N]'); }
1513
+ _cmdVerifySummary(cwd, spath, cf, false);
1514
+
1515
+ } else if (command === 'verify' && subcommand === 'plan-structure') {
1516
+ const ppath = args[2];
1517
+ if (!ppath) { error('Usage: verify plan-structure <path>'); }
1518
+ _cmdVerifyPlanStructure(cwd, ppath, false);
1519
+
1520
+ } else if (command === 'verify' && subcommand === 'phase-completeness') {
1521
+ const phase = args[2];
1522
+ if (!phase) { error('Usage: verify phase-completeness <phase>'); }
1523
+ _cmdVerifyPhaseCompleteness(cwd, phase, false);
1524
+
1525
+ } else if (command === 'verify' && subcommand === 'artifacts') {
1526
+ const planPath = args[2];
1527
+ if (!planPath) { error('Usage: verify artifacts <plan-path>'); }
1528
+ _cmdVerifyArtifacts(cwd, planPath, false);
1529
+
1530
+ } else if (command === 'verify' && subcommand === 'key-links') {
1531
+ const planPath = args[2];
1532
+ if (!planPath) { error('Usage: verify key-links <plan-path>'); }
1533
+ _cmdVerifyKeyLinks(cwd, planPath, false);
1534
+
1535
+ } else if (command === 'verify' && subcommand === 'commits') {
1536
+ const hashes = args.slice(2);
1537
+ if (!hashes.length) { error('Usage: verify commits <hash1> [hash2] ...'); }
1538
+ _cmdVerifyCommits(cwd, hashes, false);
1539
+
1540
+ } else if (command === 'verify' && subcommand === 'references') {
1541
+ const rpath = args[2];
1542
+ if (!rpath) { error('Usage: verify references <path>'); }
1543
+ _cmdVerifyReferences(cwd, rpath, false);
1544
+
1545
+ } else if (command === 'spot-check') {
1546
+ // spot-check <phaseSlug> <planId>
1547
+ // Returns JSON: { ok, summary_exists, key_files_checked, commits_present, detail }
1548
+ const phaseSlug = args[1];
1549
+ const planId = args[2];
1550
+ if (!phaseSlug || !planId) { error('Usage: spot-check <phase-slug> <plan-id>'); process.exit(1); }
1551
+ const { verifySpotCheck } = require('./lib/spot-check');
1552
+ output(verifySpotCheck(phaseSlug, planId));
1553
+ } else if (command === 'staleness-check') {
1554
+ const slug = args[1];
1555
+ if (!slug) { error('Usage: staleness-check <phase-slug>'); process.exit(1); }
1556
+ output(stalenessCheck(slug));
1557
+ } else if (command === 'summary-gate') {
1558
+ const [slug, planId] = args.slice(1);
1559
+ if (!slug || !planId) { error('Usage: summary-gate <phase-slug> <plan-id>'); process.exit(1); }
1560
+ output(summaryGate(slug, planId));
1561
+ } else if (command === 'checkpoint') {
1562
+ const sub = args[1];
1563
+ const slug = args[2];
1564
+ if (sub === 'init') {
1565
+ const plans = args[3] || '';
1566
+ output(checkpointInit(slug, plans));
1567
+ } else if (sub === 'update') {
1568
+ const waveIdx = args.indexOf('--wave');
1569
+ const wave = waveIdx !== -1 ? parseInt(args[waveIdx + 1], 10) : 1;
1570
+ const resolvedIdx = args.indexOf('--resolved');
1571
+ const resolved = resolvedIdx !== -1 ? args[resolvedIdx + 1] : '';
1572
+ const shaIdx = args.indexOf('--sha');
1573
+ const sha = shaIdx !== -1 ? args[shaIdx + 1] : '';
1574
+ output(checkpointUpdate(slug, { wave, resolved, sha }));
1575
+ } else {
1576
+ error('Usage: checkpoint init|update <phase-slug> [options]'); process.exit(1);
1577
+ }
1578
+ } else if (command === 'seeds') {
1579
+ const sub = args[1];
1580
+ if (sub === 'match') {
1581
+ const slug = args[2];
1582
+ const num = args[3];
1583
+ if (!slug) { error('Usage: seeds match <phase-slug> <phase-number>'); process.exit(1); }
1584
+ output(seedsMatch(slug, num));
1585
+ } else {
1586
+ error('Usage: seeds match <phase-slug> <phase-number>'); process.exit(1);
1587
+ }
1588
+ } else if (command === 'ci-poll') {
1589
+ const runId = args[1];
1590
+ const timeoutIdx = args.indexOf('--timeout');
1591
+ const timeoutSecs = timeoutIdx !== -1 ? parseInt(args[timeoutIdx + 1], 10) : 300;
1592
+ if (!runId) { error('Usage: pbr-tools.js ci-poll <run-id> [--timeout <seconds>]'); return; }
1593
+ output(ciPoll(runId, timeoutSecs));
1594
+ } else if (command === 'rollback') {
1595
+ const manifestPath = args[1];
1596
+ if (!manifestPath) { error('Usage: pbr-tools.js rollback <manifest-path>'); return; }
1597
+ output(rollbackPlan(manifestPath));
1598
+ } else if (command === 'session') {
1599
+ const sub = args[1];
1600
+ // Extract --session-id flag from remaining args
1601
+ const sessionIdIdx = args.indexOf('--session-id');
1602
+ const sessionId = sessionIdIdx !== -1 ? args[sessionIdIdx + 1] : null;
1603
+ // Filter out --session-id and its value from positional args
1604
+ const positional = sessionIdIdx !== -1
1605
+ ? args.filter((_a, i) => i !== sessionIdIdx && i !== sessionIdIdx + 1)
1606
+ : args;
1607
+ const key = positional[2];
1608
+ const value = positional[3];
1609
+ const dir = planningDir;
1610
+ if (sub === 'get') {
1611
+ if (!key) { error('Usage: pbr-tools.js session get <key> [--session-id <id>]'); return; }
1612
+ if (!SESSION_ALLOWED_KEYS.includes(key)) { error(`Unknown session key: ${key}. Allowed: ${SESSION_ALLOWED_KEYS.join(', ')}`); return; }
1613
+ const data = sessionLoad(dir, sessionId);
1614
+ const val = Object.prototype.hasOwnProperty.call(data, key) ? data[key] : null;
1615
+ output({ key, value: val });
1616
+ } else if (sub === 'set') {
1617
+ if (!key || value === undefined) { error('Usage: pbr-tools.js session set <key> <value> [--session-id <id>]'); return; }
1618
+ if (!SESSION_ALLOWED_KEYS.includes(key)) { error(`Unknown session key: ${key}. Allowed: ${SESSION_ALLOWED_KEYS.join(', ')}`); return; }
1619
+ // Coerce numeric strings
1620
+ let coerced = value;
1621
+ if (/^\d+$/.test(value)) coerced = parseInt(value, 10);
1622
+ else if (value === 'null') coerced = null;
1623
+ const result = sessionSave(dir, { [key]: coerced }, sessionId);
1624
+ if (!result.success) { error(result.error || 'Failed to save session'); return; }
1625
+ output({ ok: true });
1626
+ } else if (sub === 'clear') {
1627
+ if (key) {
1628
+ // Clear a specific key — set to null
1629
+ if (!SESSION_ALLOWED_KEYS.includes(key)) { error(`Unknown session key: ${key}. Allowed: ${SESSION_ALLOWED_KEYS.join(', ')}`); return; }
1630
+ const result = sessionSave(dir, { [key]: null }, sessionId);
1631
+ if (!result.success) { error(result.error || 'Failed to clear session key'); return; }
1632
+ } else {
1633
+ // Clear entire session file
1634
+ const sessionPath = sessionId
1635
+ ? resolveSessionPath(dir, '.session.json', sessionId)
1636
+ : path.join(dir, '.session.json');
1637
+ try { if (fs.existsSync(sessionPath)) fs.unlinkSync(sessionPath); } catch (e) { error(e.message); return; }
1638
+ }
1639
+ output({ ok: true });
1640
+ } else if (sub === 'dump') {
1641
+ const data = sessionLoad(dir, sessionId);
1642
+ output(data);
1643
+ } else {
1644
+ error('Usage: pbr-tools.js session get|set|clear|dump <key> [value] [--session-id <id>]');
1645
+ }
1646
+ } else if (command === 'context-triage') {
1647
+ const options = {};
1648
+ const agentsIdx = args.indexOf('--agents-done');
1649
+ if (agentsIdx !== -1) options.agentsDone = parseInt(args[agentsIdx + 1], 10);
1650
+ const plansIdx = args.indexOf('--plans-total');
1651
+ if (plansIdx !== -1) options.plansTotal = parseInt(args[plansIdx + 1], 10);
1652
+ const stepIdx = args.indexOf('--step');
1653
+ if (stepIdx !== -1) options.currentStep = args[stepIdx + 1];
1654
+ output(contextTriage(options));
1655
+ } else if (command === 'reference') {
1656
+ const name = args[1];
1657
+ if (!name) error('Usage: pbr-tools.js reference <name> [--section <heading>] [--list]');
1658
+ const listFlag = args.includes('--list');
1659
+ const sectionIdx = args.indexOf('--section');
1660
+ const section = sectionIdx !== -1 ? args.slice(sectionIdx + 1).join(' ') : null;
1661
+ output(referenceGet(name, { section: section, list: listFlag }));
1662
+ } else if (command === 'milestone-stats') {
1663
+ const version = args[1];
1664
+ if (!version) error('Usage: pbr-tools.js milestone-stats <version>');
1665
+ output(milestoneStats(version));
1666
+ } else if (command === 'skill-section') {
1667
+ // skill-section --list <skill> — list all headings
1668
+ if (args[1] === '--list') {
1669
+ const skillName = args[2];
1670
+ if (!skillName) { error('Usage: pbr-tools.js skill-section --list <skill>'); return; }
1671
+ const listResult = listSkillHeadings(skillName);
1672
+ output(listResult);
1673
+ if (listResult.error) process.exit(1);
1674
+ } else {
1675
+ // skill-section <skill> <section...>
1676
+ const skillName = args[1];
1677
+ const sectionQuery = args.slice(2).join(' ');
1678
+ if (!skillName || !sectionQuery) {
1679
+ error('Usage: pbr-tools.js skill-section <skill> <section>');
1680
+ return;
1681
+ }
1682
+ const secResult = skillSectionGet(skillName, sectionQuery);
1683
+ output(secResult);
1684
+ if (secResult.error) process.exit(1);
1685
+ }
1686
+ } else if (command === 'step-verify') {
1687
+ // step-verify <skill> <step> <checklist-json>
1688
+ const skill = args[1];
1689
+ const step = args[2];
1690
+ const checklistStr = args[3] || '[]';
1691
+ let checklist;
1692
+ try {
1693
+ checklist = JSON.parse(checklistStr);
1694
+ } catch (_e) {
1695
+ output({ error: 'Invalid checklist JSON' });
1696
+ process.exit(1);
1697
+ return;
1698
+ }
1699
+ const svPlanningDir = planningDir;
1700
+ const svContext = {
1701
+ planningDir: svPlanningDir,
1702
+ phaseSlug: process.env.PBR_PHASE_SLUG || '',
1703
+ planId: process.env.PBR_PLAN_ID || ''
1704
+ };
1705
+ const svResult = _stepVerify(skill, step, checklist, svContext);
1706
+ output(svResult);
1707
+ if (svResult.error || svResult.all_passed === false) process.exit(1);
1708
+ } else if (command === 'build-preview') {
1709
+ const phaseSlug = args[1];
1710
+ if (!phaseSlug) {
1711
+ error('Usage: pbr-tools.js build-preview <phase-slug>');
1712
+ return;
1713
+ }
1714
+ const previewPlanningDir = planningDir;
1715
+ const previewPluginRoot = path.resolve(__dirname, '..');
1716
+ const result = _buildPreview(phaseSlug, {}, previewPlanningDir, previewPluginRoot);
1717
+ if (result && result.error) {
1718
+ output(result);
1719
+ process.exit(1);
1720
+ }
1721
+ output(result);
1722
+ } else if (command === 'suggest-alternatives') {
1723
+ const errorType = args[1];
1724
+ const altPlanningDir = planningDir;
1725
+ if (errorType === 'phase-not-found') {
1726
+ output(_phaseAlternatives(args[2] || '', altPlanningDir));
1727
+ } else if (errorType === 'missing-prereq') {
1728
+ output(_prereqAlternatives(args[2] || '', altPlanningDir));
1729
+ } else if (errorType === 'config-invalid') {
1730
+ output(_configAlternatives(args[2] || '', args[3] || '', altPlanningDir));
1731
+ } else {
1732
+ output({ error: 'Unknown error type. Valid: phase-not-found, missing-prereq, config-invalid' });
1733
+ process.exit(1);
1734
+ }
1735
+ } else if (command === 'claim' && subcommand === 'acquire') {
1736
+ const phaseSlug = args[2];
1737
+ const sidIdx = args.indexOf('--session-id');
1738
+ const sessionId = sidIdx !== -1 ? args[sidIdx + 1] : null;
1739
+ const skillIdx = args.indexOf('--skill');
1740
+ const skill = skillIdx !== -1 ? args[skillIdx + 1] : 'unknown';
1741
+ if (!phaseSlug || !sessionId) {
1742
+ error('Usage: pbr-tools.js claim acquire <phase-slug> --session-id <id> --skill <name>');
1743
+ }
1744
+ output(claimAcquire(phaseSlug, sessionId, skill));
1745
+ } else if (command === 'claim' && subcommand === 'release') {
1746
+ const phaseSlug = args[2];
1747
+ const sidIdx = args.indexOf('--session-id');
1748
+ const sessionId = sidIdx !== -1 ? args[sidIdx + 1] : null;
1749
+ if (!phaseSlug || !sessionId) {
1750
+ error('Usage: pbr-tools.js claim release <phase-slug> --session-id <id>');
1751
+ }
1752
+ output(claimRelease(phaseSlug, sessionId));
1753
+ } else if (command === 'claim' && subcommand === 'list') {
1754
+ output(claimList());
1755
+ } else if (command === 'status' && subcommand === 'render') {
1756
+ output(_statusRender(planningDir));
1757
+ } else if (command === 'suggest-next') {
1758
+ output(_suggestNext(planningDir));
1759
+ } else if (command === 'tmux' && subcommand === 'detect') {
1760
+ const tmuxEnv = process.env.TMUX || '';
1761
+ const result = {
1762
+ in_tmux: !!tmuxEnv,
1763
+ pane: process.env.TMUX_PANE || null,
1764
+ session: null
1765
+ };
1766
+ if (tmuxEnv) {
1767
+ // TMUX env format: /socket/path,PID,INDEX
1768
+ const parts = tmuxEnv.split(',');
1769
+ if (parts.length >= 1) {
1770
+ result.session = parts[0].split('/').pop() || null;
1771
+ }
1772
+ }
1773
+ output(result);
1774
+
1775
+ // ─── Quick Task Operations ─────────────────────────────────────────────────
1776
+ } else if (command === 'quick' && subcommand === 'init') {
1777
+ const desc = args.slice(2).join(' ') || '';
1778
+ const quickInitMod = require('./lib/quick-init.js');
1779
+ output(quickInitMod.quickInit(desc, planningDir));
1780
+
1781
+ // ─── Slug Generation ─────────────────────────────────────────────────────
1782
+ } else if (command === 'generate-slug' || command === 'slug-generate') {
1783
+ const text = args.slice(1).join(' ');
1784
+ if (!text) error('Usage: pbr-tools.js generate-slug <text>');
1785
+ const slug = text.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, '');
1786
+ output({ slug });
1787
+
1788
+ // ─── Parse Args ────────────────────────────────────────────────────────────
1789
+ } else if (command === 'parse-args') {
1790
+ const type = args[1];
1791
+ const rawInput = args.slice(2).join(' ');
1792
+ if (!type) error('Usage: pbr-tools.js parse-args <type> <args>\nTypes: plan, quick');
1793
+ const { parseArgs } = require('./lib/parse-args');
1794
+ output(parseArgs(type, rawInput));
1795
+
1796
+ // ─── Status Fingerprint ──────────────────────────────────────────────────
1797
+ } else if (command === 'status' && subcommand === 'fingerprint') {
1798
+ const crypto = require('crypto');
1799
+ const files = {};
1800
+ let combinedContent = '';
1801
+ for (const name of ['STATE.md', 'ROADMAP.md']) {
1802
+ const filePath = path.join(planningDir, name);
1803
+ try {
1804
+ const content = fs.readFileSync(filePath, 'utf8');
1805
+ const stat = fs.statSync(filePath);
1806
+ const hash = crypto.createHash('sha256').update(content).digest('hex').slice(0, 8);
1807
+ files[name] = {
1808
+ hash,
1809
+ mtime: stat.mtime.toISOString(),
1810
+ lines: content.split('\n').length
1811
+ };
1812
+ combinedContent += content;
1813
+ } catch {
1814
+ files[name] = { hash: null, mtime: null, lines: 0 };
1815
+ }
1816
+ }
1817
+ const fingerprint = combinedContent
1818
+ ? crypto.createHash('sha256').update(combinedContent).digest('hex').slice(0, 8)
1819
+ : null;
1820
+ let phaseDirs = 0;
1821
+ const phasesDir = path.join(planningDir, 'phases');
1822
+ try {
1823
+ const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
1824
+ phaseDirs = entries.filter(e => e.isDirectory()).length;
1825
+ } catch { /* no phases dir */ }
1826
+ output({
1827
+ fingerprint,
1828
+ files,
1829
+ phase_dirs: phaseDirs,
1830
+ timestamp: new Date().toISOString()
1831
+ });
1832
+
1833
+ } else if (command === 'quick-status') {
1834
+ const result = quickStatus();
1835
+ process.stdout.write(result.text + '\n');
1836
+
1837
+ } else if (command === 'ci-fix') {
1838
+ const dryRun = args.includes('--dry-run');
1839
+ const maxIterIdx = args.indexOf('--max-iterations');
1840
+ const maxIterations = maxIterIdx !== -1 ? parseInt(args[maxIterIdx + 1], 10) : 3;
1841
+ output(ciFix({ dryRun, maxIterations }));
1842
+
1843
+ } else if (command === 'nk') {
1844
+ // Lazy require to avoid loading for unrelated commands
1845
+ const nkLib = require(path.join(__dirname, 'lib', 'negative-knowledge'));
1846
+
1847
+ if (subcommand === 'record') {
1848
+ const titleIdx = args.indexOf('--title');
1849
+ const categoryIdx = args.indexOf('--category');
1850
+ const filesIdx = args.indexOf('--files');
1851
+ const triedIdx = args.indexOf('--tried');
1852
+ const failedIdx = args.indexOf('--failed');
1853
+ const workedIdx = args.indexOf('--worked');
1854
+ const phaseIdx = args.indexOf('--phase');
1855
+
1856
+ const title = titleIdx !== -1 ? args[titleIdx + 1] : null;
1857
+ const category = categoryIdx !== -1 ? args[categoryIdx + 1] : null;
1858
+ const tried = triedIdx !== -1 ? args[triedIdx + 1] : null;
1859
+ const failed = failedIdx !== -1 ? args[failedIdx + 1] : null;
1860
+
1861
+ if (!title || !category || !tried || !failed) {
1862
+ error('Usage: pbr-tools.js nk record --title "..." --category "build-failure" --files "f1,f2" --tried "..." --failed "..."\nRequired: --title, --category, --tried, --failed\nCategories: build-failure, verification-gap, plan-revision, debug-finding');
1863
+ }
1864
+
1865
+ const filesInvolved = filesIdx !== -1 ? (args[filesIdx + 1] || '').split(',').filter(Boolean) : [];
1866
+ const whatWorked = workedIdx !== -1 ? args[workedIdx + 1] : '';
1867
+ const phase = phaseIdx !== -1 ? args[phaseIdx + 1] : '';
1868
+
1869
+ const result = nkLib.recordFailure(planningDir, {
1870
+ title, category, filesInvolved,
1871
+ whatTried: tried, whyFailed: failed,
1872
+ whatWorked, phase
1873
+ });
1874
+ output({ ok: true, path: result.path, slug: result.slug });
1875
+
1876
+ } else if (subcommand === 'list') {
1877
+ const catIdx = args.indexOf('--category');
1878
+ const phIdx = args.indexOf('--phase');
1879
+ const stIdx = args.indexOf('--status');
1880
+ const filters = {};
1881
+ if (catIdx !== -1) filters.category = args[catIdx + 1];
1882
+ if (phIdx !== -1) filters.phase = args[phIdx + 1];
1883
+ if (stIdx !== -1) filters.status = args[stIdx + 1];
1884
+ output(nkLib.listFailures(planningDir, filters));
1885
+
1886
+ } else if (subcommand === 'resolve') {
1887
+ const slug = args[2];
1888
+ if (!slug) {
1889
+ error('Usage: pbr-tools.js nk resolve <slug>');
1890
+ }
1891
+ nkLib.resolveEntry(planningDir, slug);
1892
+ output({ ok: true });
1893
+
1894
+ } else {
1895
+ error('Usage: pbr-tools.js nk <record|list|resolve>\n nk record --title "..." --category "..." --files "f1,f2" --tried "..." --failed "..."\n nk list [--category X] [--phase X] [--status X]\n nk resolve <slug>');
1896
+ }
1897
+
1898
+ } else if (command === 'data') {
1899
+ const sub = args[1];
1900
+ if (sub === 'status') {
1901
+ output(dataStatus());
1902
+ } else if (sub === 'prune') {
1903
+ const beforeIdx = args.indexOf('--before');
1904
+ const before = beforeIdx !== -1 ? args[beforeIdx + 1] : null;
1905
+ const dryRun = args.includes('--dry-run');
1906
+ if (!before) {
1907
+ error('Usage: pbr-tools.js data prune --before <ISO-date> [--dry-run]');
1908
+ }
1909
+ output(dataPrune({ before, dryRun }));
1910
+ } else {
1911
+ error('Usage: pbr-tools.js data <status|prune>\n data status — freshness report for research/, intel/, codebase/\n data prune --before <ISO-date> [--dry-run] — archive stale files');
1912
+ }
1913
+
1914
+ // --- Graph Operations ---
1915
+ } else if (command === 'graph') {
1916
+ const graphCli = require('./lib/graph-cli');
1917
+ graphCli.handleGraphCommand(subcommand, args, planningDir, cwd, output, error);
1918
+
1919
+ // --- Hooks Perf Report ---
1920
+ } else if (command === 'hooks' && subcommand === 'perf') {
1921
+ const { summarizeHookPerf, formatPerfTable, loadPerfEntries } = require('./lib/perf');
1922
+ const lastIdx = args.indexOf('--last');
1923
+ const last = lastIdx !== -1 ? parseInt(args[lastIdx + 1], 10) : undefined;
1924
+ const jsonFlag = args.includes('--json');
1925
+ const entries = loadPerfEntries(planningDir, { last });
1926
+ const summary = summarizeHookPerf(entries);
1927
+ if (jsonFlag) {
1928
+ output(summary);
1929
+ } else {
1930
+ const table = formatPerfTable(summary);
1931
+ process.stdout.write(table + '\n');
1932
+ process.stdout.write(`\nEntries analyzed: ${entries.length}\n`);
1933
+ }
1934
+
1935
+ // --- Spec Operations ---
1936
+ } else if (command === 'spec') {
1937
+ handleSpec(args, planningDir, cwd, output, error);
1938
+
1939
+ // --- Help Operations ---
1940
+ } else if (command === 'help') {
1941
+ output(helpListCmd());
1942
+
1943
+ } else if (command === 'skill-metadata') {
1944
+ const skillName = args[1];
1945
+ if (!skillName) { error('Usage: pbr-tools.js skill-metadata <name>'); return; }
1946
+ const result = skillMetadataCmd(skillName);
1947
+ output(result);
1948
+ if (result.error) process.exit(1);
1949
+
1950
+ } else {
1951
+ error(`Unknown command: ${args.join(' ')}\nCommands: state load|check-progress|update|patch|advance-plan|record-metric, config validate|load-defaults|save-defaults|resolve-depth, validate health, verify summary|plan-structure|phase-completeness|artifacts|key-links|commits|references|spot-check, migrate [--dry-run] [--force], init execute-phase|plan-phase|quick|verify-work|resume|progress|map-codebase, state-bundle <phase>, plan-index, frontmatter, must-haves, phase-info, phase add|remove|list|complete, roadmap update-status|update-plans, history append|load, todo list|get|add|done, auto-cleanup --phase N|--milestone vN, event, llm health|status|classify|score-source|classify-error|summarize|metrics [--session <ISO>]|adjust-thresholds, learnings ingest|query|check-thresholds, nk record|list|resolve, data status|prune, graph build|query|impact|stats, hooks perf [--last N] [--json], spec parse|diff|reverse|impact, milestone-stats <version>, context-triage [--agents-done N] [--plans-total N] [--step NAME], ci-poll <run-id> [--timeout <seconds>], ci-fix [--dry-run] [--max-iterations N], rollback <manifest-path>, session get|set|clear|dump, claim acquire|release|list, skill-section <skill> <section>|--list <skill>, step-verify <skill> <step> <checklist-json>, suggest-alternatives phase-not-found|missing-prereq|config-invalid [args], tmux detect, quick init, generate-slug|slug-generate, parse-args plan|quick, status fingerprint, quick-status, help, skill-metadata <name>`);
1952
+ }
1953
+ } catch (e) {
1954
+ error(e.message);
1955
+ }
1956
+ }
1957
+
1958
+ if (require.main === module || process.argv[1] === __filename) { main().catch(err => { process.stderr.write(err.message + '\n'); process.exit(1); }); }
1959
+ module.exports = { KNOWN_AGENTS, initExecutePhase, initPlanPhase, initQuick, initVerifyWork, initResume, initProgress, initStateBundle: stateBundle, stateBundle, statePatch, stateAdvancePlan, stateRecordMetric, stateRecordActivity, stateUpdateProgress, parseStateMd, parseRoadmapMd, parseYamlFrontmatter, parseMustHaves, countMustHaves, stateLoad, stateCheckProgress, configLoad, configClearCache, configValidate, lockedFileUpdate, planIndex, determinePhaseStatus, findFiles, atomicWrite, tailLines, frontmatter, mustHavesCollect, phaseInfo, stateUpdate, roadmapUpdateStatus, roadmapUpdatePlans, roadmapAnalyze, updateFrontmatterField, updateTableRow, findRoadmapRow, resolveDepthProfile, DEPTH_PROFILE_DEFAULTS, historyAppend, historyLoad, VALID_STATUS_TRANSITIONS, validateStatusTransition, writeActiveSkill, validateProject, phaseAdd, phaseRemove, phaseList, loadUserDefaults, saveUserDefaults, mergeUserDefaults, USER_DEFAULTS_PATH, todoList, todoGet, todoAdd, todoDone, migrate, verifySpotCheck, referenceGet, milestoneStats, contextTriage, stalenessCheck, summaryGate, checkpointInit, checkpointUpdate, seedsMatch, ciPoll, ciFix, parseJestOutput: _parseJestOutput, parseLintOutput: _parseLintOutput, autoFixLint: _autoFixLint, runCiFixLoop: _runCiFixLoop, rollbackPlan, sessionLoad, sessionSave, SESSION_ALLOWED_KEYS, claimAcquire, claimRelease, claimList, skillSectionGet, listSkillHeadings, stepVerify: _stepVerify, phaseAlternatives: _phaseAlternatives, prerequisiteAlternatives: _prereqAlternatives, configAlternatives: _configAlternatives, phaseComplete, phaseInsert, quickStatus, autoCloseTodos, autoArchiveNotes, buildCleanupContext, helpListCmd, skillMetadataCmd, initMapCodebase };
1960
+ // NOTE: validateProject, phaseAdd, phaseRemove, phaseList were previously CLI-only (not exported).
1961
+ // They are now exported for testability. This is additive and backwards-compatible.