@opengsd/gsd-pi 1.1.1-dev.b2556262 → 1.2.0-dev.4813ead6

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 (500) hide show
  1. package/dist/cli-web-branch.d.ts +2 -0
  2. package/dist/cli-web-branch.js +9 -2
  3. package/dist/help-text.js +5 -0
  4. package/dist/project-sessions.js +4 -2
  5. package/dist/resources/.managed-resources-content-hash +1 -1
  6. package/dist/resources/extensions/ask-user-questions.js +78 -23
  7. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +101 -237
  8. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +224 -0
  9. package/dist/resources/extensions/github-sync/templates.js +3 -3
  10. package/dist/resources/extensions/gsd/artifact-projection.js +14 -0
  11. package/dist/resources/extensions/gsd/auto/contracts.js +8 -1
  12. package/dist/resources/extensions/gsd/auto/loop.js +74 -56
  13. package/dist/resources/extensions/gsd/auto/orchestrator.js +763 -63
  14. package/dist/resources/extensions/gsd/auto/phases.js +28 -3
  15. package/dist/resources/extensions/gsd/auto/run-unit.js +2 -1
  16. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  17. package/dist/resources/extensions/gsd/auto-dashboard.js +16 -4
  18. package/dist/resources/extensions/gsd/auto-dispatch.js +6 -5
  19. package/dist/resources/extensions/gsd/auto-model-selection.js +8 -0
  20. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -3
  21. package/dist/resources/extensions/gsd/auto-prompts.js +191 -9
  22. package/dist/resources/extensions/gsd/auto-recovery.js +48 -49
  23. package/dist/resources/extensions/gsd/auto-runtime-state.js +17 -0
  24. package/dist/resources/extensions/gsd/auto-start.js +12 -23
  25. package/dist/resources/extensions/gsd/auto-timers.js +16 -2
  26. package/dist/resources/extensions/gsd/auto-tool-tracking.js +37 -0
  27. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +33 -29
  28. package/dist/resources/extensions/gsd/auto-verification.js +7 -7
  29. package/dist/resources/extensions/gsd/auto-worktree.js +45 -36
  30. package/dist/resources/extensions/gsd/auto.js +73 -471
  31. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +28 -37
  32. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +11 -37
  33. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  34. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +103 -138
  35. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +63 -4
  36. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +21 -4
  37. package/dist/resources/extensions/gsd/codebase-generator.js +8 -4
  38. package/dist/resources/extensions/gsd/commands/handlers/auto.js +3 -0
  39. package/dist/resources/extensions/gsd/commands-handlers.js +20 -0
  40. package/dist/resources/extensions/gsd/commands-inspect.js +4 -8
  41. package/dist/resources/extensions/gsd/commands-maintenance.js +61 -41
  42. package/dist/resources/extensions/gsd/commands-ship.js +2 -2
  43. package/dist/resources/extensions/gsd/commands-verdict.js +12 -2
  44. package/dist/resources/extensions/gsd/db-workspace.js +103 -0
  45. package/dist/resources/extensions/gsd/debug-logger.js +10 -0
  46. package/dist/resources/extensions/gsd/delegation-policy.js +2 -10
  47. package/dist/resources/extensions/gsd/discussion-handoff.js +218 -0
  48. package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -0
  49. package/dist/resources/extensions/gsd/doctor-proactive.js +7 -2
  50. package/dist/resources/extensions/gsd/doctor.js +16 -9
  51. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  52. package/dist/resources/extensions/gsd/git-conflict-state.js +16 -1
  53. package/dist/resources/extensions/gsd/gsd-db.js +12 -0
  54. package/dist/resources/extensions/gsd/guided-flow.js +36 -470
  55. package/dist/resources/extensions/gsd/guided-unit-completion.js +225 -0
  56. package/dist/resources/extensions/gsd/markdown-renderer.js +33 -33
  57. package/dist/resources/extensions/gsd/mcp-filter.js +8 -1
  58. package/dist/resources/extensions/gsd/mcp-tool-name.js +26 -0
  59. package/dist/resources/extensions/gsd/md-importer.js +4 -3
  60. package/dist/resources/extensions/gsd/migrate/safety.js +2 -2
  61. package/dist/resources/extensions/gsd/migration-auto-check.js +3 -2
  62. package/dist/resources/extensions/gsd/milestone-closeout-proof.js +72 -0
  63. package/dist/resources/extensions/gsd/milestone-closeout.js +12 -4
  64. package/dist/resources/extensions/gsd/milestone-merge-transaction.js +10 -0
  65. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +156 -0
  66. package/dist/resources/extensions/gsd/milestone-readiness.js +77 -0
  67. package/dist/resources/extensions/gsd/milestone-settlement.js +50 -0
  68. package/dist/resources/extensions/gsd/milestone-validation-evidence.js +73 -0
  69. package/dist/resources/extensions/gsd/milestone-validation-verdict.js +57 -0
  70. package/dist/resources/extensions/gsd/native-git-bridge.js +45 -0
  71. package/dist/resources/extensions/gsd/parallel-eligibility.js +3 -6
  72. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -2
  73. package/dist/resources/extensions/gsd/preferences-diagnostics.js +67 -0
  74. package/dist/resources/extensions/gsd/preferences.js +147 -29
  75. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -0
  76. package/dist/resources/extensions/gsd/prompts/discuss.md +6 -7
  77. package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
  78. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +5 -7
  79. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +6 -6
  80. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +1 -2
  81. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -6
  82. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
  83. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -1
  84. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -0
  85. package/dist/resources/extensions/gsd/prompts/research-milestone.md +2 -2
  86. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  87. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +5 -3
  88. package/dist/resources/extensions/gsd/provider-payload-policy.js +83 -0
  89. package/dist/resources/extensions/gsd/pull-request-process.js +13 -0
  90. package/dist/resources/extensions/gsd/quality-gate-closure.js +109 -0
  91. package/dist/resources/extensions/gsd/question-transport.js +86 -0
  92. package/dist/resources/extensions/gsd/roadmap-slices.js +8 -2
  93. package/dist/resources/extensions/gsd/schemas/parsers.js +6 -1
  94. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -2
  95. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +21 -1
  96. package/dist/resources/extensions/gsd/state.js +13 -5
  97. package/dist/resources/extensions/gsd/templates/plan.md +7 -0
  98. package/dist/resources/extensions/gsd/templates/project.md +1 -0
  99. package/dist/resources/extensions/gsd/templates/roadmap.md +1 -1
  100. package/dist/resources/extensions/gsd/templates/uat.md +5 -1
  101. package/dist/resources/extensions/gsd/tool-contract.js +52 -8
  102. package/dist/resources/extensions/gsd/tool-presentation-plan.js +15 -34
  103. package/dist/resources/extensions/gsd/tool-surface-snapshot.js +17 -0
  104. package/dist/resources/extensions/gsd/tools/plan-milestone.js +15 -143
  105. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +39 -0
  106. package/dist/resources/extensions/gsd/tools/validate-milestone.js +15 -78
  107. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +169 -20
  108. package/dist/resources/extensions/gsd/uat-policy.js +16 -10
  109. package/dist/resources/extensions/gsd/uat-run.js +9 -14
  110. package/dist/resources/extensions/gsd/unit-context-composer.js +40 -20
  111. package/dist/resources/extensions/gsd/unit-runtime.js +3 -2
  112. package/dist/resources/extensions/gsd/unit-tool-contracts.js +2 -1
  113. package/dist/resources/extensions/gsd/user-input-boundary.js +65 -4
  114. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
  115. package/dist/resources/extensions/gsd/web-app-uat.js +80 -0
  116. package/dist/resources/extensions/gsd/workflow-mcp.js +15 -102
  117. package/dist/resources/extensions/gsd/workflow-reconcile.js +4 -3
  118. package/dist/resources/extensions/gsd/workflow-tool-surface.js +46 -0
  119. package/dist/resources/extensions/gsd/workspace-git-guard.js +2 -0
  120. package/dist/resources/extensions/gsd/worktree-state-projection.js +33 -4
  121. package/dist/resources/extensions/gsd/worktree-telemetry.js +12 -0
  122. package/dist/resources/extensions/shared/interview-ui.js +2 -2
  123. package/dist/resources/shared/claude-runtime-floor.js +182 -0
  124. package/dist/tsconfig.extensions.tsbuildinfo +1 -0
  125. package/dist/update-cmd.js +20 -0
  126. package/dist/web/standalone/.next/BUILD_ID +1 -1
  127. package/dist/web/standalone/.next/app-path-routes-manifest.json +5 -5
  128. package/dist/web/standalone/.next/build-manifest.json +3 -3
  129. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  130. package/dist/web/standalone/.next/react-loadable-manifest.json +8 -8
  131. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  140. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  143. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  145. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  148. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  149. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  150. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  151. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  152. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  154. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  155. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  156. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +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.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  160. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  162. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  164. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  166. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  167. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  168. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  169. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  170. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  171. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  172. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  173. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  174. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  175. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  176. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  177. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  178. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  179. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  180. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  182. package/dist/web/standalone/.next/server/app/index.html +1 -1
  183. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  184. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  185. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  186. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  187. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  188. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  189. package/dist/web/standalone/.next/server/app-paths-manifest.json +5 -5
  190. package/dist/web/standalone/.next/server/chunks/5047.js +2 -0
  191. package/dist/web/standalone/.next/server/chunks/5124.js +1 -0
  192. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  193. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  196. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  197. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  198. package/dist/web/standalone/.next/static/chunks/2659.b7b129ee6a769448.js +1 -0
  199. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +1 -0
  200. package/dist/web/standalone/.next/static/chunks/{3616.4113d484a994e411.js → 3616.3c60753b8ffcbd2e.js} +1 -1
  201. package/dist/web/standalone/.next/static/chunks/4283.e4873b058df143a1.js +2 -0
  202. package/dist/web/standalone/.next/static/chunks/5826.a46ecdd1cfe8dabc.js +1 -0
  203. package/dist/web/standalone/.next/static/chunks/796.cf859a427a2cb2ac.js +10 -0
  204. package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +1 -0
  205. package/dist/web/standalone/.next/static/chunks/{webpack-dda80a1ef5587410.js → webpack-fbea77b5f9953368.js} +1 -1
  206. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  207. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  208. package/dist/web/standalone/node_modules/postcss/lib/container.js +26 -18
  209. package/dist/web/standalone/node_modules/postcss/lib/css-syntax-error.js +47 -14
  210. package/dist/web/standalone/node_modules/postcss/lib/declaration.js +4 -4
  211. package/dist/web/standalone/node_modules/postcss/lib/fromJSON.js +3 -3
  212. package/dist/web/standalone/node_modules/postcss/lib/input.js +54 -29
  213. package/dist/web/standalone/node_modules/postcss/lib/lazy-result.js +47 -37
  214. package/dist/web/standalone/node_modules/postcss/lib/map-generator.js +26 -9
  215. package/dist/web/standalone/node_modules/postcss/lib/no-work-result.js +57 -55
  216. package/dist/web/standalone/node_modules/postcss/lib/node.js +99 -31
  217. package/dist/web/standalone/node_modules/postcss/lib/parse.js +1 -1
  218. package/dist/web/standalone/node_modules/postcss/lib/parser.js +10 -9
  219. package/dist/web/standalone/node_modules/postcss/lib/postcss.js +12 -12
  220. package/dist/web/standalone/node_modules/postcss/lib/previous-map.js +30 -11
  221. package/dist/web/standalone/node_modules/postcss/lib/processor.js +7 -7
  222. package/dist/web/standalone/node_modules/postcss/lib/result.js +5 -5
  223. package/dist/web/standalone/node_modules/postcss/lib/rule.js +6 -6
  224. package/dist/web/standalone/node_modules/postcss/lib/stringifier.js +69 -28
  225. package/dist/web/standalone/node_modules/postcss/lib/tokenize.js +6 -2
  226. package/dist/web/standalone/node_modules/postcss/package.json +48 -48
  227. package/dist/web-mode.d.ts +2 -0
  228. package/dist/web-mode.js +20 -8
  229. package/package.json +17 -11
  230. package/packages/cloud-mcp-gateway/package.json +2 -2
  231. package/packages/contracts/package.json +1 -1
  232. package/packages/daemon/package.json +4 -4
  233. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +2 -0
  234. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
  235. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +14 -0
  236. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
  237. package/packages/gsd-agent-core/package.json +5 -5
  238. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  239. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -0
  240. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  241. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +1 -1
  242. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  243. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  244. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +106 -40
  245. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  246. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
  247. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +6 -0
  248. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
  249. package/packages/gsd-agent-modes/package.json +7 -7
  250. package/packages/mcp-server/dist/server.d.ts +10 -0
  251. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  252. package/packages/mcp-server/dist/server.js +8 -0
  253. package/packages/mcp-server/dist/server.js.map +1 -1
  254. package/packages/mcp-server/dist/workflow-tools.d.ts +41 -0
  255. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  256. package/packages/mcp-server/dist/workflow-tools.js +2 -1
  257. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  258. package/packages/mcp-server/package.json +3 -3
  259. package/packages/native/package.json +1 -1
  260. package/packages/pi-agent-core/package.json +1 -1
  261. package/packages/pi-ai/dist/image-models.generated.d.ts +30 -0
  262. package/packages/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  263. package/packages/pi-ai/dist/image-models.generated.js +30 -0
  264. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  265. package/packages/pi-ai/dist/models.generated.d.ts +8 -127
  266. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  267. package/packages/pi-ai/dist/models.generated.js +47 -166
  268. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  269. package/packages/pi-ai/package.json +1 -1
  270. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  271. package/packages/pi-coding-agent/dist/core/auth-storage.js +11 -3
  272. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  273. package/packages/pi-coding-agent/package.json +7 -7
  274. package/packages/pi-tui/dist/components/input.js +1 -1
  275. package/packages/pi-tui/dist/components/input.js.map +1 -1
  276. package/packages/pi-tui/dist/keys.d.ts.map +1 -1
  277. package/packages/pi-tui/dist/keys.js +39 -30
  278. package/packages/pi-tui/dist/keys.js.map +1 -1
  279. package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  280. package/packages/pi-tui/dist/stdin-buffer.js +22 -0
  281. package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
  282. package/packages/pi-tui/package.json +2 -2
  283. package/packages/rpc-client/package.json +2 -2
  284. package/pkg/package.json +1 -1
  285. package/scripts/install/deps.js +10 -0
  286. package/scripts/link-workspace-packages.cjs +7 -40
  287. package/src/resources/extensions/ask-user-questions.ts +87 -24
  288. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +126 -289
  289. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +242 -2
  290. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +287 -0
  291. package/src/resources/extensions/github-sync/templates.ts +3 -3
  292. package/src/resources/extensions/github-sync/tests/templates.test.ts +2 -2
  293. package/src/resources/extensions/gsd/artifact-projection.ts +31 -0
  294. package/src/resources/extensions/gsd/auto/contracts.ts +40 -121
  295. package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -0
  296. package/src/resources/extensions/gsd/auto/loop.ts +83 -61
  297. package/src/resources/extensions/gsd/auto/orchestrator.ts +913 -64
  298. package/src/resources/extensions/gsd/auto/phases.ts +35 -3
  299. package/src/resources/extensions/gsd/auto/run-unit.ts +2 -1
  300. package/src/resources/extensions/gsd/auto/session.ts +4 -0
  301. package/src/resources/extensions/gsd/auto-dashboard.ts +18 -4
  302. package/src/resources/extensions/gsd/auto-dispatch.ts +20 -7
  303. package/src/resources/extensions/gsd/auto-model-selection.ts +8 -0
  304. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -3
  305. package/src/resources/extensions/gsd/auto-prompts.ts +220 -9
  306. package/src/resources/extensions/gsd/auto-recovery.ts +50 -50
  307. package/src/resources/extensions/gsd/auto-runtime-state.ts +30 -0
  308. package/src/resources/extensions/gsd/auto-start.ts +17 -20
  309. package/src/resources/extensions/gsd/auto-timers.ts +16 -2
  310. package/src/resources/extensions/gsd/auto-tool-tracking.ts +40 -0
  311. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +42 -30
  312. package/src/resources/extensions/gsd/auto-verification.ts +7 -8
  313. package/src/resources/extensions/gsd/auto-worktree.ts +57 -42
  314. package/src/resources/extensions/gsd/auto.ts +96 -508
  315. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +29 -37
  316. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +10 -37
  317. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  318. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +120 -151
  319. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +107 -3
  320. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +27 -5
  321. package/src/resources/extensions/gsd/codebase-generator.ts +9 -5
  322. package/src/resources/extensions/gsd/commands/handlers/auto.ts +3 -0
  323. package/src/resources/extensions/gsd/commands-handlers.ts +18 -0
  324. package/src/resources/extensions/gsd/commands-inspect.ts +7 -8
  325. package/src/resources/extensions/gsd/commands-maintenance.ts +74 -40
  326. package/src/resources/extensions/gsd/commands-ship.ts +2 -2
  327. package/src/resources/extensions/gsd/commands-verdict.ts +19 -2
  328. package/src/resources/extensions/gsd/db-workspace.ts +170 -0
  329. package/src/resources/extensions/gsd/debug-logger.ts +11 -0
  330. package/src/resources/extensions/gsd/delegation-policy.ts +3 -11
  331. package/src/resources/extensions/gsd/discussion-handoff.ts +276 -0
  332. package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -0
  333. package/src/resources/extensions/gsd/doctor-proactive.ts +8 -2
  334. package/src/resources/extensions/gsd/doctor.ts +15 -5
  335. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  336. package/src/resources/extensions/gsd/git-conflict-state.ts +17 -1
  337. package/src/resources/extensions/gsd/gsd-db.ts +12 -0
  338. package/src/resources/extensions/gsd/guided-flow.ts +49 -560
  339. package/src/resources/extensions/gsd/guided-unit-completion.ts +275 -0
  340. package/src/resources/extensions/gsd/markdown-renderer.ts +40 -20
  341. package/src/resources/extensions/gsd/mcp-filter.ts +9 -1
  342. package/src/resources/extensions/gsd/mcp-tool-name.ts +35 -0
  343. package/src/resources/extensions/gsd/md-importer.ts +3 -3
  344. package/src/resources/extensions/gsd/migrate/safety.ts +2 -2
  345. package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
  346. package/src/resources/extensions/gsd/milestone-closeout-proof.ts +131 -0
  347. package/src/resources/extensions/gsd/milestone-closeout.ts +12 -4
  348. package/src/resources/extensions/gsd/milestone-merge-transaction.ts +47 -0
  349. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +224 -0
  350. package/src/resources/extensions/gsd/milestone-readiness.ts +125 -0
  351. package/src/resources/extensions/gsd/milestone-settlement.ts +81 -0
  352. package/src/resources/extensions/gsd/milestone-validation-evidence.ts +95 -0
  353. package/src/resources/extensions/gsd/milestone-validation-verdict.ts +80 -0
  354. package/src/resources/extensions/gsd/native-git-bridge.ts +48 -0
  355. package/src/resources/extensions/gsd/parallel-eligibility.ts +4 -5
  356. package/src/resources/extensions/gsd/parallel-orchestrator.ts +6 -2
  357. package/src/resources/extensions/gsd/preferences-diagnostics.ts +98 -0
  358. package/src/resources/extensions/gsd/preferences-types.ts +16 -0
  359. package/src/resources/extensions/gsd/preferences.ts +173 -28
  360. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -0
  361. package/src/resources/extensions/gsd/prompts/discuss.md +6 -7
  362. package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
  363. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +5 -7
  364. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +6 -6
  365. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +1 -2
  366. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -6
  367. package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
  368. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -1
  369. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -0
  370. package/src/resources/extensions/gsd/prompts/research-milestone.md +2 -2
  371. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  372. package/src/resources/extensions/gsd/prompts/validate-milestone.md +5 -3
  373. package/src/resources/extensions/gsd/provider-payload-policy.ts +140 -0
  374. package/src/resources/extensions/gsd/pull-request-process.ts +41 -0
  375. package/src/resources/extensions/gsd/quality-gate-closure.ts +140 -0
  376. package/src/resources/extensions/gsd/question-transport.ts +138 -0
  377. package/src/resources/extensions/gsd/roadmap-slices.ts +8 -2
  378. package/src/resources/extensions/gsd/schemas/parsers.ts +6 -1
  379. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +6 -2
  380. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +31 -10
  381. package/src/resources/extensions/gsd/state.ts +15 -5
  382. package/src/resources/extensions/gsd/templates/plan.md +7 -0
  383. package/src/resources/extensions/gsd/templates/project.md +1 -0
  384. package/src/resources/extensions/gsd/templates/roadmap.md +1 -1
  385. package/src/resources/extensions/gsd/templates/uat.md +5 -1
  386. package/src/resources/extensions/gsd/tests/artifact-db-drift-memo.test.ts +66 -0
  387. package/src/resources/extensions/gsd/tests/ask-user-questions-render.test.ts +92 -0
  388. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +29 -1
  389. package/src/resources/extensions/gsd/tests/auto-dispatch-baseline-harness.test.ts +53 -0
  390. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +321 -5
  391. package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +23 -0
  392. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +18 -0
  393. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +709 -845
  394. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +38 -10
  395. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +34 -0
  396. package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +20 -0
  397. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
  398. package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +11 -0
  399. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +38 -1
  400. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +15 -0
  401. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +34 -3
  402. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +88 -0
  403. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +18 -0
  404. package/src/resources/extensions/gsd/tests/execute-summary-save-empty-project.test.ts +64 -1
  405. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +1 -0
  406. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +1 -5
  407. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +1 -5
  408. package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +48 -1
  409. package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +157 -0
  410. package/src/resources/extensions/gsd/tests/markdown-renderer-parse-cache.test.ts +75 -0
  411. package/src/resources/extensions/gsd/tests/mcp-tool-name.test.ts +34 -0
  412. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +58 -0
  413. package/src/resources/extensions/gsd/tests/milestone-closeout-proof.test.ts +99 -0
  414. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +25 -0
  415. package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +46 -0
  416. package/src/resources/extensions/gsd/tests/milestone-readiness.test.ts +65 -0
  417. package/src/resources/extensions/gsd/tests/milestone-validation-evidence.test.ts +41 -0
  418. package/src/resources/extensions/gsd/tests/milestone-validation-verdict.test.ts +55 -0
  419. package/src/resources/extensions/gsd/tests/native-merge-regular.test.ts +139 -0
  420. package/src/resources/extensions/gsd/tests/orchestrator-legacy-parity.test.ts +127 -0
  421. package/src/resources/extensions/gsd/tests/parse-project-milestone-bridge.test.ts +77 -0
  422. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +45 -0
  423. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +6 -2
  424. package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +45 -0
  425. package/src/resources/extensions/gsd/tests/preferences-diagnostics.test.ts +67 -0
  426. package/src/resources/extensions/gsd/tests/preferences.test.ts +183 -0
  427. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +75 -2
  428. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +9 -0
  429. package/src/resources/extensions/gsd/tests/provider-payload-policy.test.ts +165 -0
  430. package/src/resources/extensions/gsd/tests/pull-request-process.test.ts +47 -0
  431. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +94 -0
  432. package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +65 -0
  433. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +40 -0
  434. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +25 -1
  435. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +80 -0
  436. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +101 -1
  437. package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +27 -0
  438. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +21 -6
  439. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +38 -0
  440. package/src/resources/extensions/gsd/tests/tool-availability-audit.test.ts +35 -0
  441. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +35 -42
  442. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +23 -0
  443. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +47 -0
  444. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +147 -0
  445. package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +39 -0
  446. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +150 -0
  447. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +126 -9
  448. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +15 -0
  449. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +21 -0
  450. package/src/resources/extensions/gsd/tests/worktree-projection-writers.test.ts +1 -1
  451. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +24 -0
  452. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +22 -0
  453. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +15 -3
  454. package/src/resources/extensions/gsd/tests/write-gate.test.ts +79 -0
  455. package/src/resources/extensions/gsd/tool-contract.ts +86 -8
  456. package/src/resources/extensions/gsd/tool-presentation-plan.ts +16 -33
  457. package/src/resources/extensions/gsd/tool-surface-snapshot.ts +47 -0
  458. package/src/resources/extensions/gsd/tools/plan-milestone.ts +19 -160
  459. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +43 -0
  460. package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -84
  461. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +183 -21
  462. package/src/resources/extensions/gsd/uat-policy.ts +19 -10
  463. package/src/resources/extensions/gsd/uat-run.ts +10 -14
  464. package/src/resources/extensions/gsd/unit-context-composer.ts +85 -20
  465. package/src/resources/extensions/gsd/unit-runtime.ts +3 -2
  466. package/src/resources/extensions/gsd/unit-tool-contracts.ts +2 -1
  467. package/src/resources/extensions/gsd/user-input-boundary.ts +55 -5
  468. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
  469. package/src/resources/extensions/gsd/web-app-uat.ts +101 -0
  470. package/src/resources/extensions/gsd/workflow-mcp.ts +22 -110
  471. package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
  472. package/src/resources/extensions/gsd/workflow-tool-surface.ts +73 -0
  473. package/src/resources/extensions/gsd/workspace-git-guard.ts +1 -0
  474. package/src/resources/extensions/gsd/worktree-lifecycle.ts +7 -16
  475. package/src/resources/extensions/gsd/worktree-state-projection.ts +55 -7
  476. package/src/resources/extensions/gsd/worktree-telemetry.ts +16 -0
  477. package/src/resources/extensions/shared/interview-ui.ts +15 -2
  478. package/src/resources/shared/claude-runtime-floor.ts +248 -0
  479. package/dist/web/standalone/.next/server/chunks/678.js +0 -2
  480. package/dist/web/standalone/.next/static/chunks/2659.feb6499ca863ebfc.js +0 -1
  481. package/dist/web/standalone/.next/static/chunks/2772.151789db0edea835.js +0 -1
  482. package/dist/web/standalone/.next/static/chunks/4283.10a065467b5340d8.js +0 -2
  483. package/dist/web/standalone/.next/static/chunks/5826.960dc4634cc9b0d3.js +0 -1
  484. package/dist/web/standalone/.next/static/chunks/796.46f811c0fac23aab.js +0 -10
  485. package/dist/web/standalone/.next/static/chunks/8785.d32f7a61f55c1600.js +0 -1
  486. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +0 -21
  487. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +0 -1
  488. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +0 -213
  489. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +0 -1
  490. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.d.ts +0 -28
  491. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.d.ts.map +0 -1
  492. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.js +0 -249
  493. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.js.map +0 -1
  494. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.d.ts +0 -19
  495. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.d.ts.map +0 -1
  496. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.js +0 -797
  497. package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.js.map +0 -1
  498. package/scripts/ensure-workspace-builds.cjs +0 -129
  499. /package/dist/web/standalone/.next/static/{tJOKQbQRO-9MiFDO8DIDS → tkLHUSzPA2kMmWz4DmGwI}/_buildManifest.js +0 -0
  500. /package/dist/web/standalone/.next/static/{tJOKQbQRO-9MiFDO8DIDS → tkLHUSzPA2kMmWz4DmGwI}/_ssgManifest.js +0 -0
@@ -13,6 +13,7 @@ import { GSDError, GSD_GIT_ERROR } from "./errors.js";
13
13
  import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
14
14
  import { getErrorMessage } from "./error-utils.js";
15
15
  import { isInfrastructureError } from "./auto/infra-errors.js";
16
+ import { debugCount } from "./debug-logger.js";
16
17
 
17
18
  // Issue #453: keep auto-mode bookkeeping on the stable git CLI path unless a
18
19
  // caller explicitly opts into the native helper.
@@ -140,6 +141,8 @@ function loadNative(): typeof nativeModule {
140
141
 
141
142
  /** Run a git command via execFileSync. Returns trimmed stdout. */
142
143
  function gitExec(basePath: string, args: string[], allowFailure = false): string {
144
+ // Counts git CLI shell-outs only (native libgit2 paths bypass this helper).
145
+ debugCount("gitInvocations");
143
146
  try {
144
147
  return execFileSync("git", args, {
145
148
  cwd: basePath,
@@ -169,6 +172,8 @@ function execGitFileSyncWithRetry(
169
172
  args: string[],
170
173
  options: Partial<ExecFileSyncOptionsWithStringEncoding>,
171
174
  ): string {
175
+ // Counts git CLI shell-outs only (native libgit2 paths bypass this helper).
176
+ debugCount("gitInvocations");
172
177
  try {
173
178
  return execFileSync("git", args, {
174
179
  cwd: basePath,
@@ -180,6 +185,8 @@ function execGitFileSyncWithRetry(
180
185
  } catch (err) {
181
186
  if (!isRetryableGitError(err)) throw err;
182
187
  sleepSync(GIT_RETRY_DELAY_MS);
188
+ // Retry is a second physical shell-out — count it too.
189
+ debugCount("gitInvocations");
183
190
  return execFileSync("git", args, {
184
191
  cwd: basePath,
185
192
  stdio: ["ignore", "pipe", "pipe"],
@@ -192,6 +199,8 @@ function execGitFileSyncWithRetry(
192
199
 
193
200
  /** Run a git command via execFileSync. Returns trimmed stdout. */
194
201
  function gitFileExec(basePath: string, args: string[], allowFailure = false): string {
202
+ // Counts git CLI shell-outs only (native libgit2 paths bypass this helper).
203
+ debugCount("gitInvocations");
195
204
  try {
196
205
  return execFileSync("git", args, {
197
206
  cwd: basePath,
@@ -1092,6 +1101,45 @@ export function nativeMergeSquash(basePath: string, branch: string): GitMergeRes
1092
1101
  }
1093
1102
  }
1094
1103
 
1104
+ /**
1105
+ * Regular (non-squash) merge a branch (stages changes, does NOT commit).
1106
+ * Uses --no-ff to ensure a proper merge commit and --no-commit so the caller
1107
+ * can supply a custom commit message via nativeCommit.
1108
+ * Respects the user's global git merge.ff config; --no-ff is additive here.
1109
+ */
1110
+ export function nativeMergeRegular(basePath: string, branch: string): GitMergeResult {
1111
+ try {
1112
+ execFileSync("git", ["merge", "--no-ff", "--no-commit", branch], {
1113
+ cwd: basePath,
1114
+ stdio: ["ignore", "pipe", "pipe"],
1115
+ encoding: "utf-8",
1116
+ env: GIT_NO_PROMPT_ENV,
1117
+ });
1118
+ return { success: true, conflicts: [] };
1119
+ } catch (err: unknown) {
1120
+ const stderr =
1121
+ err instanceof Error ? (err as Error & { stderr?: string }).stderr ?? err.message : String(err);
1122
+ if (
1123
+ stderr.includes("local changes would be overwritten") ||
1124
+ stderr.includes("not possible because you have unmerged files") ||
1125
+ stderr.includes("overwritten by merge")
1126
+ ) {
1127
+ const dirtyFiles = stderr
1128
+ .split("\n")
1129
+ .filter((line) => line.startsWith("\t"))
1130
+ .map((line) => line.trim())
1131
+ .filter(Boolean);
1132
+ return { success: false, conflicts: ["__dirty_working_tree__"], dirtyFiles };
1133
+ }
1134
+ const conflictOutput = gitExec(basePath, ["diff", "--name-only", "--diff-filter=U"], true);
1135
+ const conflicts = conflictOutput ? conflictOutput.split("\n").filter(Boolean) : [];
1136
+ if (conflicts.length > 0) {
1137
+ return { success: false, conflicts };
1138
+ }
1139
+ throw err;
1140
+ }
1141
+ }
1142
+
1095
1143
  /**
1096
1144
  * Abort an in-progress merge.
1097
1145
  * Native: libgit2 reset + cleanup.
@@ -5,11 +5,11 @@
5
5
  * dependency satisfaction and file overlap across slice plans.
6
6
  */
7
7
 
8
- import { existsSync } from "node:fs";
9
8
  import { deriveState } from "./state.js";
10
- import { resolveGsdPathContract, resolveMilestoneFile, resolveSliceFile } from "./paths.js";
9
+ import { resolveMilestoneFile, resolveSliceFile } from "./paths.js";
11
10
  import { findMilestoneIds } from "./guided-flow.js";
12
- import { isDbAvailable, getMilestoneSlices, getSliceTasks, openDatabase } from "./gsd-db.js";
11
+ import { isDbAvailable, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
12
+ import { openExistingWorkflowDatabase } from "./db-workspace.js";
13
13
  import type { MilestoneRegistryEntry } from "./types.js";
14
14
 
15
15
  // ─── Types ───────────────────────────────────────────────────────────────────
@@ -98,8 +98,7 @@ export async function analyzeParallelEligibility(
98
98
  basePath: string,
99
99
  ): Promise<ParallelCandidates> {
100
100
  if (!isDbAvailable()) {
101
- const { projectDb } = resolveGsdPathContract(basePath);
102
- if (existsSync(projectDb)) openDatabase(projectDb);
101
+ openExistingWorkflowDatabase(basePath);
103
102
  }
104
103
 
105
104
  const milestoneIds = findMilestoneIds(basePath);
@@ -21,9 +21,10 @@ import { join, dirname } from "node:path";
21
21
  import { fileURLToPath } from "node:url";
22
22
  import { gsdRoot } from "./paths.js";
23
23
  import { createWorktree, worktreePath } from "./worktree-manager.js";
24
- import { autoWorktreeBranch, fastForwardReusedMilestoneBranchIfSafe, runWorktreePostCreateHook, syncGsdStateToWorktree } from "./auto-worktree.js";
24
+ import { autoWorktreeBranch, fastForwardReusedMilestoneBranchIfSafe, runWorktreePostCreateHook, syncGsdStateToWorktreeByScope } from "./auto-worktree.js";
25
25
  import { nativeBranchExists } from "./native-git-bridge.js";
26
26
  import { readIntegrationBranch } from "./git-service.js";
27
+ import { createWorkspace, scopeMilestone } from "./workspace.js";
27
28
  import { resolveParallelConfig } from "./preferences.js";
28
29
  import type { GSDPreferences } from "./preferences.js";
29
30
  import type { ParallelConfig } from "./types.js";
@@ -561,7 +562,10 @@ export function _createMilestoneWorktree(basePath: string, milestoneId: string):
561
562
  // Copy .gsd/ planning artifacts (milestones, CONTEXT, ROADMAP, etc.) from the
562
563
  // project root into the worktree. Without this, workers for newly-planned
563
564
  // milestones can't find their roadmap and exit immediately (#2184 Bug 4).
564
- syncGsdStateToWorktree(basePath, info.path);
565
+ syncGsdStateToWorktreeByScope(
566
+ scopeMilestone(createWorkspace(basePath), milestoneId),
567
+ scopeMilestone(createWorkspace(info.path), milestoneId),
568
+ );
565
569
 
566
570
  return info.path;
567
571
  }
@@ -0,0 +1,98 @@
1
+ import type { PreferenceDiagnostic } from "./preferences-types.js";
2
+ import {
3
+ loadGlobalGSDPreferences,
4
+ loadProjectGSDPreferences,
5
+ } from "./preferences.js";
6
+
7
+ interface PreferenceNotificationContext {
8
+ ui: {
9
+ notify(message: string, type?: "info" | "warning" | "error" | "success"): void;
10
+ };
11
+ }
12
+
13
+ interface PreferenceDiagnosticNotificationOptions {
14
+ surface?: string;
15
+ }
16
+
17
+ const notifiedPreferenceDiagnostics = new Set<string>();
18
+
19
+ export function collectPreferenceDiagnostics(basePath?: string): PreferenceDiagnostic[] {
20
+ const diagnostics = [
21
+ ...(loadGlobalGSDPreferences()?.diagnostics ?? []),
22
+ ...(loadProjectGSDPreferences(basePath)?.diagnostics ?? []),
23
+ ];
24
+
25
+ const seen = new Set<string>();
26
+ const unique: PreferenceDiagnostic[] = [];
27
+ for (const diagnostic of diagnostics) {
28
+ const signature = preferenceDiagnosticSignature(diagnostic);
29
+ if (seen.has(signature)) continue;
30
+ seen.add(signature);
31
+ unique.push(diagnostic);
32
+ }
33
+ return unique;
34
+ }
35
+
36
+ export function formatPreferenceDiagnostic(diagnostic: PreferenceDiagnostic): string {
37
+ const scope = diagnostic.scope === "global" ? "global" : "project";
38
+ const level = diagnostic.severity === "error" ? "error" : "warning";
39
+ const heading = diagnostic.kind === "parse"
40
+ ? `GSD ${scope} preferences ${level}: ${diagnostic.path} could not be parsed.`
41
+ : `GSD ${scope} preferences ${level}: ${diagnostic.path} contains invalid settings.`;
42
+ const detail = formatPreferenceDiagnosticDetail(diagnostic);
43
+ const impact = diagnostic.ignored
44
+ ? "Preferences from this file were ignored; auto-mode may be using defaults."
45
+ : "Invalid settings were ignored or sanitized; auto-mode may be using defaults for them.";
46
+ return `${heading}\n${detail}\n${impact}\nRun /gsd doctor for details.`;
47
+ }
48
+
49
+ export function formatPreferenceDiagnosticDetail(diagnostic: PreferenceDiagnostic): string {
50
+ if (diagnostic.line !== undefined && diagnostic.column !== undefined) {
51
+ return `YAML error at line ${diagnostic.line}, column ${diagnostic.column}: ${diagnostic.message}`;
52
+ }
53
+ return diagnostic.message;
54
+ }
55
+
56
+ export function notifyPreferenceDiagnostics(
57
+ ctx: PreferenceNotificationContext,
58
+ basePath?: string,
59
+ options?: PreferenceDiagnosticNotificationOptions,
60
+ ): number {
61
+ let notified = 0;
62
+ for (const diagnostic of collectPreferenceDiagnostics(basePath)) {
63
+ const signature = preferenceDiagnosticNotificationSignature(diagnostic, options?.surface);
64
+ if (notifiedPreferenceDiagnostics.has(signature)) continue;
65
+ notifiedPreferenceDiagnostics.add(signature);
66
+ ctx.ui.notify(
67
+ formatPreferenceDiagnostic(diagnostic),
68
+ diagnostic.severity === "error" ? "error" : "warning",
69
+ );
70
+ notified++;
71
+ }
72
+ return notified;
73
+ }
74
+
75
+ export function _resetPreferenceDiagnosticNotificationsForTests(): void {
76
+ notifiedPreferenceDiagnostics.clear();
77
+ }
78
+
79
+ function preferenceDiagnosticSignature(diagnostic: PreferenceDiagnostic): string {
80
+ return [
81
+ diagnostic.path,
82
+ diagnostic.scope,
83
+ diagnostic.severity,
84
+ diagnostic.kind,
85
+ diagnostic.message,
86
+ diagnostic.line ?? "",
87
+ diagnostic.column ?? "",
88
+ diagnostic.ignored === true ? "ignored" : "",
89
+ diagnostic.sanitized === true ? "sanitized" : "",
90
+ ].join("\u0000");
91
+ }
92
+
93
+ function preferenceDiagnosticNotificationSignature(
94
+ diagnostic: PreferenceDiagnostic,
95
+ surface = "default",
96
+ ): string {
97
+ return `${surface}\u0000${preferenceDiagnosticSignature(diagnostic)}`;
98
+ }
@@ -594,8 +594,24 @@ export interface LoadedGSDPreferences {
594
594
  path: string;
595
595
  scope: "global" | "project";
596
596
  preferences: GSDPreferences;
597
+ /** True when the file exists but its contents were ignored before merging. */
598
+ ignored?: boolean;
597
599
  /** Validation warnings (unknown keys, type mismatches, deprecations). Empty when preferences are clean. */
598
600
  warnings?: string[];
601
+ /** Structured parse/validation diagnostics for user-visible reporting. */
602
+ diagnostics?: PreferenceDiagnostic[];
603
+ }
604
+
605
+ export interface PreferenceDiagnostic {
606
+ path: string;
607
+ scope: "global" | "project";
608
+ severity: "error" | "warning";
609
+ kind: "parse" | "validation";
610
+ message: string;
611
+ line?: number;
612
+ column?: number;
613
+ ignored?: boolean;
614
+ sanitized?: boolean;
599
615
  }
600
616
 
601
617
  export interface SkillResolution {
@@ -29,6 +29,7 @@ import {
29
29
  type WorkflowMode,
30
30
  type GSDPreferences,
31
31
  type LoadedGSDPreferences,
32
+ type PreferenceDiagnostic,
32
33
  type SkillResolution,
33
34
  type SkillDiscoveryMode,
34
35
  formatSkillRef,
@@ -59,6 +60,7 @@ export type {
59
60
  ClaudeCodeMcpConfig,
60
61
  GSDPreferences,
61
62
  LoadedGSDPreferences,
63
+ PreferenceDiagnostic,
62
64
  SkillResolution,
63
65
  SkillResolutionReport,
64
66
  } from "./preferences-types.js";
@@ -173,14 +175,18 @@ export function normalizePreferencesShape(
173
175
  // ─── Loading ────────────────────────────────────────────────────────────────
174
176
 
175
177
  export function loadGlobalGSDPreferences(): LoadedGSDPreferences | null {
176
- return loadPreferencesFile(globalPreferencesPath(), "global")
177
- ?? loadPreferencesFile(legacyGlobalPreferencesPathLowercase(), "global")
178
- ?? loadPreferencesFile(legacyGlobalPreferencesPath(), "global");
178
+ return loadFirstUsablePreferencesFile([
179
+ globalPreferencesPath(),
180
+ legacyGlobalPreferencesPathLowercase(),
181
+ legacyGlobalPreferencesPath(),
182
+ ], "global");
179
183
  }
180
184
 
181
185
  export function loadProjectGSDPreferences(basePath?: string): LoadedGSDPreferences | null {
182
- return loadPreferencesFile(projectPreferencesPath(basePath), "project")
183
- ?? loadPreferencesFile(legacyProjectPreferencesPathLowercase(basePath), "project");
186
+ return loadFirstUsablePreferencesFile([
187
+ projectPreferencesPath(basePath),
188
+ legacyProjectPreferencesPathLowercase(basePath),
189
+ ], "project");
184
190
  }
185
191
 
186
192
  export function loadEffectiveGSDPreferences(
@@ -189,25 +195,25 @@ export function loadEffectiveGSDPreferences(
189
195
  ): LoadedGSDPreferences | null {
190
196
  const globalPreferences = loadGlobalGSDPreferences();
191
197
  const projectPreferences = loadProjectGSDPreferences(basePath);
192
- const projectHasPlanningDepth = projectPreferences?.preferences.planning_depth !== undefined;
198
+ const effectiveGlobalPreferences = globalPreferences?.ignored ? null : globalPreferences;
199
+ const effectiveProjectPreferences = projectPreferences?.ignored ? null : projectPreferences;
200
+ const projectHasPlanningDepth = effectiveProjectPreferences?.preferences.planning_depth !== undefined;
193
201
 
194
- if (!globalPreferences && !projectPreferences) return null;
202
+ if (!effectiveGlobalPreferences && !effectiveProjectPreferences) return null;
195
203
 
196
204
  let result: LoadedGSDPreferences;
197
- if (!globalPreferences) {
198
- result = projectPreferences!;
199
- } else if (!projectPreferences) {
200
- result = globalPreferences;
205
+ if (!effectiveGlobalPreferences) {
206
+ result = effectiveProjectPreferences!;
207
+ } else if (!effectiveProjectPreferences) {
208
+ result = mergePreferenceMetadata(effectiveGlobalPreferences, projectPreferences);
201
209
  } else {
202
- const mergedWarnings = [
203
- ...(globalPreferences.warnings ?? []),
204
- ...(projectPreferences.warnings ?? []),
205
- ];
210
+ const metadata = mergePreferenceMetadata(effectiveGlobalPreferences, effectiveProjectPreferences);
206
211
  result = {
207
- path: projectPreferences.path,
212
+ path: effectiveProjectPreferences.path,
208
213
  scope: "project",
209
- preferences: mergePreferences(globalPreferences.preferences, projectPreferences.preferences),
210
- ...(mergedWarnings.length > 0 ? { warnings: mergedWarnings } : {}),
214
+ preferences: mergePreferences(effectiveGlobalPreferences.preferences, effectiveProjectPreferences.preferences),
215
+ ...(metadata.warnings ? { warnings: metadata.warnings } : {}),
216
+ ...(metadata.diagnostics ? { diagnostics: metadata.diagnostics } : {}),
211
217
  };
212
218
  }
213
219
 
@@ -240,6 +246,43 @@ export function loadEffectiveGSDPreferences(
240
246
  return result;
241
247
  }
242
248
 
249
+ function mergePreferenceMetadata(
250
+ primary: LoadedGSDPreferences,
251
+ secondary: LoadedGSDPreferences | null,
252
+ ): LoadedGSDPreferences {
253
+ const mergedWarnings = [
254
+ ...(primary.warnings ?? []),
255
+ ...(secondary?.warnings ?? []),
256
+ ];
257
+ const mergedDiagnostics = [
258
+ ...(primary.diagnostics ?? []),
259
+ ...(secondary?.diagnostics ?? []),
260
+ ];
261
+ return {
262
+ ...primary,
263
+ ...(mergedWarnings.length > 0 ? { warnings: mergedWarnings } : {}),
264
+ ...(mergedDiagnostics.length > 0 ? { diagnostics: mergedDiagnostics } : {}),
265
+ };
266
+ }
267
+
268
+ function loadFirstUsablePreferencesFile(
269
+ paths: string[],
270
+ scope: "global" | "project",
271
+ ): LoadedGSDPreferences | null {
272
+ let ignoredPreferences: LoadedGSDPreferences | null = null;
273
+
274
+ for (const path of paths) {
275
+ const loaded = loadPreferencesFile(path, scope);
276
+ if (!loaded) continue;
277
+ if (!loaded.ignored) return mergePreferenceMetadata(loaded, ignoredPreferences);
278
+ ignoredPreferences = ignoredPreferences
279
+ ? mergePreferenceMetadata(ignoredPreferences, loaded)
280
+ : loaded;
281
+ }
282
+
283
+ return ignoredPreferences;
284
+ }
285
+
243
286
  function stripInheritedPlanningDepth(
244
287
  loaded: LoadedGSDPreferences,
245
288
  projectHasPlanningDepth: boolean,
@@ -260,17 +303,40 @@ function loadPreferencesFile(path: string, scope: "global" | "project"): LoadedG
260
303
  if (!existsSync(path)) return null;
261
304
 
262
305
  const raw = readFileSync(path, "utf-8");
263
- const preferences = parsePreferencesMarkdown(raw);
264
- if (!preferences) return null;
306
+ const parsed = parsePreferencesMarkdownWithDiagnostics(raw);
307
+ if (!parsed.preferences && parsed.diagnostics.length === 0) return null;
265
308
 
309
+ const ignored = parsed.diagnostics.some((diagnostic) => diagnostic.ignored === true);
310
+ const preferences = parsed.preferences ?? {};
266
311
  const validation = validatePreferences(preferences);
267
312
  const allWarnings = [...validation.warnings, ...validation.errors];
313
+ const diagnostics: PreferenceDiagnostic[] = [
314
+ ...parsed.diagnostics.map((diagnostic) => ({ ...diagnostic, path, scope })),
315
+ ...validation.errors.map((message): PreferenceDiagnostic => ({
316
+ path,
317
+ scope,
318
+ severity: "error",
319
+ kind: "validation",
320
+ message,
321
+ sanitized: true,
322
+ })),
323
+ ...validation.warnings.map((message): PreferenceDiagnostic => ({
324
+ path,
325
+ scope,
326
+ severity: "warning",
327
+ kind: "validation",
328
+ message,
329
+ sanitized: true,
330
+ })),
331
+ ];
268
332
 
269
333
  return {
270
334
  path,
271
335
  scope,
272
336
  preferences: validation.preferences,
337
+ ...(ignored ? { ignored: true } : {}),
273
338
  ...(allWarnings.length > 0 ? { warnings: allWarnings } : {}),
339
+ ...(diagnostics.length > 0 ? { diagnostics } : {}),
274
340
  };
275
341
  }
276
342
 
@@ -286,20 +352,44 @@ export function _resetParseWarningFlag(): void {
286
352
 
287
353
  /** @internal Exported for testing only */
288
354
  export function parsePreferencesMarkdown(content: string): GSDPreferences | null {
355
+ return parsePreferencesMarkdownWithDiagnostics(content).preferences;
356
+ }
357
+
358
+ type PreferenceParseDiagnostic = Omit<PreferenceDiagnostic, "path" | "scope">;
359
+
360
+ interface PreferenceParseResult {
361
+ preferences: GSDPreferences | null;
362
+ diagnostics: PreferenceParseDiagnostic[];
363
+ }
364
+
365
+ function parsePreferencesMarkdownWithDiagnostics(content: string): PreferenceParseResult {
289
366
  // Use indexOf instead of [\s\S]*? regex to avoid backtracking (#468)
290
367
  const startMarker = content.startsWith('---\r\n') ? '---\r\n' : '---\n';
291
368
  if (content.startsWith(startMarker)) {
292
369
  const searchStart = startMarker.length;
293
370
  const endIdx = content.indexOf('\n---', searchStart);
294
- if (endIdx === -1) return null;
371
+ if (endIdx === -1) {
372
+ return {
373
+ preferences: null,
374
+ diagnostics: [{
375
+ severity: "error",
376
+ kind: "parse",
377
+ message: "preferences frontmatter is missing a closing --- delimiter",
378
+ ignored: true,
379
+ }],
380
+ };
381
+ }
295
382
  const block = content.slice(searchStart, endIdx);
296
- return parseFrontmatterBlock(block.replace(/\r/g, ''));
383
+ return parseFrontmatterBlockWithDiagnostics(block.replace(/\r/g, ''), 1);
297
384
  }
298
385
 
299
386
  // Fallback: heading+list format (e.g. "## Git\n- isolation: none") (#2036)
300
387
  // GSD agents may write preferences files without frontmatter delimiters.
301
388
  if (/^##\s+\w/m.test(content)) {
302
- return parseHeadingListFormat(content);
389
+ return {
390
+ preferences: parseHeadingListFormat(content),
391
+ diagnostics: [],
392
+ };
303
393
  }
304
394
 
305
395
  // Warn when a non-empty file exists but lacks frontmatter delimiters (#2036).
@@ -310,27 +400,82 @@ export function parsePreferencesMarkdown(content: string): GSDPreferences | null
310
400
  "Wrap your preferences in --- fences. See https://github.com/open-gsd/gsd-pi/issues/2036",
311
401
  );
312
402
  }
313
- return null;
403
+ return {
404
+ preferences: null,
405
+ diagnostics: content.trim().length > 0
406
+ ? [{
407
+ severity: "error",
408
+ kind: "parse",
409
+ message: "preferences file has unrecognized format; expected YAML frontmatter delimiters (---) or markdown preference sections",
410
+ ignored: true,
411
+ }]
412
+ : [],
413
+ };
314
414
  }
315
415
 
316
416
  let _warnedFrontmatterParse = false;
317
- function parseFrontmatterBlock(frontmatter: string): GSDPreferences {
417
+ function parseFrontmatterBlockWithDiagnostics(
418
+ frontmatter: string,
419
+ lineOffset: number,
420
+ ): { preferences: GSDPreferences; diagnostics: PreferenceParseDiagnostic[] } {
318
421
  try {
319
422
  const parsed = parseYaml(frontmatter);
320
423
  if (typeof parsed !== 'object' || parsed === null) {
321
- return {} as GSDPreferences;
424
+ return {
425
+ preferences: {} as GSDPreferences,
426
+ diagnostics: [{
427
+ severity: "error",
428
+ kind: "validation",
429
+ message: "preferences frontmatter must be a YAML object",
430
+ ignored: true,
431
+ }],
432
+ };
322
433
  }
323
- return normalizeParsedPreferences(parsed as GSDPreferences);
434
+ return {
435
+ preferences: normalizeParsedPreferences(parsed as GSDPreferences),
436
+ diagnostics: [],
437
+ };
324
438
  } catch (e) {
325
439
  // Warn at most once per session to avoid flooding TUI (#3376)
326
440
  if (!_warnedFrontmatterParse) {
327
441
  _warnedFrontmatterParse = true;
328
442
  logWarning("guided", `YAML parse error in preferences frontmatter (suppressing further): ${(e as Error).message}`);
329
443
  }
330
- return {} as GSDPreferences;
444
+ const location = extractYamlErrorLocation(e, lineOffset);
445
+ return {
446
+ preferences: {} as GSDPreferences,
447
+ diagnostics: [{
448
+ severity: "error",
449
+ kind: "parse",
450
+ message: cleanYamlErrorMessage(e),
451
+ ...(location.line !== undefined ? { line: location.line } : {}),
452
+ ...(location.column !== undefined ? { column: location.column } : {}),
453
+ ignored: true,
454
+ }],
455
+ };
331
456
  }
332
457
  }
333
458
 
459
+ function cleanYamlErrorMessage(error: unknown): string {
460
+ const message = error instanceof Error ? error.message : String(error);
461
+ const firstLine = message.split("\n")[0]?.trim() ?? "unknown YAML parse error";
462
+ return firstLine.replace(/\s+at line \d+, column \d+:?$/, "");
463
+ }
464
+
465
+ function extractYamlErrorLocation(
466
+ error: unknown,
467
+ lineOffset: number,
468
+ ): { line?: number; column?: number } {
469
+ const linePos = (error as { linePos?: Array<{ line?: unknown; col?: unknown }> })?.linePos;
470
+ const first = Array.isArray(linePos) ? linePos[0] : undefined;
471
+ const line = typeof first?.line === "number" ? first.line + lineOffset : undefined;
472
+ const column = typeof first?.col === "number" ? first.col : undefined;
473
+ return {
474
+ ...(line !== undefined ? { line } : {}),
475
+ ...(column !== undefined ? { column } : {}),
476
+ };
477
+ }
478
+
334
479
  function normalizeParsedPreferences(preferences: GSDPreferences): GSDPreferences {
335
480
  const remoteQuestions = preferences.remote_questions;
336
481
  if (remoteQuestions && typeof remoteQuestions === "object" && typeof remoteQuestions.channel_id === "number") {
@@ -37,6 +37,7 @@ Use `subagent` only when useful: reviewer, security, or tester. Apply findings b
37
37
  9. If requirement status changed, call `gsd_requirement_update`; do not write `.gsd/REQUIREMENTS.md` directly.
38
38
  10. Prepare `gsd_slice_complete` content with camelCase fields `milestoneId`, `sliceId`, `sliceTitle`, `oneLiner`, `narrative`, `verification`, and `uatContent`.
39
39
  11. Draft concrete UAT with preconditions, steps, expected outcomes, edge cases, and UAT Type.
40
+ **Web apps:** when inlined Web App UAT guidance is present, declare `browser-executable` or `runtime-executable` (not `artifact-driven`) for localhost/browser/screenshot steps; include dev-server preconditions and name Playwright specs when they exist.
40
41
  12. Review the inlined task-summary excerpts for DECISIONS.md/KNOWLEDGE.md-worthy decisions and gotchas. Read full `*-SUMMARY.md` only if needed. Capture with `capture_thought`; do not append knowledge files.
41
42
  13. When verification passes, call `gsd_slice_complete`. The DB-backed tool is the canonical write path. Do **not** manually write `{{sliceSummaryPath}}`. Do **not** manually write `{{sliceUatPath}}`. Do not edit roadmap checkboxes.
42
43
  14. Do not run git commands.
@@ -31,18 +31,17 @@ After reflection is confirmed, choose the approach from actual scope, not a labe
31
31
 
32
32
  {{preparationContext}}
33
33
 
34
- ## Mandatory Investigation Before First Question Round
34
+ ## Ground the First Question Round
35
35
 
36
- Before the first question round, gather enough evidence for grounded questions:
37
- 1. Scout relevant code with `ls`, `find`, `rg`, or `scout`.
38
- 2. Check mentioned tech with `resolve_library` / `get_library_docs`.
39
- 3. Use web tools only for current external facts.
36
+ Ground your questions in the **Preparation Context above** (codebase snapshot, prior context) plus the user's reflected vision — that is authoritative. **Do not survey the codebase** with `ls`/`find`/`rg`/`scout` before asking; the snapshot already covers code reality. Read a specific file only when a question's answer genuinely hinges on it.
37
+ 1. Check mentioned tech with `resolve_library` / `get_library_docs`.
38
+ 2. Use web tools only for current external facts.
40
39
 
41
- Budget searches across the discussion; prefer docs and one-shot `search_and_read`. Re-investigate only when answers expose new gaps.
40
+ Budget searches across the discussion; prefer docs and one-shot `search_and_read`. Read on-demand only when an answer exposes a specific gap.
42
41
 
43
42
  ## Layered Question Rounds
44
43
 
45
- Questions have four layers. At each layer, ask 1-3 open questions per round, investigate as needed, and gate before advancing.
44
+ Questions have four layers. At each layer, ask 1-3 open questions per round, read a specific file on-demand if an answer needs it, and gate before advancing.
46
45
 
47
46
  **Default to open questions.** Use `ask_user_questions` only for 2-3 distinct paths with clear tradeoffs. Use plain text for nuanced design questions.
48
47
 
@@ -32,6 +32,8 @@ You execute. The inlined task plan is authoritative. Verify referenced files and
32
32
  - Prior task summaries:
33
33
  {{priorTaskLines}}
34
34
 
35
+ {{onDemandContext}}
36
+
35
37
  ## Execution Rules
36
38
 
37
39
  1. Tersely narrate transitions, decisions, and verification outcomes between tool-call clusters.
@@ -19,15 +19,13 @@ Discuss milestone {{milestoneId}} ("{{milestoneTitle}}"). Identify real gray are
19
19
  Before asking, read `.gsd/PROJECT.md` and find `## Project Shape` -> `**Complexity:**`. Use `simple` or `complex`; default to `complex` if missing, stale, or unclear.
20
20
 
21
21
  - `simple`: 1-2 plain-text rounds; skip parallel-research investigation; use `ask_user_questions` only for concrete alternatives.
22
- - `complex`: investigate first, use 3-4-option structured questions, and expect multiple rounds.
22
+ - `complex`: ground in the preloaded context first, use 3-4-option structured questions, and expect multiple rounds.
23
23
 
24
24
  ### Before your first question round
25
25
 
26
- Investigate enough to avoid assumption-driven questions:
27
- - Scout existing code with `rg`, `find`, or `scout`.
28
- - Check roadmap context above for surrounding scope.
29
- - Use `resolve_library` / `get_library_docs` for unfamiliar libraries; prefer them over web search.
26
+ Ground your questions in the **preloaded context above** (milestone roadmap/context/research, the decisions register, prior-milestone summaries) plus any Preparation Context snapshot — those are authoritative. **Do not survey the codebase** with `rg`/`find`/`scout` before asking; the preloaded files are marked do-not-re-read. Read a specific file only when a question's answer genuinely hinges on it.
30
27
  - Identify the 3-5 behavioral or architectural unknowns that materially change what gets built.
28
+ - Use `resolve_library` / `get_library_docs` for unfamiliar libraries; prefer them over web search.
31
29
 
32
30
  **Web search budget:** Limited per turn, typically 3-5. Prefer docs tools and `search_and_read`; use 2-3 searches in the first pass and save the rest.
33
31
 
@@ -43,13 +41,13 @@ Ask **1–3 questions per round**. Target one focus at a time:
43
41
 
44
42
  **Never fabricate or simulate user input.** Never generate fake transcript markers like `[User]`, `[Human]`, or `User:`. Ask one question round, then wait for the user's actual response before continuing.
45
43
 
46
- **Single user-facing message (NON-BYPASSABLE):** After investigation, send **one** assistant message that contains your questions (and at most a short recap — 2-3 sentences, not a feature catalog). **End the turn there.** Do not send a second message that restates the same ask ("what do you want M00X to be?", "before I can write the context file…", etc.). If you already asked, stop — do not elaborate in a follow-up message in the same turn.
44
+ **Single user-facing message (NON-BYPASSABLE):** After grounding in the preloaded context, send **one** assistant message that contains your questions (and at most a short recap — 2-3 sentences, not a feature catalog). **End the turn there.** Do not send a second message that restates the same ask ("what do you want M00X to be?", "before I can write the context file…", etc.). If you already asked, stop — do not elaborate in a follow-up message in the same turn.
47
45
 
48
46
  **If `{{structuredQuestionsAvailable}}` is `true`:** use `ask_user_questions` exactly once per turn with 1-3 question objects. Keep labels short (3-5 words). In `complex` mode, multi-choice questions MUST offer **3 or 4 concrete, researched options** plus **"Other — let me discuss"**; options must be grounded in the investigation, not placeholders. In `simple` mode, 2 options is fine for binary alternatives. Binary depth-check/wrap-up gates are exempt. If the user chooses "Other — let me discuss" or gives a long freeform answer, switch to plain-text follow-up before resuming structured questions.
49
47
 
50
48
  **If `{{structuredQuestionsAvailable}}` is `false`:** ask questions in plain text. Keep each round to 1–3 focused questions. Wait for answers before asking the next round.
51
49
 
52
- After each answer, investigate only new unknowns, then ask the next round.
50
+ After each answer, resolve only the new unknowns from context (re-read a specific file only if one is needed), then ask the next round.
53
51
 
54
52
  ### Round cadence
55
53