@opengsd/gsd-pi 1.2.0-dev.5457a158 → 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 (489) hide show
  1. package/dist/headless-events.js +7 -5
  2. package/dist/mcp-server.js +2 -1
  3. package/dist/resource-loader.d.ts +9 -5
  4. package/dist/resource-loader.js +114 -6
  5. package/dist/resources/.managed-resources-content-hash +1 -1
  6. package/dist/resources/GSD-WORKFLOW.md +5 -4
  7. package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
  8. package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
  9. package/dist/resources/extensions/async-jobs/index.js +65 -0
  10. package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
  11. package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
  12. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
  13. package/dist/resources/extensions/bg-shell/overlay.js +9 -6
  14. package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
  15. package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
  16. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
  17. package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
  18. package/dist/resources/extensions/browser-tools/index.js +69 -12
  19. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +3 -2
  20. package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
  21. package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
  22. package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
  23. package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
  24. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  25. package/dist/resources/extensions/gsd/auto/orchestrator.js +89 -54
  26. package/dist/resources/extensions/gsd/auto/phases.js +49 -6
  27. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  28. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
  29. package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
  30. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
  31. package/dist/resources/extensions/gsd/auto-post-unit.js +30 -12
  32. package/dist/resources/extensions/gsd/auto-prompts.js +78 -19
  33. package/dist/resources/extensions/gsd/auto-start.js +12 -12
  34. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  35. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +5 -4
  36. package/dist/resources/extensions/gsd/auto-verification.js +23 -30
  37. package/dist/resources/extensions/gsd/auto-worktree.js +14 -1
  38. package/dist/resources/extensions/gsd/auto.js +37 -1
  39. package/dist/resources/extensions/gsd/blocked-models.js +28 -0
  40. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +26 -6
  41. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +23 -6
  42. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
  43. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
  44. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +172 -59
  45. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +302 -80
  46. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  47. package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
  48. package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
  49. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  50. package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
  51. package/dist/resources/extensions/gsd/consent-question.js +353 -0
  52. package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
  53. package/dist/resources/extensions/gsd/constants.js +0 -2
  54. package/dist/resources/extensions/gsd/crash-recovery.js +8 -3
  55. package/dist/resources/extensions/gsd/db/queries.js +26 -0
  56. package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
  57. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  58. package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
  59. package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
  60. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  61. package/dist/resources/extensions/gsd/files.js +33 -19
  62. package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
  63. package/dist/resources/extensions/gsd/gsd-db.js +2 -1
  64. package/dist/resources/extensions/gsd/guidance.js +60 -0
  65. package/dist/resources/extensions/gsd/guided-flow.js +6 -3
  66. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
  67. package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
  68. package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
  69. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
  70. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  71. package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
  72. package/dist/resources/extensions/gsd/preferences-models.js +2 -2
  73. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  74. package/dist/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  75. package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
  76. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  77. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  78. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  79. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  80. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  81. package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  82. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  83. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  84. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  85. package/dist/resources/extensions/gsd/prompts/run-uat.md +7 -5
  86. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  87. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  88. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  89. package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
  90. package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
  91. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  92. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  93. package/dist/resources/extensions/gsd/state.js +5 -0
  94. package/dist/resources/extensions/gsd/tool-contract.js +14 -3
  95. package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
  96. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  97. package/dist/resources/extensions/gsd/tools/complete-slice.js +22 -12
  98. package/dist/resources/extensions/gsd/tools/complete-task.js +3 -2
  99. package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -0
  100. package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -2
  101. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  102. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
  103. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  104. package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
  105. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  106. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  107. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
  108. package/dist/resources/extensions/gsd/uat-policy.js +42 -16
  109. package/dist/resources/extensions/gsd/unit-context-composer.js +65 -0
  110. package/dist/resources/extensions/gsd/unit-registry.js +7 -20
  111. package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
  112. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  113. package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
  114. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  115. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  116. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  117. package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
  118. package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
  119. package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
  120. package/dist/resources/extensions/gsd/worktree.js +8 -1
  121. package/dist/resources/extensions/search-the-web/native-search.js +5 -3
  122. package/dist/resources/extensions/shared/browser-contract.js +59 -0
  123. package/dist/resources/extensions/shared/gsd-browser-cli.js +116 -6
  124. package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
  125. package/dist/resources/shared/package-manager-detection.js +1 -1
  126. package/dist/resources/shared/package.json +3 -0
  127. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  128. package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
  129. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  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/spike-wrap-up/SKILL.md +9 -9
  137. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  138. package/dist/update-check.d.ts +2 -0
  139. package/dist/update-check.js +24 -1
  140. package/dist/update-cmd.js +20 -3
  141. package/dist/web/standalone/.next/BUILD_ID +1 -1
  142. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  143. package/dist/web/standalone/.next/build-manifest.json +3 -3
  144. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  145. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  146. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  147. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  151. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  152. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  153. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  154. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  155. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  156. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  157. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  158. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  159. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  160. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  161. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  162. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  164. package/dist/web/standalone/.next/server/app/index.html +1 -1
  165. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  166. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  167. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  169. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  170. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  171. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  172. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  173. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  176. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  177. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  178. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  179. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  180. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  181. package/dist/web/standalone/package.json +1 -1
  182. package/package.json +1 -1
  183. package/packages/cloud-mcp-gateway/package.json +2 -2
  184. package/packages/contracts/dist/rpc.d.ts +1 -0
  185. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  186. package/packages/contracts/dist/rpc.js.map +1 -1
  187. package/packages/contracts/package.json +1 -1
  188. package/packages/daemon/package.json +4 -4
  189. package/packages/gsd-agent-core/package.json +5 -5
  190. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
  191. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  192. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
  193. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  194. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  195. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
  196. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  197. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  198. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  199. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  200. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  201. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  202. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  203. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  204. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  205. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  206. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  207. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  208. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  209. package/packages/gsd-agent-modes/package.json +7 -7
  210. package/packages/mcp-server/dist/cli.js +10 -5
  211. package/packages/mcp-server/dist/cli.js.map +1 -1
  212. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
  213. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
  214. package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
  215. package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
  216. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  217. package/packages/mcp-server/dist/server.js +4 -0
  218. package/packages/mcp-server/dist/server.js.map +1 -1
  219. package/packages/mcp-server/dist/workflow-tools.d.ts +18 -18
  220. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  221. package/packages/mcp-server/dist/workflow-tools.js +99 -38
  222. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  223. package/packages/mcp-server/package.json +5 -4
  224. package/packages/native/package.json +1 -1
  225. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  226. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  227. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  228. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  229. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  230. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  231. package/packages/pi-agent-core/dist/index.js +3 -0
  232. package/packages/pi-agent-core/dist/index.js.map +1 -1
  233. package/packages/pi-agent-core/package.json +1 -1
  234. package/packages/pi-ai/README.md +1 -0
  235. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  236. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  237. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  238. package/packages/pi-ai/dist/index.d.ts +2 -0
  239. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  240. package/packages/pi-ai/dist/index.js +2 -0
  241. package/packages/pi-ai/dist/index.js.map +1 -1
  242. package/packages/pi-ai/dist/models.generated.d.ts +239 -153
  243. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  244. package/packages/pi-ai/dist/models.generated.js +256 -145
  245. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  246. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  247. package/packages/pi-ai/dist/providers/anthropic.js +12 -7
  248. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  249. package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
  250. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  251. package/packages/pi-ai/dist/providers/google-shared.js +12 -3
  252. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  253. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  254. package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
  255. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  256. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
  257. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
  258. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
  259. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
  260. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  261. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
  262. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  263. package/packages/pi-ai/package.json +3 -2
  264. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  265. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  267. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  270. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  271. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  272. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  274. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  276. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/index.js +1 -1
  278. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  280. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  282. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  283. package/packages/pi-coding-agent/package.json +7 -7
  284. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  285. package/packages/pi-tui/dist/tui.js +9 -0
  286. package/packages/pi-tui/dist/tui.js.map +1 -1
  287. package/packages/pi-tui/package.json +2 -2
  288. package/packages/rpc-client/package.json +2 -2
  289. package/pkg/package.json +1 -1
  290. package/src/resources/GSD-WORKFLOW.md +5 -4
  291. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  292. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  293. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  294. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  295. package/src/resources/extensions/async-jobs/index.ts +79 -0
  296. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  297. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  298. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  299. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  300. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  301. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  302. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  303. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
  304. package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
  305. package/src/resources/extensions/browser-tools/index.ts +71 -13
  306. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
  307. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
  308. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
  309. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +3 -2
  310. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
  311. package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
  312. package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
  313. package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
  314. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  315. package/src/resources/extensions/gsd/auto/orchestrator.ts +98 -56
  316. package/src/resources/extensions/gsd/auto/phases.ts +65 -26
  317. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  318. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
  319. package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
  320. package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
  321. package/src/resources/extensions/gsd/auto-post-unit.ts +33 -12
  322. package/src/resources/extensions/gsd/auto-prompts.ts +115 -35
  323. package/src/resources/extensions/gsd/auto-start.ts +12 -14
  324. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  325. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +4 -4
  326. package/src/resources/extensions/gsd/auto-verification.ts +26 -28
  327. package/src/resources/extensions/gsd/auto-worktree.ts +14 -1
  328. package/src/resources/extensions/gsd/auto.ts +44 -1
  329. package/src/resources/extensions/gsd/blocked-models.ts +49 -0
  330. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -5
  331. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +23 -6
  332. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
  333. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
  334. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +211 -59
  335. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +350 -86
  336. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  337. package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
  338. package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
  339. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  340. package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
  341. package/src/resources/extensions/gsd/consent-question.ts +431 -0
  342. package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
  343. package/src/resources/extensions/gsd/constants.ts +0 -3
  344. package/src/resources/extensions/gsd/crash-recovery.ts +10 -2
  345. package/src/resources/extensions/gsd/db/queries.ts +37 -0
  346. package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
  347. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  348. package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
  349. package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
  350. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  351. package/src/resources/extensions/gsd/files.ts +33 -12
  352. package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
  353. package/src/resources/extensions/gsd/gsd-db.ts +4 -3
  354. package/src/resources/extensions/gsd/guidance.ts +78 -0
  355. package/src/resources/extensions/gsd/guided-flow.ts +21 -26
  356. package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
  357. package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
  358. package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
  359. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
  360. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  361. package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
  362. package/src/resources/extensions/gsd/preferences-models.ts +2 -1
  363. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  364. package/src/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  365. package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
  366. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  367. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  368. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  369. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  370. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  371. package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  372. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  373. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  374. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  375. package/src/resources/extensions/gsd/prompts/run-uat.md +7 -5
  376. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  377. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  378. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  379. package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
  380. package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
  381. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  382. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  383. package/src/resources/extensions/gsd/state.ts +5 -0
  384. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
  385. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +198 -26
  386. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  387. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
  388. package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
  389. package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
  390. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  391. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  392. package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
  393. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
  394. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
  395. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  396. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  397. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
  398. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
  399. package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
  400. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  401. package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
  402. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  403. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  404. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
  405. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
  406. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
  407. package/src/resources/extensions/gsd/tests/guidance.test.ts +23 -0
  408. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +2 -6
  409. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +7 -11
  410. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +20 -58
  411. package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
  412. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
  413. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  414. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
  415. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  416. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  417. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
  418. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +138 -0
  419. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  420. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  421. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
  422. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  423. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +19 -1
  424. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  425. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
  426. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  427. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  428. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
  429. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +44 -0
  430. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  431. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  432. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
  433. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  434. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  435. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +273 -38
  436. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
  437. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  438. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
  439. package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
  440. package/src/resources/extensions/gsd/tool-contract.ts +38 -3
  441. package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
  442. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  443. package/src/resources/extensions/gsd/tools/complete-slice.ts +22 -12
  444. package/src/resources/extensions/gsd/tools/complete-task.ts +3 -2
  445. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -0
  446. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -2
  447. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  448. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
  449. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  450. package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
  451. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  452. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  453. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
  454. package/src/resources/extensions/gsd/uat-policy.ts +62 -16
  455. package/src/resources/extensions/gsd/unit-context-composer.ts +99 -0
  456. package/src/resources/extensions/gsd/unit-registry.ts +7 -20
  457. package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
  458. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  459. package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
  460. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  461. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  462. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  463. package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
  464. package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
  465. package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
  466. package/src/resources/extensions/gsd/worktree.ts +7 -1
  467. package/src/resources/extensions/search-the-web/native-search.ts +5 -3
  468. package/src/resources/extensions/shared/browser-contract.ts +66 -0
  469. package/src/resources/extensions/shared/gsd-browser-cli.ts +141 -6
  470. package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
  471. package/src/resources/shared/package-manager-detection.ts +1 -1
  472. package/src/resources/shared/package.json +3 -0
  473. package/src/resources/skills/create-skill/SKILL.md +3 -0
  474. package/src/resources/skills/create-skill/references/executable-code.md +1 -1
  475. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  476. package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
  477. package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
  478. package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
  479. package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  480. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  481. package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  482. package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
  483. package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
  484. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  485. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
  486. package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
  487. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  488. /package/dist/web/standalone/.next/static/{2p9Rv9pQflAxCBbGVI2vb → yWwBo-w09Y_W-nmeeWFRp}/_buildManifest.js +0 -0
  489. /package/dist/web/standalone/.next/static/{2p9Rv9pQflAxCBbGVI2vb → yWwBo-w09Y_W-nmeeWFRp}/_ssgManifest.js +0 -0
@@ -22,6 +22,7 @@
22
22
  // (`UNIT_MANIFESTS` stays in unit-context-manifest.ts, already type-enforced
23
23
  // against the registry's `UnitType`) and prompt-template association (still
24
24
  // implicit in auto-prompts.ts builders).
25
+ import { BROWSER_CONTRACT_TOOL_NAMES } from "../shared/browser-contract.js";
25
26
  // ─── Shared tool-name constants (used by registry rows) ──────────────────
26
27
  export const RUN_UAT_WORKFLOW_TOOL_NAMES = [
27
28
  "gsd_uat_exec",
@@ -37,26 +38,12 @@ export const RUN_UAT_READ_ONLY_TOOL_NAMES = [
37
38
  "ls",
38
39
  "read",
39
40
  ];
40
- export const RUN_UAT_BROWSER_TOOL_NAMES = [
41
- "browser_navigate",
42
- "browser_click",
43
- "browser_type",
44
- "browser_fill_form",
45
- "browser_click_ref",
46
- "browser_fill_ref",
47
- "browser_wait_for",
48
- "browser_assert",
49
- "browser_verify",
50
- "browser_screenshot",
51
- "browser_snapshot_refs",
52
- "browser_find",
53
- "browser_get_console_logs",
54
- "browser_get_network_logs",
55
- "browser_evaluate",
56
- "browser_reload",
57
- "browser_batch",
58
- "browser_act",
59
- ];
41
+ /**
42
+ * Browser tools presented to run-uat. A derived view of the Browser Automation
43
+ * Contract vocabulary (shared/browser-contract.ts) — the contract module is the
44
+ * only place browser tool names are declared.
45
+ */
46
+ export const RUN_UAT_BROWSER_TOOL_NAMES = BROWSER_CONTRACT_TOOL_NAMES;
60
47
  // ─── The registry ─────────────────────────────────────────────────────────
61
48
  export const UNIT_REGISTRY = {
62
49
  "research-milestone": {
@@ -128,7 +128,7 @@ export function isValidMilestoneVerdict(verdict) {
128
128
  * Extract the UAT type from content, defaulting to `"artifact-driven"`.
129
129
  *
130
130
  * The `"artifact-driven"` fallback is the original default used throughout
131
- * the codebase when a UAT file lacks an explicit `## UAT Type` section.
131
+ * the codebase when a UAT file has no parseable UAT mode declaration.
132
132
  */
133
133
  export function getUatType(content) {
134
134
  return getDeclaredUatType(content);
@@ -1,5 +1,6 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: Host-owned verification verdict policy for auto-mode units.
3
+ export const NO_HOST_CHECKS_FAILURE_CONTEXT = "No runnable host-owned verification command was discovered. Add project verification_commands in .gsd/PREFERENCES.md or a runnable task-plan Verify command, then resume with /gsd next.";
3
4
  export function decideVerificationVerdict(unitType, result) {
4
5
  if (unitType === "execute-task" && result.discoverySource === "task-plan-prose" && result.checks.length === 0) {
5
6
  return {
@@ -14,7 +15,7 @@ export function decideVerificationVerdict(unitType, result) {
14
15
  passed: false,
15
16
  reason: "no-host-checks",
16
17
  retryable: false,
17
- failureContext: "No runnable host-owned verification command was discovered. Add project verification_commands or a runnable task-plan Verify command before completing this execute-task.",
18
+ failureContext: NO_HOST_CHECKS_FAILURE_CONTEXT,
18
19
  };
19
20
  }
20
21
  if (!result.passed) {
@@ -1,8 +1,10 @@
1
1
  // Project/App: gsd-pi
2
- // File Purpose: Web-app detection and Playwright/UAT guidance for planning and slice closeout.
2
+ // File Purpose: Web-app detection and browser-UAT guidance for planning and slice closeout.
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  import { resolve } from "node:path";
5
+ import { resolveAmbientBrowserEngineResolution } from "../browser-tools/engine/selection.js";
5
6
  import { detectWebApp } from "../browser-tools/web-app-detect.js";
7
+ import { UAT_MODE_POLICIES } from "./uat-policy.js";
6
8
  export { detectWebApp };
7
9
  function readPackageJson(projectRoot) {
8
10
  const packageJsonPath = resolve(projectRoot, "package.json");
@@ -39,24 +41,56 @@ export function findPlaywrightTestScript(projectRoot) {
39
41
  }
40
42
  return null;
41
43
  }
44
+ function describeBrowserToolBacking(engineResolution) {
45
+ switch (engineResolution.engine) {
46
+ case "gsd-browser":
47
+ return "This project looks browser-facing. GSD exposes `browser_*` tools backed by the managed gsd-browser engine for run-uat.";
48
+ case "legacy":
49
+ return "This project looks browser-facing. GSD exposes Playwright-backed `browser_*` tools for run-uat.";
50
+ case "off":
51
+ return "This project looks browser-facing, but Pi browser tools are disabled (GSD_BROWSER_ENGINE=off) — prefer `runtime-executable` UAT with automated browser test commands.";
52
+ }
53
+ }
54
+ // One bullet per recommended UAT mode; `mode` keys into UAT_MODE_POLICIES so
55
+ // modes that require browser tools drop out of the guidance when the resolved
56
+ // engine provides none (mixed/live-runtime share one bullet and one policy bit).
57
+ const UAT_MODE_GUIDANCE = [
58
+ {
59
+ mode: "browser-executable",
60
+ bullet: "- `browser-executable` — navigate to `http://localhost:…`, click, screenshot, assert via `browser_*` tools during run-uat",
61
+ },
62
+ {
63
+ mode: "runtime-executable",
64
+ bullet: "- `runtime-executable` — run an automated browser test command via `gsd_uat_exec` (for example `npx playwright test`)",
65
+ },
66
+ {
67
+ mode: "mixed",
68
+ bullet: "- `mixed` / `live-runtime` — combine runtime startup checks with interactive browser verification",
69
+ },
70
+ ];
42
71
  /**
43
72
  * Markdown block injected into plan/complete-slice prompts when the project
44
- * looks browser-facing. Returns null for CLI/library-only repos.
73
+ * looks browser-facing. Returns null for CLI/library-only repos. Guidance is
74
+ * composed from the resolved Browser Automation Engine so prompts never claim
75
+ * an engine the runtime is not using; `engineResolution` is injectable for
76
+ * tests and defaults to the ambient resolution.
45
77
  */
46
- export function buildWebAppUatGuidanceBlock(projectRoot) {
78
+ export function buildWebAppUatGuidanceBlock(projectRoot, engineResolution) {
47
79
  if (!detectWebApp(projectRoot))
48
80
  return null;
81
+ const resolvedEngine = engineResolution ?? resolveAmbientBrowserEngineResolution(projectRoot);
82
+ const browserToolsAvailable = resolvedEngine.engine !== "off";
49
83
  const playwrightScript = findPlaywrightTestScript(projectRoot);
50
84
  const hasPlaywright = hasPlaywrightTestDependency(projectRoot) || playwrightScript !== null;
51
85
  const lines = [
52
86
  "### Web App UAT (detected)",
53
87
  "",
54
- "This project looks browser-facing. GSD exposes Playwright-backed `browser_*` tools by default for run-uat.",
88
+ describeBrowserToolBacking(resolvedEngine),
55
89
  "",
56
90
  "**UAT modes (pick one per slice — do not use `artifact-driven` for browser steps):**",
57
- "- `browser-executable` — navigate to `http://localhost:…`, click, screenshot, assert via `browser_*` tools during run-uat",
58
- "- `runtime-executable` run an automated browser test command via `gsd_uat_exec` (for example `npx playwright test`)",
59
- "- `mixed` / `live-runtime` — combine runtime startup checks with interactive browser verification",
91
+ ...UAT_MODE_GUIDANCE
92
+ .filter(({ mode }) => browserToolsAvailable || !UAT_MODE_POLICIES[mode].browserTools)
93
+ .map(({ bullet }) => bullet),
60
94
  "",
61
95
  "**Planning / closeout rules:**",
62
96
  "- Preconditions must name the dev-server command and URL (for example `npm run dev` → `http://localhost:3000`)",
@@ -74,7 +108,10 @@ export function buildWebAppUatGuidanceBlock(projectRoot) {
74
108
  lines.push("- Name concrete spec paths in slice Verification (for example `e2e/smoke.spec.ts`)");
75
109
  }
76
110
  else {
77
- lines.push("", "**Playwright scaffolding (first UI slice):** no `playwright` / `@playwright/test` dependency yet.", "- Add a planning task that installs Playwright, adds `playwright.config.ts`, and creates a minimal smoke spec (for example `e2e/smoke.spec.ts`)", "- Task `verify` should run `npx playwright test` (or the focused spec) with a safe, simple command", "- Until specs exist, use `browser-executable` UAT with localhost preconditions and interactive `browser_*` checks at slice closeout");
111
+ lines.push("", "**Playwright scaffolding (first UI slice):** no `playwright` / `@playwright/test` dependency yet.", "- Add a planning task that installs Playwright, adds `playwright.config.ts`, and creates a minimal smoke spec (for example `e2e/smoke.spec.ts`)", "- Task `verify` should run `npx playwright test` (or the focused spec) with a safe, simple command");
112
+ if (browserToolsAvailable) {
113
+ lines.push("- Until specs exist, use `browser-executable` UAT with localhost preconditions and interactive `browser_*` checks at slice closeout");
114
+ }
78
115
  }
79
116
  return lines.join("\n");
80
117
  }
@@ -0,0 +1,91 @@
1
+ import { createHash } from "node:crypto";
2
+ import { appendFileSync, mkdirSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { atomicWriteSync } from "./atomic-write.js";
5
+ import { resolveGsdPathContract } from "./paths.js";
6
+ import { buildAuditEnvelope, emitUokAuditEvent } from "./uok/audit.js";
7
+ import { isUnifiedAuditEnabled } from "./uok/audit-toggle.js";
8
+ import { normalizeWorkflowEventCommand } from "./workflow-event-vocabulary.js";
9
+ export const WORKFLOW_EVENT_LOG_FILENAME = "event-log.jsonl";
10
+ export function resolveWorkflowEventLedgerLocation(basePath, originalProjectRoot) {
11
+ const contract = resolveGsdPathContract(basePath, originalProjectRoot);
12
+ return {
13
+ projectRoot: contract.projectRoot,
14
+ workRoot: contract.workRoot,
15
+ projectGsd: contract.projectGsd,
16
+ worktreeGsd: contract.worktreeGsd,
17
+ projectLogPath: join(contract.projectGsd, WORKFLOW_EVENT_LOG_FILENAME),
18
+ worktreeLogPath: contract.worktreeGsd
19
+ ? join(contract.worktreeGsd, WORKFLOW_EVENT_LOG_FILENAME)
20
+ : null,
21
+ isWorktree: contract.isWorktree,
22
+ };
23
+ }
24
+ export function workflowEventLogPath(basePath) {
25
+ return resolveWorkflowEventLedgerLocation(basePath).projectLogPath;
26
+ }
27
+ export function workflowEventArchivePath(basePath, milestoneId) {
28
+ const location = resolveWorkflowEventLedgerLocation(basePath);
29
+ return join(location.projectGsd, `event-log-${milestoneId}.jsonl.archived`);
30
+ }
31
+ export function readWorktreeEventLogPath(worktreeBasePath) {
32
+ const location = resolveWorkflowEventLedgerLocation(worktreeBasePath);
33
+ return location.worktreeLogPath ?? location.projectLogPath;
34
+ }
35
+ export function buildWorkflowEvent(event, sessionId) {
36
+ const hash = createHash("sha256")
37
+ .update(JSON.stringify({ cmd: event.cmd, params: event.params }))
38
+ .digest("hex")
39
+ .slice(0, 16);
40
+ return {
41
+ v: 2,
42
+ ...event,
43
+ hash,
44
+ session_id: sessionId,
45
+ };
46
+ }
47
+ export function appendWorkflowEvent(basePath, event, sessionId) {
48
+ const fullEvent = buildWorkflowEvent(event, sessionId);
49
+ const location = resolveWorkflowEventLedgerLocation(basePath);
50
+ mkdirSync(location.projectGsd, { recursive: true });
51
+ appendFileSync(location.projectLogPath, `${JSON.stringify(fullEvent)}\n`, "utf-8");
52
+ emitWorkflowEventAudit(location.projectRoot, fullEvent);
53
+ return fullEvent;
54
+ }
55
+ export function writeWorkflowEventLog(basePath, events) {
56
+ const location = resolveWorkflowEventLedgerLocation(basePath);
57
+ mkdirSync(location.projectGsd, { recursive: true });
58
+ const content = events.map((event) => JSON.stringify(event)).join("\n") + (events.length > 0 ? "\n" : "");
59
+ atomicWriteSync(location.projectLogPath, content);
60
+ }
61
+ export function writeWorktreeEventLog(worktreeBasePath, events) {
62
+ const location = resolveWorkflowEventLedgerLocation(worktreeBasePath);
63
+ const logPath = location.worktreeLogPath ?? location.projectLogPath;
64
+ mkdirSync(dirname(logPath), { recursive: true });
65
+ const content = events.map((event) => JSON.stringify(event)).join("\n") + (events.length > 0 ? "\n" : "");
66
+ atomicWriteSync(logPath, content);
67
+ }
68
+ function emitWorkflowEventAudit(basePath, event) {
69
+ if (!isUnifiedAuditEnabled())
70
+ return;
71
+ try {
72
+ const normalized = normalizeWorkflowEventCommand(event.cmd) ?? "unknown";
73
+ emitUokAuditEvent(basePath, buildAuditEnvelope({
74
+ traceId: event.session_id,
75
+ category: "orchestration",
76
+ type: `workflow-event-${normalized}`,
77
+ payload: {
78
+ cmd: event.cmd,
79
+ params: event.params,
80
+ actor: event.actor,
81
+ actorName: event.actor_name,
82
+ triggerReason: event.trigger_reason,
83
+ eventTs: event.ts,
84
+ hash: event.hash,
85
+ },
86
+ }));
87
+ }
88
+ catch {
89
+ // Best-effort: audit projection must never block the workflow event ledger.
90
+ }
91
+ }
@@ -0,0 +1,46 @@
1
+ export function normalizeWorkflowEventCommand(cmd) {
2
+ return typeof cmd === "string" ? cmd.replace(/-/g, "_") : null;
3
+ }
4
+ /**
5
+ * Workflow progress events are keyed by the domain entity they mutate.
6
+ * Keep command aliases and conflict identity in this module so replay,
7
+ * conflict detection, and tests do not each grow their own vocabulary.
8
+ */
9
+ export function workflowEventEntityKey(event) {
10
+ const p = event.params;
11
+ const cmd = normalizeWorkflowEventCommand(event.cmd);
12
+ if (!cmd)
13
+ return null;
14
+ switch (cmd) {
15
+ case "complete_task":
16
+ case "start_task":
17
+ case "skip_task":
18
+ case "report_blocker":
19
+ case "record_verification":
20
+ case "plan_task":
21
+ return typeof p["taskId"] === "string"
22
+ ? { type: "task", id: p["taskId"] }
23
+ : null;
24
+ case "complete_slice":
25
+ case "replan_slice":
26
+ return typeof p["sliceId"] === "string"
27
+ ? { type: "slice", id: p["sliceId"] }
28
+ : null;
29
+ case "plan_slice":
30
+ return typeof p["sliceId"] === "string"
31
+ ? { type: "slice_plan", id: p["sliceId"] }
32
+ : null;
33
+ case "complete_milestone":
34
+ case "plan_milestone":
35
+ return typeof p["milestoneId"] === "string"
36
+ ? { type: "milestone", id: p["milestoneId"] }
37
+ : null;
38
+ case "save_decision":
39
+ if (typeof p["scope"] === "string" && typeof p["decision"] === "string") {
40
+ return { type: "decision", id: `${p["scope"]}:${p["decision"]}` };
41
+ }
42
+ return null;
43
+ default:
44
+ return null;
45
+ }
46
+ }
@@ -1,8 +1,8 @@
1
- import { createHash, randomUUID } from "node:crypto";
2
- import { appendFileSync, readFileSync, existsSync, mkdirSync } from "node:fs";
3
- import { join } from "node:path";
1
+ import { randomUUID } from "node:crypto";
2
+ import { readFileSync, existsSync } from "node:fs";
4
3
  import { atomicWriteSync } from "./atomic-write.js";
5
4
  import { withFileLockSync } from "./file-lock.js";
5
+ import { appendWorkflowEvent, workflowEventArchivePath, workflowEventLogPath, } from "./workflow-event-ledger.js";
6
6
  import { logWarning } from "./workflow-logger.js";
7
7
  // ─── Session ID ───────────────────────────────────────────────────────────
8
8
  /**
@@ -20,19 +20,7 @@ export function getSessionId() {
20
20
  * Creates .gsd directory if needed.
21
21
  */
22
22
  export function appendEvent(basePath, event) {
23
- const hash = createHash("sha256")
24
- .update(JSON.stringify({ cmd: event.cmd, params: event.params }))
25
- .digest("hex")
26
- .slice(0, 16);
27
- const fullEvent = {
28
- v: 2,
29
- ...event,
30
- hash,
31
- session_id: ENGINE_SESSION_ID,
32
- };
33
- const dir = join(basePath, ".gsd");
34
- mkdirSync(dir, { recursive: true });
35
- appendFileSync(join(dir, "event-log.jsonl"), JSON.stringify(fullEvent) + "\n", "utf-8");
23
+ appendWorkflowEvent(basePath, event, ENGINE_SESSION_ID);
36
24
  }
37
25
  // ─── readEvents ──────────────────────────────────────────────────────────
38
26
  /**
@@ -87,8 +75,8 @@ export function findForkPoint(logA, logB) {
87
75
  * @returns { archived: number } — count of events moved to archive
88
76
  */
89
77
  export function compactMilestoneEvents(basePath, milestoneId) {
90
- const logPath = join(basePath, ".gsd", "event-log.jsonl");
91
- const archivePath = join(basePath, ".gsd", `event-log-${milestoneId}.jsonl.archived`);
78
+ const logPath = workflowEventLogPath(basePath);
79
+ const archivePath = workflowEventArchivePath(basePath, milestoneId);
92
80
  return withFileLockSync(logPath, () => {
93
81
  const allEvents = readEvents(logPath);
94
82
  // Single-pass partition to halve the work (per reviewer agent)
@@ -2,6 +2,8 @@ import { join } from "node:path";
2
2
  import { mkdirSync, existsSync, readFileSync, unlinkSync } from "node:fs";
3
3
  import { logWarning, logError } from "./workflow-logger.js";
4
4
  import { readEvents, findForkPoint, getSessionId } from "./workflow-events.js";
5
+ import { normalizeWorkflowEventCommand, workflowEventEntityKey, } from "./workflow-event-vocabulary.js";
6
+ import { readWorktreeEventLogPath, workflowEventLogPath, writeWorkflowEventLog, writeWorktreeEventLog, } from "./workflow-event-ledger.js";
5
7
  import { transaction, updateTaskStatus, updateSliceStatus, updateMilestoneStatus, getSliceTasks, insertMilestone, getMilestoneSlices, insertVerificationEvidence, upsertDecision, setTaskBlockerDiscovered, insertOrIgnoreSlice, insertOrIgnoreTask, } from "./gsd-db.js";
6
8
  import { openWorkflowDatabasePath } from "./db-workspace.js";
7
9
  import { isClosedStatus } from "./status-guards.js";
@@ -48,14 +50,11 @@ function replayEvents(events) {
48
50
  transaction(() => {
49
51
  for (const event of events) {
50
52
  const p = event.params;
51
- // Normalize cmd format: completion tools write hyphens ("complete-task"),
52
- // legacy logs use underscores ("complete_task"). Accept both formats.
53
- // Type guard: malformed event lines with non-string cmd are skipped.
54
- if (typeof event.cmd !== "string") {
53
+ const cmd = normalizeWorkflowEventCommand(event.cmd);
54
+ if (!cmd) {
55
55
  logWarning("reconcile", `Event with non-string cmd skipped: ${JSON.stringify(event.cmd)}`);
56
56
  continue;
57
57
  }
58
- const cmd = event.cmd.replace(/-/g, "_");
59
58
  switch (cmd) {
60
59
  case "complete_task": {
61
60
  const milestoneId = p["milestoneId"];
@@ -199,43 +198,7 @@ function replayEvents(events) {
199
198
  * (e.g. unknown or future cmds).
200
199
  */
201
200
  export function extractEntityKey(event) {
202
- const p = event.params;
203
- // Normalize cmd format: accept both hyphens and underscores
204
- if (typeof event.cmd !== "string")
205
- return null;
206
- const cmd = event.cmd.replace(/-/g, "_");
207
- switch (cmd) {
208
- case "complete_task":
209
- case "start_task":
210
- case "skip_task":
211
- case "report_blocker":
212
- case "record_verification":
213
- case "plan_task":
214
- return typeof p["taskId"] === "string"
215
- ? { type: "task", id: p["taskId"] }
216
- : null;
217
- case "complete_slice":
218
- case "replan_slice":
219
- return typeof p["sliceId"] === "string"
220
- ? { type: "slice", id: p["sliceId"] }
221
- : null;
222
- case "plan_slice":
223
- return typeof p["sliceId"] === "string"
224
- ? { type: "slice_plan", id: p["sliceId"] }
225
- : null;
226
- case "complete_milestone":
227
- case "plan_milestone":
228
- return typeof p["milestoneId"] === "string"
229
- ? { type: "milestone", id: p["milestoneId"] }
230
- : null;
231
- case "save_decision":
232
- if (typeof p["scope"] === "string" && typeof p["decision"] === "string") {
233
- return { type: "decision", id: `${p["scope"]}:${p["decision"]}` };
234
- }
235
- return null;
236
- default:
237
- return null;
238
- }
201
+ return workflowEventEntityKey(event);
239
202
  }
240
203
  // ─── detectConflicts ──────────────────────────────────────────────────────────
241
204
  /**
@@ -302,12 +265,6 @@ function rewriteDivergedEventsForEntity(divergedEvents, entityType, entityId, re
302
265
  }
303
266
  return rewritten;
304
267
  }
305
- function writeEventLog(basePath, events) {
306
- const dir = join(basePath, ".gsd");
307
- mkdirSync(dir, { recursive: true });
308
- const content = events.map((e) => JSON.stringify(e)).join("\n") + (events.length > 0 ? "\n" : "");
309
- atomicWriteSync(join(dir, "event-log.jsonl"), content);
310
- }
311
268
  // ─── writeConflictsFile ───────────────────────────────────────────────────────
312
269
  /**
313
270
  * Write a human-readable CONFLICTS.md to basePath/.gsd/CONFLICTS.md.
@@ -375,10 +332,15 @@ export function reconcileWorktreeLogs(mainBasePath, worktreeBasePath) {
375
332
  }
376
333
  function _reconcileWorktreeLogsInner(mainBasePath, worktreeBasePath) {
377
334
  // Step 1: Read both logs
378
- const mainLogPath = join(mainBasePath, ".gsd", "event-log.jsonl");
379
- const wtLogPath = join(worktreeBasePath, ".gsd", "event-log.jsonl");
335
+ const mainLogPath = workflowEventLogPath(mainBasePath);
336
+ const wtLogPath = readWorktreeEventLogPath(worktreeBasePath);
380
337
  const mainEvents = readEvents(mainLogPath);
381
338
  const wtEvents = readEvents(wtLogPath);
339
+ // Canonical worktree appends are already durable in the project ledger.
340
+ // Empty/missing worktree shards are legacy-only absence, not divergence.
341
+ if (wtEvents.length === 0) {
342
+ return { autoMerged: 0, conflicts: [] };
343
+ }
382
344
  // Step 2: Find fork point
383
345
  const forkPoint = findForkPoint(mainEvents, wtEvents);
384
346
  // Step 3: Slice diverged sets
@@ -412,9 +374,7 @@ function _reconcileWorktreeLogsInner(mainBasePath, worktreeBasePath) {
412
374
  }
413
375
  const baseEvents = mainEvents.slice(0, forkPoint + 1);
414
376
  const mergedLog = baseEvents.concat(merged);
415
- const logContent = mergedLog.map((e) => JSON.stringify(e)).join("\n") + (mergedLog.length > 0 ? "\n" : "");
416
- mkdirSync(join(mainBasePath, ".gsd"), { recursive: true });
417
- atomicWriteSync(join(mainBasePath, ".gsd", "event-log.jsonl"), logContent);
377
+ writeWorkflowEventLog(mainBasePath, mergedLog);
418
378
  // Step 8: Replay into DB (wrapped in a transaction by replayEvents)
419
379
  openWorkflowDatabasePath(resolveGsdPathContract(mainBasePath).projectDb);
420
380
  replayEvents(merged);
@@ -533,8 +493,8 @@ pick) {
533
493
  throw new Error(`No conflict found for entity ${entityKey}`);
534
494
  const conflict = conflicts[idx];
535
495
  const eventsToReplay = pick === "main" ? conflict.mainSideEvents : conflict.worktreeSideEvents;
536
- const mainLogPath = join(basePath, ".gsd", "event-log.jsonl");
537
- const wtLogPath = join(worktreeBasePath, ".gsd", "event-log.jsonl");
496
+ const mainLogPath = workflowEventLogPath(basePath);
497
+ const wtLogPath = readWorktreeEventLogPath(worktreeBasePath);
538
498
  const mainEvents = readEvents(mainLogPath);
539
499
  const wtEvents = readEvents(wtLogPath);
540
500
  const forkPoint = findForkPoint(mainEvents, wtEvents);
@@ -547,7 +507,12 @@ pick) {
547
507
  : rewriteDivergedEventsForEntity(mainDiverged, entityType, entityId, eventsToReplay);
548
508
  const targetBasePath = pick === "main" ? worktreeBasePath : basePath;
549
509
  const targetBaseEvents = pick === "main" ? wtBaseEvents : mainBaseEvents;
550
- writeEventLog(targetBasePath, targetBaseEvents.concat(rewrittenTargetEvents));
510
+ if (pick === "main") {
511
+ writeWorktreeEventLog(targetBasePath, targetBaseEvents.concat(rewrittenTargetEvents));
512
+ }
513
+ else {
514
+ writeWorkflowEventLog(targetBasePath, targetBaseEvents.concat(rewrittenTargetEvents));
515
+ }
551
516
  // Replay resolved events through the DB (updates DB state)
552
517
  openWorkflowDatabasePath(resolveGsdPathContract(basePath).projectDb);
553
518
  replayEvents(eventsToReplay);
@@ -32,6 +32,7 @@ import { getCollapseCadence, getMilestoneResquash, resquashMilestoneOnMain, } fr
32
32
  // callers — production wiring previously injected them via deps; the seam
33
33
  // added type churn without enabling test variation.
34
34
  import { loadEffectiveGSDPreferences, getIsolationMode } from "./preferences.js";
35
+ import { isolationDegradedFallbackGuidance, worktreeCreationFailedGuidance } from "./guidance.js";
35
36
  import { invalidateAllCaches } from "./cache.js";
36
37
  import { resolveMilestoneFile } from "./paths.js";
37
38
  import { getMilestone, insertMilestone, isDbAvailable, updateMilestoneStatus } from "./gsd-db.js";
@@ -343,7 +344,7 @@ export function _enterMilestoneCore(s, deps, milestoneId, ctx, opts = {}) {
343
344
  s.basePath = basePath;
344
345
  rebuildGitService(s, deps);
345
346
  invalidateAllCaches();
346
- ctx.notify(`Worktree isolation is degraded. Fell back to branch milestone/${milestoneId}.`, "warning");
347
+ ctx.notify(isolationDegradedFallbackGuidance(milestoneId), "warning");
347
348
  return { ok: true, mode: "branch", path: basePath };
348
349
  }
349
350
  catch (err) {
@@ -517,7 +518,7 @@ export function _enterMilestoneCore(s, deps, milestoneId, ctx, opts = {}) {
517
518
  eventType: "worktree-create-failed",
518
519
  data: { milestoneId, error: msg, fallback: "project-root" },
519
520
  });
520
- ctx.notify(`Auto-worktree creation for ${milestoneId} failed: ${msg}. Continuing in project root.`, "warning");
521
+ ctx.notify(worktreeCreationFailedGuidance(milestoneId, msg), "warning");
521
522
  // Degrade isolation for the rest of this session so mergeAndExit
522
523
  // doesn't try to merge a nonexistent worktree branch (#2483)
523
524
  s.isolationDegraded = true;
@@ -528,7 +528,13 @@ export function removeWorktree(basePath, name, opts = {}) {
528
528
  // inside .gsd/worktrees/ — a symlink inside the directory could point out.
529
529
  const resolvedPathSafe = isInsideWorktreesDir(basePath, resolvedWtPath);
530
530
  // If we're inside the worktree, move out first — git can't remove an in-use directory
531
- const cwd = process.cwd();
531
+ let cwd;
532
+ try {
533
+ cwd = process.cwd();
534
+ }
535
+ catch {
536
+ cwd = basePath;
537
+ }
532
538
  const resolvedCwd = existsSync(cwd) ? realpathSync(cwd) : cwd;
533
539
  if (resolvedCwd === resolvedWtPath || resolvedCwd.startsWith(resolvedWtPath + sep)) {
534
540
  process.chdir(basePath);
@@ -195,7 +195,14 @@ export function resolveGitHeadPath(dir) {
195
195
  */
196
196
  export function nudgeGitBranchCache(previousCwd) {
197
197
  const now = new Date();
198
- for (const dir of [previousCwd, process.cwd()]) {
198
+ let currentCwd = null;
199
+ try {
200
+ currentCwd = process.cwd();
201
+ }
202
+ catch {
203
+ currentCwd = null;
204
+ }
205
+ for (const dir of [previousCwd, currentCwd].filter((dir) => Boolean(dir))) {
199
206
  try {
200
207
  const headPath = resolveGitHeadPath(dir);
201
208
  if (headPath)
@@ -214,9 +214,11 @@ export function registerNativeSearchHooks(pi) {
214
214
  isAnthropic = isAnthropicProvider && payloadLooksAnthropic !== false;
215
215
  }
216
216
  else {
217
- // Last resort: session-restore paths where the SDK doesn't pass model.
218
- // The model-name prefix is best-effort and assumes direct Anthropic.
219
- isAnthropic = payloadLooksAnthropic === true;
217
+ // No authoritative provider info available (no event.model, no model_select).
218
+ // Do NOT inject native web_search guessing on model name alone causes 400
219
+ // "unsupported_value" errors when the actual provider (copilot, openrouter,
220
+ // proxy, etc.) doesn't expose the server-side search tool (#648).
221
+ isAnthropic = false;
220
222
  }
221
223
  if (!isAnthropic)
222
224
  return;
@@ -0,0 +1,59 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Browser Automation Contract — the single source for the canonical
3
+ // Pi-facing browser tool vocabulary. Engine adapters (legacy Playwright, managed
4
+ // gsd-browser), UAT policy, dispatch preflight, and evidence detection all derive
5
+ // their browser tool knowledge from this module instead of re-listing names.
6
+ /**
7
+ * Canonical `browser_*` tool names of the Browser Automation Contract.
8
+ *
9
+ * These are the product-level names Units see regardless of which Browser
10
+ * Automation Engine serves them (ADR-024). Adding a capability here is the
11
+ * one-line vocabulary change; the engine adapters and presentation surfaces
12
+ * are typed against this list, so missing coverage fails typecheck.
13
+ */
14
+ export const BROWSER_CONTRACT_TOOL_NAMES = [
15
+ "browser_navigate",
16
+ "browser_click",
17
+ "browser_type",
18
+ "browser_fill_form",
19
+ "browser_click_ref",
20
+ "browser_fill_ref",
21
+ "browser_wait_for",
22
+ "browser_assert",
23
+ "browser_verify",
24
+ "browser_screenshot",
25
+ "browser_snapshot_refs",
26
+ "browser_find",
27
+ "browser_get_console_logs",
28
+ "browser_get_network_logs",
29
+ "browser_evaluate",
30
+ "browser_reload",
31
+ "browser_batch",
32
+ "browser_act",
33
+ ];
34
+ const BROWSER_CONTRACT_TOOL_NAME_SET = new Set(BROWSER_CONTRACT_TOOL_NAMES);
35
+ export function isBrowserContractToolName(name) {
36
+ return BROWSER_CONTRACT_TOOL_NAME_SET.has(name);
37
+ }
38
+ /**
39
+ * Whether a canonical (non-MCP-prefixed) tool name belongs to the browser tool
40
+ * family. Broader than the contract list on purpose: an External MCP Client or
41
+ * host integration may supply additional `browser_*` tools that still satisfy
42
+ * browser-backed UAT.
43
+ */
44
+ export function hasBrowserContractPrefix(canonicalToolName) {
45
+ return canonicalToolName.startsWith("browser_");
46
+ }
47
+ /**
48
+ * Contract tool names whose appearance in prose marks browser-backed UAT
49
+ * activity (requirement or evidence language). Consumed by the
50
+ * browser-evidence regexes so textual detection stays derived from the
51
+ * contract vocabulary.
52
+ */
53
+ export const BROWSER_EVIDENCE_SIGNAL_TOOL_NAMES = [
54
+ "browser_assert",
55
+ "browser_batch",
56
+ "browser_find",
57
+ "browser_verify",
58
+ "browser_snapshot_refs",
59
+ ];