@opengsd/gsd-pi 1.2.0-dev.4c756166 → 1.2.0-dev.822c9439

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 (688) 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 +14 -34
  6. package/dist/mcp-server.js +2 -1
  7. package/dist/models-resolver.d.ts +3 -13
  8. package/dist/models-resolver.js +3 -22
  9. package/dist/resource-loader.d.ts +9 -5
  10. package/dist/resource-loader.js +116 -20
  11. package/dist/resources/.managed-resources-content-hash +1 -1
  12. package/dist/resources/GSD-WORKFLOW.md +5 -4
  13. package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
  14. package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
  15. package/dist/resources/extensions/async-jobs/index.js +65 -0
  16. package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
  17. package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
  18. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
  19. package/dist/resources/extensions/bg-shell/overlay.js +9 -6
  20. package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
  21. package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
  22. package/dist/resources/extensions/bg-shell/utilities.js +5 -2
  23. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
  24. package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
  25. package/dist/resources/extensions/browser-tools/index.js +69 -12
  26. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  27. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +38 -6
  28. package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
  29. package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
  30. package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
  31. package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
  32. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  33. package/dist/resources/extensions/gsd/auto/orchestrator.js +122 -58
  34. package/dist/resources/extensions/gsd/auto/phases.js +54 -6
  35. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  36. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
  37. package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
  38. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
  39. package/dist/resources/extensions/gsd/auto-post-unit.js +43 -14
  40. package/dist/resources/extensions/gsd/auto-prompts.js +81 -19
  41. package/dist/resources/extensions/gsd/auto-start.js +24 -26
  42. package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
  43. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  44. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +12 -20
  45. package/dist/resources/extensions/gsd/auto-verification.js +23 -30
  46. package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
  47. package/dist/resources/extensions/gsd/auto-worktree.js +49 -353
  48. package/dist/resources/extensions/gsd/auto.js +45 -21
  49. package/dist/resources/extensions/gsd/blocked-models.js +28 -0
  50. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +29 -8
  51. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -12
  52. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
  53. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
  54. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +229 -36
  55. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +319 -71
  56. package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
  57. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  58. package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
  59. package/dist/resources/extensions/gsd/captures.js +5 -15
  60. package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
  61. package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
  62. package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
  63. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  64. package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
  65. package/dist/resources/extensions/gsd/consent-question.js +353 -0
  66. package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
  67. package/dist/resources/extensions/gsd/constants.js +0 -2
  68. package/dist/resources/extensions/gsd/crash-recovery.js +12 -15
  69. package/dist/resources/extensions/gsd/db/engine.js +755 -0
  70. package/dist/resources/extensions/gsd/db/queries.js +398 -0
  71. package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
  72. package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
  73. package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
  74. package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
  75. package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
  76. package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
  77. package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
  78. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  79. package/dist/resources/extensions/gsd/doctor-environment.js +5 -11
  80. package/dist/resources/extensions/gsd/doctor-format.js +9 -6
  81. package/dist/resources/extensions/gsd/doctor-git-checks.js +6 -21
  82. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +21 -16
  83. package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
  84. package/dist/resources/extensions/gsd/error-classifier.js +9 -0
  85. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  86. package/dist/resources/extensions/gsd/files.js +33 -19
  87. package/dist/resources/extensions/gsd/git-service.js +1 -0
  88. package/dist/resources/extensions/gsd/gitignore.js +3 -0
  89. package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
  90. package/dist/resources/extensions/gsd/gsd-db.js +172 -2048
  91. package/dist/resources/extensions/gsd/guidance.js +158 -0
  92. package/dist/resources/extensions/gsd/guided-flow.js +57 -8
  93. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
  94. package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
  95. package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
  96. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
  97. package/dist/resources/extensions/gsd/migrate/safety.js +20 -9
  98. package/dist/resources/extensions/gsd/migration-auto-check.js +24 -3
  99. package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
  100. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
  101. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  102. package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
  103. package/dist/resources/extensions/gsd/model-router.js +3 -0
  104. package/dist/resources/extensions/gsd/notification-store.js +11 -4
  105. package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
  106. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +11 -7
  107. package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
  108. package/dist/resources/extensions/gsd/paths.js +37 -24
  109. package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
  110. package/dist/resources/extensions/gsd/preferences-models.js +14 -48
  111. package/dist/resources/extensions/gsd/preferences.js +14 -0
  112. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  113. package/dist/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  114. package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
  115. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  116. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -2
  117. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  118. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  119. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  120. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  121. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  122. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  123. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  124. package/dist/resources/extensions/gsd/prompts/run-uat.md +7 -5
  125. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  126. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  127. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  128. package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
  129. package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
  130. package/dist/resources/extensions/gsd/publication.js +87 -0
  131. package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
  132. package/dist/resources/extensions/gsd/recovery-classification.js +41 -87
  133. package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
  134. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  135. package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
  136. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
  137. package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
  138. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  139. package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
  140. package/dist/resources/extensions/gsd/state.js +6 -20
  141. package/dist/resources/extensions/gsd/status-guards.js +56 -8
  142. package/dist/resources/extensions/gsd/stop-notice.js +57 -0
  143. package/dist/resources/extensions/gsd/tool-contract.js +14 -3
  144. package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
  145. package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
  146. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  147. package/dist/resources/extensions/gsd/tools/complete-slice.js +46 -55
  148. package/dist/resources/extensions/gsd/tools/complete-task.js +3 -2
  149. package/dist/resources/extensions/gsd/tools/exec-tool.js +10 -8
  150. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -8
  151. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  152. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
  153. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +13 -31
  154. package/dist/resources/extensions/gsd/tools/reopen-slice.js +16 -35
  155. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  156. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  157. package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
  158. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
  159. package/dist/resources/extensions/gsd/uat-policy.js +42 -16
  160. package/dist/resources/extensions/gsd/undo.js +8 -7
  161. package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
  162. package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
  163. package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
  164. package/dist/resources/extensions/gsd/unit-registry.js +337 -0
  165. package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
  166. package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
  167. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  168. package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
  169. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  170. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  171. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  172. package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
  173. package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
  174. package/dist/resources/extensions/gsd/worktree-git-recovery.js +293 -0
  175. package/dist/resources/extensions/gsd/worktree-lifecycle.js +12 -3
  176. package/dist/resources/extensions/gsd/worktree-manager.js +52 -29
  177. package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
  178. package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
  179. package/dist/resources/extensions/gsd/worktree-root.js +28 -6
  180. package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
  181. package/dist/resources/extensions/gsd/worktree-session-state.js +12 -11
  182. package/dist/resources/extensions/gsd/worktree.js +8 -1
  183. package/dist/resources/extensions/search-the-web/native-search.js +5 -3
  184. package/dist/resources/extensions/shared/browser-contract.js +59 -0
  185. package/dist/resources/extensions/shared/gsd-browser-cli.js +116 -6
  186. package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
  187. package/dist/resources/shared/package-manager-detection.js +1 -1
  188. package/dist/resources/shared/package.json +3 -0
  189. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  190. package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
  191. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  192. package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
  193. package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
  194. package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
  195. package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  196. package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  197. package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  198. package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
  199. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  200. package/dist/update-check.d.ts +2 -0
  201. package/dist/update-check.js +24 -1
  202. package/dist/update-cmd.js +20 -3
  203. package/dist/web/standalone/.next/BUILD_ID +1 -1
  204. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  205. package/dist/web/standalone/.next/build-manifest.json +3 -3
  206. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  207. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  208. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  209. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  210. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  211. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  212. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  213. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  214. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  215. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  216. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  217. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  218. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  219. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  220. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  221. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  222. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  223. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  224. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  225. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  226. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  227. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  228. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  229. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  230. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  231. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  232. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  233. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  234. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  235. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  236. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  237. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  238. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  239. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  240. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  241. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  242. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  243. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  244. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  245. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  246. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  247. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  248. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  249. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  250. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  251. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  252. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  253. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  254. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  255. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  256. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  257. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  258. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  259. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  260. package/dist/web/standalone/.next/server/app/index.html +1 -1
  261. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  262. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  263. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  264. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  265. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  266. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  267. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  268. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  269. package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
  270. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  271. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  272. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  273. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  274. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  275. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  276. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  277. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  278. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  279. package/dist/web/standalone/package.json +1 -1
  280. package/dist/worktree-cli.js +3 -6
  281. package/dist/worktree-status-banner.js +7 -11
  282. package/package.json +1 -1
  283. package/packages/cloud-mcp-gateway/package.json +2 -2
  284. package/packages/contracts/dist/rpc.d.ts +1 -0
  285. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  286. package/packages/contracts/dist/rpc.js.map +1 -1
  287. package/packages/contracts/dist/workflow.d.ts +4 -0
  288. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  289. package/packages/contracts/dist/workflow.js.map +1 -1
  290. package/packages/contracts/package.json +1 -1
  291. package/packages/daemon/package.json +4 -4
  292. package/packages/gsd-agent-core/package.json +5 -5
  293. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
  294. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  295. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
  296. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  297. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  298. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
  299. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  300. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  301. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  302. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  303. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  304. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  305. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  306. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  307. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  308. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  309. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  310. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  311. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  312. package/packages/gsd-agent-modes/package.json +7 -7
  313. package/packages/mcp-server/dist/cli.js +9 -1
  314. package/packages/mcp-server/dist/cli.js.map +1 -1
  315. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
  316. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
  317. package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
  318. package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
  319. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  320. package/packages/mcp-server/dist/server.js +4 -0
  321. package/packages/mcp-server/dist/server.js.map +1 -1
  322. package/packages/mcp-server/dist/workflow-tools.d.ts +26 -18
  323. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  324. package/packages/mcp-server/dist/workflow-tools.js +145 -59
  325. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  326. package/packages/mcp-server/package.json +5 -4
  327. package/packages/native/package.json +1 -1
  328. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  329. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  330. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  331. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  332. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  333. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  334. package/packages/pi-agent-core/dist/index.js +3 -0
  335. package/packages/pi-agent-core/dist/index.js.map +1 -1
  336. package/packages/pi-agent-core/package.json +1 -1
  337. package/packages/pi-ai/README.md +1 -0
  338. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  339. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  340. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  341. package/packages/pi-ai/dist/index.d.ts +2 -0
  342. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  343. package/packages/pi-ai/dist/index.js +2 -0
  344. package/packages/pi-ai/dist/index.js.map +1 -1
  345. package/packages/pi-ai/dist/models.generated.d.ts +158 -17
  346. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  347. package/packages/pi-ai/dist/models.generated.js +132 -17
  348. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  349. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  350. package/packages/pi-ai/dist/providers/anthropic.js +12 -7
  351. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  352. package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
  353. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  354. package/packages/pi-ai/dist/providers/google-shared.js +12 -3
  355. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  356. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  357. package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
  358. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  359. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
  360. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
  361. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
  362. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
  363. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  364. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
  365. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  366. package/packages/pi-ai/package.json +3 -2
  367. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  368. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  370. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/core/capability-patches.d.ts.map +1 -1
  372. package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
  373. package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
  374. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  375. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  376. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  377. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  378. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  379. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  380. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  381. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  382. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  383. package/packages/pi-coding-agent/dist/index.js +1 -1
  384. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  385. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  386. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  387. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  388. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  389. package/packages/pi-coding-agent/package.json +7 -7
  390. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  391. package/packages/pi-tui/dist/tui.js +9 -0
  392. package/packages/pi-tui/dist/tui.js.map +1 -1
  393. package/packages/pi-tui/package.json +2 -2
  394. package/packages/rpc-client/package.json +2 -2
  395. package/pkg/package.json +1 -1
  396. package/src/resources/GSD-WORKFLOW.md +5 -4
  397. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  398. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  399. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  400. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  401. package/src/resources/extensions/async-jobs/index.ts +79 -0
  402. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  403. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  404. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  405. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  406. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  407. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  408. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  409. package/src/resources/extensions/bg-shell/utilities.ts +5 -2
  410. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
  411. package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
  412. package/src/resources/extensions/browser-tools/index.ts +71 -13
  413. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
  414. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
  415. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
  416. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  417. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +40 -4
  418. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +28 -0
  419. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
  420. package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
  421. package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
  422. package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
  423. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -1
  424. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  425. package/src/resources/extensions/gsd/auto/orchestrator.ts +137 -61
  426. package/src/resources/extensions/gsd/auto/phases.ts +74 -26
  427. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  428. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
  429. package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
  430. package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
  431. package/src/resources/extensions/gsd/auto-post-unit.ts +52 -13
  432. package/src/resources/extensions/gsd/auto-prompts.ts +118 -35
  433. package/src/resources/extensions/gsd/auto-start.ts +24 -29
  434. package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
  435. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  436. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +14 -21
  437. package/src/resources/extensions/gsd/auto-verification.ts +26 -28
  438. package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
  439. package/src/resources/extensions/gsd/auto-worktree.ts +55 -365
  440. package/src/resources/extensions/gsd/auto.ts +64 -25
  441. package/src/resources/extensions/gsd/blocked-models.ts +49 -0
  442. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +37 -10
  443. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +33 -12
  444. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
  445. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
  446. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +270 -37
  447. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +368 -78
  448. package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
  449. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  450. package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
  451. package/src/resources/extensions/gsd/captures.ts +5 -16
  452. package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
  453. package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
  454. package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
  455. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  456. package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
  457. package/src/resources/extensions/gsd/consent-question.ts +431 -0
  458. package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
  459. package/src/resources/extensions/gsd/constants.ts +0 -3
  460. package/src/resources/extensions/gsd/crash-recovery.ts +13 -11
  461. package/src/resources/extensions/gsd/db/engine.ts +809 -0
  462. package/src/resources/extensions/gsd/db/queries.ts +490 -0
  463. package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
  464. package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
  465. package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
  466. package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
  467. package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
  468. package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
  469. package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
  470. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  471. package/src/resources/extensions/gsd/doctor-environment.ts +5 -13
  472. package/src/resources/extensions/gsd/doctor-format.ts +12 -7
  473. package/src/resources/extensions/gsd/doctor-git-checks.ts +5 -22
  474. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +22 -17
  475. package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
  476. package/src/resources/extensions/gsd/error-classifier.ts +11 -0
  477. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  478. package/src/resources/extensions/gsd/files.ts +33 -12
  479. package/src/resources/extensions/gsd/git-service.ts +1 -0
  480. package/src/resources/extensions/gsd/gitignore.ts +3 -0
  481. package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
  482. package/src/resources/extensions/gsd/gsd-db.ts +176 -2375
  483. package/src/resources/extensions/gsd/guidance.ts +217 -0
  484. package/src/resources/extensions/gsd/guided-flow.ts +71 -31
  485. package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
  486. package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
  487. package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
  488. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
  489. package/src/resources/extensions/gsd/migrate/safety.ts +18 -7
  490. package/src/resources/extensions/gsd/migration-auto-check.ts +28 -3
  491. package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
  492. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
  493. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  494. package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
  495. package/src/resources/extensions/gsd/model-router.ts +3 -0
  496. package/src/resources/extensions/gsd/notification-store.ts +26 -3
  497. package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
  498. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -7
  499. package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
  500. package/src/resources/extensions/gsd/paths.ts +42 -22
  501. package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
  502. package/src/resources/extensions/gsd/preferences-models.ts +12 -47
  503. package/src/resources/extensions/gsd/preferences.ts +18 -0
  504. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  505. package/src/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  506. package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
  507. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  508. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -2
  509. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  510. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  511. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  512. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  513. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  514. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  515. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  516. package/src/resources/extensions/gsd/prompts/run-uat.md +7 -5
  517. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  518. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  519. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  520. package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
  521. package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
  522. package/src/resources/extensions/gsd/publication.ts +122 -0
  523. package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
  524. package/src/resources/extensions/gsd/recovery-classification.ts +47 -88
  525. package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
  526. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  527. package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
  528. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
  529. package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
  530. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  531. package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
  532. package/src/resources/extensions/gsd/state.ts +9 -21
  533. package/src/resources/extensions/gsd/status-guards.ts +59 -8
  534. package/src/resources/extensions/gsd/stop-notice.ts +75 -0
  535. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +123 -0
  536. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
  537. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +198 -26
  538. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +3 -1
  539. package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
  540. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  541. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
  542. package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
  543. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
  544. package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
  545. package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
  546. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  547. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
  548. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +44 -0
  549. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
  550. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  551. package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
  552. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
  553. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
  554. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  555. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  556. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
  557. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
  558. package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
  559. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  560. package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
  561. package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +157 -0
  562. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  563. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  564. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
  565. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
  566. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
  567. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
  568. package/src/resources/extensions/gsd/tests/guidance.test.ts +148 -0
  569. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +2 -6
  570. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +58 -15
  571. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +74 -59
  572. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
  573. package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
  574. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
  575. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  576. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +85 -1
  577. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
  578. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  579. package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
  580. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  581. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
  582. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +138 -0
  583. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  584. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  585. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
  586. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
  587. package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
  588. package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
  589. package/src/resources/extensions/gsd/tests/recovery-classification-illegal-transition.test.ts +30 -0
  590. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +248 -1
  591. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  592. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -1
  593. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
  594. package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
  595. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +43 -6
  596. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
  597. package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
  598. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
  599. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  600. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
  601. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
  602. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +155 -0
  603. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  604. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  605. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
  606. package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
  607. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
  608. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
  609. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  610. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  611. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
  612. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  613. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
  614. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  615. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +275 -40
  616. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
  617. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +22 -1
  618. package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
  619. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
  620. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +3 -1
  621. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
  622. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +24 -2
  623. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  624. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
  625. package/src/resources/extensions/gsd/tests/write-gate.test.ts +109 -1
  626. package/src/resources/extensions/gsd/tool-contract.ts +38 -3
  627. package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
  628. package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
  629. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  630. package/src/resources/extensions/gsd/tools/complete-slice.ts +45 -70
  631. package/src/resources/extensions/gsd/tools/complete-task.ts +3 -2
  632. package/src/resources/extensions/gsd/tools/exec-tool.ts +9 -8
  633. package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -8
  634. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  635. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
  636. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +13 -40
  637. package/src/resources/extensions/gsd/tools/reopen-slice.ts +16 -44
  638. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  639. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  640. package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
  641. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
  642. package/src/resources/extensions/gsd/uat-policy.ts +62 -16
  643. package/src/resources/extensions/gsd/undo.ts +9 -8
  644. package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
  645. package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
  646. package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
  647. package/src/resources/extensions/gsd/unit-registry.ts +412 -0
  648. package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
  649. package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
  650. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  651. package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
  652. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  653. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  654. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  655. package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
  656. package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
  657. package/src/resources/extensions/gsd/worktree-git-recovery.ts +314 -0
  658. package/src/resources/extensions/gsd/worktree-lifecycle.ts +13 -9
  659. package/src/resources/extensions/gsd/worktree-manager.ts +53 -29
  660. package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
  661. package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
  662. package/src/resources/extensions/gsd/worktree-root.ts +29 -6
  663. package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
  664. package/src/resources/extensions/gsd/worktree-session-state.ts +11 -11
  665. package/src/resources/extensions/gsd/worktree.ts +7 -1
  666. package/src/resources/extensions/search-the-web/native-search.ts +5 -3
  667. package/src/resources/extensions/shared/browser-contract.ts +66 -0
  668. package/src/resources/extensions/shared/gsd-browser-cli.ts +141 -6
  669. package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
  670. package/src/resources/shared/package-manager-detection.ts +1 -1
  671. package/src/resources/shared/package.json +3 -0
  672. package/src/resources/skills/create-skill/SKILL.md +3 -0
  673. package/src/resources/skills/create-skill/references/executable-code.md +1 -1
  674. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  675. package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
  676. package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
  677. package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
  678. package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  679. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  680. package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  681. package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
  682. package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
  683. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  684. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
  685. package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
  686. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  687. /package/dist/web/standalone/.next/static/{DUFWcMFRH3iXh7d2fbrOF → yWwBo-w09Y_W-nmeeWFRp}/_buildManifest.js +0 -0
  688. /package/dist/web/standalone/.next/static/{DUFWcMFRH3iXh7d2fbrOF → yWwBo-w09Y_W-nmeeWFRp}/_ssgManifest.js +0 -0
@@ -2,7 +2,7 @@
2
2
  import { importExtensionModule, type ExtensionAPI, type ExtensionContext } from "@gsd/pi-coding-agent";
3
3
 
4
4
  import { closeManagedGsdBrowser, registerManagedGsdBrowserTools, warmUpManagedGsdBrowser } from "./engine/managed-gsd-browser.js";
5
- import { resolveBrowserEngineMode, type BrowserEngineMode } from "./engine/selection.js";
5
+ import { commitBrowserEngineResolution, resolveAmbientBrowserEngineResolution, type BrowserEngineMode } from "./engine/selection.js";
6
6
  import { setArtifactRootForCwd } from "./state.js";
7
7
  import { detectWebApp } from "./web-app-detect.js";
8
8
 
@@ -167,13 +167,59 @@ function withBrowserArtifactCwdScope(pi: ExtensionAPI): ExtensionAPI {
167
167
  };
168
168
  }
169
169
 
170
- async function registerBrowserTools(pi: ExtensionAPI): Promise<void> {
171
- const engine = resolveBrowserEngineMode();
170
+ /** Daemon-connect budget when the probe-resolved managed engine is verified at session start. */
171
+ const PROBE_WARMUP_TIMEOUT_MS = 10_000;
172
+
173
+ async function registerBrowserTools(pi: ExtensionAPI, ctx: ExtensionContext): Promise<void> {
174
+ const projectRoot = ctx.cwd || process.cwd();
175
+ const resolution = resolveAmbientBrowserEngineResolution(projectRoot);
176
+ let engine = resolution.engine;
172
177
  if (engine === "off") return;
178
+
179
+ // A probe-resolved managed engine is only a prediction that gsd-browser
180
+ // works — prove it by connecting the daemon before committing the session's
181
+ // tool registrations to it. Connect failure falls back to legacy Playwright
182
+ // (the failure mode that made ADR-024 freeze the old default) and commits
183
+ // the outcome so ambient readers see the engine actually in use. When eager
184
+ // warm-up is disabled the daemon-connect proof cannot run, so the probe
185
+ // default treats the managed engine as unprovable and falls back to legacy
186
+ // rather than registering it unverified. An explicit
187
+ // GSD_BROWSER_ENGINE=gsd-browser override skips the gate and is honored
188
+ // verbatim, matching prior behavior.
189
+ if (engine === "gsd-browser" && resolution.source === "probe" && !registeredEngine) {
190
+ if (isWarmUpDisabled()) {
191
+ engine = commitLegacyFallback(projectRoot, "warm-up disabled; managed engine unverifiable; using legacy Playwright");
192
+ } else {
193
+ const warmUp = await warmUpManagedGsdBrowser(ctx, AbortSignal.timeout(PROBE_WARMUP_TIMEOUT_MS));
194
+ if (!warmUp.ok) {
195
+ engine = commitLegacyFallback(projectRoot, `gsd-browser daemon connect failed (${warmUp.error}); using legacy Playwright`);
196
+ if (ctx.hasUI) {
197
+ ctx.ui.notify(
198
+ `gsd-browser engine unavailable (${warmUp.error}); using Playwright browser tools for this session.`,
199
+ "warning",
200
+ );
201
+ }
202
+ } else if (warmUp.coverageWarning && ctx.hasUI) {
203
+ ctx.ui.notify(warmUp.coverageWarning, "warning");
204
+ }
205
+ }
206
+ }
207
+
208
+ // Browser tool registrations are process-global and cannot be swapped once
209
+ // live. When an earlier session in this process already registered an engine
210
+ // and this project resolved a different one (per-project probe resolution can
211
+ // diverge across projects in a multi-session process), adopt the registered
212
+ // engine rather than throwing — a throw surfaces as "browser-tools failed to
213
+ // load" and leaves this session with no browser tools at all. Commit the
214
+ // adoption so ambient readers (UAT guidance, warm-up) describe the engine
215
+ // actually in use.
173
216
  if (registeredEngine && registeredEngine !== engine) {
174
- throw new Error(
175
- `Browser tools already registered with GSD_BROWSER_ENGINE=${registeredEngine}. Restart GSD before switching to ${engine}.`,
176
- );
217
+ engine = registeredEngine;
218
+ commitBrowserEngineResolution(projectRoot, {
219
+ engine,
220
+ source: "probe",
221
+ reason: `browser tools already registered with ${engine} earlier in this process; adopting it`,
222
+ });
177
223
  }
178
224
 
179
225
  let registration: Promise<void>;
@@ -202,29 +248,41 @@ async function registerBrowserTools(pi: ExtensionAPI): Promise<void> {
202
248
  }
203
249
  }
204
250
 
251
+ function commitLegacyFallback(projectRoot: string, reason: string): "legacy" {
252
+ commitBrowserEngineResolution(projectRoot, { engine: "legacy", source: "probe", reason });
253
+ return "legacy";
254
+ }
255
+
205
256
  function isWarmUpDisabled(): boolean {
206
257
  const value = process.env.GSD_BROWSER_WARMUP?.trim().toLowerCase();
207
258
  return value === "0" || value === "false" || value === "off";
208
259
  }
209
260
 
210
261
  /**
211
- * Auto-initialize the managed gsd-browser engine only when explicitly selected
212
- * for a web app. Best-effort and non-blocking: warm-up runs in the background
213
- * and only surfaces a warning if it fails.
262
+ * Auto-initialize the managed gsd-browser engine when it was selected via the
263
+ * explicit GSD_BROWSER_ENGINE override, which registers without the
264
+ * daemon-connect gate. Best-effort and non-blocking: warm-up runs in the
265
+ * background and only surfaces a warning if it fails. Probe-resolved sessions
266
+ * already connected (or fell back) during registration, so they are excluded
267
+ * to avoid re-warming and double-notifying.
214
268
  */
215
269
  function maybeWarmUpManagedEngine(pi: ExtensionAPI, ctx: ExtensionContext): void {
216
270
  if (isWarmUpDisabled()) return;
217
- if (resolveBrowserEngineMode() !== "gsd-browser") return;
218
271
 
219
272
  const projectRoot = ctx.cwd || process.cwd();
273
+ const resolution = resolveAmbientBrowserEngineResolution(projectRoot);
274
+ if (resolution.engine !== "gsd-browser" || resolution.source !== "env") return;
220
275
  if (!detectWebApp(projectRoot)) return;
221
276
 
222
277
  void warmUpManagedGsdBrowser(ctx).then((result) => {
223
- if (!result.ok && ctx.hasUI) {
278
+ if (!ctx.hasUI) return;
279
+ if (!result.ok) {
224
280
  ctx.ui.notify(
225
281
  `gsd-browser auto-init failed: ${result.error}. Browser UAT tools will retry on first use; run /gsd doctor if this persists.`,
226
282
  "warning",
227
283
  );
284
+ } else if (result.coverageWarning) {
285
+ ctx.ui.notify(result.coverageWarning, "warning");
228
286
  }
229
287
  });
230
288
  }
@@ -240,7 +298,7 @@ async function closeActiveBrowserEngines(): Promise<void> {
240
298
  export default function (pi: ExtensionAPI) {
241
299
  pi.on("session_start", async (_event, ctx) => {
242
300
  if (ctx.hasUI) {
243
- void registerBrowserTools(pi)
301
+ void registerBrowserTools(pi, ctx)
244
302
  .then(() => maybeWarmUpManagedEngine(pi, ctx))
245
303
  .catch((error) => {
246
304
  ctx.ui.notify(`browser-tools failed to load: ${error instanceof Error ? error.message : String(error)}`, "warning");
@@ -248,7 +306,7 @@ export default function (pi: ExtensionAPI) {
248
306
  return;
249
307
  }
250
308
 
251
- await registerBrowserTools(pi);
309
+ await registerBrowserTools(pi, ctx);
252
310
  maybeWarmUpManagedEngine(pi, ctx);
253
311
  });
254
312
 
@@ -1,35 +1,105 @@
1
1
  import { describe, it } from "node:test";
2
2
  import assert from "node:assert/strict";
3
+ import { mkdtempSync, writeFileSync } from "node:fs";
3
4
  import { createRequire } from "node:module";
4
- import { dirname } from "node:path";
5
+ import { tmpdir } from "node:os";
6
+ import { dirname, join } from "node:path";
5
7
  import { fileURLToPath } from "node:url";
6
8
 
7
9
  const __dirname = dirname(fileURLToPath(import.meta.url));
8
10
  const require = createRequire(import.meta.url);
9
11
  const jiti = require("jiti")(__dirname, { interopDefault: true, debug: false });
10
12
 
11
- const { resolveBrowserEngineMode } = jiti("../engine/selection.ts");
13
+ const {
14
+ commitBrowserEngineResolution,
15
+ resolveAmbientBrowserEngineResolution,
16
+ resolveBrowserEngineResolution,
17
+ } = jiti("../engine/selection.ts");
12
18
 
13
- describe("resolveBrowserEngineMode", () => {
14
- it("defaults to the Playwright engine", () => {
15
- assert.equal(resolveBrowserEngineMode({}), "legacy");
16
- });
19
+ function makeProject({ webApp }) {
20
+ const dir = mkdtempSync(join(tmpdir(), "gsd-engine-selection-"));
21
+ const pkg = webApp ? { dependencies: { react: "^18.0.0" } } : { name: "cli-tool" };
22
+ writeFileSync(join(dir, "package.json"), JSON.stringify(pkg));
23
+ return dir;
24
+ }
25
+
26
+ function makeFakeCli() {
27
+ const dir = mkdtempSync(join(tmpdir(), "gsd-fake-cli-"));
28
+ const cliPath = join(dir, "gsd-browser");
29
+ writeFileSync(cliPath, "#!/bin/sh\n");
30
+ return cliPath;
31
+ }
17
32
 
18
- it("accepts the explicit engine modes", () => {
19
- assert.equal(resolveBrowserEngineMode({ GSD_BROWSER_ENGINE: "gsd-browser" }), "gsd-browser");
20
- assert.equal(resolveBrowserEngineMode({ GSD_BROWSER_ENGINE: "legacy" }), "legacy");
21
- assert.equal(resolveBrowserEngineMode({ GSD_BROWSER_ENGINE: "off" }), "off");
33
+ describe("resolveBrowserEngineResolution", () => {
34
+ it("honors the explicit engine modes verbatim with env source", () => {
35
+ assert.deepEqual(
36
+ ["gsd-browser", "legacy", "off"].map(
37
+ (mode) => resolveBrowserEngineResolution({ GSD_BROWSER_ENGINE: mode }).engine,
38
+ ),
39
+ ["gsd-browser", "legacy", "off"],
40
+ );
41
+ assert.equal(resolveBrowserEngineResolution({ GSD_BROWSER_ENGINE: "gsd-browser" }).source, "env");
22
42
  });
23
43
 
24
44
  it("accepts compatibility aliases", () => {
25
- assert.equal(resolveBrowserEngineMode({ GSD_BROWSER_ENGINE: "playwright" }), "legacy");
26
- assert.equal(resolveBrowserEngineMode({ GSD_BROWSER_ENGINE: "false" }), "off");
45
+ assert.equal(resolveBrowserEngineResolution({ GSD_BROWSER_ENGINE: "playwright" }).engine, "legacy");
46
+ assert.equal(resolveBrowserEngineResolution({ GSD_BROWSER_ENGINE: "false" }).engine, "off");
27
47
  });
28
48
 
29
49
  it("rejects unknown engine modes", () => {
30
50
  assert.throws(
31
- () => resolveBrowserEngineMode({ GSD_BROWSER_ENGINE: "surprise" }),
51
+ () => resolveBrowserEngineResolution({ GSD_BROWSER_ENGINE: "surprise" }),
32
52
  /Expected "gsd-browser", "legacy", or "off"/,
33
53
  );
34
54
  });
55
+
56
+ it("defaults to legacy Playwright when no project root is known", () => {
57
+ const resolution = resolveBrowserEngineResolution({});
58
+ assert.equal(resolution.engine, "legacy");
59
+ assert.equal(resolution.source, "probe");
60
+ });
61
+
62
+ it("keeps legacy Playwright for non-browser-facing projects", () => {
63
+ const cliPath = makeFakeCli();
64
+ const resolution = resolveBrowserEngineResolution(
65
+ { GSD_BROWSER_CLI_PATH: cliPath },
66
+ makeProject({ webApp: false }),
67
+ );
68
+ assert.equal(resolution.engine, "legacy");
69
+ assert.match(resolution.reason, /not browser-facing/);
70
+ });
71
+
72
+ it("prefers the managed gsd-browser engine for web apps when the CLI is provable", () => {
73
+ const cliPath = makeFakeCli();
74
+ const resolution = resolveBrowserEngineResolution(
75
+ { GSD_BROWSER_CLI_PATH: cliPath },
76
+ makeProject({ webApp: true }),
77
+ );
78
+ assert.equal(resolution.engine, "gsd-browser");
79
+ assert.equal(resolution.source, "probe");
80
+ assert.match(resolution.reason, /web app detected/);
81
+ });
82
+
83
+ it("falls back to legacy Playwright with a recorded reason when the CLI is unavailable", () => {
84
+ const resolution = resolveBrowserEngineResolution(
85
+ { GSD_BROWSER_CLI_PATH: "/nonexistent/gsd-browser" },
86
+ makeProject({ webApp: true }),
87
+ );
88
+ assert.equal(resolution.engine, "legacy");
89
+ assert.equal(resolution.source, "probe");
90
+ assert.match(resolution.reason, /falling back to legacy Playwright/);
91
+ });
92
+ });
93
+
94
+ describe("committed resolution", () => {
95
+ it("ambient readers see a committed verification outcome instead of the prediction", () => {
96
+ const projectRoot = makeProject({ webApp: true });
97
+ const fallback = {
98
+ engine: "legacy",
99
+ source: "probe",
100
+ reason: "gsd-browser daemon connect failed (test); using legacy Playwright",
101
+ };
102
+ commitBrowserEngineResolution(projectRoot, fallback);
103
+ assert.deepEqual(resolveAmbientBrowserEngineResolution(projectRoot), fallback);
104
+ });
35
105
  });
@@ -1,7 +1,10 @@
1
1
  import { describe, it } from "node:test";
2
2
  import assert from "node:assert/strict";
3
3
 
4
- const { resolveGsdBrowserMcpLaunchConfig } = await import("../../shared/gsd-browser-cli.ts");
4
+ const {
5
+ resolveGsdBrowserDaemonStartInvocation,
6
+ resolveGsdBrowserMcpLaunchConfig,
7
+ } = await import("../../shared/gsd-browser-cli.ts");
5
8
 
6
9
  describe("resolveGsdBrowserMcpLaunchConfig identity flags", () => {
7
10
  it("emits a non-empty --identity-key alongside --identity-scope", () => {
@@ -34,4 +37,40 @@ describe("resolveGsdBrowserMcpLaunchConfig identity flags", () => {
34
37
  });
35
38
  assert.equal(args[args.indexOf("--identity-key") + 1], "custom-key");
36
39
  });
40
+
41
+ it("splits GSD_BROWSER_MCP_COMMAND command lines before spawning", () => {
42
+ const commandLine = '"C:\\Program Files\\nodejs\\node.exe" "C:\\Users\\Test User\\AppData\\Roaming\\npm\\node_modules\\@opengsd\\gsd-browser\\bin\\gsd-browser"';
43
+ const { command, args } = resolveGsdBrowserMcpLaunchConfig("C:\\Users\\Test User\\project", {
44
+ GSD_BROWSER_MCP_COMMAND: commandLine,
45
+ });
46
+
47
+ assert.equal(command, "C:\\Program Files\\nodejs\\node.exe");
48
+ assert.equal(args[0], "C:\\Users\\Test User\\AppData\\Roaming\\npm\\node_modules\\@opengsd\\gsd-browser\\bin\\gsd-browser");
49
+ assert.equal(args[1], "mcp");
50
+ });
51
+
52
+ it("uses a path-safe identity-project identifier", () => {
53
+ const { args } = resolveGsdBrowserMcpLaunchConfig("/tmp/example/project", {});
54
+ const projectId = args[args.indexOf("--identity-project") + 1];
55
+ assert.equal(typeof projectId, "string");
56
+ assert.doesNotMatch(projectId, /[\\/]/);
57
+ });
58
+ });
59
+
60
+ describe("resolveGsdBrowserDaemonStartInvocation", () => {
61
+ it("mirrors MCP session and identity flags with daemon start", () => {
62
+ const launch = resolveGsdBrowserMcpLaunchConfig("/tmp/example-project", {});
63
+ const daemon = resolveGsdBrowserDaemonStartInvocation("/tmp/example-project", {});
64
+
65
+ assert.equal(daemon.command, launch.command);
66
+ assert.equal(daemon.cwd, launch.cwd);
67
+ assert.deepEqual(
68
+ daemon.args.slice(daemon.args.indexOf("--session")),
69
+ launch.args.slice(launch.args.indexOf("--session")),
70
+ );
71
+ assert.deepEqual(
72
+ daemon.args.slice(0, daemon.args.indexOf("--session")),
73
+ [...launch.args.slice(0, launch.args.indexOf("mcp")), "daemon", "start"],
74
+ );
75
+ });
37
76
  });
@@ -2,10 +2,33 @@ import { describe, it } from "node:test";
2
2
  import assert from "node:assert/strict";
3
3
 
4
4
  const {
5
+ MANAGED_BROWSER_TOOL_SPECS,
5
6
  MANAGED_GSD_BROWSER_TOOL_NAMES,
7
+ findMissingContractCoverage,
8
+ normalizeManagedArgs,
6
9
  registerManagedGsdBrowserTools,
7
10
  } = await import("../engine/managed-gsd-browser.ts");
8
11
 
12
+ // The tools @opengsd/gsd-browser actually serves over MCP (subset relevant to
13
+ // the contract). Notably absent: browser_click, browser_type, browser_verify,
14
+ // browser_reload — those are satisfied through translations.
15
+ const GSD_BROWSER_SERVED_TOOLS = [
16
+ "browser_navigate",
17
+ "browser_snapshot",
18
+ "browser_click_ref",
19
+ "browser_fill_ref",
20
+ "browser_fill_form",
21
+ "browser_wait_for",
22
+ "browser_assert",
23
+ "browser_screenshot",
24
+ "browser_find_element",
25
+ "browser_console",
26
+ "browser_network",
27
+ "browser_evaluate",
28
+ "browser_batch",
29
+ "browser_act",
30
+ ];
31
+
9
32
  describe("registerManagedGsdBrowserTools", () => {
10
33
  it("registers the curated Pi browser contract", () => {
11
34
  const tools = [];
@@ -31,3 +54,116 @@ describe("registerManagedGsdBrowserTools", () => {
31
54
  assert.equal(screenshot?.compatibility?.producesImages, true);
32
55
  });
33
56
  });
57
+
58
+ describe("findMissingContractCoverage", () => {
59
+ it("reports nothing for the tool list gsd-browser actually serves", () => {
60
+ assert.deepEqual(findMissingContractCoverage(GSD_BROWSER_SERVED_TOOLS), []);
61
+ });
62
+
63
+ it("reports contract tools none of whose MCP candidates are served", () => {
64
+ const served = GSD_BROWSER_SERVED_TOOLS.filter((name) => name !== "browser_assert");
65
+ // browser_verify also depends on browser_assert through its translation.
66
+ assert.deepEqual(findMissingContractCoverage(served), ["browser_assert", "browser_verify"]);
67
+ });
68
+
69
+ it("reports translated tools when a required MCP tool is missing", () => {
70
+ const served = GSD_BROWSER_SERVED_TOOLS.filter((name) => name !== "browser_batch");
71
+ assert.deepEqual(findMissingContractCoverage(served), ["browser_click", "browser_type", "browser_batch"]);
72
+ });
73
+ });
74
+
75
+ describe("contract tool translations", () => {
76
+ it("translates browser_click into a single-step batch call", () => {
77
+ const calls = MANAGED_BROWSER_TOOL_SPECS.browser_click.translate.build({ selector: "#save" });
78
+ assert.deepEqual(calls, [{
79
+ mcpTool: "browser_batch",
80
+ args: { steps: [{ action: "click", selector: "#save" }] },
81
+ }]);
82
+ });
83
+
84
+ it("translates browser_type into a single-step batch call", () => {
85
+ const calls = MANAGED_BROWSER_TOOL_SPECS.browser_type.translate.build({
86
+ selector: "#name",
87
+ text: "hello",
88
+ clearFirst: true,
89
+ submit: true,
90
+ });
91
+ assert.deepEqual(calls, [{
92
+ mcpTool: "browser_batch",
93
+ args: { steps: [{ action: "type", selector: "#name", text: "hello", clearFirst: true, submit: true }] },
94
+ }]);
95
+ });
96
+
97
+ it("normalizes batch options and step keys to the daemon's snake_case", () => {
98
+ const normalized = normalizeManagedArgs("browser_batch", {
99
+ steps: [{ action: "type", selector: "#name", text: "hi", clearFirst: true }],
100
+ stopOnFailure: false,
101
+ finalSummaryOnly: true,
102
+ });
103
+ assert.deepEqual(normalized, {
104
+ steps: [{ action: "type", selector: "#name", text: "hi", clear_first: true }],
105
+ stop_on_failure: false,
106
+ summary_only: true,
107
+ });
108
+ });
109
+
110
+ it("translates browser_verify into navigate, assert, and screenshot calls", () => {
111
+ const calls = MANAGED_BROWSER_TOOL_SPECS.browser_verify.translate.build({
112
+ url: "http://localhost:3000",
113
+ timeout: 5000,
114
+ checks: [
115
+ { description: "heading shows", selector: "h1", expectedText: "Welcome" },
116
+ { description: "spinner gone", selector: ".spinner", expectedVisible: false },
117
+ { description: "evidence", selector: "main", expectedVisible: true, screenshot: true },
118
+ ],
119
+ });
120
+ assert.deepEqual(calls, [
121
+ { mcpTool: "browser_navigate", args: { url: "http://localhost:3000", timeout: 5000 } },
122
+ {
123
+ mcpTool: "browser_assert",
124
+ args: {
125
+ checks: [
126
+ { kind: "text_visible", text: "Welcome" },
127
+ { kind: "selector_hidden", selector: ".spinner" },
128
+ { kind: "selector_visible", selector: "main" },
129
+ ],
130
+ },
131
+ },
132
+ { mcpTool: "browser_screenshot", args: {}, optional: true },
133
+ ]);
134
+ });
135
+
136
+ it("declares every tool a translation can emit in its coverage requirements", () => {
137
+ for (const [name, spec] of Object.entries(MANAGED_BROWSER_TOOL_SPECS)) {
138
+ if (!spec.translate) continue;
139
+ const maximalArgs = {
140
+ url: "http://localhost:3000",
141
+ timeout: 5000,
142
+ selector: "#el",
143
+ text: "hi",
144
+ clearFirst: true,
145
+ checks: [{ description: "d", selector: "#el", expectedText: "hi", expectedVisible: true, screenshot: true }],
146
+ };
147
+ const emitted = spec.translate.build(maximalArgs).map((call) => call.mcpTool);
148
+ for (const mcpTool of emitted) {
149
+ assert.ok(
150
+ spec.translate.requires.includes(mcpTool),
151
+ `${name} translation emits ${mcpTool} but does not require it for coverage`,
152
+ );
153
+ }
154
+ }
155
+ });
156
+
157
+ it("translates browser_verify without checks into navigation only", () => {
158
+ const calls = MANAGED_BROWSER_TOOL_SPECS.browser_verify.translate.build({ url: "http://localhost:3000", checks: [] });
159
+ assert.deepEqual(calls, [{ mcpTool: "browser_navigate", args: { url: "http://localhost:3000" } }]);
160
+ });
161
+
162
+ it("translates browser_reload into evaluate plus best-effort network-idle wait", () => {
163
+ const calls = MANAGED_BROWSER_TOOL_SPECS.browser_reload.translate.build({});
164
+ assert.deepEqual(calls, [
165
+ { mcpTool: "browser_evaluate", args: { expression: "location.reload()" } },
166
+ { mcpTool: "browser_wait_for", args: { condition: "network_idle", timeout: 3_000 }, optional: true },
167
+ ]);
168
+ });
169
+ });
@@ -39,6 +39,15 @@ export const CLAUDE_CODE_MODELS = [
39
39
  contextWindow: 1_000_000,
40
40
  maxTokens: 128_000,
41
41
  },
42
+ {
43
+ id: "claude-fable-5",
44
+ name: "Claude Fable 5 (via Claude Code)",
45
+ reasoning: true,
46
+ input: ["text", "image"] as ("text" | "image")[],
47
+ cost: ZERO_COST,
48
+ contextWindow: 1_000_000,
49
+ maxTokens: 128_000,
50
+ },
42
51
  {
43
52
  id: "claude-sonnet-4-6",
44
53
  name: "Claude Sonnet 4.6 (via Claude Code)",
@@ -59,6 +59,8 @@ import {
59
59
  computeMcpDisallowedTools,
60
60
  } from "../gsd/mcp-filter.js";
61
61
  import { RUN_UAT_CLAUDE_NATIVE_TOOL_NAMES, RUN_UAT_FORBIDDEN_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES, resolveToolPresentationPlan } from "../gsd/tool-presentation-plan.js";
62
+ import { getToolSurfaceReadinessError } from "../gsd/tool-surface-readiness.js";
63
+ import { hasBrowserContractPrefix } from "../shared/browser-contract.js";
62
64
  import { showInterviewRound, type Question, type RoundResult } from "../shared/tui.js";
63
65
  import type {
64
66
  SDKAssistantMessage,
@@ -1542,6 +1544,8 @@ function modelSupportsAdaptiveThinking(modelId: string): boolean {
1542
1544
  || modelId.includes("opus-4.7")
1543
1545
  || modelId.includes("opus-4-8")
1544
1546
  || modelId.includes("opus-4.8")
1547
+ || modelId.includes("fable-5")
1548
+ || modelId.includes("fable.5")
1545
1549
  || modelId.includes("sonnet-4-6")
1546
1550
  || modelId.includes("sonnet-4.6")
1547
1551
  || modelId.includes("sonnet-4-7")
@@ -1567,6 +1571,8 @@ function mapThinkingLevelToAnthropicEffort(level: ThinkingLevel | undefined, mod
1567
1571
  || modelId.includes("opus-4.7")
1568
1572
  || modelId.includes("opus-4-8")
1569
1573
  || modelId.includes("opus-4.8")
1574
+ || modelId.includes("fable-5")
1575
+ || modelId.includes("fable.5")
1570
1576
  ) return "xhigh";
1571
1577
  if (modelId.includes("opus-4-6") || modelId.includes("opus-4.6")) return "max";
1572
1578
  return "high";
@@ -1586,7 +1592,7 @@ function browserMcpServerNameFromAllowedTools(allowedTools: unknown): string | u
1586
1592
  if (typeof toolName !== "string") continue;
1587
1593
  const parsed = parseAllowedMcpToolName(toolName);
1588
1594
  if (!parsed) continue;
1589
- if (parsed.server === "gsd-browser" || parsed.tool.startsWith("browser_")) {
1595
+ if (parsed.server === "gsd-browser" || hasBrowserContractPrefix(parsed.tool)) {
1590
1596
  return parsed.server;
1591
1597
  }
1592
1598
  }
@@ -1599,7 +1605,7 @@ function workflowMcpServerNameFromAllowedTools(allowedTools: unknown): string |
1599
1605
  for (const toolName of allowedTools) {
1600
1606
  if (typeof toolName !== "string") continue;
1601
1607
  const parsed = parseAllowedMcpToolName(toolName);
1602
- if (!parsed || parsed.server === browserServerName || parsed.tool.startsWith("browser_")) continue;
1608
+ if (!parsed || parsed.server === browserServerName || hasBrowserContractPrefix(parsed.tool)) continue;
1603
1609
  return parsed.server;
1604
1610
  }
1605
1611
  return undefined;
@@ -1899,6 +1905,8 @@ export function buildSdkOptions(
1899
1905
  || modelId.includes("opus-4.7")
1900
1906
  || modelId.includes("opus-4-8")
1901
1907
  || modelId.includes("opus-4.8")
1908
+ || modelId.includes("fable-5")
1909
+ || modelId.includes("fable.5")
1902
1910
  ) ? ["context-1m-2025-08-07"] : [],
1903
1911
  ...(thinkingConfig ?? {}),
1904
1912
  ...(effort ? { effort } : {}),
@@ -1992,8 +2000,9 @@ async function pumpSdkMessages(
1992
2000
  : {}),
1993
2001
  },
1994
2002
  );
2003
+ const workflowMcpServerName = workflowMcpServerNameFromAllowedTools(sdkOpts.allowedTools);
1995
2004
  const prompt = buildPromptFromContext(context, {
1996
- workflowMcpServerName: workflowMcpServerNameFromAllowedTools(sdkOpts.allowedTools),
2005
+ workflowMcpServerName,
1997
2006
  browserMcpServerName: browserMcpServerNameFromAllowedTools(sdkOpts.allowedTools),
1998
2007
  });
1999
2008
  const queryPrompt = buildSdkQueryPrompt(context, prompt);
@@ -2035,7 +2044,34 @@ async function pumpSdkMessages(
2035
2044
  switch (msg.type) {
2036
2045
  // -- Init --
2037
2046
  case "system": {
2038
- // Nothing to emit the stream is already started.
2047
+ // Tool Surface Readiness gate: the init message is the first (and
2048
+ // only) point where the session reports its live tool surface and
2049
+ // MCP server statuses. If the workflow server failed or has not
2050
+ // registered this Unit's required tools, abort before the first
2051
+ // model turn with a transient, recovery-classifiable error
2052
+ // (tool-unavailable → retry) instead of letting the model hit
2053
+ // "No such tool available" mid-Unit and improvise around it.
2054
+ const init = msg as unknown as {
2055
+ subtype?: string;
2056
+ tools?: string[];
2057
+ mcp_servers?: { name: string; status: string }[];
2058
+ };
2059
+ if (init.subtype === "init") {
2060
+ const readinessError = getToolSurfaceReadinessError({
2061
+ unitType: gsdPhase,
2062
+ workflowServerName: workflowMcpServerName,
2063
+ observation: { tools: init.tools ?? [], mcpServers: init.mcp_servers ?? [] },
2064
+ });
2065
+ if (readinessError) {
2066
+ controller.abort();
2067
+ stream.push({
2068
+ type: "error",
2069
+ reason: "error",
2070
+ error: makeErrorMessage(modelId, readinessError),
2071
+ });
2072
+ return;
2073
+ }
2074
+ }
2039
2075
  break;
2040
2076
  }
2041
2077
 
@@ -36,6 +36,7 @@ import {
36
36
  autoInitClaudeCodeWorkflowMcp,
37
37
  inferGsdPhaseFromContext,
38
38
  } from "../stream-adapter.ts";
39
+ import { CLAUDE_CODE_MODELS } from "../models.ts";
39
40
  import type { AssistantMessage, Context, Message } from "@gsd/pi-ai";
40
41
  import type { SDKUserMessage } from "../sdk-types.ts";
41
42
  import { _setAutoActiveForTest } from "../../gsd/auto.ts";
@@ -793,6 +794,33 @@ describe("stream-adapter — Claude Code external tool results", () => {
793
794
  });
794
795
  });
795
796
 
797
+ describe("claude-code-cli — Claude Fable 5 Opus-tier support", () => {
798
+ test("Fable 5 is exposed in the Claude Code model picker list", () => {
799
+ const fable = CLAUDE_CODE_MODELS.find((m) => m.id === "claude-fable-5");
800
+ assert.ok(fable, "claude-fable-5 must appear in CLAUDE_CODE_MODELS");
801
+ assert.equal(fable!.reasoning, true);
802
+ assert.equal(fable!.contextWindow, 1_000_000);
803
+ assert.equal(fable!.maxTokens, 128_000);
804
+ });
805
+
806
+ test("Fable 5 gets Opus-tier gates: xhigh effort, adaptive thinking, 1M-context beta", () => {
807
+ const options = buildSdkOptions("claude-fable-5", "test prompt", undefined, { reasoning: "xhigh" });
808
+ assert.equal(options.effort, "xhigh", "xhigh must pass through natively for Fable 5");
809
+ assert.deepEqual(options.thinking, { type: "adaptive" }, "Fable 5 must use adaptive thinking");
810
+ assert.ok(
811
+ Array.isArray(options.betas) && (options.betas as string[]).includes("context-1m-2025-08-07"),
812
+ "Fable 5 must enable the 1M-context beta",
813
+ );
814
+ });
815
+
816
+ test("non-Opus models do not receive Fable 5's Opus-tier gates", () => {
817
+ // Failure/contrast path: Haiku supports adaptive thinking but is not xhigh/1M-tier.
818
+ const options = buildSdkOptions("claude-haiku-4-5", "test prompt", undefined, { reasoning: "xhigh" });
819
+ assert.equal(options.effort, "high", "xhigh must clamp to high for non-Opus-tier models");
820
+ assert.deepEqual(options.betas, [], "Haiku must not enable the 1M-context beta");
821
+ });
822
+ });
823
+
796
824
  describe("stream-adapter — session persistence (#2859)", () => {
797
825
  test("buildSdkOptions enables persistSession by default", () => {
798
826
  const options = buildSdkOptions("claude-sonnet-4-20250514", "test prompt");