gsd-pi 2.82.0-dev.ed17d078d → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (567) hide show
  1. package/README.md +6 -5
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/GSD-WORKFLOW.md +10 -1
  4. package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
  5. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +1 -1
  6. package/dist/resources/extensions/cmux/index.js +5 -0
  7. package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
  8. package/dist/resources/extensions/gsd/auto/loop.js +19 -6
  9. package/dist/resources/extensions/gsd/auto/orchestrator.js +11 -0
  10. package/dist/resources/extensions/gsd/auto/phases.js +81 -31
  11. package/dist/resources/extensions/gsd/auto/session.js +4 -0
  12. package/dist/resources/extensions/gsd/auto/workflow-kernel.js +3 -0
  13. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  14. package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
  15. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +1 -0
  16. package/dist/resources/extensions/gsd/auto-dispatch.js +20 -19
  17. package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
  18. package/dist/resources/extensions/gsd/auto-post-unit.js +246 -133
  19. package/dist/resources/extensions/gsd/auto-prompts.js +2 -2
  20. package/dist/resources/extensions/gsd/auto-recovery.js +71 -14
  21. package/dist/resources/extensions/gsd/auto-start.js +87 -14
  22. package/dist/resources/extensions/gsd/auto-verification.js +45 -26
  23. package/dist/resources/extensions/gsd/auto-worktree.js +176 -10
  24. package/dist/resources/extensions/gsd/auto.js +57 -33
  25. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +31 -7
  26. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +10 -9
  27. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +4 -2
  28. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
  29. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +17 -3
  30. package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
  31. package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
  32. package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -0
  33. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  34. package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
  35. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +7 -2
  36. package/dist/resources/extensions/gsd/commands-verdict.js +139 -0
  37. package/dist/resources/extensions/gsd/crash-recovery.js +43 -5
  38. package/dist/resources/extensions/gsd/db/milestone-leases.js +24 -0
  39. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  40. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -2
  41. package/dist/resources/extensions/gsd/doctor-git-checks.js +46 -1
  42. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  43. package/dist/resources/extensions/gsd/doctor.js +2 -28
  44. package/dist/resources/extensions/gsd/export-html.js +27 -425
  45. package/dist/resources/extensions/gsd/forensics.js +3 -3
  46. package/dist/resources/extensions/gsd/git-service.js +45 -3
  47. package/dist/resources/extensions/gsd/gsd-db.js +21 -6
  48. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -3
  49. package/dist/resources/extensions/gsd/guided-flow.js +101 -116
  50. package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
  51. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -8
  52. package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
  53. package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
  54. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  55. package/dist/resources/extensions/gsd/native-git-bridge.js +48 -12
  56. package/dist/resources/extensions/gsd/paths.js +4 -0
  57. package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
  58. package/dist/resources/extensions/gsd/post-execution-checks.js +73 -2
  59. package/dist/resources/extensions/gsd/pre-execution-checks.js +28 -1
  60. package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
  61. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  62. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  63. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  64. package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
  65. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  66. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  67. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  68. package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
  69. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  70. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  71. package/dist/resources/extensions/gsd/queue-reorder-ui.js +30 -13
  72. package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
  73. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  74. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
  75. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
  76. package/dist/resources/extensions/gsd/state.js +3 -3
  77. package/dist/resources/extensions/gsd/status-guards.js +11 -0
  78. package/dist/resources/extensions/gsd/templates/plan.md +9 -5
  79. package/dist/resources/extensions/gsd/templates/task-plan.md +10 -2
  80. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
  81. package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
  82. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  83. package/dist/resources/extensions/gsd/tools/plan-slice.js +87 -14
  84. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
  85. package/dist/resources/extensions/gsd/unit-context-manifest.js +32 -10
  86. package/dist/resources/extensions/gsd/validation.js +23 -1
  87. package/dist/resources/extensions/gsd/verification-gate.js +68 -7
  88. package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
  89. package/dist/resources/extensions/gsd/workflow-mcp.js +17 -1
  90. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  91. package/dist/resources/extensions/gsd/worktree-lifecycle.js +54 -10
  92. package/dist/resources/extensions/gsd/worktree-manager.js +1 -1
  93. package/dist/resources/extensions/shared/html-shell.js +388 -0
  94. package/dist/resources/extensions/subagent/index.js +448 -78
  95. package/dist/resources/extensions/subagent/launch.js +77 -0
  96. package/dist/resources/extensions/subagent/run-store.js +148 -0
  97. package/dist/resources/extensions/ttsr/ttsr-manager.js +3 -1
  98. package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
  99. package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
  100. package/dist/resources/extensions/visual-brief/index.js +5 -0
  101. package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
  102. package/dist/resources/extensions/visual-brief/prompts.js +140 -0
  103. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  104. package/dist/web/standalone/.next/BUILD_ID +1 -1
  105. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  106. package/dist/web/standalone/.next/build-manifest.json +4 -4
  107. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  108. package/dist/web/standalone/.next/react-loadable-manifest.json +5 -5
  109. package/dist/web/standalone/.next/required-server-files.json +3 -3
  110. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  111. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  121. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  122. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  125. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  126. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  128. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  131. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  138. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  150. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  170. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  180. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  186. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  202. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
  206. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/app/index.html +1 -1
  216. package/dist/web/standalone/.next/server/app/index.rsc +5 -8
  217. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  218. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -8
  219. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  220. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  221. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  222. package/dist/web/standalone/.next/server/app/page.js +2 -2
  223. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  224. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  225. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  226. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  227. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  228. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  229. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  230. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  231. package/dist/web/standalone/.next/server/middleware.js +2 -2
  232. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  233. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  234. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  235. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  236. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  237. package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
  238. package/dist/web/standalone/.next/static/chunks/8359.65b24fac92188a6b.js +10 -0
  239. package/dist/web/standalone/.next/static/chunks/9441.ff70bb53f6835771.js +1 -0
  240. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
  241. package/dist/web/standalone/.next/static/chunks/app/layout-b23b3f6858dc6dc8.js +1 -0
  242. package/dist/web/standalone/.next/static/chunks/app/page-200592a7f3baf579.js +1 -0
  243. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
  244. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
  245. package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-855d616060cb6e59.js} +1 -1
  246. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  247. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  248. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  249. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  250. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  251. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  252. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  253. package/dist/web/standalone/server.js +1 -1
  254. package/package.json +4 -4
  255. package/packages/contracts/dist/rpc.test.js +7 -0
  256. package/packages/contracts/dist/rpc.test.js.map +1 -1
  257. package/packages/contracts/dist/workflow.d.ts +21 -0
  258. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  259. package/packages/contracts/dist/workflow.js +24 -0
  260. package/packages/contracts/dist/workflow.js.map +1 -1
  261. package/packages/contracts/src/rpc.test.ts +8 -0
  262. package/packages/contracts/src/workflow.ts +24 -0
  263. package/packages/daemon/package.json +2 -2
  264. package/packages/mcp-server/README.md +13 -4
  265. package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
  266. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  267. package/packages/mcp-server/dist/workflow-tools.js +80 -0
  268. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  269. package/packages/mcp-server/package.json +2 -2
  270. package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
  271. package/packages/mcp-server/src/workflow-tools.ts +168 -0
  272. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  273. package/packages/native/package.json +1 -1
  274. package/packages/native/tsconfig.json +2 -1
  275. package/packages/native/tsconfig.tsbuildinfo +1 -1
  276. package/packages/pi-agent-core/package.json +1 -1
  277. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  278. package/packages/pi-ai/dist/providers/google-gemini-cli.js +5 -0
  279. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  280. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts +2 -0
  281. package/packages/pi-ai/dist/providers/google-gemini-cli.test.d.ts.map +1 -0
  282. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js +41 -0
  283. package/packages/pi-ai/dist/providers/google-gemini-cli.test.js.map +1 -0
  284. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  285. package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
  286. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  287. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
  288. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
  289. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
  290. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
  291. package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
  292. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  293. package/packages/pi-ai/dist/providers/simple-options.js +5 -6
  294. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  295. package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
  296. package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
  297. package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
  298. package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
  299. package/packages/pi-ai/package.json +1 -1
  300. package/packages/pi-ai/src/providers/google-gemini-cli.test.ts +49 -0
  301. package/packages/pi-ai/src/providers/google-gemini-cli.ts +7 -0
  302. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
  303. package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
  304. package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
  305. package/packages/pi-ai/src/providers/simple-options.ts +5 -6
  306. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  307. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
  308. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
  309. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
  310. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
  311. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
  312. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  313. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +44 -3
  314. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  315. package/packages/pi-coding-agent/dist/core/sdk.js +1 -1
  316. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  317. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  318. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
  319. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  321. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +71 -97
  322. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  323. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js +25 -1
  324. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-ordering.test.js.map +1 -1
  325. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  326. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  327. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +24 -10
  328. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  329. package/packages/pi-coding-agent/package.json +1 -1
  330. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  331. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  332. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +53 -3
  333. package/packages/pi-coding-agent/src/core/sdk.ts +1 -1
  334. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
  335. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +75 -102
  336. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-ordering.test.ts +30 -1
  337. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +29 -10
  338. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  339. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts +2 -0
  340. package/packages/pi-tui/dist/__tests__/terminal.test.d.ts.map +1 -0
  341. package/packages/pi-tui/dist/__tests__/terminal.test.js +103 -0
  342. package/packages/pi-tui/dist/__tests__/terminal.test.js.map +1 -0
  343. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  344. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  345. package/packages/pi-tui/dist/terminal.js +12 -0
  346. package/packages/pi-tui/dist/terminal.js.map +1 -1
  347. package/packages/pi-tui/package.json +1 -1
  348. package/packages/pi-tui/src/__tests__/terminal.test.ts +121 -0
  349. package/packages/pi-tui/src/terminal.ts +11 -0
  350. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  351. package/packages/rpc-client/package.json +1 -1
  352. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  353. package/pkg/package.json +1 -1
  354. package/src/resources/GSD-WORKFLOW.md +10 -1
  355. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  356. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +1 -1
  357. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  358. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +9 -0
  359. package/src/resources/extensions/cmux/index.ts +6 -0
  360. package/src/resources/extensions/gsd/auto/contracts.ts +14 -6
  361. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  362. package/src/resources/extensions/gsd/auto/loop.ts +22 -6
  363. package/src/resources/extensions/gsd/auto/orchestrator.ts +11 -0
  364. package/src/resources/extensions/gsd/auto/phases.ts +90 -38
  365. package/src/resources/extensions/gsd/auto/session.ts +4 -0
  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-dashboard.ts +72 -1
  369. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +1 -0
  370. package/src/resources/extensions/gsd/auto-dispatch.ts +21 -19
  371. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  372. package/src/resources/extensions/gsd/auto-post-unit.ts +279 -144
  373. package/src/resources/extensions/gsd/auto-prompts.ts +2 -2
  374. package/src/resources/extensions/gsd/auto-recovery.ts +74 -11
  375. package/src/resources/extensions/gsd/auto-start.ts +94 -12
  376. package/src/resources/extensions/gsd/auto-verification.ts +58 -36
  377. package/src/resources/extensions/gsd/auto-worktree.ts +193 -10
  378. package/src/resources/extensions/gsd/auto.ts +59 -31
  379. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +42 -7
  380. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +10 -9
  381. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +4 -2
  382. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
  383. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +20 -4
  384. package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
  385. package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
  386. package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -0
  387. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  388. package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
  389. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +8 -3
  390. package/src/resources/extensions/gsd/commands-verdict.ts +202 -0
  391. package/src/resources/extensions/gsd/crash-recovery.ts +44 -4
  392. package/src/resources/extensions/gsd/db/milestone-leases.ts +26 -0
  393. package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
  394. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -2
  395. package/src/resources/extensions/gsd/doctor-git-checks.ts +45 -1
  396. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  397. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  398. package/src/resources/extensions/gsd/doctor.ts +2 -27
  399. package/src/resources/extensions/gsd/export-html.ts +27 -427
  400. package/src/resources/extensions/gsd/forensics.ts +3 -3
  401. package/src/resources/extensions/gsd/git-service.ts +51 -4
  402. package/src/resources/extensions/gsd/gsd-db.ts +21 -6
  403. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -3
  404. package/src/resources/extensions/gsd/guided-flow.ts +134 -133
  405. package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
  406. package/src/resources/extensions/gsd/markdown-renderer.ts +10 -8
  407. package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
  408. package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
  409. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  410. package/src/resources/extensions/gsd/native-git-bridge.ts +54 -12
  411. package/src/resources/extensions/gsd/paths.ts +5 -0
  412. package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
  413. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -2
  414. package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -1
  415. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  416. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  417. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  418. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  419. package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
  420. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  421. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  422. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  423. package/src/resources/extensions/gsd/prompts/queue.md +4 -4
  424. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  425. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  426. package/src/resources/extensions/gsd/queue-reorder-ui.ts +31 -13
  427. package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
  428. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  429. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
  430. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
  431. package/src/resources/extensions/gsd/state.ts +3 -3
  432. package/src/resources/extensions/gsd/status-guards.ts +13 -0
  433. package/src/resources/extensions/gsd/templates/plan.md +9 -5
  434. package/src/resources/extensions/gsd/templates/task-plan.md +10 -2
  435. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
  436. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  437. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +56 -0
  438. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +80 -1
  439. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +151 -12
  440. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
  441. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +18 -6
  442. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +91 -6
  443. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  444. package/src/resources/extensions/gsd/tests/auto-stop-notification.test.ts +20 -0
  445. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  446. package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
  447. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +87 -0
  448. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
  449. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +11 -2
  450. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
  451. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +378 -0
  452. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
  453. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -9
  454. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  455. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +86 -2
  456. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
  457. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
  458. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +59 -2
  459. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +66 -0
  460. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
  461. package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +65 -0
  462. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +38 -0
  463. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  464. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +11 -0
  465. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +5 -2
  466. package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
  467. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
  468. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
  469. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  470. package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
  471. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
  472. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  473. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  474. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  475. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  476. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +112 -1
  477. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  478. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +46 -0
  479. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +179 -0
  480. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
  481. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
  482. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +63 -2
  483. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
  484. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
  485. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
  486. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +2 -1
  487. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
  488. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  489. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +251 -2
  490. package/src/resources/extensions/gsd/tests/plan-task.test.ts +17 -0
  491. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  492. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +86 -0
  493. package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
  494. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +84 -0
  495. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +53 -0
  496. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +59 -0
  497. package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
  498. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +37 -1
  499. package/src/resources/extensions/gsd/tests/quality-gates.test.ts +6 -0
  500. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +54 -0
  501. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +89 -2
  502. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +2 -3
  503. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
  504. package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
  505. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +53 -2
  506. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
  507. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
  508. package/src/resources/extensions/gsd/tests/status-guards.test.ts +13 -1
  509. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  510. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  511. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +103 -7
  512. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +29 -2
  513. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +110 -1
  514. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
  515. package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +7 -0
  516. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +19 -1
  517. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
  518. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +1 -1
  519. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
  520. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
  521. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +25 -0
  522. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +54 -0
  523. package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
  524. package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
  525. package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
  526. package/src/resources/extensions/gsd/tools/plan-slice.ts +97 -12
  527. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
  528. package/src/resources/extensions/gsd/types.ts +1 -1
  529. package/src/resources/extensions/gsd/unit-context-manifest.ts +47 -11
  530. package/src/resources/extensions/gsd/validation.ts +23 -1
  531. package/src/resources/extensions/gsd/verification-gate.ts +78 -6
  532. package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
  533. package/src/resources/extensions/gsd/workflow-mcp.ts +18 -1
  534. package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
  535. package/src/resources/extensions/gsd/worktree-lifecycle.ts +61 -10
  536. package/src/resources/extensions/gsd/worktree-manager.ts +1 -1
  537. package/src/resources/extensions/shared/html-shell.ts +412 -0
  538. package/src/resources/extensions/subagent/index.ts +567 -103
  539. package/src/resources/extensions/subagent/launch.ts +131 -0
  540. package/src/resources/extensions/subagent/run-store.ts +218 -0
  541. package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
  542. package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
  543. package/src/resources/extensions/ttsr/ttsr-manager.ts +5 -1
  544. package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
  545. package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
  546. package/src/resources/extensions/visual-brief/index.ts +8 -0
  547. package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
  548. package/src/resources/extensions/visual-brief/prompts.ts +183 -0
  549. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
  550. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  551. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  552. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +0 -10
  553. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +0 -1
  554. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
  555. package/dist/web/standalone/.next/static/chunks/app/page-752f1e2ebdaa3e45.js +0 -1
  556. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
  557. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
  558. package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
  559. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  560. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  561. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  562. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  563. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  564. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  565. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  566. /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → qoMxZh-xuwuvpFW0x0k01}/_buildManifest.js +0 -0
  567. /package/dist/web/standalone/.next/static/{YEvjuT-fsFfYQhDSWtueS → qoMxZh-xuwuvpFW0x0k01}/_ssgManifest.js +0 -0
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { test } from "node:test";
9
9
  import assert from "node:assert/strict";
10
- import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
10
+ import { existsSync, mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
11
11
  import { join } from "node:path";
12
12
  import { tmpdir } from "node:os";
13
13
 
@@ -48,6 +48,60 @@ test("parkMilestone updates DB status to 'parked' (#2694)", () => {
48
48
  }
49
49
  });
50
50
 
51
+ test("parkMilestone ignores blocked SUMMARY.md when DB milestone is active (#5828)", () => {
52
+ const base = createBase();
53
+ try {
54
+ openDatabase(":memory:");
55
+ insertMilestone({ id: "M001", title: "Test", status: "active" });
56
+ writeFileSync(
57
+ join(base, ".gsd", "milestones", "M001", "M001-SUMMARY.md"),
58
+ [
59
+ "---",
60
+ "status: closeout_blocked",
61
+ "---",
62
+ "",
63
+ "# M001 Summary",
64
+ "",
65
+ "Completion was not persisted.",
66
+ ].join("\n"),
67
+ "utf-8",
68
+ );
69
+
70
+ const parked = parkMilestone(base, "M001", "test");
71
+
72
+ assert.ok(parked, "active DB row should allow parking despite a blocked SUMMARY.md");
73
+ assert.ok(
74
+ existsSync(join(base, ".gsd", "milestones", "M001", "M001-PARKED.md")),
75
+ "PARKED.md should be written",
76
+ );
77
+ assert.equal(getMilestone("M001")!.status, "parked", "DB status should be parked");
78
+ } finally {
79
+ closeDatabase();
80
+ rmSync(base, { recursive: true, force: true });
81
+ }
82
+ });
83
+
84
+ test("parkMilestone refuses DB-complete milestones (#5828)", () => {
85
+ const base = createBase();
86
+ try {
87
+ openDatabase(":memory:");
88
+ insertMilestone({ id: "M001", title: "Test", status: "complete" });
89
+
90
+ const parked = parkMilestone(base, "M001", "test");
91
+
92
+ assert.equal(parked, false, "complete DB row should not be parkable");
93
+ assert.equal(
94
+ existsSync(join(base, ".gsd", "milestones", "M001", "M001-PARKED.md")),
95
+ false,
96
+ "PARKED.md should not be written",
97
+ );
98
+ assert.equal(getMilestone("M001")!.status, "complete", "DB status should remain complete");
99
+ } finally {
100
+ closeDatabase();
101
+ rmSync(base, { recursive: true, force: true });
102
+ }
103
+ });
104
+
51
105
  test("unparkMilestone updates DB status to 'active' (#2694)", () => {
52
106
  const base = createBase();
53
107
  try {
@@ -11,6 +11,7 @@ import {
11
11
  clearPendingAutoStart,
12
12
  _getPendingAutoStart,
13
13
  } from "../guided-flow.ts";
14
+ import type { PendingAutoStartInput } from "../pending-auto-start.ts";
14
15
 
15
16
  // ─── Helpers ─────────────────────────────────────────────────────────────────
16
17
 
@@ -20,6 +21,15 @@ function makeProjectDir(): string {
20
21
  return dir;
21
22
  }
22
23
 
24
+ function pendingInput(basePath: string, milestoneId: string) {
25
+ return {
26
+ basePath,
27
+ milestoneId,
28
+ ctx: { ui: { notify: () => undefined } } as any,
29
+ pi: { sendMessage: () => undefined } as any,
30
+ };
31
+ }
32
+
23
33
  // ─── Tests ───────────────────────────────────────────────────────────────────
24
34
 
25
35
  describe("pendingAutoStart scope pinning (C1)", () => {
@@ -38,7 +48,7 @@ describe("pendingAutoStart scope pinning (C1)", () => {
38
48
  });
39
49
 
40
50
  test("setPendingAutoStart stores a scope whose paths derive from the basePath at reservation time", () => {
41
- setPendingAutoStart(base, { basePath: base, milestoneId: "M001" });
51
+ setPendingAutoStart(base, pendingInput(base, "M001"));
42
52
 
43
53
  const entry = _getPendingAutoStart(base);
44
54
  assert.ok(entry, "entry should exist");
@@ -54,8 +64,22 @@ describe("pendingAutoStart scope pinning (C1)", () => {
54
64
  assert.equal(entry.scope.stateFile(), expectedState);
55
65
  });
56
66
 
67
+ test("setPendingAutoStart rejects entries without ctx and pi before storing them", () => {
68
+ assert.throws(
69
+ () =>
70
+ setPendingAutoStart(base, {
71
+ basePath: base,
72
+ milestoneId: "M001",
73
+ } as PendingAutoStartInput),
74
+ /requires ctx and pi/,
75
+ "pending entries must include the handles later used by auto-start recovery",
76
+ );
77
+
78
+ assert.equal(_getPendingAutoStart(base), null);
79
+ });
80
+
57
81
  test("scope paths are unaffected by process.chdir after reservation", (t) => {
58
- setPendingAutoStart(base, { basePath: base, milestoneId: "M002" });
82
+ setPendingAutoStart(base, pendingInput(base, "M002"));
59
83
 
60
84
  const entry = _getPendingAutoStart(base);
61
85
  assert.ok(entry, "entry should exist");
@@ -82,7 +106,7 @@ describe("pendingAutoStart scope pinning (C1)", () => {
82
106
 
83
107
  test("scope identityKey matches the realpath of the original basePath even with trailing slash", () => {
84
108
  const baseWithSlash = base + "/";
85
- setPendingAutoStart(base, { basePath: baseWithSlash, milestoneId: "M003" });
109
+ setPendingAutoStart(base, pendingInput(baseWithSlash, "M003"));
86
110
 
87
111
  const entry = _getPendingAutoStart(base);
88
112
  assert.ok(entry, "entry should exist");
@@ -96,7 +120,7 @@ describe("pendingAutoStart scope pinning (C1)", () => {
96
120
  });
97
121
 
98
122
  test("clearPendingAutoStart removes the entry", () => {
99
- setPendingAutoStart(base, { basePath: base, milestoneId: "M001" });
123
+ setPendingAutoStart(base, pendingInput(base, "M001"));
100
124
 
101
125
  const before = _getPendingAutoStart(base);
102
126
  assert.ok(before, "entry should exist before clear");
@@ -108,7 +132,7 @@ describe("pendingAutoStart scope pinning (C1)", () => {
108
132
  });
109
133
 
110
134
  test("_getPendingAutoStart with no basePath argument returns the sole entry", () => {
111
- setPendingAutoStart(base, { basePath: base, milestoneId: "M001" });
135
+ setPendingAutoStart(base, pendingInput(base, "M001"));
112
136
 
113
137
  // No argument — should return the sole entry
114
138
  const entry = _getPendingAutoStart();
@@ -243,7 +243,8 @@ test("#4781 phase 2: validate-milestone rule writes pass-through VALIDATION for
243
243
  const content = readFileSync(validationPath, "utf-8");
244
244
  assert.match(content, /verdict: pass/);
245
245
  assert.match(content, /skip_validation: true/);
246
- assert.match(content, /trivial-scope pipeline variant \(#4781\)/);
246
+ assert.match(content, /trivial-scope pipeline variant/);
247
+ assert.doesNotMatch(content, /#[0-9]{3,}/, "validation output must not include tracker-style refs");
247
248
  });
248
249
 
249
250
  test("#4781 phase 2: validate-milestone skip path does not persist gates without a real slice", async (t) => {
@@ -116,6 +116,32 @@ test('handlePlanMilestone rejects invalid payloads', async () => {
116
116
  }
117
117
  });
118
118
 
119
+ test('handlePlanMilestone rejects delimiter characters in milestone and slice titles', async () => {
120
+ const base = makeTmpBase();
121
+ const dbPath = join(base, '.gsd', 'gsd.db');
122
+ openDatabase(dbPath);
123
+
124
+ try {
125
+ const milestoneResult = await handlePlanMilestone({ ...validParams(), title: 'Client/Server split' }, base);
126
+ assert.ok('error' in milestoneResult);
127
+ assert.match(milestoneResult.error, /validation failed: title is invalid: .*forward slash/);
128
+ assert.equal(getMilestone('M001'), null, 'invalid milestone title must not persist');
129
+
130
+ const sliceResult = await handlePlanMilestone({
131
+ ...validParams(),
132
+ slices: [
133
+ validParams().slices[0],
134
+ { ...validParams().slices[1], title: 'Client/Server migration' },
135
+ ],
136
+ }, base);
137
+ assert.ok('error' in sliceResult);
138
+ assert.match(sliceResult.error, /validation failed: slices\[1\]\.title is invalid: .*forward slash/);
139
+ assert.equal(getMilestoneSlices('M001').length, 0, 'invalid slice title must not persist partial roadmap state');
140
+ } finally {
141
+ cleanup(base);
142
+ }
143
+ });
144
+
119
145
  test('handlePlanMilestone surfaces render failures and does not clear parse-visible state on failure', async () => {
120
146
  const base = makeTmpBase();
121
147
  const dbPath = join(base, '.gsd', 'gsd.db');
@@ -65,7 +65,9 @@ test("plan-slice prompt: DB-backed tool names survive template substitution", ()
65
65
  const result = loadPrompt("plan-slice", { ...BASE_VARS, commitInstruction: "Do not commit." });
66
66
  assert.ok(result.includes("gsd_plan_slice"), "gsd_plan_slice should appear in rendered prompt");
67
67
  assert.ok(result.includes("gsd_plan_task"), "gsd_plan_task should appear in rendered prompt");
68
+ assert.ok(result.includes("gsd_decision_save"), "structural decisions should use DB-backed decision tool");
68
69
  assert.ok(result.includes("canonical write path"), "canonical write path language should survive substitution");
70
+ assert.doesNotMatch(result, /append them to `.gsd\/DECISIONS\.md`/);
69
71
  });
70
72
 
71
73
  test("plan-slice prompt: compact planning gates survive template substitution", () => {
@@ -2,11 +2,11 @@
2
2
 
3
3
  import test from 'node:test';
4
4
  import assert from 'node:assert/strict';
5
- import { mkdtempSync, mkdirSync, rmSync, readFileSync, existsSync, writeFileSync } from 'node:fs';
5
+ import { mkdtempSync, mkdirSync, rmSync, readFileSync, existsSync, writeFileSync, realpathSync } from 'node:fs';
6
6
  import { join } from 'node:path';
7
7
  import { tmpdir } from 'node:os';
8
8
 
9
- import { openDatabase, closeDatabase, insertMilestone, insertSlice, getSlice, getSliceTasks, getTask } from '../gsd-db.ts';
9
+ import { openDatabase, closeDatabase, insertMilestone, insertSlice, getSlice, getSliceTasks, getTask, getGateResults, updateTaskStatus } from '../gsd-db.ts';
10
10
  import { handlePlanSlice } from '../tools/plan-slice.ts';
11
11
  import { parsePlan } from '../parsers-legacy.ts';
12
12
  import { parseTaskPlanFile } from '../files.ts';
@@ -15,6 +15,10 @@ import { deriveState, invalidateStateCache } from '../state.ts';
15
15
  function makeTmpBase(): string {
16
16
  const base = mkdtempSync(join(tmpdir(), 'gsd-plan-slice-'));
17
17
  mkdirSync(join(base, '.gsd', 'milestones', 'M001', 'slices', 'S02', 'tasks'), { recursive: true });
18
+ mkdirSync(join(base, 'src', 'resources', 'extensions', 'gsd', 'tools'), { recursive: true });
19
+ writeFileSync(join(base, 'src', 'resources', 'extensions', 'gsd', 'tools', 'plan-milestone.ts'), '// fixture\n', 'utf-8');
20
+ writeFileSync(join(base, 'src', 'resources', 'extensions', 'gsd', 'tools', 'plan-task.ts'), '// fixture\n', 'utf-8');
21
+ writeFileSync(join(base, 'stale-input.py'), '# fixture\n', 'utf-8');
18
22
  return base;
19
23
  }
20
24
 
@@ -101,6 +105,31 @@ test('handlePlanSlice writes slice/task planning state and renders plan artifact
101
105
  }
102
106
  });
103
107
 
108
+ test('handlePlanSlice renders plan artifacts under worktree-local .gsd while using project DB', async () => {
109
+ const base = makeTmpBase();
110
+ const worktree = join(base, '.gsd', 'worktrees', 'M001');
111
+ mkdirSync(join(worktree, '.gsd'), { recursive: true });
112
+ mkdirSync(join(worktree, 'src', 'resources', 'extensions', 'gsd', 'tools'), { recursive: true });
113
+ writeFileSync(join(worktree, 'src', 'resources', 'extensions', 'gsd', 'tools', 'plan-milestone.ts'), '// fixture\n', 'utf-8');
114
+ writeFileSync(join(worktree, 'src', 'resources', 'extensions', 'gsd', 'tools', 'plan-task.ts'), '// fixture\n', 'utf-8');
115
+ openDatabase(join(base, '.gsd', 'gsd.db'));
116
+
117
+ try {
118
+ seedParentSlice();
119
+
120
+ const result = await handlePlanSlice(validParams(), worktree);
121
+ assert.ok(!('error' in result), `unexpected error: ${'error' in result ? result.error : ''}`);
122
+
123
+ const worktreePlan = join(worktree, '.gsd', 'milestones', 'M001', 'slices', 'S02', 'S02-PLAN.md');
124
+ const projectPlan = join(base, '.gsd', 'milestones', 'M001', 'slices', 'S02', 'S02-PLAN.md');
125
+ assert.ok(existsSync(worktreePlan), 'slice plan should be rendered to worktree-local .gsd');
126
+ assert.ok(!existsSync(projectPlan), 'slice plan should not be rendered to project .gsd');
127
+ assert.equal(result.planPath, realpathSync(worktreePlan));
128
+ } finally {
129
+ cleanup(base);
130
+ }
131
+ });
132
+
104
133
  test('handlePlanSlice advances DB-derived state out of planning immediately', async () => {
105
134
  const base = makeTmpBase();
106
135
  openDatabase(join(base, '.gsd', 'gsd.db'));
@@ -125,6 +154,31 @@ test('handlePlanSlice advances DB-derived state out of planning immediately', as
125
154
  }
126
155
  });
127
156
 
157
+ test('handlePlanSlice clears sketch flag so DB-derived state leaves refining', async () => {
158
+ const base = makeTmpBase();
159
+ openDatabase(join(base, '.gsd', 'gsd.db'));
160
+
161
+ try {
162
+ insertMilestone({ id: 'M001', title: 'Milestone', status: 'active' });
163
+ insertSlice({ id: 'S02', milestoneId: 'M001', title: 'Planning slice', status: 'pending', demo: 'Rendered plans exist.', isSketch: true });
164
+
165
+ invalidateStateCache();
166
+ const before = await deriveState(base);
167
+ assert.equal(before.phase, 'refining');
168
+
169
+ const result = await handlePlanSlice(validParams(), base);
170
+ assert.ok(!('error' in result), `unexpected error: ${'error' in result ? result.error : ''}`);
171
+ assert.equal(getSlice('M001', 'S02')?.is_sketch, 0, 'planned slice must no longer be treated as a sketch');
172
+
173
+ invalidateStateCache();
174
+ const after = await deriveState(base);
175
+ assert.notEqual(after.phase, 'refining');
176
+ assert.equal(after.progress?.tasks?.total, 2);
177
+ } finally {
178
+ cleanup(base);
179
+ }
180
+ });
181
+
128
182
  test('handlePlanSlice leaves omitted enrichment fields empty instead of rendering placeholders', async () => {
129
183
  const base = makeTmpBase();
130
184
  openDatabase(join(base, '.gsd', 'gsd.db'));
@@ -172,6 +226,28 @@ test('handlePlanSlice rejects invalid payloads', async () => {
172
226
  }
173
227
  });
174
228
 
229
+ test('handlePlanSlice explains string task IO fields must be arrays', async () => {
230
+ const base = makeTmpBase();
231
+ openDatabase(join(base, '.gsd', 'gsd.db'));
232
+
233
+ try {
234
+ seedParentSlice();
235
+ const result = await handlePlanSlice({
236
+ ...validParams(),
237
+ tasks: [
238
+ {
239
+ ...validParams().tasks[0],
240
+ inputs: 'src/index.ts' as unknown as string[],
241
+ },
242
+ ],
243
+ }, base);
244
+ assert.ok('error' in result);
245
+ assert.match(result.error, /validation failed: tasks\[0\]\.inputs must be an array of strings, not string/);
246
+ } finally {
247
+ cleanup(base);
248
+ }
249
+ });
250
+
175
251
  test('handlePlanSlice rejects absolute task IO paths outside the active worktree', async () => {
176
252
  const base = makeTmpBase();
177
253
  openDatabase(join(base, '.gsd', 'gsd.db'));
@@ -198,6 +274,63 @@ test('handlePlanSlice rejects absolute task IO paths outside the active worktree
198
274
  }
199
275
  });
200
276
 
277
+ test('handlePlanSlice rejects missing task input paths before persisting tasks', async () => {
278
+ const base = makeTmpBase();
279
+ openDatabase(join(base, '.gsd', 'gsd.db'));
280
+
281
+ try {
282
+ seedParentSlice();
283
+ const result = await handlePlanSlice({
284
+ ...validParams(),
285
+ tasks: [
286
+ {
287
+ ...validParams().tasks[0],
288
+ inputs: ['fixtures/missing-source.json'],
289
+ },
290
+ ],
291
+ }, base);
292
+
293
+ assert.ok('error' in result);
294
+ assert.match(result.error, /pre-execution validation failed:/);
295
+ assert.match(result.error, /fixtures\/missing-source\.json/);
296
+ assert.equal(getSliceTasks('M001', 'S02').length, 0, 'invalid planning IO must not persist tasks');
297
+ } finally {
298
+ cleanup(base);
299
+ }
300
+ });
301
+
302
+ test('handlePlanSlice rejects task input paths created by later tasks before persisting tasks', async () => {
303
+ const base = makeTmpBase();
304
+ openDatabase(join(base, '.gsd', 'gsd.db'));
305
+
306
+ try {
307
+ seedParentSlice();
308
+ const params = validParams();
309
+ const result = await handlePlanSlice({
310
+ ...params,
311
+ tasks: [
312
+ {
313
+ ...params.tasks[0],
314
+ inputs: ['generated/report.json'],
315
+ expectedOutput: ['generated/summary.json'],
316
+ },
317
+ {
318
+ ...params.tasks[1],
319
+ inputs: [],
320
+ expectedOutput: ['generated/report.json'],
321
+ },
322
+ ],
323
+ }, base);
324
+
325
+ assert.ok('error' in result);
326
+ assert.match(result.error, /pre-execution validation failed:/);
327
+ assert.match(result.error, /sequence violation/);
328
+ assert.equal(getSliceTasks('M001', 'S02').length, 0, 'invalid task ordering must not persist tasks');
329
+ } finally {
330
+ cleanup(base);
331
+ }
332
+ });
333
+
201
334
  test('handlePlanSlice accepts absolute task IO paths inside the active worktree', async () => {
202
335
  const base = makeTmpBase();
203
336
  openDatabase(join(base, '.gsd', 'gsd.db'));
@@ -304,3 +437,119 @@ test('handlePlanSlice reruns idempotently and refreshes parse-visible state', as
304
437
  cleanup(base);
305
438
  }
306
439
  });
440
+
441
+ test('handlePlanSlice removes omitted pending tasks when replanning a smaller task set', async () => {
442
+ const base = makeTmpBase();
443
+ openDatabase(join(base, '.gsd', 'gsd.db'));
444
+
445
+ try {
446
+ seedParentSlice();
447
+ const fourTaskPlan = {
448
+ ...validParams(),
449
+ tasks: [
450
+ ...validParams().tasks,
451
+ { ...validParams().tasks[0], taskId: 'T03', title: 'Third task' },
452
+ { ...validParams().tasks[0], taskId: 'T04', title: 'Stale task', inputs: ['stale-input.py'] },
453
+ ],
454
+ };
455
+
456
+ const first = await handlePlanSlice(fourTaskPlan, base);
457
+ assert.ok(!('error' in first), `unexpected error: ${'error' in first ? first.error : ''}`);
458
+ const staleTaskPlanPath = join(base, '.gsd', 'milestones', 'M001', 'slices', 'S02', 'tasks', 'T04-PLAN.md');
459
+ assert.ok(existsSync(staleTaskPlanPath), 'initial plan should render T04');
460
+
461
+ const second = await handlePlanSlice({
462
+ ...validParams(),
463
+ tasks: fourTaskPlan.tasks.filter((task) => task.taskId !== 'T04'),
464
+ }, base);
465
+ assert.ok(!('error' in second), `unexpected error: ${'error' in second ? second.error : ''}`);
466
+
467
+ assert.deepEqual(getSliceTasks('M001', 'S02').map((task) => task.id), ['T01', 'T02', 'T03']);
468
+ assert.equal(getGateResults('M001', 'S02', 'task').some((gate) => gate.task_id === 'T04'), false);
469
+ assert.equal(existsSync(staleTaskPlanPath), false, 'omitted task plan artifact should be removed');
470
+ } finally {
471
+ cleanup(base);
472
+ }
473
+ });
474
+
475
+ test('handlePlanSlice rejects omitted completed tasks without changing slice or task state', async () => {
476
+ const base = makeTmpBase();
477
+ openDatabase(join(base, '.gsd', 'gsd.db'));
478
+
479
+ try {
480
+ seedParentSlice();
481
+ const fourTaskPlan = {
482
+ ...validParams(),
483
+ tasks: [
484
+ ...validParams().tasks,
485
+ { ...validParams().tasks[0], taskId: 'T03', title: 'Third task' },
486
+ { ...validParams().tasks[0], taskId: 'T04', title: 'Stale task', inputs: ['stale-input.py'] },
487
+ ],
488
+ };
489
+
490
+ const first = await handlePlanSlice(fourTaskPlan, base);
491
+ assert.ok(!('error' in first), `unexpected error: ${'error' in first ? first.error : ''}`);
492
+ const staleTaskPlanPath = join(base, '.gsd', 'milestones', 'M001', 'slices', 'S02', 'tasks', 'T04-PLAN.md');
493
+ assert.ok(existsSync(staleTaskPlanPath), 'initial plan should render T04');
494
+
495
+ updateTaskStatus('M001', 'S02', 'T04', 'complete', '2026-05-12T00:00:00.000Z');
496
+ const tasksBefore = getSliceTasks('M001', 'S02');
497
+ const gatesBefore = getGateResults('M001', 'S02', 'task');
498
+
499
+ const second = await handlePlanSlice({
500
+ ...validParams(),
501
+ goal: 'Rejected replan should not persist.',
502
+ tasks: fourTaskPlan.tasks.filter((task) => task.taskId !== 'T04'),
503
+ }, base);
504
+ assert.deepEqual(second, { error: 'cannot remove completed task T04' });
505
+
506
+ assert.equal(getSlice('M001', 'S02')?.goal, 'Persist slice planning through the DB.');
507
+ assert.deepEqual(getSliceTasks('M001', 'S02'), tasksBefore);
508
+ assert.deepEqual(getGateResults('M001', 'S02', 'task'), gatesBefore);
509
+ assert.ok(existsSync(staleTaskPlanPath), 'completed task plan artifact should remain after rejected replan');
510
+ } finally {
511
+ cleanup(base);
512
+ }
513
+ });
514
+
515
+ test('regression: validateTasks surfaces clean per-field errors for non-array IO inputs', async () => {
516
+ // Regression for the bug fixed in PR #5872: an earlier refactor on main
517
+ // (0b0e1a901) re-added validateStringArray() calls inside validateTasks
518
+ // without re-adding its import. The catch around validateParams swallowed
519
+ // the ReferenceError into a generic "validation failed: validateStringArray
520
+ // is not defined" message, so silent runtime breakage was possible.
521
+ //
522
+ // Exercise every validateStringArray call site (files, inputs, expectedOutput)
523
+ // so a future missing-import would surface as a per-field assertion failure
524
+ // here, not a deep ReferenceError that's easy to mis-diagnose.
525
+ const base = makeTmpBase();
526
+ openDatabase(join(base, '.gsd', 'gsd.db'));
527
+
528
+ try {
529
+ seedParentSlice();
530
+
531
+ for (const field of ['files', 'inputs', 'expectedOutput'] as const) {
532
+ const result = await handlePlanSlice({
533
+ ...validParams(),
534
+ tasks: [{
535
+ ...validParams().tasks[0],
536
+ [field]: 'not-an-array' as unknown as string[],
537
+ }],
538
+ }, base);
539
+ assert.ok('error' in result, `${field}: expected validation error, got success`);
540
+ assert.match(
541
+ result.error,
542
+ new RegExp(`tasks\\[0\\]\\.${field} must be an array`),
543
+ `${field}: expected per-field validation message, got: ${result.error}`,
544
+ );
545
+ assert.doesNotMatch(
546
+ result.error,
547
+ /is not defined/,
548
+ `${field}: validation surfaced ReferenceError — likely a missing import in plan-slice.ts`,
549
+ );
550
+ assert.equal(getSliceTasks('M001', 'S02').length, 0, `${field}: invalid input must not persist`);
551
+ }
552
+ } finally {
553
+ cleanup(base);
554
+ }
555
+ });
@@ -79,6 +79,23 @@ test('handlePlanTask rejects invalid payloads', async () => {
79
79
  }
80
80
  });
81
81
 
82
+ test('handlePlanTask explains string IO fields must be arrays', async () => {
83
+ const base = makeTmpBase();
84
+ openDatabase(join(base, '.gsd', 'gsd.db'));
85
+
86
+ try {
87
+ seedParent();
88
+ const result = await handlePlanTask({
89
+ ...validParams(),
90
+ expectedOutput: 'src/output.ts' as unknown as string[],
91
+ }, base);
92
+ assert.ok('error' in result);
93
+ assert.match(result.error, /validation failed: expectedOutput must be an array of strings, not string/);
94
+ } finally {
95
+ cleanup(base);
96
+ }
97
+ });
98
+
82
99
  test('handlePlanTask rejects absolute task IO paths outside the active worktree', async () => {
83
100
  const base = makeTmpBase();
84
101
  openDatabase(join(base, '.gsd', 'gsd.db'));
@@ -1,3 +1,5 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Tests for post-execution retry bypass and verification gate failure handling.
1
3
  /**
2
4
  * post-exec-retry-bypass.test.ts — Tests for post-execution blocking failure retry bypass.
3
5
  *
@@ -9,7 +11,7 @@
9
11
  import { describe, test, mock, beforeEach, afterEach } from "node:test";
10
12
  import assert from "node:assert/strict";
11
13
  import { tmpdir } from "node:os";
12
- import { mkdirSync, writeFileSync, rmSync, existsSync } from "node:fs";
14
+ import { mkdirSync, readFileSync, writeFileSync, rmSync } from "node:fs";
13
15
  import { join } from "node:path";
14
16
 
15
17
  import { runPostUnitVerification, type VerificationContext } from "../auto-verification.ts";
@@ -71,6 +73,7 @@ function setupTestEnvironment(): void {
71
73
  mkdirSync(milestonesDir, { recursive: true });
72
74
 
73
75
  process.chdir(tempDir);
76
+ invalidateAllCaches();
74
77
  _clearGsdRootCache();
75
78
 
76
79
  dbPath = join(gsdDir, "gsd.db");
@@ -140,6 +143,34 @@ function createBasicTask(): void {
140
143
  });
141
144
  }
142
145
 
146
+ function createTaskWithoutVerify(): void {
147
+ insertMilestone({ id: "M001" });
148
+ insertSlice({
149
+ id: "S01",
150
+ milestoneId: "M001",
151
+ title: "Test Slice",
152
+ risk: "low",
153
+ });
154
+
155
+ insertTask({
156
+ id: "T01",
157
+ sliceId: "S01",
158
+ milestoneId: "M001",
159
+ title: "Task without host verification",
160
+ status: "pending",
161
+ planning: {
162
+ description: "Task intentionally missing runnable verification",
163
+ estimate: "1h",
164
+ files: [],
165
+ verify: "",
166
+ inputs: [],
167
+ expectedOutput: [],
168
+ observabilityImpact: "",
169
+ },
170
+ sequence: 0,
171
+ });
172
+ }
173
+
143
174
  function createPostExecFailureTask(): void {
144
175
  insertMilestone({ id: "M001" });
145
176
  insertSlice({
@@ -327,6 +358,53 @@ describe("Post-execution blocking failure retry bypass", () => {
327
358
  assert.equal(row?.outcome, "fail");
328
359
  assert.equal(row?.failure_class, "artifact");
329
360
  });
361
+
362
+ test("execute-task with no host-owned verification pauses fail-closed", async () => {
363
+ createTaskWithoutVerify();
364
+
365
+ const ctx = makeMockCtx();
366
+ const pi = makeMockPi();
367
+ const pauseAutoMock = mock.fn(async () => {});
368
+ const s = makeMockSession(tempDir, { type: "execute-task", id: "M001/S01/T01" });
369
+
370
+ const result = await runPostUnitVerification({ s, ctx, pi }, pauseAutoMock);
371
+
372
+ assert.equal(result, "pause");
373
+ assert.equal(pauseAutoMock.mock.callCount(), 1);
374
+ assert.equal(s.pendingVerificationRetry, null);
375
+
376
+ const evidencePath = join(tempDir, ".gsd", "milestones", "M001", "slices", "S01", "tasks", "T01-VERIFY.json");
377
+ const evidence = JSON.parse(readFileSync(evidencePath, "utf-8"));
378
+ assert.equal(evidence.passed, false);
379
+ assert.equal(evidence.discoverySource, "none");
380
+ assert.ok(!("retryAttempt" in evidence), "no-host-checks evidence must not include retryAttempt");
381
+ assert.ok(!("maxRetries" in evidence), "no-host-checks evidence must not include maxRetries");
382
+ });
383
+
384
+ test("auto-discovered package.json verification failure retries instead of continuing", async () => {
385
+ createTaskWithoutVerify();
386
+ writeFileSync(
387
+ join(tempDir, "package.json"),
388
+ JSON.stringify({ scripts: { test: "exit 1" } }),
389
+ "utf-8",
390
+ );
391
+ writePreferences({
392
+ verification_auto_fix: true,
393
+ verification_max_retries: 2,
394
+ });
395
+
396
+ const ctx = makeMockCtx();
397
+ const pi = makeMockPi();
398
+ const pauseAutoMock = mock.fn(async () => {});
399
+ const s = makeMockSession(tempDir, { type: "execute-task", id: "M001/S01/T01" });
400
+
401
+ const result = await runPostUnitVerification({ s, ctx, pi }, pauseAutoMock);
402
+
403
+ assert.equal(result, "retry");
404
+ assert.equal(pauseAutoMock.mock.callCount(), 0);
405
+ assert.equal(s.pendingVerificationRetry?.unitId, "M001/S01/T01");
406
+ assert.match(s.pendingVerificationRetry?.failureContext ?? "", /npm run test/);
407
+ });
330
408
  });
331
409
 
332
410
  describe("Post-execution retry behavior", () => {