gsd-pi 2.81.0-dev.72a81bdf3 → 2.82.0-dev.20138ae42

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 (463) hide show
  1. package/README.md +50 -31
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/GSD-WORKFLOW.md +10 -1
  4. package/dist/resources/extensions/browser-tools/tools/screenshot.js +1 -0
  5. package/dist/resources/extensions/browser-tools/tools/zoom.js +1 -0
  6. package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
  7. package/dist/resources/extensions/cmux/index.js +5 -0
  8. package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
  9. package/dist/resources/extensions/gsd/auto/loop.js +5 -5
  10. package/dist/resources/extensions/gsd/auto/orchestrator.js +124 -6
  11. package/dist/resources/extensions/gsd/auto/phases.js +30 -1
  12. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  13. package/dist/resources/extensions/gsd/auto-dashboard.js +66 -1
  14. package/dist/resources/extensions/gsd/auto-dispatch.js +13 -6
  15. package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
  16. package/dist/resources/extensions/gsd/auto-post-unit.js +233 -127
  17. package/dist/resources/extensions/gsd/auto-prompts.js +13 -5
  18. package/dist/resources/extensions/gsd/auto-recovery.js +31 -1
  19. package/dist/resources/extensions/gsd/auto-start.js +85 -12
  20. package/dist/resources/extensions/gsd/auto-verification.js +28 -22
  21. package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
  22. package/dist/resources/extensions/gsd/auto.js +158 -55
  23. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +25 -6
  24. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +9 -8
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +9 -2
  26. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
  27. package/dist/resources/extensions/gsd/bootstrap/system-context.js +55 -12
  28. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +16 -2
  29. package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
  30. package/dist/resources/extensions/gsd/commands/catalog.js +4 -1
  31. package/dist/resources/extensions/gsd/commands/handlers/core.js +38 -1
  32. package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
  33. package/dist/resources/extensions/gsd/commands-handlers.js +15 -2
  34. package/dist/resources/extensions/gsd/context-store.js +112 -0
  35. package/dist/resources/extensions/gsd/crash-recovery.js +31 -5
  36. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  37. package/dist/resources/extensions/gsd/db-writer.js +150 -84
  38. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -2
  39. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  40. package/dist/resources/extensions/gsd/doctor-git-checks.js +41 -6
  41. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  42. package/dist/resources/extensions/gsd/doctor.js +2 -28
  43. package/dist/resources/extensions/gsd/export-html.js +27 -425
  44. package/dist/resources/extensions/gsd/git-service.js +39 -1
  45. package/dist/resources/extensions/gsd/gsd-db.js +1 -0
  46. package/dist/resources/extensions/gsd/guided-flow.js +93 -111
  47. package/dist/resources/extensions/gsd/guided-unit-context.js +23 -0
  48. package/dist/resources/extensions/gsd/knowledge-backfill.js +144 -0
  49. package/dist/resources/extensions/gsd/knowledge-capture.js +136 -0
  50. package/dist/resources/extensions/gsd/knowledge-parser.js +154 -0
  51. package/dist/resources/extensions/gsd/knowledge-projection.js +210 -0
  52. package/dist/resources/extensions/gsd/markdown-renderer.js +6 -1
  53. package/dist/resources/extensions/gsd/md-importer.js +1 -1
  54. package/dist/resources/extensions/gsd/memory-backfill.js +73 -17
  55. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +222 -0
  56. package/dist/resources/extensions/gsd/migrate/command.js +5 -0
  57. package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
  58. package/dist/resources/extensions/gsd/migrate/preview.js +9 -0
  59. package/dist/resources/extensions/gsd/migrate/transformer.js +51 -4
  60. package/dist/resources/extensions/gsd/migrate/writer.js +11 -1
  61. package/dist/resources/extensions/gsd/migration-auto-check.js +12 -17
  62. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  63. package/dist/resources/extensions/gsd/native-git-bridge.js +48 -12
  64. package/dist/resources/extensions/gsd/pending-auto-start.js +52 -0
  65. package/dist/resources/extensions/gsd/post-execution-checks.js +73 -2
  66. package/dist/resources/extensions/gsd/pre-execution-checks.js +28 -1
  67. package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
  68. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  69. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  70. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  71. package/dist/resources/extensions/gsd/prompts/discuss.md +9 -9
  72. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  73. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  74. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  75. package/dist/resources/extensions/gsd/prompts/queue.md +4 -4
  76. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  77. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  78. package/dist/resources/extensions/gsd/prompts/system.md +2 -2
  79. package/dist/resources/extensions/gsd/provider-switch-observer.js +146 -0
  80. package/dist/resources/extensions/gsd/smart-entry-routing.js +36 -0
  81. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  82. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +9 -14
  83. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +19 -24
  84. package/dist/resources/extensions/gsd/status-guards.js +4 -0
  85. package/dist/resources/extensions/gsd/templates/knowledge.md +2 -2
  86. package/dist/resources/extensions/gsd/templates/plan.md +8 -5
  87. package/dist/resources/extensions/gsd/templates/task-plan.md +4 -2
  88. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
  89. package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
  90. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  91. package/dist/resources/extensions/gsd/tools/plan-slice.js +89 -14
  92. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +119 -0
  93. package/dist/resources/extensions/gsd/unit-context-manifest.js +32 -10
  94. package/dist/resources/extensions/gsd/validation.js +23 -1
  95. package/dist/resources/extensions/gsd/verification-gate.js +68 -7
  96. package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
  97. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  98. package/dist/resources/extensions/gsd/worktree-lifecycle.js +54 -10
  99. package/dist/resources/extensions/shared/html-shell.js +388 -0
  100. package/dist/resources/extensions/subagent/index.js +448 -78
  101. package/dist/resources/extensions/subagent/launch.js +77 -0
  102. package/dist/resources/extensions/subagent/run-store.js +148 -0
  103. package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
  104. package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
  105. package/dist/resources/extensions/visual-brief/index.js +5 -0
  106. package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
  107. package/dist/resources/extensions/visual-brief/prompts.js +140 -0
  108. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  109. package/dist/web/standalone/.next/BUILD_ID +1 -1
  110. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  111. package/dist/web/standalone/.next/build-manifest.json +3 -3
  112. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  113. package/dist/web/standalone/.next/react-loadable-manifest.json +3 -3
  114. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  124. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  128. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  131. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  134. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  135. package/dist/web/standalone/.next/server/app/index.html +1 -1
  136. package/dist/web/standalone/.next/server/app/index.rsc +4 -7
  137. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
  139. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  141. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  142. package/dist/web/standalone/.next/server/app/page.js +2 -2
  143. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  144. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  146. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  147. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  151. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  152. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  153. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  154. package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
  155. package/dist/web/standalone/.next/static/chunks/{8359.e059d86b255fce1c.js → 8359.7eb3bb8f8ecf4c01.js} +2 -2
  156. package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
  157. package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-9a4db269f9ed63ad.js} +1 -1
  158. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  159. package/package.json +6 -5
  160. package/packages/contracts/dist/rpc.test.js +7 -0
  161. package/packages/contracts/dist/rpc.test.js.map +1 -1
  162. package/packages/contracts/dist/workflow.d.ts +21 -0
  163. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  164. package/packages/contracts/dist/workflow.js +24 -0
  165. package/packages/contracts/dist/workflow.js.map +1 -1
  166. package/packages/contracts/src/rpc.test.ts +8 -0
  167. package/packages/contracts/src/workflow.ts +24 -0
  168. package/packages/daemon/package.json +2 -2
  169. package/packages/mcp-server/README.md +14 -3
  170. package/packages/mcp-server/dist/workflow-tools.d.ts +0 -3
  171. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  172. package/packages/mcp-server/dist/workflow-tools.js +80 -0
  173. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  174. package/packages/mcp-server/package.json +2 -2
  175. package/packages/mcp-server/src/workflow-tools-parity.test.ts +244 -0
  176. package/packages/mcp-server/src/workflow-tools.test.ts +23 -1
  177. package/packages/mcp-server/src/workflow-tools.ts +168 -0
  178. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  179. package/packages/native/package.json +1 -1
  180. package/packages/native/tsconfig.json +2 -1
  181. package/packages/native/tsconfig.tsbuildinfo +1 -1
  182. package/packages/pi-agent-core/package.json +1 -1
  183. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  184. package/packages/pi-ai/dist/index.d.ts +2 -2
  185. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  186. package/packages/pi-ai/dist/index.js +1 -1
  187. package/packages/pi-ai/dist/index.js.map +1 -1
  188. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  189. package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
  190. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  191. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
  192. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
  193. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
  194. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
  195. package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
  196. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  197. package/packages/pi-ai/dist/providers/simple-options.js +5 -6
  198. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  199. package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
  200. package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
  201. package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
  202. package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
  203. package/packages/pi-ai/dist/providers/transform-messages.d.ts +11 -0
  204. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  205. package/packages/pi-ai/dist/providers/transform-messages.js +20 -0
  206. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  207. package/packages/pi-ai/package.json +1 -1
  208. package/packages/pi-ai/src/index.ts +7 -2
  209. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
  210. package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
  211. package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
  212. package/packages/pi-ai/src/providers/simple-options.ts +5 -6
  213. package/packages/pi-ai/src/providers/transform-messages.ts +24 -0
  214. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  215. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
  216. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
  217. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
  218. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
  219. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
  220. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  221. package/packages/pi-coding-agent/dist/core/system-prompt.js +4 -4
  222. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  223. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  224. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +24 -6
  225. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  226. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts +2 -0
  227. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.d.ts.map +1 -0
  228. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js +17 -0
  229. package/packages/pi-coding-agent/dist/tests/system-prompt-file-safety.test.js.map +1 -0
  230. package/packages/pi-coding-agent/package.json +1 -1
  231. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  232. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  233. package/packages/pi-coding-agent/src/core/system-prompt.ts +4 -4
  234. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +23 -7
  235. package/packages/pi-coding-agent/src/tests/system-prompt-file-safety.test.ts +22 -0
  236. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  237. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  238. package/packages/pi-tui/dist/tui.js +5 -0
  239. package/packages/pi-tui/dist/tui.js.map +1 -1
  240. package/packages/pi-tui/package.json +1 -1
  241. package/packages/pi-tui/src/tui.ts +6 -0
  242. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  243. package/packages/rpc-client/package.json +1 -1
  244. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  245. package/pkg/package.json +1 -1
  246. package/src/resources/GSD-WORKFLOW.md +10 -1
  247. package/src/resources/extensions/browser-tools/tools/screenshot.ts +1 -0
  248. package/src/resources/extensions/browser-tools/tools/zoom.ts +1 -0
  249. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  250. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  251. package/src/resources/extensions/cmux/index.ts +6 -0
  252. package/src/resources/extensions/gsd/auto/contracts.ts +59 -16
  253. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  254. package/src/resources/extensions/gsd/auto/loop.ts +8 -5
  255. package/src/resources/extensions/gsd/auto/orchestrator.ts +129 -6
  256. package/src/resources/extensions/gsd/auto/phases.ts +36 -1
  257. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
  258. package/src/resources/extensions/gsd/auto-dashboard.ts +72 -1
  259. package/src/resources/extensions/gsd/auto-dispatch.ts +14 -6
  260. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  261. package/src/resources/extensions/gsd/auto-post-unit.ts +266 -139
  262. package/src/resources/extensions/gsd/auto-prompts.ts +13 -5
  263. package/src/resources/extensions/gsd/auto-recovery.ts +29 -0
  264. package/src/resources/extensions/gsd/auto-start.ts +92 -9
  265. package/src/resources/extensions/gsd/auto-verification.ts +36 -34
  266. package/src/resources/extensions/gsd/auto-worktree.ts +119 -1
  267. package/src/resources/extensions/gsd/auto.ts +167 -53
  268. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +33 -6
  269. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +9 -8
  270. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +10 -2
  271. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
  272. package/src/resources/extensions/gsd/bootstrap/system-context.ts +58 -15
  273. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +19 -3
  274. package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
  275. package/src/resources/extensions/gsd/commands/catalog.ts +4 -1
  276. package/src/resources/extensions/gsd/commands/handlers/core.ts +41 -1
  277. package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
  278. package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
  279. package/src/resources/extensions/gsd/context-store.ts +120 -1
  280. package/src/resources/extensions/gsd/crash-recovery.ts +30 -4
  281. package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
  282. package/src/resources/extensions/gsd/db-writer.ts +167 -84
  283. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -2
  284. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  285. package/src/resources/extensions/gsd/doctor-git-checks.ts +44 -6
  286. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  287. package/src/resources/extensions/gsd/doctor-types.ts +2 -0
  288. package/src/resources/extensions/gsd/doctor.ts +2 -27
  289. package/src/resources/extensions/gsd/export-html.ts +27 -427
  290. package/src/resources/extensions/gsd/git-service.ts +45 -1
  291. package/src/resources/extensions/gsd/gsd-db.ts +3 -0
  292. package/src/resources/extensions/gsd/guided-flow.ts +126 -128
  293. package/src/resources/extensions/gsd/guided-unit-context.ts +30 -0
  294. package/src/resources/extensions/gsd/knowledge-backfill.ts +164 -0
  295. package/src/resources/extensions/gsd/knowledge-capture.ts +160 -0
  296. package/src/resources/extensions/gsd/knowledge-parser.ts +174 -0
  297. package/src/resources/extensions/gsd/knowledge-projection.ts +241 -0
  298. package/src/resources/extensions/gsd/markdown-renderer.ts +6 -1
  299. package/src/resources/extensions/gsd/md-importer.ts +1 -1
  300. package/src/resources/extensions/gsd/memory-backfill.ts +89 -17
  301. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +277 -0
  302. package/src/resources/extensions/gsd/migrate/command.ts +5 -0
  303. package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
  304. package/src/resources/extensions/gsd/migrate/preview.ts +10 -0
  305. package/src/resources/extensions/gsd/migrate/transformer.ts +58 -4
  306. package/src/resources/extensions/gsd/migrate/writer.ts +14 -1
  307. package/src/resources/extensions/gsd/migration-auto-check.ts +15 -23
  308. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  309. package/src/resources/extensions/gsd/native-git-bridge.ts +54 -12
  310. package/src/resources/extensions/gsd/pending-auto-start.ts +79 -0
  311. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -2
  312. package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -1
  313. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  314. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  315. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  316. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -8
  317. package/src/resources/extensions/gsd/prompts/discuss.md +9 -9
  318. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +4 -4
  319. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +3 -3
  320. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -4
  321. package/src/resources/extensions/gsd/prompts/queue.md +4 -4
  322. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  323. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  324. package/src/resources/extensions/gsd/prompts/system.md +2 -2
  325. package/src/resources/extensions/gsd/provider-switch-observer.ts +185 -0
  326. package/src/resources/extensions/gsd/smart-entry-routing.ts +77 -0
  327. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  328. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +12 -15
  329. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +17 -25
  330. package/src/resources/extensions/gsd/status-guards.ts +5 -0
  331. package/src/resources/extensions/gsd/templates/knowledge.md +2 -2
  332. package/src/resources/extensions/gsd/templates/plan.md +8 -5
  333. package/src/resources/extensions/gsd/templates/task-plan.md +4 -2
  334. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +71 -0
  335. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  336. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +129 -0
  337. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +487 -4
  338. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +12 -11
  339. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +53 -2
  340. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +12 -1
  341. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +15 -1
  342. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +4 -4
  343. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  344. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  345. package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
  346. package/src/resources/extensions/gsd/tests/browser-tools-compatibility-declarations.test.ts +62 -0
  347. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
  348. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +11 -2
  349. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
  350. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
  351. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +5 -9
  352. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  353. package/src/resources/extensions/gsd/tests/context-store-decisions-from-memories.test.ts +312 -0
  354. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +43 -2
  355. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +208 -0
  356. package/src/resources/extensions/gsd/tests/db-writer.test.ts +13 -8
  357. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +453 -0
  358. package/src/resources/extensions/gsd/tests/decisions-stop-table-writes.test.ts +348 -0
  359. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +59 -2
  360. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +39 -0
  361. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
  362. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +38 -0
  363. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  364. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +8 -4
  365. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +11 -7
  366. package/src/resources/extensions/gsd/tests/guided-discuss-project-prompt-rendering.test.ts +2 -0
  367. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +106 -0
  368. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +59 -11
  369. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  370. package/src/resources/extensions/gsd/tests/guided-tool-contract.test.ts +65 -0
  371. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +7 -7
  372. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  373. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  374. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  375. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +44 -0
  376. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  377. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +103 -1
  378. package/src/resources/extensions/gsd/tests/integration/integration-lifecycle.test.ts +13 -5
  379. package/src/resources/extensions/gsd/tests/integration/migrate-command.test.ts +48 -3
  380. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  381. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +323 -0
  382. package/src/resources/extensions/gsd/tests/knowledge-capture.test.ts +242 -0
  383. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -2
  384. package/src/resources/extensions/gsd/tests/load-knowledge-block-rules-only.test.ts +209 -0
  385. package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +316 -0
  386. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +5 -1
  387. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
  388. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +6 -1
  389. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +26 -18
  390. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +63 -2
  391. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
  392. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
  393. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +29 -5
  394. package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +157 -0
  395. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
  396. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
  397. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +225 -1
  398. package/src/resources/extensions/gsd/tests/plan-task.test.ts +17 -0
  399. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  400. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +86 -0
  401. package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
  402. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +53 -0
  403. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -0
  404. package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
  405. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +20 -1
  406. package/src/resources/extensions/gsd/tests/provider-switch-observer.test.ts +252 -0
  407. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +46 -2
  408. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +16 -4
  409. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
  410. package/src/resources/extensions/gsd/tests/smart-entry-routing.test.ts +113 -0
  411. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +53 -2
  412. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -0
  413. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +119 -23
  414. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  415. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  416. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +86 -7
  417. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +110 -1
  418. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
  419. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +1 -1
  420. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
  421. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +1 -1
  422. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
  423. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
  424. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +25 -0
  425. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +54 -0
  426. package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
  427. package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
  428. package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
  429. package/src/resources/extensions/gsd/tools/plan-slice.ts +98 -12
  430. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +135 -0
  431. package/src/resources/extensions/gsd/types.ts +1 -1
  432. package/src/resources/extensions/gsd/unit-context-manifest.ts +47 -11
  433. package/src/resources/extensions/gsd/validation.ts +23 -1
  434. package/src/resources/extensions/gsd/verification-gate.ts +78 -6
  435. package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
  436. package/src/resources/extensions/gsd/workflow-logger.ts +4 -0
  437. package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
  438. package/src/resources/extensions/gsd/worktree-lifecycle.ts +61 -10
  439. package/src/resources/extensions/shared/html-shell.ts +412 -0
  440. package/src/resources/extensions/subagent/index.ts +567 -103
  441. package/src/resources/extensions/subagent/launch.ts +131 -0
  442. package/src/resources/extensions/subagent/run-store.ts +218 -0
  443. package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
  444. package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
  445. package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
  446. package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
  447. package/src/resources/extensions/visual-brief/index.ts +8 -0
  448. package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
  449. package/src/resources/extensions/visual-brief/prompts.ts +183 -0
  450. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
  451. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  452. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  453. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
  454. package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
  455. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  456. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  457. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  458. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  459. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  460. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  461. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  462. /package/dist/web/standalone/.next/static/{rIkMv4YSNlfSeqmGqWVns → xRy4LqKSNKdT7y6ATYyEl}/_buildManifest.js +0 -0
  463. /package/dist/web/standalone/.next/static/{rIkMv4YSNlfSeqmGqWVns → xRy4LqKSNKdT7y6ATYyEl}/_ssgManifest.js +0 -0
@@ -44,7 +44,7 @@ import { readSessionLockData, isSessionLockProcessAlive } from "./session-lock.j
44
44
  import { nativeAddAll, nativeCommit, nativeHasCommittedHead, nativeIsRepo, nativeInit } from "./native-git-bridge.js";
45
45
  import { isInheritedRepo } from "./repo-identity.js";
46
46
  import { ensureGitignore, ensurePreferences, untrackRuntimeFiles } from "./gitignore.js";
47
- import { loadEffectiveGSDPreferences } from "./preferences.js";
47
+ import { getIsolationMode, loadEffectiveGSDPreferences } from "./preferences.js";
48
48
  import { resolveUokFlags } from "./uok/flags.js";
49
49
  import { ensurePlanV2Graph, isMissingFinalizedContextResult } from "./uok/plan-v2.js";
50
50
  import { detectProjectState, hasGsdBootstrapArtifacts } from "./detection.js";
@@ -69,8 +69,24 @@ import {
69
69
  formatPriorContextBrief,
70
70
  } from "./preparation.js";
71
71
  import { verifyExpectedArtifact } from "./auto-recovery.js";
72
- import { createWorkspace, scopeMilestone, type MilestoneScope } from "./workspace.js";
72
+ import type { MilestoneScope } from "./workspace.js";
73
73
  import { getPendingGate, extractDepthVerificationMilestoneId } from "./bootstrap/write-gate.js";
74
+ import {
75
+ _getPendingAutoStart,
76
+ clearPendingAutoStart,
77
+ deletePendingAutoStart,
78
+ getDiscussionMilestoneId,
79
+ hasPendingAutoStart,
80
+ setPendingAutoStart,
81
+ } from "./pending-auto-start.js";
82
+ import { clearGuidedUnitContext, setGuidedUnitContext } from "./guided-unit-context.js";
83
+
84
+ export {
85
+ _getPendingAutoStart,
86
+ clearPendingAutoStart,
87
+ getDiscussionMilestoneId,
88
+ setPendingAutoStart,
89
+ } from "./pending-auto-start.js";
74
90
 
75
91
  export function shouldSkipGitBootstrapAfterInit(result: { gitEnabled?: boolean }): boolean {
76
92
  return result.gitEnabled === false;
@@ -92,6 +108,12 @@ import { deleteRuntimeKv } from "./db/runtime-kv.js";
92
108
  import { PAUSED_SESSION_KV_KEY } from "./interrupted-session.js";
93
109
  import { buildWorkflowDispatchContent } from "./workflow-protocol.js";
94
110
  import { isFullGsdToolSurfaceRequested, restoreGsdWorkflowTools, scopeGsdWorkflowToolsForDispatch } from "./bootstrap/register-hooks.js";
111
+ import {
112
+ resolveActiveTaskChoiceRoute,
113
+ type ActiveTaskChoice,
114
+ } from "./smart-entry-routing.js";
115
+
116
+ export { resolveGuidedExecuteLaunchMode } from "./smart-entry-routing.js";
95
117
 
96
118
  type AutoStartOptions = Parameters<typeof startAutoDetached>[4];
97
119
  type AutoStartLauncher = typeof startAutoDetached;
@@ -228,26 +250,6 @@ function buildDocsCommitInstruction(_message: string): string {
228
250
 
229
251
  // ─── Auto-start after discuss ─────────────────────────────────────────────────
230
252
 
231
- /** Pending auto-start context, keyed by basePath for session isolation (#2985). */
232
- interface PendingAutoStartEntry {
233
- ctx: ExtensionCommandContext;
234
- pi: ExtensionAPI;
235
- basePath: string;
236
- milestoneId: string; // the milestone being discussed
237
- step?: boolean; // preserve step mode through discuss → auto transition
238
- createdAt: number; // timestamp for staleness detection (#3274)
239
- // #4573: counter for how many times the LLM emitted the ready phrase
240
- // without writing the required artifacts. Cleared on entry delete/recreate.
241
- readyRejectCount?: number;
242
- // C1: scope is pinned at reservation time so path resolution is immune to
243
- // cwd-drift between discuss and checkAutoStartAfterDiscuss.
244
- // TODO(C3): basePath becomes redundant once all consumers migrate to scope.
245
- scope: MilestoneScope;
246
- // H1: retry counter for Gate 1b plan-blocked recovery. Capped at
247
- // MAX_PLAN_BLOCKED_RECOVERIES to prevent infinite recovery loops (#5012).
248
- planBlockedRecoveryCount: number;
249
- }
250
-
251
253
  interface PendingDeepProjectSetupEntry {
252
254
  ctx: ExtensionCommandContext;
253
255
  pi: ExtensionAPI;
@@ -273,7 +275,6 @@ const MAX_PLAN_BLOCKED_RECOVERIES = 3;
273
275
  // suffix) with optional trailing punctuation.
274
276
  const READY_PHRASE_RE = /\bMilestone\s+M\d{3}[A-Z0-9-]*\s+ready\.?/i;
275
277
 
276
- const pendingAutoStartMap = new Map<string, PendingAutoStartEntry>();
277
278
  const pendingDeepProjectSetupMap = new Map<string, PendingDeepProjectSetupEntry>();
278
279
  const USER_DRIVEN_DEEP_SETUP_UNITS = new Set([
279
280
  "discuss-project",
@@ -300,17 +301,6 @@ This stage is running inside the foreground \`/gsd new-project --deep\` intervie
300
301
  - Do NOT call \`ask_user_questions\`, \`AskUserQuestion\`, or ToolSearch to discover user-input tools.
301
302
  - Ask one focused round, then stop and wait for the user's normal chat response.`;
302
303
 
303
- /**
304
- * Backward-compat bridge: returns a mutable reference to the entry matching
305
- * basePath, or the sole entry when only one session exists.
306
- * Exported for testing — internal use only in production code.
307
- */
308
- export function _getPendingAutoStart(basePath?: string): PendingAutoStartEntry | null {
309
- if (basePath) return pendingAutoStartMap.get(basePath) ?? null;
310
- if (pendingAutoStartMap.size === 1) return pendingAutoStartMap.values().next().value!;
311
- return null;
312
- }
313
-
314
304
  function hasNestedFileOrSymlink(dir: string): boolean {
315
305
  for (const entry of readdirSync(dir, { withFileTypes: true })) {
316
306
  if (entry.isFile() || entry.isSymbolicLink()) return true;
@@ -344,29 +334,6 @@ function clearEmptyLegacyDeepSetupPseudoMilestones(basePath: string, entries: st
344
334
  return remaining;
345
335
  }
346
336
 
347
- /**
348
- * Store pending auto-start state for a project.
349
- * Exported for testing (#2985).
350
- */
351
- export function setPendingAutoStart(basePath: string, entry: { basePath: string; milestoneId: string; ctx?: ExtensionCommandContext; pi?: ExtensionAPI; step?: boolean; createdAt?: number }): void {
352
- const ws = createWorkspace(entry.basePath);
353
- const scope = scopeMilestone(ws, entry.milestoneId);
354
- pendingAutoStartMap.set(basePath, { createdAt: Date.now(), planBlockedRecoveryCount: 0, ...entry, scope } as PendingAutoStartEntry);
355
- }
356
-
357
- /**
358
- * Clear pending auto-start state.
359
- * If basePath is given, clears only that project. Otherwise clears all.
360
- * Exported for testing (#2985).
361
- */
362
- export function clearPendingAutoStart(basePath?: string): void {
363
- if (basePath) {
364
- pendingAutoStartMap.delete(basePath);
365
- } else {
366
- pendingAutoStartMap.clear();
367
- }
368
- }
369
-
370
337
  export function clearPendingDeepProjectSetup(basePath?: string): void {
371
338
  if (basePath) {
372
339
  pendingDeepProjectSetupMap.delete(basePath);
@@ -375,23 +342,6 @@ export function clearPendingDeepProjectSetup(basePath?: string): void {
375
342
  }
376
343
  }
377
344
 
378
- /**
379
- * Returns the milestoneId being discussed for the given project.
380
- * When basePath is omitted and only one session is active, returns that
381
- * session's milestoneId for backward compatibility. Returns null when
382
- * multiple sessions exist and basePath is not specified (#2985 Bug 4).
383
- */
384
- export function getDiscussionMilestoneId(basePath?: string): string | null {
385
- if (basePath) {
386
- return pendingAutoStartMap.get(basePath)?.milestoneId ?? null;
387
- }
388
- // Backward compat: return the sole entry's milestoneId, or null if ambiguous
389
- if (pendingAutoStartMap.size === 1) {
390
- return pendingAutoStartMap.values().next().value!.milestoneId;
391
- }
392
- return null;
393
- }
394
-
395
345
  function _getPendingDeepProjectSetup(basePath?: string): PendingDeepProjectSetupEntry | null {
396
346
  if (basePath) return pendingDeepProjectSetupMap.get(basePath) ?? null;
397
347
  if (pendingDeepProjectSetupMap.size === 1) return pendingDeepProjectSetupMap.values().next().value!;
@@ -544,13 +494,14 @@ async function dispatchNextDeepProjectSetupStage(entry: PendingDeepProjectSetupE
544
494
  "gsd-run",
545
495
  entry.ctx,
546
496
  result.unitType,
497
+ { basePath: entry.basePath },
547
498
  );
548
499
  return true;
549
500
  }
550
501
 
551
502
  /** Called from agent_end to check if auto-mode should start after discuss */
552
- export function checkAutoStartAfterDiscuss(): boolean {
553
- const entry = _getPendingAutoStart();
503
+ export function checkAutoStartAfterDiscuss(lookupBasePath?: string): boolean {
504
+ const entry = _getPendingAutoStart(lookupBasePath);
554
505
  if (!entry) return false;
555
506
 
556
507
  const { ctx, pi, basePath, milestoneId, step } = entry;
@@ -735,7 +686,7 @@ export function checkAutoStartAfterDiscuss(): boolean {
735
686
  }
736
687
  }
737
688
 
738
- pendingAutoStartMap.delete(basePath);
689
+ deletePendingAutoStart(basePath);
739
690
  ctx.ui.notify(`Milestone ${milestoneId} ready.`, "success");
740
691
  scheduleAutoStartAfterIdle(ctx, pi, basePath, false, { step });
741
692
  return true;
@@ -806,8 +757,8 @@ function hasToolUse(msg: any): boolean {
806
757
  * Returns true when a nudge (or give-up) was emitted, signaling the caller to
807
758
  * skip `resolveAgentEnd`.
808
759
  */
809
- export function maybeHandleReadyPhraseWithoutFiles(event: { messages: any[] }): boolean {
810
- const entry = _getPendingAutoStart();
760
+ export function maybeHandleReadyPhraseWithoutFiles(event: { messages: any[] }, lookupBasePath?: string): boolean {
761
+ const entry = _getPendingAutoStart(lookupBasePath);
811
762
  if (!entry) return false;
812
763
  const { ctx, pi, basePath, milestoneId } = entry;
813
764
 
@@ -854,7 +805,7 @@ export function maybeHandleReadyPhraseWithoutFiles(event: { messages: any[] }):
854
805
  if (entry.readyRejectCount > MAX_READY_REJECTS) {
855
806
  // Give up: clear state and tell the user to re-run /gsd. Avoids an
856
807
  // infinite nudge loop when the LLM never produces the writes.
857
- pendingAutoStartMap.delete(basePath);
808
+ deletePendingAutoStart(basePath);
858
809
  ctx.ui.notify(
859
810
  `Milestone ${milestoneId}: LLM signaled "ready" ${entry.readyRejectCount} times without writing files. ` +
860
811
  `Stopping auto-nudge. Run /gsd to try again.`,
@@ -935,10 +886,11 @@ export function resetEmptyTurnCounter(basePath?: string): void {
935
886
  export function maybeHandleEmptyIntentTurn(
936
887
  event: { messages: any[] },
937
888
  isAuto: boolean,
889
+ lookupBasePath?: string,
938
890
  ): boolean {
939
891
  // Gate: only fire when there is system-driven work in flight. Interactive
940
892
  // /gsd discuss (user-driven) produces legitimate text-only turns.
941
- if (!isAuto && pendingAutoStartMap.size === 0) return false;
893
+ if (!isAuto && !hasPendingAutoStart(lookupBasePath)) return false;
942
894
 
943
895
  const lastMsg = event.messages[event.messages.length - 1];
944
896
  if (!lastMsg) return false;
@@ -965,7 +917,7 @@ export function maybeHandleEmptyIntentTurn(
965
917
 
966
918
  // Resolve the target basePath + pi for injection. Prefer the pending
967
919
  // autostart entry (discuss flow); otherwise we cannot inject.
968
- const entry = _getPendingAutoStart();
920
+ const entry = _getPendingAutoStart(lookupBasePath);
969
921
  if (!entry) return false;
970
922
  const { ctx, pi, basePath } = entry;
971
923
 
@@ -1024,6 +976,19 @@ type UIContext = ExtensionContext;
1024
976
 
1025
977
  // ─── Helpers ──────────────────────────────────────────────────────────────────
1026
978
 
979
+ interface DispatchWorkflowOptions {
980
+ basePath?: string;
981
+ deps?: {
982
+ loadPreferences?: typeof loadEffectiveGSDPreferences;
983
+ selectModel?: typeof selectAndApplyModel;
984
+ getTransportSupportError?: typeof getWorkflowTransportSupportError;
985
+ };
986
+ }
987
+
988
+ export function resolveGuidedDispatchProjectRoot(basePath?: string): string {
989
+ return basePath ?? process.cwd();
990
+ }
991
+
1027
992
  /**
1028
993
  * Read GSD-WORKFLOW.md and dispatch it to the LLM with a contextual note.
1029
994
  * This is the only way the wizard triggers work — everything else is the LLM's job.
@@ -1039,13 +1004,20 @@ async function dispatchWorkflow(
1039
1004
  customType = "gsd-run",
1040
1005
  ctx?: ExtensionContext,
1041
1006
  unitType?: string,
1007
+ options?: DispatchWorkflowOptions,
1042
1008
  ): Promise<void> {
1009
+ const resolvedOptions = options ?? {};
1010
+ const projectRoot = resolveGuidedDispatchProjectRoot(resolvedOptions.basePath);
1011
+ const loadPreferences = resolvedOptions.deps?.loadPreferences ?? loadEffectiveGSDPreferences;
1012
+ const selectModel = resolvedOptions.deps?.selectModel ?? selectAndApplyModel;
1013
+ const getTransportSupportError = resolvedOptions.deps?.getTransportSupportError ?? getWorkflowTransportSupportError;
1014
+
1043
1015
  // Route through the dynamic routing pipeline (complexity classification,
1044
1016
  // tier downgrade, fallback chains) — same path as auto-mode dispatches (#2958).
1045
1017
  if (ctx && unitType) {
1046
- const prefs = loadEffectiveGSDPreferences()?.preferences;
1047
- const result = await selectAndApplyModel(
1048
- ctx, pi, unitType, /* unitId */ "", /* basePath */ process.cwd(),
1018
+ const prefs = loadPreferences(projectRoot)?.preferences;
1019
+ const result = await selectModel(
1020
+ ctx, pi, unitType, /* unitId */ "", projectRoot,
1049
1021
  prefs, /* verbose */ false, /* autoModeStartModel */ null,
1050
1022
  /* retryContext */ undefined, /* isAutoMode */ false,
1051
1023
  );
@@ -1057,11 +1029,11 @@ async function dispatchWorkflow(
1057
1029
  });
1058
1030
  }
1059
1031
 
1060
- const compatibilityError = getWorkflowTransportSupportError(
1032
+ const compatibilityError = getTransportSupportError(
1061
1033
  result.appliedModel?.provider ?? ctx.model?.provider,
1062
1034
  getRequiredWorkflowToolsForGuidedUnit(unitType),
1063
1035
  {
1064
- projectRoot: process.cwd(),
1036
+ projectRoot,
1065
1037
  surface: "guided flow",
1066
1038
  unitType,
1067
1039
  authMode: result.appliedModel?.provider
@@ -1119,14 +1091,20 @@ async function dispatchWorkflow(
1119
1091
  const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(gsdHome(), "agent", "GSD-WORKFLOW.md");
1120
1092
  const workflow = readFileSync(workflowPath, "utf-8");
1121
1093
 
1122
- pi.sendMessage(
1123
- {
1124
- customType,
1125
- content: buildWorkflowDispatchContent({ workflow, workflowPath, task: note }),
1126
- display: false,
1127
- },
1128
- { triggerTurn: true },
1129
- );
1094
+ if (unitType) setGuidedUnitContext(projectRoot, unitType);
1095
+ try {
1096
+ pi.sendMessage(
1097
+ {
1098
+ customType,
1099
+ content: buildWorkflowDispatchContent({ workflow, workflowPath, task: note }),
1100
+ display: false,
1101
+ },
1102
+ { triggerTurn: true },
1103
+ );
1104
+ } catch (err) {
1105
+ clearGuidedUnitContext(projectRoot);
1106
+ throw err;
1107
+ }
1130
1108
  } finally {
1131
1109
  // Restore full tool set after the message is queued. The LLM turn has
1132
1110
  // already captured the scoped set — restoring prevents the narrowed
@@ -1357,7 +1335,7 @@ export async function showHeadlessMilestoneCreation(
1357
1335
  // model/tool routing to skip discuss-flow tool scoping and
1358
1336
  // `checkAutoStartAfterDiscuss` guardrails that rely on the
1359
1337
  // "discuss-"-prefixed unitType.
1360
- await dispatchWorkflow(pi, prompt, "gsd-run", ctx, "discuss-milestone");
1338
+ await dispatchWorkflow(pi, prompt, "gsd-run", ctx, "discuss-milestone", { basePath });
1361
1339
  }
1362
1340
 
1363
1341
 
@@ -1539,6 +1517,7 @@ export async function showDiscuss(
1539
1517
  const discussMilestoneTemplates = inlineTemplate("context", "Context");
1540
1518
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
1541
1519
  const basePrompt = loadPrompt("guided-discuss-milestone", {
1520
+ workingDirectory: basePath,
1542
1521
  milestoneId: mid, milestoneTitle, inlinedTemplates: discussMilestoneTemplates, structuredQuestionsAvailable,
1543
1522
  commitInstruction: buildDocsCommitInstruction(`docs(${mid}): milestone context from discuss`),
1544
1523
  fastPathInstruction: "",
@@ -1547,16 +1526,17 @@ export async function showDiscuss(
1547
1526
  ? `${basePrompt}\n\n## Prior Discussion (Draft Seed)\n\n${draftContent}`
1548
1527
  : basePrompt;
1549
1528
  setPendingAutoStart(basePath, { ctx, pi, basePath, milestoneId: mid, step: false });
1550
- await dispatchWorkflow(pi, seed, "gsd-discuss", ctx, "discuss-milestone");
1529
+ await dispatchWorkflow(pi, seed, "gsd-discuss", ctx, "discuss-milestone", { basePath });
1551
1530
  } else if (choice === "discuss_fresh") {
1552
1531
  const discussMilestoneTemplates = inlineTemplate("context", "Context");
1553
1532
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
1554
1533
  setPendingAutoStart(basePath, { ctx, pi, basePath, milestoneId: mid, step: false });
1555
1534
  await dispatchWorkflow(pi, loadPrompt("guided-discuss-milestone", {
1535
+ workingDirectory: basePath,
1556
1536
  milestoneId: mid, milestoneTitle, inlinedTemplates: discussMilestoneTemplates, structuredQuestionsAvailable,
1557
1537
  commitInstruction: buildDocsCommitInstruction(`docs(${mid}): milestone context from discuss`),
1558
1538
  fastPathInstruction: "",
1559
- }), "gsd-discuss", ctx, "discuss-milestone");
1539
+ }), "gsd-discuss", ctx, "discuss-milestone", { basePath });
1560
1540
  } else if (choice === "skip_milestone") {
1561
1541
  const { ensureDbOpen } = await import("./bootstrap/dynamic-tools.js");
1562
1542
  await ensureDbOpen(basePath);
@@ -1564,7 +1544,7 @@ export async function showDiscuss(
1564
1544
  const uniqueMilestoneIds = !!loadEffectiveGSDPreferences()?.preferences?.unique_milestone_ids;
1565
1545
  const nextId = nextMilestoneIdReserved(milestoneIds, uniqueMilestoneIds, basePath);
1566
1546
  setPendingAutoStart(basePath, { ctx, pi, basePath, milestoneId: nextId, step: false });
1567
- await dispatchWorkflow(pi, await prepareAndBuildDiscussPrompt(ctx, pi, nextId, `New milestone ${nextId}.`, basePath), "gsd-run", ctx, "discuss-milestone");
1547
+ await dispatchWorkflow(pi, await prepareAndBuildDiscussPrompt(ctx, pi, nextId, `New milestone ${nextId}.`, basePath), "gsd-run", ctx, "discuss-milestone", { basePath });
1568
1548
  }
1569
1549
  return;
1570
1550
  }
@@ -1712,7 +1692,7 @@ export async function showDiscuss(
1712
1692
 
1713
1693
  const sqAvail = getStructuredQuestionsAvailability(pi, ctx);
1714
1694
  const prompt = await buildDiscussSlicePrompt(mid, chosen.id, chosen.title, basePath, { rediscuss: isRediscuss, structuredQuestionsAvailable: sqAvail });
1715
- await dispatchWorkflow(pi, prompt, "gsd-discuss", ctx, "discuss-slice");
1695
+ await dispatchWorkflow(pi, prompt, "gsd-discuss", ctx, "discuss-slice", { basePath });
1716
1696
 
1717
1697
  // Wait for the discuss session to finish, then loop back to the picker
1718
1698
  await ctx.waitForIdle();
@@ -1822,6 +1802,7 @@ async function dispatchDiscussForMilestone(
1822
1802
  const discussMilestoneTemplates = inlineTemplate("context", "Context");
1823
1803
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
1824
1804
  const basePrompt = loadPrompt("guided-discuss-milestone", {
1805
+ workingDirectory: basePath,
1825
1806
  milestoneId: mid,
1826
1807
  milestoneTitle,
1827
1808
  inlinedTemplates: discussMilestoneTemplates,
@@ -1832,7 +1813,7 @@ async function dispatchDiscussForMilestone(
1832
1813
  const prompt = draftContent
1833
1814
  ? `${basePrompt}\n\n## Prior Discussion (Draft Seed)\n\n${draftContent}`
1834
1815
  : basePrompt;
1835
- await dispatchWorkflow(pi, prompt, "gsd-discuss", ctx, "discuss-milestone");
1816
+ await dispatchWorkflow(pi, prompt, "gsd-discuss", ctx, "discuss-milestone", { basePath });
1836
1817
  }
1837
1818
 
1838
1819
  // ─── Smart Entry Point ────────────────────────────────────────────────────────
@@ -1975,7 +1956,7 @@ async function handleMilestoneActions(
1975
1956
  await dispatchWorkflow(pi, await prepareAndBuildDiscussPrompt(ctx, pi, nextId,
1976
1957
  `New milestone ${nextId}.`,
1977
1958
  basePath
1978
- ), "gsd-run", ctx, "discuss-milestone");
1959
+ ), "gsd-run", ctx, "discuss-milestone", { basePath });
1979
1960
  return true;
1980
1961
  }
1981
1962
 
@@ -2121,18 +2102,19 @@ export async function showSmartEntry(
2121
2102
 
2122
2103
  if (interrupted.classification !== "recoverable") {
2123
2104
  try {
2124
- const { autoImportMarkdownHierarchyIfDbMismatch } = await import("./migration-auto-check.js");
2125
- const result = await autoImportMarkdownHierarchyIfDbMismatch(basePath);
2126
- if (result.action === "imported") {
2105
+ const { checkMarkdownHierarchyAgainstDb } = await import("./migration-auto-check.js");
2106
+ const result = await checkMarkdownHierarchyAgainstDb(basePath);
2107
+ if (result.action === "recovery-required") {
2127
2108
  ctx.ui.notify(
2128
- `Recovered migrated planning state into gsd.db (${result.reason}): ${result.afterDb.milestones} milestone(s), ${result.afterDb.slices} slice(s), ${result.afterDb.tasks} task(s).`,
2129
- "info",
2109
+ result.message ??
2110
+ `Markdown planning artifacts do not match the authoritative DB. Run \`${result.recoveryCommand ?? "gsd recover"}\` to import markdown explicitly.`,
2111
+ "warning",
2130
2112
  );
2131
2113
  }
2132
2114
  } catch (err) {
2133
2115
  const message = err instanceof Error ? err.message : String(err);
2134
- ctx.ui.notify(`GSD could not auto-import existing planning state into gsd.db: ${message}`, "warning");
2135
- logWarning("guided", `planning state auto-import failed: ${message}`, { file: "guided-flow.ts" });
2116
+ ctx.ui.notify(`GSD could not compare markdown planning artifacts with gsd.db: ${message}`, "warning");
2117
+ logWarning("guided", `planning state DB/markdown comparison failed: ${message}`, { file: "guided-flow.ts" });
2136
2118
  }
2137
2119
  }
2138
2120
 
@@ -2173,17 +2155,17 @@ export async function showSmartEntry(
2173
2155
  // Both /gsd and /gsd auto reach this branch when no milestone exists yet.
2174
2156
  // Without this guard, every subsequent /gsd call overwrites the pending auto-start
2175
2157
  // and fires another dispatchWorkflow, resetting the conversation mid-interview.
2176
- if (pendingAutoStartMap.has(basePath)) {
2158
+ if (hasPendingAutoStart(basePath)) {
2177
2159
  // #3274: If /clear interrupted the discussion, the pending entry is stale.
2178
2160
  // Detect staleness: no manifest, no milestone CONTEXT artifact, AND entry is older than
2179
2161
  // 30s (avoids race between .set() and LLM writing first artifact).
2180
- const entry = pendingAutoStartMap.get(basePath)!;
2162
+ const entry = _getPendingAutoStart(basePath)!;
2181
2163
  const ageMs = Date.now() - (entry.createdAt || 0);
2182
2164
  const manifestExists = existsSync(join(gsdRoot(basePath), "DISCUSSION-MANIFEST.json"));
2183
2165
  const milestoneHasContext = !!resolveMilestoneFile(basePath, entry.milestoneId, "CONTEXT");
2184
2166
  if (!manifestExists && !milestoneHasContext && ageMs > 30_000) {
2185
2167
  // Stale entry from an interrupted discussion — clear and continue
2186
- pendingAutoStartMap.delete(basePath);
2168
+ deletePendingAutoStart(basePath);
2187
2169
  } else {
2188
2170
  ctx.ui.notify("Discussion already in progress — answer the question above to continue.", "info");
2189
2171
  return;
@@ -2223,7 +2205,7 @@ export async function showSmartEntry(
2223
2205
  await dispatchWorkflow(pi, await prepareAndBuildDiscussPrompt(ctx, pi, nextId,
2224
2206
  `New project, milestone ${nextId}. Do NOT read or explore .gsd/ — it's empty scaffolding.`,
2225
2207
  basePath
2226
- ), "gsd-run", ctx, "discuss-milestone");
2208
+ ), "gsd-run", ctx, "discuss-milestone", { basePath });
2227
2209
  } else {
2228
2210
  const choice = await showNextAction(ctx, {
2229
2211
  title: "GSD — Get Shit Done",
@@ -2252,7 +2234,7 @@ export async function showSmartEntry(
2252
2234
  await dispatchWorkflow(pi, await prepareAndBuildDiscussPrompt(ctx, pi, nextId,
2253
2235
  `New milestone ${nextId}.`,
2254
2236
  basePath
2255
- ), "gsd-run", ctx, "discuss-milestone");
2237
+ ), "gsd-run", ctx, "discuss-milestone", { basePath });
2256
2238
  }
2257
2239
  }
2258
2240
  return;
@@ -2274,6 +2256,7 @@ export async function showSmartEntry(
2274
2256
  "gsd-discuss",
2275
2257
  ctx,
2276
2258
  "discuss-milestone",
2259
+ { basePath },
2277
2260
  );
2278
2261
  return;
2279
2262
  }
@@ -2315,7 +2298,7 @@ export async function showSmartEntry(
2315
2298
  await dispatchWorkflow(pi, await prepareAndBuildDiscussPrompt(ctx, pi, nextId,
2316
2299
  `New milestone ${nextId}.`,
2317
2300
  basePath
2318
- ), "gsd-run", ctx, "discuss-milestone");
2301
+ ), "gsd-run", ctx, "discuss-milestone", { basePath });
2319
2302
  } else if (choice === "status") {
2320
2303
  const { fireStatusViaCommand } = await import("./commands.js");
2321
2304
  await fireStatusViaCommand(ctx);
@@ -2356,6 +2339,7 @@ export async function showSmartEntry(
2356
2339
  const discussMilestoneTemplates = inlineTemplate("context", "Context");
2357
2340
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
2358
2341
  const basePrompt = loadPrompt("guided-discuss-milestone", {
2342
+ workingDirectory: basePath,
2359
2343
  milestoneId, milestoneTitle, inlinedTemplates: discussMilestoneTemplates, structuredQuestionsAvailable,
2360
2344
  commitInstruction: buildDocsCommitInstruction(`docs(${milestoneId}): milestone context from discuss`),
2361
2345
  fastPathInstruction: "",
@@ -2364,16 +2348,17 @@ export async function showSmartEntry(
2364
2348
  ? `${basePrompt}\n\n## Prior Discussion (Draft Seed)\n\n${draftContent}`
2365
2349
  : basePrompt;
2366
2350
  setPendingAutoStart(basePath, { ctx, pi, basePath, milestoneId, step: stepMode });
2367
- await dispatchWorkflow(pi, seed, "gsd-discuss", ctx, "discuss-milestone");
2351
+ await dispatchWorkflow(pi, seed, "gsd-discuss", ctx, "discuss-milestone", { basePath });
2368
2352
  } else if (choice === "discuss_fresh") {
2369
2353
  const discussMilestoneTemplates = inlineTemplate("context", "Context");
2370
2354
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
2371
2355
  setPendingAutoStart(basePath, { ctx, pi, basePath, milestoneId, step: stepMode });
2372
2356
  await dispatchWorkflow(pi, loadPrompt("guided-discuss-milestone", {
2357
+ workingDirectory: basePath,
2373
2358
  milestoneId, milestoneTitle, inlinedTemplates: discussMilestoneTemplates, structuredQuestionsAvailable,
2374
2359
  commitInstruction: buildDocsCommitInstruction(`docs(${milestoneId}): milestone context from discuss`),
2375
2360
  fastPathInstruction: "",
2376
- }), "gsd-discuss", ctx, "discuss-milestone");
2361
+ }), "gsd-discuss", ctx, "discuss-milestone", { basePath });
2377
2362
  } else if (choice === "skip_milestone") {
2378
2363
  const milestoneIds = findMilestoneIds(basePath);
2379
2364
  const uniqueMilestoneIds = !!loadEffectiveGSDPreferences()?.preferences?.unique_milestone_ids;
@@ -2382,7 +2367,7 @@ export async function showSmartEntry(
2382
2367
  await dispatchWorkflow(pi, await prepareAndBuildDiscussPrompt(ctx, pi, nextId,
2383
2368
  `New milestone ${nextId}.`,
2384
2369
  basePath
2385
- ), "gsd-run", ctx, "discuss-milestone");
2370
+ ), "gsd-run", ctx, "discuss-milestone", { basePath });
2386
2371
  }
2387
2372
  return;
2388
2373
  }
@@ -2457,15 +2442,17 @@ export async function showSmartEntry(
2457
2442
  "gsd-run",
2458
2443
  ctx,
2459
2444
  "plan-milestone",
2445
+ { basePath },
2460
2446
  );
2461
2447
  } else if (choice === "discuss") {
2462
2448
  const discussMilestoneTemplates = inlineTemplate("context", "Context");
2463
2449
  const structuredQuestionsAvailable = getStructuredQuestionsAvailability(pi, ctx);
2464
2450
  await dispatchWorkflow(pi, loadPrompt("guided-discuss-milestone", {
2451
+ workingDirectory: basePath,
2465
2452
  milestoneId, milestoneTitle, inlinedTemplates: discussMilestoneTemplates, structuredQuestionsAvailable,
2466
2453
  commitInstruction: buildDocsCommitInstruction(`docs(${milestoneId}): milestone context from discuss`),
2467
2454
  fastPathInstruction: "",
2468
- }), "gsd-run", ctx, "discuss-milestone");
2455
+ }), "gsd-run", ctx, "discuss-milestone", { basePath });
2469
2456
  } else if (choice === "skip_milestone") {
2470
2457
  const milestoneIds = findMilestoneIds(basePath);
2471
2458
  const uniqueMilestoneIds = !!loadEffectiveGSDPreferences()?.preferences?.unique_milestone_ids;
@@ -2474,7 +2461,7 @@ export async function showSmartEntry(
2474
2461
  await dispatchWorkflow(pi, await prepareAndBuildDiscussPrompt(ctx, pi, nextId,
2475
2462
  `New milestone ${nextId}.`,
2476
2463
  basePath
2477
- ), "gsd-run", ctx, "discuss-milestone");
2464
+ ), "gsd-run", ctx, "discuss-milestone", { basePath });
2478
2465
  } else if (choice === "discard_milestone") {
2479
2466
  const confirmed = await showConfirm(ctx, {
2480
2467
  title: "Discard milestone?",
@@ -2589,10 +2576,11 @@ export async function showSmartEntry(
2589
2576
  "gsd-run",
2590
2577
  ctx,
2591
2578
  "plan-slice",
2579
+ { basePath },
2592
2580
  );
2593
2581
  } else if (choice === "discuss") {
2594
2582
  const sqAvail = getStructuredQuestionsAvailability(pi, ctx);
2595
- await dispatchWorkflow(pi, await buildDiscussSlicePrompt(milestoneId, sliceId, sliceTitle, basePath, { rediscuss: hasContext, structuredQuestionsAvailable: sqAvail }), "gsd-run", ctx, "discuss-slice");
2583
+ await dispatchWorkflow(pi, await buildDiscussSlicePrompt(milestoneId, sliceId, sliceTitle, basePath, { rediscuss: hasContext, structuredQuestionsAvailable: sqAvail }), "gsd-run", ctx, "discuss-slice", { basePath });
2596
2584
  } else if (choice === "research") {
2597
2585
  const researchTemplates = inlineTemplate("research", "Research");
2598
2586
  await dispatchWorkflow(pi, loadPrompt("guided-research-slice", {
@@ -2607,7 +2595,7 @@ export async function showSmartEntry(
2607
2595
  sliceTitle,
2608
2596
  extraContext: [researchTemplates],
2609
2597
  }),
2610
- }), "gsd-run", ctx, "research-slice");
2598
+ }), "gsd-run", ctx, "research-slice", { basePath });
2611
2599
  } else if (choice === "status") {
2612
2600
  const { fireStatusViaCommand } = await import("./commands.js");
2613
2601
  await fireStatusViaCommand(ctx);
@@ -2652,6 +2640,7 @@ export async function showSmartEntry(
2652
2640
  "gsd-run",
2653
2641
  ctx,
2654
2642
  "complete-slice",
2643
+ { basePath },
2655
2644
  );
2656
2645
  } else if (choice === "status") {
2657
2646
  const { fireStatusViaCommand } = await import("./commands.js");
@@ -2708,12 +2697,20 @@ export async function showSmartEntry(
2708
2697
  notYetMessage: "Run /gsd when ready.",
2709
2698
  });
2710
2699
 
2711
- if (choice === "auto") {
2712
- startAutoDetached(ctx, pi, basePath, false);
2700
+ if (choice === "not_yet") return;
2701
+
2702
+ const route = resolveActiveTaskChoiceRoute({
2703
+ choice: choice as ActiveTaskChoice,
2704
+ isolationMode: getIsolationMode(basePath),
2705
+ milestoneId,
2706
+ });
2707
+
2708
+ if (route.kind === "auto-bootstrap") {
2709
+ startAutoDetached(ctx, pi, basePath, route.verboseMode, route.options);
2713
2710
  return;
2714
2711
  }
2715
2712
 
2716
- if (choice === "execute") {
2713
+ if (route.kind === "guided-dispatch") {
2717
2714
  ctx.ui.setStatus("gsd-step", "Executing Task · follow progress above");
2718
2715
  if (hasInterrupted) {
2719
2716
  await dispatchWorkflow(pi, loadPrompt("guided-resume-task", {
@@ -2726,7 +2723,7 @@ export async function showSmartEntry(
2726
2723
  taskId,
2727
2724
  taskTitle,
2728
2725
  }),
2729
- }), "gsd-run", ctx, "execute-task");
2726
+ }), "gsd-run", ctx, "execute-task", { basePath });
2730
2727
  } else {
2731
2728
  await dispatchWorkflow(
2732
2729
  pi,
@@ -2734,12 +2731,13 @@ export async function showSmartEntry(
2734
2731
  "gsd-run",
2735
2732
  ctx,
2736
2733
  "execute-task",
2734
+ { basePath },
2737
2735
  );
2738
2736
  }
2739
- } else if (choice === "status") {
2737
+ } else if (route.kind === "status") {
2740
2738
  const { fireStatusViaCommand } = await import("./commands.js");
2741
2739
  await fireStatusViaCommand(ctx);
2742
- } else if (choice === "milestone_actions") {
2740
+ } else if (route.kind === "milestone-actions") {
2743
2741
  const acted = await handleMilestoneActions(ctx, pi, basePath, milestoneId, milestoneTitle, options);
2744
2742
  if (acted) return showSmartEntry(ctx, pi, basePath, options);
2745
2743
  }
@@ -0,0 +1,30 @@
1
+ // GSD-2 — Guided workflow Unit context.
2
+ // Tracks the guided Unit whose queued turn should use manifest Tool Contract policy.
3
+
4
+ export interface GuidedUnitContext {
5
+ basePath: string;
6
+ unitType: string;
7
+ startedAt: number;
8
+ }
9
+
10
+ const guidedUnitContextByBasePath = new Map<string, GuidedUnitContext>();
11
+
12
+ export function setGuidedUnitContext(basePath: string, unitType: string): GuidedUnitContext {
13
+ const context = { basePath, unitType, startedAt: Date.now() };
14
+ guidedUnitContextByBasePath.set(basePath, context);
15
+ return context;
16
+ }
17
+
18
+ export function getGuidedUnitContext(basePath?: string): GuidedUnitContext | null {
19
+ if (basePath) return guidedUnitContextByBasePath.get(basePath) ?? null;
20
+ if (guidedUnitContextByBasePath.size === 1) return guidedUnitContextByBasePath.values().next().value!;
21
+ return null;
22
+ }
23
+
24
+ export function clearGuidedUnitContext(basePath?: string): void {
25
+ if (basePath) {
26
+ guidedUnitContextByBasePath.delete(basePath);
27
+ } else {
28
+ guidedUnitContextByBasePath.clear();
29
+ }
30
+ }