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
@@ -132,6 +132,9 @@ export type ContextModePolicy =
132
132
  * the explicit `allowedPathGlobs` set; Bash safe-allowlist;
133
133
  * no subagents. Reserved for rewrite-docs, which legitimately
134
134
  * edits project markdown outside .gsd/.
135
+ * - "verification"
136
+ * — Read tools + Bash for verification commands, writes
137
+ * restricted to .gsd/**, no subagents.
135
138
  *
136
139
  * The allowlist for "docs" is declared per-manifest rather than hardcoded so
137
140
  * projects with non-standard doc layouts can extend it without forking the
@@ -143,7 +146,8 @@ export type ToolsPolicy =
143
146
  | { readonly mode: "read-only" }
144
147
  | { readonly mode: "planning" }
145
148
  | { readonly mode: "planning-dispatch"; readonly allowedSubagents: readonly string[] }
146
- | { readonly mode: "docs"; readonly allowedPathGlobs: readonly string[] };
149
+ | { readonly mode: "docs"; readonly allowedPathGlobs: readonly string[] }
150
+ | { readonly mode: "verification" };
147
151
 
148
152
  // ─── Computed-artifact registry (#4924 v2 contract) ───────────────────────
149
153
 
@@ -288,6 +292,7 @@ const COMMON_BUDGET_SMALL = 250_000; // ~65K tokens
288
292
 
289
293
  const TOOLS_ALL: ToolsPolicy = { mode: "all" };
290
294
  const TOOLS_PLANNING: ToolsPolicy = { mode: "planning" };
295
+ const TOOLS_VERIFICATION: ToolsPolicy = { mode: "verification" };
291
296
  // Like TOOLS_PLANNING but permits dispatch to read-only recon/planning
292
297
  // specialists. Runtime-enforced by write-gate.ts before the subagent tool runs.
293
298
  const TOOLS_PLANNING_DISPATCH_RECON: ToolsPolicy = {
@@ -406,8 +411,8 @@ export const UNIT_MANIFESTS: Record<UnitType, UnitContextManifest> = {
406
411
  contextMode: "verification",
407
412
  // planning-dispatch: validation is a verification-fan-out unit. It reads
408
413
  // the milestone surface and dispatches reviewer/security/tester subagents
409
- // to report findings without touching user source. Mirrors
410
- // complete-milestone's policy. Write isolation to .gsd/ is preserved.
414
+ // to report findings without touching user source. Write isolation to
415
+ // .gsd/ is preserved.
411
416
  tools: TOOLS_PLANNING_DISPATCH_REVIEW,
412
417
  artifacts: {
413
418
  inline: ["roadmap", "slice-summary", "slice-uat", "requirements", "decisions", "templates"],
@@ -423,11 +428,9 @@ export const UNIT_MANIFESTS: Record<UnitType, UnitContextManifest> = {
423
428
  codebaseMap: false,
424
429
  preferences: "active-only",
425
430
  contextMode: "verification",
426
- // planning-dispatch: completion is a high-leverage place to fan out to
427
- // reviewer / security / tester subagents. They read the diff and report
428
- // findings; they do not write user source. Write isolation to .gsd/ is
429
- // preserved.
430
- tools: TOOLS_PLANNING_DISPATCH_REVIEW,
431
+ // Milestone closeout must run unrestricted shell verification commands
432
+ // against the final diff before recording completion.
433
+ tools: TOOLS_ALL,
431
434
  artifacts: {
432
435
  // #4780 landed slice-summary as excerpt for this unit; phase 2 of
433
436
  // the architecture will read this manifest as the source of truth
@@ -447,7 +450,9 @@ export const UNIT_MANIFESTS: Record<UnitType, UnitContextManifest> = {
447
450
  codebaseMap: true,
448
451
  preferences: "active-only",
449
452
  contextMode: "research",
450
- tools: TOOLS_PLANNING,
453
+ // Multi-slice research dispatches use the research-slice unit contract to
454
+ // fan out scout subagents that write .gsd research artifacts.
455
+ tools: TOOLS_PLANNING_DISPATCH_RECON,
451
456
  artifacts: {
452
457
  inline: ["roadmap", "milestone-research", "dependency-summaries", "templates"],
453
458
  excerpt: [],
@@ -587,7 +592,7 @@ export const UNIT_MANIFESTS: Record<UnitType, UnitContextManifest> = {
587
592
  codebaseMap: false,
588
593
  preferences: "active-only",
589
594
  contextMode: "verification",
590
- tools: TOOLS_PLANNING,
595
+ tools: TOOLS_VERIFICATION,
591
596
  artifacts: {
592
597
  // Phase 3 migration (#4782): manifest matches today's actual
593
598
  // buildRunUatPrompt inlining. Prior phase-1 entry listed
@@ -606,7 +611,9 @@ export const UNIT_MANIFESTS: Record<UnitType, UnitContextManifest> = {
606
611
  codebaseMap: false,
607
612
  preferences: "active-only",
608
613
  contextMode: "verification",
609
- tools: TOOLS_PLANNING,
614
+ // Gate evaluation fans out tester-style subagents, which read the slice
615
+ // plan and report via the DB-backed gate-result tool.
616
+ tools: TOOLS_PLANNING_DISPATCH_REVIEW,
610
617
  artifacts: {
611
618
  inline: ["slice-plan", "prior-task-summaries"],
612
619
  excerpt: [],
@@ -734,3 +741,32 @@ export const UNIT_MANIFESTS: Record<UnitType, UnitContextManifest> = {
734
741
  export function resolveManifest(unitType: string): UnitContextManifest | null {
735
742
  return (UNIT_MANIFESTS as Record<string, UnitContextManifest>)[unitType] ?? null;
736
743
  }
744
+
745
+ export interface SubagentPermissionContract {
746
+ readonly allowed: boolean;
747
+ readonly allowedSubagents: readonly string[];
748
+ readonly toolsMode: ToolsPolicy["mode"] | "unknown";
749
+ }
750
+
751
+ export function compileSubagentPermissionContract(
752
+ policy: ToolsPolicy | null | undefined,
753
+ ): SubagentPermissionContract {
754
+ if (!policy) {
755
+ return { allowed: false, allowedSubagents: [], toolsMode: "unknown" };
756
+ }
757
+ if (policy.mode === "all") {
758
+ return { allowed: true, allowedSubagents: ["*"], toolsMode: policy.mode };
759
+ }
760
+ if (policy.mode === "planning-dispatch") {
761
+ return {
762
+ allowed: true,
763
+ allowedSubagents: [...policy.allowedSubagents],
764
+ toolsMode: policy.mode,
765
+ };
766
+ }
767
+ return { allowed: false, allowedSubagents: [], toolsMode: policy.mode };
768
+ }
769
+
770
+ export function resolveSubagentPermissionContract(unitType: string): SubagentPermissionContract {
771
+ return compileSubagentPermissionContract(resolveManifest(unitType)?.tools);
772
+ }
@@ -7,6 +7,27 @@ export function isNonEmptyString(value: unknown): value is string {
7
7
  return typeof value === "string" && value.trim().length > 0;
8
8
  }
9
9
 
10
+ /**
11
+ * Characters that are used as delimiters in GSD state management documents
12
+ * and should not appear in milestone or slice titles.
13
+ */
14
+ const TITLE_DELIMITER_RE = /[\u2014\u2013\/]/; // em dash, en dash, forward slash
15
+
16
+ /**
17
+ * Check whether a milestone or slice title contains characters that conflict
18
+ * with GSD's state document delimiter conventions.
19
+ * Returns a human-readable description of the problem, or null if the title is safe.
20
+ */
21
+ export function validateTitle(title: string): string | null {
22
+ if (TITLE_DELIMITER_RE.test(title)) {
23
+ const found: string[] = [];
24
+ if (/[\u2014\u2013]/.test(title)) found.push("em/en dash (\u2014 or \u2013)");
25
+ if (/\//.test(title)) found.push("forward slash (/)");
26
+ return `title contains ${found.join(" and ")}, which conflict with GSD state document delimiters`;
27
+ }
28
+ return null;
29
+ }
30
+
10
31
  /**
11
32
  * Validate that `value` is an array of non-empty strings.
12
33
  * Throws with a message referencing `field` on failure.
@@ -14,7 +35,8 @@ export function isNonEmptyString(value: unknown): value is string {
14
35
  */
15
36
  export function validateStringArray(value: unknown, field: string): string[] {
16
37
  if (!Array.isArray(value)) {
17
- throw new Error(`${field} must be an array`);
38
+ const received = value === null ? "null" : typeof value;
39
+ throw new Error(`${field} must be an array of strings, not ${received}`);
18
40
  }
19
41
  if (value.some((item) => !isNonEmptyString(item))) {
20
42
  throw new Error(`${field} must contain only non-empty strings`);
@@ -4,7 +4,7 @@
4
4
  // First non-empty source wins.
5
5
 
6
6
  import { spawnSync, type SpawnSyncReturns } from "node:child_process";
7
- import { existsSync, readFileSync } from "node:fs";
7
+ import { existsSync, readFileSync, readdirSync, type Dirent } from "node:fs";
8
8
  import { join, basename } from "node:path";
9
9
  import type { AuditWarning, RuntimeError, VerificationCheck, VerificationResult } from "./types.js";
10
10
  import { DEFAULT_COMMAND_TIMEOUT_MS } from "./constants.js";
@@ -44,7 +44,8 @@ const PACKAGE_SCRIPT_KEYS = ["typecheck", "lint", "test"] as const;
44
44
  * 1. Explicit preference commands
45
45
  * 2. Task plan verify field (split on &&)
46
46
  * 3. package.json scripts (typecheck, lint, test)
47
- * 4. None found
47
+ * 4. Python pytest project markers
48
+ * 5. None found
48
49
  */
49
50
  export function discoverCommands(options: DiscoverCommandsOptions): DiscoveredCommands {
50
51
  // 1. Preference commands
@@ -91,10 +92,67 @@ export function discoverCommands(options: DiscoverCommandsOptions): DiscoveredCo
91
92
  }
92
93
  }
93
94
 
94
- // 4. Nothing found
95
+ const pythonCommand = discoverPythonPytestCommand(options.cwd);
96
+ if (pythonCommand) {
97
+ return { commands: [pythonCommand], source: "python-project" };
98
+ }
99
+
100
+ // 5. Nothing found
95
101
  return { commands: [], source: "none" };
96
102
  }
97
103
 
104
+ function discoverPythonPytestCommand(cwd: string): string | null {
105
+ const hasPythonTestFiles = hasPythonTests(join(cwd, "tests"));
106
+ const hasPytestConfig = existsSync(join(cwd, "pytest.ini"));
107
+ const pyprojectPath = join(cwd, "pyproject.toml");
108
+ const hasPyproject = existsSync(pyprojectPath);
109
+
110
+ if (!hasPythonTestFiles && !hasPytestConfig && !hasPyproject) {
111
+ return null;
112
+ }
113
+
114
+ if (hasPytestConfig || hasPythonTestFiles) {
115
+ return "python3 -m pytest";
116
+ }
117
+
118
+ try {
119
+ const pyproject = readFileSync(pyprojectPath, "utf-8");
120
+ if (
121
+ pyproject.includes("[tool.pytest]") ||
122
+ pyproject.includes("[tool.pytest.") ||
123
+ pyproject.includes("[pytest]") ||
124
+ pyproject.includes("[tool:pytest]")
125
+ ) {
126
+ return "python3 -m pytest";
127
+ }
128
+ } catch {
129
+ // Ignore unreadable pyproject.toml and fall through.
130
+ }
131
+
132
+ return null;
133
+ }
134
+
135
+ function hasPythonTests(dir: string): boolean {
136
+ let entries: Dirent[];
137
+ try {
138
+ entries = readdirSync(dir, { withFileTypes: true });
139
+ } catch {
140
+ return false;
141
+ }
142
+
143
+ for (const entry of entries) {
144
+ const path = join(dir, entry.name);
145
+ if (entry.isDirectory() && hasPythonTests(path)) {
146
+ return true;
147
+ }
148
+ if (entry.isFile() && /^test_.*\.py$|^.*_test\.py$/.test(entry.name)) {
149
+ return true;
150
+ }
151
+ }
152
+
153
+ return false;
154
+ }
155
+
98
156
  // ─── Failure Context Formatting ──────────────────────────────────────────────
99
157
 
100
158
  /** Maximum chars of stderr to include per failed check in failure context. */
@@ -144,7 +202,7 @@ export function formatFailureContext(result: VerificationResult): string {
144
202
  // ─── Gate Execution ─────────────────────────────────────────────────────────
145
203
 
146
204
  /** Characters that indicate shell injection when found in a command string. */
147
- const SHELL_INJECTION_PATTERN = /[;|`]|\$\(/;
205
+ const SHELL_INJECTION_PATTERN = /[;|`<>]|\$\(/;
148
206
 
149
207
  /**
150
208
  * Known executable first-tokens that are safe to run.
@@ -182,6 +240,7 @@ const KNOWN_COMMAND_PREFIXES = new Set([
182
240
  * Heuristics (any true → prose-like):
183
241
  * 1. First token starts with an uppercase letter and the string has 4+ words
184
242
  * 2. String contains commas followed by spaces (prose clause structure)
243
+ * 3. First token has no ASCII letters or digits and the string has 4+ words
185
244
  */
186
245
  export function isLikelyCommand(cmd: string): boolean {
187
246
  const trimmed = cmd.trim();
@@ -208,6 +267,9 @@ export function isLikelyCommand(cmd: string): boolean {
208
267
  // First token has uppercase letters and no path separators → prose
209
268
  if (/[A-Z]/.test(firstToken) && !firstToken.includes("/")) return false;
210
269
 
270
+ // Non-ASCII prose with multiple words should not be executed as a command.
271
+ if (!/[A-Za-z0-9]/.test(firstToken) && tokens.length >= 4) return false;
272
+
211
273
  return true;
212
274
  }
213
275
 
@@ -215,9 +277,19 @@ export function isLikelyCommand(cmd: string): boolean {
215
277
  * Validate a command string for obvious shell injection patterns.
216
278
  * Returns the command unchanged if safe, or null if suspicious.
217
279
  */
280
+ export function validateVerificationCommand(cmd: string): { ok: true } | { ok: false; reason: string } {
281
+ if (SHELL_INJECTION_PATTERN.test(cmd)) {
282
+ return { ok: false, reason: "contains shell control syntax such as pipes, redirects, semicolons, backticks, or command substitution" };
283
+ }
284
+ if (!isLikelyCommand(cmd)) {
285
+ return { ok: false, reason: "does not look like a runnable command" };
286
+ }
287
+ return { ok: true };
288
+ }
289
+
218
290
  function sanitizeCommand(cmd: string): string | null {
219
- if (SHELL_INJECTION_PATTERN.test(cmd)) return null;
220
- if (!isLikelyCommand(cmd)) return null;
291
+ const validation = validateVerificationCommand(cmd);
292
+ if (!validation.ok) return null;
221
293
  return cmd;
222
294
  }
223
295
 
@@ -0,0 +1,47 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Host-owned verification verdict policy for auto-mode units.
3
+
4
+ import type { VerificationResult as VerificationGateResult } from "./types.js";
5
+
6
+ export type VerificationVerdictReason =
7
+ | "passed"
8
+ | "no-host-checks"
9
+ | "checks-failed";
10
+
11
+ export interface VerificationVerdict {
12
+ passed: boolean;
13
+ reason: VerificationVerdictReason;
14
+ retryable: boolean;
15
+ failureContext: string;
16
+ }
17
+
18
+ export function decideVerificationVerdict(
19
+ unitType: string,
20
+ result: VerificationGateResult,
21
+ ): VerificationVerdict {
22
+ if (unitType === "execute-task" && result.discoverySource === "none" && result.checks.length === 0) {
23
+ return {
24
+ passed: false,
25
+ reason: "no-host-checks",
26
+ retryable: false,
27
+ failureContext:
28
+ "No runnable host-owned verification command was discovered. Add project verification_commands or a runnable task-plan Verify command before completing this execute-task.",
29
+ };
30
+ }
31
+
32
+ if (!result.passed) {
33
+ return {
34
+ passed: false,
35
+ reason: "checks-failed",
36
+ retryable: true,
37
+ failureContext: "",
38
+ };
39
+ }
40
+
41
+ return {
42
+ passed: true,
43
+ reason: "passed",
44
+ retryable: false,
45
+ failureContext: "",
46
+ };
47
+ }
@@ -18,6 +18,7 @@ export interface WorkflowCapabilityOptions {
18
18
  unitType?: string;
19
19
  authMode?: "apiKey" | "oauth" | "externalCli" | "none";
20
20
  baseUrl?: string;
21
+ activeTools?: string[];
21
22
  }
22
23
 
23
24
  const MCP_WORKFLOW_TOOL_SURFACE = new Set([
@@ -383,6 +384,15 @@ function hasAskUserQuestionsTool(activeTools: string[]): boolean {
383
384
  });
384
385
  }
385
386
 
387
+ function hasRequiredTool(requiredTool: string, activeTools: string[]): boolean {
388
+ return activeTools.some((toolName) => {
389
+ if (toolName === requiredTool) return true;
390
+ if (!toolName.startsWith("mcp__")) return false;
391
+ const toolSeparator = toolName.indexOf("__", "mcp__".length);
392
+ return toolSeparator >= 0 && toolName.slice(toolSeparator + 2) === requiredTool;
393
+ });
394
+ }
395
+
386
396
  function workflowMcpStructuredQuestionsOptIn(env: NodeJS.ProcessEnv = process.env): boolean {
387
397
  const value = env.GSD_WORKFLOW_MCP_STRUCTURED_QUESTIONS;
388
398
  return value === "1" || value === "true";
@@ -423,8 +433,15 @@ export function getWorkflowTransportSupportError(
423
433
  return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: the GSD workflow MCP server is not configured or discoverable. Detected Claude Code model but no workflow MCP. Please run /gsd mcp init . from your project root. You can also configure GSD_WORKFLOW_MCP_COMMAND, build packages/mcp-server/dist/cli.js, or install gsd-mcp-server on PATH.`;
424
434
  }
425
435
 
426
- const missing = [...new Set(requiredTools)].filter((tool) => !MCP_WORKFLOW_TOOL_SURFACE.has(tool));
436
+ const uniqueRequired = [...new Set(requiredTools)];
437
+ const missing = (options.activeTools && options.activeTools.length > 0)
438
+ ? uniqueRequired.filter((tool) => !hasRequiredTool(tool, options.activeTools!))
439
+ : uniqueRequired.filter((tool) => !MCP_WORKFLOW_TOOL_SURFACE.has(tool));
427
440
  if (missing.length === 0) return null;
428
441
 
442
+ if (options.activeTools && options.activeTools.length > 0) {
443
+ return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: this unit requires ${missing.join(", ")}, but the active runtime toolset currently exposes only ${options.activeTools.slice().sort().join(", ")}.`;
444
+ }
445
+
429
446
  return `Provider ${providerLabel} cannot run ${surface}${unitLabel}: this unit requires ${missing.join(", ")}, but the workflow MCP transport currently exposes only ${Array.from(MCP_WORKFLOW_TOOL_SURFACE).sort().join(", ")}.`;
430
447
  }
@@ -195,11 +195,11 @@ export function renderSummaryContent(
195
195
 
196
196
  // ── Frontmatter (YAML list format, matches parseSummary() expectations) ──
197
197
  const keyFilesYaml = taskRow.key_files && taskRow.key_files.length > 0
198
- ? taskRow.key_files.map(f => ` - ${f}`).join("\n")
199
- : " - (none)";
198
+ ? `\n${taskRow.key_files.map(f => ` - ${f}`).join("\n")}`
199
+ : " []";
200
200
  const keyDecisionsYaml = taskRow.key_decisions && taskRow.key_decisions.length > 0
201
- ? taskRow.key_decisions.map(d => ` - ${d}`).join("\n")
202
- : " - (none)";
201
+ ? `\n${taskRow.key_decisions.map(d => ` - ${d}`).join("\n")}`
202
+ : " []";
203
203
 
204
204
  // Derive verification_result from evidence if available
205
205
  const evidenceList = evidence ?? [];
@@ -230,10 +230,8 @@ export function renderSummaryContent(
230
230
  id: ${taskRow.id}
231
231
  parent: ${sliceId}
232
232
  milestone: ${milestoneId}
233
- key_files:
234
- ${keyFilesYaml}
235
- key_decisions:
236
- ${keyDecisionsYaml}
233
+ key_files:${keyFilesYaml}
234
+ key_decisions:${keyDecisionsYaml}
237
235
  duration: ${taskRow.duration || ""}
238
236
  verification_result: ${verificationResult}
239
237
  completed_at: ${taskRow.completed_at || ""}
@@ -23,6 +23,7 @@ import { join } from "node:path";
23
23
 
24
24
  import type { AutoSession } from "./auto/session.js";
25
25
  import { debugLog } from "./debug-logger.js";
26
+ import { logWarning } from "./workflow-logger.js";
26
27
  import { emitJournalEvent } from "./journal.js";
27
28
  import { emitWorktreeCreated, emitWorktreeMerged } from "./worktree-telemetry.js";
28
29
  import {
@@ -76,6 +77,13 @@ import {
76
77
  teardownAutoWorktree,
77
78
  } from "./auto-worktree.js";
78
79
 
80
+ const recentWorktreeMergeFailures = new Map<string, number>();
81
+ const MERGE_FAILURE_DEDUPE_MS = 60_000;
82
+
83
+ export function resetRecentWorktreeMergeFailuresForTest(): void {
84
+ recentWorktreeMergeFailures.clear();
85
+ }
86
+
79
87
  // ─── Types ───────────────────────────────────────────────────────────────
80
88
 
81
89
  export interface NotifyCtx {
@@ -525,7 +533,7 @@ export function _enterMilestoneCore(
525
533
 
526
534
  // Phase B: claim a milestone lease before any worktree mutation. Two
527
535
  // workers cannot enter the same milestone concurrently. Best-effort:
528
- // skip if no worker registered (single-worker fallback) or DB
536
+ // warn if no worker registered (single-worker fallback) or skip if DB
529
537
  // unavailable; reuse existing lease if we already hold it on this
530
538
  // milestone (re-entry within the same session).
531
539
  if (s.workerId) {
@@ -618,6 +626,11 @@ export function _enterMilestoneCore(
618
626
  });
619
627
  }
620
628
  }
629
+ } else {
630
+ logWarning(
631
+ "worktree",
632
+ `enterMilestone(${milestoneId}) ran before auto worker registration; milestone lease was not claimed.`,
633
+ );
621
634
  }
622
635
 
623
636
  // Resolve the project root for worktree operations via shared helper.
@@ -836,6 +849,32 @@ function rebuildGitService(
836
849
  s.gitService = deps.gitServiceFactory(s.basePath);
837
850
  }
838
851
 
852
+ function emitWorktreeMergeFailedOnce(
853
+ basePath: string,
854
+ milestoneId: string,
855
+ err: unknown,
856
+ ): void {
857
+ const msg = err instanceof Error ? err.message : String(err);
858
+ const errorCategory = err instanceof Error ? err.name : "Error";
859
+ const now = Date.now();
860
+ const key = `${basePath}\0${milestoneId}\0${errorCategory}`;
861
+ const previous = recentWorktreeMergeFailures.get(key);
862
+ if (previous && now - previous < MERGE_FAILURE_DEDUPE_MS) return;
863
+ for (const [candidate, ts] of recentWorktreeMergeFailures) {
864
+ if (now - ts >= MERGE_FAILURE_DEDUPE_MS) {
865
+ recentWorktreeMergeFailures.delete(candidate);
866
+ }
867
+ }
868
+ emitJournalEvent(basePath, {
869
+ ts: new Date().toISOString(),
870
+ flowId: randomUUID(),
871
+ seq: 0,
872
+ eventType: "worktree-merge-failed",
873
+ data: { milestoneId, error: msg },
874
+ });
875
+ recentWorktreeMergeFailures.set(key, now);
876
+ }
877
+
839
878
  // ─── Session-less merge entry (ADR-016 phase 2 / A1) ─────────────────────
840
879
 
841
880
  /**
@@ -985,13 +1024,7 @@ function _mergeWorktreeModeImpl(
985
1024
  error: msg,
986
1025
  fallback: "chdir-to-project-root",
987
1026
  });
988
- emitJournalEvent(originalBasePath || worktreeBasePath, {
989
- ts: new Date().toISOString(),
990
- flowId: randomUUID(),
991
- seq: 0,
992
- eventType: "worktree-merge-failed",
993
- data: { milestoneId, error: msg },
994
- });
1027
+ emitWorktreeMergeFailedOnce(originalBasePath || worktreeBasePath, milestoneId, err);
995
1028
  // Surface a clear, actionable error. Worktree and milestone branch
996
1029
  // are intentionally preserved — nothing has been deleted. User can
997
1030
  // retry /gsd dispatch complete-milestone or merge manually once the
@@ -1702,16 +1735,34 @@ export class WorktreeLifecycle {
1702
1735
  }
1703
1736
 
1704
1737
  /**
1705
- * Restore `s.basePath` to `s.originalBasePath` and rebuild `s.gitService`.
1706
- * No-op when `originalBasePath` is empty (fresh sessions).
1738
+ * Restore `s.basePath` to `s.originalBasePath`, chdir process cwd, and
1739
+ * rebuild `s.gitService`. No-op when `originalBasePath` is empty (fresh
1740
+ * sessions).
1707
1741
  *
1708
1742
  * Used by error/cleanup paths that need the session to behave as if the
1709
1743
  * worktree was never entered. Does NOT teardown the worktree directory —
1710
1744
  * callers that need teardown go through `exitMilestone({ merge: false })`.
1745
+ *
1746
+ * ADR-016 phase 3 (#5693): chdir lives inside the verb so callers do not
1747
+ * pair `restoreToProjectRoot()` with a redundant `process.chdir`. The
1748
+ * chdir runs BEFORE the throwable work (`rebuildGitService`, cache
1749
+ * invalidation) so that cleanup-path cwd is restored even if the
1750
+ * downstream rebuild throws. The chdir itself is best-effort; failure is
1751
+ * logged via debugLog and swallowed.
1711
1752
  */
1712
1753
  restoreToProjectRoot(): void {
1713
1754
  if (!this.s.originalBasePath) return;
1714
1755
  this.s.basePath = this.s.originalBasePath;
1756
+ try {
1757
+ process.chdir(this.s.basePath);
1758
+ } catch (err) {
1759
+ debugLog("WorktreeLifecycle", {
1760
+ action: "restoreToProjectRoot",
1761
+ result: "chdir-failed",
1762
+ basePath: this.s.basePath,
1763
+ error: err instanceof Error ? err.message : String(err),
1764
+ });
1765
+ }
1715
1766
  rebuildGitService(this.s, this.deps);
1716
1767
  invalidateAllCaches();
1717
1768
  }
@@ -618,7 +618,7 @@ export function removeWorktree(
618
618
  try {
619
619
  rmSync(nestedGitPath, { recursive: true, force: true });
620
620
  logWarning("reconcile",
621
- `Removed nested .git directory from scaffolded project to prevent data loss (#2616)`,
621
+ `Removed nested .git directory from scaffolded project to prevent data loss`,
622
622
  { worktree: name, nestedRepo: nestedDir },
623
623
  );
624
624
  } catch {