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

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 (551) 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/models-resolver.d.ts +3 -13
  7. package/dist/models-resolver.js +3 -22
  8. package/dist/resource-loader.js +2 -14
  9. package/dist/resources/.managed-resources-content-hash +1 -1
  10. package/dist/resources/GSD-WORKFLOW.md +5 -4
  11. package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
  12. package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
  13. package/dist/resources/extensions/async-jobs/index.js +65 -0
  14. package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
  15. package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
  16. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
  17. package/dist/resources/extensions/bg-shell/overlay.js +9 -6
  18. package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
  19. package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
  20. package/dist/resources/extensions/bg-shell/utilities.js +5 -2
  21. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
  22. package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
  23. package/dist/resources/extensions/browser-tools/index.js +69 -12
  24. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  25. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +38 -6
  26. package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
  27. package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
  28. package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
  29. package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
  30. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  31. package/dist/resources/extensions/gsd/auto/orchestrator.js +94 -48
  32. package/dist/resources/extensions/gsd/auto/phases.js +8 -3
  33. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +8 -32
  34. package/dist/resources/extensions/gsd/auto-dispatch.js +40 -57
  35. package/dist/resources/extensions/gsd/auto-model-selection.js +25 -6
  36. package/dist/resources/extensions/gsd/auto-post-unit.js +31 -14
  37. package/dist/resources/extensions/gsd/auto-prompts.js +81 -19
  38. package/dist/resources/extensions/gsd/auto-start.js +24 -26
  39. package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
  40. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +12 -20
  41. package/dist/resources/extensions/gsd/auto-verification.js +9 -28
  42. package/dist/resources/extensions/gsd/auto-worktree-repair.js +10 -2
  43. package/dist/resources/extensions/gsd/auto-worktree.js +35 -352
  44. package/dist/resources/extensions/gsd/auto.js +8 -20
  45. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +3 -2
  46. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -12
  47. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
  48. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +229 -36
  49. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +319 -71
  50. package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
  51. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  52. package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
  53. package/dist/resources/extensions/gsd/captures.js +5 -15
  54. package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
  55. package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
  56. package/dist/resources/extensions/gsd/consent-question.js +337 -0
  57. package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
  58. package/dist/resources/extensions/gsd/constants.js +0 -2
  59. package/dist/resources/extensions/gsd/crash-recovery.js +4 -12
  60. package/dist/resources/extensions/gsd/db/engine.js +755 -0
  61. package/dist/resources/extensions/gsd/db/queries.js +398 -0
  62. package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
  63. package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
  64. package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
  65. package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
  66. package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
  67. package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
  68. package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
  69. package/dist/resources/extensions/gsd/doctor-environment.js +5 -11
  70. package/dist/resources/extensions/gsd/doctor-format.js +9 -6
  71. package/dist/resources/extensions/gsd/doctor-git-checks.js +4 -3
  72. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +21 -16
  73. package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
  74. package/dist/resources/extensions/gsd/error-classifier.js +9 -0
  75. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  76. package/dist/resources/extensions/gsd/files.js +33 -19
  77. package/dist/resources/extensions/gsd/git-service.js +1 -0
  78. package/dist/resources/extensions/gsd/gitignore.js +3 -0
  79. package/dist/resources/extensions/gsd/gsd-db.js +171 -2048
  80. package/dist/resources/extensions/gsd/guidance.js +158 -0
  81. package/dist/resources/extensions/gsd/guided-flow.js +51 -5
  82. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
  83. package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
  84. package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
  85. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
  86. package/dist/resources/extensions/gsd/migrate/safety.js +20 -9
  87. package/dist/resources/extensions/gsd/migration-auto-check.js +24 -3
  88. package/dist/resources/extensions/gsd/milestone-closeout.js +13 -23
  89. package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
  90. package/dist/resources/extensions/gsd/model-router.js +3 -0
  91. package/dist/resources/extensions/gsd/notification-store.js +11 -4
  92. package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
  93. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +11 -7
  94. package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
  95. package/dist/resources/extensions/gsd/paths.js +37 -24
  96. package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
  97. package/dist/resources/extensions/gsd/preferences-models.js +14 -48
  98. package/dist/resources/extensions/gsd/preferences.js +14 -0
  99. package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
  100. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  101. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  102. package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  103. package/dist/resources/extensions/gsd/prompts/run-uat.md +6 -4
  104. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  105. package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
  106. package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
  107. package/dist/resources/extensions/gsd/publication.js +87 -0
  108. package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
  109. package/dist/resources/extensions/gsd/recovery-classification.js +41 -87
  110. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  111. package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
  112. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
  113. package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
  114. package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
  115. package/dist/resources/extensions/gsd/state.js +6 -20
  116. package/dist/resources/extensions/gsd/status-guards.js +56 -8
  117. package/dist/resources/extensions/gsd/stop-notice.js +57 -0
  118. package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
  119. package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
  120. package/dist/resources/extensions/gsd/tools/complete-slice.js +44 -53
  121. package/dist/resources/extensions/gsd/tools/exec-tool.js +10 -8
  122. package/dist/resources/extensions/gsd/tools/plan-slice.js +12 -6
  123. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +11 -29
  124. package/dist/resources/extensions/gsd/tools/reopen-slice.js +14 -33
  125. package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
  126. package/dist/resources/extensions/gsd/uat-policy.js +42 -16
  127. package/dist/resources/extensions/gsd/undo.js +8 -7
  128. package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
  129. package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
  130. package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
  131. package/dist/resources/extensions/gsd/unit-registry.js +337 -0
  132. package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
  133. package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
  134. package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
  135. package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
  136. package/dist/resources/extensions/gsd/worktree-git-recovery.js +293 -0
  137. package/dist/resources/extensions/gsd/worktree-lifecycle.js +12 -3
  138. package/dist/resources/extensions/gsd/worktree-manager.js +45 -28
  139. package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
  140. package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
  141. package/dist/resources/extensions/gsd/worktree-root.js +28 -6
  142. package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
  143. package/dist/resources/extensions/gsd/worktree-session-state.js +12 -11
  144. package/dist/resources/extensions/search-the-web/native-search.js +5 -3
  145. package/dist/resources/extensions/shared/browser-contract.js +59 -0
  146. package/dist/resources/extensions/shared/gsd-browser-cli.js +96 -5
  147. package/dist/resources/shared/package.json +3 -0
  148. package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
  149. package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
  150. package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
  151. package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
  152. package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  153. package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  154. package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  155. package/dist/resources/skills/gsd-browser/SKILL.md +1 -1
  156. package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
  157. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  158. package/dist/web/standalone/.next/BUILD_ID +1 -1
  159. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  160. package/dist/web/standalone/.next/build-manifest.json +3 -3
  161. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  162. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  163. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  164. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  165. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  166. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  167. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  169. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  170. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  171. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  172. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  173. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  174. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  175. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  176. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  177. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  178. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  179. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  180. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  182. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  184. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  185. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  186. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  187. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  188. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  190. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  191. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  192. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  193. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  194. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  195. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  196. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  197. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  198. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  199. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  200. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  201. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  202. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  203. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  204. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  205. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  206. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  207. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  208. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  209. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  210. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  211. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  212. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  214. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  215. package/dist/web/standalone/.next/server/app/index.html +1 -1
  216. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  217. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  218. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  219. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  220. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  221. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  222. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  223. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  224. package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
  225. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  226. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  227. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  228. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  229. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  230. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  231. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  232. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  233. package/dist/web/standalone/package.json +1 -1
  234. package/dist/worktree-cli.js +3 -6
  235. package/dist/worktree-status-banner.js +7 -11
  236. package/package.json +1 -1
  237. package/packages/cloud-mcp-gateway/package.json +2 -2
  238. package/packages/contracts/dist/rpc.d.ts +1 -0
  239. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  240. package/packages/contracts/dist/rpc.js.map +1 -1
  241. package/packages/contracts/dist/workflow.d.ts +4 -0
  242. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  243. package/packages/contracts/dist/workflow.js.map +1 -1
  244. package/packages/contracts/package.json +1 -1
  245. package/packages/daemon/package.json +4 -4
  246. package/packages/gsd-agent-core/package.json +5 -5
  247. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
  248. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  249. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +8 -0
  250. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  251. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  252. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
  253. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  254. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  255. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  256. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  257. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  258. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  259. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  260. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  261. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  262. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  263. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  264. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  265. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  266. package/packages/gsd-agent-modes/package.json +7 -7
  267. package/packages/mcp-server/dist/cli.js +6 -3
  268. package/packages/mcp-server/dist/cli.js.map +1 -1
  269. package/packages/mcp-server/dist/workflow-tools.d.ts +8 -0
  270. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  271. package/packages/mcp-server/dist/workflow-tools.js +46 -21
  272. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  273. package/packages/mcp-server/package.json +3 -3
  274. package/packages/native/package.json +1 -1
  275. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  276. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  277. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  278. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  279. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  280. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  281. package/packages/pi-agent-core/dist/index.js +3 -0
  282. package/packages/pi-agent-core/dist/index.js.map +1 -1
  283. package/packages/pi-agent-core/package.json +1 -1
  284. package/packages/pi-ai/README.md +1 -0
  285. package/packages/pi-ai/dist/models.generated.d.ts +192 -0
  286. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  287. package/packages/pi-ai/dist/models.generated.js +166 -0
  288. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  289. package/packages/pi-ai/package.json +3 -2
  290. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  291. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  292. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  293. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  294. package/packages/pi-coding-agent/dist/core/capability-patches.d.ts.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
  296. package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  298. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  299. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  300. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  301. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  302. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  303. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  304. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  305. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  306. package/packages/pi-coding-agent/dist/index.js +1 -1
  307. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  308. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  309. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  310. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  311. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  312. package/packages/pi-coding-agent/package.json +7 -7
  313. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  314. package/packages/pi-tui/dist/tui.js +9 -0
  315. package/packages/pi-tui/dist/tui.js.map +1 -1
  316. package/packages/pi-tui/package.json +2 -2
  317. package/packages/rpc-client/package.json +2 -2
  318. package/pkg/package.json +1 -1
  319. package/src/resources/GSD-WORKFLOW.md +5 -4
  320. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  321. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  322. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  323. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  324. package/src/resources/extensions/async-jobs/index.ts +79 -0
  325. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  326. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  327. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  328. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  329. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  330. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  331. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  332. package/src/resources/extensions/bg-shell/utilities.ts +5 -2
  333. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
  334. package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
  335. package/src/resources/extensions/browser-tools/index.ts +71 -13
  336. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
  337. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +29 -1
  338. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
  339. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  340. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +40 -4
  341. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +28 -0
  342. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
  343. package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
  344. package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
  345. package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
  346. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -1
  347. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  348. package/src/resources/extensions/gsd/auto/orchestrator.ts +109 -51
  349. package/src/resources/extensions/gsd/auto/phases.ts +12 -3
  350. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -32
  351. package/src/resources/extensions/gsd/auto-dispatch.ts +38 -52
  352. package/src/resources/extensions/gsd/auto-model-selection.ts +25 -5
  353. package/src/resources/extensions/gsd/auto-post-unit.ts +37 -13
  354. package/src/resources/extensions/gsd/auto-prompts.ts +118 -35
  355. package/src/resources/extensions/gsd/auto-start.ts +24 -29
  356. package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
  357. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +14 -21
  358. package/src/resources/extensions/gsd/auto-verification.ts +8 -26
  359. package/src/resources/extensions/gsd/auto-worktree-repair.ts +13 -2
  360. package/src/resources/extensions/gsd/auto-worktree.ts +41 -364
  361. package/src/resources/extensions/gsd/auto.ts +20 -24
  362. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +3 -5
  363. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +33 -12
  364. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
  365. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +270 -37
  366. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +368 -78
  367. package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
  368. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  369. package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
  370. package/src/resources/extensions/gsd/captures.ts +5 -16
  371. package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
  372. package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
  373. package/src/resources/extensions/gsd/consent-question.ts +416 -0
  374. package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
  375. package/src/resources/extensions/gsd/constants.ts +0 -3
  376. package/src/resources/extensions/gsd/crash-recovery.ts +3 -9
  377. package/src/resources/extensions/gsd/db/engine.ts +809 -0
  378. package/src/resources/extensions/gsd/db/queries.ts +490 -0
  379. package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
  380. package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
  381. package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
  382. package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
  383. package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
  384. package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
  385. package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
  386. package/src/resources/extensions/gsd/doctor-environment.ts +5 -13
  387. package/src/resources/extensions/gsd/doctor-format.ts +12 -7
  388. package/src/resources/extensions/gsd/doctor-git-checks.ts +3 -3
  389. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +22 -17
  390. package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
  391. package/src/resources/extensions/gsd/error-classifier.ts +11 -0
  392. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  393. package/src/resources/extensions/gsd/files.ts +33 -12
  394. package/src/resources/extensions/gsd/git-service.ts +1 -0
  395. package/src/resources/extensions/gsd/gitignore.ts +3 -0
  396. package/src/resources/extensions/gsd/gsd-db.ts +173 -2373
  397. package/src/resources/extensions/gsd/guidance.ts +217 -0
  398. package/src/resources/extensions/gsd/guided-flow.ts +50 -5
  399. package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
  400. package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
  401. package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
  402. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
  403. package/src/resources/extensions/gsd/migrate/safety.ts +18 -7
  404. package/src/resources/extensions/gsd/migration-auto-check.ts +28 -3
  405. package/src/resources/extensions/gsd/milestone-closeout.ts +13 -23
  406. package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
  407. package/src/resources/extensions/gsd/model-router.ts +3 -0
  408. package/src/resources/extensions/gsd/notification-store.ts +26 -3
  409. package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
  410. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -7
  411. package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
  412. package/src/resources/extensions/gsd/paths.ts +42 -22
  413. package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
  414. package/src/resources/extensions/gsd/preferences-models.ts +12 -47
  415. package/src/resources/extensions/gsd/preferences.ts +18 -0
  416. package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
  417. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  418. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  419. package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  420. package/src/resources/extensions/gsd/prompts/run-uat.md +6 -4
  421. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  422. package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
  423. package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
  424. package/src/resources/extensions/gsd/publication.ts +122 -0
  425. package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
  426. package/src/resources/extensions/gsd/recovery-classification.ts +47 -88
  427. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  428. package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
  429. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
  430. package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
  431. package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
  432. package/src/resources/extensions/gsd/state.ts +9 -21
  433. package/src/resources/extensions/gsd/status-guards.ts +59 -8
  434. package/src/resources/extensions/gsd/stop-notice.ts +75 -0
  435. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +123 -0
  436. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +22 -0
  437. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +101 -26
  438. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +3 -1
  439. package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
  440. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
  441. package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
  442. package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
  443. package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
  444. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  445. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
  446. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +44 -0
  447. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
  448. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  449. package/src/resources/extensions/gsd/tests/consent-question.test.ts +336 -0
  450. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
  451. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
  452. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  453. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
  454. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
  455. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  456. package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
  457. package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +157 -0
  458. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  459. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  460. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
  461. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
  462. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
  463. package/src/resources/extensions/gsd/tests/guidance.test.ts +148 -0
  464. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +58 -15
  465. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +74 -59
  466. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
  467. package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
  468. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
  469. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  470. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +85 -1
  471. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  472. package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
  473. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  474. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
  475. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +139 -0
  476. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
  477. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
  478. package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
  479. package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
  480. package/src/resources/extensions/gsd/tests/recovery-classification-illegal-transition.test.ts +30 -0
  481. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +248 -1
  482. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +1 -0
  483. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +38 -0
  484. package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
  485. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +43 -6
  486. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +36 -0
  487. package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
  488. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
  489. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
  490. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
  491. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +155 -0
  492. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
  493. package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
  494. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
  495. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
  496. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
  497. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
  498. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +2 -2
  499. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +41 -4
  500. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +22 -1
  501. package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
  502. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
  503. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +3 -1
  504. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
  505. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +2 -2
  506. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
  507. package/src/resources/extensions/gsd/tests/write-gate.test.ts +109 -1
  508. package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
  509. package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
  510. package/src/resources/extensions/gsd/tools/complete-slice.ts +43 -68
  511. package/src/resources/extensions/gsd/tools/exec-tool.ts +9 -8
  512. package/src/resources/extensions/gsd/tools/plan-slice.ts +12 -6
  513. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +11 -38
  514. package/src/resources/extensions/gsd/tools/reopen-slice.ts +14 -42
  515. package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
  516. package/src/resources/extensions/gsd/uat-policy.ts +62 -16
  517. package/src/resources/extensions/gsd/undo.ts +9 -8
  518. package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
  519. package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
  520. package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
  521. package/src/resources/extensions/gsd/unit-registry.ts +412 -0
  522. package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
  523. package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
  524. package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
  525. package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
  526. package/src/resources/extensions/gsd/worktree-git-recovery.ts +314 -0
  527. package/src/resources/extensions/gsd/worktree-lifecycle.ts +13 -9
  528. package/src/resources/extensions/gsd/worktree-manager.ts +47 -28
  529. package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
  530. package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
  531. package/src/resources/extensions/gsd/worktree-root.ts +29 -6
  532. package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
  533. package/src/resources/extensions/gsd/worktree-session-state.ts +11 -11
  534. package/src/resources/extensions/search-the-web/native-search.ts +5 -3
  535. package/src/resources/extensions/shared/browser-contract.ts +66 -0
  536. package/src/resources/extensions/shared/gsd-browser-cli.ts +119 -5
  537. package/src/resources/shared/package.json +3 -0
  538. package/src/resources/skills/create-skill/references/executable-code.md +1 -1
  539. package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
  540. package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
  541. package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
  542. package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  543. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  544. package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  545. package/src/resources/skills/gsd-browser/SKILL.md +1 -1
  546. package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
  547. package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
  548. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
  549. package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
  550. /package/dist/web/standalone/.next/static/{3PtrU9qGPEXwNLWkIyiqk → jmTLg6xZmAuq_LIqKOxrH}/_buildManifest.js +0 -0
  551. /package/dist/web/standalone/.next/static/{3PtrU9qGPEXwNLWkIyiqk → jmTLg6xZmAuq_LIqKOxrH}/_ssgManifest.js +0 -0
@@ -27,21 +27,23 @@ You are the UAT runner. Execute every check defined in `{{uatPath}}` as deeply a
27
27
  ### Automation rules by mode
28
28
 
29
29
  - `artifact-driven` — verify with shell commands, scripts, file reads, and artifact structure checks.
30
- - `browser-executable` — use browser tools to navigate to the target URL and verify expected behavior. Prefer direct `browser_*` tools when available. Capture screenshots as evidence. Record pass/fail with specific assertions.
31
- - `runtime-executable` — execute the specified command or script. Capture stdout/stderr as evidence. Record pass/fail based on exit code and output.
30
+ - `browser-executable` — use browser tools to navigate to the target URL and verify expected behavior. Prefer direct `browser_*` tools when available. Capture screenshots as evidence. Record pass/fail with specific assertions. When the UAT **Evidence** section names a self-contained runtime harness (for example `npm run test:uat` or `node tests/browser/search-uat.mjs`), treat the effective mode as **runtime-executable** instead: run that command only and do not start a separate server or `browser_navigate` to a hardcoded localhost port.
31
+ - `runtime-executable` — execute the specified command or script. Capture stdout/stderr as evidence. Record pass/fail based on exit code and output. When the verification script starts its own dev/static server (for example `node tests/browser/search-uat.mjs`), do **not** start a separate server with `uat-service-start` — the script owns server lifecycle and binds an ephemeral port. If a server is already running, pass its URL via `UAT_BASE_URL` or `PORT` in the `gsd_uat_exec` environment instead of hardcoding a fixed port like 4173.
32
32
  - `live-runtime` — exercise the real runtime path. Start or connect to the app/service if needed, use browser/runtime/network checks, and verify observable behavior.
33
33
  - `mixed` — run all automatable artifact-driven and live-runtime checks. Separate any remaining human-only checks explicitly.
34
34
  - `human-experience` — automate setup, preconditions, screenshots, logs, and objective checks, but do **not** invent subjective PASS results. Mark taste-based, experiential, or purely human-judgment checks as `NEEDS-HUMAN`. Use an overall verdict of `PASS` when all automatable checks succeed (even if human-only checks remain as `NEEDS-HUMAN`). Use `PARTIAL` only when automatable checks themselves were inconclusive.
35
35
 
36
36
  ### Evidence tools
37
37
 
38
- Choose the lightest tool that proves the check honestly:
38
+ The **Tool Surface** block prepended above lists unavailable tools for this unit. In short:
39
39
 
40
40
  - Run automated checks with `gsd_uat_exec`
41
41
  - Use `uat-artifact-check` as `intent` for static file, grep, structure, or artifact checks.
42
42
  - Use `uat-runtime-check` as `intent` for executing tests, scripts, or runtime assertions.
43
43
  - Use `uat-browser-check` as `intent` for browser interaction or screenshot-backed UI checks.
44
- - Use `uat-service-start` as `intent` only when starting or connecting to an app/service.
44
+ - Use `uat-service-start` as `intent` only when starting or connecting to an app/service that the UAT checks will not start themselves.
45
+ - Do not start a dev/static server separately when a runtime test script owns server lifecycle — run the script directly instead.
46
+ - When you do start a service, capture the URL from its stdout (for example `Ready at http://127.0.0.1:PORT`) and pass it to downstream checks via `UAT_BASE_URL` rather than assuming a fixed port.
45
47
  - Use `uat-log-inspection` as `intent` for checking logs or captured output files.
46
48
  - The result-table evidence mode is separate; do not use `artifact`, `runtime`, or `human-follow-up` as `intent`.
47
49
  - Run `grep` / `rg` checks against files
@@ -110,9 +110,12 @@ Templates are in `{{templatesDir}}`.
110
110
 
111
111
  **External facts:** Use `search-the-web` + `fetch_page`, or `search_and_read`; use `freshness` for recency. Never state current facts from training data without verification.
112
112
 
113
- **Background processes:** Use `bg_shell` `start` + `wait_for_ready` for servers/watchers/daemons. Never use `bash` with `&` or `nohup`; inherited stdout can hang. Never poll with `sleep`; use `wait_for_ready`. For status use `digest`, `highlights` for significant lines, and `output` only when debugging.
113
+ **Choosing a shell tool decide by how the command runs, not how long it takes:**
114
114
 
115
- **One-shot commands:** Use `async_bash` for builds, tests, and installs. Results are pushed on exit; use `await_job` only to block on a specific job.
115
+ - **Runs and exits (a batch command):** anything that does work and finishes — `terraform apply`, DB migrations, builds, tests, installs, long scripts. Use synchronous `bash` when you want to block and read the result now (uncapped; in auto-mode genuine hangs are caught by the stalled-tool watchdog, interactively they end on human ESC). Use `async_bash` when you want it non-blocking — it returns a job ID immediately and you `await_job` later. **Never** put a run-to-completion command under `bg_shell` `wait_for_ready`: it exits instead of staying alive, so readiness never trips and a clean exit looks like a failure.
116
+ - **Stays alive and you interact with it over time:** servers, watchers, daemons, REPLs. Use `bg_shell` `start`, then `wait_for_ready` (block until it listens/prints its ready pattern), `output`/`digest`/`highlights` to inspect, `send`/`send_and_wait` to drive it, and `kill`/`restart` to manage it. Never use `bash` with `&` or `nohup` (inherited stdout can hang); never poll with `sleep` (use `wait_for_ready`).
117
+
118
+ Quick rule of thumb: if the command would exit on its own, it's `bash`/`async_bash`; if it would keep running until you stop it, it's `bg_shell`.
116
119
 
117
120
  **Stale job hygiene:** After editing source to fix a failure, `cancel_job` every in-flight `async_bash` job before rerunning. Changed inputs make in-flight outputs untrusted.
118
121
 
@@ -1,7 +1,10 @@
1
1
  /**
2
2
  * Actionable remediation hints when auto-mode pauses on provider/model errors.
3
+ * Render with formatGuidance from the Guidance module.
3
4
  */
4
5
 
6
+ import type { Guidance } from "./guidance.js";
7
+
5
8
  export interface ProviderErrorGuidanceInput {
6
9
  errorMsg: string;
7
10
  provider?: string;
@@ -12,10 +15,7 @@ export interface ProviderErrorGuidanceInput {
12
15
  hasConfiguredFallbacks?: boolean;
13
16
  }
14
17
 
15
- export interface ProviderErrorGuidance {
16
- summary: string;
17
- steps: string[];
18
- }
18
+ export type ProviderErrorGuidance = Guidance;
19
19
 
20
20
  /** Map auto unit types to the `models:` key in PREFERENCES.md. */
21
21
  export function unitTypeToPrefsPhaseKey(unitType: string | undefined): string | undefined {
@@ -129,8 +129,3 @@ export function resolveProviderErrorGuidance(input: ProviderErrorGuidanceInput):
129
129
  return { summary, steps };
130
130
  }
131
131
 
132
- /** Flatten guidance into a pause banner / notification string. */
133
- export function formatProviderErrorGuidance(guidance: ProviderErrorGuidance): string {
134
- const numbered = guidance.steps.map((step, index) => `${index + 1}. ${step}`).join("\n");
135
- return `${guidance.summary}\n\n${numbered}`;
136
- }
@@ -128,7 +128,7 @@ function emitAudit(report: ProviderSwitchReport): void {
128
128
 
129
129
  function emitNotification(report: ProviderSwitchReport): void {
130
130
  try {
131
- appendNotification(summarize(report), "warning", "workflow-logger");
131
+ appendNotification(summarize(report), "warning", "workflow-logger", { kind: "provider-switch" });
132
132
  } catch {
133
133
  // Notification persistence is best-effort.
134
134
  }
@@ -0,0 +1,122 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Publication module — push and draft-PR creation for a merged milestone (ADR-034).
3
+ //
4
+ // Publication is distinct from the merge verb: merging a milestone branch is a
5
+ // Worktree Lifecycle concern (worktree, branch, lease, stash discipline);
6
+ // publication needs only the resulting commit, a remote, and preferences.
7
+ // Extracted from the tail of `mergeMilestoneToMain` (auto-worktree.ts) so it is
8
+ // testable without a merge fixture and reachable from any closeout path.
9
+ //
10
+ // Publication failure is non-fatal to a completed local merge: every failure is
11
+ // logged and reported in the result, never thrown.
12
+
13
+ import { execFileSync } from "node:child_process";
14
+
15
+ import {
16
+ buildPullRequestEvidence,
17
+ createDraftPullRequestFromEvidence,
18
+ } from "./pull-request-process.js";
19
+ import { logWarning } from "./workflow-logger.js";
20
+
21
+ export interface PublicationPrefs {
22
+ autoPush: boolean;
23
+ autoPr: boolean;
24
+ remote?: string;
25
+ prTargetBranch?: string;
26
+ }
27
+
28
+ export interface PublicationRequest {
29
+ basePath: string;
30
+ milestoneId: string;
31
+ milestoneTitle: string;
32
+ /** The branch the milestone was merged to (push target for auto-push). */
33
+ integrationBranch: string;
34
+ /** The milestone branch (push + PR head for auto-PR). */
35
+ milestoneBranch: string;
36
+ /** Pre-rendered per-slice summary blocks for the PR body. */
37
+ sliceSummaries: readonly string[];
38
+ /** True when the merge found nothing to commit — publication is skipped. */
39
+ nothingToCommit: boolean;
40
+ prefs: PublicationPrefs;
41
+ }
42
+
43
+ export interface PublicationResult {
44
+ pushed: boolean;
45
+ prCreated: boolean;
46
+ prUrl?: string;
47
+ }
48
+
49
+ export function gitRemoteExists(basePath: string, remote: string): boolean {
50
+ try {
51
+ execFileSync("git", ["remote", "get-url", remote], {
52
+ cwd: basePath,
53
+ stdio: ["ignore", "pipe", "pipe"],
54
+ encoding: "utf-8",
55
+ });
56
+ return true;
57
+ } catch {
58
+ return false;
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Publish a merged milestone per preferences: push the integration branch
64
+ * (auto-push, suppressed when auto-PR owns the remote interaction) and/or
65
+ * push the milestone branch and open a draft PR (auto-PR).
66
+ */
67
+ export function publishMilestone(request: PublicationRequest): PublicationResult {
68
+ const result: PublicationResult = { pushed: false, prCreated: false };
69
+ if (request.nothingToCommit) return result;
70
+
71
+ const { basePath, prefs } = request;
72
+ const remote = prefs.remote ?? "origin";
73
+
74
+ if (prefs.autoPush && !prefs.autoPr && gitRemoteExists(basePath, remote)) {
75
+ try {
76
+ execFileSync("git", ["push", remote, request.integrationBranch], {
77
+ cwd: basePath,
78
+ stdio: ["ignore", "pipe", "pipe"],
79
+ encoding: "utf-8",
80
+ });
81
+ result.pushed = true;
82
+ } catch (err) {
83
+ // Push failure is non-fatal
84
+ logWarning("worktree", `git push failed: ${err instanceof Error ? err.message : String(err)}`);
85
+ }
86
+ }
87
+
88
+ // #2302: PR creation is not gated on pushed/auto-push.
89
+ if (prefs.autoPr && gitRemoteExists(basePath, remote)) {
90
+ try {
91
+ // Push the milestone branch to remote first
92
+ execFileSync("git", ["push", remote, request.milestoneBranch], {
93
+ cwd: basePath,
94
+ stdio: ["ignore", "pipe", "pipe"],
95
+ encoding: "utf-8",
96
+ });
97
+ const prEvidence = buildPullRequestEvidence({
98
+ milestoneId: request.milestoneId,
99
+ milestoneTitle: request.milestoneTitle,
100
+ changeType: "feat",
101
+ summaries: [...request.sliceSummaries],
102
+ testsRun: ["Auto-created after milestone merge. Run `npm run verify:merge` before marking this draft ready."],
103
+ rollbackNotes: ["Close the draft PR or revert the merge commit if review finds a behavior regression."],
104
+ how: "Generated by git.auto_pr after the milestone branch was pushed and merged locally.",
105
+ });
106
+ const prUrl = createDraftPullRequestFromEvidence(basePath, request.milestoneId, prEvidence, {
107
+ head: request.milestoneBranch,
108
+ base: prefs.prTargetBranch ?? request.integrationBranch,
109
+ });
110
+ if (!prUrl) {
111
+ throw new Error("gh pr create returned no URL");
112
+ }
113
+ result.prCreated = true;
114
+ result.prUrl = prUrl;
115
+ } catch (err) {
116
+ // PR creation failure is non-fatal — gh may not be installed or authenticated
117
+ logWarning("worktree", `PR creation failed: ${err instanceof Error ? err.message : String(err)}`);
118
+ }
119
+ }
120
+
121
+ return result;
122
+ }
@@ -12,7 +12,11 @@
12
12
  import type { TaskIO, DerivedTaskNode, ReactiveExecutionState } from "./types.js";
13
13
  import { loadFile, parseTaskPlanIO } from "./files.js";
14
14
  import { isDbAvailable, getSliceTasks } from "./gsd-db.js";
15
+ // Explicit degraded-mode fallback ONLY (ADR-017): parsePlan is consulted when
16
+ // the DB is unavailable or has no task rows for the slice; the DB path in
17
+ // loadSliceTaskIO always wins when rows exist, and the fallback logs a warning.
15
18
  import { parsePlan } from "./parsers-legacy.js";
19
+ import { logWarning } from "./workflow-logger.js";
16
20
  import { resolveTasksDir, resolveTaskFiles } from "./paths.js";
17
21
  import { join } from "node:path";
18
22
  import { loadJsonFileOrNull, saveJsonFile } from "./json-persistence.js";
@@ -224,7 +228,13 @@ export async function loadSliceTaskIO(
224
228
  } catch { /* fall through */ }
225
229
 
226
230
  if (!taskEntries) {
227
- // File-based fallback: parse slice plan for task entries
231
+ // Degraded-mode fallback (ADR-017): no DB task rows for this slice —
232
+ // parse the PLAN.md projection instead. Warn so silent drift from the
233
+ // DB-authoritative path is visible in logs.
234
+ logWarning(
235
+ "projection",
236
+ `reactive-graph: DB unavailable or no task rows for ${mid}/${sid}; falling back to PLAN.md parsing`,
237
+ );
228
238
  const parsed = parsePlan(planContent);
229
239
  if (parsed.tasks.length > 0) {
230
240
  taskEntries = parsed.tasks.map(t => ({
@@ -1,18 +1,23 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: ADR-015 Recovery Classification module for runtime failure taxonomy.
3
3
 
4
+ import { isToolUnavailableError } from "./auto-tool-tracking.js";
4
5
  import { classifyError, isTransient, type ErrorClass } from "./error-classifier.js";
6
+ import { recoveryRemediation } from "./guidance.js";
5
7
  import { ReconciliationFailedError } from "./state-reconciliation.js";
8
+ import { IllegalPhaseTransitionError } from "./state-transition-matrix.js";
6
9
 
7
10
  export type RecoveryFailureKind =
8
11
  | "tool-schema"
9
12
  | "tool-contract"
13
+ | "tool-unavailable"
10
14
  | "deterministic-policy"
11
15
  | "lifecycle-progression"
12
16
  | "stale-worker"
13
17
  | "worktree-invalid"
14
18
  | "verification-drift"
15
19
  | "reconciliation-drift"
20
+ | "illegal-transition"
16
21
  | "provider"
17
22
  | "runtime-unknown";
18
23
 
@@ -43,99 +48,53 @@ export function classifyFailure(input: RecoveryClassificationInput): RecoveryCla
43
48
  const failureKind =
44
49
  input.error instanceof ReconciliationFailedError
45
50
  ? "reconciliation-drift"
46
- : input.failureKind ?? inferFailureKind(message);
51
+ : input.error instanceof IllegalPhaseTransitionError
52
+ ? "illegal-transition"
53
+ : input.failureKind ?? inferFailureKind(message);
47
54
 
48
- switch (failureKind) {
49
- case "tool-schema":
50
- return {
51
- failureKind,
52
- action: "stop",
53
- reason: `Tool schema failure${unitSuffix(input)}: ${message}`,
54
- exitReason: "tool-schema",
55
- remediation: "Fix the Unit Tool Contract or tool schema before retrying.",
56
- };
57
- case "tool-contract":
58
- return {
59
- failureKind,
60
- action: "stop",
61
- reason: `Tool Contract failure${unitSuffix(input)}: ${message}`,
62
- exitReason: "tool-contract",
63
- remediation: "Fix the Unit Tool Contract or prompt so the Unit is only asked to use tools owned by its phase.",
64
- };
65
- case "deterministic-policy":
66
- return {
67
- failureKind,
68
- action: "stop",
69
- reason: `Deterministic policy failure${unitSuffix(input)}: ${message}`,
70
- exitReason: "deterministic-policy",
71
- remediation: "Resolve the policy blocker; retrying the same Unit will repeat the failure.",
72
- };
73
- case "lifecycle-progression":
74
- return {
75
- failureKind,
76
- action: "stop",
77
- reason: `Lifecycle progression failure${unitSuffix(input)}: ${message}`,
78
- exitReason: "lifecycle-progression",
79
- remediation: "Route to the required owning Unit or restore the missing artifact before advancing lifecycle state.",
80
- };
81
- case "stale-worker":
82
- return {
83
- failureKind,
84
- action: "stop",
85
- reason: `Stale worker failure${unitSuffix(input)}: ${message}`,
86
- exitReason: "stale-worker",
87
- remediation: "Clear or reconcile the stale worker before dispatching another Unit.",
88
- };
89
- case "worktree-invalid":
90
- return {
91
- failureKind,
92
- action: "stop",
93
- reason: `Worktree invalid${unitSuffix(input)}: ${message}`,
94
- exitReason: "worktree-invalid",
95
- remediation: "Repair or recreate the milestone worktree before launching source-writing Units.",
96
- };
97
- case "verification-drift":
98
- return {
99
- failureKind,
100
- action: "escalate",
101
- reason: `Verification drift${unitSuffix(input)}: ${message}`,
102
- exitReason: "verification-drift",
103
- remediation: "Inspect the verification artifact and reconcile the state snapshot before resuming.",
104
- };
105
- case "reconciliation-drift":
106
- return {
107
- failureKind,
108
- action: "escalate",
109
- reason: `Reconciliation drift${unitSuffix(input)}: ${message}`,
110
- exitReason: "reconciliation-drift",
111
- remediation:
112
- "Inspect the persistent or repair-failed drift kinds reported by the State Reconciliation Module before resuming.",
113
- };
114
- case "provider": {
115
- const providerClass = classifyError(message, input.retryAfterMs);
116
- return {
117
- failureKind,
118
- action: isTransient(providerClass) ? "retry" : "escalate",
119
- reason: message,
120
- exitReason: `provider-${providerClass.kind}`,
121
- remediation: isTransient(providerClass)
122
- ? "Retry after the provider/network condition clears."
123
- : "Inspect provider credentials, model entitlement, or request shape.",
124
- providerClass: providerClass.kind,
125
- };
126
- }
127
- case "runtime-unknown":
128
- return {
129
- failureKind,
130
- action: "escalate",
131
- reason: message,
132
- exitReason: "runtime-unknown",
133
- remediation: "Inspect the runtime error and add a dedicated classification if it is repeatable.",
134
- };
55
+ if (failureKind === "provider") {
56
+ const providerClass = classifyError(message, input.retryAfterMs);
57
+ const transient = isTransient(providerClass);
58
+ return {
59
+ failureKind,
60
+ action: transient ? "retry" : "escalate",
61
+ reason: message,
62
+ exitReason: `provider-${providerClass.kind}`,
63
+ remediation: recoveryRemediation(transient ? "provider-transient" : "provider-permanent"),
64
+ providerClass: providerClass.kind,
65
+ };
135
66
  }
67
+
68
+ const { action, label } = FAILURE_TAXONOMY[failureKind];
69
+ return {
70
+ failureKind,
71
+ action,
72
+ reason: label ? `${label}${unitSuffix(input)}: ${message}` : message,
73
+ exitReason: failureKind,
74
+ remediation: recoveryRemediation(failureKind),
75
+ };
136
76
  }
137
77
 
78
+ /** Per-kind action and reason label. Remediation lives in the Guidance module. */
79
+ const FAILURE_TAXONOMY: Record<
80
+ Exclude<RecoveryFailureKind, "provider">,
81
+ { action: RecoveryAction; label: string | null }
82
+ > = {
83
+ "tool-schema": { action: "stop", label: "Tool schema failure" },
84
+ "tool-contract": { action: "stop", label: "Tool Contract failure" },
85
+ "tool-unavailable": { action: "retry", label: "Tool unavailable" },
86
+ "deterministic-policy": { action: "stop", label: "Deterministic policy failure" },
87
+ "lifecycle-progression": { action: "stop", label: "Lifecycle progression failure" },
88
+ "stale-worker": { action: "stop", label: "Stale worker failure" },
89
+ "worktree-invalid": { action: "stop", label: "Worktree invalid" },
90
+ "verification-drift": { action: "escalate", label: "Verification drift" },
91
+ "reconciliation-drift": { action: "escalate", label: "Reconciliation drift" },
92
+ "illegal-transition": { action: "escalate", label: "Illegal phase transition" },
93
+ "runtime-unknown": { action: "escalate", label: null },
94
+ };
95
+
138
96
  function inferFailureKind(message: string): RecoveryFailureKind {
97
+ if (isToolUnavailableError(message)) return "tool-unavailable";
139
98
  if (/tool contract|auto-unit tool scope|phase-boundary gate|not permitted.*own/i.test(message)) return "tool-contract";
140
99
  if (/lifecycle progression|required artifact|missing .*assessment|missing .*closeout|cannot legally (?:advance|progress)/i.test(message)) return "lifecycle-progression";
141
100
  if (/schema|invalid.*tool|tool.*invalid|enum/i.test(message)) return "tool-schema";
@@ -0,0 +1,134 @@
1
+ /**
2
+ * One-shot confirmation token for destructive bash commands.
3
+ *
4
+ * The destructive-command guard hard-blocks classified commands (force push,
5
+ * rm -rf, SQL drop, etc.) in all modes. The block instructs the model to
6
+ * confirm via ask_user_questions and re-issue the command. This module is the
7
+ * missing escape hatch: it records the user's confirmation and lets the exact
8
+ * confirmed command through exactly once.
9
+ *
10
+ * Design constraints:
11
+ * - In-memory only, never persisted. A confirmation token written to disk
12
+ * could silently auto-approve a destructive command in a later session —
13
+ * confirmation must be re-obtained every process lifetime.
14
+ * - One-shot. Consuming a token clears it, so a second destructive command
15
+ * (even an identical one) re-blocks and re-prompts.
16
+ * - Command-bound. The token only matches the exact (normalized) command
17
+ * string the user confirmed. A reworded command re-blocks, which is safe.
18
+ * - Per basePath, so concurrent workspaces in one process never share tokens.
19
+ *
20
+ * Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
21
+ */
22
+
23
+ import { resolve } from "node:path";
24
+
25
+ /**
26
+ * Question-id substring that marks an ask_user_questions call as a
27
+ * destructive-command confirmation. The tool_result handler promotes the
28
+ * pending command to a confirmed token when an affirmative answer arrives for
29
+ * a question whose id contains this marker.
30
+ */
31
+ export const DESTRUCTIVE_CONFIRM_GATE_MARKER = "destructive_confirm";
32
+
33
+ interface DestructiveConfirmationState {
34
+ /** Command awaiting confirmation, captured when the guard blocked it. */
35
+ pendingCommand: string | null;
36
+ /** Confirmed command cleared on first matching consume. */
37
+ confirmedCommand: string | null;
38
+ }
39
+
40
+ const statesByBasePath = new Map<string, DestructiveConfirmationState>();
41
+
42
+ function stateKey(basePath: string): string {
43
+ return resolve(basePath);
44
+ }
45
+
46
+ function getState(basePath: string): DestructiveConfirmationState {
47
+ const key = stateKey(basePath);
48
+ let state = statesByBasePath.get(key);
49
+ if (!state) {
50
+ state = { pendingCommand: null, confirmedCommand: null };
51
+ statesByBasePath.set(key, state);
52
+ }
53
+ return state;
54
+ }
55
+
56
+ /**
57
+ * Normalize a command for stable matching across block → confirm → retry.
58
+ * Trims surrounding whitespace and collapses internal runs of whitespace so
59
+ * cosmetic reformatting of the same command still matches the token.
60
+ */
61
+ export function normalizeDestructiveCommand(command: string): string {
62
+ return command.replace(/\s+/g, " ").trim();
63
+ }
64
+
65
+ /**
66
+ * Whether an ask_user_questions question id is a destructive-confirm gate.
67
+ */
68
+ export function isDestructiveConfirmGateId(questionId: unknown): boolean {
69
+ return typeof questionId === "string" && questionId.includes(DESTRUCTIVE_CONFIRM_GATE_MARKER);
70
+ }
71
+
72
+ /**
73
+ * Record that a destructive command was blocked and is awaiting confirmation.
74
+ * Called by the guard at block time. Overwrites any prior pending command —
75
+ * only the most recently blocked command can be confirmed.
76
+ */
77
+ export function requestDestructiveConfirmation(
78
+ command: string,
79
+ basePath: string = process.cwd(),
80
+ ): void {
81
+ const state = getState(basePath);
82
+ state.pendingCommand = normalizeDestructiveCommand(command);
83
+ // A fresh request invalidates any stale confirmed token for a different
84
+ // command so confirmation cannot leak across distinct destructive actions.
85
+ state.confirmedCommand = null;
86
+ }
87
+
88
+ /**
89
+ * Promote the pending command to a confirmed, one-shot token. Called by the
90
+ * tool_result handler when the user gives an affirmative answer to a
91
+ * destructive-confirm gate. Returns the confirmed command, or null if there
92
+ * was nothing pending (e.g. confirmation arrived without a preceding block).
93
+ */
94
+ export function confirmDestructiveCommand(
95
+ basePath: string = process.cwd(),
96
+ ): string | null {
97
+ const state = getState(basePath);
98
+ if (!state.pendingCommand) return null;
99
+ state.confirmedCommand = state.pendingCommand;
100
+ state.pendingCommand = null;
101
+ return state.confirmedCommand;
102
+ }
103
+
104
+ /**
105
+ * Check whether the given command has been confirmed, consuming the token if
106
+ * so. Returns true exactly once per confirmation; subsequent calls (or a
107
+ * non-matching command) return false. Called by the guard before blocking.
108
+ */
109
+ export function consumeDestructiveConfirmation(
110
+ command: string,
111
+ basePath: string = process.cwd(),
112
+ ): boolean {
113
+ const state = getState(basePath);
114
+ if (!state.confirmedCommand) return false;
115
+ if (state.confirmedCommand !== normalizeDestructiveCommand(command)) return false;
116
+ state.confirmedCommand = null;
117
+ return true;
118
+ }
119
+
120
+ /**
121
+ * Inspect the pending command without consuming it (diagnostics/tests).
122
+ */
123
+ export function peekPendingDestructiveCommand(
124
+ basePath: string = process.cwd(),
125
+ ): string | null {
126
+ return getState(basePath).pendingCommand;
127
+ }
128
+
129
+ /**
130
+ * Clear all destructive-confirmation state for a basePath (tests / flow reset).
131
+ */
132
+ export function resetDestructiveConfirmation(basePath: string = process.cwd()): void {
133
+ statesByBasePath.delete(stateKey(basePath));
134
+ }
@@ -57,9 +57,10 @@ const EXECUTION_TOOL_NAMES = new Set([
57
57
  "functions.exec_command",
58
58
  "gsd_exec",
59
59
  "gsd_exec_search",
60
+ "gsd_uat_exec",
60
61
  "powershell",
61
62
  ]);
62
- const MCP_EXECUTION_TOOL_RE = /^mcp__.+__gsd_exec(?:_search)?$/;
63
+ const MCP_EXECUTION_TOOL_RE = /^mcp__.+__gsd_(?:uat_)?exec(?:_search)?$/;
63
64
 
64
65
  // ─── Module State ───────────────────────────────────────────────────────────
65
66
 
@@ -206,11 +207,17 @@ export function clearEvidenceFromDisk(
206
207
  * Exit codes and output are filled in by recordToolResult after execution.
207
208
  */
208
209
  export function recordToolCall(toolCallId: string, toolName: string, input: Record<string, unknown>): void {
210
+ // Idempotent by toolCallId: native tools reach this via both
211
+ // tool_execution_start and tool_call; external (pre-executed) tools only
212
+ // via tool_execution_start. First recording wins.
213
+ if (unitEvidence.some(e => e.toolCallId === toolCallId)) return;
209
214
  if (isExecutionToolName(toolName)) {
210
215
  unitEvidence.push({
211
216
  kind: "bash",
212
217
  toolCallId,
213
- command: String(input.command ?? input.cmd ?? input.query ?? ""),
218
+ // gsd_exec / gsd_uat_exec carry the script body in `script` (or `code`);
219
+ // bash-style tools use `command`/`cmd`; gsd_exec_search uses `query`.
220
+ command: String(input.command ?? input.script ?? input.cmd ?? input.code ?? input.query ?? ""),
214
221
  exitCode: -1,
215
222
  outputSnippet: "",
216
223
  timestamp: Date.now(),
@@ -249,11 +256,36 @@ export function recordToolResult(
249
256
  if (entry.kind === "bash") {
250
257
  const text = extractResultText(result);
251
258
  entry.outputSnippet = text.slice(0, 500);
252
- const exitMatch = text.match(/Command exited with code (\d+)/);
253
- entry.exitCode = exitMatch ? Number(exitMatch[1]) : (isError ? 1 : 0);
259
+ entry.exitCode = resolveExitCode(text, isError);
254
260
  }
255
261
  }
256
262
 
263
+ /**
264
+ * Resolve the exit code from a tool result's text. Handles the bash tool's
265
+ * prose marker, the gsd_exec / gsd_uat_exec JSON envelope (`"exit_code": N`),
266
+ * and a last-resort read of the run's persisted `.gsd/exec/<id>.meta.json`
267
+ * (covers truncated result text).
268
+ */
269
+ function resolveExitCode(text: string, isError: boolean): number {
270
+ const proseMatch = text.match(/Command exited with code (\d+)/);
271
+ if (proseMatch) return Number(proseMatch[1]);
272
+
273
+ const jsonMatch = text.match(/"exit_code"\s*:\s*(-?\d+)/);
274
+ if (jsonMatch) return Number(jsonMatch[1]);
275
+
276
+ const metaMatch = text.match(/"meta_path"\s*:\s*"([^"]+)"/);
277
+ if (metaMatch) {
278
+ try {
279
+ const meta = JSON.parse(readFileSync(metaMatch[1], "utf-8")) as Record<string, unknown>;
280
+ if (typeof meta.exit_code === "number") return meta.exit_code;
281
+ } catch {
282
+ // Fall through to the isError heuristic
283
+ }
284
+ }
285
+
286
+ return isError ? 1 : 0;
287
+ }
288
+
257
289
  // ─── Internals ──────────────────────────────────────────────────────────────
258
290
 
259
291
  function extractResultText(result: unknown): string {
@@ -121,9 +121,14 @@ function findMatches(
121
121
  const exact = bashCalls.filter(b => b.command.trim() === normalized);
122
122
  if (exact.length > 0) return exact;
123
123
 
124
- // Substring match: claimed is contained in actual or actual in claimed
124
+ // Substring match: claimed is contained in actual or actual in claimed.
125
+ // A claimed verification command typically appears verbatim inside a
126
+ // larger gsd_exec script body (cd prefix, multi-line scripts), so
127
+ // script-containing-claim is the common direction. Blank-command entries
128
+ // must be excluded — `"x".includes("")` is true, so they'd match anything.
125
129
  const substring = bashCalls.filter(
126
- b => b.command.includes(normalized) || normalized.includes(b.command),
130
+ b => b.command.trim().length > 0 &&
131
+ (b.command.includes(normalized) || normalized.includes(b.command)),
127
132
  );
128
133
  if (substring.length > 0) return substring;
129
134
 
@@ -39,6 +39,20 @@ export interface FileChangeAudit {
39
39
 
40
40
  // ─── Public API ─────────────────────────────────────────────────────────────
41
41
 
42
+ /**
43
+ * Build the effective allowlist for a unit's file-change audit.
44
+ *
45
+ * When GSD manages .gitignore (manage_gitignore unset or true), ensureGitignore()
46
+ * appends baseline patterns at auto-start and the edit rides into the task's
47
+ * auto-commit — so .gitignore changes must not be attributed to the task.
48
+ */
49
+ export function effectiveFileChangeAllowlist(
50
+ baseAllowlist: string[],
51
+ manageGitignore: boolean | undefined,
52
+ ): string[] {
53
+ return manageGitignore === false ? baseAllowlist : [...baseAllowlist, ".gitignore"];
54
+ }
55
+
42
56
  /**
43
57
  * Validate file changes after auto-commit for an execute-task unit.
44
58
  * Returns null if task data is unavailable or DB is not loaded.