@opengsd/gsd-pi 1.2.0-dev.0b870afa → 1.2.0-dev.23d85b63

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 (579) hide show
  1. package/dist/cli-model-override.d.ts +15 -0
  2. package/dist/cli-model-override.js +21 -0
  3. package/dist/cli.js +14 -19
  4. package/dist/headless-events.d.ts +16 -1
  5. package/dist/headless-events.js +19 -2
  6. package/dist/headless.js +8 -1
  7. package/dist/loader.js +6 -4
  8. package/dist/onboarding.js +9 -4
  9. package/dist/provider-migrations.d.ts +23 -0
  10. package/dist/provider-migrations.js +41 -0
  11. package/dist/register-agent-bundles.d.ts +11 -2
  12. package/dist/register-agent-bundles.js +18 -4
  13. package/dist/resource-loader.d.ts +10 -5
  14. package/dist/resource-loader.js +121 -6
  15. package/dist/resources/.managed-resources-content-hash +1 -1
  16. package/dist/resources/extensions/ask-user-questions.js +3 -2
  17. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +447 -215
  18. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +33 -1
  19. package/dist/resources/extensions/google-cli/stream-adapter.js +16 -1
  20. package/dist/resources/extensions/gsd/auto/closeout.js +215 -0
  21. package/dist/resources/extensions/gsd/auto/dispatch-history.js +21 -6
  22. package/dist/resources/extensions/gsd/auto/dispatch.js +365 -0
  23. package/dist/resources/extensions/gsd/auto/finalize.js +347 -0
  24. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  25. package/dist/resources/extensions/gsd/auto/milestone-lease-reclaim.js +56 -0
  26. package/dist/resources/extensions/gsd/auto/orchestrator.js +119 -18
  27. package/dist/resources/extensions/gsd/auto/phase-helpers.js +146 -0
  28. package/dist/resources/extensions/gsd/auto/phases.js +17 -2372
  29. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +542 -0
  30. package/dist/resources/extensions/gsd/auto/unit-phase.js +694 -0
  31. package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +1 -1
  32. package/dist/resources/extensions/gsd/auto/worktree-safety-phase.js +125 -0
  33. package/dist/resources/extensions/gsd/auto-closeout-messaging.js +90 -0
  34. package/dist/resources/extensions/gsd/auto-dashboard.js +255 -431
  35. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +15 -3
  36. package/dist/resources/extensions/gsd/auto-dispatch.js +19 -1
  37. package/dist/resources/extensions/gsd/auto-model-selection.js +9 -6
  38. package/dist/resources/extensions/gsd/auto-post-unit.js +12 -8
  39. package/dist/resources/extensions/gsd/auto-prompts.js +5 -1
  40. package/dist/resources/extensions/gsd/auto-recovery.js +52 -6
  41. package/dist/resources/extensions/gsd/auto-start.js +28 -7
  42. package/dist/resources/extensions/gsd/auto-worktree.js +48 -3
  43. package/dist/resources/extensions/gsd/auto.js +83 -19
  44. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +4 -2
  45. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -7
  46. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +3 -1
  47. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +32 -3
  48. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +56 -16
  49. package/dist/resources/extensions/gsd/closeout-wizard.js +8 -3
  50. package/dist/resources/extensions/gsd/commands/handlers/core.js +22 -8
  51. package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
  52. package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -2
  53. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +8 -0
  54. package/dist/resources/extensions/gsd/commands-workflow-templates.js +9 -2
  55. package/dist/resources/extensions/gsd/config-overlay.js +11 -8
  56. package/dist/resources/extensions/gsd/db/engine.js +24 -6
  57. package/dist/resources/extensions/gsd/db/queries.js +30 -0
  58. package/dist/resources/extensions/gsd/db/writers/reconcile.js +19 -1
  59. package/dist/resources/extensions/gsd/db-migration-backup.js +51 -8
  60. package/dist/resources/extensions/gsd/db-transaction.js +27 -23
  61. package/dist/resources/extensions/gsd/db-writer.js +8 -17
  62. package/dist/resources/extensions/gsd/doctor-environment.js +256 -125
  63. package/dist/resources/extensions/gsd/doctor-git-checks.js +5 -1
  64. package/dist/resources/extensions/gsd/doctor-providers.js +1 -1
  65. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +11 -9
  66. package/dist/resources/extensions/gsd/gsd-db.js +15 -20
  67. package/dist/resources/extensions/gsd/guided-flow.js +88 -2
  68. package/dist/resources/extensions/gsd/health-widget.js +87 -28
  69. package/dist/resources/extensions/gsd/mcp-bridge.js +10 -0
  70. package/dist/resources/extensions/gsd/memory-relations.js +1 -1
  71. package/dist/resources/extensions/gsd/milestone-settlement.js +2 -2
  72. package/dist/resources/extensions/gsd/notifications.js +12 -7
  73. package/dist/resources/extensions/gsd/preferences-models.js +17 -9
  74. package/dist/resources/extensions/gsd/preferences.js +91 -5
  75. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +8 -2
  76. package/dist/resources/extensions/gsd/prompts/complete-slice.md +6 -2
  77. package/dist/resources/extensions/gsd/prompts/execute-task.md +7 -2
  78. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  79. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +2 -2
  80. package/dist/resources/extensions/gsd/prompts/run-uat.md +7 -1
  81. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  82. package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  83. package/dist/resources/extensions/gsd/provider-error-guidance.js +24 -0
  84. package/dist/resources/extensions/gsd/session-lock.js +4 -3
  85. package/dist/resources/extensions/gsd/skill-activation.js +3 -6
  86. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +13 -6
  87. package/dist/resources/extensions/gsd/state.js +6 -2
  88. package/dist/resources/extensions/gsd/tool-surface-readiness.js +83 -31
  89. package/dist/resources/extensions/gsd/tools/complete-task.js +62 -0
  90. package/dist/resources/extensions/gsd/tools/exec-tool.js +2 -109
  91. package/dist/resources/extensions/gsd/tui/render-kit.js +38 -13
  92. package/dist/resources/extensions/gsd/unit-context-composer.js +1 -1
  93. package/dist/resources/extensions/gsd/unit-registry.js +34 -4
  94. package/dist/resources/extensions/gsd/workflow-logger.js +4 -0
  95. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +2 -0
  96. package/dist/resources/extensions/gsd/workflow-mcp-readiness-cache.js +105 -0
  97. package/dist/resources/extensions/gsd/worktree-manager.js +101 -2
  98. package/dist/resources/extensions/gsd/worktree-safety.js +28 -26
  99. package/dist/resources/extensions/gsd/worktree-shell-guard.js +113 -0
  100. package/dist/resources/extensions/gsd/worktree.js +8 -1
  101. package/dist/resources/extensions/mcp-client/manager.js +6 -1
  102. package/dist/resources/extensions/search-the-web/index.js +41 -9
  103. package/dist/resources/extensions/search-the-web/native-search.js +18 -4
  104. package/dist/resources/extensions/shared/gsd-browser-cli.js +40 -2
  105. package/dist/resources/extensions/subagent/index.js +20 -15
  106. package/dist/resources/extensions/subagent/worktree-cwd.js +31 -0
  107. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  108. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  109. package/dist/runtime-checks.d.ts +10 -0
  110. package/dist/runtime-checks.js +27 -0
  111. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  112. package/dist/web/standalone/.next/BUILD_ID +1 -1
  113. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  114. package/dist/web/standalone/.next/build-manifest.json +2 -2
  115. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  116. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  133. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  134. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  135. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  136. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  137. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  138. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  139. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  140. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  142. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  143. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  144. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  145. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  146. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  147. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  148. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  149. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  150. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  151. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  152. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  154. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  155. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  156. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  158. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  160. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  162. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  164. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  166. package/dist/web/standalone/.next/server/app/index.html +1 -1
  167. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  169. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  170. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  171. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  172. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  173. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  174. package/dist/web/standalone/.next/server/chunks/{5942.js → 1128.js} +1 -1
  175. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  176. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  178. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  179. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  180. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  181. package/package.json +4 -4
  182. package/packages/cloud-mcp-gateway/package.json +2 -2
  183. package/packages/contracts/package.json +1 -1
  184. package/packages/daemon/package.json +4 -4
  185. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  186. package/packages/gsd-agent-core/dist/sdk.js +12 -6
  187. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  188. package/packages/gsd-agent-core/package.json +5 -5
  189. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.d.ts +5 -5
  190. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  191. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js +12 -24
  192. package/packages/gsd-agent-modes/dist/modes/interactive/components/assistant-message.js.map +1 -1
  193. package/packages/gsd-agent-modes/dist/modes/interactive/components/bash-execution.js +5 -5
  194. package/packages/gsd-agent-modes/dist/modes/interactive/components/bash-execution.js.map +1 -1
  195. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.d.ts +3 -3
  196. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  197. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.js +20 -11
  198. package/packages/gsd-agent-modes/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  199. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-turn-connect.d.ts +4 -3
  200. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-turn-connect.d.ts.map +1 -1
  201. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-turn-connect.js +5 -54
  202. package/packages/gsd-agent-modes/dist/modes/interactive/components/chat-turn-connect.js.map +1 -1
  203. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.d.ts +2 -4
  204. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  205. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.js +2 -4
  206. package/packages/gsd-agent-modes/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  207. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.d.ts +2 -0
  208. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  209. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.js +4 -0
  210. package/packages/gsd-agent-modes/dist/modes/interactive/components/custom-editor.js.map +1 -1
  211. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.d.ts +9 -12
  212. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.d.ts.map +1 -1
  213. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.js +100 -166
  214. package/packages/gsd-agent-modes/dist/modes/interactive/components/footer.js.map +1 -1
  215. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-progress-state.d.ts +2 -0
  216. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-progress-state.d.ts.map +1 -0
  217. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-progress-state.js +4 -0
  218. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-progress-state.js.map +1 -0
  219. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-status-widget.d.ts +23 -0
  220. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-status-widget.d.ts.map +1 -0
  221. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-status-widget.js +178 -0
  222. package/packages/gsd-agent-modes/dist/modes/interactive/components/gsd-status-widget.js.map +1 -0
  223. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts +8 -0
  224. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  225. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js +21 -9
  226. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js.map +1 -1
  227. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
  228. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  229. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
  230. package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
  231. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -3
  232. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  233. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.js +2 -3
  234. package/packages/gsd-agent-modes/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  235. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +11 -0
  236. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  237. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +85 -19
  238. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  239. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +71 -3
  240. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  241. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +257 -37
  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/components/user-message.d.ts +3 -3
  244. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  245. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message.js +19 -19
  246. package/packages/gsd-agent-modes/dist/modes/interactive/components/user-message.js.map +1 -1
  247. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -0
  248. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  249. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -10
  250. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  251. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/extension-ui-controller.d.ts.map +1 -1
  252. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/extension-ui-controller.js +12 -1
  253. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/extension-ui-controller.js.map +1 -1
  254. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  255. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +5 -0
  256. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  257. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
  258. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.js +3 -1
  259. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
  260. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  261. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +3 -5
  262. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  263. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js +2 -2
  264. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
  265. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts +1 -0
  266. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
  267. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +25 -0
  268. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
  269. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-key-handlers.d.ts.map +1 -1
  270. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-key-handlers.js +1 -0
  271. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-key-handlers.js.map +1 -1
  272. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-init.d.ts +1 -0
  273. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-init.d.ts.map +1 -1
  274. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-init.js +20 -49
  275. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-init.js.map +1 -1
  276. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +4 -0
  277. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  278. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  279. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +10 -2
  280. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  281. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +48 -6
  282. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  283. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
  284. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +4 -0
  285. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
  286. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-ui-messaging.d.ts.map +1 -1
  287. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-ui-messaging.js +0 -1
  288. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-ui-messaging.js.map +1 -1
  289. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  290. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -0
  291. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  292. package/packages/gsd-agent-modes/package.json +7 -7
  293. package/packages/mcp-server/README.md +12 -3
  294. package/packages/mcp-server/dist/cli-runner.d.ts +40 -0
  295. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -0
  296. package/packages/mcp-server/dist/cli-runner.js +137 -0
  297. package/packages/mcp-server/dist/cli-runner.js.map +1 -0
  298. package/packages/mcp-server/dist/cli.js +2 -58
  299. package/packages/mcp-server/dist/cli.js.map +1 -1
  300. package/packages/mcp-server/dist/pid-registry.d.ts +46 -0
  301. package/packages/mcp-server/dist/pid-registry.d.ts.map +1 -0
  302. package/packages/mcp-server/dist/pid-registry.js +459 -0
  303. package/packages/mcp-server/dist/pid-registry.js.map +1 -0
  304. package/packages/mcp-server/dist/probe-mode.d.ts +4 -0
  305. package/packages/mcp-server/dist/probe-mode.d.ts.map +1 -0
  306. package/packages/mcp-server/dist/probe-mode.js +10 -0
  307. package/packages/mcp-server/dist/probe-mode.js.map +1 -0
  308. package/packages/mcp-server/dist/stdio-watchdog.d.ts +8 -0
  309. package/packages/mcp-server/dist/stdio-watchdog.d.ts.map +1 -0
  310. package/packages/mcp-server/dist/stdio-watchdog.js +40 -0
  311. package/packages/mcp-server/dist/stdio-watchdog.js.map +1 -0
  312. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  313. package/packages/mcp-server/dist/workflow-tools.js +62 -43
  314. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  315. package/packages/mcp-server/package.json +5 -5
  316. package/packages/native/package.json +1 -1
  317. package/packages/pi-agent-core/dist/agent-loop.js +52 -2
  318. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  319. package/packages/pi-agent-core/package.json +1 -1
  320. package/packages/pi-ai/package.json +1 -1
  321. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +28 -2
  322. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
  323. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
  324. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  325. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  326. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  327. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +5 -1
  328. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  329. package/packages/pi-coding-agent/dist/core/extensions/runner.js +3 -1
  330. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  331. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
  332. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  333. package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
  334. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  335. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  336. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  337. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  338. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  339. package/packages/pi-coding-agent/dist/theme/theme.js +45 -17
  340. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  341. package/packages/pi-coding-agent/package.json +8 -8
  342. package/packages/pi-tui/README.md +15 -0
  343. package/packages/pi-tui/dist/autocomplete.d.ts.map +1 -1
  344. package/packages/pi-tui/dist/autocomplete.js +6 -1
  345. package/packages/pi-tui/dist/autocomplete.js.map +1 -1
  346. package/packages/pi-tui/dist/components/input.js +1 -1
  347. package/packages/pi-tui/dist/components/input.js.map +1 -1
  348. package/packages/pi-tui/dist/components/loader.d.ts.map +1 -1
  349. package/packages/pi-tui/dist/components/loader.js +1 -0
  350. package/packages/pi-tui/dist/components/loader.js.map +1 -1
  351. package/packages/pi-tui/dist/components/select-list.d.ts.map +1 -1
  352. package/packages/pi-tui/dist/components/select-list.js +8 -2
  353. package/packages/pi-tui/dist/components/select-list.js.map +1 -1
  354. package/packages/pi-tui/dist/index.d.ts +2 -2
  355. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  356. package/packages/pi-tui/dist/index.js +2 -2
  357. package/packages/pi-tui/dist/index.js.map +1 -1
  358. package/packages/pi-tui/dist/terminal-image.d.ts +33 -0
  359. package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
  360. package/packages/pi-tui/dist/terminal-image.js +54 -2
  361. package/packages/pi-tui/dist/terminal-image.js.map +1 -1
  362. package/packages/pi-tui/dist/terminal.d.ts +12 -0
  363. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  364. package/packages/pi-tui/dist/terminal.js +70 -25
  365. package/packages/pi-tui/dist/terminal.js.map +1 -1
  366. package/packages/pi-tui/dist/tui.d.ts +15 -0
  367. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  368. package/packages/pi-tui/dist/tui.js +106 -21
  369. package/packages/pi-tui/dist/tui.js.map +1 -1
  370. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  371. package/packages/pi-tui/dist/utils.js +110 -36
  372. package/packages/pi-tui/dist/utils.js.map +1 -1
  373. package/packages/pi-tui/package.json +2 -2
  374. package/packages/rpc-client/package.json +2 -2
  375. package/pkg/dist/theme/theme.d.ts.map +1 -1
  376. package/pkg/dist/theme/theme.js +45 -17
  377. package/pkg/dist/theme/theme.js.map +1 -1
  378. package/pkg/package.json +1 -1
  379. package/src/resources/extensions/ask-user-questions.ts +7 -2
  380. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +80 -0
  381. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +531 -226
  382. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +672 -7
  383. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +38 -1
  384. package/src/resources/extensions/google-cli/stream-adapter.ts +22 -1
  385. package/src/resources/extensions/gsd/auto/closeout.ts +309 -0
  386. package/src/resources/extensions/gsd/auto/dispatch-history.ts +22 -6
  387. package/src/resources/extensions/gsd/auto/dispatch.ts +449 -0
  388. package/src/resources/extensions/gsd/auto/finalize.ts +445 -0
  389. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  390. package/src/resources/extensions/gsd/auto/milestone-lease-reclaim.ts +74 -0
  391. package/src/resources/extensions/gsd/auto/orchestrator.ts +140 -18
  392. package/src/resources/extensions/gsd/auto/phase-helpers.ts +199 -0
  393. package/src/resources/extensions/gsd/auto/phases.ts +58 -3061
  394. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +716 -0
  395. package/src/resources/extensions/gsd/auto/unit-phase.ts +910 -0
  396. package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +1 -1
  397. package/src/resources/extensions/gsd/auto/worktree-safety-phase.ts +149 -0
  398. package/src/resources/extensions/gsd/auto-closeout-messaging.ts +90 -0
  399. package/src/resources/extensions/gsd/auto-dashboard.ts +310 -454
  400. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +15 -2
  401. package/src/resources/extensions/gsd/auto-dispatch.ts +24 -2
  402. package/src/resources/extensions/gsd/auto-model-selection.ts +20 -5
  403. package/src/resources/extensions/gsd/auto-post-unit.ts +16 -9
  404. package/src/resources/extensions/gsd/auto-prompts.ts +5 -1
  405. package/src/resources/extensions/gsd/auto-recovery.ts +62 -8
  406. package/src/resources/extensions/gsd/auto-start.ts +44 -7
  407. package/src/resources/extensions/gsd/auto-worktree.ts +51 -3
  408. package/src/resources/extensions/gsd/auto.ts +118 -18
  409. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +6 -2
  410. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +56 -6
  411. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -1
  412. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +36 -3
  413. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +69 -16
  414. package/src/resources/extensions/gsd/closeout-wizard.ts +11 -2
  415. package/src/resources/extensions/gsd/commands/handlers/core.ts +27 -8
  416. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -2
  417. package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -2
  418. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +7 -0
  419. package/src/resources/extensions/gsd/commands-workflow-templates.ts +11 -4
  420. package/src/resources/extensions/gsd/config-overlay.ts +22 -9
  421. package/src/resources/extensions/gsd/db/engine.ts +26 -6
  422. package/src/resources/extensions/gsd/db/queries.ts +29 -0
  423. package/src/resources/extensions/gsd/db/writers/reconcile.ts +24 -1
  424. package/src/resources/extensions/gsd/db-migration-backup.ts +56 -7
  425. package/src/resources/extensions/gsd/db-transaction.ts +37 -20
  426. package/src/resources/extensions/gsd/db-writer.ts +11 -19
  427. package/src/resources/extensions/gsd/doctor-environment.ts +267 -142
  428. package/src/resources/extensions/gsd/doctor-git-checks.ts +4 -1
  429. package/src/resources/extensions/gsd/doctor-providers.ts +1 -1
  430. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +10 -10
  431. package/src/resources/extensions/gsd/gsd-db.ts +15 -19
  432. package/src/resources/extensions/gsd/guided-flow.ts +128 -2
  433. package/src/resources/extensions/gsd/health-widget.ts +91 -27
  434. package/src/resources/extensions/gsd/mcp-bridge.ts +39 -0
  435. package/src/resources/extensions/gsd/memory-relations.ts +1 -1
  436. package/src/resources/extensions/gsd/milestone-settlement.ts +2 -2
  437. package/src/resources/extensions/gsd/notifications.ts +13 -6
  438. package/src/resources/extensions/gsd/preferences-models.ts +26 -8
  439. package/src/resources/extensions/gsd/preferences.ts +111 -5
  440. package/src/resources/extensions/gsd/prompts/complete-milestone.md +8 -2
  441. package/src/resources/extensions/gsd/prompts/complete-slice.md +6 -2
  442. package/src/resources/extensions/gsd/prompts/execute-task.md +7 -2
  443. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  444. package/src/resources/extensions/gsd/prompts/reactive-execute.md +2 -2
  445. package/src/resources/extensions/gsd/prompts/run-uat.md +7 -1
  446. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  447. package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -1
  448. package/src/resources/extensions/gsd/provider-error-guidance.ts +32 -0
  449. package/src/resources/extensions/gsd/session-lock.ts +8 -7
  450. package/src/resources/extensions/gsd/skill-activation.ts +3 -6
  451. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +23 -10
  452. package/src/resources/extensions/gsd/state.ts +7 -1
  453. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +1 -1
  454. package/src/resources/extensions/gsd/tests/auto-blocked-remediation-message.test.ts +1 -1
  455. package/src/resources/extensions/gsd/tests/auto-closeout-messaging.test.ts +71 -0
  456. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +68 -116
  457. package/src/resources/extensions/gsd/tests/auto-direct-dispatch-parse.test.ts +33 -0
  458. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +206 -22
  459. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +7 -2
  460. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +16 -1
  461. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +89 -22
  462. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +1 -1
  463. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +97 -4
  464. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +2 -1
  465. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
  466. package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +169 -1
  467. package/src/resources/extensions/gsd/tests/auto-verification.test.ts +36 -0
  468. package/src/resources/extensions/gsd/tests/blocker-placeholder-logs.test.ts +218 -0
  469. package/src/resources/extensions/gsd/tests/complete-milestone-prompt-rendering.test.ts +6 -2
  470. package/src/resources/extensions/gsd/tests/complete-task.test.ts +141 -5
  471. package/src/resources/extensions/gsd/tests/core-overlay-fallback.test.ts +1 -0
  472. package/src/resources/extensions/gsd/tests/db-engine-logs.test.ts +207 -0
  473. package/src/resources/extensions/gsd/tests/db-migration-backup.test.ts +68 -19
  474. package/src/resources/extensions/gsd/tests/db-transaction.test.ts +59 -0
  475. package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
  476. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +2 -1
  477. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +62 -0
  478. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  479. package/src/resources/extensions/gsd/tests/dispatch-db-degradation-logs.test.ts +98 -0
  480. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +55 -0
  481. package/src/resources/extensions/gsd/tests/dispatch-logs.test.ts +103 -0
  482. package/src/resources/extensions/gsd/tests/dispatch-reactive-logs.test.ts +98 -0
  483. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +8 -0
  484. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +6 -4
  485. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +117 -91
  486. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +113 -0
  487. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -1
  488. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +40 -7
  489. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +19 -0
  490. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +16 -0
  491. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +75 -0
  492. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +15 -0
  493. package/src/resources/extensions/gsd/tests/integration/doctor-environment-async.test.ts +104 -0
  494. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +18 -0
  495. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +1 -0
  496. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +47 -16
  497. package/src/resources/extensions/gsd/tests/loop.test.ts +60 -0
  498. package/src/resources/extensions/gsd/tests/mcp-readiness-preflight.test.ts +205 -0
  499. package/src/resources/extensions/gsd/tests/mcp-status.test.ts +6 -5
  500. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +1 -1
  501. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +1 -1
  502. package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +92 -0
  503. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +1 -1
  504. package/src/resources/extensions/gsd/tests/model-router.test.ts +139 -0
  505. package/src/resources/extensions/gsd/tests/notifications.test.ts +64 -9
  506. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +13 -1
  507. package/src/resources/extensions/gsd/tests/orchestrator-legacy-parity.test.ts +1 -1
  508. package/src/resources/extensions/gsd/tests/orchestrator-logs.test.ts +335 -0
  509. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +2 -2
  510. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +5 -0
  511. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +1 -1
  512. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +1 -1
  513. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +3 -3
  514. package/src/resources/extensions/gsd/tests/prefs-missing-models-crash.test.ts +35 -4
  515. package/src/resources/extensions/gsd/tests/progress-strip-test-helpers.ts +79 -0
  516. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +2 -0
  517. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +11 -2
  518. package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +15 -0
  519. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -4
  520. package/src/resources/extensions/gsd/tests/reconcile-logs.test.ts +244 -0
  521. package/src/resources/extensions/gsd/tests/recovery-finalize-logs.test.ts +119 -0
  522. package/src/resources/extensions/gsd/tests/recovery-verify-logs.test.ts +428 -0
  523. package/src/resources/extensions/gsd/tests/register-extension-guard.test.ts +25 -0
  524. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +31 -81
  525. package/src/resources/extensions/gsd/tests/resume-missing-worktree-warning.test.ts +5 -5
  526. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +7 -1
  527. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +68 -0
  528. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +3 -0
  529. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +170 -48
  530. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -17
  531. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +7 -3
  532. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +17 -1
  533. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +1 -1
  534. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  535. package/src/resources/extensions/gsd/tests/thinking-level-resolution.test.ts +1 -1
  536. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -2
  537. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +184 -10
  538. package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +40 -86
  539. package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +44 -6
  540. package/src/resources/extensions/gsd/tests/uok-audit.test.ts +194 -0
  541. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  542. package/src/resources/extensions/gsd/tests/workflow-mcp-readiness-cache.test.ts +119 -0
  543. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +65 -2
  544. package/src/resources/extensions/gsd/tests/workflow-phase-contract-matrix.test.ts +332 -0
  545. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +92 -0
  546. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +1 -1
  547. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +36 -0
  548. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +1 -1
  549. package/src/resources/extensions/gsd/tests/worktree-safety-phase.test.ts +100 -0
  550. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +72 -0
  551. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
  552. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +75 -3
  553. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  554. package/src/resources/extensions/gsd/tool-surface-readiness.ts +126 -19
  555. package/src/resources/extensions/gsd/tools/complete-task.ts +87 -0
  556. package/src/resources/extensions/gsd/tools/exec-tool.ts +2 -118
  557. package/src/resources/extensions/gsd/tui/render-kit.ts +56 -13
  558. package/src/resources/extensions/gsd/unit-context-composer.ts +1 -1
  559. package/src/resources/extensions/gsd/unit-registry.ts +34 -4
  560. package/src/resources/extensions/gsd/workflow-logger.ts +5 -0
  561. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -0
  562. package/src/resources/extensions/gsd/workflow-mcp-readiness-cache.ts +150 -0
  563. package/src/resources/extensions/gsd/worktree-manager.ts +97 -2
  564. package/src/resources/extensions/gsd/worktree-safety.ts +41 -39
  565. package/src/resources/extensions/gsd/worktree-shell-guard.ts +123 -0
  566. package/src/resources/extensions/gsd/worktree.ts +7 -1
  567. package/src/resources/extensions/mcp-client/manager.ts +7 -1
  568. package/src/resources/extensions/search-the-web/index.ts +45 -9
  569. package/src/resources/extensions/search-the-web/native-search.ts +16 -4
  570. package/src/resources/extensions/shared/gsd-browser-cli.ts +41 -2
  571. package/src/resources/extensions/subagent/index.ts +20 -15
  572. package/src/resources/extensions/subagent/tests/worktree-cwd.test.ts +57 -0
  573. package/src/resources/extensions/subagent/worktree-cwd.ts +35 -0
  574. package/src/resources/skills/create-skill/SKILL.md +3 -0
  575. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  576. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  577. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  578. /package/dist/web/standalone/.next/static/{T-LTxEw5wir5Lm5T3qEVd → Wn9u2NYq0cyUigB_3Z0_N}/_buildManifest.js +0 -0
  579. /package/dist/web/standalone/.next/static/{T-LTxEw5wir5Lm5T3qEVd → Wn9u2NYq0cyUigB_3Z0_N}/_ssgManifest.js +0 -0
@@ -76,9 +76,24 @@ import {
76
76
  countUnmappedActiveRequirements,
77
77
  showRequirementsBacklogReview,
78
78
  } from "./requirements-backlog.js";
79
- import { selectAndApplyModel } from "./auto-model-selection.js";
79
+ import { selectAndApplyModel, getRegisteredToolSnapshot } from "./auto-model-selection.js";
80
80
  import { DISCUSS_TOOLS_ALLOWLIST } from "./constants.js";
81
- import { supportsStructuredQuestions } from "./workflow-mcp.js";
81
+ import {
82
+ detectWorkflowMcpLaunchConfig,
83
+ resolveWorkflowMcpProjectRoot,
84
+ supportsStructuredQuestions,
85
+ } from "./workflow-mcp.js";
86
+ import { usesWorkflowMcpTransport } from "./question-transport.js";
87
+ import {
88
+ getCachedWorkflowMcpProbe,
89
+ probeAndCacheWorkflowMcp,
90
+ warmWorkflowMcpProbeInBackground,
91
+ workflowMcpProbeAdvertisesSurface,
92
+ WORKFLOW_MCP_PROBE_TIMEOUT_MS,
93
+ } from "./workflow-mcp-readiness-cache.js";
94
+ import { probeCoversRequiredWorkflowTools } from "./tool-surface-readiness.js";
95
+ import { getRequiredWorkflowToolsForUnit } from "./unit-tool-contracts.js";
96
+ import { isWorkflowToolSurfaceName } from "./workflow-tool-surface.js";
82
97
  import { getUnitWorkflowDispatchReadinessError } from "./tool-contract.js";
83
98
  import {
84
99
  runPreparation,
@@ -560,6 +575,93 @@ export function resolveGuidedDispatchProjectRoot(basePath?: string): string {
560
575
  return basePath ?? process.cwd();
561
576
  }
562
577
 
578
+ /**
579
+ * Wait until the workflow MCP server is reachable and advertising its tool
580
+ * surface. Returns failure details when timed out, or null when ready (or MCP
581
+ * is not the transport). Called inside dispatchWorkflow() so every guided-flow
582
+ * dispatch path is gated automatically.
583
+ */
584
+ const MCP_READINESS_TIMEOUT_MS = 15_000;
585
+ const MCP_READINESS_POLL_MS = 200;
586
+
587
+ export interface WorkflowMcpReadinessFailure {
588
+ server: string;
589
+ error?: string;
590
+ }
591
+
592
+ async function awaitWorkflowMcpReadiness(
593
+ pi: ExtensionAPI,
594
+ ctx: ExtensionContext,
595
+ basePath: string,
596
+ options: {
597
+ unitType?: string;
598
+ timeoutMs?: number;
599
+ pollMs?: number;
600
+ probeTimeoutMs?: number;
601
+ probe?: typeof probeAndCacheWorkflowMcp;
602
+ } = {},
603
+ ): Promise<WorkflowMcpReadinessFailure | null> {
604
+ const provider = ctx.model?.provider;
605
+ const authMode = provider ? ctx.modelRegistry.getProviderAuthMode(provider) : undefined;
606
+ if (!usesWorkflowMcpTransport(authMode, ctx.model?.baseUrl)) return null;
607
+
608
+ const projectRoot = resolveWorkflowMcpProjectRoot(basePath);
609
+ const launch = detectWorkflowMcpLaunchConfig(projectRoot);
610
+ if (!launch) return null;
611
+
612
+ const requiredTools = options.unitType
613
+ ? getRequiredWorkflowToolsForUnit(options.unitType).filter(isWorkflowToolSurfaceName)
614
+ : [];
615
+ const coversExpectedSurface = (tools: readonly string[]) =>
616
+ requiredTools.length > 0
617
+ ? probeCoversRequiredWorkflowTools(tools, requiredTools)
618
+ : workflowMcpProbeAdvertisesSurface(tools);
619
+
620
+ const serverPrefix = `mcp__${launch.name}__`;
621
+ const systemPrompt = () => typeof ctx.getSystemPrompt === "function" ? ctx.getSystemPrompt() : "";
622
+ const systemPromptCoversExpectedSurface = () => {
623
+ const prompt = systemPrompt();
624
+ return requiredTools.length > 0
625
+ ? requiredTools.every((tool) => prompt.includes(`${serverPrefix}${tool}`))
626
+ : prompt.includes(serverPrefix);
627
+ };
628
+ const sessionAlreadyReady = () =>
629
+ coversExpectedSurface(getRegisteredToolSnapshot(pi)) ||
630
+ systemPromptCoversExpectedSurface();
631
+ if (sessionAlreadyReady()) return null;
632
+
633
+ if (coversExpectedSurface(getCachedWorkflowMcpProbe(projectRoot)?.tools ?? [])) {
634
+ return null;
635
+ }
636
+
637
+ const probe = options.probe ?? probeAndCacheWorkflowMcp;
638
+ const probeTimeoutMs = options.probeTimeoutMs ?? WORKFLOW_MCP_PROBE_TIMEOUT_MS;
639
+
640
+ ctx.ui.setStatus("gsd-step", `Waiting for ${launch.name} MCP server…`);
641
+ let lastError: string | undefined;
642
+ const deadline = Date.now() + (options.timeoutMs ?? MCP_READINESS_TIMEOUT_MS);
643
+ const pollMs = options.pollMs ?? MCP_READINESS_POLL_MS;
644
+ while (Date.now() < deadline) {
645
+ if (sessionAlreadyReady()) {
646
+ ctx.ui.setStatus("gsd-step", "");
647
+ return null;
648
+ }
649
+
650
+ const result = await probe(projectRoot, { timeoutMs: probeTimeoutMs });
651
+ if (result.ok && coversExpectedSurface(result.tools)) {
652
+ ctx.ui.setStatus("gsd-step", "");
653
+ return null;
654
+ }
655
+ lastError = result.error;
656
+
657
+ await new Promise((r) => setTimeout(r, pollMs));
658
+ }
659
+ ctx.ui.setStatus("gsd-step", "");
660
+ return lastError ? { server: launch.name, error: lastError } : { server: launch.name };
661
+ }
662
+
663
+ export const _awaitWorkflowMcpReadinessForTest = awaitWorkflowMcpReadiness;
664
+
563
665
  /**
564
666
  * Read GSD-WORKFLOW.md and dispatch it to the LLM with a contextual note.
565
667
  * This is the only way the wizard triggers work — everything else is the LLM's job.
@@ -621,6 +723,29 @@ async function dispatchWorkflow(
621
723
  ctx.ui.notify(compatibilityError, "error");
622
724
  return;
623
725
  }
726
+
727
+ // ── Live MCP readiness gate ────────────────────────────────────────
728
+ // Units with required workflow tools must not dispatch until the MCP
729
+ // surface covers that exact contract; otherwise the model can race into
730
+ // "No such tool available" before recovery sees a clean readiness error.
731
+ warmWorkflowMcpProbeInBackground(projectRoot);
732
+ const requiredWorkflowTools = getRequiredWorkflowToolsForUnit(unitType).filter(isWorkflowToolSurfaceName);
733
+ const strictBlocking = requiredWorkflowTools.length > 0
734
+ && (process.env.GSD_GUIDED_MCP_BLOCKING ?? "").trim() !== "0";
735
+ if (strictBlocking) {
736
+ // If the workflow MCP server is configured but still connecting, wait
737
+ // for it instead of dispatching into a child session that will abort.
738
+ const readinessFailure = await awaitWorkflowMcpReadiness(pi, ctx, projectRoot, { unitType });
739
+ if (readinessFailure) {
740
+ const detail = readinessFailure.error ? ` ${readinessFailure.error}` : "";
741
+ ctx.ui.notify(
742
+ `GSD workflow server "${readinessFailure.server}" did not connect in time.${detail} ` +
743
+ `Run \`/gsd mcp check ${readinessFailure.server}\` for details.`,
744
+ "warning",
745
+ );
746
+ return;
747
+ }
748
+ }
624
749
  }
625
750
 
626
751
  // Scope tools for guided workflow turns (#2949, token-consumption savings).
@@ -1703,6 +1828,7 @@ export async function showSmartEntry(
1703
1828
  options?: { step?: boolean },
1704
1829
  ): Promise<void> {
1705
1830
  const stepMode = options?.step ?? true;
1831
+ warmWorkflowMcpProbeInBackground(basePath);
1706
1832
 
1707
1833
  // ── Clear stale milestone ID reservations from previous cancelled sessions ──
1708
1834
  // Reservations only need to survive within a single /gsd interaction.
@@ -4,7 +4,7 @@
4
4
  import type { ExtensionContext } from "@gsd/pi-coding-agent";
5
5
  import type { GSDState } from "./types.js";
6
6
  import { runProviderChecks, summariseProviderIssues } from "./doctor-providers.js";
7
- import { runEnvironmentChecks } from "./doctor-environment.js";
7
+ import { runEnvironmentChecks, runEnvironmentChecksAsync } from "./doctor-environment.js";
8
8
  import { loadEffectiveGSDPreferences } from "./preferences.js";
9
9
  import { nativeIsRepo, nativeLastCommitEpoch, nativeGetCurrentBranch, nativeCommitSubject } from "./native-git-bridge.js";
10
10
  import { loadLedgerFromDisk, getProjectTotals } from "./metrics.js";
@@ -22,7 +22,31 @@ export const HEALTH_WIDGET_ACTIVE_HINTS =
22
22
 
23
23
  // ── Data loader ────────────────────────────────────────────────────────────────
24
24
 
25
- function loadHealthWidgetData(basePath: string): HealthWidgetData {
25
+ // Last-commit lookup is subprocess-backed (native-git-bridge git spawns),
26
+ // so it is treated like the other expensive checks: skipped on first paint,
27
+ // run only by the background refresh.
28
+ function loadLastCommitInfo(basePath: string): { epoch: number | null; message: string | null } {
29
+ try {
30
+ if (nativeIsRepo(basePath)) {
31
+ const branch = nativeGetCurrentBranch(basePath);
32
+ const epoch = nativeLastCommitEpoch(basePath, branch || "HEAD");
33
+ if (epoch > 0) {
34
+ return { epoch, message: nativeCommitSubject(basePath, branch || "HEAD") || null };
35
+ }
36
+ }
37
+ } catch { /* non-fatal */ }
38
+ return { epoch: null, message: null };
39
+ }
40
+
41
+ function loadHealthWidgetData(
42
+ basePath: string,
43
+ options?: { includeChecks?: boolean },
44
+ ): HealthWidgetData {
45
+ // `includeChecks` gates the expensive subprocess-backed checks (provider +
46
+ // environment doctor: `lsof`, `docker`, `node --version`, ...). The initial
47
+ // synchronous render passes `false` so first paint is never blocked on them;
48
+ // the async refresh (off the first-paint path) runs the full suite.
49
+ const includeChecks = options?.includeChecks ?? true;
26
50
  let budgetCeiling: number | undefined;
27
51
  let budgetSpent = 0;
28
52
  let providerIssue: string | null = null;
@@ -44,40 +68,73 @@ function loadHealthWidgetData(basePath: string): HealthWidgetData {
44
68
  }
45
69
  } catch { /* non-fatal */ }
46
70
 
71
+ if (includeChecks) {
72
+ try {
73
+ const providerResults = runProviderChecks();
74
+ providerIssue = summariseProviderIssues(providerResults);
75
+ } catch { /* non-fatal */ }
76
+
77
+ try {
78
+ const envResults = runEnvironmentChecks(basePath);
79
+ for (const r of envResults) {
80
+ if (r.status === "error") environmentErrorCount++;
81
+ else if (r.status === "warning") environmentWarningCount++;
82
+ }
83
+ } catch { /* non-fatal */ }
84
+ }
85
+
86
+ // ── Last commit info ── (git spawns — gated like the other expensive checks)
87
+ if (includeChecks) {
88
+ const commit = loadLastCommitInfo(basePath);
89
+ lastCommitEpoch = commit.epoch;
90
+ lastCommitMessage = commit.message;
91
+ }
92
+
93
+ return {
94
+ projectState,
95
+ budgetCeiling,
96
+ budgetSpent,
97
+ providerIssue,
98
+ environmentErrorCount,
99
+ environmentWarningCount,
100
+ lastCommitEpoch,
101
+ lastCommitMessage,
102
+ lastRefreshed: Date.now(),
103
+ };
104
+ }
105
+
106
+ // Non-blocking variant used by the widget's background refresh: the cheap fields
107
+ // come from the synchronous snapshot, then provider + environment checks are
108
+ // layered in off the event-loop critical path (env checks run concurrently via
109
+ // runEnvironmentChecksAsync). Keeps the always-on widget from stalling the UI on
110
+ // its initial enrichment or its 60s refresh.
111
+ async function loadHealthWidgetDataAsync(basePath: string): Promise<HealthWidgetData> {
112
+ const data = loadHealthWidgetData(basePath, { includeChecks: false });
113
+ let providerIssue = data.providerIssue;
114
+ let environmentErrorCount = 0;
115
+ let environmentWarningCount = 0;
116
+
47
117
  try {
48
- const providerResults = runProviderChecks();
49
- providerIssue = summariseProviderIssues(providerResults);
118
+ providerIssue = summariseProviderIssues(runProviderChecks());
50
119
  } catch { /* non-fatal */ }
51
120
 
52
121
  try {
53
- const envResults = runEnvironmentChecks(basePath);
122
+ const envResults = await runEnvironmentChecksAsync(basePath);
54
123
  for (const r of envResults) {
55
124
  if (r.status === "error") environmentErrorCount++;
56
125
  else if (r.status === "warning") environmentWarningCount++;
57
126
  }
58
127
  } catch { /* non-fatal */ }
59
128
 
60
- // ── Last commit info ──
61
- try {
62
- if (nativeIsRepo(basePath)) {
63
- const branch = nativeGetCurrentBranch(basePath);
64
- const epoch = nativeLastCommitEpoch(basePath, branch || "HEAD");
65
- if (epoch > 0) {
66
- lastCommitEpoch = epoch;
67
- lastCommitMessage = nativeCommitSubject(basePath, branch || "HEAD") || null;
68
- }
69
- }
70
- } catch { /* non-fatal */ }
129
+ const commit = loadLastCommitInfo(basePath);
71
130
 
72
131
  return {
73
- projectState,
74
- budgetCeiling,
75
- budgetSpent,
132
+ ...data,
76
133
  providerIssue,
77
134
  environmentErrorCount,
78
135
  environmentWarningCount,
79
- lastCommitEpoch,
80
- lastCommitMessage,
136
+ lastCommitEpoch: commit.epoch,
137
+ lastCommitMessage: commit.message,
81
138
  lastRefreshed: Date.now(),
82
139
  };
83
140
  }
@@ -95,8 +152,13 @@ export function initHealthWidget(ctx: ExtensionContext): void {
95
152
 
96
153
  const basePath = projectRoot();
97
154
 
98
- // String-array fallback — used in RPC mode (factory is a no-op there)
99
- const initialData = loadHealthWidgetData(basePath);
155
+ // String-array fallback — used in RPC mode (factory is a no-op there).
156
+ // Skip the expensive provider/environment doctor checks here: this runs
157
+ // synchronously on the interactive-startup path, where running them would
158
+ // block first paint by ~0.9s (lsof/docker probes, otherwise run again
159
+ // immediately by the factory below). The factory's async refresh fills in
160
+ // real health once the screen is up.
161
+ const initialData = loadHealthWidgetData(basePath, { includeChecks: false });
100
162
  ctx.ui.setWidget("gsd-health", buildHealthLines(initialData), { placement: "belowEditor" });
101
163
 
102
164
  // Factory-based widget for TUI mode — replaces the string-array above
@@ -110,7 +172,7 @@ export function initHealthWidget(ctx: ExtensionContext): void {
110
172
  if (refreshInFlight) return;
111
173
  refreshInFlight = true;
112
174
  try {
113
- data = loadHealthWidgetData(basePath);
175
+ data = await loadHealthWidgetDataAsync(basePath);
114
176
  cachedLines = undefined;
115
177
  if (!isDisposed) _tui.requestRender();
116
178
  } catch { /* non-fatal */ } finally {
@@ -118,9 +180,11 @@ export function initHealthWidget(ctx: ExtensionContext): void {
118
180
  }
119
181
  };
120
182
 
121
- // Fire first enrichment immediately. requestRender() inside is a no-op
122
- // if the widget has not yet rendered, so this is safe before factory return.
123
- void refresh();
183
+ // Fire the first full enrichment off the first-paint path. setTimeout(0)
184
+ // yields to the initial render + input loop, so the expensive doctor checks
185
+ // (provider + environment) never delay the moment the user sees the UI.
186
+ // requestRender() inside refresh repaints the widget once data is ready.
187
+ setTimeout(() => { void refresh(); }, 0);
124
188
 
125
189
  const refreshTimer = setInterval(() => {
126
190
  void refresh();
@@ -0,0 +1,39 @@
1
+ // mcp-bridge.ts — stable runtime seam for MCP server consumption (phase 1).
2
+ export {
3
+ loadWriteGateSnapshot,
4
+ shouldBlockPendingGateInSnapshot,
5
+ shouldBlockQueueExecutionInSnapshot,
6
+ } from "./bootstrap/write-gate.js";
7
+ export { ensureDbOpen } from "./bootstrap/dynamic-tools.js";
8
+ export {
9
+ _getAdapter,
10
+ checkpointDatabase,
11
+ closeDatabase,
12
+ getAllMilestones,
13
+ getDb,
14
+ getGateResults,
15
+ getMilestoneSlices,
16
+ getPendingGates,
17
+ getSliceTasks,
18
+ insertDecision,
19
+ insertMilestone,
20
+ insertSlice,
21
+ openDatabase,
22
+ upsertMilestonePlanning,
23
+ } from "./gsd-db.js";
24
+ export { invalidateStateCache, isReusableGhostMilestone } from "./state.js";
25
+ export { loadEffectiveGSDPreferences } from "./preferences.js";
26
+ export {
27
+ saveDecisionToDb,
28
+ saveRequirementToDb,
29
+ updateRequirementInDb,
30
+ } from "./db-writer.js";
31
+ export { rebuildState } from "./doctor.js";
32
+ export { queryJournal } from "./journal.js";
33
+ export {
34
+ claimReservedId,
35
+ findMilestoneIds,
36
+ getReservedMilestoneIds,
37
+ milestoneIdSort,
38
+ nextMilestoneId,
39
+ } from "./milestone-ids.js";
@@ -3,7 +3,7 @@
3
3
  // Phase 4 companion to memory-store.ts. Edges live in the `memory_relations`
4
4
  // table and are created by (a) explicit LINK actions emitted by the memory
5
5
  // extractor, or (b) future `/gsd memory link` CLI commands. All writes go
6
- // through the single-writer gate in `gsd-db.ts`.
6
+ // through typed writer wrappers re-exported by `gsd-db.ts`.
7
7
 
8
8
  import {
9
9
  _getAdapter,
@@ -74,8 +74,8 @@ export function evaluateAllCompleteSettlement(
74
74
  action: "pause",
75
75
  message:
76
76
  `Milestone ${milestoneId} is complete, but its worktree branch has not been merged to main. ` +
77
- `Retry with \`/gsd dispatch complete-milestone ${milestoneId}\` or merge manually.`,
78
- nextAction: `Retry \`/gsd dispatch complete-milestone ${milestoneId}\` or merge manually.`,
77
+ `Retry with \`/gsd dispatch complete-milestone ${milestoneId}\` to finish the system-owned merge.`,
78
+ nextAction: `Retry \`/gsd dispatch complete-milestone ${milestoneId}\`.`,
79
79
  milestoneId,
80
80
  };
81
81
  }
@@ -4,7 +4,12 @@
4
4
  import { execFileSync } from "node:child_process";
5
5
  import type { NotificationPreferences } from "./types.js";
6
6
  import { loadEffectiveGSDPreferences } from "./preferences.js";
7
- import { sendRemoteNotification } from "../remote-questions/notify.js";
7
+ import { sendRemoteNotification as _sendRemoteNotification } from "../remote-questions/notify.js";
8
+
9
+ /** Swappable dispatcher for remote notifications — exported so tests can mock it. */
10
+ export const remoteNotificationDispatcher = {
11
+ send: _sendRemoteNotification,
12
+ };
8
13
 
9
14
  export type NotifyLevel = "info" | "success" | "warning" | "error";
10
15
  export type NotificationKind = "complete" | "error" | "budget" | "milestone" | "attention";
@@ -30,28 +35,30 @@ export function sendDesktopNotification(
30
35
  level: NotifyLevel = "info",
31
36
  kind: NotificationKind = "complete",
32
37
  projectName?: string,
38
+ deps: { notifications?: NotificationPreferences } = {},
33
39
  ): void {
34
40
  // When a projectName is provided and the title is the default "GSD",
35
41
  // replace it with a project-qualified title for multi-project clarity.
36
42
  if (projectName && title === "GSD") {
37
43
  title = formatNotificationTitle(projectName);
38
44
  }
39
- const loaded = loadEffectiveGSDPreferences()?.preferences;
45
+ const loadedPreferences = loadEffectiveGSDPreferences()?.preferences;
46
+ const notifications = deps.notifications ?? loadedPreferences?.notifications;
40
47
 
41
48
  // Remote notifications fire independently of desktop preferences.
42
49
  // sendRemoteNotification handles "not configured" gracefully (early return).
43
- void sendRemoteNotification(title, message).catch(() => {});
50
+ void remoteNotificationDispatcher.send(title, message).catch(() => {});
44
51
 
45
- if (!shouldSendDesktopNotification(kind, loaded?.notifications)) return;
52
+ if (!shouldSendDesktopNotification(kind, notifications)) return;
46
53
 
47
54
  // cmux delivery and desktop delivery are independent — if cmux import or
48
55
  // delivery fails, we must still attempt the native desktop notification.
49
56
  const runCmux = async () => {
50
57
  try {
51
58
  const { CmuxClient, emitOsc777Notification, resolveCmuxConfig } = await import("../cmux/index.js");
52
- const cmux = resolveCmuxConfig(loaded);
59
+ const cmux = resolveCmuxConfig(loadedPreferences);
53
60
  if (cmux.notifications) {
54
- const delivered = CmuxClient.fromPreferences(loaded).notify(title, message);
61
+ const delivered = CmuxClient.fromPreferences(loadedPreferences).notify(title, message);
55
62
  if (delivered) return true;
56
63
  emitOsc777Notification(title, message);
57
64
  }
@@ -94,8 +94,13 @@ function resolveWinningPhase(
94
94
  * - Legacy: `planning: claude-opus-4-6`
95
95
  * - Extended: `planning: { model: claude-opus-4-6, fallbacks: [glm-5, minimax-m2.5] }`
96
96
  */
97
- export function resolveModelWithFallbacksForUnit(unitType: string): ResolvedModelConfig | undefined {
98
- const prefs = loadEffectiveGSDPreferences(undefined, { availableModelIds: [] });
97
+ export function resolveModelWithFallbacksForUnit(
98
+ unitType: string,
99
+ basePath?: string,
100
+ availableModelIds?: string[],
101
+ ): ResolvedModelConfig | undefined {
102
+ const loadOpts = availableModelIds !== undefined ? { availableModelIds } : undefined;
103
+ const prefs = loadEffectiveGSDPreferences(basePath, loadOpts);
99
104
  const chain = phaseChainForUnit(unitType);
100
105
  if (!chain) return undefined;
101
106
  const winner = resolveWinningPhase(prefs?.preferences?.models as GSDModelConfigV2 | undefined, chain);
@@ -141,8 +146,13 @@ export function resolveModelWithFallbacksForUnit(unitType: string): ResolvedMode
141
146
  * floor. Session level, defaults, the floor, and capability clamping are NOT
142
147
  * applied here.
143
148
  */
144
- export function resolveThinkingLevelForUnit(unitType: string): GSDThinkingLevel | undefined {
145
- const prefs = loadEffectiveGSDPreferences(undefined, { availableModelIds: [] })?.preferences;
149
+ export function resolveThinkingLevelForUnit(
150
+ unitType: string,
151
+ basePath?: string,
152
+ availableModelIds?: string[],
153
+ ): GSDThinkingLevel | undefined {
154
+ const loadOpts = availableModelIds !== undefined ? { availableModelIds } : undefined;
155
+ const prefs = loadEffectiveGSDPreferences(basePath, loadOpts)?.preferences;
146
156
  if (!prefs) return undefined;
147
157
  const chain = phaseChainForUnit(unitType);
148
158
  if (!chain) return undefined;
@@ -186,8 +196,10 @@ export function resolveThinkingLevelForUnit(unitType: string): GSDThinkingLevel
186
196
  export function resolveDefaultSessionModel(
187
197
  sessionProvider?: string,
188
198
  basePath?: string,
199
+ availableModelIds?: string[],
189
200
  ): { provider: string; id: string } | undefined {
190
- const prefs = loadEffectiveGSDPreferences(basePath, { availableModelIds: [] });
201
+ const loadOpts = availableModelIds !== undefined ? { availableModelIds } : undefined;
202
+ const prefs = loadEffectiveGSDPreferences(basePath, loadOpts);
191
203
  const models = prefs?.preferences?.models;
192
204
  if (!models) return undefined;
193
205
 
@@ -413,7 +425,10 @@ export function resolveAutoSupervisorConfig(): AutoSupervisorConfig {
413
425
 
414
426
  // ─── Token Profile Resolution ─────────────────────────────────────────────
415
427
 
416
- const VALID_TOKEN_PROFILES = new Set<TokenProfile>(["budget", "balanced", "quality", "burn-max"]);
428
+ export const VALID_TOKEN_PROFILES = new Set<TokenProfile>(["budget", "balanced", "quality", "burn-max"]);
429
+
430
+ /** D046: balanced is the implicit profile when `token_profile` is omitted. */
431
+ export const DEFAULT_TOKEN_PROFILE: TokenProfile = "balanced";
417
432
 
418
433
  /**
419
434
  * Per-phase tier intentions for each token profile.
@@ -459,8 +474,11 @@ const PROFILE_TIER_MAP: Record<TokenProfile, Record<string, ComplexityTier>> = {
459
474
  *
460
475
  * Model IDs are resolved from capability tiers, not hardcoded to any
461
476
  * provider. When available models are known (runtime), the resolver picks
462
- * the best match across all configured providers. When not known (e.g.,
463
- * early startup), falls back to canonical Anthropic model IDs.
477
+ * the best match on the anchor provider (session / auto-start model). Callers
478
+ * scope the available-model list via `modelIdsForProfileResolution` so token
479
+ * profiles do not hop to a cheaper provider (e.g. Gemini Flash) when the user
480
+ * is working on OpenAI or Anthropic. When not known (e.g., early startup),
481
+ * falls back to canonical Anthropic model IDs.
464
482
  *
465
483
  * @param profile The token profile to resolve
466
484
  * @param availableModelIds Optional list of available model IDs for cross-provider resolution.
@@ -20,7 +20,12 @@ import type { PostUnitHookConfig, PreDispatchHookConfig, TokenProfile } from "./
20
20
  import type { DynamicRoutingConfig } from "./model-router.js";
21
21
  import { normalizeStringArray } from "../shared/format-utils.js";
22
22
  import { logWarning } from "./workflow-logger.js";
23
- import { resolveProfileDefaults as _resolveProfileDefaults } from "./preferences-models.js";
23
+ import {
24
+ DEFAULT_TOKEN_PROFILE,
25
+ resolveProfileDefaults as _resolveProfileDefaults,
26
+ VALID_TOKEN_PROFILES,
27
+ resolveDisabledModelProvidersFromPreferences,
28
+ } from "./preferences-models.js";
24
29
  import { nativeHasCommittedHead, nativeIsRepo } from "./native-git-bridge.js";
25
30
 
26
31
  import {
@@ -142,6 +147,90 @@ export function getProjectGSDPreferencesPath(basePath?: string): string {
142
147
  return projectPreferencesPath(basePath);
143
148
  }
144
149
 
150
+ /** Minimal model-registry surface for provider-aware preference resolution. */
151
+ export type PreferencesModelRegistry = {
152
+ getAvailable: () => ReadonlyArray<{ provider: string; id: string }>;
153
+ };
154
+
155
+ /** Format registry models the same way tier resolution and prefs persistence use. */
156
+ export function availableModelIdsFromRegistry(registry: PreferencesModelRegistry): string[] {
157
+ return registry.getAvailable().map((m) => `${m.provider}/${m.id}`);
158
+ }
159
+
160
+ /**
161
+ * Keep only provider-qualified model IDs for a single provider (case-insensitive).
162
+ * Bare IDs are excluded — tier resolution requires provider/model form.
163
+ */
164
+ export function restrictModelIdsToProvider(modelIds: string[], provider: string): string[] {
165
+ const normalized = provider.trim().toLowerCase();
166
+ if (!normalized) return modelIds;
167
+ return modelIds.filter((id) => {
168
+ const slash = id.indexOf("/");
169
+ if (slash <= 0) return false;
170
+ return id.slice(0, slash).toLowerCase() === normalized;
171
+ });
172
+ }
173
+
174
+ /**
175
+ * Model IDs for token-profile tier resolution. When an anchor provider is known
176
+ * (session model / auto-start snapshot), stay on that provider instead of picking
177
+ * the globally cheapest tier match across every logged-in provider (e.g. Gemini
178
+ * Flash beating GPT mini on cost).
179
+ */
180
+ export function modelIdsForProfileResolution(
181
+ registry: PreferencesModelRegistry,
182
+ anchorProvider?: string,
183
+ disabledProviders?: string[],
184
+ ): string[] | undefined {
185
+ let all = availableModelIdsFromRegistry(registry);
186
+ if (disabledProviders?.length) {
187
+ const blocked = new Set(
188
+ disabledProviders.map((p) => p.trim().toLowerCase()).filter((p) => p.length > 0),
189
+ );
190
+ all = all.filter((id) => {
191
+ const slash = id.indexOf("/");
192
+ if (slash <= 0) return true;
193
+ return !blocked.has(id.slice(0, slash).toLowerCase());
194
+ });
195
+ }
196
+ if (all.length === 0) return undefined;
197
+ if (!anchorProvider?.trim()) return all;
198
+ // Stay on the anchor provider — do not fall back to the full registry when the
199
+ // scoped list is empty (that reintroduces cross-provider cost picks like Gemini).
200
+ return restrictModelIdsToProvider(all, anchorProvider);
201
+ }
202
+
203
+ /** Provider anchor for token-profile tier resolution (auto-start model wins). */
204
+ export function resolveProfileAnchorProvider(
205
+ sessionProvider?: string,
206
+ autoModeStartProvider?: string | null,
207
+ ): string | undefined {
208
+ const start = autoModeStartProvider?.trim();
209
+ if (start) return start;
210
+ const session = sessionProvider?.trim();
211
+ return session || undefined;
212
+ }
213
+
214
+ /**
215
+ * Load effective preferences with token-profile tiers resolved against models
216
+ * the user can actually call (from the live registry), not canonical Anthropic
217
+ * fallbacks.
218
+ */
219
+ export function loadEffectiveGSDPreferencesWithRegistry(
220
+ registry: PreferencesModelRegistry | undefined,
221
+ basePath?: string,
222
+ anchorProvider?: string,
223
+ ): LoadedGSDPreferences | null {
224
+ if (!registry) {
225
+ return loadEffectiveGSDPreferences(basePath);
226
+ }
227
+ const disabledProviders = resolveDisabledModelProvidersFromPreferences();
228
+ const availableModelIds = modelIdsForProfileResolution(registry, anchorProvider, disabledProviders);
229
+ if (!availableModelIds) {
230
+ return loadEffectiveGSDPreferences(basePath);
231
+ }
232
+ return loadEffectiveGSDPreferences(basePath, { availableModelIds });
233
+ }
145
234
 
146
235
  /**
147
236
  * Normalize a value loaded from disk (or passed from another component) into
@@ -220,16 +309,27 @@ export function loadEffectiveGSDPreferences(
220
309
  // Apply token-profile defaults as the lowest-priority layer so that
221
310
  // `token_profile: budget` sets models and phase-skips automatically.
222
311
  // Explicit user preferences always override profile defaults.
223
- const profile = result.preferences.token_profile as TokenProfile | undefined;
224
- if (profile) {
312
+ const explicitProfile = result.preferences.token_profile as TokenProfile | undefined;
313
+ let profileForDefaults: TokenProfile | undefined;
314
+ if (explicitProfile) {
315
+ if (VALID_TOKEN_PROFILES.has(explicitProfile)) {
316
+ profileForDefaults = explicitProfile;
317
+ }
318
+ } else {
319
+ profileForDefaults = DEFAULT_TOKEN_PROFILE;
320
+ }
321
+ if (profileForDefaults) {
225
322
  const profileDefaults = _resolveProfileDefaults(
226
- profile,
323
+ profileForDefaults,
227
324
  opts?.availableModelIds,
228
325
  result.preferences.dynamic_routing,
229
326
  );
327
+ const defaultsToApply = explicitProfile
328
+ ? profileDefaults
329
+ : withoutProfilePhaseDefaults(profileDefaults);
230
330
  result = {
231
331
  ...result,
232
- preferences: mergePreferences(profileDefaults as GSDPreferences, result.preferences),
332
+ preferences: mergePreferences(defaultsToApply as GSDPreferences, result.preferences),
233
333
  };
234
334
  }
235
335
 
@@ -246,6 +346,12 @@ export function loadEffectiveGSDPreferences(
246
346
  return result;
247
347
  }
248
348
 
349
+ function withoutProfilePhaseDefaults(defaults: Partial<GSDPreferences>): Partial<GSDPreferences> {
350
+ if (defaults.phases === undefined) return defaults;
351
+ const { phases: _phases, ...rest } = defaults;
352
+ return rest;
353
+ }
354
+
249
355
  function mergePreferenceMetadata(
250
356
  primary: LoadedGSDPreferences,
251
357
  secondary: LoadedGSDPreferences | null,