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
@@ -8,7 +8,7 @@
8
8
 
9
9
  import test from "node:test";
10
10
  import assert from "node:assert/strict";
11
- import { mkdtempSync, mkdirSync, writeFileSync, rmSync, readFileSync, realpathSync } from "node:fs";
11
+ import { existsSync, mkdtempSync, mkdirSync, writeFileSync, rmSync, readFileSync, realpathSync } from "node:fs";
12
12
  import { join } from "node:path";
13
13
  import { tmpdir } from "node:os";
14
14
  import { execSync } from "node:child_process";
@@ -208,8 +208,8 @@ test("postflightPopStash conflict warning names the exact stash ref", () => {
208
208
  assert.match(postflight.message, /failed after merge of milestone M005C/);
209
209
 
210
210
  const warning = notifications.find((n) => n.level === "warning")?.msg ?? "";
211
- assert.match(warning, /git stash pop stash@\{\d+\}/);
212
211
  assert.match(warning, /git stash apply stash@\{\d+\}/);
212
+ assert.match(warning, /git stash drop stash@\{\d+\}/);
213
213
  } finally {
214
214
  try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
215
215
  }
@@ -279,3 +279,108 @@ test("postflightPopStash falls back to milestone marker prefix when exact marker
279
279
  try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
280
280
  }
281
281
  });
282
+
283
+ test("postflightPopStash preserves stash when untracked collision differs from merged file", () => {
284
+ const repo = createTempRepo();
285
+ try {
286
+ writeFileSync(join(repo, "tests.txt"), "local preflight test\n");
287
+ const preflight = preflightCleanRoot(repo, "M009", () => {});
288
+ assert.equal(preflight.stashPushed, true, "preflight must stash untracked file");
289
+
290
+ writeFileSync(join(repo, "tests.txt"), "merged milestone test\n");
291
+ run("git add tests.txt", repo);
292
+ run('git commit -m "feat: add merged test"', repo);
293
+
294
+ const notifications: Array<{ msg: string; level: string }> = [];
295
+ const postflight = postflightPopStash(repo, "M009", preflight.stashMarker, (msg, level) => {
296
+ notifications.push({ msg, level });
297
+ });
298
+
299
+ assert.equal(postflight.needsManualRecovery, false, "different already-present untracked files must not stop auto-mode");
300
+ assert.equal(postflight.resolution, "already-present-preserved");
301
+ assert.deepEqual(postflight.collidedPaths, ["tests.txt"]);
302
+ assert.equal(readFileSync(join(repo, "tests.txt"), "utf-8"), "merged milestone test\n");
303
+ assert.equal(run("git status --porcelain", repo), "", "merged file must stay clean");
304
+
305
+ const stashList = run("git stash list", repo);
306
+ assert.ok(preflight.stashMarker && stashList.includes(preflight.stashMarker), "stash backup must be preserved");
307
+ assert.ok(
308
+ notifications.some((n) => n.level === "warning" && n.msg.includes("preserving")),
309
+ "user must be warned that the stash was preserved as backup",
310
+ );
311
+ } finally {
312
+ try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
313
+ }
314
+ });
315
+
316
+ test("postflightPopStash drops stash when untracked collision is identical to merged file", () => {
317
+ const repo = createTempRepo();
318
+ try {
319
+ writeFileSync(join(repo, "tests.txt"), "same test content\n");
320
+ const preflight = preflightCleanRoot(repo, "M010", () => {});
321
+ assert.equal(preflight.stashPushed, true, "preflight must stash untracked file");
322
+
323
+ writeFileSync(join(repo, "tests.txt"), "same test content\n");
324
+ run("git add tests.txt", repo);
325
+ run('git commit -m "feat: add same test"', repo);
326
+
327
+ const postflight = postflightPopStash(repo, "M010", preflight.stashMarker, () => {});
328
+
329
+ assert.equal(postflight.needsManualRecovery, false, "identical already-present files must not stop auto-mode");
330
+ assert.equal(postflight.resolution, "already-present-dropped");
331
+ assert.equal(readFileSync(join(repo, "tests.txt"), "utf-8"), "same test content\n");
332
+
333
+ const stashList = run("git stash list", repo);
334
+ assert.ok(!stashList.includes(preflight.stashMarker ?? ""), "identical stash must be dropped");
335
+ } finally {
336
+ try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
337
+ }
338
+ });
339
+
340
+ test("postflightPopStash requires manual recovery for mixed tracked changes and untracked collision", () => {
341
+ const repo = createTempRepo();
342
+ try {
343
+ writeFileSync(join(repo, "README.md"), "# local tracked work\n");
344
+ writeFileSync(join(repo, "tests.txt"), "local untracked work\n");
345
+ const preflight = preflightCleanRoot(repo, "M011", () => {});
346
+ assert.equal(preflight.stashPushed, true, "preflight must stash mixed changes");
347
+
348
+ writeFileSync(join(repo, "tests.txt"), "merged milestone test\n");
349
+ run("git add tests.txt", repo);
350
+ run('git commit -m "feat: add merged test"', repo);
351
+
352
+ const postflight = postflightPopStash(repo, "M011", preflight.stashMarker, () => {});
353
+
354
+ assert.equal(postflight.needsManualRecovery, true, "tracked stash payload must still require manual recovery");
355
+ assert.equal(postflight.resolution, "manual-recovery");
356
+ const stashList = run("git stash list", repo);
357
+ assert.ok(preflight.stashMarker && stashList.includes(preflight.stashMarker), "mixed stash must be preserved");
358
+ } finally {
359
+ try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
360
+ }
361
+ });
362
+
363
+ test("postflightPopStash requires manual recovery when an untracked stash path is missing after collision", () => {
364
+ const repo = createTempRepo();
365
+ try {
366
+ writeFileSync(join(repo, "tests.txt"), "local untracked work\n");
367
+ writeFileSync(join(repo, "other-tests.txt"), "other local untracked work\n");
368
+ const preflight = preflightCleanRoot(repo, "M012", () => {});
369
+ assert.equal(preflight.stashPushed, true, "preflight must stash untracked files");
370
+
371
+ writeFileSync(join(repo, "tests.txt"), "merged milestone test\n");
372
+ run("git add tests.txt", repo);
373
+ run('git commit -m "feat: add one merged test"', repo);
374
+
375
+ const postflight = postflightPopStash(repo, "M012", preflight.stashMarker, () => {});
376
+
377
+ assert.equal(postflight.needsManualRecovery, true, "partial untracked restores must still require manual recovery");
378
+ assert.equal(postflight.resolution, "manual-recovery");
379
+ assert.equal(existsSync(join(repo, "other-tests.txt")), true, "git may partially restore the non-colliding path");
380
+ assert.match(run("git status --porcelain", repo), /\?\? other-tests\.txt/, "partial restore must leave manual recovery visible");
381
+ const stashList = run("git stash list", repo);
382
+ assert.ok(preflight.stashMarker && stashList.includes(preflight.stashMarker), "stash must remain for manual recovery");
383
+ } finally {
384
+ try { rmSync(repo, { recursive: true, force: true, maxRetries: 3, retryDelay: 100 }); } catch { /* ignore */ }
385
+ }
386
+ });
@@ -17,6 +17,15 @@ import {
17
17
  setPendingAutoStart,
18
18
  } from "../guided-flow.ts";
19
19
 
20
+ function pendingInput(basePath: string, milestoneId: string) {
21
+ return {
22
+ basePath,
23
+ milestoneId,
24
+ ctx: { ui: { notify: () => undefined } } as any,
25
+ pi: { sendMessage: () => undefined } as any,
26
+ };
27
+ }
28
+
20
29
  afterEach(() => {
21
30
  clearPendingAutoStart();
22
31
  });
@@ -28,7 +37,7 @@ describe("clear stale pending auto-start (#3667)", () => {
28
37
  mkdirSync(join(base, ".gsd"), { recursive: true });
29
38
  const before = Date.now();
30
39
 
31
- setPendingAutoStart(base, { basePath: base, milestoneId: "M001" });
40
+ setPendingAutoStart(base, pendingInput(base, "M001"));
32
41
 
33
42
  const entry = _getPendingAutoStart(base);
34
43
  assert.ok(entry);
@@ -41,7 +50,7 @@ describe("clear stale pending auto-start (#3667)", () => {
41
50
  t.after(() => rmSync(base, { recursive: true, force: true }));
42
51
  mkdirSync(join(base, ".gsd"), { recursive: true });
43
52
 
44
- setPendingAutoStart(base, { basePath: base, milestoneId: "M001", createdAt: 123 });
53
+ setPendingAutoStart(base, { ...pendingInput(base, "M001"), createdAt: 123 });
45
54
 
46
55
  assert.equal(_getPendingAutoStart(base)?.createdAt, 123);
47
56
  });
@@ -0,0 +1,16 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Tests closeout git action deferral policy for auto-mode units.
3
+
4
+ import test from "node:test";
5
+ import assert from "node:assert/strict";
6
+
7
+ import { shouldDeferCloseoutGitAction } from "../auto-post-unit.ts";
8
+
9
+ test("execute-task defers closeout git action until verification passes", () => {
10
+ assert.equal(shouldDeferCloseoutGitAction("execute-task"), true);
11
+ });
12
+
13
+ test("non execute-task units keep pre-verification closeout git action", () => {
14
+ assert.equal(shouldDeferCloseoutGitAction("plan-slice"), false);
15
+ assert.equal(shouldDeferCloseoutGitAction("complete-slice"), false);
16
+ });
@@ -0,0 +1,378 @@
1
+ /**
2
+ * Tests for /gsd verdict — manual override of milestone validation verdict.
3
+ *
4
+ * Covers parseValidationFile section extraction and handleVerdict end-to-end:
5
+ * pass override, needs-remediation override with rationale, missing rationale
6
+ * rejection, active-milestone fallback, missing VALIDATION rejection.
7
+ *
8
+ * Also asserts the three paused-state messages reference /gsd verdict so the
9
+ * user has a discoverable recovery path.
10
+ */
11
+ import test from "node:test";
12
+ import assert from "node:assert/strict";
13
+ import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
14
+ import { join } from "node:path";
15
+ import { tmpdir } from "node:os";
16
+ import { randomUUID } from "node:crypto";
17
+
18
+ import { handleVerdict, parseValidationFile } from "../commands-verdict.ts";
19
+ import { openDatabase, closeDatabase, _getAdapter } from "../gsd-db.ts";
20
+ import { invalidateStateCache } from "../state.ts";
21
+
22
+ interface NotifyCall {
23
+ message: string;
24
+ kind: string;
25
+ }
26
+
27
+ function makeMockCtx(): { ctx: any; calls: NotifyCall[] } {
28
+ const calls: NotifyCall[] = [];
29
+ const ctx = {
30
+ ui: {
31
+ notify: (message: string, kind: string) => {
32
+ calls.push({ message, kind });
33
+ },
34
+ },
35
+ };
36
+ return { ctx, calls };
37
+ }
38
+
39
+ function makeBase(): string {
40
+ const base = mkdtempSync(join(tmpdir(), `gsd-verdict-${randomUUID()}-`));
41
+ mkdirSync(join(base, ".gsd"), { recursive: true });
42
+ return base;
43
+ }
44
+
45
+ function cleanup(base: string): void {
46
+ try { rmSync(base, { recursive: true, force: true }); } catch { /* swallow */ }
47
+ }
48
+
49
+ function openTestDb(base: string): void {
50
+ openDatabase(join(base, ".gsd", "gsd.db"));
51
+ }
52
+
53
+ function seedMilestone(milestoneId: string, title: string, status = "active"): void {
54
+ const db = _getAdapter();
55
+ if (!db) throw new Error("DB not open");
56
+ db.prepare(
57
+ "INSERT OR REPLACE INTO milestones (id, title, status, created_at) VALUES (?, ?, ?, ?)",
58
+ ).run(milestoneId, title, status, new Date().toISOString());
59
+ }
60
+
61
+ function seedSlice(milestoneId: string, sliceId: string, status: string): void {
62
+ const db = _getAdapter();
63
+ if (!db) throw new Error("DB not open");
64
+ db.prepare(
65
+ "INSERT OR REPLACE INTO slices (milestone_id, id, title, status, created_at) VALUES (?, ?, ?, ?, ?)",
66
+ ).run(milestoneId, sliceId, `Slice ${sliceId}`, status, new Date().toISOString());
67
+ }
68
+
69
+ function writeValidation(base: string, milestoneId: string, verdict: string, round = 0): string {
70
+ const milestoneDir = join(base, ".gsd", "milestones", milestoneId);
71
+ mkdirSync(milestoneDir, { recursive: true });
72
+ const path = join(milestoneDir, `${milestoneId}-VALIDATION.md`);
73
+ const md = [
74
+ "---",
75
+ `verdict: ${verdict}`,
76
+ `remediation_round: ${round}`,
77
+ "---",
78
+ "",
79
+ `# Milestone Validation: ${milestoneId}`,
80
+ "",
81
+ "## Success Criteria Checklist",
82
+ "- [x] Criterion A met",
83
+ "- [x] Criterion B met",
84
+ "",
85
+ "## Slice Delivery Audit",
86
+ "| Slice | Result |",
87
+ "| --- | --- |",
88
+ "| S01 | delivered |",
89
+ "",
90
+ "## Cross-Slice Integration",
91
+ "No cross-slice mismatches detected.",
92
+ "",
93
+ "## Requirement Coverage",
94
+ "All requirements covered.",
95
+ "",
96
+ "## Verdict Rationale",
97
+ `Initial verdict was ${verdict}.`,
98
+ "",
99
+ ].join("\n");
100
+ writeFileSync(path, md);
101
+ return path;
102
+ }
103
+
104
+ // ─── parseValidationFile ────────────────────────────────────────────────
105
+
106
+ test("parseValidationFile extracts all standard sections and frontmatter", () => {
107
+ const md = [
108
+ "---",
109
+ "verdict: needs-attention",
110
+ "remediation_round: 2",
111
+ "---",
112
+ "",
113
+ "# Milestone Validation: M001",
114
+ "",
115
+ "## Success Criteria Checklist",
116
+ "- [x] First",
117
+ "- [ ] Second",
118
+ "",
119
+ "## Slice Delivery Audit",
120
+ "| Slice | Delivered |",
121
+ "",
122
+ "## Cross-Slice Integration",
123
+ "Boundary intact.",
124
+ "",
125
+ "## Requirement Coverage",
126
+ "R001 covered.",
127
+ "",
128
+ "## Verification Class Compliance",
129
+ "Operational: MET",
130
+ "",
131
+ "## Verdict Rationale",
132
+ "Acceptance proof incomplete.",
133
+ "",
134
+ "## Remediation Plan",
135
+ "Address acceptance proof.",
136
+ "",
137
+ ].join("\n");
138
+
139
+ const parsed = parseValidationFile(md);
140
+
141
+ assert.equal(parsed.verdict, "needs-attention");
142
+ assert.equal(parsed.remediationRound, 2);
143
+ assert.match(parsed.successCriteriaChecklist, /First/);
144
+ assert.match(parsed.successCriteriaChecklist, /Second/);
145
+ assert.match(parsed.sliceDeliveryAudit, /Delivered/);
146
+ assert.match(parsed.crossSliceIntegration, /Boundary intact/);
147
+ assert.match(parsed.requirementCoverage, /R001 covered/);
148
+ assert.match(parsed.verificationClasses ?? "", /Operational: MET/);
149
+ assert.match(parsed.verdictRationale, /Acceptance proof incomplete/);
150
+ assert.match(parsed.remediationPlan ?? "", /Address acceptance proof/);
151
+ });
152
+
153
+ test("parseValidationFile omits optional sections when absent", () => {
154
+ const md = [
155
+ "---",
156
+ "verdict: pass",
157
+ "remediation_round: 0",
158
+ "---",
159
+ "",
160
+ "## Success Criteria Checklist",
161
+ "- [x] All met",
162
+ "",
163
+ "## Slice Delivery Audit",
164
+ "Done.",
165
+ "",
166
+ "## Cross-Slice Integration",
167
+ "Clean.",
168
+ "",
169
+ "## Requirement Coverage",
170
+ "Complete.",
171
+ "",
172
+ "## Verdict Rationale",
173
+ "All criteria met.",
174
+ ].join("\n");
175
+
176
+ const parsed = parseValidationFile(md);
177
+
178
+ assert.equal(parsed.verdict, "pass");
179
+ assert.equal(parsed.remediationRound, 0);
180
+ assert.equal(parsed.verificationClasses, undefined);
181
+ assert.equal(parsed.remediationPlan, undefined);
182
+ });
183
+
184
+ // ─── handleVerdict — argument validation ────────────────────────────────
185
+
186
+ test("handleVerdict rejects missing verdict", async () => {
187
+ const { ctx, calls } = makeMockCtx();
188
+ await handleVerdict("", ctx, "/tmp/unused");
189
+ assert.equal(calls.length, 1);
190
+ assert.match(calls[0].message, /Usage: \/gsd verdict/);
191
+ assert.equal(calls[0].kind, "warning");
192
+ });
193
+
194
+ test("handleVerdict rejects invalid verdict", async () => {
195
+ const { ctx, calls } = makeMockCtx();
196
+ await handleVerdict("yolo", ctx, "/tmp/unused");
197
+ assert.equal(calls.length, 1);
198
+ assert.match(calls[0].message, /Invalid verdict "yolo"/);
199
+ assert.equal(calls[0].kind, "warning");
200
+ });
201
+
202
+ test("handleVerdict rejects needs-remediation without --rationale", async () => {
203
+ const base = makeBase();
204
+ try {
205
+ openTestDb(base);
206
+ seedMilestone("M001", "Test Milestone");
207
+ seedSlice("M001", "S01", "complete");
208
+ writeValidation(base, "M001", "pass");
209
+
210
+ const { ctx, calls } = makeMockCtx();
211
+ await handleVerdict("needs-remediation --milestone M001", ctx, base);
212
+
213
+ assert.ok(
214
+ calls.some((c) => /--rationale is required/.test(c.message)),
215
+ `expected rationale-required warning, got: ${JSON.stringify(calls)}`,
216
+ );
217
+ } finally {
218
+ closeDatabase();
219
+ invalidateStateCache();
220
+ cleanup(base);
221
+ }
222
+ });
223
+
224
+ test("handleVerdict rejects when VALIDATION file is missing", async () => {
225
+ const base = makeBase();
226
+ try {
227
+ openTestDb(base);
228
+ seedMilestone("M001", "Test Milestone");
229
+ seedSlice("M001", "S01", "complete");
230
+ mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
231
+
232
+ const { ctx, calls } = makeMockCtx();
233
+ await handleVerdict("pass --milestone M001", ctx, base);
234
+
235
+ assert.ok(
236
+ calls.some((c) => /No VALIDATION file found/.test(c.message)),
237
+ `expected missing-VALIDATION warning, got: ${JSON.stringify(calls)}`,
238
+ );
239
+ } finally {
240
+ closeDatabase();
241
+ invalidateStateCache();
242
+ cleanup(base);
243
+ }
244
+ });
245
+
246
+ // ─── handleVerdict — pass override flow ─────────────────────────────────
247
+
248
+ test("handleVerdict pass override flips verdict and preserves sections", async () => {
249
+ const base = makeBase();
250
+ try {
251
+ openTestDb(base);
252
+ seedMilestone("M001", "Test Milestone");
253
+ seedSlice("M001", "S01", "complete");
254
+ const validationPath = writeValidation(base, "M001", "needs-attention");
255
+
256
+ const { ctx, calls } = makeMockCtx();
257
+ await handleVerdict("pass --milestone M001", ctx, base);
258
+
259
+ const rewritten = readFileSync(validationPath, "utf-8");
260
+ assert.match(rewritten, /^verdict: pass$/m, "verdict should flip to pass");
261
+ assert.match(rewritten, /Criterion A met/, "success criteria preserved");
262
+ assert.match(rewritten, /S01 \| delivered/, "slice audit preserved");
263
+ assert.match(rewritten, /Manually overridden via \/gsd verdict/, "default rationale applied");
264
+
265
+ assert.ok(
266
+ calls.some((c) => c.kind === "success" && /needs-attention.*->.*pass/.test(c.message)),
267
+ `expected success notification, got: ${JSON.stringify(calls)}`,
268
+ );
269
+ } finally {
270
+ closeDatabase();
271
+ invalidateStateCache();
272
+ cleanup(base);
273
+ }
274
+ });
275
+
276
+ test("handleVerdict needs-remediation override with --rationale rewrites verdict", async () => {
277
+ const base = makeBase();
278
+ try {
279
+ openTestDb(base);
280
+ seedMilestone("M001", "Test Milestone");
281
+ seedSlice("M001", "S01", "complete");
282
+ const validationPath = writeValidation(base, "M001", "pass");
283
+
284
+ const { ctx, calls } = makeMockCtx();
285
+ await handleVerdict(
286
+ 'needs-remediation --milestone M001 --rationale "found missing slice"',
287
+ ctx,
288
+ base,
289
+ );
290
+
291
+ const rewritten = readFileSync(validationPath, "utf-8");
292
+ assert.match(rewritten, /^verdict: needs-remediation$/m);
293
+ assert.match(rewritten, /found missing slice/);
294
+
295
+ assert.ok(
296
+ calls.some((c) => /gsd_reassess_roadmap/.test(c.message)),
297
+ "needs-remediation override should suggest gsd_reassess_roadmap follow-up",
298
+ );
299
+ } finally {
300
+ closeDatabase();
301
+ invalidateStateCache();
302
+ cleanup(base);
303
+ }
304
+ });
305
+
306
+ test("handleVerdict resolves active milestone when --milestone omitted", async () => {
307
+ const base = makeBase();
308
+ try {
309
+ openTestDb(base);
310
+ seedMilestone("M042", "Active Milestone");
311
+ seedSlice("M042", "S01", "complete");
312
+ const validationPath = writeValidation(base, "M042", "needs-attention");
313
+
314
+ const { ctx, calls } = makeMockCtx();
315
+ invalidateStateCache();
316
+ await handleVerdict("pass", ctx, base);
317
+
318
+ const rewritten = readFileSync(validationPath, "utf-8");
319
+ assert.match(rewritten, /^verdict: pass$/m);
320
+ assert.ok(
321
+ calls.some((c) => c.kind === "success" && /M042/.test(c.message)),
322
+ `expected success notification naming M042, got: ${JSON.stringify(calls)}`,
323
+ );
324
+ } finally {
325
+ closeDatabase();
326
+ invalidateStateCache();
327
+ cleanup(base);
328
+ }
329
+ });
330
+
331
+ // ─── Pause messages reference /gsd verdict ─────────────────────────────
332
+
333
+ test("auto-dispatch needs-attention pause message references /gsd verdict", async () => {
334
+ const { DISPATCH_RULES } = await import("../auto-dispatch.ts");
335
+ const rule = DISPATCH_RULES.find((r) => r.name === "completing-milestone → complete-milestone");
336
+ assert.ok(rule, "completing-milestone rule should exist");
337
+
338
+ const base = mkdtempSync(join(tmpdir(), "gsd-verdict-paused-"));
339
+ mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
340
+ try {
341
+ writeFileSync(
342
+ join(base, ".gsd", "milestones", "M001", "M001-VALIDATION.md"),
343
+ "---\nverdict: needs-attention\nremediation_round: 0\n---\n\n# Validation\nNeeds work.\n",
344
+ );
345
+
346
+ const result = await rule!.match({
347
+ mid: "M001",
348
+ midTitle: "Test",
349
+ basePath: base,
350
+ state: { phase: "completing-milestone" } as any,
351
+ prefs: {} as any,
352
+ session: undefined,
353
+ } as any);
354
+
355
+ assert.ok(result !== null);
356
+ assert.equal(result!.action, "stop");
357
+ if (result!.action === "stop") {
358
+ assert.match(result!.reason, /\/gsd verdict/);
359
+ }
360
+ } finally {
361
+ cleanup(base);
362
+ }
363
+ });
364
+
365
+ test("state.ts needs-remediation blocker messages reference /gsd verdict", async () => {
366
+ // We don't need to invoke deriveState — just assert the substring is in the
367
+ // source. The blocker strings are constructed inline and shipped to the user
368
+ // verbatim, so a static check is sufficient and avoids fragile DB setup.
369
+ const stateSource = readFileSync(
370
+ new URL("../state.ts", import.meta.url).pathname,
371
+ "utf-8",
372
+ );
373
+ const occurrences = stateSource.match(/`\/gsd verdict /g) ?? [];
374
+ assert.ok(
375
+ occurrences.length >= 2,
376
+ `expected at least 2 references to /gsd verdict in state.ts blockers, found ${occurrences.length}`,
377
+ );
378
+ });
@@ -645,7 +645,7 @@ describe("complete-milestone", () => {
645
645
  assert.strictEqual(sanitized.triggerReason, undefined);
646
646
  });
647
647
 
648
- test("rendered SUMMARY.md uses placeholder text for empty enrichment fields", async () => {
648
+ test("rendered SUMMARY.md uses empty frontmatter lists for empty key fields", async () => {
649
649
  const { handleCompleteMilestone } = await import("../tools/complete-milestone.ts");
650
650
  const base = createFixtureBase();
651
651
  const mid = "M001";
@@ -678,6 +678,9 @@ describe("complete-milestone", () => {
678
678
  assert.match(summary, /## Success Criteria Results\n\nNot provided\./);
679
679
  assert.match(summary, /## Definition of Done Results\n\nNot provided\./);
680
680
  assert.match(summary, /## Requirement Outcomes\n\nNot provided\./);
681
+ assert.match(summary, /key_decisions:\s*\[\]/);
682
+ assert.match(summary, /key_files:\s*\[\]/);
683
+ assert.doesNotMatch(summary, /key_(?:decisions|files):\n - \(none\)/);
681
684
  assert.match(summary, /## Deviations\n\nNone\./);
682
685
  assert.match(summary, /## Follow-ups\n\nNone\./);
683
686
  } finally {
@@ -408,10 +408,10 @@ console.log('\n=== complete-slice: handler with missing roadmap ===');
408
408
  }
409
409
 
410
410
  // ═══════════════════════════════════════════════════════════════════════════
411
- // complete-slice: step 13 specifies write tool for PROJECT.md (#2946)
411
+ // complete-slice: PROJECT refresh uses DB-backed artifact tool.
412
412
  // ═══════════════════════════════════════════════════════════════════════════
413
413
 
414
- console.log('\n=== complete-slice: step 13 specifies write tool for PROJECT.md (#2946) ===');
414
+ console.log('\n=== complete-slice: PROJECT refresh uses gsd_summary_save ===');
415
415
  {
416
416
  const promptPath = path.join(
417
417
  path.dirname(new URL(import.meta.url).pathname),
@@ -419,13 +419,9 @@ console.log('\n=== complete-slice: step 13 specifies write tool for PROJECT.md (
419
419
  );
420
420
  const prompt = fs.readFileSync(promptPath, 'utf-8');
421
421
 
422
- // Step 13 must explicitly name the `write` tool so the LLM doesn't
423
- // confuse it with `edit` (which requires path + oldText + newText).
424
- // See: https://github.com/gsd-build/gsd-2/issues/2946
425
- const mentionsWriteTool =
426
- /PROJECT\.md.*\bwrite\b/i.test(prompt) ||
427
- /\bwrite\b.*PROJECT\.md/i.test(prompt);
428
- assertTrue(mentionsWriteTool, 'step 13 must name the `write` tool when updating PROJECT.md');
422
+ assertTrue(prompt.includes('gsd_summary_save'), 'PROJECT refresh must use gsd_summary_save');
423
+ assertTrue(prompt.includes('artifact_type: "PROJECT"'), 'PROJECT refresh must use artifact_type PROJECT');
424
+ assertTrue(!/with a full `write`/i.test(prompt), 'prompt must not instruct direct PROJECT.md writes');
429
425
  }
430
426
 
431
427
  // ═══════════════════════════════════════════════════════════════════════════
@@ -491,7 +491,9 @@ console.log('\n=== complete-task: minimal params (no keyFiles, keyDecisions, ver
491
491
  assertTrue(fs.existsSync(result.summaryPath), 'summary file should be written with minimal params');
492
492
  const summaryContent = fs.readFileSync(result.summaryPath, 'utf-8');
493
493
  assertMatch(summaryContent, /blocker_discovered:\s*false/, 'blocker_discovered should default to false');
494
- assertMatch(summaryContent, /\(none\)/, 'key_files/key_decisions should show (none) placeholder');
494
+ assertMatch(summaryContent, /key_files:\s*\[\]/, 'key_files should render as an empty frontmatter list');
495
+ assertMatch(summaryContent, /key_decisions:\s*\[\]/, 'key_decisions should render as an empty frontmatter list');
496
+ assertTrue(!summaryContent.includes(' - (none)'), 'empty frontmatter lists should not render (none) as a list item');
495
497
  }
496
498
 
497
499
  cleanupDir(basePath);