@opengsd/gsd-pi 1.2.0-dev.844675c9 → 1.2.0-dev.955e4da0

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 (530) hide show
  1. package/dist/cli-web-branch.d.ts +2 -0
  2. package/dist/cli-web-branch.js +9 -2
  3. package/dist/help-text.js +5 -0
  4. package/dist/resources/.managed-resources-content-hash +1 -1
  5. package/dist/resources/extensions/ask-user-questions.js +78 -23
  6. package/dist/resources/extensions/bg-shell/utilities.js +2 -2
  7. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  8. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +92 -230
  9. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +224 -0
  10. package/dist/resources/extensions/github-sync/templates.js +3 -3
  11. package/dist/resources/extensions/gsd/artifact-projection.js +14 -0
  12. package/dist/resources/extensions/gsd/auto/loop.js +74 -56
  13. package/dist/resources/extensions/gsd/auto/orchestrator.js +142 -15
  14. package/dist/resources/extensions/gsd/auto/phases.js +34 -4
  15. package/dist/resources/extensions/gsd/auto/run-unit.js +2 -1
  16. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  17. package/dist/resources/extensions/gsd/auto-dashboard.js +16 -4
  18. package/dist/resources/extensions/gsd/auto-dispatch.js +6 -5
  19. package/dist/resources/extensions/gsd/auto-model-selection.js +8 -0
  20. package/dist/resources/extensions/gsd/auto-post-unit.js +12 -9
  21. package/dist/resources/extensions/gsd/auto-prompts.js +81 -8
  22. package/dist/resources/extensions/gsd/auto-recovery.js +48 -49
  23. package/dist/resources/extensions/gsd/auto-runtime-state.js +14 -0
  24. package/dist/resources/extensions/gsd/auto-start.js +20 -36
  25. package/dist/resources/extensions/gsd/auto-timers.js +16 -2
  26. package/dist/resources/extensions/gsd/auto-tool-tracking.js +32 -0
  27. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +4 -29
  28. package/dist/resources/extensions/gsd/auto-verification.js +7 -7
  29. package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
  30. package/dist/resources/extensions/gsd/auto-worktree.js +34 -289
  31. package/dist/resources/extensions/gsd/auto.js +15 -14
  32. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +28 -37
  33. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +20 -43
  34. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  35. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +131 -140
  36. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +89 -8
  37. package/dist/resources/extensions/gsd/captures.js +5 -13
  38. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +21 -4
  39. package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
  40. package/dist/resources/extensions/gsd/codebase-generator.js +8 -4
  41. package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
  42. package/dist/resources/extensions/gsd/commands/handlers/auto.js +3 -0
  43. package/dist/resources/extensions/gsd/commands-handlers.js +20 -0
  44. package/dist/resources/extensions/gsd/commands-inspect.js +4 -8
  45. package/dist/resources/extensions/gsd/commands-maintenance.js +61 -41
  46. package/dist/resources/extensions/gsd/commands-ship.js +2 -2
  47. package/dist/resources/extensions/gsd/commands-verdict.js +12 -2
  48. package/dist/resources/extensions/gsd/db/engine.js +755 -0
  49. package/dist/resources/extensions/gsd/db/queries.js +372 -0
  50. package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
  51. package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
  52. package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
  53. package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
  54. package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
  55. package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
  56. package/dist/resources/extensions/gsd/db-workspace.js +103 -0
  57. package/dist/resources/extensions/gsd/delegation-policy.js +2 -10
  58. package/dist/resources/extensions/gsd/discussion-handoff.js +218 -0
  59. package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -0
  60. package/dist/resources/extensions/gsd/doctor-environment.js +8 -10
  61. package/dist/resources/extensions/gsd/doctor-git-checks.js +4 -3
  62. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +9 -2
  63. package/dist/resources/extensions/gsd/doctor.js +16 -9
  64. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  65. package/dist/resources/extensions/gsd/git-conflict-state.js +16 -1
  66. package/dist/resources/extensions/gsd/git-service.js +1 -0
  67. package/dist/resources/extensions/gsd/gitignore.js +3 -0
  68. package/dist/resources/extensions/gsd/gsd-db.js +183 -2048
  69. package/dist/resources/extensions/gsd/guided-flow.js +68 -471
  70. package/dist/resources/extensions/gsd/guided-unit-completion.js +225 -0
  71. package/dist/resources/extensions/gsd/markdown-renderer.js +2 -1
  72. package/dist/resources/extensions/gsd/mcp-filter.js +2 -1
  73. package/dist/resources/extensions/gsd/mcp-tool-name.js +26 -0
  74. package/dist/resources/extensions/gsd/md-importer.js +4 -3
  75. package/dist/resources/extensions/gsd/migrate/safety.js +19 -11
  76. package/dist/resources/extensions/gsd/migration-auto-check.js +27 -5
  77. package/dist/resources/extensions/gsd/milestone-closeout-proof.js +72 -0
  78. package/dist/resources/extensions/gsd/milestone-closeout.js +12 -4
  79. package/dist/resources/extensions/gsd/milestone-merge-transaction.js +10 -0
  80. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +156 -0
  81. package/dist/resources/extensions/gsd/milestone-readiness.js +77 -0
  82. package/dist/resources/extensions/gsd/milestone-settlement.js +50 -0
  83. package/dist/resources/extensions/gsd/milestone-validation-evidence.js +73 -0
  84. package/dist/resources/extensions/gsd/milestone-validation-verdict.js +57 -0
  85. package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
  86. package/dist/resources/extensions/gsd/model-router.js +3 -0
  87. package/dist/resources/extensions/gsd/parallel-eligibility.js +3 -6
  88. package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
  89. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +7 -5
  90. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -2
  91. package/dist/resources/extensions/gsd/paths.js +10 -24
  92. package/dist/resources/extensions/gsd/preferences-diagnostics.js +67 -0
  93. package/dist/resources/extensions/gsd/preferences.js +161 -29
  94. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -0
  95. package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
  96. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
  97. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
  98. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
  99. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -0
  100. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  101. package/dist/resources/extensions/gsd/provider-payload-policy.js +83 -0
  102. package/dist/resources/extensions/gsd/pull-request-process.js +13 -0
  103. package/dist/resources/extensions/gsd/quality-gate-closure.js +109 -0
  104. package/dist/resources/extensions/gsd/question-transport.js +86 -0
  105. package/dist/resources/extensions/gsd/recovery-classification.js +12 -1
  106. package/dist/resources/extensions/gsd/roadmap-slices.js +8 -2
  107. package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
  108. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
  109. package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
  110. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -2
  111. package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
  112. package/dist/resources/extensions/gsd/state.js +13 -5
  113. package/dist/resources/extensions/gsd/status-guards.js +56 -8
  114. package/dist/resources/extensions/gsd/templates/plan.md +7 -0
  115. package/dist/resources/extensions/gsd/templates/project.md +1 -0
  116. package/dist/resources/extensions/gsd/templates/roadmap.md +1 -1
  117. package/dist/resources/extensions/gsd/templates/uat.md +5 -1
  118. package/dist/resources/extensions/gsd/tool-contract.js +52 -8
  119. package/dist/resources/extensions/gsd/tool-presentation-plan.js +15 -34
  120. package/dist/resources/extensions/gsd/tool-surface-snapshot.js +17 -0
  121. package/dist/resources/extensions/gsd/tools/complete-slice.js +24 -43
  122. package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -5
  123. package/dist/resources/extensions/gsd/tools/plan-milestone.js +15 -143
  124. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +39 -0
  125. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +11 -29
  126. package/dist/resources/extensions/gsd/tools/reopen-slice.js +14 -33
  127. package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
  128. package/dist/resources/extensions/gsd/tools/validate-milestone.js +15 -78
  129. package/dist/resources/extensions/gsd/uat-policy.js +16 -10
  130. package/dist/resources/extensions/gsd/uat-run.js +9 -14
  131. package/dist/resources/extensions/gsd/undo.js +8 -7
  132. package/dist/resources/extensions/gsd/unit-context-composer.js +40 -20
  133. package/dist/resources/extensions/gsd/unit-runtime.js +3 -2
  134. package/dist/resources/extensions/gsd/unit-tool-contracts.js +2 -1
  135. package/dist/resources/extensions/gsd/user-input-boundary.js +23 -0
  136. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
  137. package/dist/resources/extensions/gsd/web-app-uat.js +80 -0
  138. package/dist/resources/extensions/gsd/workflow-mcp.js +15 -102
  139. package/dist/resources/extensions/gsd/workflow-reconcile.js +4 -3
  140. package/dist/resources/extensions/gsd/workflow-tool-surface.js +46 -0
  141. package/dist/resources/extensions/gsd/workspace-git-guard.js +2 -0
  142. package/dist/resources/extensions/gsd/worktree-git-recovery.js +287 -0
  143. package/dist/resources/extensions/gsd/worktree-lifecycle.js +9 -1
  144. package/dist/resources/extensions/gsd/worktree-manager.js +45 -28
  145. package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
  146. package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
  147. package/dist/resources/extensions/gsd/worktree-root.js +17 -6
  148. package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
  149. package/dist/resources/extensions/gsd/worktree-session-state.js +12 -10
  150. package/dist/resources/extensions/gsd/worktree-state-projection.js +33 -4
  151. package/dist/resources/extensions/gsd/worktree-telemetry.js +12 -0
  152. package/dist/resources/extensions/shared/interview-ui.js +2 -2
  153. package/dist/resources/shared/claude-runtime-floor.js +182 -0
  154. package/dist/resources/skills/gsd-browser/SKILL.md +1 -1
  155. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  156. package/dist/update-cmd.js +20 -0
  157. package/dist/web/standalone/.next/BUILD_ID +1 -1
  158. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  159. package/dist/web/standalone/.next/build-manifest.json +3 -3
  160. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  161. package/dist/web/standalone/.next/react-loadable-manifest.json +8 -8
  162. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  163. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  164. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  165. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  166. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  167. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  169. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  170. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  171. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  172. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  173. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  174. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  175. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  176. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  177. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  178. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  179. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  180. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  182. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  184. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  185. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  186. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  187. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  188. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  190. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  191. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  192. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  193. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  194. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  195. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  196. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  197. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  198. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  199. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  200. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  201. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  202. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  203. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  204. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  205. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  206. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  207. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  208. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  209. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  210. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  211. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  212. package/dist/web/standalone/.next/server/app/index.html +1 -1
  213. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  214. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  215. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  216. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  217. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  218. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  219. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  220. package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
  221. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  222. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  223. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  224. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  225. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  226. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  227. package/dist/web/standalone/.next/static/chunks/2659.b7b129ee6a769448.js +1 -0
  228. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +1 -0
  229. package/dist/web/standalone/.next/static/chunks/{3616.4113d484a994e411.js → 3616.3c60753b8ffcbd2e.js} +1 -1
  230. package/dist/web/standalone/.next/static/chunks/4283.e4873b058df143a1.js +2 -0
  231. package/dist/web/standalone/.next/static/chunks/5826.a46ecdd1cfe8dabc.js +1 -0
  232. package/dist/web/standalone/.next/static/chunks/796.cf859a427a2cb2ac.js +10 -0
  233. package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +1 -0
  234. package/dist/web/standalone/.next/static/chunks/{webpack-dda80a1ef5587410.js → webpack-fbea77b5f9953368.js} +1 -1
  235. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  236. package/dist/web-mode.d.ts +2 -0
  237. package/dist/web-mode.js +20 -8
  238. package/dist/worktree-status-banner.js +7 -3
  239. package/package.json +2 -1
  240. package/packages/cloud-mcp-gateway/package.json +2 -2
  241. package/packages/contracts/package.json +1 -1
  242. package/packages/daemon/package.json +4 -4
  243. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +2 -0
  244. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
  245. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +14 -0
  246. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
  247. package/packages/gsd-agent-core/package.json +5 -5
  248. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  249. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -0
  250. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  251. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  252. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +106 -40
  253. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  254. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
  255. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +6 -0
  256. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
  257. package/packages/gsd-agent-modes/package.json +7 -7
  258. package/packages/mcp-server/dist/server.d.ts +10 -0
  259. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  260. package/packages/mcp-server/dist/server.js +8 -0
  261. package/packages/mcp-server/dist/server.js.map +1 -1
  262. package/packages/mcp-server/dist/workflow-tools.d.ts +41 -0
  263. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  264. package/packages/mcp-server/dist/workflow-tools.js +32 -22
  265. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  266. package/packages/mcp-server/package.json +3 -3
  267. package/packages/native/package.json +1 -1
  268. package/packages/pi-agent-core/package.json +1 -1
  269. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  270. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  271. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  272. package/packages/pi-ai/dist/models.generated.d.ts +295 -98
  273. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  274. package/packages/pi-ai/dist/models.generated.js +309 -154
  275. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  276. package/packages/pi-ai/package.json +1 -1
  277. package/packages/pi-coding-agent/dist/core/capability-patches.d.ts.map +1 -1
  278. package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
  279. package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
  280. package/packages/pi-coding-agent/package.json +7 -7
  281. package/packages/pi-tui/dist/components/input.js +1 -1
  282. package/packages/pi-tui/dist/components/input.js.map +1 -1
  283. package/packages/pi-tui/dist/keys.d.ts.map +1 -1
  284. package/packages/pi-tui/dist/keys.js +39 -30
  285. package/packages/pi-tui/dist/keys.js.map +1 -1
  286. package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  287. package/packages/pi-tui/dist/stdin-buffer.js +22 -0
  288. package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
  289. package/packages/pi-tui/package.json +2 -2
  290. package/packages/rpc-client/package.json +2 -2
  291. package/pkg/package.json +1 -1
  292. package/src/resources/extensions/ask-user-questions.ts +87 -24
  293. package/src/resources/extensions/bg-shell/utilities.ts +2 -2
  294. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  295. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +114 -281
  296. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +268 -0
  297. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +287 -0
  298. package/src/resources/extensions/github-sync/templates.ts +3 -3
  299. package/src/resources/extensions/github-sync/tests/templates.test.ts +2 -2
  300. package/src/resources/extensions/gsd/artifact-projection.ts +31 -0
  301. package/src/resources/extensions/gsd/auto/contracts.ts +32 -2
  302. package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -1
  303. package/src/resources/extensions/gsd/auto/loop.ts +83 -61
  304. package/src/resources/extensions/gsd/auto/orchestrator.ts +164 -17
  305. package/src/resources/extensions/gsd/auto/phases.ts +45 -4
  306. package/src/resources/extensions/gsd/auto/run-unit.ts +2 -1
  307. package/src/resources/extensions/gsd/auto/session.ts +4 -0
  308. package/src/resources/extensions/gsd/auto-dashboard.ts +18 -4
  309. package/src/resources/extensions/gsd/auto-dispatch.ts +20 -7
  310. package/src/resources/extensions/gsd/auto-model-selection.ts +8 -0
  311. package/src/resources/extensions/gsd/auto-post-unit.ts +16 -8
  312. package/src/resources/extensions/gsd/auto-prompts.ts +107 -9
  313. package/src/resources/extensions/gsd/auto-recovery.ts +50 -50
  314. package/src/resources/extensions/gsd/auto-runtime-state.ts +26 -0
  315. package/src/resources/extensions/gsd/auto-start.ts +25 -34
  316. package/src/resources/extensions/gsd/auto-timers.ts +16 -2
  317. package/src/resources/extensions/gsd/auto-tool-tracking.ts +35 -0
  318. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +9 -30
  319. package/src/resources/extensions/gsd/auto-verification.ts +7 -8
  320. package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
  321. package/src/resources/extensions/gsd/auto-worktree.ts +53 -306
  322. package/src/resources/extensions/gsd/auto.ts +27 -17
  323. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +29 -37
  324. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +20 -43
  325. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  326. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +147 -153
  327. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +132 -6
  328. package/src/resources/extensions/gsd/captures.ts +5 -14
  329. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +27 -5
  330. package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
  331. package/src/resources/extensions/gsd/codebase-generator.ts +9 -5
  332. package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
  333. package/src/resources/extensions/gsd/commands/handlers/auto.ts +3 -0
  334. package/src/resources/extensions/gsd/commands-handlers.ts +18 -0
  335. package/src/resources/extensions/gsd/commands-inspect.ts +7 -8
  336. package/src/resources/extensions/gsd/commands-maintenance.ts +74 -40
  337. package/src/resources/extensions/gsd/commands-ship.ts +2 -2
  338. package/src/resources/extensions/gsd/commands-verdict.ts +19 -2
  339. package/src/resources/extensions/gsd/db/engine.ts +809 -0
  340. package/src/resources/extensions/gsd/db/queries.ts +453 -0
  341. package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
  342. package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
  343. package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
  344. package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
  345. package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
  346. package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
  347. package/src/resources/extensions/gsd/db-workspace.ts +170 -0
  348. package/src/resources/extensions/gsd/delegation-policy.ts +3 -11
  349. package/src/resources/extensions/gsd/discussion-handoff.ts +276 -0
  350. package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -0
  351. package/src/resources/extensions/gsd/doctor-environment.ts +8 -11
  352. package/src/resources/extensions/gsd/doctor-git-checks.ts +3 -3
  353. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +10 -3
  354. package/src/resources/extensions/gsd/doctor.ts +15 -5
  355. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  356. package/src/resources/extensions/gsd/git-conflict-state.ts +17 -1
  357. package/src/resources/extensions/gsd/git-service.ts +1 -0
  358. package/src/resources/extensions/gsd/gitignore.ts +3 -0
  359. package/src/resources/extensions/gsd/gsd-db.ts +185 -2373
  360. package/src/resources/extensions/gsd/guided-flow.ts +81 -561
  361. package/src/resources/extensions/gsd/guided-unit-completion.ts +275 -0
  362. package/src/resources/extensions/gsd/markdown-renderer.ts +2 -1
  363. package/src/resources/extensions/gsd/mcp-filter.ts +2 -1
  364. package/src/resources/extensions/gsd/mcp-tool-name.ts +35 -0
  365. package/src/resources/extensions/gsd/md-importer.ts +3 -3
  366. package/src/resources/extensions/gsd/migrate/safety.ts +17 -9
  367. package/src/resources/extensions/gsd/migration-auto-check.ts +30 -5
  368. package/src/resources/extensions/gsd/milestone-closeout-proof.ts +131 -0
  369. package/src/resources/extensions/gsd/milestone-closeout.ts +12 -4
  370. package/src/resources/extensions/gsd/milestone-merge-transaction.ts +47 -0
  371. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +224 -0
  372. package/src/resources/extensions/gsd/milestone-readiness.ts +125 -0
  373. package/src/resources/extensions/gsd/milestone-settlement.ts +81 -0
  374. package/src/resources/extensions/gsd/milestone-validation-evidence.ts +95 -0
  375. package/src/resources/extensions/gsd/milestone-validation-verdict.ts +80 -0
  376. package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
  377. package/src/resources/extensions/gsd/model-router.ts +3 -0
  378. package/src/resources/extensions/gsd/parallel-eligibility.ts +4 -5
  379. package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
  380. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -5
  381. package/src/resources/extensions/gsd/parallel-orchestrator.ts +6 -2
  382. package/src/resources/extensions/gsd/paths.ts +9 -22
  383. package/src/resources/extensions/gsd/preferences-diagnostics.ts +98 -0
  384. package/src/resources/extensions/gsd/preferences-types.ts +16 -0
  385. package/src/resources/extensions/gsd/preferences.ts +191 -28
  386. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -0
  387. package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
  388. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
  389. package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
  390. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
  391. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -0
  392. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  393. package/src/resources/extensions/gsd/provider-payload-policy.ts +140 -0
  394. package/src/resources/extensions/gsd/pull-request-process.ts +41 -0
  395. package/src/resources/extensions/gsd/quality-gate-closure.ts +140 -0
  396. package/src/resources/extensions/gsd/question-transport.ts +138 -0
  397. package/src/resources/extensions/gsd/recovery-classification.ts +14 -1
  398. package/src/resources/extensions/gsd/roadmap-slices.ts +8 -2
  399. package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
  400. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
  401. package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
  402. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +6 -2
  403. package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
  404. package/src/resources/extensions/gsd/state.ts +15 -5
  405. package/src/resources/extensions/gsd/status-guards.ts +59 -8
  406. package/src/resources/extensions/gsd/templates/plan.md +7 -0
  407. package/src/resources/extensions/gsd/templates/project.md +1 -0
  408. package/src/resources/extensions/gsd/templates/roadmap.md +1 -1
  409. package/src/resources/extensions/gsd/templates/uat.md +5 -1
  410. package/src/resources/extensions/gsd/tests/ask-user-questions-render.test.ts +92 -0
  411. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +29 -1
  412. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +444 -5
  413. package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +23 -0
  414. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +18 -0
  415. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +133 -4
  416. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +3 -1
  417. package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
  418. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +34 -0
  419. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
  420. package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
  421. package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +20 -0
  422. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -0
  423. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
  424. package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +11 -0
  425. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +38 -1
  426. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +34 -3
  427. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +88 -0
  428. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +18 -0
  429. package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +157 -0
  430. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +1 -0
  431. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
  432. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +1 -5
  433. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +1 -5
  434. package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +48 -1
  435. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +5 -4
  436. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +1 -1
  437. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
  438. package/src/resources/extensions/gsd/tests/mcp-tool-name.test.ts +34 -0
  439. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +143 -1
  440. package/src/resources/extensions/gsd/tests/milestone-closeout-proof.test.ts +99 -0
  441. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +25 -0
  442. package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +46 -0
  443. package/src/resources/extensions/gsd/tests/milestone-readiness.test.ts +65 -0
  444. package/src/resources/extensions/gsd/tests/milestone-validation-evidence.test.ts +41 -0
  445. package/src/resources/extensions/gsd/tests/milestone-validation-verdict.test.ts +55 -0
  446. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +45 -0
  447. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  448. package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +45 -0
  449. package/src/resources/extensions/gsd/tests/preferences-diagnostics.test.ts +67 -0
  450. package/src/resources/extensions/gsd/tests/preferences.test.ts +183 -0
  451. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +46 -0
  452. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +9 -0
  453. package/src/resources/extensions/gsd/tests/provider-payload-policy.test.ts +165 -0
  454. package/src/resources/extensions/gsd/tests/pull-request-process.test.ts +47 -0
  455. package/src/resources/extensions/gsd/tests/recovery-classification-illegal-transition.test.ts +30 -0
  456. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +185 -1
  457. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +40 -0
  458. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +25 -1
  459. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
  460. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +80 -0
  461. package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
  462. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +144 -7
  463. package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +27 -0
  464. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +2 -1
  465. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
  466. package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
  467. package/src/resources/extensions/gsd/tests/tool-availability-audit.test.ts +35 -0
  468. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +35 -42
  469. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +23 -0
  470. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +47 -0
  471. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +86 -1
  472. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +39 -0
  473. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +150 -0
  474. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +126 -9
  475. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +15 -0
  476. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
  477. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +43 -1
  478. package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
  479. package/src/resources/extensions/gsd/tests/worktree-projection-writers.test.ts +1 -1
  480. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
  481. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +3 -1
  482. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
  483. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +2 -2
  484. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +22 -0
  485. package/src/resources/extensions/gsd/tests/write-gate.test.ts +121 -0
  486. package/src/resources/extensions/gsd/tool-contract.ts +86 -8
  487. package/src/resources/extensions/gsd/tool-presentation-plan.ts +16 -33
  488. package/src/resources/extensions/gsd/tool-surface-snapshot.ts +47 -0
  489. package/src/resources/extensions/gsd/tools/complete-slice.ts +23 -58
  490. package/src/resources/extensions/gsd/tools/exec-tool.ts +5 -5
  491. package/src/resources/extensions/gsd/tools/plan-milestone.ts +19 -160
  492. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +43 -0
  493. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +11 -38
  494. package/src/resources/extensions/gsd/tools/reopen-slice.ts +14 -42
  495. package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
  496. package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -84
  497. package/src/resources/extensions/gsd/uat-policy.ts +19 -10
  498. package/src/resources/extensions/gsd/uat-run.ts +10 -14
  499. package/src/resources/extensions/gsd/undo.ts +9 -8
  500. package/src/resources/extensions/gsd/unit-context-composer.ts +85 -20
  501. package/src/resources/extensions/gsd/unit-runtime.ts +3 -2
  502. package/src/resources/extensions/gsd/unit-tool-contracts.ts +2 -1
  503. package/src/resources/extensions/gsd/user-input-boundary.ts +18 -0
  504. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
  505. package/src/resources/extensions/gsd/web-app-uat.ts +101 -0
  506. package/src/resources/extensions/gsd/workflow-mcp.ts +22 -110
  507. package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
  508. package/src/resources/extensions/gsd/workflow-tool-surface.ts +73 -0
  509. package/src/resources/extensions/gsd/workspace-git-guard.ts +1 -0
  510. package/src/resources/extensions/gsd/worktree-git-recovery.ts +308 -0
  511. package/src/resources/extensions/gsd/worktree-lifecycle.ts +17 -17
  512. package/src/resources/extensions/gsd/worktree-manager.ts +47 -28
  513. package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
  514. package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
  515. package/src/resources/extensions/gsd/worktree-root.ts +17 -6
  516. package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
  517. package/src/resources/extensions/gsd/worktree-session-state.ts +12 -10
  518. package/src/resources/extensions/gsd/worktree-state-projection.ts +55 -7
  519. package/src/resources/extensions/gsd/worktree-telemetry.ts +16 -0
  520. package/src/resources/extensions/shared/interview-ui.ts +15 -2
  521. package/src/resources/shared/claude-runtime-floor.ts +248 -0
  522. package/src/resources/skills/gsd-browser/SKILL.md +1 -1
  523. package/dist/web/standalone/.next/static/chunks/2659.feb6499ca863ebfc.js +0 -1
  524. package/dist/web/standalone/.next/static/chunks/2772.151789db0edea835.js +0 -1
  525. package/dist/web/standalone/.next/static/chunks/4283.10a065467b5340d8.js +0 -2
  526. package/dist/web/standalone/.next/static/chunks/5826.960dc4634cc9b0d3.js +0 -1
  527. package/dist/web/standalone/.next/static/chunks/796.46f811c0fac23aab.js +0 -10
  528. package/dist/web/standalone/.next/static/chunks/8785.d32f7a61f55c1600.js +0 -1
  529. /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → C24pqUd-aru-l0Dp0gLZP}/_buildManifest.js +0 -0
  530. /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → C24pqUd-aru-l0Dp0gLZP}/_ssgManifest.js +0 -0
@@ -1,7 +1,10 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: Resolve phase-aware tool surfaces for GSD model presentations.
3
3
  import { RUN_UAT_BROWSER_TOOL_NAMES, RUN_UAT_READ_ONLY_TOOL_NAMES, RUN_UAT_TOOL_PRESENTATION_PLAN_ID, RUN_UAT_WORKFLOW_TOOL_NAMES, } from "./unit-tool-contracts.js";
4
+ import { toMcpToolName } from "./mcp-tool-name.js";
5
+ import { createToolSurfaceSnapshot } from "./tool-surface-snapshot.js";
4
6
  import { uatTypeIncludesBrowser } from "./uat-policy.js";
7
+ import { canonicalWorkflowSurfaceToolName } from "./workflow-tool-surface.js";
5
8
  export { RUN_UAT_BROWSER_TOOL_NAMES, RUN_UAT_READ_ONLY_TOOL_NAMES, RUN_UAT_TOOL_PRESENTATION_PLAN_ID, RUN_UAT_WORKFLOW_TOOL_NAMES, } from "./unit-tool-contracts.js";
6
9
  export const RUN_UAT_FORBIDDEN_TOOL_NAMES = [
7
10
  "edit",
@@ -21,43 +24,12 @@ export const RUN_UAT_CLAUDE_NATIVE_TOOL_NAMES = [
21
24
  "Glob",
22
25
  "Grep",
23
26
  ];
24
- const WORKFLOW_ALIAS_TO_CANONICAL = {
25
- gsd_save_decision: "gsd_decision_save",
26
- gsd_update_requirement: "gsd_requirement_update",
27
- gsd_save_requirement: "gsd_requirement_save",
28
- gsd_save_summary: "gsd_summary_save",
29
- gsd_generate_milestone_id: "gsd_milestone_generate_id",
30
- gsd_milestone_plan: "gsd_plan_milestone",
31
- gsd_slice_plan: "gsd_plan_slice",
32
- gsd_task_plan: "gsd_plan_task",
33
- gsd_slice_replan: "gsd_replan_slice",
34
- gsd_complete_slice: "gsd_slice_complete",
35
- gsd_milestone_complete: "gsd_complete_milestone",
36
- gsd_milestone_validate: "gsd_validate_milestone",
37
- gsd_roadmap_reassess: "gsd_reassess_roadmap",
38
- gsd_complete_task: "gsd_task_complete",
39
- gsd_reopen_task: "gsd_task_reopen",
40
- gsd_reopen_slice: "gsd_slice_reopen",
41
- gsd_reopen_milestone: "gsd_milestone_reopen",
42
- };
43
27
  export function canonicalWorkflowToolName(toolName) {
44
- const mcp = parseMcpToolName(toolName);
45
- const baseName = mcp?.tool ?? toolName;
46
- return WORKFLOW_ALIAS_TO_CANONICAL[baseName] ?? baseName;
47
- }
48
- export function parseMcpToolName(toolName) {
49
- if (!toolName.startsWith("mcp__"))
50
- return null;
51
- const toolSeparator = toolName.indexOf("__", "mcp__".length);
52
- if (toolSeparator < 0)
53
- return null;
54
- return {
55
- server: toolName.slice("mcp__".length, toolSeparator),
56
- tool: toolName.slice(toolSeparator + 2),
57
- };
28
+ return canonicalWorkflowSurfaceToolName(toolName);
58
29
  }
30
+ export { parseMcpToolName } from "./mcp-tool-name.js";
59
31
  export function toWorkflowMcpToolName(serverName, toolName) {
60
- return `mcp__${serverName}__${canonicalWorkflowToolName(toolName)}`;
32
+ return toMcpToolName(serverName, canonicalWorkflowToolName(toolName));
61
33
  }
62
34
  function dedupe(values) {
63
35
  return [...new Set(values)];
@@ -134,6 +106,14 @@ export function resolveToolPresentationPlan(options) {
134
106
  ? toWorkflowMcpToolName(workflowServerName, name)
135
107
  : name)
136
108
  : allowedToolNames;
109
+ const toolSurface = createToolSurfaceSnapshot({
110
+ source: "presentation-plan",
111
+ phase: options.phase,
112
+ modelFacingToolNames: options.availableToolNames ?? requested,
113
+ registeredToolNames: options.availableToolNames ?? requested,
114
+ scopedToolNames: allowedToolNames,
115
+ presentedToolNames,
116
+ });
137
117
  if (options.phase === "run-uat") {
138
118
  for (const forbidden of RUN_UAT_FORBIDDEN_TOOL_NAMES) {
139
119
  addBlockedTool(blockedToolNames, forbidden, "forbidden during run-uat");
@@ -148,5 +128,6 @@ export function resolveToolPresentationPlan(options) {
148
128
  blockedToolNames,
149
129
  aliases,
150
130
  diagnostics: [],
131
+ toolSurface,
151
132
  };
152
133
  }
@@ -0,0 +1,17 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Typed snapshots for model-facing, registered, scoped, and presented tool surfaces.
3
+ function dedupeToolNames(toolNames) {
4
+ return [...new Set(toolNames ?? [])];
5
+ }
6
+ export function createToolSurfaceSnapshot(input) {
7
+ return {
8
+ source: input.source,
9
+ unitType: input.unitType,
10
+ phase: input.phase,
11
+ modelFacingToolNames: dedupeToolNames(input.modelFacingToolNames),
12
+ registeredToolNames: dedupeToolNames(input.registeredToolNames),
13
+ scopedToolNames: dedupeToolNames(input.scopedToolNames),
14
+ presentedToolNames: dedupeToolNames(input.presentedToolNames),
15
+ capturedAt: input.capturedAt ?? Date.now(),
16
+ };
17
+ }
@@ -11,8 +11,7 @@
11
11
  */
12
12
  import { existsSync, readFileSync } from "node:fs";
13
13
  import { join } from "node:path";
14
- import { isClosedStatus } from "../status-guards.js";
15
- import { transaction, insertMilestone, insertSlice, getSlice, getSliceTasks, getMilestone, updateSliceStatus, setSliceSummaryMd, saveGateResult, getPendingGatesForTurn, getMilestoneSlices, updateMilestoneStatus, } from "../gsd-db.js";
14
+ import { completeSliceCascade, setSliceSummaryMd, saveGateResult, getPendingGatesForTurn, } from "../gsd-db.js";
16
15
  import { getGatesForTurn } from "../gate-registry.js";
17
16
  import { gsdProjectionRoot, clearPathCache, resolveMilestoneFile } from "../paths.js";
18
17
  import { resolveCanonicalMilestoneRoot } from "../worktree-manager.js";
@@ -295,52 +294,34 @@ export async function handleCompleteSlice(params, basePath) {
295
294
  error: `UAT requires browser verification (opening a page in a browser, navigating to a page or localhost, screenshots) but declares "UAT mode: artifact-driven", which only runs static/file checks and would defer the browser work to a human. Use a mode that actually verifies the UI: "browser-executable" (interactive browser tools), "runtime-executable" (a browser test command such as playwright), or a browser-inclusive "mixed"/"live-runtime". Re-author the UAT Type section and complete the slice again.`,
296
295
  };
297
296
  }
298
- // ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
297
+ // ── Atomic completion cascade (guards + writes in one transaction) ───────
299
298
  const completedAt = new Date().toISOString();
300
299
  let guardError = null;
301
300
  let existingSummaryMd = "";
302
301
  let duplicateComplete = false;
303
- transaction(() => {
304
- // State machine preconditions (inside txn for atomicity).
305
- // Milestone/slice not existing is OK — insertMilestone/insertSlice below will auto-create.
306
- // Only block if they exist and are closed.
307
- const milestone = getMilestone(params.milestoneId);
308
- if (milestone && isClosedStatus(milestone.status)) {
309
- guardError = `cannot complete slice in a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
310
- return;
311
- }
312
- const slice = getSlice(params.milestoneId, params.sliceId);
313
- existingSummaryMd = slice?.full_summary_md?.trim() ?? "";
314
- if (slice && isClosedStatus(slice.status)) {
315
- duplicateComplete = true;
316
- return;
317
- }
318
- // Verify all tasks are complete
319
- const tasks = getSliceTasks(params.milestoneId, params.sliceId);
320
- if (tasks.length === 0) {
321
- guardError = `no tasks found for slice ${params.sliceId} in milestone ${params.milestoneId}`;
322
- return;
323
- }
324
- const incompleteTasks = tasks.filter(t => !isClosedStatus(t.status));
325
- if (incompleteTasks.length > 0) {
326
- const incompleteIds = incompleteTasks.map(t => `${t.id} (status: ${t.status})`).join(", ");
327
- guardError = `incomplete tasks: ${incompleteIds}`;
328
- return;
329
- }
330
- // All guards passed — perform writes. Preserve existing planning metadata:
331
- // completion should not overwrite title/risk/depends/demo/sequence.
332
- insertMilestone({ id: params.milestoneId, title: params.milestoneId });
333
- if (!slice) {
334
- insertSlice({ id: params.sliceId, milestoneId: params.milestoneId, title: params.sliceTitle || params.sliceId });
335
- }
336
- updateSliceStatus(params.milestoneId, params.sliceId, "complete", completedAt);
337
- const updatedSlices = getMilestoneSlices(params.milestoneId);
338
- if (milestone?.status === "planned" &&
339
- updatedSlices.length > 0 &&
340
- updatedSlices.every((s) => isClosedStatus(s.status))) {
341
- updateMilestoneStatus(params.milestoneId, "active");
342
- }
302
+ const outcome = completeSliceCascade(params.milestoneId, params.sliceId, {
303
+ sliceTitle: params.sliceTitle,
304
+ completedAt,
343
305
  });
306
+ if (outcome.ok) {
307
+ existingSummaryMd = outcome.existingSummaryMd;
308
+ duplicateComplete = outcome.duplicate;
309
+ }
310
+ else {
311
+ switch (outcome.reason) {
312
+ case "milestone-closed":
313
+ guardError = `cannot complete slice in a closed milestone: ${params.milestoneId} (status: ${outcome.status})`;
314
+ break;
315
+ case "no-tasks":
316
+ guardError = `no tasks found for slice ${params.sliceId} in milestone ${params.milestoneId}`;
317
+ break;
318
+ case "incomplete-tasks": {
319
+ const incompleteIds = outcome.incomplete.map((t) => `${t.id} (status: ${t.status})`).join(", ");
320
+ guardError = `incomplete tasks: ${incompleteIds}`;
321
+ break;
322
+ }
323
+ }
324
+ }
344
325
  if (duplicateComplete) {
345
326
  const staleSummaryPath = sliceSummaryPath(artifactBasePath, params.milestoneId, params.sliceId);
346
327
  const duplicateIsStale = isStaleWrite("complete-slice");
@@ -4,6 +4,7 @@ import { EXEC_DEFAULTS, runExecSandbox, } from "../exec-sandbox.js";
4
4
  import { realpathSync } from "node:fs";
5
5
  import path from "node:path";
6
6
  import { isContextModeEnabled } from "../preferences-types.js";
7
+ import { findWorktreeSegment } from "../worktree-root.js";
7
8
  import { contextModeDisabledResult } from "./context-mode-tool-result.js";
8
9
  const UAT_EXEC_INTENTS = [
9
10
  "uat-artifact-check",
@@ -141,12 +142,11 @@ function normalizeScanPath(value) {
141
142
  }
142
143
  function parseWorktreeBase(baseDir) {
143
144
  const normalizedBase = normalizeScanPath(baseDir);
144
- const marker = "/.gsd/worktrees/";
145
- const markerIndex = normalizedBase.indexOf(marker);
146
- if (markerIndex <= 0)
145
+ const segment = findWorktreeSegment(normalizedBase);
146
+ if (!segment || segment.gsdIdx <= 0)
147
147
  return null;
148
148
  return {
149
- originalRoot: normalizedBase.slice(0, markerIndex),
149
+ originalRoot: normalizedBase.slice(0, segment.gsdIdx),
150
150
  worktreeRoot: normalizedBase,
151
151
  };
152
152
  }
@@ -234,7 +234,7 @@ function scriptReferencesOriginalRootFromWorktree(script, baseDir) {
234
234
  return false;
235
235
  const normalizedScript = script.replace(/\\/g, "/");
236
236
  return comparablePathVariants(parsed.originalRoot).some((originalRoot) => {
237
- const originalRootPattern = new RegExp(`${escapeRegExp(originalRoot)}(?=$|[\\s'"\\\`;)&|<>]|/(?!\\.gsd/worktrees(?:/|$)))`);
237
+ const originalRootPattern = new RegExp(`${escapeRegExp(originalRoot)}(?=$|[\\s'"\\\`;)&|<>]|/(?!\\.gsd(?:-worktrees|/worktrees)(?:/|$)))`);
238
238
  return originalRootPattern.test(normalizedScript);
239
239
  });
240
240
  }
@@ -1,15 +1,7 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: Plans milestone roadmap state through DB-backed workflow tools.
3
- import { clearParseCache } from "../files.js";
4
- import { isClosedStatus } from "../status-guards.js";
5
3
  import { isNonEmptyString, validateStringArray, validateTitle } from "../validation.js";
6
- import { transaction, getMilestone, getMilestoneSlices, getSlice, insertMilestone, insertSlice, upsertMilestonePlanning, upsertSlicePlanning, } from "../gsd-db.js";
7
- import { invalidateStateCache } from "../state.js";
8
- import { renderRoadmapFromDb } from "../markdown-renderer.js";
9
- import { renderAllProjections } from "../workflow-projections.js";
10
- import { writeManifest } from "../workflow-manifest.js";
11
- import { appendEvent } from "../workflow-events.js";
12
- import { logWarning } from "../workflow-logger.js";
4
+ import { persistMilestonePlan } from "../milestone-planning-persistence.js";
13
5
  function validateRiskEntries(value) {
14
6
  if (!Array.isArray(value)) {
15
7
  throw new Error("keyRisks must be an array");
@@ -43,10 +35,16 @@ function validateProofStrategy(value) {
43
35
  return { riskOrUnknown, retireIn, whatWillBeProven };
44
36
  });
45
37
  }
38
+ const SLICE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9-]*$/;
46
39
  function validateSlices(value) {
47
40
  if (!Array.isArray(value) || value.length === 0) {
48
41
  throw new Error("slices must be a non-empty array");
49
42
  }
43
+ // Pre-collect all slice IDs so depends cross-validation can reference the full set.
44
+ const allSliceIds = new Set(value
45
+ .filter((e) => !!e && typeof e === "object")
46
+ .map(e => e.sliceId)
47
+ .filter((id) => isNonEmptyString(id)));
50
48
  const seen = new Set();
51
49
  return value.map((entry, index) => {
52
50
  if (!entry || typeof entry !== "object") {
@@ -84,8 +82,13 @@ function validateSlices(value) {
84
82
  throw new Error(`slices[${index}].title is invalid: ${titleIssue}`);
85
83
  if (!isNonEmptyString(risk))
86
84
  throw new Error(`slices[${index}].risk must be a non-empty string`);
87
- if (!Array.isArray(depends) || depends.some((item) => !isNonEmptyString(item))) {
88
- throw new Error(`slices[${index}].depends must be an array of non-empty strings`);
85
+ if (!Array.isArray(depends) || depends.some((item) => !isNonEmptyString(item) || !SLICE_ID_RE.test(item))) {
86
+ throw new Error(`slices[${index}].depends must be an array of valid slice IDs (e.g. "S01")`);
87
+ }
88
+ for (const dep of depends) {
89
+ if (!allSliceIds.has(dep)) {
90
+ throw new Error(`slices[${index}].depends references unknown slice "${dep}" — check that it is defined in the same milestone`);
91
+ }
89
92
  }
90
93
  if (!isNonEmptyString(demo))
91
94
  throw new Error(`slices[${index}].demo must be a non-empty string`);
@@ -160,136 +163,5 @@ export async function handlePlanMilestone(rawParams, basePath) {
160
163
  catch (err) {
161
164
  return { error: `validation failed: ${err.message}` };
162
165
  }
163
- // ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
164
- // Guards must be inside the transaction so the state they check cannot
165
- // change between the read and the write (#2723).
166
- let guardError = null;
167
- try {
168
- transaction(() => {
169
- const existingMilestone = getMilestone(params.milestoneId);
170
- if (existingMilestone && isClosedStatus(existingMilestone.status)) {
171
- guardError = `cannot re-plan milestone ${params.milestoneId}: it is already complete`;
172
- return;
173
- }
174
- // Guard: refuse to re-plan a milestone that would drop completed slices (#2960).
175
- // Allow re-planning when all completed slices are still present in the
176
- // incoming plan — their status is preserved below (#2558). Block only when
177
- // the new plan omits a completed slice, which could shadow completed work.
178
- const existingSlices = getMilestoneSlices(params.milestoneId);
179
- const completedSlices = existingSlices.filter(s => isClosedStatus(s.status));
180
- if (completedSlices.length > 0) {
181
- const incomingSliceIds = new Set(params.slices.map(s => s.sliceId));
182
- const droppedCompleted = completedSlices.filter(s => !incomingSliceIds.has(s.id));
183
- if (droppedCompleted.length > 0) {
184
- guardError = `cannot re-plan milestone ${params.milestoneId}: ${droppedCompleted.length} completed slice(s) would be dropped (${droppedCompleted.map(s => s.id).join(", ")}). Use gsd_reassess_roadmap to modify the roadmap.`;
185
- return;
186
- }
187
- }
188
- // Validate depends_on: all dependencies must exist and be complete
189
- if (params.dependsOn && params.dependsOn.length > 0) {
190
- for (const depId of params.dependsOn) {
191
- const dep = getMilestone(depId);
192
- if (!dep) {
193
- guardError = `depends_on references unknown milestone: ${depId}`;
194
- return;
195
- }
196
- if (!isClosedStatus(dep.status)) {
197
- guardError = `depends_on milestone ${depId} is not yet complete (status: ${dep.status})`;
198
- return;
199
- }
200
- }
201
- }
202
- insertMilestone({
203
- id: params.milestoneId,
204
- title: params.title,
205
- status: params.status ?? "active",
206
- depends_on: params.dependsOn ?? [],
207
- });
208
- upsertMilestonePlanning(params.milestoneId, {
209
- title: params.title,
210
- status: params.status ?? "active",
211
- depends_on: params.dependsOn ?? [],
212
- vision: params.vision,
213
- successCriteria: params.successCriteria,
214
- keyRisks: params.keyRisks,
215
- proofStrategy: params.proofStrategy,
216
- verificationContract: params.verificationContract,
217
- verificationIntegration: params.verificationIntegration,
218
- verificationOperational: params.verificationOperational,
219
- verificationUat: params.verificationUat,
220
- definitionOfDone: params.definitionOfDone,
221
- requirementCoverage: params.requirementCoverage,
222
- boundaryMapMarkdown: params.boundaryMapMarkdown,
223
- });
224
- for (let i = 0; i < params.slices.length; i++) {
225
- const slice = params.slices[i];
226
- // Preserve completed/done status on re-plan (#2558).
227
- // Without this, a re-plan after milestone transition would reset
228
- // already-completed slices back to "pending".
229
- const existing = getSlice(params.milestoneId, slice.sliceId);
230
- const status = existing && (existing.status === "complete" || existing.status === "done")
231
- ? existing.status
232
- : "pending";
233
- insertSlice({
234
- id: slice.sliceId,
235
- milestoneId: params.milestoneId,
236
- title: slice.title,
237
- status,
238
- risk: slice.risk,
239
- depends: slice.depends,
240
- demo: slice.demo,
241
- sequence: i + 1, // Preserve agent-ordered sequence (#3356)
242
- // ADR-011: pass undefined through so ON CONFLICT preserves existing values
243
- // when the caller omitted the fields on a re-plan.
244
- isSketch: slice.isSketch,
245
- sketchScope: slice.sketchScope,
246
- });
247
- upsertSlicePlanning(params.milestoneId, slice.sliceId, {
248
- goal: slice.goal,
249
- successCriteria: slice.successCriteria,
250
- proofLevel: slice.proofLevel,
251
- integrationClosure: slice.integrationClosure,
252
- observabilityImpact: slice.observabilityImpact,
253
- });
254
- }
255
- });
256
- }
257
- catch (err) {
258
- return { error: `db write failed: ${err.message}` };
259
- }
260
- if (guardError) {
261
- return { error: guardError };
262
- }
263
- let roadmapPath;
264
- try {
265
- const renderResult = await renderRoadmapFromDb(basePath, params.milestoneId);
266
- roadmapPath = renderResult.roadmapPath;
267
- }
268
- catch (renderErr) {
269
- logWarning("tool", `plan_milestone — render failed (DB rows preserved for debugging): ${renderErr.message}`);
270
- invalidateStateCache();
271
- return { error: `render failed: ${renderErr.message}` };
272
- }
273
- invalidateStateCache();
274
- clearParseCache();
275
- // ── Post-mutation hook: projections, manifest, event log ───────────────
276
- try {
277
- await renderAllProjections(basePath, params.milestoneId);
278
- writeManifest(basePath);
279
- appendEvent(basePath, {
280
- cmd: "plan-milestone",
281
- params: { milestoneId: params.milestoneId },
282
- ts: new Date().toISOString(),
283
- actor: "agent",
284
- actor_name: params.actorName,
285
- trigger_reason: params.triggerReason,
286
- });
287
- }
288
- catch (hookErr) {
289
- logWarning("tool", `plan-milestone post-mutation hook warning: ${hookErr.message}`);
290
- }
291
- return {
292
- milestoneId: params.milestoneId,
293
- roadmapPath,
294
- };
166
+ return persistMilestonePlan(params, basePath);
295
167
  }
@@ -31,6 +31,7 @@ function validateParams(params) {
31
31
  if (!Array.isArray(params.sliceChanges.removed)) {
32
32
  throw new Error("sliceChanges.removed must be an array");
33
33
  }
34
+ const SLICE_ID_RE = /^[A-Za-z0-9][A-Za-z0-9-]*$/;
34
35
  // Validate each modified slice
35
36
  for (let i = 0; i < params.sliceChanges.modified.length; i++) {
36
37
  const s = params.sliceChanges.modified[i];
@@ -40,6 +41,11 @@ function validateParams(params) {
40
41
  throw new Error(`sliceChanges.modified[${i}].sliceId is required`);
41
42
  if (!isNonEmptyString(s.title))
42
43
  throw new Error(`sliceChanges.modified[${i}].title is required`);
44
+ if (s.depends !== undefined) {
45
+ if (!Array.isArray(s.depends) || s.depends.some((item) => !isNonEmptyString(item) || !SLICE_ID_RE.test(item))) {
46
+ throw new Error(`sliceChanges.modified[${i}].depends must be an array of valid slice IDs (e.g. "S01")`);
47
+ }
48
+ }
43
49
  }
44
50
  // Validate each added slice
45
51
  for (let i = 0; i < params.sliceChanges.added.length; i++) {
@@ -50,6 +56,11 @@ function validateParams(params) {
50
56
  throw new Error(`sliceChanges.added[${i}].sliceId is required`);
51
57
  if (!isNonEmptyString(s.title))
52
58
  throw new Error(`sliceChanges.added[${i}].title is required`);
59
+ if (s.depends !== undefined) {
60
+ if (!Array.isArray(s.depends) || s.depends.some((item) => !isNonEmptyString(item) || !SLICE_ID_RE.test(item))) {
61
+ throw new Error(`sliceChanges.added[${i}].depends must be an array of valid slice IDs (e.g. "S01")`);
62
+ }
63
+ }
53
64
  }
54
65
  return params;
55
66
  }
@@ -111,6 +122,34 @@ export async function handleReassessRoadmap(rawParams, basePath) {
111
122
  return;
112
123
  }
113
124
  }
125
+ // Cross-milestone depends validation — effective slice ID set after this reassessment
126
+ const removedIds = new Set(params.sliceChanges.removed);
127
+ const effectiveSliceIds = new Set(existingSlices.map(s => s.id).filter(id => !removedIds.has(id)));
128
+ for (const added of params.sliceChanges.added) {
129
+ effectiveSliceIds.add(added.sliceId);
130
+ }
131
+ for (let i = 0; i < params.sliceChanges.modified.length; i++) {
132
+ const mod = params.sliceChanges.modified[i];
133
+ if (mod.depends !== undefined) {
134
+ for (const dep of mod.depends) {
135
+ if (!effectiveSliceIds.has(dep)) {
136
+ guardError = `sliceChanges.modified[${i}].depends references unknown slice "${dep}" — check that it is defined in this milestone`;
137
+ return;
138
+ }
139
+ }
140
+ }
141
+ }
142
+ for (let i = 0; i < params.sliceChanges.added.length; i++) {
143
+ const added = params.sliceChanges.added[i];
144
+ if (added.depends !== undefined) {
145
+ for (const dep of added.depends) {
146
+ if (!effectiveSliceIds.has(dep)) {
147
+ guardError = `sliceChanges.added[${i}].depends references unknown slice "${dep}" — check that it is defined in this milestone`;
148
+ return;
149
+ }
150
+ }
151
+ }
152
+ }
114
153
  // Record assessment
115
154
  insertAssessment({
116
155
  path: assessmentRelPath,
@@ -7,9 +7,8 @@
7
7
  * artifacts so the DB-filesystem reconciler does not auto-correct
8
8
  * entities back to "complete".
9
9
  */
10
- import { getMilestone, getMilestoneSlices, getSliceTasks, reopenMilestoneStatus, updateSliceStatus, updateTaskStatus, transaction, } from "../gsd-db.js";
10
+ import { getMilestoneSlices, getSliceTasks, reopenMilestoneCascade, } from "../gsd-db.js";
11
11
  import { invalidateStateCache } from "../state.js";
12
- import { isClosedStatus } from "../status-guards.js";
13
12
  import { renderAllProjections } from "../workflow-projections.js";
14
13
  import { writeManifest } from "../workflow-manifest.js";
15
14
  import { appendEvent } from "../workflow-events.js";
@@ -23,35 +22,18 @@ export async function handleReopenMilestone(params, basePath) {
23
22
  if (!params.milestoneId || typeof params.milestoneId !== "string" || params.milestoneId.trim() === "") {
24
23
  return { error: "milestoneId is required and must be a non-empty string" };
25
24
  }
26
- // ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
27
- let guardError = null;
28
- let slicesResetCount = 0;
29
- let tasksResetCount = 0;
30
- transaction(() => {
31
- const milestone = getMilestone(params.milestoneId);
32
- if (!milestone) {
33
- guardError = `milestone not found: ${params.milestoneId}`;
34
- return;
25
+ // ── Atomic reopen cascade (guards + writes in one transaction) ───────────
26
+ const outcome = reopenMilestoneCascade(params.milestoneId);
27
+ if (!outcome.ok) {
28
+ switch (outcome.reason) {
29
+ case "milestone-not-found":
30
+ return { error: `milestone not found: ${params.milestoneId}` };
31
+ case "milestone-not-closed":
32
+ return { error: `milestone ${params.milestoneId} is not closed (status: ${outcome.status}) — nothing to reopen` };
35
33
  }
36
- if (!isClosedStatus(milestone.status)) {
37
- guardError = `milestone ${params.milestoneId} is not closed (status: ${milestone.status}) — nothing to reopen`;
38
- return;
39
- }
40
- reopenMilestoneStatus(params.milestoneId);
41
- const slices = getMilestoneSlices(params.milestoneId);
42
- slicesResetCount = slices.length;
43
- for (const slice of slices) {
44
- updateSliceStatus(params.milestoneId, slice.id, "in_progress");
45
- const tasks = getSliceTasks(params.milestoneId, slice.id);
46
- tasksResetCount += tasks.length;
47
- for (const task of tasks) {
48
- updateTaskStatus(params.milestoneId, slice.id, task.id, "pending");
49
- }
50
- }
51
- });
52
- if (guardError) {
53
- return { error: guardError };
54
34
  }
35
+ const slicesResetCount = outcome.slicesReset;
36
+ const tasksResetCount = outcome.tasksReset;
55
37
  // ── Invalidate caches ────────────────────────────────────────────────────
56
38
  invalidateStateCache();
57
39
  // ── Clean up stale filesystem artifacts (M12 fix) ────────────────────────
@@ -9,9 +9,8 @@
9
9
  */
10
10
  // GSD — reopen-slice tool handler
11
11
  // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
12
- import { getMilestone, getSlice, getSliceTasks, updateSliceStatus, updateTaskStatus, transaction, } from "../gsd-db.js";
12
+ import { getSliceTasks, reopenSliceCascade, } from "../gsd-db.js";
13
13
  import { invalidateStateCache } from "../state.js";
14
- import { isClosedStatus } from "../status-guards.js";
15
14
  import { renderAllProjections } from "../workflow-projections.js";
16
15
  import { writeManifest } from "../workflow-manifest.js";
17
16
  import { appendEvent } from "../workflow-events.js";
@@ -27,39 +26,21 @@ export async function handleReopenSlice(params, basePath) {
27
26
  if (!params.milestoneId || typeof params.milestoneId !== "string" || params.milestoneId.trim() === "") {
28
27
  return { error: "milestoneId is required and must be a non-empty string" };
29
28
  }
30
- // ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
31
- let guardError = null;
32
- let tasksResetCount = 0;
33
- transaction(() => {
34
- const milestone = getMilestone(params.milestoneId);
35
- if (!milestone) {
36
- guardError = `milestone not found: ${params.milestoneId}`;
37
- return;
29
+ // ── Atomic reopen cascade (guards + writes in one transaction) ───────────
30
+ const outcome = reopenSliceCascade(params.milestoneId, params.sliceId);
31
+ if (!outcome.ok) {
32
+ switch (outcome.reason) {
33
+ case "milestone-not-found":
34
+ return { error: `milestone not found: ${params.milestoneId}` };
35
+ case "milestone-closed":
36
+ return { error: `cannot reopen slice in a closed milestone: ${params.milestoneId} (status: ${outcome.status})` };
37
+ case "slice-not-found":
38
+ return { error: `slice not found: ${params.milestoneId}/${params.sliceId}` };
39
+ case "slice-not-complete":
40
+ return { error: `slice ${params.sliceId} is not complete (status: ${outcome.status}) — nothing to reopen` };
38
41
  }
39
- if (isClosedStatus(milestone.status)) {
40
- guardError = `cannot reopen slice in a closed milestone: ${params.milestoneId} (status: ${milestone.status})`;
41
- return;
42
- }
43
- const slice = getSlice(params.milestoneId, params.sliceId);
44
- if (!slice) {
45
- guardError = `slice not found: ${params.milestoneId}/${params.sliceId}`;
46
- return;
47
- }
48
- if (!isClosedStatus(slice.status)) {
49
- guardError = `slice ${params.sliceId} is not complete (status: ${slice.status}) — nothing to reopen`;
50
- return;
51
- }
52
- // Fetch tasks inside txn so the list is consistent with the slice status check
53
- const tasks = getSliceTasks(params.milestoneId, params.sliceId);
54
- tasksResetCount = tasks.length;
55
- updateSliceStatus(params.milestoneId, params.sliceId, "in_progress");
56
- for (const task of tasks) {
57
- updateTaskStatus(params.milestoneId, params.sliceId, task.id, "pending");
58
- }
59
- });
60
- if (guardError) {
61
- return { error: guardError };
62
42
  }
43
+ const tasksResetCount = outcome.tasksReset;
63
44
  // ── Invalidate caches ────────────────────────────────────────────────────
64
45
  invalidateStateCache();
65
46
  // ── Clean up stale filesystem artifacts (M12 fix) ────────────────────────