gsd-pi 2.82.0-dev.ed17d078d → 3.0.0-dev.04f5ccf82

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 (653) hide show
  1. package/README.md +93 -18
  2. package/dist/cli.js +20 -9
  3. package/dist/headless-ui.js +13 -6
  4. package/dist/headless.js +9 -2
  5. package/dist/resources/.managed-resources-content-hash +1 -1
  6. package/dist/resources/GSD-WORKFLOW.md +10 -1
  7. package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
  8. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +44 -6
  9. package/dist/resources/extensions/cmux/index.js +5 -0
  10. package/dist/resources/extensions/gsd/auto/detect-stuck.js +1 -1
  11. package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
  12. package/dist/resources/extensions/gsd/auto/loop.js +122 -40
  13. package/dist/resources/extensions/gsd/auto/orchestrator.js +15 -4
  14. package/dist/resources/extensions/gsd/auto/phases.js +146 -49
  15. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  16. package/dist/resources/extensions/gsd/auto/unit-runner-events.js +7 -1
  17. package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
  18. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  19. package/dist/resources/extensions/gsd/auto-budget.js +9 -0
  20. package/dist/resources/extensions/gsd/auto-dashboard.js +72 -5
  21. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
  22. package/dist/resources/extensions/gsd/auto-dispatch.js +185 -30
  23. package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
  24. package/dist/resources/extensions/gsd/auto-post-unit.js +329 -137
  25. package/dist/resources/extensions/gsd/auto-prompts.js +36 -10
  26. package/dist/resources/extensions/gsd/auto-recovery.js +82 -16
  27. package/dist/resources/extensions/gsd/auto-start.js +99 -16
  28. package/dist/resources/extensions/gsd/auto-timers.js +11 -3
  29. package/dist/resources/extensions/gsd/auto-verification.js +146 -34
  30. package/dist/resources/extensions/gsd/auto-worktree.js +185 -26
  31. package/dist/resources/extensions/gsd/auto.js +135 -74
  32. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +65 -10
  33. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +13 -10
  34. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +14 -4
  35. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
  36. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +24 -9
  37. package/dist/resources/extensions/gsd/clean-root-preflight.js +267 -8
  38. package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
  39. package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -0
  40. package/dist/resources/extensions/gsd/commands/handlers/ops.js +20 -0
  41. package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
  42. package/dist/resources/extensions/gsd/commands-handlers.js +2 -0
  43. package/dist/resources/extensions/gsd/commands-mcp-status.js +9 -0
  44. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +16 -4
  45. package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
  46. package/dist/resources/extensions/gsd/crash-recovery.js +55 -7
  47. package/dist/resources/extensions/gsd/db/auto-workers.js +30 -0
  48. package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
  49. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  50. package/dist/resources/extensions/gsd/db-base-schema.js +2 -0
  51. package/dist/resources/extensions/gsd/db-migration-steps.js +4 -0
  52. package/dist/resources/extensions/gsd/db-task-slice-rows.js +2 -0
  53. package/dist/resources/extensions/gsd/dispatch-guard.js +46 -2
  54. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  55. package/dist/resources/extensions/gsd/doctor-git-checks.js +74 -3
  56. package/dist/resources/extensions/gsd/doctor-proactive.js +14 -2
  57. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  58. package/dist/resources/extensions/gsd/doctor.js +2 -28
  59. package/dist/resources/extensions/gsd/export-html.js +27 -425
  60. package/dist/resources/extensions/gsd/forensics.js +10 -3
  61. package/dist/resources/extensions/gsd/git-conflict-state.js +21 -0
  62. package/dist/resources/extensions/gsd/git-service.js +152 -15
  63. package/dist/resources/extensions/gsd/gsd-db.js +76 -33
  64. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
  65. package/dist/resources/extensions/gsd/guided-flow.js +110 -117
  66. package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
  67. package/dist/resources/extensions/gsd/init-wizard.js +17 -2
  68. package/dist/resources/extensions/gsd/markdown-renderer.js +14 -11
  69. package/dist/resources/extensions/gsd/mcp-filter.js +58 -0
  70. package/dist/resources/extensions/gsd/migrate/parsers.js +121 -2
  71. package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
  72. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  73. package/dist/resources/extensions/gsd/native-git-bridge.js +57 -14
  74. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -0
  75. package/dist/resources/extensions/gsd/paths.js +4 -0
  76. package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
  77. package/dist/resources/extensions/gsd/planning-path-scope.js +9 -3
  78. package/dist/resources/extensions/gsd/post-execution-checks.js +73 -9
  79. package/dist/resources/extensions/gsd/pre-execution-checks.js +54 -19
  80. package/dist/resources/extensions/gsd/preferences-mcp.js +19 -0
  81. package/dist/resources/extensions/gsd/preferences-models.js +6 -4
  82. package/dist/resources/extensions/gsd/preferences-types.js +3 -0
  83. package/dist/resources/extensions/gsd/preferences-validation.js +147 -0
  84. package/dist/resources/extensions/gsd/preferences.js +35 -0
  85. package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
  86. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  87. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  88. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  89. package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
  90. package/dist/resources/extensions/gsd/prompts/forensics.md +3 -3
  91. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  92. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  93. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  94. package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
  95. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  96. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  97. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  98. package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
  99. package/dist/resources/extensions/gsd/repo-identity.js +39 -22
  100. package/dist/resources/extensions/gsd/repository-registry.js +44 -0
  101. package/dist/resources/extensions/gsd/safety/evidence-collector.js +2 -0
  102. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +42 -18
  103. package/dist/resources/extensions/gsd/session-lock.js +15 -2
  104. package/dist/resources/extensions/gsd/slice-parallel-conflict.js +2 -2
  105. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +84 -5
  106. package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
  107. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  108. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
  109. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
  110. package/dist/resources/extensions/gsd/state.js +28 -7
  111. package/dist/resources/extensions/gsd/status-guards.js +14 -2
  112. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  113. package/dist/resources/extensions/gsd/templates/plan.md +9 -5
  114. package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
  115. package/dist/resources/extensions/gsd/tools/complete-milestone.js +15 -9
  116. package/dist/resources/extensions/gsd/tools/complete-slice.js +56 -10
  117. package/dist/resources/extensions/gsd/tools/exec-tool.js +87 -5
  118. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  119. package/dist/resources/extensions/gsd/tools/plan-slice.js +151 -15
  120. package/dist/resources/extensions/gsd/tools/validate-milestone.js +32 -1
  121. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +185 -40
  122. package/dist/resources/extensions/gsd/tui/render-kit.js +33 -0
  123. package/dist/resources/extensions/gsd/unit-context-composer.js +2 -0
  124. package/dist/resources/extensions/gsd/unit-context-manifest.js +69 -17
  125. package/dist/resources/extensions/gsd/validation.js +23 -1
  126. package/dist/resources/extensions/gsd/verification-gate.js +142 -7
  127. package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
  128. package/dist/resources/extensions/gsd/watch/header-renderer.js +34 -25
  129. package/dist/resources/extensions/gsd/workflow-manifest.js +2 -0
  130. package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
  131. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  132. package/dist/resources/extensions/gsd/worktree-lifecycle.js +86 -19
  133. package/dist/resources/extensions/gsd/worktree-manager.js +11 -2
  134. package/dist/resources/extensions/gsd/worktree-safety.js +43 -4
  135. package/dist/resources/extensions/gsd/worktree-state-projection.js +31 -0
  136. package/dist/resources/extensions/gsd/worktree-telemetry.js +32 -0
  137. package/dist/resources/extensions/shared/html-shell.js +388 -0
  138. package/dist/resources/extensions/shared/interview-ui.js +6 -4
  139. package/dist/resources/extensions/shared/next-action-ui.js +13 -5
  140. package/dist/resources/extensions/subagent/index.js +448 -78
  141. package/dist/resources/extensions/subagent/launch.js +77 -0
  142. package/dist/resources/extensions/subagent/run-store.js +148 -0
  143. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  144. package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
  145. package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
  146. package/dist/resources/extensions/visual-brief/index.js +5 -0
  147. package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
  148. package/dist/resources/extensions/visual-brief/prompts.js +140 -0
  149. package/dist/resources/skills/forensics/SKILL.md +1 -1
  150. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  151. package/dist/web/standalone/.next/BUILD_ID +1 -1
  152. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  153. package/dist/web/standalone/.next/build-manifest.json +3 -3
  154. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  155. package/dist/web/standalone/.next/react-loadable-manifest.json +5 -5
  156. package/dist/web/standalone/.next/required-server-files.json +1 -1
  157. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  159. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  160. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  161. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  162. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  163. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  164. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  165. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  166. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  167. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  168. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  170. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  171. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  172. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  173. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  174. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  175. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  176. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  177. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/index.html +1 -1
  180. package/dist/web/standalone/.next/server/app/index.rsc +4 -7
  181. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  182. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
  183. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  184. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  185. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  186. package/dist/web/standalone/.next/server/app/page.js +2 -2
  187. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  188. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  190. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  191. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  195. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  196. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  197. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  198. package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
  199. package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
  200. package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
  201. package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
  202. package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
  203. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  204. package/dist/web/standalone/server.js +1 -1
  205. package/dist/welcome-screen.js +7 -8
  206. package/package.json +4 -4
  207. package/packages/contracts/dist/rpc.test.js +7 -0
  208. package/packages/contracts/dist/rpc.test.js.map +1 -1
  209. package/packages/contracts/dist/workflow.d.ts +21 -0
  210. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  211. package/packages/contracts/dist/workflow.js +24 -0
  212. package/packages/contracts/dist/workflow.js.map +1 -1
  213. package/packages/contracts/src/rpc.test.ts +8 -0
  214. package/packages/contracts/src/workflow.ts +24 -0
  215. package/packages/daemon/package.json +2 -2
  216. package/packages/mcp-server/README.md +13 -4
  217. package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
  218. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  219. package/packages/mcp-server/dist/workflow-tools.js +80 -0
  220. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  221. package/packages/mcp-server/package.json +2 -2
  222. package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
  223. package/packages/mcp-server/src/workflow-tools.ts +168 -0
  224. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  225. package/packages/native/package.json +1 -1
  226. package/packages/native/src/__tests__/stream-process.test.mjs +32 -12
  227. package/packages/native/tsconfig.json +2 -1
  228. package/packages/native/tsconfig.tsbuildinfo +1 -1
  229. package/packages/pi-agent-core/package.json +1 -1
  230. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  231. package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
  232. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  233. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
  234. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
  235. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
  236. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
  237. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  238. package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
  239. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  240. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
  241. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
  242. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
  243. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
  244. package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
  245. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  246. package/packages/pi-ai/dist/providers/simple-options.js +5 -6
  247. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  248. package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
  249. package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
  250. package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
  251. package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
  252. package/packages/pi-ai/package.json +1 -1
  253. package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
  254. package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
  255. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
  256. package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
  257. package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
  258. package/packages/pi-ai/src/providers/simple-options.ts +5 -6
  259. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  260. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
  261. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
  262. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
  263. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
  264. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
  265. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  266. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
  267. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +6 -1
  269. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  270. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +7 -2
  271. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +14 -1
  273. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
  274. package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
  275. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  276. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +8 -2
  277. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  278. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  279. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +3 -0
  280. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  281. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +16 -0
  282. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
  283. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  284. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
  285. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  286. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -1
  287. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  288. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +82 -97
  290. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  291. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -7
  292. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +11 -0
  294. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  295. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  298. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  299. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
  300. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  301. package/packages/pi-coding-agent/package.json +1 -1
  302. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  303. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  304. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
  305. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +23 -1
  306. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +7 -2
  307. package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
  308. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +17 -1
  309. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +20 -0
  310. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +3 -0
  311. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
  312. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -1
  313. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +91 -102
  314. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +15 -1
  315. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +9 -9
  316. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
  317. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
  318. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  319. package/packages/pi-tui/dist/__tests__/loader.test.d.ts +2 -0
  320. package/packages/pi-tui/dist/__tests__/loader.test.d.ts.map +1 -0
  321. package/packages/pi-tui/dist/__tests__/loader.test.js +24 -0
  322. package/packages/pi-tui/dist/__tests__/loader.test.js.map +1 -0
  323. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
  324. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
  325. package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
  326. package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
  327. package/packages/pi-tui/dist/__tests__/tui.test.js +72 -4
  328. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  329. package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
  330. package/packages/pi-tui/dist/components/loader.js +3 -0
  331. package/packages/pi-tui/dist/components/loader.js.map +1 -1
  332. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  333. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  334. package/packages/pi-tui/dist/terminal.js +12 -0
  335. package/packages/pi-tui/dist/terminal.js.map +1 -1
  336. package/packages/pi-tui/dist/tui.d.ts +1 -0
  337. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  338. package/packages/pi-tui/dist/tui.js +117 -33
  339. package/packages/pi-tui/dist/tui.js.map +1 -1
  340. package/packages/pi-tui/package.json +1 -1
  341. package/packages/pi-tui/src/__tests__/loader.test.ts +30 -0
  342. package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
  343. package/packages/pi-tui/src/__tests__/tui.test.ts +90 -4
  344. package/packages/pi-tui/src/components/loader.ts +3 -0
  345. package/packages/pi-tui/src/terminal.ts +11 -0
  346. package/packages/pi-tui/src/tui.ts +116 -33
  347. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  348. package/packages/rpc-client/package.json +1 -1
  349. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  350. package/pkg/package.json +1 -1
  351. package/src/resources/GSD-WORKFLOW.md +10 -1
  352. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  353. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +52 -6
  354. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  355. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +49 -2
  356. package/src/resources/extensions/cmux/index.ts +6 -0
  357. package/src/resources/extensions/gsd/auto/contracts.ts +19 -6
  358. package/src/resources/extensions/gsd/auto/detect-stuck.ts +1 -0
  359. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  360. package/src/resources/extensions/gsd/auto/loop.ts +123 -40
  361. package/src/resources/extensions/gsd/auto/orchestrator.ts +15 -4
  362. package/src/resources/extensions/gsd/auto/phases.ts +172 -60
  363. package/src/resources/extensions/gsd/auto/session.ts +16 -0
  364. package/src/resources/extensions/gsd/auto/types.ts +3 -0
  365. package/src/resources/extensions/gsd/auto/unit-runner-events.ts +6 -2
  366. package/src/resources/extensions/gsd/auto/workflow-kernel.ts +5 -1
  367. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
  368. package/src/resources/extensions/gsd/auto-budget.ts +11 -0
  369. package/src/resources/extensions/gsd/auto-dashboard.ts +78 -5
  370. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
  371. package/src/resources/extensions/gsd/auto-dispatch.ts +208 -29
  372. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  373. package/src/resources/extensions/gsd/auto-post-unit.ts +369 -148
  374. package/src/resources/extensions/gsd/auto-prompts.ts +36 -13
  375. package/src/resources/extensions/gsd/auto-recovery.ts +86 -13
  376. package/src/resources/extensions/gsd/auto-start.ts +109 -14
  377. package/src/resources/extensions/gsd/auto-timers.ts +10 -3
  378. package/src/resources/extensions/gsd/auto-verification.ts +174 -42
  379. package/src/resources/extensions/gsd/auto-worktree.ts +202 -30
  380. package/src/resources/extensions/gsd/auto.ts +172 -81
  381. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +66 -10
  382. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +13 -10
  383. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +13 -4
  384. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
  385. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +27 -10
  386. package/src/resources/extensions/gsd/clean-root-preflight.ts +284 -8
  387. package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
  388. package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -0
  389. package/src/resources/extensions/gsd/commands/handlers/ops.ts +21 -0
  390. package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
  391. package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
  392. package/src/resources/extensions/gsd/commands-mcp-status.ts +8 -0
  393. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +17 -4
  394. package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
  395. package/src/resources/extensions/gsd/crash-recovery.ts +55 -6
  396. package/src/resources/extensions/gsd/db/auto-workers.ts +37 -0
  397. package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
  398. package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
  399. package/src/resources/extensions/gsd/db-base-schema.ts +2 -0
  400. package/src/resources/extensions/gsd/db-migration-steps.ts +5 -0
  401. package/src/resources/extensions/gsd/db-task-slice-rows.ts +4 -0
  402. package/src/resources/extensions/gsd/dispatch-guard.ts +60 -2
  403. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  404. package/src/resources/extensions/gsd/doctor-git-checks.ts +73 -3
  405. package/src/resources/extensions/gsd/doctor-proactive.ts +18 -2
  406. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  407. package/src/resources/extensions/gsd/doctor-types.ts +2 -0
  408. package/src/resources/extensions/gsd/doctor.ts +2 -27
  409. package/src/resources/extensions/gsd/export-html.ts +27 -427
  410. package/src/resources/extensions/gsd/forensics.ts +9 -3
  411. package/src/resources/extensions/gsd/git-conflict-state.ts +23 -0
  412. package/src/resources/extensions/gsd/git-service.ts +182 -16
  413. package/src/resources/extensions/gsd/gsd-db.ts +80 -31
  414. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
  415. package/src/resources/extensions/gsd/guided-flow.ts +142 -134
  416. package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
  417. package/src/resources/extensions/gsd/init-wizard.ts +17 -2
  418. package/src/resources/extensions/gsd/journal.ts +8 -1
  419. package/src/resources/extensions/gsd/markdown-renderer.ts +14 -11
  420. package/src/resources/extensions/gsd/mcp-filter.ts +80 -0
  421. package/src/resources/extensions/gsd/migrate/parsers.ts +139 -2
  422. package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
  423. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  424. package/src/resources/extensions/gsd/native-git-bridge.ts +63 -14
  425. package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -0
  426. package/src/resources/extensions/gsd/paths.ts +5 -0
  427. package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
  428. package/src/resources/extensions/gsd/planning-path-scope.ts +10 -2
  429. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -12
  430. package/src/resources/extensions/gsd/pre-execution-checks.ts +67 -19
  431. package/src/resources/extensions/gsd/preferences-mcp.ts +27 -0
  432. package/src/resources/extensions/gsd/preferences-models.ts +6 -4
  433. package/src/resources/extensions/gsd/preferences-types.ts +35 -0
  434. package/src/resources/extensions/gsd/preferences-validation.ts +154 -0
  435. package/src/resources/extensions/gsd/preferences.ts +39 -0
  436. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  437. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  438. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  439. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  440. package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
  441. package/src/resources/extensions/gsd/prompts/forensics.md +3 -3
  442. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  443. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  444. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  445. package/src/resources/extensions/gsd/prompts/queue.md +4 -4
  446. package/src/resources/extensions/gsd/prompts/reactive-execute.md +1 -1
  447. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  448. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  449. package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
  450. package/src/resources/extensions/gsd/repo-identity.ts +45 -25
  451. package/src/resources/extensions/gsd/repository-registry.ts +77 -0
  452. package/src/resources/extensions/gsd/safety/evidence-collector.ts +2 -0
  453. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +54 -19
  454. package/src/resources/extensions/gsd/session-lock.ts +15 -2
  455. package/src/resources/extensions/gsd/slice-parallel-conflict.ts +2 -2
  456. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +75 -3
  457. package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
  458. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  459. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
  460. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
  461. package/src/resources/extensions/gsd/state.ts +33 -7
  462. package/src/resources/extensions/gsd/status-guards.ts +16 -2
  463. package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  464. package/src/resources/extensions/gsd/templates/plan.md +9 -5
  465. package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
  466. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +1 -1
  467. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +10 -1
  468. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
  469. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  470. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +775 -34
  471. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +245 -28
  472. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
  473. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
  474. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
  475. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +136 -13
  476. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +64 -0
  477. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +12 -0
  478. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  479. package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
  480. package/src/resources/extensions/gsd/tests/auto-workers.test.ts +29 -0
  481. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  482. package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +21 -0
  483. package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
  484. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
  485. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +170 -3
  486. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +32 -4
  487. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
  488. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
  489. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +55 -2
  490. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +60 -9
  491. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  492. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +104 -2
  493. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
  494. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
  495. package/src/resources/extensions/gsd/tests/db-task-slice-rows.test.ts +1 -0
  496. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +61 -2
  497. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +139 -1
  498. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +68 -1
  499. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +140 -1
  500. package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
  501. package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +50 -0
  502. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +97 -0
  503. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +99 -1
  504. package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +15 -1
  505. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  506. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +28 -0
  507. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
  508. package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
  509. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
  510. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
  511. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  512. package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
  513. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
  514. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  515. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  516. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  517. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +22 -0
  518. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +36 -1
  519. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +33 -1
  520. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  521. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +226 -2
  522. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +5 -21
  523. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +15 -0
  524. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  525. package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +40 -0
  526. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +49 -3
  527. package/src/resources/extensions/gsd/tests/journal.test.ts +32 -0
  528. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +287 -0
  529. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +11 -0
  530. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
  531. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +21 -40
  532. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +59 -1
  533. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
  534. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +60 -0
  535. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +80 -2
  536. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
  537. package/src/resources/extensions/gsd/tests/parallel-orchestrator-zombie-cleanup.test.ts +55 -0
  538. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
  539. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
  540. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
  541. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
  542. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  543. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +343 -3
  544. package/src/resources/extensions/gsd/tests/plan-task.test.ts +18 -1
  545. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  546. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -3
  547. package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +8 -1
  548. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
  549. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +147 -0
  550. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +54 -0
  551. package/src/resources/extensions/gsd/tests/preferences-mcp.test.ts +128 -0
  552. package/src/resources/extensions/gsd/tests/preferences.test.ts +75 -0
  553. package/src/resources/extensions/gsd/tests/prefs-missing-models-crash.test.ts +148 -0
  554. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +79 -0
  555. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +42 -1
  556. package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
  557. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
  558. package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
  559. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
  560. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
  561. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +28 -1
  562. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +52 -0
  563. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
  564. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +35 -0
  565. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +59 -1
  566. package/src/resources/extensions/gsd/tests/slice-parallel-conflict.test.ts +2 -2
  567. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +112 -1
  568. package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
  569. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +94 -2
  570. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
  571. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
  572. package/src/resources/extensions/gsd/tests/status-guards.test.ts +17 -1
  573. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  574. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +2 -1
  575. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  576. package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +22 -0
  577. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +1 -0
  578. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +131 -9
  579. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +111 -1
  580. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
  581. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +68 -0
  582. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +42 -1
  583. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +188 -1
  584. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
  585. package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
  586. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
  587. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
  588. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +153 -1
  589. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
  590. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
  591. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +73 -2
  592. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +25 -0
  593. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +90 -0
  594. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +95 -0
  595. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +16 -0
  596. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +27 -0
  597. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +59 -0
  598. package/src/resources/extensions/gsd/tools/complete-milestone.ts +18 -10
  599. package/src/resources/extensions/gsd/tools/complete-slice.ts +57 -10
  600. package/src/resources/extensions/gsd/tools/exec-tool.ts +98 -5
  601. package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
  602. package/src/resources/extensions/gsd/tools/plan-slice.ts +172 -12
  603. package/src/resources/extensions/gsd/tools/validate-milestone.ts +31 -0
  604. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +166 -17
  605. package/src/resources/extensions/gsd/tui/render-kit.ts +44 -0
  606. package/src/resources/extensions/gsd/types.ts +1 -1
  607. package/src/resources/extensions/gsd/unit-context-composer.ts +3 -0
  608. package/src/resources/extensions/gsd/unit-context-manifest.ts +86 -19
  609. package/src/resources/extensions/gsd/validation.ts +23 -1
  610. package/src/resources/extensions/gsd/verification-gate.ts +170 -6
  611. package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
  612. package/src/resources/extensions/gsd/watch/header-renderer.ts +35 -24
  613. package/src/resources/extensions/gsd/workflow-manifest.ts +2 -0
  614. package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
  615. package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
  616. package/src/resources/extensions/gsd/worktree-lifecycle.ts +98 -20
  617. package/src/resources/extensions/gsd/worktree-manager.ts +14 -2
  618. package/src/resources/extensions/gsd/worktree-safety.ts +57 -10
  619. package/src/resources/extensions/gsd/worktree-state-projection.ts +43 -0
  620. package/src/resources/extensions/gsd/worktree-telemetry.ts +39 -0
  621. package/src/resources/extensions/shared/html-shell.ts +412 -0
  622. package/src/resources/extensions/shared/interview-ui.ts +6 -4
  623. package/src/resources/extensions/shared/next-action-ui.ts +11 -5
  624. package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +15 -0
  625. package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +32 -0
  626. package/src/resources/extensions/subagent/index.ts +567 -103
  627. package/src/resources/extensions/subagent/launch.ts +131 -0
  628. package/src/resources/extensions/subagent/run-store.ts +218 -0
  629. package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
  630. package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
  631. package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
  632. package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
  633. package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
  634. package/src/resources/extensions/visual-brief/index.ts +8 -0
  635. package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
  636. package/src/resources/extensions/visual-brief/prompts.ts +183 -0
  637. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
  638. package/src/resources/skills/forensics/SKILL.md +1 -1
  639. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  640. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  641. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
  642. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
  643. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
  644. package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
  645. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  646. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  647. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  648. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  649. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  650. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  651. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  652. /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → w_ikFkx_-OHxisG9xjz4u}/_buildManifest.js +0 -0
  653. /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → w_ikFkx_-OHxisG9xjz4u}/_ssgManifest.js +0 -0
@@ -57,6 +57,12 @@ skills_used:
57
57
  - {{howToVerifyThisTaskIsActuallyDone}}
58
58
  - {{commandToRun_OR_behaviorToCheck}}
59
59
 
60
+ ## Verify Rules
61
+
62
+ - Use a real executable check, not prose.
63
+ - If the check needs file-content assertions, write a `node:test` file and run it with `node --test` or a package test script.
64
+ - Do not use inline `node -e` assertions for verification.
65
+
60
66
  ## Observability Impact
61
67
 
62
68
  <!-- OMIT THIS SECTION ENTIRELY for simple tasks that don't touch runtime boundaries,
@@ -72,7 +78,8 @@ skills_used:
72
78
  <!-- Every input MUST be a backtick-wrapped file path. These paths are machine-parsed to
73
79
  derive task dependencies — vague descriptions without paths break dependency detection.
74
80
  For the first task in a slice with no prior task outputs, list the existing source files
75
- this task reads or modifies. -->
81
+ this task reads or modifies.
82
+ Tool field: inputs must be an array of strings, e.g. ["src/index.ts"], never a single string. -->
76
83
 
77
84
  - `{{filePath}}` — {{whatThisTaskNeedsFromPriorWork}}
78
85
 
@@ -82,6 +89,7 @@ skills_used:
82
89
  or modifies. These paths are machine-parsed to derive task dependencies.
83
90
  This task should produce a real increment toward making the slice goal/demo true. A full
84
91
  slice plan should not be able to mark every task complete while the claimed slice behavior
85
- still does not work at the stated proof level. -->
92
+ still does not work at the stated proof level.
93
+ Tool field: expectedOutput must be an array of strings, e.g. ["src/index.ts"], never a single string. -->
86
94
 
87
95
  - `{{filePath}}` — {{whatThisTaskCreatesOrModifies}}
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { join } from "node:path";
10
10
  import { mkdirSync, existsSync } from "node:fs";
11
- import { transaction, getMilestone, getMilestoneSlices, getSliceTasks, updateMilestoneStatus, } from "../gsd-db.js";
11
+ import { transaction, getMilestone, getMilestoneSlices, getSliceTasks, getLatestAssessmentByScope, updateMilestoneStatus, } from "../gsd-db.js";
12
12
  import { resolveMilestonePath, clearPathCache } from "../paths.js";
13
13
  import { isClosedStatus } from "../status-guards.js";
14
14
  import { saveFile, clearParseCache } from "../files.js";
@@ -24,11 +24,11 @@ function renderMilestoneSummaryMarkdown(params, completedAt) {
24
24
  const keyFiles = params.keyFiles ?? [];
25
25
  const lessonsLearned = params.lessonsLearned ?? [];
26
26
  const keyDecisionsYaml = keyDecisions.length > 0
27
- ? keyDecisions.map(d => ` - ${d}`).join("\n")
28
- : " - (none)";
27
+ ? `\n${keyDecisions.map(d => ` - ${d}`).join("\n")}`
28
+ : " []";
29
29
  const keyFilesYaml = keyFiles.length > 0
30
- ? keyFiles.map(f => ` - ${f}`).join("\n")
31
- : " - (none)";
30
+ ? `\n${keyFiles.map(f => ` - ${f}`).join("\n")}`
31
+ : " []";
32
32
  const lessonsYaml = lessonsLearned.length > 0
33
33
  ? lessonsLearned.map(l => ` - ${l}`).join("\n")
34
34
  : " - (none)";
@@ -37,10 +37,8 @@ id: ${params.milestoneId}
37
37
  title: "${displayTitle}"
38
38
  status: complete
39
39
  completed_at: ${completedAt}
40
- key_decisions:
41
- ${keyDecisionsYaml}
42
- key_files:
43
- ${keyFilesYaml}
40
+ key_decisions:${keyDecisionsYaml}
41
+ key_files:${keyFilesYaml}
44
42
  lessons_learned:
45
43
  ${lessonsYaml}
46
44
  ---
@@ -101,6 +99,14 @@ export async function handleCompleteMilestone(params, basePath) {
101
99
  alreadyComplete = true;
102
100
  return;
103
101
  }
102
+ // Defense-in-depth: only a passing milestone validation permits closeout.
103
+ const validation = getLatestAssessmentByScope(params.milestoneId, "milestone-validation");
104
+ if (validation?.status !== "pass") {
105
+ guardError =
106
+ `Refusing to complete ${params.milestoneId}: latest milestone-validation verdict is ` +
107
+ `"${validation?.status ?? "absent"}". Only verdict=pass permits closeout.`;
108
+ return;
109
+ }
104
110
  // Verify all slices are complete
105
111
  const slices = getMilestoneSlices(params.milestoneId);
106
112
  if (slices.length === 0) {
@@ -65,11 +65,11 @@ function renderSliceSummaryMarkdown(params) {
65
65
  ? affects.map(a => ` - ${a}`).join("\n")
66
66
  : " []";
67
67
  const keyFilesYaml = keyFiles.length > 0
68
- ? keyFiles.map(f => ` - ${f}`).join("\n")
69
- : " - (none)";
68
+ ? `\n${keyFiles.map(f => ` - ${f}`).join("\n")}`
69
+ : " []";
70
70
  const keyDecisionsYaml = keyDecisions.length > 0
71
- ? keyDecisions.map(d => ` - ${d}`).join("\n")
72
- : " - (none)";
71
+ ? `\n${keyDecisions.map(d => ` - ${d}`).join("\n")}`
72
+ : " []";
73
73
  const patternsYaml = patternsEstablished.length > 0
74
74
  ? patternsEstablished.map(p => ` - ${p}`).join("\n")
75
75
  : " - (none)";
@@ -106,10 +106,8 @@ requires:
106
106
  ${requiresYaml}
107
107
  affects:
108
108
  ${affectsYaml}
109
- key_files:
110
- ${keyFilesYaml}
111
- key_decisions:
112
- ${keyDecisionsYaml}
109
+ key_files:${keyFilesYaml}
110
+ key_decisions:${keyDecisionsYaml}
113
111
  patterns_established:
114
112
  ${patternsYaml}
115
113
  observability_surfaces:
@@ -183,6 +181,31 @@ function renderUatMarkdown(params) {
183
181
  ${params.uatContent}
184
182
  `;
185
183
  }
184
+ function parseRequirementSection(summaryMd, heading, field) {
185
+ const headingLine = `## ${heading}\n\n`;
186
+ const start = summaryMd.indexOf(headingLine);
187
+ if (start === -1)
188
+ return [];
189
+ const contentStart = start + headingLine.length;
190
+ const nextHeading = summaryMd.indexOf("\n\n## ", contentStart);
191
+ const content = nextHeading === -1
192
+ ? summaryMd.slice(contentStart)
193
+ : summaryMd.slice(contentStart, nextHeading);
194
+ return content
195
+ .split("\n")
196
+ .map((line) => line.trim())
197
+ .filter((line) => line.startsWith("- "))
198
+ .map((line) => line.slice(2).trim())
199
+ .map((line) => {
200
+ const pair = line.match(/^(.+?)\s*(?:—|-)\s+(.+)$/);
201
+ const id = pair ? pair[1].trim() : line.trim();
202
+ const detail = pair ? pair[2].trim() : "";
203
+ if (!id || !detail)
204
+ return null;
205
+ return { id, [field]: detail };
206
+ })
207
+ .filter((entry) => entry !== null);
208
+ }
186
209
  /**
187
210
  * Handle the complete_slice operation end-to-end.
188
211
  *
@@ -218,6 +241,7 @@ export async function handleCompleteSlice(params, basePath) {
218
241
  // ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
219
242
  const completedAt = new Date().toISOString();
220
243
  let guardError = null;
244
+ let existingSummaryMd = "";
221
245
  transaction(() => {
222
246
  // State machine preconditions (inside txn for atomicity).
223
247
  // Milestone/slice not existing is OK — insertMilestone/insertSlice below will auto-create.
@@ -228,6 +252,7 @@ export async function handleCompleteSlice(params, basePath) {
228
252
  return;
229
253
  }
230
254
  const slice = getSlice(params.milestoneId, params.sliceId);
255
+ existingSummaryMd = slice?.full_summary_md?.trim() ?? "";
231
256
  if (slice && isClosedStatus(slice.status)) {
232
257
  if (isStaleWrite("complete-slice")) {
233
258
  guardError = "__stale_duplicate__";
@@ -272,8 +297,29 @@ export async function handleCompleteSlice(params, basePath) {
272
297
  if (guardError) {
273
298
  return { error: guardError };
274
299
  }
300
+ const effectiveParams = { ...params };
301
+ if (existingSummaryMd) {
302
+ // Keep these heading names in lock-step with renderSliceSummaryMarkdown's
303
+ // section titles so omitted CompleteSliceParams requirement fields can be
304
+ // backfilled from previously rendered summary markdown.
305
+ if (effectiveParams.requirementsAdvanced === undefined) {
306
+ const parsed = parseRequirementSection(existingSummaryMd, "Requirements Advanced", "how");
307
+ if (parsed.length > 0)
308
+ effectiveParams.requirementsAdvanced = parsed;
309
+ }
310
+ if (effectiveParams.requirementsValidated === undefined) {
311
+ const parsed = parseRequirementSection(existingSummaryMd, "Requirements Validated", "proof");
312
+ if (parsed.length > 0)
313
+ effectiveParams.requirementsValidated = parsed;
314
+ }
315
+ if (effectiveParams.requirementsInvalidated === undefined) {
316
+ const parsed = parseRequirementSection(existingSummaryMd, "Requirements Invalidated or Re-scoped", "what");
317
+ if (parsed.length > 0)
318
+ effectiveParams.requirementsInvalidated = parsed;
319
+ }
320
+ }
275
321
  // Render summary markdown
276
- const summaryMd = renderSliceSummaryMarkdown(params);
322
+ const summaryMd = renderSliceSummaryMarkdown(effectiveParams);
277
323
  // Resolve and write summary to disk
278
324
  let summaryPath;
279
325
  const sliceDir = resolveSlicePath(basePath, params.milestoneId, params.sliceId);
@@ -287,7 +333,7 @@ export async function handleCompleteSlice(params, basePath) {
287
333
  mkdirSync(manualSliceDir, { recursive: true });
288
334
  summaryPath = join(manualSliceDir, `${params.sliceId}-SUMMARY.md`);
289
335
  }
290
- const uatMd = renderUatMarkdown(params);
336
+ const uatMd = renderUatMarkdown(effectiveParams);
291
337
  const uatPath = summaryPath.replace(/-SUMMARY\.md$/, "-UAT.md");
292
338
  setSliceSummaryMd(params.milestoneId, params.sliceId, summaryMd, uatMd);
293
339
  let projectionStale = false;
@@ -1,9 +1,7 @@
1
- // GSD Exec Tool — executor for the gsd_exec MCP tool.
2
- //
3
- // Thin wrapper around exec-sandbox.ts that reads effective options from
4
- // the project preferences (context_mode block) and formats the result
5
- // for MCP return.
1
+ // Project/App: GSD-2
2
+ // File Purpose: Executor for the gsd_exec MCP tool.
6
3
  import { EXEC_DEFAULTS, runExecSandbox, } from "../exec-sandbox.js";
4
+ import path from "node:path";
7
5
  import { isContextModeEnabled } from "../preferences-types.js";
8
6
  import { contextModeDisabledResult } from "./context-mode-tool-result.js";
9
7
  export function buildExecOptions(baseDir, cfg, extras) {
@@ -41,6 +39,86 @@ function paramError(message) {
41
39
  isError: true,
42
40
  };
43
41
  }
42
+ function escapeRegExp(value) {
43
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
44
+ }
45
+ function normalizeScanPath(value) {
46
+ return value.replace(/\\/g, "/").replace(/\/+$/, "");
47
+ }
48
+ function parseWorktreeBase(baseDir) {
49
+ const normalizedBase = normalizeScanPath(baseDir);
50
+ const marker = "/.gsd/worktrees/";
51
+ const markerIndex = normalizedBase.indexOf(marker);
52
+ if (markerIndex <= 0)
53
+ return null;
54
+ return {
55
+ originalRoot: normalizedBase.slice(0, markerIndex),
56
+ worktreeRoot: normalizedBase,
57
+ };
58
+ }
59
+ function pathInside(parent, target) {
60
+ const parentWithSep = parent.endsWith("/") ? parent : `${parent}/`;
61
+ return target === parent || target.startsWith(parentWithSep);
62
+ }
63
+ function stripWrappingQuotes(value) {
64
+ const trimmed = value.trim();
65
+ if (trimmed.length < 2)
66
+ return trimmed;
67
+ const first = trimmed[0];
68
+ const last = trimmed[trimmed.length - 1];
69
+ if ((first === "'" || first === '"' || first === "`") && last === first) {
70
+ return trimmed.slice(1, -1).trim();
71
+ }
72
+ return trimmed;
73
+ }
74
+ function extractPathLikeValues(script) {
75
+ const values = [];
76
+ const push = (candidate) => {
77
+ const cleaned = stripWrappingQuotes(candidate).trim();
78
+ if (!cleaned)
79
+ return;
80
+ values.push(cleaned);
81
+ };
82
+ const pushQuotedLiterals = (source, depth = 0) => {
83
+ for (const match of source.matchAll(/(["'`])((?:\\.|(?!\1).)*)\1/g)) {
84
+ push(match[2]);
85
+ if (depth < 2 && /["'`]/.test(match[2])) {
86
+ pushQuotedLiterals(match[2], depth + 1);
87
+ }
88
+ }
89
+ };
90
+ for (const match of script.matchAll(/(?:^|[;\n\r]|\&\&|\|\|)\s*cd\s+([^\n\r;|&]+)/g)) {
91
+ push(match[1]);
92
+ }
93
+ for (const match of script.matchAll(/process\.chdir\(\s*([^\n\r;]+?)\s*\)/g)) {
94
+ push(match[1]);
95
+ pushQuotedLiterals(match[1]);
96
+ }
97
+ pushQuotedLiterals(script);
98
+ return values;
99
+ }
100
+ function resolvesToOriginalRootOutsideWorktree(script, baseDir) {
101
+ const parsed = parseWorktreeBase(baseDir);
102
+ if (!parsed)
103
+ return false;
104
+ const normalizedWorktree = normalizeScanPath(path.resolve(parsed.worktreeRoot));
105
+ const normalizedOriginalRoot = normalizeScanPath(path.resolve(parsed.originalRoot));
106
+ for (const value of extractPathLikeValues(script)) {
107
+ const resolved = normalizeScanPath(path.resolve(normalizedWorktree, value));
108
+ if (pathInside(normalizedOriginalRoot, resolved) && !pathInside(normalizedWorktree, resolved)) {
109
+ return true;
110
+ }
111
+ }
112
+ return false;
113
+ }
114
+ function scriptReferencesOriginalRootFromWorktree(script, baseDir) {
115
+ const parsed = parseWorktreeBase(baseDir);
116
+ if (!parsed)
117
+ return false;
118
+ const normalizedScript = script.replace(/\\/g, "/");
119
+ const originalRootPattern = new RegExp(`${escapeRegExp(parsed.originalRoot)}(?=$|[\\s'"\\\`;)&|<>]|/(?!\\.gsd/worktrees(?:/|$)))`);
120
+ return originalRootPattern.test(normalizedScript);
121
+ }
44
122
  export async function executeGsdExec(params, deps) {
45
123
  if (!isEnabled(deps.preferences))
46
124
  return contextModeDisabledResult("gsd_exec");
@@ -55,6 +133,10 @@ export async function executeGsdExec(params, deps) {
55
133
  if (Buffer.byteLength(script, "utf8") > 200_000) {
56
134
  return paramError("script exceeds the 200 KB length limit");
57
135
  }
136
+ if (resolvesToOriginalRootOutsideWorktree(script, deps.baseDir)
137
+ || scriptReferencesOriginalRootFromWorktree(script, deps.baseDir)) {
138
+ return paramError("script references the original project root while running inside a milestone worktree; use the active worktree path or relative paths");
139
+ }
58
140
  const opts = buildExecOptions(deps.baseDir, deps.preferences?.context_mode, { env: deps.env, now: deps.now, generateId: deps.generateId });
59
141
  const run = deps.run ?? runExecSandbox;
60
142
  try {
@@ -1,6 +1,6 @@
1
1
  import { clearParseCache } from "../files.js";
2
2
  import { isClosedStatus } from "../status-guards.js";
3
- import { isNonEmptyString, validateStringArray } from "../validation.js";
3
+ import { isNonEmptyString, validateStringArray, validateTitle } from "../validation.js";
4
4
  import { transaction, getMilestone, getMilestoneSlices, getSlice, insertMilestone, insertSlice, upsertMilestonePlanning, upsertSlicePlanning, } from "../gsd-db.js";
5
5
  import { invalidateStateCache } from "../state.js";
6
6
  import { renderRoadmapFromDb } from "../markdown-renderer.js";
@@ -77,6 +77,9 @@ function validateSlices(value) {
77
77
  seen.add(sliceId);
78
78
  if (!isNonEmptyString(title))
79
79
  throw new Error(`slices[${index}].title must be a non-empty string`);
80
+ const titleIssue = validateTitle(title);
81
+ if (titleIssue)
82
+ throw new Error(`slices[${index}].title is invalid: ${titleIssue}`);
80
83
  if (!isNonEmptyString(risk))
81
84
  throw new Error(`slices[${index}].risk must be a non-empty string`);
82
85
  if (!Array.isArray(depends) || depends.some((item) => !isNonEmptyString(item))) {
@@ -127,6 +130,9 @@ function validateParams(params) {
127
130
  throw new Error("title is required");
128
131
  if (!isNonEmptyString(params?.vision))
129
132
  throw new Error("vision is required");
133
+ const milestoneTitleIssue = validateTitle(params.title);
134
+ if (milestoneTitleIssue)
135
+ throw new Error(`title is invalid: ${milestoneTitleIssue}`);
130
136
  return {
131
137
  ...params,
132
138
  dependsOn: params.dependsOn ? validateStringArray(params.dependsOn, "dependsOn") : [],
@@ -1,7 +1,9 @@
1
+ import { existsSync, rmSync } from "node:fs";
2
+ import { join, relative } from "node:path";
1
3
  import { clearParseCache } from "../files.js";
2
4
  import { isClosedStatus, isDeferredStatus } from "../status-guards.js";
3
- import { isNonEmptyString } from "../validation.js";
4
- import { transaction, getMilestone, getSlice, insertTask, upsertSlicePlanning, upsertTaskPlanning, insertGateRow, updateSliceStatus, } from "../gsd-db.js";
5
+ import { isNonEmptyString, validateStringArray } from "../validation.js";
6
+ import { transaction, getMilestone, getSlice, getSliceTasks, insertTask, upsertSlicePlanning, upsertTaskPlanning, insertGateRow, updateSliceStatus, setSliceSketchFlag, deleteTask, deleteArtifactByPath, } from "../gsd-db.js";
5
7
  import { invalidateStateCache } from "../state.js";
6
8
  import { renderPlanFromDb } from "../markdown-renderer.js";
7
9
  import { renderAllProjections } from "../workflow-projections.js";
@@ -9,6 +11,21 @@ import { writeManifest } from "../workflow-manifest.js";
9
11
  import { appendEvent } from "../workflow-events.js";
10
12
  import { logWarning } from "../workflow-logger.js";
11
13
  import { validatePlanningPathScope } from "../planning-path-scope.js";
14
+ import { checkFilePathConsistency, checkTaskOrdering } from "../pre-execution-checks.js";
15
+ import { buildTaskFileName, gsdProjectionRoot } from "../paths.js";
16
+ import { loadEffectiveGSDPreferences } from "../preferences.js";
17
+ import { createRepositoryRegistryFromPreferences } from "../repository-registry.js";
18
+ function validateRepositoryTargetIds(field, value) {
19
+ if (value === undefined)
20
+ return null;
21
+ const ids = validateStringArray(value, field);
22
+ if (ids.length === 0)
23
+ throw new Error(`${field} must include at least one repository id when provided`);
24
+ const deduped = Array.from(new Set(ids.map((id) => id.trim()).filter(Boolean)));
25
+ if (deduped.length === 0)
26
+ throw new Error(`${field} must include at least one repository id when provided`);
27
+ return deduped;
28
+ }
12
29
  function validateTasks(value) {
13
30
  if (!Array.isArray(value) || value.length === 0) {
14
31
  throw new Error("tasks must be a non-empty array");
@@ -28,6 +45,7 @@ function validateTasks(value) {
28
45
  const inputs = obj.inputs;
29
46
  const expectedOutput = obj.expectedOutput;
30
47
  const observabilityImpact = obj.observabilityImpact;
48
+ const targetRepositories = obj.targetRepositories;
31
49
  if (!isNonEmptyString(taskId))
32
50
  throw new Error(`tasks[${index}].taskId must be a non-empty string`);
33
51
  if (seen.has(taskId))
@@ -39,30 +57,26 @@ function validateTasks(value) {
39
57
  throw new Error(`tasks[${index}].description must be a non-empty string`);
40
58
  if (!isNonEmptyString(estimate))
41
59
  throw new Error(`tasks[${index}].estimate must be a non-empty string`);
42
- if (!Array.isArray(files) || files.some((item) => !isNonEmptyString(item))) {
43
- throw new Error(`tasks[${index}].files must be an array of non-empty strings`);
44
- }
60
+ const validatedFiles = validateStringArray(files, `tasks[${index}].files`);
45
61
  if (!isNonEmptyString(verify))
46
62
  throw new Error(`tasks[${index}].verify must be a non-empty string`);
47
- if (!Array.isArray(inputs) || inputs.some((item) => !isNonEmptyString(item))) {
48
- throw new Error(`tasks[${index}].inputs must be an array of non-empty strings`);
49
- }
50
- if (!Array.isArray(expectedOutput) || expectedOutput.some((item) => !isNonEmptyString(item))) {
51
- throw new Error(`tasks[${index}].expectedOutput must be an array of non-empty strings`);
52
- }
63
+ const validatedInputs = validateStringArray(inputs, `tasks[${index}].inputs`);
64
+ const validatedExpectedOutput = validateStringArray(expectedOutput, `tasks[${index}].expectedOutput`);
53
65
  if (observabilityImpact !== undefined && !isNonEmptyString(observabilityImpact)) {
54
66
  throw new Error(`tasks[${index}].observabilityImpact must be a non-empty string when provided`);
55
67
  }
68
+ const validatedTargetRepositories = validateRepositoryTargetIds(`tasks[${index}].targetRepositories`, targetRepositories);
56
69
  return {
57
70
  taskId,
58
71
  title,
59
72
  description,
60
73
  estimate,
61
- files,
74
+ files: validatedFiles,
62
75
  verify,
63
- inputs,
64
- expectedOutput,
76
+ inputs: validatedInputs,
77
+ expectedOutput: validatedExpectedOutput,
65
78
  observabilityImpact: typeof observabilityImpact === "string" ? observabilityImpact : "",
79
+ targetRepositories: validatedTargetRepositories ?? undefined,
66
80
  };
67
81
  });
68
82
  }
@@ -73,6 +87,7 @@ function validateParams(params) {
73
87
  throw new Error("sliceId is required");
74
88
  if (!isNonEmptyString(params?.goal))
75
89
  throw new Error("goal is required");
90
+ const validatedTargetRepositories = validateRepositoryTargetIds("targetRepositories", params.targetRepositories);
76
91
  return {
77
92
  ...params,
78
93
  // Keep optional enrichment fields empty when omitted. The renderer supplies
@@ -81,9 +96,94 @@ function validateParams(params) {
81
96
  proofLevel: params.proofLevel ?? "",
82
97
  integrationClosure: params.integrationClosure ?? "",
83
98
  observabilityImpact: params.observabilityImpact ?? "",
99
+ targetRepositories: validatedTargetRepositories ?? undefined,
84
100
  tasks: validateTasks(params.tasks),
85
101
  };
86
102
  }
103
+ function loadRepositoryRegistry(basePath) {
104
+ const loaded = loadEffectiveGSDPreferences(basePath);
105
+ return createRepositoryRegistryFromPreferences(basePath, loaded?.preferences);
106
+ }
107
+ function validateReferencedRepositories(params, registry) {
108
+ const known = new Set(registry.repositories.map((repo) => repo.id));
109
+ const missing = [];
110
+ const noteMissing = (id) => {
111
+ if (!known.has(id) && !missing.includes(id))
112
+ missing.push(id);
113
+ };
114
+ for (const id of params.targetRepositories ?? [])
115
+ noteMissing(id);
116
+ for (const task of params.tasks) {
117
+ for (const id of task.targetRepositories ?? [])
118
+ noteMissing(id);
119
+ }
120
+ if (missing.length === 0)
121
+ return null;
122
+ return `unknown targetRepositories: ${missing.join(", ")}. Declared repositories: ${Array.from(known).join(", ")}`;
123
+ }
124
+ function resolveAllowedRootsForPathScope(params, registry) {
125
+ const requested = new Set();
126
+ for (const id of params.targetRepositories ?? [])
127
+ requested.add(id);
128
+ for (const task of params.tasks) {
129
+ for (const id of task.targetRepositories ?? [])
130
+ requested.add(id);
131
+ }
132
+ if (requested.size === 0)
133
+ return [registry.projectRoot];
134
+ const roots = Array.from(requested)
135
+ .map((id) => registry.byId.get(id)?.root)
136
+ .filter((root) => typeof root === "string");
137
+ return roots.length > 0 ? roots : [registry.projectRoot];
138
+ }
139
+ function toTaskRows(params) {
140
+ return params.tasks.map((task, index) => ({
141
+ milestone_id: params.milestoneId,
142
+ slice_id: params.sliceId,
143
+ id: task.taskId,
144
+ title: task.title,
145
+ status: "pending",
146
+ one_liner: "",
147
+ narrative: "",
148
+ verification_result: "",
149
+ duration: "",
150
+ completed_at: null,
151
+ blocker_discovered: false,
152
+ deviations: "",
153
+ known_issues: "",
154
+ key_files: [],
155
+ key_decisions: [],
156
+ full_summary_md: "",
157
+ description: task.description,
158
+ estimate: task.estimate,
159
+ files: task.files,
160
+ verify: task.verify,
161
+ inputs: task.inputs,
162
+ expected_output: task.expectedOutput,
163
+ observability_impact: task.observabilityImpact ?? "",
164
+ full_plan_md: task.fullPlanMd ?? "",
165
+ target_repositories: task.targetRepositories ?? params.targetRepositories ?? ["project"],
166
+ sequence: index + 1,
167
+ blocker_source: "",
168
+ escalation_pending: 0,
169
+ escalation_awaiting_review: 0,
170
+ escalation_artifact_path: null,
171
+ escalation_override_applied_at: null,
172
+ }));
173
+ }
174
+ function validateTaskPathsBeforePersist(params, basePath) {
175
+ const taskRows = toTaskRows(params);
176
+ const checks = [
177
+ ...checkFilePathConsistency(taskRows, basePath),
178
+ ...checkTaskOrdering(taskRows, basePath),
179
+ ];
180
+ const blocking = checks.filter((check) => !check.passed && check.blocking);
181
+ if (blocking.length === 0)
182
+ return null;
183
+ return blocking
184
+ .map((check) => `[${check.category}] ${check.target}: ${check.message}`)
185
+ .join("\n");
186
+ }
87
187
  export async function handlePlanSlice(rawParams, basePath) {
88
188
  let params;
89
189
  try {
@@ -92,18 +192,29 @@ export async function handlePlanSlice(rawParams, basePath) {
92
192
  catch (err) {
93
193
  return { error: `validation failed: ${err.message}` };
94
194
  }
195
+ const repositoryRegistry = loadRepositoryRegistry(basePath);
196
+ const repoValidationError = validateReferencedRepositories(params, repositoryRegistry);
197
+ if (repoValidationError) {
198
+ return { error: `validation failed: ${repoValidationError}` };
199
+ }
200
+ const allowedAbsoluteRoots = resolveAllowedRootsForPathScope(params, repositoryRegistry);
95
201
  const pathScopeError = validatePlanningPathScope(basePath, params.tasks.flatMap((task, index) => [
96
202
  { field: `tasks[${index}].files`, values: task.files },
97
203
  { field: `tasks[${index}].inputs`, values: task.inputs },
98
204
  { field: `tasks[${index}].expectedOutput`, values: task.expectedOutput },
99
- ]));
205
+ ]), allowedAbsoluteRoots);
100
206
  if (pathScopeError) {
101
207
  return { error: `validation failed: ${pathScopeError}` };
102
208
  }
209
+ const pathError = validateTaskPathsBeforePersist(params, basePath);
210
+ if (pathError) {
211
+ return { error: `pre-execution validation failed:\n${pathError}` };
212
+ }
103
213
  // ── Guards + DB writes inside a single transaction (prevents TOCTOU) ───
104
214
  // Guards must be inside the transaction so the state they check cannot
105
215
  // change between the read and the write (#2723).
106
216
  let guardError = null;
217
+ let omittedTaskIds = [];
107
218
  try {
108
219
  transaction(() => {
109
220
  const parentMilestone = getMilestone(params.milestoneId);
@@ -124,16 +235,32 @@ export async function handlePlanSlice(rawParams, basePath) {
124
235
  guardError = `cannot re-plan slice ${params.sliceId}: it is already complete — use gsd_slice_reopen first`;
125
236
  return;
126
237
  }
238
+ const newTaskIds = new Set(params.tasks.map((task) => task.taskId));
239
+ const existingTasks = getSliceTasks(params.milestoneId, params.sliceId);
240
+ omittedTaskIds = existingTasks
241
+ .filter((task) => !newTaskIds.has(task.id))
242
+ .map((task) => task.id);
243
+ for (const task of existingTasks) {
244
+ if (!newTaskIds.has(task.id) && isClosedStatus(task.status)) {
245
+ guardError = `cannot remove completed task ${task.id}`;
246
+ return;
247
+ }
248
+ }
127
249
  if (isDeferredStatus(parentSlice.status)) {
128
250
  updateSliceStatus(params.milestoneId, params.sliceId, "pending");
129
251
  }
252
+ setSliceSketchFlag(params.milestoneId, params.sliceId, false);
130
253
  upsertSlicePlanning(params.milestoneId, params.sliceId, {
131
254
  goal: params.goal,
132
255
  successCriteria: params.successCriteria,
133
256
  proofLevel: params.proofLevel,
134
257
  integrationClosure: params.integrationClosure,
135
258
  observabilityImpact: params.observabilityImpact,
259
+ targetRepositories: params.targetRepositories ?? ["project"],
136
260
  });
261
+ for (const taskId of omittedTaskIds) {
262
+ deleteTask(params.milestoneId, params.sliceId, taskId);
263
+ }
137
264
  for (const task of params.tasks) {
138
265
  insertTask({
139
266
  id: task.taskId,
@@ -152,6 +279,7 @@ export async function handlePlanSlice(rawParams, basePath) {
152
279
  expectedOutput: task.expectedOutput,
153
280
  observabilityImpact: task.observabilityImpact ?? "",
154
281
  fullPlanMd: task.fullPlanMd,
282
+ targetRepositories: task.targetRepositories ?? params.targetRepositories ?? ["project"],
155
283
  });
156
284
  }
157
285
  // Seed quality gate rows inside the transaction — all-or-nothing with
@@ -176,6 +304,14 @@ export async function handlePlanSlice(rawParams, basePath) {
176
304
  return { error: guardError };
177
305
  }
178
306
  try {
307
+ const tasksDir = join(gsdProjectionRoot(basePath), "milestones", params.milestoneId, "slices", params.sliceId, "tasks");
308
+ for (const taskId of omittedTaskIds) {
309
+ const taskPlanPath = join(tasksDir, buildTaskFileName(taskId, "PLAN"));
310
+ if (existsSync(taskPlanPath))
311
+ rmSync(taskPlanPath, { force: true });
312
+ const artifactPath = relative(gsdProjectionRoot(basePath), taskPlanPath).replace(/\\/g, "/");
313
+ deleteArtifactByPath(artifactPath);
314
+ }
179
315
  const renderResult = await renderPlanFromDb(basePath, params.milestoneId, params.sliceId);
180
316
  invalidateStateCache();
181
317
  clearParseCache();
@@ -9,7 +9,7 @@
9
9
  * despite passing validation.
10
10
  */
11
11
  import { join } from "node:path";
12
- import { transaction, insertAssessment, getMilestoneSlices, } from "../gsd-db.js";
12
+ import { transaction, insertAssessment, getMilestoneSlices, getMilestone, } from "../gsd-db.js";
13
13
  import { resolveMilestonePath, clearPathCache } from "../paths.js";
14
14
  import { resolveCanonicalMilestoneRoot } from "../worktree-manager.js";
15
15
  import { saveFile, clearParseCache } from "../files.js";
@@ -20,6 +20,27 @@ import { logWarning } from "../workflow-logger.js";
20
20
  import { UokGateRunner } from "../uok/gate-runner.js";
21
21
  import { loadEffectiveGSDPreferences } from "../preferences.js";
22
22
  import { resolveUokFlags } from "../uok/flags.js";
23
+ function isVerificationNotApplicable(value) {
24
+ const v = (value ?? "").toLowerCase().trim().replace(/[.\s]+$/, "");
25
+ if (!v || v === "none")
26
+ return true;
27
+ return /^(?:none(?:[\s._\u2014-]+[\s\S]*)?|n\/?a(?:[\s._\u2014-]+[\s\S]*)?|not[\s._-]+(?:applicable|required|needed|provided)(?:[\s._\u2014-]+[\s\S]*)?|no[\s._-]+operational[\s\S]*)$/i.test(v);
28
+ }
29
+ function getRequiredVerificationClasses(milestoneId) {
30
+ const milestone = getMilestone(milestoneId);
31
+ if (!milestone)
32
+ return [];
33
+ const required = [];
34
+ if (!isVerificationNotApplicable(milestone.verification_contract))
35
+ required.push("Contract");
36
+ if (!isVerificationNotApplicable(milestone.verification_integration))
37
+ required.push("Integration");
38
+ if (!isVerificationNotApplicable(milestone.verification_operational))
39
+ required.push("Operational");
40
+ if (!isVerificationNotApplicable(milestone.verification_uat))
41
+ required.push("UAT");
42
+ return required;
43
+ }
23
44
  function renderValidationMarkdown(params) {
24
45
  let md = `---
25
46
  verdict: ${params.verdict}
@@ -59,6 +80,16 @@ export async function handleValidateMilestone(params, basePath, opts) {
59
80
  if (!isValidMilestoneVerdict(params.verdict)) {
60
81
  return { error: `verdict must be one of: ${VALIDATION_VERDICTS.join(", ")}` };
61
82
  }
83
+ const requiredClasses = getRequiredVerificationClasses(params.milestoneId);
84
+ if (requiredClasses.length > 0) {
85
+ const verificationClasses = params.verificationClasses ?? "";
86
+ const missingClass = requiredClasses.find((className) => !new RegExp(`\\b${className}\\b`, "i").test(verificationClasses));
87
+ if (missingClass) {
88
+ return {
89
+ error: `verificationClasses must include canonical row "${missingClass}" because this milestone planned ${missingClass.toLowerCase()} verification`,
90
+ };
91
+ }
92
+ }
62
93
  // ── Resolve paths and render markdown ────────────────────────────────
63
94
  // #4761: route through the canonical-root resolver so that when a live
64
95
  // worktree exists for this milestone, validation reads/writes the