@opengsd/gsd-pi 1.2.0-dev.b1abb545 → 1.2.0-dev.fb12b103

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 (520) hide show
  1. package/dist/cli-style.d.ts +17 -0
  2. package/dist/cli-style.js +28 -0
  3. package/dist/cli.js +1 -1
  4. package/dist/headless-events.d.ts +4 -2
  5. package/dist/headless-events.js +7 -29
  6. package/dist/models-resolver.d.ts +3 -13
  7. package/dist/models-resolver.js +3 -22
  8. package/dist/resource-loader.js +2 -14
  9. package/dist/resources/.managed-resources-content-hash +1 -1
  10. package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
  11. package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
  12. package/dist/resources/extensions/async-jobs/index.js +65 -0
  13. package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
  14. package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
  15. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
  16. package/dist/resources/extensions/bg-shell/overlay.js +9 -6
  17. package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
  18. package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
  19. package/dist/resources/extensions/bg-shell/utilities.js +5 -2
  20. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
  21. package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
  22. package/dist/resources/extensions/browser-tools/index.js +69 -12
  23. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  24. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +38 -6
  25. package/dist/resources/extensions/gsd/auto/orchestrator.js +40 -9
  26. package/dist/resources/extensions/gsd/auto/phases.js +6 -1
  27. package/dist/resources/extensions/gsd/auto-dispatch.js +12 -1
  28. package/dist/resources/extensions/gsd/auto-model-selection.js +25 -6
  29. package/dist/resources/extensions/gsd/auto-post-unit.js +19 -8
  30. package/dist/resources/extensions/gsd/auto-prompts.js +15 -10
  31. package/dist/resources/extensions/gsd/auto-start.js +21 -21
  32. package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
  33. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +7 -16
  34. package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
  35. package/dist/resources/extensions/gsd/auto-worktree.js +35 -352
  36. package/dist/resources/extensions/gsd/auto.js +8 -20
  37. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +3 -2
  38. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -12
  39. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
  40. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +151 -20
  41. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +30 -4
  42. package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
  43. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  44. package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
  45. package/dist/resources/extensions/gsd/captures.js +5 -15
  46. package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
  47. package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
  48. package/dist/resources/extensions/gsd/constants.js +0 -2
  49. package/dist/resources/extensions/gsd/crash-recovery.js +4 -12
  50. package/dist/resources/extensions/gsd/db/engine.js +755 -0
  51. package/dist/resources/extensions/gsd/db/queries.js +372 -0
  52. package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
  53. package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
  54. package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
  55. package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
  56. package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
  57. package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
  58. package/dist/resources/extensions/gsd/doctor-environment.js +5 -11
  59. package/dist/resources/extensions/gsd/doctor-format.js +9 -6
  60. package/dist/resources/extensions/gsd/doctor-git-checks.js +4 -3
  61. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +21 -16
  62. package/dist/resources/extensions/gsd/error-classifier.js +9 -0
  63. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  64. package/dist/resources/extensions/gsd/git-service.js +1 -0
  65. package/dist/resources/extensions/gsd/gitignore.js +3 -0
  66. package/dist/resources/extensions/gsd/gsd-db.js +171 -2048
  67. package/dist/resources/extensions/gsd/guidance.js +98 -0
  68. package/dist/resources/extensions/gsd/guided-flow.js +51 -5
  69. package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
  70. package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
  71. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
  72. package/dist/resources/extensions/gsd/migrate/safety.js +20 -9
  73. package/dist/resources/extensions/gsd/migration-auto-check.js +24 -3
  74. package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
  75. package/dist/resources/extensions/gsd/model-router.js +3 -0
  76. package/dist/resources/extensions/gsd/notification-store.js +11 -4
  77. package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
  78. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +11 -7
  79. package/dist/resources/extensions/gsd/paths.js +37 -24
  80. package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
  81. package/dist/resources/extensions/gsd/preferences-models.js +14 -48
  82. package/dist/resources/extensions/gsd/preferences.js +14 -0
  83. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  84. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  85. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  86. package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  87. package/dist/resources/extensions/gsd/prompts/run-uat.md +1 -1
  88. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  89. package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
  90. package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
  91. package/dist/resources/extensions/gsd/publication.js +87 -0
  92. package/dist/resources/extensions/gsd/recovery-classification.js +41 -87
  93. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  94. package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
  95. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
  96. package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
  97. package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
  98. package/dist/resources/extensions/gsd/state.js +1 -20
  99. package/dist/resources/extensions/gsd/status-guards.js +56 -8
  100. package/dist/resources/extensions/gsd/stop-notice.js +57 -0
  101. package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
  102. package/dist/resources/extensions/gsd/tools/complete-slice.js +24 -43
  103. package/dist/resources/extensions/gsd/tools/exec-tool.js +10 -8
  104. package/dist/resources/extensions/gsd/tools/plan-slice.js +12 -6
  105. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +11 -29
  106. package/dist/resources/extensions/gsd/tools/reopen-slice.js +14 -33
  107. package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
  108. package/dist/resources/extensions/gsd/uat-policy.js +2 -1
  109. package/dist/resources/extensions/gsd/undo.js +8 -7
  110. package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
  111. package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
  112. package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
  113. package/dist/resources/extensions/gsd/unit-registry.js +337 -0
  114. package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
  115. package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
  116. package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
  117. package/dist/resources/extensions/gsd/worktree-git-recovery.js +293 -0
  118. package/dist/resources/extensions/gsd/worktree-lifecycle.js +9 -1
  119. package/dist/resources/extensions/gsd/worktree-manager.js +45 -28
  120. package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
  121. package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
  122. package/dist/resources/extensions/gsd/worktree-root.js +28 -6
  123. package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
  124. package/dist/resources/extensions/gsd/worktree-session-state.js +12 -11
  125. package/dist/resources/extensions/search-the-web/native-search.js +5 -3
  126. package/dist/resources/extensions/shared/browser-contract.js +59 -0
  127. package/dist/resources/extensions/shared/gsd-browser-cli.js +96 -5
  128. package/dist/resources/shared/package.json +3 -0
  129. package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
  130. package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
  131. package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
  132. package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
  133. package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  134. package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  135. package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  136. package/dist/resources/skills/gsd-browser/SKILL.md +1 -1
  137. package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
  138. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  139. package/dist/web/standalone/.next/BUILD_ID +1 -1
  140. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  141. package/dist/web/standalone/.next/build-manifest.json +3 -3
  142. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  143. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  144. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  145. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  151. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  152. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  153. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  154. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  155. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  156. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  157. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  158. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  159. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  160. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  162. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  164. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  166. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  167. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  168. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  169. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  170. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  171. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  172. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  173. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  174. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  175. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  176. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  177. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  178. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  179. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  180. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  182. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  184. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  185. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  186. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  187. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  188. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  190. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  191. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  192. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  193. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  195. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  196. package/dist/web/standalone/.next/server/app/index.html +1 -1
  197. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  198. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  199. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  200. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  201. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  202. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  203. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  204. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  205. package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
  206. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  207. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  210. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  211. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  212. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  213. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  214. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  215. package/dist/web/standalone/node_modules/postcss/lib/container.js +18 -26
  216. package/dist/web/standalone/node_modules/postcss/lib/css-syntax-error.js +14 -47
  217. package/dist/web/standalone/node_modules/postcss/lib/declaration.js +4 -4
  218. package/dist/web/standalone/node_modules/postcss/lib/fromJSON.js +3 -3
  219. package/dist/web/standalone/node_modules/postcss/lib/input.js +29 -54
  220. package/dist/web/standalone/node_modules/postcss/lib/lazy-result.js +37 -47
  221. package/dist/web/standalone/node_modules/postcss/lib/map-generator.js +9 -26
  222. package/dist/web/standalone/node_modules/postcss/lib/no-work-result.js +55 -57
  223. package/dist/web/standalone/node_modules/postcss/lib/node.js +31 -99
  224. package/dist/web/standalone/node_modules/postcss/lib/parse.js +1 -1
  225. package/dist/web/standalone/node_modules/postcss/lib/parser.js +9 -10
  226. package/dist/web/standalone/node_modules/postcss/lib/postcss.js +12 -12
  227. package/dist/web/standalone/node_modules/postcss/lib/previous-map.js +11 -30
  228. package/dist/web/standalone/node_modules/postcss/lib/processor.js +7 -7
  229. package/dist/web/standalone/node_modules/postcss/lib/result.js +5 -5
  230. package/dist/web/standalone/node_modules/postcss/lib/rule.js +6 -6
  231. package/dist/web/standalone/node_modules/postcss/lib/stringifier.js +28 -69
  232. package/dist/web/standalone/node_modules/postcss/lib/tokenize.js +2 -6
  233. package/dist/web/standalone/node_modules/postcss/package.json +48 -48
  234. package/dist/web/standalone/package.json +1 -1
  235. package/dist/worktree-cli.js +3 -6
  236. package/dist/worktree-status-banner.js +7 -11
  237. package/package.json +1 -1
  238. package/packages/cloud-mcp-gateway/package.json +2 -2
  239. package/packages/contracts/dist/rpc.d.ts +1 -0
  240. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  241. package/packages/contracts/dist/rpc.js.map +1 -1
  242. package/packages/contracts/dist/workflow.d.ts +4 -0
  243. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  244. package/packages/contracts/dist/workflow.js.map +1 -1
  245. package/packages/contracts/package.json +1 -1
  246. package/packages/daemon/package.json +4 -4
  247. package/packages/gsd-agent-core/package.json +5 -5
  248. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
  249. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  250. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +8 -0
  251. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  252. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  253. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
  254. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  255. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  256. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  257. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  258. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  259. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  260. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  261. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  262. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  263. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  264. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  265. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  266. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  267. package/packages/gsd-agent-modes/package.json +7 -7
  268. package/packages/mcp-server/dist/cli.js +6 -3
  269. package/packages/mcp-server/dist/cli.js.map +1 -1
  270. package/packages/mcp-server/dist/workflow-tools.d.ts +8 -0
  271. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  272. package/packages/mcp-server/dist/workflow-tools.js +46 -21
  273. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  274. package/packages/mcp-server/package.json +3 -3
  275. package/packages/native/package.json +1 -1
  276. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  277. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  278. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  279. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  280. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  281. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  282. package/packages/pi-agent-core/dist/index.js +3 -0
  283. package/packages/pi-agent-core/dist/index.js.map +1 -1
  284. package/packages/pi-agent-core/package.json +1 -1
  285. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  286. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  287. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  288. package/packages/pi-ai/dist/models.generated.d.ts +478 -484
  289. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  290. package/packages/pi-ai/dist/models.generated.js +500 -533
  291. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  292. package/packages/pi-ai/package.json +1 -1
  293. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  294. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  296. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/capability-patches.d.ts.map +1 -1
  298. package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
  299. package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
  300. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  301. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  302. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  303. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  304. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  305. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  306. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  307. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  308. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  309. package/packages/pi-coding-agent/dist/index.js +1 -1
  310. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  311. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  312. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  313. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  314. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  315. package/packages/pi-coding-agent/package.json +7 -7
  316. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  317. package/packages/pi-tui/dist/tui.js +9 -0
  318. package/packages/pi-tui/dist/tui.js.map +1 -1
  319. package/packages/pi-tui/package.json +2 -2
  320. package/packages/rpc-client/package.json +2 -2
  321. package/pkg/package.json +1 -1
  322. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  323. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  324. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  325. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  326. package/src/resources/extensions/async-jobs/index.ts +79 -0
  327. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  328. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  329. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  330. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  331. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  332. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  333. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  334. package/src/resources/extensions/bg-shell/utilities.ts +5 -2
  335. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
  336. package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
  337. package/src/resources/extensions/browser-tools/index.ts +71 -13
  338. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
  339. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +29 -1
  340. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
  341. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  342. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +40 -4
  343. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +28 -0
  344. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -1
  345. package/src/resources/extensions/gsd/auto/orchestrator.ts +46 -10
  346. package/src/resources/extensions/gsd/auto/phases.ts +10 -1
  347. package/src/resources/extensions/gsd/auto-dispatch.ts +12 -0
  348. package/src/resources/extensions/gsd/auto-model-selection.ts +25 -5
  349. package/src/resources/extensions/gsd/auto-post-unit.ts +25 -7
  350. package/src/resources/extensions/gsd/auto-prompts.ts +40 -26
  351. package/src/resources/extensions/gsd/auto-start.ts +21 -22
  352. package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
  353. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +10 -17
  354. package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
  355. package/src/resources/extensions/gsd/auto-worktree.ts +41 -364
  356. package/src/resources/extensions/gsd/auto.ts +20 -24
  357. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +3 -5
  358. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +33 -12
  359. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
  360. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +180 -15
  361. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +29 -3
  362. package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
  363. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  364. package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
  365. package/src/resources/extensions/gsd/captures.ts +5 -16
  366. package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
  367. package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
  368. package/src/resources/extensions/gsd/constants.ts +0 -3
  369. package/src/resources/extensions/gsd/crash-recovery.ts +3 -9
  370. package/src/resources/extensions/gsd/db/engine.ts +809 -0
  371. package/src/resources/extensions/gsd/db/queries.ts +453 -0
  372. package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
  373. package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
  374. package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
  375. package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
  376. package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
  377. package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
  378. package/src/resources/extensions/gsd/doctor-environment.ts +5 -13
  379. package/src/resources/extensions/gsd/doctor-format.ts +12 -7
  380. package/src/resources/extensions/gsd/doctor-git-checks.ts +3 -3
  381. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +22 -17
  382. package/src/resources/extensions/gsd/error-classifier.ts +11 -0
  383. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  384. package/src/resources/extensions/gsd/git-service.ts +1 -0
  385. package/src/resources/extensions/gsd/gitignore.ts +3 -0
  386. package/src/resources/extensions/gsd/gsd-db.ts +173 -2373
  387. package/src/resources/extensions/gsd/guidance.ts +139 -0
  388. package/src/resources/extensions/gsd/guided-flow.ts +50 -5
  389. package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
  390. package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
  391. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
  392. package/src/resources/extensions/gsd/migrate/safety.ts +18 -7
  393. package/src/resources/extensions/gsd/migration-auto-check.ts +28 -3
  394. package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
  395. package/src/resources/extensions/gsd/model-router.ts +3 -0
  396. package/src/resources/extensions/gsd/notification-store.ts +26 -3
  397. package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
  398. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -7
  399. package/src/resources/extensions/gsd/paths.ts +42 -22
  400. package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
  401. package/src/resources/extensions/gsd/preferences-models.ts +12 -47
  402. package/src/resources/extensions/gsd/preferences.ts +18 -0
  403. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  404. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  405. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  406. package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  407. package/src/resources/extensions/gsd/prompts/run-uat.md +1 -1
  408. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  409. package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
  410. package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
  411. package/src/resources/extensions/gsd/publication.ts +122 -0
  412. package/src/resources/extensions/gsd/recovery-classification.ts +47 -88
  413. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  414. package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
  415. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
  416. package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
  417. package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
  418. package/src/resources/extensions/gsd/state.ts +4 -21
  419. package/src/resources/extensions/gsd/status-guards.ts +59 -8
  420. package/src/resources/extensions/gsd/stop-notice.ts +75 -0
  421. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +123 -0
  422. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +22 -0
  423. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +16 -19
  424. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +3 -1
  425. package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
  426. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
  427. package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
  428. package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
  429. package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
  430. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  431. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
  432. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +44 -0
  433. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
  434. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  435. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
  436. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  437. package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +157 -0
  438. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  439. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  440. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
  441. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
  442. package/src/resources/extensions/gsd/tests/guidance.test.ts +125 -0
  443. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +58 -15
  444. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +74 -59
  445. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
  446. package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
  447. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  448. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +85 -1
  449. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  450. package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
  451. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  452. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
  453. package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
  454. package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
  455. package/src/resources/extensions/gsd/tests/recovery-classification-illegal-transition.test.ts +30 -0
  456. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +248 -1
  457. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +1 -0
  458. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
  459. package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
  460. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +43 -6
  461. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
  462. package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
  463. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
  464. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
  465. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
  466. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +155 -0
  467. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +24 -29
  468. package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
  469. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
  470. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
  471. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
  472. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
  473. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +2 -2
  474. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
  475. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +22 -1
  476. package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
  477. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
  478. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +3 -1
  479. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
  480. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +2 -2
  481. package/src/resources/extensions/gsd/tests/write-gate.test.ts +42 -0
  482. package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
  483. package/src/resources/extensions/gsd/tools/complete-slice.ts +23 -58
  484. package/src/resources/extensions/gsd/tools/exec-tool.ts +9 -8
  485. package/src/resources/extensions/gsd/tools/plan-slice.ts +12 -6
  486. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +11 -38
  487. package/src/resources/extensions/gsd/tools/reopen-slice.ts +14 -42
  488. package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
  489. package/src/resources/extensions/gsd/uat-policy.ts +2 -1
  490. package/src/resources/extensions/gsd/undo.ts +9 -8
  491. package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
  492. package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
  493. package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
  494. package/src/resources/extensions/gsd/unit-registry.ts +412 -0
  495. package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
  496. package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
  497. package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
  498. package/src/resources/extensions/gsd/worktree-git-recovery.ts +314 -0
  499. package/src/resources/extensions/gsd/worktree-lifecycle.ts +10 -1
  500. package/src/resources/extensions/gsd/worktree-manager.ts +47 -28
  501. package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
  502. package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
  503. package/src/resources/extensions/gsd/worktree-root.ts +29 -6
  504. package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
  505. package/src/resources/extensions/gsd/worktree-session-state.ts +11 -11
  506. package/src/resources/extensions/search-the-web/native-search.ts +5 -3
  507. package/src/resources/extensions/shared/browser-contract.ts +66 -0
  508. package/src/resources/extensions/shared/gsd-browser-cli.ts +119 -5
  509. package/src/resources/shared/package.json +3 -0
  510. package/src/resources/skills/create-skill/references/executable-code.md +1 -1
  511. package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
  512. package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
  513. package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
  514. package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  515. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  516. package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  517. package/src/resources/skills/gsd-browser/SKILL.md +1 -1
  518. package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
  519. /package/dist/web/standalone/.next/static/{3PtrU9qGPEXwNLWkIyiqk → mU4QIDlpVHDdjDpeEKh5W}/_buildManifest.js +0 -0
  520. /package/dist/web/standalone/.next/static/{3PtrU9qGPEXwNLWkIyiqk → mU4QIDlpVHDdjDpeEKh5W}/_ssgManifest.js +0 -0
@@ -1,7 +1,7 @@
1
1
  /** browser-tools — Pi Browser Automation Contract adapter. */
2
2
  import { importExtensionModule } from "@gsd/pi-coding-agent";
3
3
  import { closeManagedGsdBrowser, registerManagedGsdBrowserTools, warmUpManagedGsdBrowser } from "./engine/managed-gsd-browser.js";
4
- import { resolveBrowserEngineMode } from "./engine/selection.js";
4
+ import { commitBrowserEngineResolution, resolveAmbientBrowserEngineResolution } from "./engine/selection.js";
5
5
  import { setArtifactRootForCwd } from "./state.js";
6
6
  import { detectWebApp } from "./web-app-detect.js";
7
7
  let legacyRegistrationPromise = null;
@@ -130,12 +130,56 @@ function withBrowserArtifactCwdScope(pi) {
130
130
  },
131
131
  };
132
132
  }
133
- async function registerBrowserTools(pi) {
134
- const engine = resolveBrowserEngineMode();
133
+ /** Daemon-connect budget when the probe-resolved managed engine is verified at session start. */
134
+ const PROBE_WARMUP_TIMEOUT_MS = 10_000;
135
+ async function registerBrowserTools(pi, ctx) {
136
+ const projectRoot = ctx.cwd || process.cwd();
137
+ const resolution = resolveAmbientBrowserEngineResolution(projectRoot);
138
+ let engine = resolution.engine;
135
139
  if (engine === "off")
136
140
  return;
141
+ // A probe-resolved managed engine is only a prediction that gsd-browser
142
+ // works — prove it by connecting the daemon before committing the session's
143
+ // tool registrations to it. Connect failure falls back to legacy Playwright
144
+ // (the failure mode that made ADR-024 freeze the old default) and commits
145
+ // the outcome so ambient readers see the engine actually in use. When eager
146
+ // warm-up is disabled the daemon-connect proof cannot run, so the probe
147
+ // default treats the managed engine as unprovable and falls back to legacy
148
+ // rather than registering it unverified. An explicit
149
+ // GSD_BROWSER_ENGINE=gsd-browser override skips the gate and is honored
150
+ // verbatim, matching prior behavior.
151
+ if (engine === "gsd-browser" && resolution.source === "probe" && !registeredEngine) {
152
+ if (isWarmUpDisabled()) {
153
+ engine = commitLegacyFallback(projectRoot, "warm-up disabled; managed engine unverifiable; using legacy Playwright");
154
+ }
155
+ else {
156
+ const warmUp = await warmUpManagedGsdBrowser(ctx, AbortSignal.timeout(PROBE_WARMUP_TIMEOUT_MS));
157
+ if (!warmUp.ok) {
158
+ engine = commitLegacyFallback(projectRoot, `gsd-browser daemon connect failed (${warmUp.error}); using legacy Playwright`);
159
+ if (ctx.hasUI) {
160
+ ctx.ui.notify(`gsd-browser engine unavailable (${warmUp.error}); using Playwright browser tools for this session.`, "warning");
161
+ }
162
+ }
163
+ else if (warmUp.coverageWarning && ctx.hasUI) {
164
+ ctx.ui.notify(warmUp.coverageWarning, "warning");
165
+ }
166
+ }
167
+ }
168
+ // Browser tool registrations are process-global and cannot be swapped once
169
+ // live. When an earlier session in this process already registered an engine
170
+ // and this project resolved a different one (per-project probe resolution can
171
+ // diverge across projects in a multi-session process), adopt the registered
172
+ // engine rather than throwing — a throw surfaces as "browser-tools failed to
173
+ // load" and leaves this session with no browser tools at all. Commit the
174
+ // adoption so ambient readers (UAT guidance, warm-up) describe the engine
175
+ // actually in use.
137
176
  if (registeredEngine && registeredEngine !== engine) {
138
- throw new Error(`Browser tools already registered with GSD_BROWSER_ENGINE=${registeredEngine}. Restart GSD before switching to ${engine}.`);
177
+ engine = registeredEngine;
178
+ commitBrowserEngineResolution(projectRoot, {
179
+ engine,
180
+ source: "probe",
181
+ reason: `browser tools already registered with ${engine} earlier in this process; adopting it`,
182
+ });
139
183
  }
140
184
  let registration;
141
185
  if (engine === "legacy") {
@@ -165,27 +209,40 @@ async function registerBrowserTools(pi) {
165
209
  throw error;
166
210
  }
167
211
  }
212
+ function commitLegacyFallback(projectRoot, reason) {
213
+ commitBrowserEngineResolution(projectRoot, { engine: "legacy", source: "probe", reason });
214
+ return "legacy";
215
+ }
168
216
  function isWarmUpDisabled() {
169
217
  const value = process.env.GSD_BROWSER_WARMUP?.trim().toLowerCase();
170
218
  return value === "0" || value === "false" || value === "off";
171
219
  }
172
220
  /**
173
- * Auto-initialize the managed gsd-browser engine only when explicitly selected
174
- * for a web app. Best-effort and non-blocking: warm-up runs in the background
175
- * and only surfaces a warning if it fails.
221
+ * Auto-initialize the managed gsd-browser engine when it was selected via the
222
+ * explicit GSD_BROWSER_ENGINE override, which registers without the
223
+ * daemon-connect gate. Best-effort and non-blocking: warm-up runs in the
224
+ * background and only surfaces a warning if it fails. Probe-resolved sessions
225
+ * already connected (or fell back) during registration, so they are excluded
226
+ * to avoid re-warming and double-notifying.
176
227
  */
177
228
  function maybeWarmUpManagedEngine(pi, ctx) {
178
229
  if (isWarmUpDisabled())
179
230
  return;
180
- if (resolveBrowserEngineMode() !== "gsd-browser")
181
- return;
182
231
  const projectRoot = ctx.cwd || process.cwd();
232
+ const resolution = resolveAmbientBrowserEngineResolution(projectRoot);
233
+ if (resolution.engine !== "gsd-browser" || resolution.source !== "env")
234
+ return;
183
235
  if (!detectWebApp(projectRoot))
184
236
  return;
185
237
  void warmUpManagedGsdBrowser(ctx).then((result) => {
186
- if (!result.ok && ctx.hasUI) {
238
+ if (!ctx.hasUI)
239
+ return;
240
+ if (!result.ok) {
187
241
  ctx.ui.notify(`gsd-browser auto-init failed: ${result.error}. Browser UAT tools will retry on first use; run /gsd doctor if this persists.`, "warning");
188
242
  }
243
+ else if (result.coverageWarning) {
244
+ ctx.ui.notify(result.coverageWarning, "warning");
245
+ }
189
246
  });
190
247
  }
191
248
  async function closeActiveBrowserEngines() {
@@ -198,14 +255,14 @@ async function closeActiveBrowserEngines() {
198
255
  export default function (pi) {
199
256
  pi.on("session_start", async (_event, ctx) => {
200
257
  if (ctx.hasUI) {
201
- void registerBrowserTools(pi)
258
+ void registerBrowserTools(pi, ctx)
202
259
  .then(() => maybeWarmUpManagedEngine(pi, ctx))
203
260
  .catch((error) => {
204
261
  ctx.ui.notify(`browser-tools failed to load: ${error instanceof Error ? error.message : String(error)}`, "warning");
205
262
  });
206
263
  return;
207
264
  }
208
- await registerBrowserTools(pi);
265
+ await registerBrowserTools(pi, ctx);
209
266
  maybeWarmUpManagedEngine(pi, ctx);
210
267
  });
211
268
  pi.on("session_shutdown", async () => {
@@ -37,6 +37,15 @@ export const CLAUDE_CODE_MODELS = [
37
37
  contextWindow: 1_000_000,
38
38
  maxTokens: 128_000,
39
39
  },
40
+ {
41
+ id: "claude-fable-5",
42
+ name: "Claude Fable 5 (via Claude Code)",
43
+ reasoning: true,
44
+ input: ["text", "image"],
45
+ cost: ZERO_COST,
46
+ contextWindow: 1_000_000,
47
+ maxTokens: 128_000,
48
+ },
40
49
  {
41
50
  id: "claude-sonnet-4-6",
42
51
  name: "Claude Sonnet 4.6 (via Claude Code)",
@@ -24,6 +24,8 @@ import { markToolStart, markToolEnd } from "../gsd/auto.js";
24
24
  import { markInteractiveElicitationStart, markInteractiveElicitationEnd, } from "../gsd/auto-tool-tracking.js";
25
25
  import { discoverBrowserMcpServerName, discoverMcpServers, discoverMcpServerNames, discoverUserMcpServerNames, discoverWorkflowMcpServerName, computeMcpDisallowedTools, } from "../gsd/mcp-filter.js";
26
26
  import { RUN_UAT_CLAUDE_NATIVE_TOOL_NAMES, RUN_UAT_FORBIDDEN_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES, resolveToolPresentationPlan } from "../gsd/tool-presentation-plan.js";
27
+ import { getToolSurfaceReadinessError } from "../gsd/tool-surface-readiness.js";
28
+ import { hasBrowserContractPrefix } from "../shared/browser-contract.js";
27
29
  import { showInterviewRound } from "../shared/tui.js";
28
30
  export { buildFinalAssistantContent, extractToolResultsFromSdkUserMessage, handleClaudeCodePartialStreamEvent, mergePendingToolCalls, } from "./turn-assembler.js";
29
31
  export function serverToolUseToToolCallLike(block) {
@@ -1242,6 +1244,8 @@ function modelSupportsAdaptiveThinking(modelId) {
1242
1244
  || modelId.includes("opus-4.7")
1243
1245
  || modelId.includes("opus-4-8")
1244
1246
  || modelId.includes("opus-4.8")
1247
+ || modelId.includes("fable-5")
1248
+ || modelId.includes("fable.5")
1245
1249
  || modelId.includes("sonnet-4-6")
1246
1250
  || modelId.includes("sonnet-4.6")
1247
1251
  || modelId.includes("sonnet-4-7")
@@ -1263,7 +1267,9 @@ function mapThinkingLevelToAnthropicEffort(level, modelId) {
1263
1267
  if (modelId.includes("opus-4-7")
1264
1268
  || modelId.includes("opus-4.7")
1265
1269
  || modelId.includes("opus-4-8")
1266
- || modelId.includes("opus-4.8"))
1270
+ || modelId.includes("opus-4.8")
1271
+ || modelId.includes("fable-5")
1272
+ || modelId.includes("fable.5"))
1267
1273
  return "xhigh";
1268
1274
  if (modelId.includes("opus-4-6") || modelId.includes("opus-4.6"))
1269
1275
  return "max";
@@ -1285,7 +1291,7 @@ function browserMcpServerNameFromAllowedTools(allowedTools) {
1285
1291
  const parsed = parseAllowedMcpToolName(toolName);
1286
1292
  if (!parsed)
1287
1293
  continue;
1288
- if (parsed.server === "gsd-browser" || parsed.tool.startsWith("browser_")) {
1294
+ if (parsed.server === "gsd-browser" || hasBrowserContractPrefix(parsed.tool)) {
1289
1295
  return parsed.server;
1290
1296
  }
1291
1297
  }
@@ -1299,7 +1305,7 @@ function workflowMcpServerNameFromAllowedTools(allowedTools) {
1299
1305
  if (typeof toolName !== "string")
1300
1306
  continue;
1301
1307
  const parsed = parseAllowedMcpToolName(toolName);
1302
- if (!parsed || parsed.server === browserServerName || parsed.tool.startsWith("browser_"))
1308
+ if (!parsed || parsed.server === browserServerName || hasBrowserContractPrefix(parsed.tool))
1303
1309
  continue;
1304
1310
  return parsed.server;
1305
1311
  }
@@ -1564,7 +1570,9 @@ export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
1564
1570
  || modelId.includes("opus-4-7")
1565
1571
  || modelId.includes("opus-4.7")
1566
1572
  || modelId.includes("opus-4-8")
1567
- || modelId.includes("opus-4.8")) ? ["context-1m-2025-08-07"] : [],
1573
+ || modelId.includes("opus-4.8")
1574
+ || modelId.includes("fable-5")
1575
+ || modelId.includes("fable.5")) ? ["context-1m-2025-08-07"] : [],
1568
1576
  ...(thinkingConfig ?? {}),
1569
1577
  ...(effort ? { effort } : {}),
1570
1578
  ...sdkExtraOptions,
@@ -1629,8 +1637,9 @@ async function pumpSdkMessages(model, context, options, stream) {
1629
1637
  }
1630
1638
  : {}),
1631
1639
  });
1640
+ const workflowMcpServerName = workflowMcpServerNameFromAllowedTools(sdkOpts.allowedTools);
1632
1641
  const prompt = buildPromptFromContext(context, {
1633
- workflowMcpServerName: workflowMcpServerNameFromAllowedTools(sdkOpts.allowedTools),
1642
+ workflowMcpServerName,
1634
1643
  browserMcpServerName: browserMcpServerNameFromAllowedTools(sdkOpts.allowedTools),
1635
1644
  });
1636
1645
  const queryPrompt = buildSdkQueryPrompt(context, prompt);
@@ -1668,7 +1677,30 @@ async function pumpSdkMessages(model, context, options, stream) {
1668
1677
  switch (msg.type) {
1669
1678
  // -- Init --
1670
1679
  case "system": {
1671
- // Nothing to emit the stream is already started.
1680
+ // Tool Surface Readiness gate: the init message is the first (and
1681
+ // only) point where the session reports its live tool surface and
1682
+ // MCP server statuses. If the workflow server failed or has not
1683
+ // registered this Unit's required tools, abort before the first
1684
+ // model turn with a transient, recovery-classifiable error
1685
+ // (tool-unavailable → retry) instead of letting the model hit
1686
+ // "No such tool available" mid-Unit and improvise around it.
1687
+ const init = msg;
1688
+ if (init.subtype === "init") {
1689
+ const readinessError = getToolSurfaceReadinessError({
1690
+ unitType: gsdPhase,
1691
+ workflowServerName: workflowMcpServerName,
1692
+ observation: { tools: init.tools ?? [], mcpServers: init.mcp_servers ?? [] },
1693
+ });
1694
+ if (readinessError) {
1695
+ controller.abort();
1696
+ stream.push({
1697
+ type: "error",
1698
+ reason: "error",
1699
+ error: makeErrorMessage(modelId, readinessError),
1700
+ });
1701
+ return;
1702
+ }
1703
+ }
1672
1704
  break;
1673
1705
  }
1674
1706
  // -- Streaming partial messages --
@@ -9,8 +9,9 @@
9
9
  // the real collaborators (state-reconciliation, doctor-proactive,
10
10
  // auto-dispatch, recovery-classification, tool-contract, worktree-safety,
11
11
  // uok/gate-runner, journal, session-lock, ctx.ui.notify) directly.
12
- import { debugCount, debugTime } from "../debug-logger.js";
12
+ import { debugCount, debugLog, debugTime } from "../debug-logger.js";
13
13
  import { reconcileBeforeDispatch } from "../state-reconciliation.js";
14
+ import { isLegalEdge, IllegalPhaseTransitionError } from "../state-transition-matrix.js";
14
15
  import { resolveDispatch } from "../auto-dispatch.js";
15
16
  import { classifyFailure } from "../recovery-classification.js";
16
17
  import { verifyExpectedArtifact, refreshRecoveryDbForArtifact } from "../auto-recovery.js";
@@ -24,7 +25,7 @@ import { checkResourcesStale, autoWorktreeBranch, mergeMilestoneToMain } from ".
24
25
  import { getSessionLockStatus } from "../session-lock.js";
25
26
  import { resolveUokFlags } from "../uok/flags.js";
26
27
  import { emitJournalEvent as _emitJournalEvent } from "../journal.js";
27
- import { loadEffectiveGSDPreferences, getIsolationMode } from "../preferences.js";
28
+ import { loadEffectiveGSDPreferences, getIsolationMode, resolveEffectiveUnitIsolationMode } from "../preferences.js";
28
29
  import { detectWorktreeName, getMainBranch, resolveProjectRoot, resolveWorktreeProjectRoot, } from "../worktree.js";
29
30
  import { getPriorSliceCompletionBlocker } from "../dispatch-guard.js";
30
31
  import { GitServiceImpl } from "../git-service.js";
@@ -244,6 +245,10 @@ export class AutoOrchestrator {
244
245
  lastAdvanceKey = null;
245
246
  lastFinalizedUnitKey = null;
246
247
  dispatchKeyWindow = [];
248
+ // ADR-030 Phase Transition Invariant: the prior advance's reconciled Phase,
249
+ // the "from" endpoint of the edge check. In-memory; reset on start/resume/stop
250
+ // so the first advance of a session has no edge to assert.
251
+ lastDerivedPhase = null;
247
252
  // #442: the unit key we last attempted graduated stuck-recovery for. Bounds
248
253
  // recovery to one attempt per stuck episode per run (reset on start/resume/
249
254
  // stop), mirroring the legacy Level-1-then-Level-2 escalation in phases.ts.
@@ -476,8 +481,7 @@ export class AutoOrchestrator {
476
481
  }
477
482
  // ── WorktreeAdapter (folded) ─────────────────────────────────────────────
478
483
  getEffectiveUnitIsolationMode(basePath) {
479
- const configuredMode = getIsolationMode(basePath);
480
- return configuredMode === "worktree" && this.s.isolationDegraded ? "branch" : configuredMode;
484
+ return resolveEffectiveUnitIsolationMode(getIsolationMode(basePath), this.s.isolationDegraded, this.s.strandedRecoveryIsolationMode);
481
485
  }
482
486
  buildLifecycle() {
483
487
  return new WorktreeLifecycle(this.s, {
@@ -576,6 +580,21 @@ export class AutoOrchestrator {
576
580
  const recovery = classifyFailure(input);
577
581
  return { action: recovery.action, reason: recovery.reason };
578
582
  }
583
+ /**
584
+ * ADR-030 Phase Transition Invariant (advisory mode). The matrix is an
585
+ * assertion, not a decision-maker — deriveState already chose the phase; we
586
+ * only observe illegal *derived* edges that survived reconciliation. The
587
+ * matrix is still a sparse hardening spec, so this is telemetry-only (no
588
+ * block) until it is expanded into a validated legal-edge graph. To enforce:
589
+ * `throw violation;` instead of logging — recovery-classification maps
590
+ * IllegalPhaseTransitionError to kind "illegal-transition" (escalate).
591
+ */
592
+ observePhaseTransition(from, to) {
593
+ if (isLegalEdge(from, to))
594
+ return;
595
+ const violation = new IllegalPhaseTransitionError(from, to);
596
+ debugLog("phase-transition-advisory", { from, to, message: violation.message });
597
+ }
579
598
  // ── Lifecycle verbs ──────────────────────────────────────────────────────
580
599
  /**
581
600
  * #442: graduated stuck recovery, ported from the legacy
@@ -636,6 +655,7 @@ export class AutoOrchestrator {
636
655
  this.lastFinalizedUnitKey = null;
637
656
  this.dispatchKeyWindow = [];
638
657
  this.lastStuckRecoveryKey = null;
658
+ this.lastDerivedPhase = null;
639
659
  this.status.phase = "running";
640
660
  this.bumpTransition();
641
661
  this.journalTransition({ name: "start" });
@@ -721,6 +741,11 @@ export class AutoOrchestrator {
721
741
  this.postAdvanceRecord(blocked);
722
742
  return blocked;
723
743
  }
744
+ const reconciledPhase = reconciliation.stateSnapshot.phase;
745
+ if (this.lastDerivedPhase !== null) {
746
+ this.observePhaseTransition(this.lastDerivedPhase, reconciledPhase);
747
+ }
748
+ this.lastDerivedPhase = reconciledPhase;
724
749
  const decision = await this.decideNextUnit({ stateSnapshot: reconciliation.stateSnapshot });
725
750
  if (!decision) {
726
751
  const settlementBlock = this.evaluateNoRemainingUnitsSettlement(reconciliation.stateSnapshot);
@@ -833,16 +858,18 @@ export class AutoOrchestrator {
833
858
  // checks coexist: idempotency for the common immediate-repeat case,
834
859
  // stuck-loop for the saturated-window case.
835
860
  if (this.lastAdvanceKey === nextKey && matchingCount < STUCK_WINDOW_SIZE) {
861
+ // Unit already active — benign no-op. Return skipped so the loop re-polls
862
+ // without cancelling the in-flight unit (blocked+pause would force-cancel it).
836
863
  this.clearPendingDispatch();
837
- const blocked = { kind: "blocked", reason: "idempotent advance: unit already active", action: "pause" };
864
+ const skipped = { kind: "skipped", reason: "idempotent advance: unit already active" };
838
865
  this.journalTransition({
839
- name: "advance-blocked",
840
- reason: blocked.reason,
866
+ name: "advance-skipped",
867
+ reason: skipped.reason,
841
868
  unitType: decision.unitType,
842
869
  unitId: decision.unitId,
843
870
  });
844
- this.postAdvanceRecord(blocked);
845
- return blocked;
871
+ this.postAdvanceRecord(skipped);
872
+ return skipped;
846
873
  }
847
874
  // Stuck-loop detection: when the ring is saturated with copies of
848
875
  // `nextKey` (count >= STUCK_WINDOW_SIZE), the orchestrator has been
@@ -981,6 +1008,9 @@ export class AutoOrchestrator {
981
1008
  // Preserve dispatchKeyWindow across resume so stuck-loop detection
982
1009
  // accumulates across pause/resume cycles rather than resetting each time.
983
1010
  this.lastStuckRecoveryKey = null;
1011
+ // ADR-030: drop the prior "from" — the first advance after resume has no
1012
+ // edge to assert (avoids a false illegal-edge across the pause boundary).
1013
+ this.lastDerivedPhase = null;
984
1014
  this.status.phase = "running";
985
1015
  this.bumpTransition();
986
1016
  this.journalTransition({ name: "resume" });
@@ -996,6 +1026,7 @@ export class AutoOrchestrator {
996
1026
  this.status.activeUnit = undefined;
997
1027
  this.lastAdvanceKey = null;
998
1028
  this.lastFinalizedUnitKey = null;
1029
+ this.lastDerivedPhase = null;
999
1030
  // Preserve dispatchKeyWindow on pause so stuck-loop detection accumulates
1000
1031
  // across pause/resume cycles. Only clear on a hard stop.
1001
1032
  if (reason !== "pause") {
@@ -11,6 +11,7 @@
11
11
  import { importExtensionModule } from "@gsd/pi-coding-agent";
12
12
  import { USER_DRIVEN_DEEP_UNITS, isAwaitingUserInput, } from "../auto-post-unit.js";
13
13
  import { lastAssistantText } from "../user-input-boundary.js";
14
+ import { resolveEffectiveUnitIsolationMode } from "../preferences.js";
14
15
  import { MAX_RECOVERY_CHARS, BUDGET_THRESHOLDS, MAX_FINALIZE_TIMEOUTS, } from "./types.js";
15
16
  import { detectStuck } from "./detect-stuck.js";
16
17
  import { runUnit } from "./run-unit.js";
@@ -265,7 +266,11 @@ async function validateSourceWriteWorktreeSafety(ic, unitType, unitId, milestone
265
266
  if (!writesSource)
266
267
  return null;
267
268
  const projectRoot = s.canonicalProjectRoot ?? resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
268
- const isolationMode = deps.getIsolationMode(projectRoot);
269
+ // A degraded session already fell back to the milestone branch in the
270
+ // project root — validating against the canonical worktree root there
271
+ // would fail every dispatch with a false invalid-root. The same applies
272
+ // to a stranded-recovery session that adopted the milestone branch.
273
+ const isolationMode = resolveEffectiveUnitIsolationMode(deps.getIsolationMode(projectRoot), s.isolationDegraded, s.strandedRecoveryIsolationMode);
269
274
  if (isolationMode !== "worktree")
270
275
  return null;
271
276
  const safety = createWorktreeSafetyModule();
@@ -22,7 +22,8 @@ import { isAutoActive } from "./auto.js";
22
22
  import { markDepthVerified } from "./bootstrap/write-gate.js";
23
23
  import { ensureWorkflowPreferencesCaptured } from "./planning-depth.js";
24
24
  import { MILESTONE_ID_RE } from "./milestone-ids.js";
25
- import { getWorkflowTransportSupportError, getRequiredWorkflowToolsForAutoUnit, } from "./workflow-mcp.js";
25
+ import { getWorkflowTransportSupportError, getRequiredWorkflowToolsForAutoUnit, resolveWorkflowMcpProjectRoot, } from "./workflow-mcp.js";
26
+ import { prepareBrowserDaemonForUat } from "./browser-daemon-auto-prep.js";
26
27
  import { PROJECT_RESEARCH_INFLIGHT_MARKER, } from "./project-research-policy.js";
27
28
  import { isWorkflowPrefsCaptured, resolveDeepProjectSetupState, } from "./deep-project-setup-policy.js";
28
29
  import { annotateBackgroundable } from "./delegation-policy.js";
@@ -540,6 +541,16 @@ export const DISPATCH_RULES = [
540
541
  if (browserToolError) {
541
542
  return { action: "stop", reason: browserToolError, level: "warning" };
542
543
  }
544
+ const browserDaemonError = prepareBrowserDaemonForUat({
545
+ uatType,
546
+ sessionProvider,
547
+ sessionAuthMode,
548
+ sessionBaseUrl,
549
+ projectRoot: resolveWorkflowMcpProjectRoot(basePath),
550
+ });
551
+ if (browserDaemonError) {
552
+ return { action: "stop", reason: browserDaemonError, level: "warning" };
553
+ }
543
554
  // Cap run-uat dispatch attempts to prevent infinite replay (#3624).
544
555
  // Check before incrementing so an exhausted counter cannot create a
545
556
  // no-progress skip loop that starves later dispatch rules.
@@ -839,15 +839,34 @@ export function resolveModelId(modelId, availableModels, currentProvider) {
839
839
  if (providerMatch)
840
840
  return providerMatch;
841
841
  }
842
- // Prefer "anthropic" as the canonical provider for Anthropic models.
843
- // Transport-specific tiebreaker (ADR-012): intentionally keys on provider,
844
- // not api we want the plain Anthropic transport when multiple are available.
845
- const anthropicMatch = candidates.find(m => m.provider === "anthropic");
846
- if (anthropicMatch)
847
- return anthropicMatch;
842
+ // Subscription/OAuth routes beat pay-per-token API when the same model ID
843
+ // exists on multiple providers. Order matters — first match wins.
844
+ for (const provider of BARE_ID_SUBSCRIPTION_PROVIDER_PRECEDENCE) {
845
+ const match = candidates.find(m => m.provider === provider);
846
+ if (match)
847
+ return match;
848
+ }
848
849
  // Fall back to first non-extension candidate, or any candidate
849
850
  return candidates.find(m => !EXTENSION_PROVIDERS.has(m.provider)) ?? candidates[0];
850
851
  }
852
+ /**
853
+ * When a bare model ID exists on multiple providers, prefer subscription/OAuth
854
+ * routes over pay-per-token API keys. Matches PROVIDER_ROUTES in doctor-providers
855
+ * but applies when *both* sides are authenticated.
856
+ *
857
+ * Order rationale:
858
+ * - openai-codex before github-copilot: ChatGPT-native for shared GPT IDs
859
+ * - google-gemini-cli before github-copilot: first-party Gemini CLI
860
+ * - anthropic before github-copilot: first-party Claude API/OAuth over Copilot
861
+ * - github-copilot before openai/google: Copilot OAuth over platform API keys
862
+ */
863
+ export const BARE_ID_SUBSCRIPTION_PROVIDER_PRECEDENCE = [
864
+ "openai-codex",
865
+ "google-gemini-cli",
866
+ "anthropic",
867
+ "github-copilot",
868
+ "google-antigravity",
869
+ ];
851
870
  /**
852
871
  * Flat-rate providers charge the same per request regardless of model.
853
872
  * Dynamic routing provides no cost benefit — it only degrades quality (#3453).
@@ -39,7 +39,7 @@ import { debugLog } from "./debug-logger.js";
39
39
  import { runSafely } from "./auto-utils.js";
40
40
  import { isMilestoneCloseoutSettled, runMilestoneCloseoutGitHub, } from "./milestone-closeout.js";
41
41
  import { getEvidence, clearEvidenceFromDisk, isExecutionToolName } from "./safety/evidence-collector.js";
42
- import { validateFileChanges } from "./safety/file-change-validator.js";
42
+ import { validateFileChanges, effectiveFileChangeAllowlist } from "./safety/file-change-validator.js";
43
43
  import { crossReferenceEvidence } from "./safety/evidence-cross-ref.js";
44
44
  import { validateContent } from "./safety/content-validator.js";
45
45
  import { resolveSafetyHarnessConfig } from "./safety/safety-harness.js";
@@ -55,7 +55,7 @@ import { writeTurnGitTransaction } from "./uok/gitops.js";
55
55
  import { isClosedStatus } from "./status-guards.js";
56
56
  import { detectAbandonMilestone } from "./abandon-detect.js";
57
57
  import { getPendingGate } from "./bootstrap/write-gate.js";
58
- import { isDeterministicPolicyError } from "./auto-tool-tracking.js";
58
+ import { isDeterministicPolicyError, isToolUnavailableError } from "./auto-tool-tracking.js";
59
59
  import { formatConnectedStepStack, formatPostUnitStatusCard } from "./auto-status-message.js";
60
60
  import { clearProjectResearchInflightMarker, finalizeProjectResearchTimeout, } from "./project-research-policy.js";
61
61
  import { validateArtifact } from "./schemas/validate.js";
@@ -507,9 +507,10 @@ export function _hasExecutionToolCallsInSessionForTest(entries) {
507
507
  if (e?.type === "toolCall" && isExecutionToolName(e?.name ?? e?.toolName)) {
508
508
  return true;
509
509
  }
510
- if (e?.type !== "message")
511
- continue;
512
- const msg = e?.message;
510
+ // Accept both session-manager entries ({type: "message", message}) and
511
+ // bare agent-end messages ({role, content}) — the auto loop passes the
512
+ // latter via opts.agentEndMessages.
513
+ const msg = e?.type === "message" ? e?.message : e;
513
514
  if (!msg || msg.role !== "assistant" || !Array.isArray(msg.content))
514
515
  continue;
515
516
  for (const block of msg.content) {
@@ -1289,6 +1290,7 @@ export async function postUnitPreVerification(pctx, opts) {
1289
1290
  const safetyConfig = resolveSafetyHarnessConfig(prefs?.safety_harness);
1290
1291
  if (safetyConfig.enabled) {
1291
1292
  const { milestone: sMid, slice: sSid, task: sTid } = parseUnitId(s.currentUnit.id);
1293
+ const fileChangeAllowlist = effectiveFileChangeAllowlist(safetyConfig.file_change_allowlist, prefs?.git?.manage_gitignore);
1292
1294
  // File change validation (execute-task only, after unit execution)
1293
1295
  if (safetyConfig.file_change_validation && s.currentUnit.type === "execute-task" && sMid && sSid && sTid) {
1294
1296
  try {
@@ -1303,7 +1305,7 @@ export async function postUnitPreVerification(pctx, opts) {
1303
1305
  const plannedFiles = getPlannedKeyFiles(sliceTaskRows.map((taskRow) => ({
1304
1306
  files: taskRow.files,
1305
1307
  })));
1306
- const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, safetyConfig.file_change_allowlist);
1308
+ const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, fileChangeAllowlist);
1307
1309
  if (audit && audit.violations.length > 0) {
1308
1310
  const warnings = audit.violations.filter(v => v.severity === "warning");
1309
1311
  for (const v of warnings) {
@@ -1319,7 +1321,7 @@ export async function postUnitPreVerification(pctx, opts) {
1319
1321
  if (taskRow) {
1320
1322
  const expectedOutput = taskRow.expected_output ?? [];
1321
1323
  const plannedFiles = taskRow.files ?? [];
1322
- const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, safetyConfig.file_change_allowlist);
1324
+ const audit = validateFileChanges(s.basePath, expectedOutput, plannedFiles, fileChangeAllowlist);
1323
1325
  if (audit && audit.violations.length > 0) {
1324
1326
  const warnings = audit.violations.filter(v => v.severity === "warning");
1325
1327
  for (const v of warnings) {
@@ -1699,7 +1701,16 @@ export async function postUnitPreVerification(pctx, opts) {
1699
1701
  ctx.ui.notify(`Artifact missing for ${s.currentUnit.type} ${s.currentUnit.id} — DB unavailable, skipping retry.${dbSkipDiag ? ` Expected: ${dbSkipDiag}` : ""}`, "error");
1700
1702
  }
1701
1703
  else if (!triggerArtifactVerified) {
1702
- if (s.lastToolInvocationError) {
1704
+ if (s.lastToolInvocationError && isToolUnavailableError(s.lastToolInvocationError)) {
1705
+ // Tool-unavailable is the one transient invocation error: the
1706
+ // workflow MCP server registers its surface asynchronously, so a
1707
+ // Unit's first call can race the registration. Fall through to the
1708
+ // bounded verification retry instead of pausing.
1709
+ debugLog("postUnit", { phase: "tool-unavailable-retry", unitType: s.currentUnit.type, unitId: s.currentUnit.id, error: s.lastToolInvocationError });
1710
+ ctx.ui.notify(`Tool unavailable for ${s.currentUnit.type}: ${s.lastToolInvocationError}. The tool surface may still be registering — retrying.`, "warning");
1711
+ s.lastToolInvocationError = null;
1712
+ }
1713
+ else if (s.lastToolInvocationError) {
1703
1714
  const isUserSkip = /queued user message/i.test(s.lastToolInvocationError);
1704
1715
  const errMsg = isUserSkip
1705
1716
  ? `Tool skipped for ${s.currentUnit.type}: ${s.lastToolInvocationError}. Queued user message interrupted the turn — pausing auto-mode.`
@@ -21,7 +21,7 @@ import { getPendingGatesForTurn } from "./gsd-db.js";
21
21
  import { assertGateCoverage, getGatesForTurn, } from "./gate-registry.js";
22
22
  import { formatDecisionsCompact, formatRequirementsCompact } from "./structured-data-formatter.js";
23
23
  import { readPhaseAnchor, formatAnchorForPrompt } from "./phase-anchor.js";
24
- import { composeContextModeInstructions, composeContractedUnitContext, composeInlinedContext, composeUnitContext, } from "./unit-context-composer.js";
24
+ import { composeContextModeInstructions, composeContractedUnitContext, composeInlinedContext, composeToolSurfaceInstructions, composeUnitContext, } from "./unit-context-composer.js";
25
25
  import { resolveManifest } from "./unit-context-manifest.js";
26
26
  import { compileUnitContextContract } from "./tool-contract.js";
27
27
  import { readCompactionSnapshot } from "./compaction-snapshot.js";
@@ -224,12 +224,14 @@ function renderContextModeBlockForPrompt(unitType, base, renderMode = "standalon
224
224
  return `${contextMode}\n\n## Context Snapshot\nSource: \`.gsd/last-snapshot.md\`\n\n${snapshot.trimEnd()}`;
225
225
  }
226
226
  function prependContextModeToBlock(unitType, base, block, renderMode = "standalone") {
227
+ const toolSurface = composeToolSurfaceInstructions(unitType, { renderMode });
227
228
  const contextMode = renderContextModeBlockForPrompt(unitType, base, renderMode);
228
- if (!contextMode)
229
+ const guidance = [toolSurface, contextMode].filter(Boolean).join("\n\n");
230
+ if (!guidance)
229
231
  return block;
230
232
  if (!block.trim())
231
- return contextMode;
232
- return `${contextMode}\n\n${block}`;
233
+ return guidance;
234
+ return `${guidance}\n\n${block}`;
233
235
  }
234
236
  function requireUnitPromptContextContract(unitType) {
235
237
  const result = compileUnitContextContract(unitType);
@@ -2146,6 +2148,9 @@ export async function buildPlanSlicePrompt(mid, _midTitle, sid, sTitle, base, le
2146
2148
  `Either (a) add an earlier task that creates X on disk before the task that needs it, ` +
2147
2149
  `or (b) if this task IS the one that creates X, move X from inputs to expected_output. ` +
2148
2150
  `Do NOT put X in a task's expected_output if that task only reads or verifies X — only tasks that actually write X to disk should list it in expected_output.\n` +
2151
+ `- **"[file] X: ... GSD planning artifacts are projections preloaded as context / written by workflow tools"**: ` +
2152
+ `Remove X from the task's inputs, files, and expectedOutput entirely. Planning artifacts (anything under .gsd/, .planning/, or .audits/, or names like M001-CONTEXT.md / S01-PLAN.md) are preloaded as context and written by workflow tools — ` +
2153
+ `do NOT add a task that creates X and do NOT move X to expectedOutput.\n` +
2149
2154
  `- **"[file] X: Task T_early reads X but it's created by task T_late (sequence violation)"**: ` +
2150
2155
  `Either (a) reorder tasks so T_late (the creator) runs before T_early (the reader), ` +
2151
2156
  `or (b) if T_late doesn't actually create X (it only reads/tests it), remove X from T_late's expected_output entirely.\n` +
@@ -3338,18 +3343,18 @@ opts) {
3338
3343
  }
3339
3344
  const inlinedTemplates = inlineTemplate("task-summary", "Task Summary");
3340
3345
  trackPromptContext(contextTelemetry, "templates", "inline", inlinedTemplates);
3341
- const prompt = loadPrompt("reactive-execute", {
3346
+ const prompt = prependContextModeToBlock("reactive-execute", base, loadPrompt("reactive-execute", {
3342
3347
  workingDirectory: base,
3343
3348
  milestoneId: mid,
3344
3349
  milestoneTitle: midTitle,
3345
3350
  sliceId: sid,
3346
3351
  sliceTitle: sTitle,
3347
- graphContext: prependContextModeToBlock("reactive-execute", base, graphContext),
3352
+ graphContext,
3348
3353
  readyTaskCount: String(readyTaskIds.length),
3349
3354
  readyTaskList: readyTaskListLines.join("\n"),
3350
3355
  subagentPrompts: subagentSections.join("\n\n---\n\n"),
3351
3356
  inlinedTemplates,
3352
- });
3357
+ }));
3353
3358
  emitPromptContextTelemetry("reactive-execute", contextTelemetry, prompt);
3354
3359
  return prompt;
3355
3360
  }
@@ -3489,17 +3494,17 @@ export async function buildGateEvaluatePrompt(mid, midTitle, sid, sTitle, base,
3489
3494
  "```",
3490
3495
  ].join("\n"));
3491
3496
  }
3492
- return loadPrompt("gate-evaluate", {
3497
+ return prependContextModeToBlock("gate-evaluate", base, loadPrompt("gate-evaluate", {
3493
3498
  workingDirectory: base,
3494
3499
  milestoneId: mid,
3495
3500
  milestoneTitle: midTitle,
3496
3501
  sliceId: sid,
3497
3502
  sliceTitle: sTitle,
3498
- slicePlanContent: prependContextModeToBlock("gate-evaluate", base, planContent),
3503
+ slicePlanContent: planContent,
3499
3504
  gateCount: String(pending.length),
3500
3505
  gateList: gateListLines.join("\n"),
3501
3506
  subagentPrompts: subagentSections.join("\n\n---\n\n"),
3502
- });
3507
+ }));
3503
3508
  }
3504
3509
  export async function buildRewriteDocsPrompt(mid, midTitle, activeSlice, base, overrides) {
3505
3510
  const sid = activeSlice?.id;