@sienklogic/plan-build-run 2.19.0 → 2.19.1

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 (977) hide show
  1. package/CHANGELOG.md +1265 -320
  2. package/CLAUDE.md +56 -34
  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 +142 -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 +213 -0
  16. package/dashboard/server/routes/config.js +64 -0
  17. package/dashboard/server/routes/health.js +95 -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 +214 -0
  29. package/dashboard/server/services/file-watcher.js +105 -0
  30. package/dashboard/server/services/planning-reader.js +741 -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 +1420 -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 +100 -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 +216 -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 +223 -36
  156. package/plugins/pbr/agents/roadmapper.md +397 -0
  157. package/plugins/pbr/agents/synthesizer.md +170 -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 +162 -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 +241 -0
  226. package/plugins/pbr/dist/check-read-first.js +345 -0
  227. package/plugins/pbr/dist/check-roadmap-sync.js +503 -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 +452 -0
  231. package/plugins/pbr/dist/check-summary-gate.js +199 -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 +172 -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 +606 -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 +569 -0
  251. package/plugins/pbr/dist/pbr-tools.js +2044 -0
  252. package/plugins/pbr/dist/post-bash-triage.js +154 -0
  253. package/plugins/pbr/dist/post-compact.js +135 -0
  254. package/plugins/pbr/dist/post-hoc.js +286 -0
  255. package/plugins/pbr/dist/post-write-dispatch.js +279 -0
  256. package/plugins/pbr/dist/post-write-quality.js +208 -0
  257. package/plugins/pbr/dist/pre-bash-dispatch.js +218 -0
  258. package/plugins/pbr/dist/pre-skill-dispatch.js +114 -0
  259. package/plugins/pbr/dist/pre-task-dispatch.js +297 -0
  260. package/plugins/pbr/dist/pre-write-dispatch.js +234 -0
  261. package/plugins/pbr/dist/progress-tracker.js +198 -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 +683 -0
  268. package/plugins/pbr/dist/session-tracker.js +124 -0
  269. package/plugins/pbr/dist/status-line.js +847 -0
  270. package/plugins/pbr/dist/suggest-compact.js +315 -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 +271 -0
  277. package/plugins/pbr/dist/validate-skill-args.js +222 -0
  278. package/plugins/pbr/dist/validate-task.js +301 -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/behavioral-contexts.md +53 -0
  297. package/plugins/pbr/references/checkpoints.md +723 -104
  298. package/plugins/pbr/references/config-reference.md +472 -10
  299. package/plugins/pbr/references/continuation-format.md +1 -0
  300. package/plugins/pbr/references/decimal-phase-calculation.md +65 -0
  301. package/plugins/pbr/references/deviation-rules.md +12 -0
  302. package/plugins/pbr/references/git-integration.md +110 -27
  303. package/plugins/pbr/references/git-planning-commit.md +35 -0
  304. package/plugins/pbr/references/model-profile-resolution.md +34 -0
  305. package/plugins/pbr/references/model-profiles.md +90 -7
  306. package/plugins/pbr/references/model-selection.md +1 -1
  307. package/plugins/pbr/references/node-repair.md +48 -0
  308. package/plugins/pbr/references/plan-authoring.md +65 -0
  309. package/plugins/pbr/references/plan-format.md +161 -10
  310. package/plugins/pbr/references/questioning.md +138 -49
  311. package/plugins/pbr/references/reading-verification.md +4 -4
  312. package/plugins/pbr/references/tdd.md +263 -0
  313. package/plugins/pbr/references/ui-brand.md +449 -0
  314. package/plugins/pbr/references/verification-overrides.md +39 -0
  315. package/plugins/pbr/references/verification-patterns.md +529 -113
  316. package/plugins/pbr/scripts/architecture-guard.js +59 -0
  317. package/plugins/pbr/scripts/audit-checks/behavioral-compliance.js +2098 -0
  318. package/plugins/pbr/scripts/audit-checks/error-analysis.js +989 -0
  319. package/plugins/pbr/scripts/audit-checks/feature-verification.js +723 -0
  320. package/plugins/pbr/scripts/audit-checks/index.js +433 -0
  321. package/plugins/pbr/scripts/audit-checks/infrastructure.js +816 -0
  322. package/plugins/pbr/scripts/audit-checks/quality-metrics.js +452 -0
  323. package/plugins/pbr/scripts/audit-checks/session-quality.js +980 -0
  324. package/plugins/pbr/scripts/audit-checks/si-agent-hook-config-checks.js +466 -0
  325. package/plugins/pbr/scripts/audit-checks/si-cross-cutting-checks.js +272 -0
  326. package/plugins/pbr/scripts/audit-checks/si-skill-checks.js +424 -0
  327. package/plugins/pbr/scripts/audit-checks/workflow-compliance.js +1211 -0
  328. package/plugins/pbr/scripts/audit-dimensions.js +556 -0
  329. package/plugins/pbr/scripts/auto-continue.js +192 -31
  330. package/plugins/pbr/scripts/block-skill-self-read.js +124 -0
  331. package/plugins/pbr/scripts/check-agent-state-write.js +63 -0
  332. package/plugins/pbr/scripts/check-config-change.js +162 -0
  333. package/plugins/pbr/scripts/check-cross-plugin-sync.js +93 -0
  334. package/plugins/pbr/scripts/check-dangerous-commands.js +18 -5
  335. package/plugins/pbr/scripts/check-direct-state-write.js +37 -0
  336. package/plugins/pbr/scripts/check-phase-boundary.js +3 -8
  337. package/plugins/pbr/scripts/check-plan-format.js +166 -277
  338. package/plugins/pbr/scripts/check-read-first.js +345 -0
  339. package/plugins/pbr/scripts/check-roadmap-sync.js +167 -10
  340. package/plugins/pbr/scripts/check-skill-workflow.js +24 -27
  341. package/plugins/pbr/scripts/check-state-sync.js +339 -215
  342. package/plugins/pbr/scripts/check-subagent-output.js +338 -276
  343. package/plugins/pbr/scripts/check-summary-gate.js +2 -1
  344. package/plugins/pbr/scripts/config-schema.json +1247 -95
  345. package/plugins/pbr/scripts/context-bridge.js +425 -0
  346. package/plugins/pbr/scripts/context-budget-check.js +169 -14
  347. package/plugins/pbr/scripts/context-quality.js +271 -0
  348. package/plugins/pbr/scripts/enforce-context-budget.js +138 -0
  349. package/plugins/pbr/scripts/enforce-pbr-workflow.js +277 -0
  350. package/plugins/pbr/scripts/event-handler.js +127 -87
  351. package/plugins/pbr/scripts/event-logger.js +58 -25
  352. package/plugins/pbr/scripts/feedback-loop.js +172 -0
  353. package/plugins/pbr/scripts/graph-update.js +422 -0
  354. package/plugins/pbr/scripts/hook-logger.js +69 -35
  355. package/plugins/pbr/scripts/hook-server-client.js +361 -0
  356. package/plugins/pbr/scripts/hook-server.js +606 -0
  357. package/plugins/pbr/scripts/hooks-schema.json +13 -5
  358. package/plugins/pbr/scripts/instructions-loaded.js +173 -0
  359. package/plugins/pbr/scripts/intent-router.cjs +147 -0
  360. package/plugins/pbr/scripts/intercept-plan-mode.js +52 -18
  361. package/plugins/pbr/scripts/lib/alternatives.js +203 -0
  362. package/plugins/pbr/scripts/lib/audit.js +65 -0
  363. package/plugins/pbr/scripts/lib/auto-cleanup.js +221 -0
  364. package/plugins/pbr/scripts/lib/auto-verify.js +103 -0
  365. package/plugins/pbr/scripts/lib/autonomy.js +91 -0
  366. package/plugins/pbr/scripts/lib/build.js +719 -0
  367. package/plugins/pbr/scripts/lib/ci-fix-loop.js +228 -0
  368. package/plugins/pbr/scripts/lib/circuit-state.js +133 -0
  369. package/plugins/pbr/scripts/lib/commands.js +483 -0
  370. package/plugins/pbr/scripts/lib/completion.js +377 -0
  371. package/plugins/pbr/scripts/lib/compound.js +216 -0
  372. package/plugins/pbr/scripts/lib/config.js +1315 -0
  373. package/plugins/pbr/scripts/lib/context.js +254 -0
  374. package/plugins/pbr/scripts/lib/contextual-help.js +207 -0
  375. package/plugins/pbr/scripts/lib/convention-detector.js +413 -0
  376. package/plugins/pbr/scripts/lib/core.js +1569 -0
  377. package/plugins/pbr/scripts/lib/dashboard-launch.js +364 -0
  378. package/plugins/pbr/scripts/lib/data-hygiene.js +179 -0
  379. package/plugins/pbr/scripts/lib/decision-extraction.js +183 -0
  380. package/plugins/pbr/scripts/lib/decisions.js +194 -0
  381. package/plugins/pbr/scripts/lib/dependency-break.js +147 -0
  382. package/plugins/pbr/scripts/lib/format-validators.js +1050 -0
  383. package/plugins/pbr/scripts/lib/frontmatter.js +302 -0
  384. package/plugins/pbr/scripts/lib/gates/advisories.js +129 -0
  385. package/plugins/pbr/scripts/lib/gates/build-dependency.js +115 -0
  386. package/plugins/pbr/scripts/lib/gates/build-executor.js +104 -0
  387. package/plugins/pbr/scripts/lib/gates/doc-existence.js +46 -0
  388. package/plugins/pbr/scripts/lib/gates/helpers.js +93 -0
  389. package/plugins/pbr/scripts/lib/gates/inline-execution.js +185 -0
  390. package/plugins/pbr/scripts/lib/gates/milestone-complete.js +136 -0
  391. package/plugins/pbr/scripts/lib/gates/milestone-summary.js +119 -0
  392. package/plugins/pbr/scripts/lib/gates/multi-phase-loader.js +147 -0
  393. package/plugins/pbr/scripts/lib/gates/plan-executor.js +36 -0
  394. package/plugins/pbr/scripts/lib/gates/plan-validation.js +114 -0
  395. package/plugins/pbr/scripts/lib/gates/quick-executor.js +76 -0
  396. package/plugins/pbr/scripts/lib/gates/review-planner.js +61 -0
  397. package/plugins/pbr/scripts/lib/gates/review-verifier.js +69 -0
  398. package/plugins/pbr/scripts/lib/gates/rich-agent-context.js +143 -0
  399. package/plugins/pbr/scripts/lib/gates/user-confirmation.js +93 -0
  400. package/plugins/pbr/scripts/lib/graph-cli.js +89 -0
  401. package/plugins/pbr/scripts/lib/graph.js +553 -0
  402. package/plugins/pbr/scripts/lib/health-checks.js +107 -0
  403. package/plugins/pbr/scripts/lib/health-phase06.js +120 -0
  404. package/plugins/pbr/scripts/lib/health.js +133 -0
  405. package/plugins/pbr/scripts/lib/help.js +151 -0
  406. package/plugins/pbr/scripts/lib/history.js +150 -0
  407. package/plugins/pbr/scripts/lib/hypothesis-runner.js +127 -0
  408. package/plugins/pbr/scripts/lib/impact-analysis.js +319 -0
  409. package/plugins/pbr/scripts/lib/incidents.js +190 -0
  410. package/plugins/pbr/scripts/lib/init.js +643 -0
  411. package/plugins/pbr/scripts/lib/insights-parser.js +320 -0
  412. package/plugins/pbr/scripts/lib/intel.js +653 -0
  413. package/plugins/pbr/scripts/lib/learnings.js +511 -0
  414. package/plugins/pbr/scripts/lib/local-llm/client.js +237 -0
  415. package/plugins/pbr/scripts/lib/local-llm/health.js +12 -0
  416. package/plugins/pbr/scripts/lib/local-llm/index.js +89 -0
  417. package/plugins/pbr/scripts/lib/local-llm/metrics.js +20 -0
  418. package/plugins/pbr/scripts/lib/local-llm/operations/classify-artifact.js +4 -0
  419. package/plugins/pbr/scripts/lib/local-llm/operations/classify-commit.js +4 -0
  420. package/plugins/pbr/scripts/lib/local-llm/operations/classify-error.js +4 -0
  421. package/plugins/pbr/scripts/lib/local-llm/operations/classify-file-intent.js +4 -0
  422. package/plugins/pbr/scripts/lib/local-llm/operations/score-source.js +72 -0
  423. package/plugins/pbr/scripts/lib/local-llm/operations/summarize-context.js +62 -0
  424. package/plugins/pbr/scripts/lib/local-llm/operations/triage-test-output.js +12 -0
  425. package/plugins/pbr/scripts/lib/local-llm/operations/validate-task.js +4 -0
  426. package/plugins/pbr/scripts/lib/local-llm/router.js +101 -0
  427. package/plugins/pbr/scripts/lib/local-llm/shadow.js +60 -0
  428. package/plugins/pbr/scripts/lib/local-llm/threshold-tuner.js +118 -0
  429. package/plugins/pbr/scripts/lib/migrate.js +298 -0
  430. package/plugins/pbr/scripts/lib/milestone.js +306 -0
  431. package/plugins/pbr/scripts/lib/negative-knowledge.js +194 -0
  432. package/plugins/pbr/scripts/lib/notification-throttle.js +141 -0
  433. package/plugins/pbr/scripts/lib/onboarding-generator.js +288 -0
  434. package/plugins/pbr/scripts/lib/parse-args.js +134 -0
  435. package/plugins/pbr/scripts/lib/pattern-routing.js +55 -0
  436. package/plugins/pbr/scripts/lib/patterns.js +272 -0
  437. package/plugins/pbr/scripts/lib/perf.js +190 -0
  438. package/plugins/pbr/scripts/lib/phase.js +1027 -0
  439. package/plugins/pbr/scripts/lib/pid-lock.js +154 -0
  440. package/plugins/pbr/scripts/lib/post-hoc.js +160 -0
  441. package/plugins/pbr/scripts/lib/pre-commit-checks.js +220 -0
  442. package/plugins/pbr/scripts/lib/pre-research.js +133 -0
  443. package/plugins/pbr/scripts/lib/preview.js +174 -0
  444. package/plugins/pbr/scripts/lib/progress-visualization.js +296 -0
  445. package/plugins/pbr/scripts/lib/quick-init.js +131 -0
  446. package/plugins/pbr/scripts/lib/reference.js +236 -0
  447. package/plugins/pbr/scripts/lib/requirements.js +153 -0
  448. package/plugins/pbr/scripts/lib/resolve-root.js +66 -0
  449. package/plugins/pbr/scripts/lib/reverse-spec.js +259 -0
  450. package/plugins/pbr/scripts/lib/roadmap.js +1113 -0
  451. package/plugins/pbr/scripts/lib/security-scan.js +200 -0
  452. package/plugins/pbr/scripts/lib/session-briefing.js +895 -0
  453. package/plugins/pbr/scripts/lib/skill-section.js +99 -0
  454. package/plugins/pbr/scripts/lib/smart-next-task.js +207 -0
  455. package/plugins/pbr/scripts/lib/snapshot-manager.js +232 -0
  456. package/plugins/pbr/scripts/lib/spec-diff.js +209 -0
  457. package/plugins/pbr/scripts/lib/spec-engine.js +189 -0
  458. package/plugins/pbr/scripts/lib/spot-check.js +642 -0
  459. package/plugins/pbr/scripts/lib/state-queue.js +171 -0
  460. package/plugins/pbr/scripts/lib/state.js +1187 -0
  461. package/plugins/pbr/scripts/lib/status-render.js +511 -0
  462. package/plugins/pbr/scripts/lib/step-verify.js +149 -0
  463. package/plugins/pbr/scripts/lib/subagent-validators.js +1059 -0
  464. package/plugins/pbr/scripts/lib/suggest-next.js +435 -0
  465. package/plugins/pbr/scripts/lib/team-composer.js +87 -0
  466. package/plugins/pbr/scripts/lib/team-coordinator.js +153 -0
  467. package/plugins/pbr/scripts/lib/tech-debt-scanner.js +116 -0
  468. package/plugins/pbr/scripts/lib/template.js +222 -0
  469. package/plugins/pbr/scripts/lib/templates.js +362 -0
  470. package/plugins/pbr/scripts/lib/test-cache.js +54 -0
  471. package/plugins/pbr/scripts/lib/test-selection.js +163 -0
  472. package/plugins/pbr/scripts/lib/todo.js +300 -0
  473. package/plugins/pbr/scripts/lib/trust-gate.js +84 -0
  474. package/plugins/pbr/scripts/lib/verify.js +1473 -0
  475. package/plugins/pbr/scripts/lib/wiring-check.js +196 -0
  476. package/plugins/pbr/scripts/log-notification.js +131 -0
  477. package/plugins/pbr/scripts/log-subagent.js +203 -18
  478. package/plugins/pbr/scripts/log-tool-failure.js +60 -8
  479. package/plugins/pbr/scripts/milestone-learnings.js +569 -0
  480. package/plugins/pbr/scripts/package.json +1 -1
  481. package/plugins/pbr/scripts/pbr-tools.js +1833 -1167
  482. package/plugins/pbr/scripts/post-bash-triage.js +154 -0
  483. package/plugins/pbr/scripts/post-compact.js +135 -0
  484. package/plugins/pbr/scripts/post-hoc.js +286 -0
  485. package/plugins/pbr/scripts/post-write-dispatch.js +237 -31
  486. package/plugins/pbr/scripts/post-write-quality.js +4 -3
  487. package/plugins/pbr/scripts/pre-bash-dispatch.js +154 -52
  488. package/plugins/pbr/scripts/pre-skill-dispatch.js +114 -0
  489. package/plugins/pbr/scripts/pre-task-dispatch.js +297 -0
  490. package/plugins/pbr/scripts/pre-write-dispatch.js +170 -73
  491. package/plugins/pbr/scripts/progress-tracker.js +144 -307
  492. package/plugins/pbr/scripts/prompt-guard.js +114 -0
  493. package/plugins/pbr/scripts/prompt-routing.js +209 -0
  494. package/plugins/pbr/scripts/quick-status.js +179 -0
  495. package/plugins/pbr/scripts/record-incident.js +37 -0
  496. package/plugins/pbr/scripts/risk-classifier.cjs +123 -0
  497. package/plugins/pbr/scripts/run-hook.js +62 -10
  498. package/plugins/pbr/scripts/session-cleanup.js +458 -29
  499. package/plugins/pbr/scripts/session-tracker.js +124 -0
  500. package/plugins/pbr/scripts/status-line.js +591 -32
  501. package/plugins/pbr/scripts/suggest-compact.js +203 -7
  502. package/plugins/pbr/scripts/sync-context-to-claude.js +100 -0
  503. package/plugins/pbr/scripts/task-completed.js +165 -4
  504. package/plugins/pbr/scripts/test/config.test.js +126 -0
  505. package/plugins/pbr/scripts/test/cross-platform.test.js +131 -0
  506. package/plugins/pbr/scripts/test/fixtures/config.json +20 -0
  507. package/plugins/pbr/scripts/test/fixtures/plan.md +54 -0
  508. package/plugins/pbr/scripts/test/fixtures/project.md +30 -0
  509. package/plugins/pbr/scripts/test/fixtures/roadmap.md +55 -0
  510. package/plugins/pbr/scripts/test/fixtures/state.md +60 -0
  511. package/plugins/pbr/scripts/test/fixtures/summary.md +35 -0
  512. package/plugins/pbr/scripts/test/fixtures.test.js +184 -0
  513. package/plugins/pbr/scripts/test/phase.test.js +142 -0
  514. package/plugins/pbr/scripts/test/roadmap.test.js +96 -0
  515. package/plugins/pbr/scripts/test/state.test.js +163 -0
  516. package/plugins/pbr/scripts/track-context-budget.js +368 -99
  517. package/plugins/pbr/scripts/track-user-gates.js +88 -0
  518. package/plugins/pbr/scripts/trust-tracker.js +193 -0
  519. package/plugins/pbr/scripts/validate-commit.js +97 -26
  520. package/plugins/pbr/scripts/validate-skill-args.js +87 -15
  521. package/plugins/pbr/scripts/validate-task.js +112 -626
  522. package/plugins/pbr/scripts/worktree-create.js +144 -0
  523. package/plugins/pbr/scripts/worktree-remove.js +147 -0
  524. package/plugins/pbr/skills/audit/SKILL.md +195 -24
  525. package/plugins/pbr/skills/audit-fix/SKILL.md +326 -0
  526. package/plugins/pbr/skills/autonomous/SKILL.md +545 -0
  527. package/plugins/pbr/skills/backlog/SKILL.md +56 -0
  528. package/plugins/pbr/skills/begin/SKILL.md +507 -153
  529. package/plugins/pbr/skills/begin/templates/STATE.md.tmpl +1 -2
  530. package/plugins/pbr/skills/begin/templates/config.json.tmpl +415 -36
  531. package/plugins/pbr/skills/begin/templates/researcher-prompt.md.tmpl +28 -0
  532. package/plugins/pbr/skills/begin/templates/roadmap-prompt.md.tmpl +28 -3
  533. package/plugins/pbr/skills/begin/templates/synthesis-prompt.md.tmpl +33 -5
  534. package/plugins/pbr/skills/build/SKILL.md +1040 -354
  535. package/plugins/pbr/skills/build/templates/continuation-prompt.md.tmpl +26 -0
  536. package/plugins/pbr/skills/build/templates/executor-prompt.md.tmpl +77 -0
  537. package/plugins/pbr/skills/build/templates/inline-verifier-prompt.md.tmpl +33 -0
  538. package/plugins/pbr/skills/config/SKILL.md +111 -9
  539. package/plugins/pbr/skills/continue/SKILL.md +113 -33
  540. package/plugins/pbr/skills/dashboard/SKILL.md +21 -9
  541. package/plugins/pbr/skills/debug/SKILL.md +70 -12
  542. package/plugins/pbr/skills/debug/templates/continuation-prompt.md.tmpl +12 -1
  543. package/plugins/pbr/skills/debug/templates/initial-investigation-prompt.md.tmpl +12 -5
  544. package/plugins/pbr/skills/discuss/SKILL.md +206 -25
  545. package/plugins/pbr/skills/discuss/templates/CONTEXT.md.tmpl +21 -1
  546. package/plugins/pbr/skills/do/SKILL.md +119 -24
  547. package/plugins/pbr/skills/explore/SKILL.md +95 -20
  548. package/plugins/pbr/skills/fast/SKILL.md +94 -0
  549. package/plugins/pbr/skills/forensics/SKILL.md +144 -0
  550. package/plugins/pbr/skills/health/SKILL.md +35 -117
  551. package/plugins/pbr/skills/help/SKILL.md +83 -101
  552. package/plugins/pbr/skills/import/SKILL.md +332 -13
  553. package/plugins/pbr/skills/intel/SKILL.md +131 -0
  554. package/plugins/pbr/skills/list-phase-assumptions/SKILL.md +231 -0
  555. package/plugins/pbr/skills/milestone/SKILL.md +421 -263
  556. package/plugins/pbr/skills/milestone/templates/audit-output.md.tmpl +76 -0
  557. package/plugins/pbr/skills/milestone/templates/complete-output.md.tmpl +32 -0
  558. package/plugins/pbr/skills/milestone/templates/edge-cases.md +54 -0
  559. package/plugins/pbr/skills/milestone/templates/gaps-output.md.tmpl +25 -0
  560. package/plugins/pbr/skills/milestone/templates/integration-checker-prompt.md.tmpl +25 -0
  561. package/plugins/pbr/skills/milestone/templates/new-output.md.tmpl +29 -0
  562. package/plugins/pbr/skills/milestone-summary/SKILL.md +86 -0
  563. package/plugins/pbr/skills/note/SKILL.md +20 -4
  564. package/plugins/pbr/skills/pause/SKILL.md +53 -14
  565. package/plugins/pbr/skills/pause/templates/continue-here.md.tmpl +33 -52
  566. package/plugins/pbr/skills/plan/SKILL.md +526 -280
  567. package/plugins/pbr/skills/plan/templates/checker-prompt.md.tmpl +5 -2
  568. package/plugins/pbr/skills/plan/templates/completion-output.md.tmpl +27 -0
  569. package/plugins/pbr/skills/plan/templates/planner-prompt.md.tmpl +27 -1
  570. package/plugins/pbr/skills/plan/templates/revision-prompt.md.tmpl +21 -5
  571. package/plugins/pbr/skills/profile/SKILL.md +185 -0
  572. package/plugins/pbr/skills/profile-user/SKILL.md +226 -0
  573. package/plugins/pbr/skills/quick/SKILL.md +434 -100
  574. package/plugins/pbr/skills/release/SKILL.md +206 -0
  575. package/plugins/pbr/skills/resume/SKILL.md +169 -46
  576. package/plugins/pbr/skills/review/SKILL.md +217 -164
  577. package/plugins/pbr/skills/review/templates/verifier-prompt.md.tmpl +7 -0
  578. package/plugins/pbr/skills/scan/SKILL.md +151 -106
  579. package/plugins/pbr/skills/scan/templates/mapper-prompt.md.tmpl +5 -56
  580. package/plugins/pbr/skills/seed/SKILL.md +87 -0
  581. package/plugins/pbr/skills/session-report/SKILL.md +130 -0
  582. package/plugins/pbr/skills/setup/SKILL.md +149 -202
  583. package/plugins/pbr/skills/shared/agent-context-enrichment.md +21 -0
  584. package/plugins/pbr/skills/shared/agent-type-resolution.md +32 -0
  585. package/plugins/pbr/skills/shared/commit-planning-docs.md +8 -0
  586. package/plugins/pbr/skills/shared/context-budget.md +66 -1
  587. package/plugins/pbr/skills/shared/context-loader-task.md +18 -11
  588. package/plugins/pbr/skills/shared/digest-select.md +2 -2
  589. package/plugins/pbr/skills/shared/domain-probes.md +1 -1
  590. package/plugins/pbr/skills/shared/error-reporting.md +38 -60
  591. package/plugins/pbr/skills/shared/gate-prompts.md +4 -2
  592. package/plugins/pbr/skills/shared/memory-capture.md +48 -0
  593. package/plugins/pbr/skills/shared/phase-argument-parsing.md +4 -4
  594. package/plugins/pbr/skills/shared/revision-loop.md +24 -6
  595. package/plugins/pbr/skills/shared/state-update.md +47 -54
  596. package/plugins/pbr/skills/shared/universal-anti-patterns.md +27 -4
  597. package/plugins/pbr/skills/ship/SKILL.md +155 -0
  598. package/plugins/pbr/skills/stats/SKILL.md +80 -0
  599. package/plugins/pbr/skills/status/SKILL.md +184 -119
  600. package/plugins/pbr/skills/test/SKILL.md +254 -0
  601. package/plugins/pbr/skills/thread/SKILL.md +73 -0
  602. package/plugins/pbr/skills/todo/SKILL.md +28 -72
  603. package/plugins/pbr/skills/ui-phase/SKILL.md +180 -0
  604. package/plugins/pbr/skills/ui-review/SKILL.md +206 -0
  605. package/plugins/pbr/skills/undo/SKILL.md +221 -0
  606. package/plugins/pbr/skills/validate-phase/SKILL.md +362 -0
  607. package/plugins/pbr/templates/CONTEXT.md.tmpl +45 -20
  608. package/plugins/pbr/templates/DISCOVERY.md.tmpl +29 -0
  609. package/plugins/pbr/templates/DISCUSSION-LOG.md.tmpl +49 -0
  610. package/plugins/pbr/templates/HANDOFF.json.tmpl +30 -0
  611. package/plugins/pbr/templates/INTEGRATION-REPORT.md.tmpl +18 -2
  612. package/plugins/pbr/templates/MILESTONE-AUDIT.md.tmpl +44 -0
  613. package/plugins/pbr/templates/PROJECT.md.tmpl +126 -0
  614. package/plugins/pbr/templates/REQUIREMENTS.md.tmpl +96 -0
  615. package/plugins/pbr/templates/RETROSPECTIVE.md.tmpl +43 -0
  616. package/plugins/pbr/templates/ROADMAP.md.tmpl +108 -14
  617. package/plugins/pbr/templates/SUMMARY-complex.md.tmpl +133 -0
  618. package/plugins/pbr/templates/SUMMARY-minimal.md.tmpl +55 -0
  619. package/plugins/pbr/templates/SUMMARY.md.tmpl +21 -0
  620. package/plugins/pbr/templates/UAT.md.tmpl +94 -0
  621. package/plugins/pbr/templates/UI-SPEC.md.tmpl +144 -0
  622. package/plugins/pbr/templates/VALIDATION.md.tmpl +94 -0
  623. package/plugins/pbr/templates/VERIFICATION-DETAIL.md.tmpl +49 -13
  624. package/plugins/pbr/templates/project-CONTEXT.md.tmpl +59 -0
  625. package/plugins/pbr/templates/research-outputs/ARCHITECTURE.md.tmpl +91 -0
  626. package/plugins/pbr/templates/research-outputs/FEATURES.md.tmpl +64 -0
  627. package/plugins/pbr/templates/research-outputs/PITFALLS.md.tmpl +50 -0
  628. package/plugins/pbr/templates/research-outputs/STACK.md.tmpl +63 -0
  629. package/plugins/pbr/templates/research-outputs/SUMMARY.md.tmpl +98 -0
  630. package/scripts/build-hooks.js +61 -0
  631. package/scripts/check-ci.js +100 -0
  632. package/scripts/clean-changelog.js +364 -0
  633. package/scripts/generate-derivatives.js +581 -0
  634. package/scripts/posttest.js +93 -0
  635. package/scripts/release.js +262 -0
  636. package/scripts/run-tests.cjs +29 -0
  637. package/scripts/test-wrapper.js +43 -0
  638. package/dashboard/bin/cli.js +0 -25
  639. package/dashboard/public/css/layout.css +0 -704
  640. package/dashboard/public/css/status-colors.css +0 -98
  641. package/dashboard/public/css/tokens.css +0 -59
  642. package/dashboard/public/js/htmx-title.js +0 -5
  643. package/dashboard/public/js/sidebar-toggle.js +0 -34
  644. package/dashboard/public/js/sse-client.js +0 -100
  645. package/dashboard/public/js/theme-toggle.js +0 -46
  646. package/dashboard/src/app.js +0 -91
  647. package/dashboard/src/middleware/current-phase.js +0 -24
  648. package/dashboard/src/middleware/errorHandler.js +0 -52
  649. package/dashboard/src/middleware/notFoundHandler.js +0 -9
  650. package/dashboard/src/repositories/planning.repository.js +0 -130
  651. package/dashboard/src/routes/events.routes.js +0 -45
  652. package/dashboard/src/routes/index.routes.js +0 -35
  653. package/dashboard/src/routes/pages.routes.js +0 -426
  654. package/dashboard/src/server.js +0 -42
  655. package/dashboard/src/services/analytics.service.js +0 -141
  656. package/dashboard/src/services/dashboard.service.js +0 -309
  657. package/dashboard/src/services/milestone.service.js +0 -222
  658. package/dashboard/src/services/notes.service.js +0 -50
  659. package/dashboard/src/services/phase.service.js +0 -232
  660. package/dashboard/src/services/project.service.js +0 -57
  661. package/dashboard/src/services/roadmap.service.js +0 -258
  662. package/dashboard/src/services/sse.service.js +0 -58
  663. package/dashboard/src/services/todo.service.js +0 -272
  664. package/dashboard/src/services/watcher.service.js +0 -48
  665. package/dashboard/src/utils/cache.js +0 -55
  666. package/dashboard/src/views/analytics.ejs +0 -5
  667. package/dashboard/src/views/coming-soon.ejs +0 -11
  668. package/dashboard/src/views/dependencies.ejs +0 -5
  669. package/dashboard/src/views/error.ejs +0 -20
  670. package/dashboard/src/views/index.ejs +0 -5
  671. package/dashboard/src/views/milestone-detail.ejs +0 -5
  672. package/dashboard/src/views/milestones.ejs +0 -5
  673. package/dashboard/src/views/notes.ejs +0 -5
  674. package/dashboard/src/views/partials/analytics-content.ejs +0 -90
  675. package/dashboard/src/views/partials/breadcrumbs.ejs +0 -14
  676. package/dashboard/src/views/partials/dashboard-content.ejs +0 -84
  677. package/dashboard/src/views/partials/dependencies-content.ejs +0 -48
  678. package/dashboard/src/views/partials/empty-state.ejs +0 -7
  679. package/dashboard/src/views/partials/footer.ejs +0 -3
  680. package/dashboard/src/views/partials/head.ejs +0 -30
  681. package/dashboard/src/views/partials/header.ejs +0 -21
  682. package/dashboard/src/views/partials/layout-bottom.ejs +0 -43
  683. package/dashboard/src/views/partials/layout-top.ejs +0 -16
  684. package/dashboard/src/views/partials/milestone-detail-content.ejs +0 -20
  685. package/dashboard/src/views/partials/milestones-content.ejs +0 -88
  686. package/dashboard/src/views/partials/notes-content.ejs +0 -23
  687. package/dashboard/src/views/partials/phase-content.ejs +0 -193
  688. package/dashboard/src/views/partials/phase-doc-content.ejs +0 -38
  689. package/dashboard/src/views/partials/phases-content.ejs +0 -124
  690. package/dashboard/src/views/partials/roadmap-content.ejs +0 -180
  691. package/dashboard/src/views/partials/sidebar.ejs +0 -99
  692. package/dashboard/src/views/partials/todo-create-content.ejs +0 -54
  693. package/dashboard/src/views/partials/todo-detail-content.ejs +0 -42
  694. package/dashboard/src/views/partials/todos-content.ejs +0 -97
  695. package/dashboard/src/views/phase-detail.ejs +0 -5
  696. package/dashboard/src/views/phase-doc.ejs +0 -5
  697. package/dashboard/src/views/phases.ejs +0 -5
  698. package/dashboard/src/views/roadmap.ejs +0 -5
  699. package/dashboard/src/views/todo-create.ejs +0 -5
  700. package/dashboard/src/views/todo-detail.ejs +0 -5
  701. package/dashboard/src/views/todos.ejs +0 -5
  702. package/plugins/copilot-pbr/CHANGELOG.md +0 -19
  703. package/plugins/copilot-pbr/README.md +0 -139
  704. package/plugins/copilot-pbr/agents/audit.agent.md +0 -113
  705. package/plugins/copilot-pbr/agents/codebase-mapper.agent.md +0 -151
  706. package/plugins/copilot-pbr/agents/debugger.agent.md +0 -182
  707. package/plugins/copilot-pbr/agents/executor.agent.md +0 -267
  708. package/plugins/copilot-pbr/agents/general.agent.md +0 -88
  709. package/plugins/copilot-pbr/agents/integration-checker.agent.md +0 -119
  710. package/plugins/copilot-pbr/agents/plan-checker.agent.md +0 -208
  711. package/plugins/copilot-pbr/agents/planner.agent.md +0 -238
  712. package/plugins/copilot-pbr/agents/researcher.agent.md +0 -186
  713. package/plugins/copilot-pbr/agents/synthesizer.agent.md +0 -126
  714. package/plugins/copilot-pbr/agents/verifier.agent.md +0 -228
  715. package/plugins/copilot-pbr/hooks/hooks.json +0 -156
  716. package/plugins/copilot-pbr/plugin.json +0 -30
  717. package/plugins/copilot-pbr/references/agent-anti-patterns.md +0 -25
  718. package/plugins/copilot-pbr/references/agent-contracts.md +0 -297
  719. package/plugins/copilot-pbr/references/agent-interactions.md +0 -135
  720. package/plugins/copilot-pbr/references/agent-teams.md +0 -55
  721. package/plugins/copilot-pbr/references/checkpoints.md +0 -158
  722. package/plugins/copilot-pbr/references/common-bug-patterns.md +0 -14
  723. package/plugins/copilot-pbr/references/config-reference.md +0 -442
  724. package/plugins/copilot-pbr/references/continuation-format.md +0 -213
  725. package/plugins/copilot-pbr/references/deviation-rules.md +0 -113
  726. package/plugins/copilot-pbr/references/git-integration.md +0 -227
  727. package/plugins/copilot-pbr/references/integration-patterns.md +0 -118
  728. package/plugins/copilot-pbr/references/model-profiles.md +0 -100
  729. package/plugins/copilot-pbr/references/model-selection.md +0 -32
  730. package/plugins/copilot-pbr/references/pbr-rules.md +0 -195
  731. package/plugins/copilot-pbr/references/pbr-tools-cli.md +0 -285
  732. package/plugins/copilot-pbr/references/plan-authoring.md +0 -182
  733. package/plugins/copilot-pbr/references/plan-format.md +0 -288
  734. package/plugins/copilot-pbr/references/planning-config.md +0 -214
  735. package/plugins/copilot-pbr/references/questioning.md +0 -215
  736. package/plugins/copilot-pbr/references/reading-verification.md +0 -128
  737. package/plugins/copilot-pbr/references/stub-patterns.md +0 -161
  738. package/plugins/copilot-pbr/references/subagent-coordination.md +0 -120
  739. package/plugins/copilot-pbr/references/ui-formatting.md +0 -444
  740. package/plugins/copilot-pbr/references/verification-patterns.md +0 -199
  741. package/plugins/copilot-pbr/references/wave-execution.md +0 -96
  742. package/plugins/copilot-pbr/rules/pbr-workflow.mdc +0 -48
  743. package/plugins/copilot-pbr/setup.ps1 +0 -93
  744. package/plugins/copilot-pbr/setup.sh +0 -93
  745. package/plugins/copilot-pbr/skills/audit/SKILL.md +0 -330
  746. package/plugins/copilot-pbr/skills/begin/SKILL.md +0 -589
  747. package/plugins/copilot-pbr/skills/begin/templates/PROJECT.md.tmpl +0 -34
  748. package/plugins/copilot-pbr/skills/begin/templates/REQUIREMENTS.md.tmpl +0 -19
  749. package/plugins/copilot-pbr/skills/begin/templates/STATE.md.tmpl +0 -50
  750. package/plugins/copilot-pbr/skills/begin/templates/config.json.tmpl +0 -64
  751. package/plugins/copilot-pbr/skills/begin/templates/researcher-prompt.md.tmpl +0 -20
  752. package/plugins/copilot-pbr/skills/begin/templates/roadmap-prompt.md.tmpl +0 -31
  753. package/plugins/copilot-pbr/skills/begin/templates/synthesis-prompt.md.tmpl +0 -17
  754. package/plugins/copilot-pbr/skills/build/SKILL.md +0 -960
  755. package/plugins/copilot-pbr/skills/config/SKILL.md +0 -250
  756. package/plugins/copilot-pbr/skills/continue/SKILL.md +0 -159
  757. package/plugins/copilot-pbr/skills/dashboard/SKILL.md +0 -43
  758. package/plugins/copilot-pbr/skills/debug/SKILL.md +0 -508
  759. package/plugins/copilot-pbr/skills/debug/templates/continuation-prompt.md.tmpl +0 -17
  760. package/plugins/copilot-pbr/skills/debug/templates/initial-investigation-prompt.md.tmpl +0 -28
  761. package/plugins/copilot-pbr/skills/discuss/SKILL.md +0 -353
  762. package/plugins/copilot-pbr/skills/discuss/templates/CONTEXT.md.tmpl +0 -62
  763. package/plugins/copilot-pbr/skills/discuss/templates/decision-categories.md +0 -10
  764. package/plugins/copilot-pbr/skills/do/SKILL.md +0 -66
  765. package/plugins/copilot-pbr/skills/explore/SKILL.md +0 -373
  766. package/plugins/copilot-pbr/skills/health/SKILL.md +0 -283
  767. package/plugins/copilot-pbr/skills/health/templates/check-pattern.md.tmpl +0 -31
  768. package/plugins/copilot-pbr/skills/health/templates/output-format.md.tmpl +0 -64
  769. package/plugins/copilot-pbr/skills/help/SKILL.md +0 -170
  770. package/plugins/copilot-pbr/skills/import/SKILL.md +0 -502
  771. package/plugins/copilot-pbr/skills/milestone/SKILL.md +0 -745
  772. package/plugins/copilot-pbr/skills/milestone/templates/audit-report.md.tmpl +0 -49
  773. package/plugins/copilot-pbr/skills/milestone/templates/stats-file.md.tmpl +0 -31
  774. package/plugins/copilot-pbr/skills/note/SKILL.md +0 -213
  775. package/plugins/copilot-pbr/skills/pause/SKILL.md +0 -247
  776. package/plugins/copilot-pbr/skills/pause/templates/continue-here.md.tmpl +0 -72
  777. package/plugins/copilot-pbr/skills/plan/SKILL.md +0 -662
  778. package/plugins/copilot-pbr/skills/plan/templates/checker-prompt.md.tmpl +0 -22
  779. package/plugins/copilot-pbr/skills/plan/templates/gap-closure-prompt.md.tmpl +0 -33
  780. package/plugins/copilot-pbr/skills/plan/templates/planner-prompt.md.tmpl +0 -39
  781. package/plugins/copilot-pbr/skills/plan/templates/researcher-prompt.md.tmpl +0 -20
  782. package/plugins/copilot-pbr/skills/plan/templates/revision-prompt.md.tmpl +0 -24
  783. package/plugins/copilot-pbr/skills/quick/SKILL.md +0 -376
  784. package/plugins/copilot-pbr/skills/resume/SKILL.md +0 -399
  785. package/plugins/copilot-pbr/skills/review/SKILL.md +0 -653
  786. package/plugins/copilot-pbr/skills/review/templates/debugger-prompt.md.tmpl +0 -61
  787. package/plugins/copilot-pbr/skills/review/templates/gap-planner-prompt.md.tmpl +0 -41
  788. package/plugins/copilot-pbr/skills/review/templates/verifier-prompt.md.tmpl +0 -116
  789. package/plugins/copilot-pbr/skills/scan/SKILL.md +0 -299
  790. package/plugins/copilot-pbr/skills/scan/templates/mapper-prompt.md.tmpl +0 -202
  791. package/plugins/copilot-pbr/skills/setup/SKILL.md +0 -296
  792. package/plugins/copilot-pbr/skills/shared/commit-planning-docs.md +0 -36
  793. package/plugins/copilot-pbr/skills/shared/config-loading.md +0 -103
  794. package/plugins/copilot-pbr/skills/shared/context-budget.md +0 -41
  795. package/plugins/copilot-pbr/skills/shared/context-loader-task.md +0 -87
  796. package/plugins/copilot-pbr/skills/shared/digest-select.md +0 -80
  797. package/plugins/copilot-pbr/skills/shared/domain-probes.md +0 -126
  798. package/plugins/copilot-pbr/skills/shared/error-reporting.md +0 -81
  799. package/plugins/copilot-pbr/skills/shared/gate-prompts.md +0 -389
  800. package/plugins/copilot-pbr/skills/shared/phase-argument-parsing.md +0 -46
  801. package/plugins/copilot-pbr/skills/shared/progress-display.md +0 -53
  802. package/plugins/copilot-pbr/skills/shared/revision-loop.md +0 -82
  803. package/plugins/copilot-pbr/skills/shared/state-loading.md +0 -63
  804. package/plugins/copilot-pbr/skills/shared/state-update.md +0 -162
  805. package/plugins/copilot-pbr/skills/shared/universal-anti-patterns.md +0 -38
  806. package/plugins/copilot-pbr/skills/status/SKILL.md +0 -362
  807. package/plugins/copilot-pbr/skills/statusline/SKILL.md +0 -149
  808. package/plugins/copilot-pbr/skills/todo/SKILL.md +0 -279
  809. package/plugins/copilot-pbr/templates/CONTEXT.md.tmpl +0 -53
  810. package/plugins/copilot-pbr/templates/INTEGRATION-REPORT.md.tmpl +0 -152
  811. package/plugins/copilot-pbr/templates/RESEARCH-SUMMARY.md.tmpl +0 -98
  812. package/plugins/copilot-pbr/templates/ROADMAP.md.tmpl +0 -41
  813. package/plugins/copilot-pbr/templates/SUMMARY.md.tmpl +0 -82
  814. package/plugins/copilot-pbr/templates/VERIFICATION-DETAIL.md.tmpl +0 -117
  815. package/plugins/copilot-pbr/templates/codebase/ARCHITECTURE.md.tmpl +0 -98
  816. package/plugins/copilot-pbr/templates/codebase/CONCERNS.md.tmpl +0 -93
  817. package/plugins/copilot-pbr/templates/codebase/CONVENTIONS.md.tmpl +0 -104
  818. package/plugins/copilot-pbr/templates/codebase/INTEGRATIONS.md.tmpl +0 -78
  819. package/plugins/copilot-pbr/templates/codebase/STACK.md.tmpl +0 -78
  820. package/plugins/copilot-pbr/templates/codebase/STRUCTURE.md.tmpl +0 -80
  821. package/plugins/copilot-pbr/templates/codebase/TESTING.md.tmpl +0 -107
  822. package/plugins/copilot-pbr/templates/continue-here.md.tmpl +0 -74
  823. package/plugins/copilot-pbr/templates/prompt-partials/phase-project-context.md.tmpl +0 -38
  824. package/plugins/copilot-pbr/templates/research/ARCHITECTURE.md.tmpl +0 -124
  825. package/plugins/copilot-pbr/templates/research/STACK.md.tmpl +0 -71
  826. package/plugins/copilot-pbr/templates/research/SUMMARY.md.tmpl +0 -112
  827. package/plugins/copilot-pbr/templates/research-outputs/phase-research.md.tmpl +0 -81
  828. package/plugins/copilot-pbr/templates/research-outputs/project-research.md.tmpl +0 -99
  829. package/plugins/copilot-pbr/templates/research-outputs/synthesis.md.tmpl +0 -36
  830. package/plugins/cursor-pbr/.cursor-plugin/plugin.json +0 -32
  831. package/plugins/cursor-pbr/CHANGELOG.md +0 -15
  832. package/plugins/cursor-pbr/README.md +0 -123
  833. package/plugins/cursor-pbr/agents/audit.md +0 -178
  834. package/plugins/cursor-pbr/agents/codebase-mapper.md +0 -150
  835. package/plugins/cursor-pbr/agents/debugger.md +0 -181
  836. package/plugins/cursor-pbr/agents/executor.md +0 -266
  837. package/plugins/cursor-pbr/agents/general.md +0 -87
  838. package/plugins/cursor-pbr/agents/integration-checker.md +0 -118
  839. package/plugins/cursor-pbr/agents/plan-checker.md +0 -207
  840. package/plugins/cursor-pbr/agents/planner.md +0 -237
  841. package/plugins/cursor-pbr/agents/researcher.md +0 -185
  842. package/plugins/cursor-pbr/agents/synthesizer.md +0 -125
  843. package/plugins/cursor-pbr/agents/verifier.md +0 -227
  844. package/plugins/cursor-pbr/assets/.gitkeep +0 -0
  845. package/plugins/cursor-pbr/assets/logo.svg +0 -21
  846. package/plugins/cursor-pbr/hooks/hooks.json +0 -213
  847. package/plugins/cursor-pbr/references/agent-anti-patterns.md +0 -25
  848. package/plugins/cursor-pbr/references/agent-contracts.md +0 -297
  849. package/plugins/cursor-pbr/references/agent-interactions.md +0 -135
  850. package/plugins/cursor-pbr/references/agent-teams.md +0 -55
  851. package/plugins/cursor-pbr/references/checkpoints.md +0 -158
  852. package/plugins/cursor-pbr/references/common-bug-patterns.md +0 -14
  853. package/plugins/cursor-pbr/references/config-reference.md +0 -442
  854. package/plugins/cursor-pbr/references/continuation-format.md +0 -213
  855. package/plugins/cursor-pbr/references/deviation-rules.md +0 -113
  856. package/plugins/cursor-pbr/references/git-integration.md +0 -227
  857. package/plugins/cursor-pbr/references/integration-patterns.md +0 -118
  858. package/plugins/cursor-pbr/references/model-profiles.md +0 -100
  859. package/plugins/cursor-pbr/references/model-selection.md +0 -32
  860. package/plugins/cursor-pbr/references/pbr-rules.md +0 -195
  861. package/plugins/cursor-pbr/references/pbr-tools-cli.md +0 -285
  862. package/plugins/cursor-pbr/references/plan-authoring.md +0 -182
  863. package/plugins/cursor-pbr/references/plan-format.md +0 -288
  864. package/plugins/cursor-pbr/references/planning-config.md +0 -214
  865. package/plugins/cursor-pbr/references/questioning.md +0 -215
  866. package/plugins/cursor-pbr/references/reading-verification.md +0 -128
  867. package/plugins/cursor-pbr/references/stub-patterns.md +0 -161
  868. package/plugins/cursor-pbr/references/subagent-coordination.md +0 -120
  869. package/plugins/cursor-pbr/references/ui-formatting.md +0 -444
  870. package/plugins/cursor-pbr/references/verification-patterns.md +0 -199
  871. package/plugins/cursor-pbr/references/wave-execution.md +0 -96
  872. package/plugins/cursor-pbr/rules/pbr-workflow.mdc +0 -48
  873. package/plugins/cursor-pbr/setup.ps1 +0 -78
  874. package/plugins/cursor-pbr/setup.sh +0 -83
  875. package/plugins/cursor-pbr/skills/audit/SKILL.md +0 -331
  876. package/plugins/cursor-pbr/skills/begin/SKILL.md +0 -589
  877. package/plugins/cursor-pbr/skills/begin/templates/PROJECT.md.tmpl +0 -34
  878. package/plugins/cursor-pbr/skills/begin/templates/REQUIREMENTS.md.tmpl +0 -19
  879. package/plugins/cursor-pbr/skills/begin/templates/STATE.md.tmpl +0 -50
  880. package/plugins/cursor-pbr/skills/begin/templates/config.json.tmpl +0 -64
  881. package/plugins/cursor-pbr/skills/begin/templates/researcher-prompt.md.tmpl +0 -20
  882. package/plugins/cursor-pbr/skills/begin/templates/roadmap-prompt.md.tmpl +0 -31
  883. package/plugins/cursor-pbr/skills/begin/templates/synthesis-prompt.md.tmpl +0 -17
  884. package/plugins/cursor-pbr/skills/build/SKILL.md +0 -961
  885. package/plugins/cursor-pbr/skills/config/SKILL.md +0 -252
  886. package/plugins/cursor-pbr/skills/continue/SKILL.md +0 -159
  887. package/plugins/cursor-pbr/skills/dashboard/SKILL.md +0 -44
  888. package/plugins/cursor-pbr/skills/debug/SKILL.md +0 -512
  889. package/plugins/cursor-pbr/skills/debug/templates/continuation-prompt.md.tmpl +0 -17
  890. package/plugins/cursor-pbr/skills/debug/templates/initial-investigation-prompt.md.tmpl +0 -28
  891. package/plugins/cursor-pbr/skills/discuss/SKILL.md +0 -354
  892. package/plugins/cursor-pbr/skills/discuss/templates/CONTEXT.md.tmpl +0 -62
  893. package/plugins/cursor-pbr/skills/discuss/templates/decision-categories.md +0 -10
  894. package/plugins/cursor-pbr/skills/do/SKILL.md +0 -67
  895. package/plugins/cursor-pbr/skills/explore/SKILL.md +0 -376
  896. package/plugins/cursor-pbr/skills/health/SKILL.md +0 -283
  897. package/plugins/cursor-pbr/skills/health/templates/check-pattern.md.tmpl +0 -31
  898. package/plugins/cursor-pbr/skills/health/templates/output-format.md.tmpl +0 -64
  899. package/plugins/cursor-pbr/skills/help/SKILL.md +0 -170
  900. package/plugins/cursor-pbr/skills/import/SKILL.md +0 -505
  901. package/plugins/cursor-pbr/skills/milestone/SKILL.md +0 -746
  902. package/plugins/cursor-pbr/skills/milestone/templates/audit-report.md.tmpl +0 -49
  903. package/plugins/cursor-pbr/skills/milestone/templates/stats-file.md.tmpl +0 -31
  904. package/plugins/cursor-pbr/skills/note/SKILL.md +0 -214
  905. package/plugins/cursor-pbr/skills/pause/SKILL.md +0 -248
  906. package/plugins/cursor-pbr/skills/pause/templates/continue-here.md.tmpl +0 -72
  907. package/plugins/cursor-pbr/skills/plan/SKILL.md +0 -663
  908. package/plugins/cursor-pbr/skills/plan/templates/checker-prompt.md.tmpl +0 -22
  909. package/plugins/cursor-pbr/skills/plan/templates/gap-closure-prompt.md.tmpl +0 -33
  910. package/plugins/cursor-pbr/skills/plan/templates/planner-prompt.md.tmpl +0 -39
  911. package/plugins/cursor-pbr/skills/plan/templates/researcher-prompt.md.tmpl +0 -20
  912. package/plugins/cursor-pbr/skills/plan/templates/revision-prompt.md.tmpl +0 -24
  913. package/plugins/cursor-pbr/skills/quick/SKILL.md +0 -376
  914. package/plugins/cursor-pbr/skills/resume/SKILL.md +0 -399
  915. package/plugins/cursor-pbr/skills/review/SKILL.md +0 -654
  916. package/plugins/cursor-pbr/skills/review/templates/debugger-prompt.md.tmpl +0 -61
  917. package/plugins/cursor-pbr/skills/review/templates/gap-planner-prompt.md.tmpl +0 -41
  918. package/plugins/cursor-pbr/skills/review/templates/verifier-prompt.md.tmpl +0 -116
  919. package/plugins/cursor-pbr/skills/scan/SKILL.md +0 -300
  920. package/plugins/cursor-pbr/skills/scan/templates/mapper-prompt.md.tmpl +0 -202
  921. package/plugins/cursor-pbr/skills/setup/SKILL.md +0 -296
  922. package/plugins/cursor-pbr/skills/shared/commit-planning-docs.md +0 -36
  923. package/plugins/cursor-pbr/skills/shared/config-loading.md +0 -103
  924. package/plugins/cursor-pbr/skills/shared/context-budget.md +0 -41
  925. package/plugins/cursor-pbr/skills/shared/context-loader-task.md +0 -87
  926. package/plugins/cursor-pbr/skills/shared/digest-select.md +0 -80
  927. package/plugins/cursor-pbr/skills/shared/domain-probes.md +0 -126
  928. package/plugins/cursor-pbr/skills/shared/error-reporting.md +0 -81
  929. package/plugins/cursor-pbr/skills/shared/gate-prompts.md +0 -389
  930. package/plugins/cursor-pbr/skills/shared/phase-argument-parsing.md +0 -46
  931. package/plugins/cursor-pbr/skills/shared/progress-display.md +0 -53
  932. package/plugins/cursor-pbr/skills/shared/revision-loop.md +0 -82
  933. package/plugins/cursor-pbr/skills/shared/state-loading.md +0 -63
  934. package/plugins/cursor-pbr/skills/shared/state-update.md +0 -162
  935. package/plugins/cursor-pbr/skills/shared/universal-anti-patterns.md +0 -38
  936. package/plugins/cursor-pbr/skills/status/SKILL.md +0 -362
  937. package/plugins/cursor-pbr/skills/statusline/SKILL.md +0 -150
  938. package/plugins/cursor-pbr/skills/todo/SKILL.md +0 -280
  939. package/plugins/cursor-pbr/templates/CONTEXT.md.tmpl +0 -53
  940. package/plugins/cursor-pbr/templates/INTEGRATION-REPORT.md.tmpl +0 -152
  941. package/plugins/cursor-pbr/templates/RESEARCH-SUMMARY.md.tmpl +0 -98
  942. package/plugins/cursor-pbr/templates/ROADMAP.md.tmpl +0 -41
  943. package/plugins/cursor-pbr/templates/SUMMARY.md.tmpl +0 -82
  944. package/plugins/cursor-pbr/templates/VERIFICATION-DETAIL.md.tmpl +0 -117
  945. package/plugins/cursor-pbr/templates/codebase/ARCHITECTURE.md.tmpl +0 -98
  946. package/plugins/cursor-pbr/templates/codebase/CONCERNS.md.tmpl +0 -93
  947. package/plugins/cursor-pbr/templates/codebase/CONVENTIONS.md.tmpl +0 -104
  948. package/plugins/cursor-pbr/templates/codebase/INTEGRATIONS.md.tmpl +0 -78
  949. package/plugins/cursor-pbr/templates/codebase/STACK.md.tmpl +0 -78
  950. package/plugins/cursor-pbr/templates/codebase/STRUCTURE.md.tmpl +0 -80
  951. package/plugins/cursor-pbr/templates/codebase/TESTING.md.tmpl +0 -107
  952. package/plugins/cursor-pbr/templates/continue-here.md.tmpl +0 -74
  953. package/plugins/cursor-pbr/templates/prompt-partials/phase-project-context.md.tmpl +0 -38
  954. package/plugins/cursor-pbr/templates/research/ARCHITECTURE.md.tmpl +0 -124
  955. package/plugins/cursor-pbr/templates/research/STACK.md.tmpl +0 -71
  956. package/plugins/cursor-pbr/templates/research/SUMMARY.md.tmpl +0 -112
  957. package/plugins/cursor-pbr/templates/research-outputs/phase-research.md.tmpl +0 -81
  958. package/plugins/cursor-pbr/templates/research-outputs/project-research.md.tmpl +0 -99
  959. package/plugins/cursor-pbr/templates/research-outputs/synthesis.md.tmpl +0 -36
  960. package/plugins/pbr/references/agent-interactions.md +0 -134
  961. package/plugins/pbr/references/pbr-rules.md +0 -194
  962. package/plugins/pbr/references/pbr-tools-cli.md +0 -285
  963. package/plugins/pbr/references/planning-config.md +0 -213
  964. package/plugins/pbr/references/subagent-coordination.md +0 -119
  965. package/plugins/pbr/references/ui-formatting.md +0 -444
  966. package/plugins/pbr/scripts/validate-plugin-structure.js +0 -183
  967. package/plugins/pbr/skills/milestone/templates/audit-report.md.tmpl +0 -48
  968. package/plugins/pbr/skills/shared/progress-display.md +0 -53
  969. package/plugins/pbr/skills/shared/state-loading.md +0 -62
  970. package/plugins/pbr/templates/RESEARCH-SUMMARY.md.tmpl +0 -97
  971. package/plugins/pbr/templates/research/ARCHITECTURE.md.tmpl +0 -124
  972. package/plugins/pbr/templates/research/STACK.md.tmpl +0 -71
  973. package/plugins/pbr/templates/research/SUMMARY.md.tmpl +0 -112
  974. package/plugins/pbr/templates/research-outputs/phase-research.md.tmpl +0 -81
  975. package/plugins/pbr/templates/research-outputs/project-research.md.tmpl +0 -99
  976. package/plugins/pbr/templates/research-outputs/synthesis.md.tmpl +0 -36
  977. /package/plugins/pbr/references/{agent-anti-patterns.md → archive/agent-anti-patterns.md} +0 -0
@@ -0,0 +1,1113 @@
1
+ /**
2
+ * lib/roadmap.cjs — ROADMAP.md operations for Plan-Build-Run tools.
3
+ *
4
+ * Handles parsing and updating the ROADMAP.md phase overview table,
5
+ * comprehensive analysis with disk cross-referencing, and dynamic
6
+ * phase operations (append, remove, insert, renumber).
7
+ *
8
+ * Hybrid module merging PBR reference features with GSD-unique utilities.
9
+ */
10
+
11
+ const fs = require('fs');
12
+ const path = require('path');
13
+ const {
14
+ lockedFileUpdate,
15
+ validateStatusTransition,
16
+ parseYamlFrontmatter,
17
+ findFiles
18
+ } = require('./core');
19
+
20
+ // --- Parsers ---
21
+
22
+ function parseRoadmapMd(content) {
23
+ // Normalize CRLF to LF at parse boundary for cross-platform support
24
+ const normalized = content.replace(/\r\n/g, '\n');
25
+ // Strip <details>/<summary> tags so collapsed milestones are parsed
26
+ const stripped = normalized
27
+ .replace(/<\/?details>/gi, '')
28
+ .replace(/<\/?summary>/gi, '');
29
+ const result = { phases: [], has_progress_table: false };
30
+
31
+ // Parse Progress table (primary) or Phase Overview table (legacy fallback)
32
+ const progressMatch = stripped.match(/## Progress[\s\S]*?(?=\n##(?!\s*Progress)|\s*$)/);
33
+ // Only use Progress table if it actually contains a markdown table with pipe rows
34
+ const progressRows = progressMatch ? progressMatch[0].split('\n').filter(r => r.includes('|')) : [];
35
+ if (progressMatch && progressRows.length >= 2) {
36
+ result.has_progress_table = true;
37
+ const rows = progressRows;
38
+ if (rows.length >= 2) {
39
+ // Dynamic column detection from header row
40
+ const headers = rows[0].split('|').map(h => h.trim().toLowerCase()).filter(Boolean);
41
+ const colIdx = {
42
+ phase: headers.findIndex(h => /phase/i.test(h)),
43
+ milestone: headers.findIndex(h => /milestone/i.test(h)),
44
+ plans: headers.findIndex(h => /plans?\s*complete/i.test(h)),
45
+ status: headers.findIndex(h => /status/i.test(h)),
46
+ completed: headers.findIndex(h => /completed/i.test(h))
47
+ };
48
+
49
+ // Skip header (0) and separator (1) rows
50
+ for (let i = 2; i < rows.length; i++) {
51
+ const cols = rows[i].split('|').map(c => c.trim()).filter(Boolean);
52
+ if (cols.length >= 2) {
53
+ result.phases.push({
54
+ number: colIdx.phase !== -1 ? cols[colIdx.phase] || '' : cols[0] || '',
55
+ name: '', // Name is embedded in Phase column as "N. Name"
56
+ goal: '',
57
+ plans: colIdx.plans !== -1 && colIdx.plans < cols.length ? cols[colIdx.plans] : '',
58
+ milestone: colIdx.milestone !== -1 && colIdx.milestone < cols.length ? cols[colIdx.milestone] : '',
59
+ status: colIdx.status !== -1 && colIdx.status < cols.length ? cols[colIdx.status] : 'pending',
60
+ completed: colIdx.completed !== -1 && colIdx.completed < cols.length ? cols[colIdx.completed] : ''
61
+ });
62
+ }
63
+ }
64
+ }
65
+ } else {
66
+ // Fallback: try legacy Phase Overview table
67
+ const overviewMatch = stripped.match(/## Phase Overview[\s\S]*?\|[\s\S]*?(?=\n##|\s*$)/);
68
+ if (overviewMatch) {
69
+ const rows = overviewMatch[0].split('\n').filter(r => r.includes('|'));
70
+ for (let i = 2; i < rows.length; i++) {
71
+ const cols = rows[i].split('|').map(c => c.trim()).filter(Boolean);
72
+ if (cols.length >= 3) {
73
+ result.phases.push({
74
+ number: cols[0],
75
+ name: cols[1],
76
+ goal: cols[2],
77
+ plans: cols[3] || '',
78
+ wave: cols[4] || '',
79
+ status: cols[5] || 'pending'
80
+ });
81
+ }
82
+ }
83
+ }
84
+ // Even without a parseable Progress table, note if the heading exists
85
+ result.has_progress_table = !!progressMatch;
86
+ }
87
+
88
+ // Heading-based phase discovery fallback: if no table rows produced phases,
89
+ // scan for "## Phase N: Name" / "### Phase N: Name" headings (v14.0+ format)
90
+ if (result.phases.length === 0) {
91
+ const headingRe = /#{2,4}\s*Phase\s+(\d+(?:\.\d+)*)\s*:\s*([^\n]+)/gi;
92
+ let hm;
93
+ while ((hm = headingRe.exec(stripped)) !== null) {
94
+ result.phases.push({
95
+ number: hm[1],
96
+ name: hm[2].trim(),
97
+ goal: '',
98
+ plans: '',
99
+ status: 'unknown'
100
+ });
101
+ }
102
+ }
103
+
104
+ // Parse phase heading blocks for requirements and success criteria
105
+ const lines = stripped.split('\n');
106
+ const phaseMap = new Map();
107
+ for (const phase of result.phases) {
108
+ const numMatch = String(phase.number).match(/^(\d+)/);
109
+ if (numMatch) phaseMap.set(parseInt(numMatch[1], 10), phase);
110
+ }
111
+
112
+ for (let i = 0; i < lines.length; i++) {
113
+ const phaseMatch = lines[i].match(/^###\s+Phase\s+(\d+)\s*:\s*(.*)/i);
114
+ if (phaseMatch) {
115
+ const phaseNum = parseInt(phaseMatch[1], 10);
116
+ const phase = phaseMap.get(phaseNum);
117
+ if (phase) {
118
+ if (!phase.name) phase.name = phaseMatch[2].trim();
119
+ // Look ahead for fields
120
+ for (let j = i + 1; j < Math.min(i + 20, lines.length); j++) {
121
+ if (/^#{1,3}\s/.test(lines[j])) break;
122
+ const goalMatch = lines[j].match(/\*\*Goal:\*\*\s*(.*)/i);
123
+ if (goalMatch && !phase.goal) phase.goal = goalMatch[1].trim();
124
+ const reqMatch = lines[j].match(/\*\*Requirements:\*\*\s*(.*)/i);
125
+ if (reqMatch) phase.requirements = reqMatch[1].trim();
126
+ const critMatch = lines[j].match(/\*\*Success Criteria:\*\*\s*(.*)/i);
127
+ if (critMatch) phase.success_criteria = critMatch[1].trim();
128
+ }
129
+ }
130
+ }
131
+ }
132
+
133
+ return result;
134
+ }
135
+
136
+ // --- Table helpers ---
137
+
138
+ /**
139
+ * Find the row index of a phase in a ROADMAP.md table.
140
+ * @returns {number} Line index or -1 if not found
141
+ */
142
+ function findRoadmapRow(lines, phaseNum) {
143
+ const paddedPhase = phaseNum.padStart(2, '0');
144
+ const numericPhase = String(parseInt(phaseNum, 10));
145
+ for (let i = 0; i < lines.length; i++) {
146
+ if (!lines[i].includes('|')) continue;
147
+ // Skip separator rows
148
+ if (/^\s*\|[\s-:|]+\|\s*$/.test(lines[i])) continue;
149
+ const parts = lines[i].split('|');
150
+ if (parts.length < 3) continue;
151
+ // Search ALL columns for a phase number match (handles both old and new column layouts)
152
+ // Handles v9+ format: "| 21. Phase Name | X/Y | Status |" (number+name merged in 3-col table)
153
+ // as well as legacy formats: "| 21 | Phase Name | ... |" (separate columns)
154
+ for (let c = 1; c < parts.length - 1; c++) {
155
+ const col = (parts[c] || '').trim();
156
+ // Match "01", "1", "01.", "01. Name", etc.
157
+ const match = col.match(/^0*(\d+)\./);
158
+ if (match && (match[1] === numericPhase || col === paddedPhase)) {
159
+ return i;
160
+ }
161
+ if (col === paddedPhase || col === numericPhase) {
162
+ return i;
163
+ }
164
+ }
165
+ }
166
+ return -1;
167
+ }
168
+
169
+ /**
170
+ * Update a specific column in a markdown table row.
171
+ * @param {string} row - The full table row string (e.g., "| 01 | Setup | ... |")
172
+ * @param {number} columnIndex - 0-based column index (Phase=0, Name=1, ..., Status=5)
173
+ * @param {string} newValue - New cell value
174
+ * @returns {string} Updated row
175
+ */
176
+ function updateTableRow(row, columnIndex, newValue) {
177
+ const parts = row.split('|');
178
+ // parts[0] is empty (before first |), data starts at parts[1]
179
+ const partIndex = columnIndex + 1;
180
+ if (partIndex < parts.length) {
181
+ parts[partIndex] = ` ${newValue} `;
182
+ }
183
+ return parts.join('|');
184
+ }
185
+
186
+ /**
187
+ * Find the pipe-delimited column index for a header matching `pattern` by
188
+ * scanning backward from `rowIdx` to find the nearest header row.
189
+ * Returns the raw split('|') index (includes leading empty element), or -1.
190
+ */
191
+ function _findColumnIndex(lines, rowIdx, pattern) {
192
+ // Scan backward from rowIdx to find the header row
193
+ for (let h = rowIdx - 1; h >= 0; h--) {
194
+ if (!lines[h].includes('|')) continue;
195
+ // Skip separator rows
196
+ if (/^\s*\|[\s-:|]+\|\s*$/.test(lines[h])) continue;
197
+ // Check if this looks like a header (contains recognizable column names)
198
+ if (/phase/i.test(lines[h]) || /status/i.test(lines[h]) || /plans/i.test(lines[h])) {
199
+ const parts = lines[h].split('|');
200
+ for (let c = 0; c < parts.length; c++) {
201
+ if (pattern.test(parts[c].trim())) return c;
202
+ }
203
+ }
204
+ }
205
+ return -1;
206
+ }
207
+
208
+ // --- Mutation commands ---
209
+
210
+ /**
211
+ * Update the Status column for a phase in ROADMAP.md's Phase Overview table.
212
+ *
213
+ * @param {string} phaseNum - Phase number
214
+ * @param {string} newStatus - New status value
215
+ * @param {string} [planningDir] - Path to .planning directory
216
+ */
217
+ function roadmapUpdateStatus(phaseNum, newStatus, planningDir) {
218
+ const dir = planningDir || path.join(process.env.PBR_PROJECT_ROOT || process.cwd(), '.planning');
219
+ const roadmapPath = path.join(dir, 'ROADMAP.md');
220
+ if (!fs.existsSync(roadmapPath)) {
221
+ return { success: false, error: 'ROADMAP.md not found' };
222
+ }
223
+
224
+ let oldStatus = null;
225
+
226
+ const result = lockedFileUpdate(roadmapPath, (content) => {
227
+ const lineEnding = content.includes('\r\n') ? '\r\n' : '\n';
228
+ const lines = content.replace(/\r\n/g, '\n').split('\n');
229
+ const rowIdx = findRoadmapRow(lines, phaseNum);
230
+ if (rowIdx === -1) {
231
+ return content; // No matching row found
232
+ }
233
+ // Dynamic column detection: find Status column from nearest header row
234
+ const statusColIdx = _findColumnIndex(lines, rowIdx, /status/i);
235
+ const parts = lines[rowIdx].split('|');
236
+ if (statusColIdx !== -1 && statusColIdx < parts.length) {
237
+ oldStatus = parts[statusColIdx] ? parts[statusColIdx].trim() : 'unknown';
238
+ parts[statusColIdx] = ` ${newStatus} `;
239
+ lines[rowIdx] = parts.join('|');
240
+ } else {
241
+ // Fallback: detect column count to pick correct index
242
+ // 3-col table (v9+ format): Status at raw index 3; legacy 6-col: index 5
243
+ const colCount = parts.filter(p => p.trim()).length;
244
+ const fallbackIdx = colCount <= 3 ? 3 : 5;
245
+ oldStatus = parts[fallbackIdx] ? parts[fallbackIdx].trim() : (parts[4] ? parts[4].trim() : 'unknown');
246
+ lines[rowIdx] = updateTableRow(lines[rowIdx], fallbackIdx - 1, newStatus);
247
+ }
248
+ return lines.join(lineEnding);
249
+ });
250
+
251
+ if (!oldStatus) {
252
+ return { success: false, error: `Phase ${phaseNum} not found in ROADMAP.md table` };
253
+ }
254
+
255
+ // Advisory transition validation -- warn on suspicious transitions but don't block
256
+ const transition = validateStatusTransition(oldStatus, newStatus);
257
+ if (!transition.valid && transition.warning) {
258
+ process.stderr.write(`[pbr-tools] WARNING: ${transition.warning}\n`);
259
+ }
260
+
261
+ if (result.success) {
262
+ const response = { success: true, old_status: oldStatus, new_status: newStatus };
263
+ if (!transition.valid) {
264
+ response.transition_warning = transition.warning;
265
+ }
266
+ return response;
267
+ }
268
+ return { success: false, error: result.error };
269
+ }
270
+
271
+ /**
272
+ * Update the Plans column for a phase in ROADMAP.md's Phase Overview table.
273
+ *
274
+ * @param {string} phaseNum - Phase number
275
+ * @param {string} complete - Completed plan count
276
+ * @param {string} total - Total plan count
277
+ * @param {string} [planningDir] - Path to .planning directory
278
+ */
279
+ function roadmapUpdatePlans(phaseNum, complete, total, planningDir) {
280
+ const dir = planningDir || path.join(process.env.PBR_PROJECT_ROOT || process.cwd(), '.planning');
281
+ const roadmapPath = path.join(dir, 'ROADMAP.md');
282
+ if (!fs.existsSync(roadmapPath)) {
283
+ return { success: false, error: 'ROADMAP.md not found' };
284
+ }
285
+
286
+ let oldPlans = null;
287
+ const newPlans = `${complete}/${total}`;
288
+
289
+ const result = lockedFileUpdate(roadmapPath, (content) => {
290
+ const lineEnding = content.includes('\r\n') ? '\r\n' : '\n';
291
+ const lines = content.replace(/\r\n/g, '\n').split('\n');
292
+ const rowIdx = findRoadmapRow(lines, phaseNum);
293
+ if (rowIdx === -1) {
294
+ return content;
295
+ }
296
+ // Dynamic column detection: find Plans Complete column from nearest header row
297
+ const plansColIdx = _findColumnIndex(lines, rowIdx, /plans?\s*complete/i);
298
+ const parts = lines[rowIdx].split('|');
299
+ if (plansColIdx !== -1 && plansColIdx < parts.length) {
300
+ oldPlans = parts[plansColIdx] ? parts[plansColIdx].trim() : 'unknown';
301
+ parts[plansColIdx] = ` ${newPlans} `;
302
+ lines[rowIdx] = parts.join('|');
303
+ } else {
304
+ // Fallback: detect column count to pick correct index
305
+ // 3-col table (v9+ format): Plans Complete at raw index 2; legacy 6-col: index 3
306
+ const colCount = parts.filter(p => p.trim()).length;
307
+ const fallbackIdx = colCount <= 3 ? 2 : 3;
308
+ oldPlans = parts[fallbackIdx + 1] ? parts[fallbackIdx + 1].trim() : (parts[2] ? parts[2].trim() : 'unknown');
309
+ lines[rowIdx] = updateTableRow(lines[rowIdx], fallbackIdx, newPlans);
310
+ }
311
+ return lines.join(lineEnding);
312
+ });
313
+
314
+ if (!oldPlans) {
315
+ return { success: false, error: `Phase ${phaseNum} not found in ROADMAP.md table` };
316
+ }
317
+
318
+ if (result.success) {
319
+ return { success: true, old_plans: oldPlans, new_plans: newPlans };
320
+ }
321
+ return { success: false, error: result.error };
322
+ }
323
+
324
+ /**
325
+ * Update plan progress for a specific phase in ROADMAP.md.
326
+ * GSD-unique: updates progress table row, plan count in phase section,
327
+ * and checkbox completion status.
328
+ *
329
+ * @param {string} phaseNum - Phase number
330
+ * @param {string} [planningDir] - Path to .planning directory
331
+ */
332
+ function roadmapUpdatePlanProgress(phaseNum, planningDir) {
333
+ const dir = planningDir || path.join(process.env.PBR_PROJECT_ROOT || process.cwd(), '.planning');
334
+ const roadmapPath = path.join(dir, 'ROADMAP.md');
335
+ if (!fs.existsSync(roadmapPath)) {
336
+ return { success: false, error: 'ROADMAP.md not found' };
337
+ }
338
+
339
+ // Find the phase directory to count plans and summaries
340
+ const phasesDir = path.join(dir, 'phases');
341
+ if (!fs.existsSync(phasesDir)) {
342
+ return { success: false, error: 'No phases directory found' };
343
+ }
344
+
345
+ const paddedPhase = String(phaseNum).padStart(2, '0');
346
+ let phaseDir = null;
347
+ try {
348
+ const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
349
+ for (const entry of entries) {
350
+ if (entry.isDirectory() && entry.name.startsWith(paddedPhase + '-')) {
351
+ phaseDir = path.join(phasesDir, entry.name);
352
+ break;
353
+ }
354
+ }
355
+ } catch (_e) { /* ignore */ }
356
+
357
+ if (!phaseDir) {
358
+ return { success: false, error: `Phase ${phaseNum} directory not found` };
359
+ }
360
+
361
+ const planFiles = findFiles(phaseDir, /PLAN.*\.md$/i);
362
+ const summaryFiles = findFiles(phaseDir, /SUMMARY.*\.md$/i);
363
+ const planCount = planFiles.length;
364
+ const summaryCount = summaryFiles.length;
365
+
366
+ if (planCount === 0) {
367
+ return { success: false, error: 'No plans found', plan_count: 0, summary_count: 0 };
368
+ }
369
+
370
+ const isComplete = summaryCount >= planCount;
371
+ const status = isComplete ? 'Complete' : summaryCount > 0 ? 'In Progress' : 'Planned';
372
+ const today = new Date().toISOString().slice(0, 10);
373
+
374
+ const { escapeRegex } = require('./core');
375
+ const phaseEscaped = escapeRegex(String(phaseNum));
376
+
377
+ const result = lockedFileUpdate(roadmapPath, (content) => {
378
+ let updated = content;
379
+
380
+ // Progress table row: update Plans column (summaries/plans) and Status column
381
+ const tablePattern = new RegExp(
382
+ `(\\|\\s*${phaseEscaped}\\.?\\s[^|]*\\|)[^|]*(\\|)\\s*[^|]*(\\|)\\s*[^|]*(\\|)`,
383
+ 'i'
384
+ );
385
+ const dateField = isComplete ? ` ${today} ` : ' ';
386
+ updated = updated.replace(
387
+ tablePattern,
388
+ `$1 ${summaryCount}/${planCount} $2 ${status.padEnd(11)}$3${dateField}$4`
389
+ );
390
+
391
+ // Update plan count in phase detail section
392
+ const planCountPattern = new RegExp(
393
+ `(#{2,4}\\s*Phase\\s+${phaseEscaped}[\\s\\S]*?\\*\\*Plans:\\*\\*\\s*)[^\\n]+`,
394
+ 'i'
395
+ );
396
+ const planCountText = isComplete
397
+ ? `${summaryCount}/${planCount} plans complete`
398
+ : `${summaryCount}/${planCount} plans executed`;
399
+ updated = updated.replace(planCountPattern, `$1${planCountText}`);
400
+
401
+ // If complete: check checkbox
402
+ if (isComplete) {
403
+ const checkboxPattern = new RegExp(
404
+ `(-\\s*\\[)[ ](\\]\\s*.*Phase\\s+${phaseEscaped}[:\\s][^\\n]*)`,
405
+ 'i'
406
+ );
407
+ updated = updated.replace(checkboxPattern, `$1x$2 (completed ${today})`);
408
+ }
409
+
410
+ return updated;
411
+ });
412
+
413
+ if (result.success) {
414
+ return { success: true, phase: phaseNum, plan_count: planCount, summary_count: summaryCount, status, complete: isComplete };
415
+ }
416
+ return { success: false, error: result.error };
417
+ }
418
+
419
+ // --- Comprehensive analysis ---
420
+
421
+ /**
422
+ * Analyze ROADMAP.md comprehensively, cross-referencing with disk state.
423
+ *
424
+ * Returns a structured object with all phases, their goals, dependencies,
425
+ * progress, disk status, and aggregated statistics.
426
+ *
427
+ * @param {string} planningDir - Path to .planning/ directory
428
+ * @returns {{ phases: Array, current_phase: number|null, next_phase: number|null, stats: object, error?: string }}
429
+ */
430
+ function roadmapAnalyze(planningDir) {
431
+ const roadmapPath = path.join(planningDir, 'ROADMAP.md');
432
+ if (!fs.existsSync(roadmapPath)) {
433
+ return { phases: [], current_phase: null, next_phase: null, stats: _emptyStats(), error: 'ROADMAP.md not found' };
434
+ }
435
+
436
+ // snapshot pattern: single read, parse from memory -- no re-reads during analysis or renumbering
437
+ const content = fs.readFileSync(roadmapPath, 'utf8');
438
+ // Strip <details>/<summary> tags so collapsed milestones are parsed correctly
439
+ const stripped = content.replace(/<\/?details>/gi, '').replace(/<\/?summary>/gi, '');
440
+ const lines = stripped.split(/\r?\n/);
441
+
442
+ // 1. Parse phase headings, goals, dependencies from milestone sections
443
+ const phases = _parsePhaseHeadings(lines);
444
+
445
+ // 2. Parse progress tables and merge
446
+ _mergeProgressTables(lines, phases);
447
+
448
+ // 3. Parse phase checklist items and merge
449
+ _mergePhaseChecklist(lines, phases);
450
+
451
+ // 4. Cross-reference with disk
452
+ const phasesDir = path.join(planningDir, 'phases');
453
+ for (const phase of phases) {
454
+ _crossReferenceDisk(phase, phasesDir);
455
+ }
456
+
457
+ // 5. Get current_phase from STATE.md
458
+ let current_phase = null;
459
+ const statePath = path.join(planningDir, 'STATE.md');
460
+ if (fs.existsSync(statePath)) {
461
+ try {
462
+ const stateContent = fs.readFileSync(statePath, 'utf8');
463
+ const fm = parseYamlFrontmatter(stateContent);
464
+ if (fm && fm.current_phase != null) {
465
+ current_phase = typeof fm.current_phase === 'number' ? fm.current_phase : parseInt(fm.current_phase, 10);
466
+ if (isNaN(current_phase)) current_phase = null;
467
+ }
468
+ } catch (_e) { /* ignore */ }
469
+ }
470
+
471
+ // 6. Derive next_phase
472
+ let next_phase = null;
473
+ if (current_phase != null) {
474
+ // Find phases after current that are not complete
475
+ const remaining = phases
476
+ .filter(p => p.number > current_phase && p.disk_status !== 'complete')
477
+ .sort((a, b) => a.number - b.number);
478
+ if (remaining.length > 0) {
479
+ next_phase = remaining[0].number;
480
+ }
481
+ }
482
+
483
+ // 7. Compute stats
484
+ const stats = _computeStats(phases);
485
+
486
+ return { phases, current_phase, next_phase, stats };
487
+ }
488
+
489
+ function _emptyStats() {
490
+ return {
491
+ total_phases: 0,
492
+ total_plans: 0,
493
+ total_summaries: 0,
494
+ progress_percent: 0,
495
+ phases_complete: 0,
496
+ phases_remaining: 0
497
+ };
498
+ }
499
+
500
+ /**
501
+ * Parse `### Phase N:` headings within milestone `## Milestone:` sections.
502
+ */
503
+ function _parsePhaseHeadings(lines) {
504
+ const phases = [];
505
+ const phaseMap = new Map();
506
+ let currentMilestone = null;
507
+
508
+ // Strip <details>/<summary> HTML tags from lines so collapsed milestones are parsed
509
+ const cleanLines = lines.map(l => l.replace(/<\/?details>/gi, '').replace(/<\/?summary>/gi, ''));
510
+
511
+ for (let i = 0; i < cleanLines.length; i++) {
512
+ const line = cleanLines[i];
513
+
514
+ // Detect milestone heading: ## Milestone: ... or ## Milestone N: ...
515
+ const milestoneMatch = line.match(/^##\s+Milestone[:\s]+(.*)/i);
516
+ if (milestoneMatch) {
517
+ currentMilestone = milestoneMatch[1].trim();
518
+ continue;
519
+ }
520
+
521
+ // Detect phase heading: ### Phase N: Name or ### Phase NN: Name
522
+ const phaseMatch = line.match(/^###\s+Phase\s+(\d+)\s*:\s*(.*)/i);
523
+ if (phaseMatch) {
524
+ const phaseNum = parseInt(phaseMatch[1], 10);
525
+ const phaseName = phaseMatch[2].trim();
526
+
527
+ // Look ahead for **Goal:**, **Depends on:**, **Requirements:**, **Success Criteria:**
528
+ let goal = '';
529
+ let depends_on = [];
530
+ let requirements = '';
531
+ let success_criteria = '';
532
+ for (let j = i + 1; j < Math.min(i + 20, cleanLines.length); j++) {
533
+ const ahead = cleanLines[j];
534
+ // Stop at next heading
535
+ if (/^#{1,3}\s/.test(ahead)) break;
536
+
537
+ const goalMatch = ahead.match(/\*\*Goal:\*\*\s*(.*)/i);
538
+ if (goalMatch) {
539
+ goal = goalMatch[1].trim();
540
+ }
541
+
542
+ const depsMatch = ahead.match(/\*\*Depends?\s*on:\*\*\s*(.*)/i);
543
+ if (depsMatch) {
544
+ const depsStr = depsMatch[1].trim();
545
+ if (depsStr && depsStr !== 'None' && depsStr !== '-' && depsStr !== 'none') {
546
+ depends_on = depsStr.split(/[,;]/)
547
+ .map(s => s.replace(/[^0-9]/g, ''))
548
+ .filter(Boolean)
549
+ .map(Number);
550
+ }
551
+ }
552
+
553
+ const reqMatch = ahead.match(/\*\*Requirements:\*\*\s*(.*)/i);
554
+ if (reqMatch) {
555
+ requirements = reqMatch[1].trim();
556
+ }
557
+
558
+ const critMatch = ahead.match(/\*\*Success Criteria:\*\*\s*(.*)/i);
559
+ if (critMatch) {
560
+ success_criteria = critMatch[1].trim();
561
+ }
562
+ }
563
+
564
+ const entry = {
565
+ number: phaseNum,
566
+ name: phaseName,
567
+ goal,
568
+ depends_on,
569
+ requirements,
570
+ success_criteria,
571
+ milestone: currentMilestone || 'Unknown',
572
+ progress: null,
573
+ checklist_checked: null,
574
+ plan_count: 0,
575
+ summary_count: 0,
576
+ has_verification: false,
577
+ verification_result: null,
578
+ disk_status: 'no_directory'
579
+ };
580
+
581
+ phases.push(entry);
582
+ phaseMap.set(phaseNum, entry);
583
+ continue;
584
+ }
585
+ }
586
+
587
+ return phases;
588
+ }
589
+
590
+ /**
591
+ * Parse Progress tables: `| N. Phase Name | X/Y | Status |`
592
+ */
593
+ function _mergeProgressTables(lines, phases) {
594
+ const phaseMap = new Map(phases.map(p => [p.number, p]));
595
+ let inProgressSection = false;
596
+ let progressColIdx = { phase: 0, plans: 1 };
597
+
598
+ // Strip <details>/<summary> tags from lines for parsing
599
+ const cleanLines = lines.map(l => l.replace(/<\/?details>/gi, '').replace(/<\/?summary>/gi, ''));
600
+
601
+ for (const line of cleanLines) {
602
+ if (/^##\s+Progress/i.test(line)) {
603
+ inProgressSection = true;
604
+ continue;
605
+ }
606
+ if (inProgressSection && /^##\s/.test(line) && !/^##\s+Progress/i.test(line)) {
607
+ inProgressSection = false;
608
+ continue;
609
+ }
610
+
611
+ if (inProgressSection && line.includes('|')) {
612
+ const cols = line.split('|').map(c => c.trim()).filter(Boolean);
613
+
614
+ // Detect header row and extract column positions
615
+ if (/Plans?\s*Complete/i.test(line)) {
616
+ const lowerCols = cols.map(c => c.toLowerCase());
617
+ const pIdx = lowerCols.findIndex(c => /phase/i.test(c));
618
+ const plIdx = lowerCols.findIndex(c => /plans?\s*complete/i.test(c));
619
+ if (pIdx !== -1) progressColIdx.phase = pIdx;
620
+ if (plIdx !== -1) progressColIdx.plans = plIdx;
621
+ continue;
622
+ }
623
+
624
+ // Skip separator rows
625
+ if (/^[\s-:|]+$/.test(cols.join(''))) continue;
626
+
627
+ if (cols.length >= 2) {
628
+ const phaseCol = cols[progressColIdx.phase] || cols[0];
629
+ const numMatch = phaseCol.match(/^(\d+)/);
630
+ if (numMatch) {
631
+ const phaseNum = parseInt(numMatch[1], 10);
632
+ const phase = phaseMap.get(phaseNum);
633
+ if (phase) {
634
+ const plansCol = progressColIdx.plans < cols.length ? cols[progressColIdx.plans] : cols[1];
635
+ const progressMatch = plansCol.match(/(\d+)\s*\/\s*(\d+)/);
636
+ if (progressMatch) {
637
+ phase.progress = `${progressMatch[1]}/${progressMatch[2]}`;
638
+ }
639
+ }
640
+ }
641
+ }
642
+ }
643
+ }
644
+ }
645
+
646
+ /**
647
+ * Parse Phase Checklist items: `- [ ] Phase N:` or `- [x] Phase N:`
648
+ */
649
+ function _mergePhaseChecklist(lines, phases) {
650
+ const phaseMap = new Map(phases.map(p => [p.number, p]));
651
+
652
+ for (const line of lines) {
653
+ const checkMatch = line.match(/^-\s+\[([ xX])\]\s+Phase\s+(\d+)/i);
654
+ if (checkMatch) {
655
+ const checked = checkMatch[1].toLowerCase() === 'x';
656
+ const phaseNum = parseInt(checkMatch[2], 10);
657
+ const phase = phaseMap.get(phaseNum);
658
+ if (phase) {
659
+ phase.checklist_checked = checked;
660
+ }
661
+ }
662
+ }
663
+ }
664
+
665
+ /**
666
+ * Cross-reference a phase entry against files on disk.
667
+ */
668
+ function _crossReferenceDisk(phase, phasesDir) {
669
+ if (!fs.existsSync(phasesDir)) {
670
+ phase.disk_status = 'no_directory';
671
+ return;
672
+ }
673
+
674
+ // Find matching directory by phase number prefix
675
+ const paddedNum = String(phase.number).padStart(2, '0');
676
+ let phaseDir = null;
677
+ try {
678
+ const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
679
+ for (const entry of entries) {
680
+ if (entry.isDirectory() && entry.name.startsWith(paddedNum + '-')) {
681
+ phaseDir = path.join(phasesDir, entry.name);
682
+ break;
683
+ }
684
+ }
685
+ } catch (_e) { /* ignore */ }
686
+
687
+ if (!phaseDir) {
688
+ phase.disk_status = 'no_directory';
689
+ return;
690
+ }
691
+
692
+ // Count PLANs and SUMMARYs
693
+ const plans = findFiles(phaseDir, /^PLAN.*\.md$/i);
694
+ const summaries = findFiles(phaseDir, /^SUMMARY.*\.md$/i);
695
+ phase.plan_count = plans.length;
696
+ phase.summary_count = summaries.length;
697
+
698
+ // Check VERIFICATION.md
699
+ const verificationPath = path.join(phaseDir, 'VERIFICATION.md');
700
+ if (fs.existsSync(verificationPath)) {
701
+ phase.has_verification = true;
702
+ try {
703
+ const vContent = fs.readFileSync(verificationPath, 'utf8');
704
+ const fm = parseYamlFrontmatter(vContent);
705
+ if (fm && fm.result) {
706
+ phase.verification_result = fm.result;
707
+ }
708
+ } catch (_e) { /* ignore */ }
709
+ }
710
+
711
+ // Determine disk_status
712
+ if (phase.has_verification && phase.verification_result === 'passed') {
713
+ phase.disk_status = 'complete';
714
+ } else if (phase.summary_count > 0) {
715
+ phase.disk_status = 'partial';
716
+ } else if (phase.plan_count > 0) {
717
+ phase.disk_status = 'planned';
718
+ } else {
719
+ phase.disk_status = 'empty';
720
+ }
721
+ }
722
+
723
+ /**
724
+ * Compute aggregated stats from phase data.
725
+ */
726
+ function _computeStats(phases) {
727
+ let total_plans = 0;
728
+ let total_summaries = 0;
729
+ let phases_complete = 0;
730
+
731
+ for (const phase of phases) {
732
+ total_plans += phase.plan_count;
733
+ total_summaries += phase.summary_count;
734
+ if (phase.disk_status === 'complete') {
735
+ phases_complete++;
736
+ }
737
+ }
738
+
739
+ const total_phases = phases.length;
740
+ const phases_remaining = total_phases - phases_complete;
741
+ const progress_percent = total_phases > 0 ? Math.round((phases_complete / total_phases) * 100) : 0;
742
+
743
+ return {
744
+ total_phases,
745
+ total_plans,
746
+ total_summaries,
747
+ progress_percent,
748
+ phases_complete,
749
+ phases_remaining
750
+ };
751
+ }
752
+
753
+ // --- Dynamic phase operations ---
754
+
755
+ /**
756
+ * Append a new phase heading + progress row to the current (non-COMPLETED) milestone section.
757
+ *
758
+ * @param {string} planningDir - Path to .planning/ directory
759
+ * @param {number} phaseNum - Phase number to add
760
+ * @param {string} name - Human-readable phase name
761
+ * @param {string} [goal] - Goal description
762
+ * @param {number|null} [dependsOn] - Phase number this depends on
763
+ * @returns {{ success: boolean, error?: string }}
764
+ */
765
+ function roadmapAppendPhase(planningDir, phaseNum, name, goal, dependsOn) {
766
+ const roadmapPath = path.join(planningDir, 'ROADMAP.md');
767
+ if (!fs.existsSync(roadmapPath)) {
768
+ return { success: false, error: 'ROADMAP.md not found' };
769
+ }
770
+
771
+ return lockedFileUpdate(roadmapPath, (content) => {
772
+ const lines = content.split(/\r?\n/);
773
+ const lineEnding = content.includes('\r\n') ? '\r\n' : '\n';
774
+
775
+ // Find the last milestone section that is NOT completed
776
+ let lastMilestoneIdx = -1;
777
+ for (let i = 0; i < lines.length; i++) {
778
+ if (/^##\s+Milestone/i.test(lines[i]) && !/COMPLETED/i.test(lines[i])) {
779
+ lastMilestoneIdx = i;
780
+ }
781
+ }
782
+
783
+ // Build the phase heading block
784
+ const block = [];
785
+ block.push(`### Phase ${phaseNum}: ${name}`);
786
+ if (goal) block.push(`**Goal:** ${goal}`);
787
+ const depText = dependsOn ? `Phase ${dependsOn}` : 'None';
788
+ block.push(`**Depends on:** ${depText}`);
789
+ block.push('');
790
+
791
+ // Find where to insert the phase heading: before the next ## heading after the milestone
792
+ let insertIdx = lines.length;
793
+ if (lastMilestoneIdx !== -1) {
794
+ for (let i = lastMilestoneIdx + 1; i < lines.length; i++) {
795
+ if (/^##\s+[^#]/.test(lines[i])) {
796
+ insertIdx = i;
797
+ break;
798
+ }
799
+ }
800
+ }
801
+
802
+ // Insert the phase heading block
803
+ lines.splice(insertIdx, 0, ...block);
804
+
805
+ // Find and update Progress table: append a row
806
+ // Detect if existing table has Milestone column
807
+ let hasMilestoneCol = false;
808
+ let hasCompletedCol = false;
809
+ for (let i = 0; i < lines.length; i++) {
810
+ if (lines[i].includes('|') && /Plans?\s*Complete/i.test(lines[i])) {
811
+ hasMilestoneCol = /milestone/i.test(lines[i]);
812
+ hasCompletedCol = /completed/i.test(lines[i]);
813
+ break;
814
+ }
815
+ }
816
+ let progressRowLine = `| ${phaseNum}. ${name} |`;
817
+ if (hasMilestoneCol) progressRowLine += ' |';
818
+ progressRowLine += ' 0/0 | Pending |';
819
+ if (hasCompletedCol) progressRowLine += ' |';
820
+
821
+ let progressTableEnd = -1;
822
+ let inProgressSection = false;
823
+ for (let i = 0; i < lines.length; i++) {
824
+ if (/^##\s+Progress/i.test(lines[i])) {
825
+ inProgressSection = true;
826
+ continue;
827
+ }
828
+ if (inProgressSection) {
829
+ if (/^##\s/.test(lines[i]) && !/^##\s+Progress/i.test(lines[i])) {
830
+ progressTableEnd = i;
831
+ break;
832
+ }
833
+ // Track last table row
834
+ if (lines[i].includes('|')) {
835
+ progressTableEnd = i + 1;
836
+ }
837
+ }
838
+ }
839
+
840
+ if (progressTableEnd > 0) {
841
+ lines.splice(progressTableEnd, 0, progressRowLine);
842
+ }
843
+
844
+ return lines.join(lineEnding);
845
+ });
846
+ }
847
+
848
+ /**
849
+ * Remove a phase heading block and its progress table row from ROADMAP.md.
850
+ *
851
+ * @param {string} planningDir - Path to .planning/ directory
852
+ * @param {number} phaseNum - Phase number to remove
853
+ * @returns {{ success: boolean, error?: string }}
854
+ */
855
+ function roadmapRemovePhase(planningDir, phaseNum) {
856
+ const roadmapPath = path.join(planningDir, 'ROADMAP.md');
857
+ if (!fs.existsSync(roadmapPath)) {
858
+ return { success: false, error: 'ROADMAP.md not found' };
859
+ }
860
+
861
+ return lockedFileUpdate(roadmapPath, (content) => {
862
+ const lines = content.split(/\r?\n/);
863
+ const lineEnding = content.includes('\r\n') ? '\r\n' : '\n';
864
+
865
+ // Find and remove the ### Phase N: heading and its content block
866
+ let headingIdx = -1;
867
+ let blockEnd = -1;
868
+ for (let i = 0; i < lines.length; i++) {
869
+ const match = lines[i].match(/^###\s+Phase\s+(\d+)\s*:/i);
870
+ if (match && parseInt(match[1], 10) === phaseNum) {
871
+ headingIdx = i;
872
+ // Find end of this block (next ### or ## heading)
873
+ for (let j = i + 1; j < lines.length; j++) {
874
+ if (/^#{1,3}\s/.test(lines[j])) {
875
+ blockEnd = j;
876
+ break;
877
+ }
878
+ }
879
+ if (blockEnd === -1) blockEnd = lines.length;
880
+ break;
881
+ }
882
+ }
883
+
884
+ if (headingIdx !== -1) {
885
+ lines.splice(headingIdx, blockEnd - headingIdx);
886
+ }
887
+
888
+ // Remove progress table row matching "| N. " pattern
889
+ for (let i = lines.length - 1; i >= 0; i--) {
890
+ const rowMatch = lines[i].match(/^\|\s*(\d+)\./);
891
+ if (rowMatch && parseInt(rowMatch[1], 10) === phaseNum) {
892
+ lines.splice(i, 1);
893
+ break;
894
+ }
895
+ }
896
+
897
+ return lines.join(lineEnding);
898
+ });
899
+ }
900
+
901
+ /**
902
+ * Renumber all phase references >= startNum by delta in ROADMAP.md.
903
+ * Handles: ### Phase N: headings, "Phase N" in text, progress table rows "| N.",
904
+ * checklist items "Phase N:".
905
+ *
906
+ * Iterates in reverse when delta > 0 (to avoid collisions), forward when delta < 0.
907
+ *
908
+ * @param {string} planningDir - Path to .planning/ directory
909
+ * @param {number} startNum - Renumber phases with number >= this
910
+ * @param {number} delta - Amount to shift (+1 for insert, -1 for remove)
911
+ * @returns {{ success: boolean, error?: string }}
912
+ */
913
+ function roadmapRenumberPhases(planningDir, startNum, delta) {
914
+ const roadmapPath = path.join(planningDir, 'ROADMAP.md');
915
+ if (!fs.existsSync(roadmapPath)) {
916
+ return { success: false, error: 'ROADMAP.md not found' };
917
+ }
918
+
919
+ return lockedFileUpdate(roadmapPath, (content) => {
920
+ const lines = content.split(/\r?\n/);
921
+ const lineEnding = content.includes('\r\n') ? '\r\n' : '\n';
922
+
923
+ // Collect all phase numbers that need renumbering, process in correct order
924
+ const nums = [];
925
+ for (let i = 0; i < lines.length; i++) {
926
+ const headingMatch = lines[i].match(/^###\s+Phase\s+(\d+)\s*:/i);
927
+ if (headingMatch) {
928
+ const n = parseInt(headingMatch[1], 10);
929
+ if (n >= startNum && !nums.includes(n)) nums.push(n);
930
+ }
931
+ const rowMatch = lines[i].match(/^\|\s*(\d+)\./);
932
+ if (rowMatch) {
933
+ const n = parseInt(rowMatch[1], 10);
934
+ if (n >= startNum && !nums.includes(n)) nums.push(n);
935
+ }
936
+ }
937
+
938
+ // Sort: reverse for delta > 0 (avoid collisions), forward for delta < 0
939
+ if (delta > 0) {
940
+ nums.sort((a, b) => b - a);
941
+ } else {
942
+ nums.sort((a, b) => a - b);
943
+ }
944
+
945
+ for (const num of nums) {
946
+ const newNum = num + delta;
947
+ for (let i = 0; i < lines.length; i++) {
948
+ // ### Phase N: heading
949
+ const headingRegex = new RegExp(`^(###\\s+Phase\\s+)${num}(\\s*:.*)`, 'i');
950
+ if (headingRegex.test(lines[i])) {
951
+ lines[i] = lines[i].replace(headingRegex, `$1${newNum}$2`);
952
+ }
953
+ // Progress table row: | N. Name |
954
+ const rowRegex = new RegExp(`^(\\|\\s*)${num}(\\.)`);
955
+ if (rowRegex.test(lines[i])) {
956
+ lines[i] = lines[i].replace(rowRegex, `$1${newNum}$2`);
957
+ }
958
+ // Checklist: - [ ] Phase N: or - [x] Phase N:
959
+ const checkRegex = new RegExp(`^(\\s*-\\s+\\[[ xX]\\]\\s+Phase\\s+)${num}(\\s*[:])`, 'i');
960
+ if (checkRegex.test(lines[i])) {
961
+ lines[i] = lines[i].replace(checkRegex, `$1${newNum}$2`);
962
+ }
963
+ // Dependency text: "Phase N" (but not in headings already handled)
964
+ if (!/^###/.test(lines[i]) && !/^\|/.test(lines[i])) {
965
+ const depRegex = new RegExp(`(Phase\\s+)${num}(?=\\b)`, 'gi');
966
+ lines[i] = lines[i].replace(depRegex, `$1${newNum}`);
967
+ }
968
+ }
969
+ }
970
+
971
+ return lines.join(lineEnding);
972
+ });
973
+ }
974
+
975
+ /**
976
+ * Insert a phase heading at a specific position in ROADMAP.md (before the next phase).
977
+ * Unlike roadmapAppendPhase which appends at end, this inserts at the right position.
978
+ *
979
+ * @param {string} planningDir - Path to .planning/ directory
980
+ * @param {number} position - Position number for the new phase
981
+ * @param {string} name - Phase name
982
+ * @param {string} [goal] - Goal description
983
+ * @param {number|null} [dependsOn] - Dependency phase number
984
+ * @returns {{ success: boolean, error?: string }}
985
+ */
986
+ function roadmapInsertPhase(planningDir, position, name, goal, dependsOn) {
987
+ const roadmapPath = path.join(planningDir, 'ROADMAP.md');
988
+ if (!fs.existsSync(roadmapPath)) {
989
+ return { success: false, error: 'ROADMAP.md not found' };
990
+ }
991
+
992
+ return lockedFileUpdate(roadmapPath, (content) => {
993
+ const lines = content.split(/\r?\n/);
994
+ const lineEnding = content.includes('\r\n') ? '\r\n' : '\n';
995
+
996
+ // Build the phase heading block
997
+ const block = [];
998
+ block.push(`### Phase ${position}: ${name}`);
999
+ if (goal) block.push(`**Goal:** ${goal}`);
1000
+ const depText = dependsOn ? `Phase ${dependsOn}` : 'None';
1001
+ block.push(`**Depends on:** ${depText}`);
1002
+ block.push('');
1003
+
1004
+ // Find where to insert: before the phase heading that now has number position+1
1005
+ // (since renumbering already happened)
1006
+ let insertIdx = -1;
1007
+ for (let i = 0; i < lines.length; i++) {
1008
+ const match = lines[i].match(/^###\s+Phase\s+(\d+)\s*:/i);
1009
+ if (match && parseInt(match[1], 10) === position + 1) {
1010
+ insertIdx = i;
1011
+ break;
1012
+ }
1013
+ }
1014
+
1015
+ if (insertIdx === -1) {
1016
+ // No phase after this position found; append at end of last milestone section
1017
+ let lastMilestoneEnd = lines.length;
1018
+ for (let i = 0; i < lines.length; i++) {
1019
+ if (/^##\s+Milestone/i.test(lines[i]) && !/COMPLETED/i.test(lines[i])) {
1020
+ // Find end of this milestone section
1021
+ for (let j = i + 1; j < lines.length; j++) {
1022
+ if (/^##\s+[^#]/.test(lines[j])) {
1023
+ lastMilestoneEnd = j;
1024
+ break;
1025
+ }
1026
+ }
1027
+ }
1028
+ }
1029
+ insertIdx = lastMilestoneEnd;
1030
+ }
1031
+
1032
+ lines.splice(insertIdx, 0, ...block);
1033
+
1034
+ // Insert progress table row at the right position — detect Milestone/Completed columns
1035
+ let _hasMilestoneCol = false;
1036
+ let _hasCompletedCol = false;
1037
+ for (let i = 0; i < lines.length; i++) {
1038
+ if (lines[i].includes('|') && /Plans?\s*Complete/i.test(lines[i])) {
1039
+ _hasMilestoneCol = /milestone/i.test(lines[i]);
1040
+ _hasCompletedCol = /completed/i.test(lines[i]);
1041
+ break;
1042
+ }
1043
+ }
1044
+ let progressRow = `| ${position}. ${name} |`;
1045
+ if (_hasMilestoneCol) progressRow += ' |';
1046
+ progressRow += ' 0/0 | Pending |';
1047
+ if (_hasCompletedCol) progressRow += ' |';
1048
+ let progressInsertIdx = -1;
1049
+ let inProgressSection = false;
1050
+ for (let i = 0; i < lines.length; i++) {
1051
+ if (/^##\s+Progress/i.test(lines[i])) {
1052
+ inProgressSection = true;
1053
+ continue;
1054
+ }
1055
+ if (inProgressSection) {
1056
+ if (/^##\s/.test(lines[i]) && !/^##\s+Progress/i.test(lines[i])) {
1057
+ // End of progress section, insert here if we haven't found a spot
1058
+ if (progressInsertIdx === -1) progressInsertIdx = i;
1059
+ break;
1060
+ }
1061
+ // Find the row for position+1 (the phase that was just shifted)
1062
+ const rowMatch = lines[i].match(/^\|\s*(\d+)\./);
1063
+ if (rowMatch) {
1064
+ const rowNum = parseInt(rowMatch[1], 10);
1065
+ if (rowNum === position + 1 && progressInsertIdx === -1) {
1066
+ progressInsertIdx = i;
1067
+ }
1068
+ }
1069
+ }
1070
+ }
1071
+
1072
+ if (progressInsertIdx > 0) {
1073
+ lines.splice(progressInsertIdx, 0, progressRow);
1074
+ }
1075
+
1076
+ return lines.join(lineEnding);
1077
+ });
1078
+ }
1079
+
1080
+ /**
1081
+ * Get a single phase entry from ROADMAP.md by number.
1082
+ *
1083
+ * @param {string} phaseNum - Phase number
1084
+ * @param {string} [planningDir] - Path to .planning directory
1085
+ * @returns {object|null} Phase entry or null
1086
+ */
1087
+ function roadmapGetPhase(phaseNum, planningDir) {
1088
+ const dir = planningDir || path.join(process.env.PBR_PROJECT_ROOT || process.cwd(), '.planning');
1089
+ const roadmapPath = path.join(dir, 'ROADMAP.md');
1090
+ if (!fs.existsSync(roadmapPath)) {
1091
+ return null;
1092
+ }
1093
+
1094
+ const content = fs.readFileSync(roadmapPath, 'utf8');
1095
+ const parsed = parseRoadmapMd(content);
1096
+ const paddedPhase = String(phaseNum).padStart(2, '0');
1097
+ return parsed.phases.find(p => p.number === paddedPhase) || null;
1098
+ }
1099
+
1100
+ module.exports = {
1101
+ parseRoadmapMd,
1102
+ findRoadmapRow,
1103
+ updateTableRow,
1104
+ roadmapUpdateStatus,
1105
+ roadmapUpdatePlans,
1106
+ roadmapUpdatePlanProgress,
1107
+ roadmapAnalyze,
1108
+ roadmapAppendPhase,
1109
+ roadmapRemovePhase,
1110
+ roadmapRenumberPhases,
1111
+ roadmapInsertPhase,
1112
+ roadmapGetPhase
1113
+ };