@opengsd/gsd-pi 1.2.0-dev.955e4da0 → 1.2.0-dev.9ad8ae33

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 (575) hide show
  1. package/dist/cli-style.d.ts +17 -0
  2. package/dist/cli-style.js +28 -0
  3. package/dist/cli.js +1 -1
  4. package/dist/headless-events.d.ts +4 -2
  5. package/dist/headless-events.js +14 -34
  6. package/dist/mcp-server.js +2 -1
  7. package/dist/models-resolver.d.ts +3 -13
  8. package/dist/models-resolver.js +3 -22
  9. package/dist/resource-loader.d.ts +10 -5
  10. package/dist/resource-loader.js +123 -20
  11. package/dist/resources/.managed-resources-content-hash +1 -1
  12. package/dist/resources/GSD-WORKFLOW.md +5 -4
  13. package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
  14. package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
  15. package/dist/resources/extensions/async-jobs/index.js +65 -0
  16. package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
  17. package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
  18. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
  19. package/dist/resources/extensions/bg-shell/overlay.js +9 -6
  20. package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
  21. package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
  22. package/dist/resources/extensions/bg-shell/utilities.js +3 -0
  23. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
  24. package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
  25. package/dist/resources/extensions/browser-tools/index.js +69 -12
  26. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +30 -4
  27. package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
  28. package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
  29. package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
  30. package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
  31. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  32. package/dist/resources/extensions/gsd/auto/orchestrator.js +89 -54
  33. package/dist/resources/extensions/gsd/auto/phases.js +49 -6
  34. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  35. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
  36. package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
  37. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
  38. package/dist/resources/extensions/gsd/auto-post-unit.js +35 -8
  39. package/dist/resources/extensions/gsd/auto-prompts.js +81 -19
  40. package/dist/resources/extensions/gsd/auto-start.js +41 -18
  41. package/dist/resources/extensions/gsd/auto-tool-tracking.js +18 -0
  42. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  43. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +12 -20
  44. package/dist/resources/extensions/gsd/auto-verification.js +23 -30
  45. package/dist/resources/extensions/gsd/auto-worktree.js +44 -91
  46. package/dist/resources/extensions/gsd/auto.js +41 -14
  47. package/dist/resources/extensions/gsd/blocked-models.js +28 -0
  48. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +29 -8
  49. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +23 -6
  50. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
  51. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
  52. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +212 -48
  53. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +303 -77
  54. package/dist/resources/extensions/gsd/branch-patterns.js +2 -0
  55. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  56. package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
  57. package/dist/resources/extensions/gsd/captures.js +4 -6
  58. package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
  59. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  60. package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
  61. package/dist/resources/extensions/gsd/consent-question.js +353 -0
  62. package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
  63. package/dist/resources/extensions/gsd/constants.js +0 -2
  64. package/dist/resources/extensions/gsd/crash-recovery.js +12 -15
  65. package/dist/resources/extensions/gsd/db/queries.js +26 -0
  66. package/dist/resources/extensions/gsd/db-writer.js +8 -17
  67. package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
  68. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  69. package/dist/resources/extensions/gsd/doctor-environment.js +2 -6
  70. package/dist/resources/extensions/gsd/doctor-format.js +9 -6
  71. package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
  72. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +13 -15
  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/gsd-command-home.js +22 -12
  78. package/dist/resources/extensions/gsd/gsd-db.js +2 -1
  79. package/dist/resources/extensions/gsd/guidance.js +158 -0
  80. package/dist/resources/extensions/gsd/guided-flow.js +23 -5
  81. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
  82. package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
  83. package/dist/resources/extensions/gsd/mcp-tool-name.js +5 -13
  84. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +1 -1
  85. package/dist/resources/extensions/gsd/migrate/safety.js +4 -1
  86. package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
  87. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
  88. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  89. package/dist/resources/extensions/gsd/notification-store.js +11 -4
  90. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +6 -4
  91. package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
  92. package/dist/resources/extensions/gsd/paths.js +27 -0
  93. package/dist/resources/extensions/gsd/pre-execution-checks.js +91 -3
  94. package/dist/resources/extensions/gsd/preferences-models.js +14 -48
  95. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  96. package/dist/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  97. package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
  98. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  99. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -2
  100. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  101. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  102. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  103. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  104. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  105. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  106. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  107. package/dist/resources/extensions/gsd/prompts/run-uat.md +7 -5
  108. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  109. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  110. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  111. package/dist/resources/extensions/gsd/provider-error-guidance.js +1 -5
  112. package/dist/resources/extensions/gsd/provider-switch-observer.js +1 -1
  113. package/dist/resources/extensions/gsd/publication.js +87 -0
  114. package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
  115. package/dist/resources/extensions/gsd/recovery-classification.js +37 -94
  116. package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
  117. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  118. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  119. package/dist/resources/extensions/gsd/state.js +6 -20
  120. package/dist/resources/extensions/gsd/stop-notice.js +57 -0
  121. package/dist/resources/extensions/gsd/tool-contract.js +14 -3
  122. package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
  123. package/dist/resources/extensions/gsd/tool-surface-readiness.js +56 -0
  124. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  125. package/dist/resources/extensions/gsd/tools/complete-slice.js +22 -12
  126. package/dist/resources/extensions/gsd/tools/complete-task.js +3 -2
  127. package/dist/resources/extensions/gsd/tools/exec-tool.js +9 -7
  128. package/dist/resources/extensions/gsd/tools/plan-slice.js +14 -8
  129. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  130. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
  131. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  132. package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
  133. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  134. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  135. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
  136. package/dist/resources/extensions/gsd/uat-policy.js +42 -16
  137. package/dist/resources/extensions/gsd/unit-closeout.js +138 -0
  138. package/dist/resources/extensions/gsd/unit-context-composer.js +74 -1
  139. package/dist/resources/extensions/gsd/unit-context-manifest.js +4 -27
  140. package/dist/resources/extensions/gsd/unit-registry.js +337 -0
  141. package/dist/resources/extensions/gsd/unit-tool-contracts.js +9 -182
  142. package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
  143. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  144. package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
  145. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  146. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  147. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  148. package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
  149. package/dist/resources/extensions/gsd/workflow-tool-surface.js +1 -1
  150. package/dist/resources/extensions/gsd/worktree-git-recovery.js +15 -9
  151. package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
  152. package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
  153. package/dist/resources/extensions/gsd/worktree-root.js +11 -0
  154. package/dist/resources/extensions/gsd/worktree-session-state.js +4 -5
  155. package/dist/resources/extensions/gsd/worktree.js +8 -1
  156. package/dist/resources/extensions/search-the-web/native-search.js +5 -3
  157. package/dist/resources/extensions/shared/browser-contract.js +59 -0
  158. package/dist/resources/extensions/shared/gsd-browser-cli.js +116 -6
  159. package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
  160. package/dist/resources/shared/package-manager-detection.js +1 -1
  161. package/dist/resources/shared/package.json +3 -0
  162. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  163. package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
  164. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  165. package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
  166. package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
  167. package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
  168. package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  169. package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  170. package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  171. package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
  172. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  173. package/dist/update-check.d.ts +2 -0
  174. package/dist/update-check.js +24 -1
  175. package/dist/update-cmd.js +20 -3
  176. package/dist/web/standalone/.next/BUILD_ID +1 -1
  177. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  178. package/dist/web/standalone/.next/build-manifest.json +3 -3
  179. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  180. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  181. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  182. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  183. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  184. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  185. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  186. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  187. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  188. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  189. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  190. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  191. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  192. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  193. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  194. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  195. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  196. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  197. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  199. package/dist/web/standalone/.next/server/app/index.html +1 -1
  200. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  201. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  202. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  203. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  204. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  205. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  206. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  207. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  208. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  209. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  212. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  213. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  214. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  215. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  216. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  217. package/dist/web/standalone/package.json +1 -1
  218. package/dist/worktree-cli.js +3 -6
  219. package/dist/worktree-status-banner.js +7 -15
  220. package/package.json +2 -2
  221. package/packages/cloud-mcp-gateway/package.json +2 -2
  222. package/packages/contracts/dist/rpc.d.ts +1 -0
  223. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  224. package/packages/contracts/dist/rpc.js.map +1 -1
  225. package/packages/contracts/dist/workflow.d.ts +4 -0
  226. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  227. package/packages/contracts/dist/workflow.js.map +1 -1
  228. package/packages/contracts/package.json +1 -1
  229. package/packages/daemon/package.json +4 -4
  230. package/packages/gsd-agent-core/package.json +5 -5
  231. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
  232. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  233. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
  234. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  235. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  236. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
  237. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  238. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  239. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  240. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  241. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  242. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  243. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  244. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  245. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  246. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  247. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  248. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  249. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  250. package/packages/gsd-agent-modes/package.json +7 -7
  251. package/packages/mcp-server/dist/cli.js +9 -1
  252. package/packages/mcp-server/dist/cli.js.map +1 -1
  253. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
  254. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
  255. package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
  256. package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
  257. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  258. package/packages/mcp-server/dist/server.js +4 -0
  259. package/packages/mcp-server/dist/server.js.map +1 -1
  260. package/packages/mcp-server/dist/workflow-tools.d.ts +26 -18
  261. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  262. package/packages/mcp-server/dist/workflow-tools.js +116 -39
  263. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  264. package/packages/mcp-server/package.json +5 -4
  265. package/packages/native/package.json +1 -1
  266. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  267. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  268. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  269. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  270. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  271. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  272. package/packages/pi-agent-core/dist/index.js +3 -0
  273. package/packages/pi-agent-core/dist/index.js.map +1 -1
  274. package/packages/pi-agent-core/package.json +1 -1
  275. package/packages/pi-ai/README.md +1 -0
  276. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  277. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  278. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  279. package/packages/pi-ai/dist/index.d.ts +2 -0
  280. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  281. package/packages/pi-ai/dist/index.js +2 -0
  282. package/packages/pi-ai/dist/index.js.map +1 -1
  283. package/packages/pi-ai/dist/models.generated.d.ts +35 -125
  284. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  285. package/packages/pi-ai/dist/models.generated.js +46 -120
  286. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  287. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  288. package/packages/pi-ai/dist/providers/anthropic.js +12 -7
  289. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  290. package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
  291. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  292. package/packages/pi-ai/dist/providers/google-shared.js +12 -3
  293. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  294. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  295. package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
  296. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  297. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
  298. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
  299. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
  300. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
  301. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  302. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
  303. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  304. package/packages/pi-ai/package.json +3 -2
  305. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  306. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  307. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  308. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  309. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  310. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  311. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  313. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  314. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  315. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  316. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  317. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  318. package/packages/pi-coding-agent/dist/index.js +1 -1
  319. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  321. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  322. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  323. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  324. package/packages/pi-coding-agent/package.json +7 -7
  325. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  326. package/packages/pi-tui/dist/tui.js +9 -0
  327. package/packages/pi-tui/dist/tui.js.map +1 -1
  328. package/packages/pi-tui/package.json +2 -2
  329. package/packages/rpc-client/package.json +2 -2
  330. package/pkg/package.json +1 -1
  331. package/src/resources/GSD-WORKFLOW.md +5 -4
  332. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  333. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  334. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  335. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  336. package/src/resources/extensions/async-jobs/index.ts +79 -0
  337. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  338. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  339. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  340. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  341. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  342. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  343. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  344. package/src/resources/extensions/bg-shell/utilities.ts +3 -0
  345. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
  346. package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
  347. package/src/resources/extensions/browser-tools/index.ts +71 -13
  348. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
  349. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
  350. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
  351. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +34 -4
  352. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
  353. package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
  354. package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
  355. package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
  356. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  357. package/src/resources/extensions/gsd/auto/orchestrator.ts +98 -56
  358. package/src/resources/extensions/gsd/auto/phases.ts +65 -26
  359. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  360. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
  361. package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
  362. package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
  363. package/src/resources/extensions/gsd/auto-post-unit.ts +40 -8
  364. package/src/resources/extensions/gsd/auto-prompts.ts +118 -35
  365. package/src/resources/extensions/gsd/auto-start.ts +42 -21
  366. package/src/resources/extensions/gsd/auto-tool-tracking.ts +19 -0
  367. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  368. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +14 -21
  369. package/src/resources/extensions/gsd/auto-verification.ts +26 -28
  370. package/src/resources/extensions/gsd/auto-worktree.ts +44 -94
  371. package/src/resources/extensions/gsd/auto.ts +52 -16
  372. package/src/resources/extensions/gsd/blocked-models.ts +49 -0
  373. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +37 -10
  374. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +23 -6
  375. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
  376. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
  377. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +251 -47
  378. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +352 -84
  379. package/src/resources/extensions/gsd/branch-patterns.ts +3 -0
  380. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  381. package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
  382. package/src/resources/extensions/gsd/captures.ts +4 -6
  383. package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
  384. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  385. package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
  386. package/src/resources/extensions/gsd/consent-question.ts +431 -0
  387. package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
  388. package/src/resources/extensions/gsd/constants.ts +0 -3
  389. package/src/resources/extensions/gsd/crash-recovery.ts +13 -11
  390. package/src/resources/extensions/gsd/db/queries.ts +37 -0
  391. package/src/resources/extensions/gsd/db-writer.ts +11 -19
  392. package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
  393. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  394. package/src/resources/extensions/gsd/doctor-environment.ts +2 -7
  395. package/src/resources/extensions/gsd/doctor-format.ts +12 -7
  396. package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
  397. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +13 -15
  398. package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
  399. package/src/resources/extensions/gsd/error-classifier.ts +11 -0
  400. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  401. package/src/resources/extensions/gsd/files.ts +33 -12
  402. package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
  403. package/src/resources/extensions/gsd/gsd-db.ts +4 -3
  404. package/src/resources/extensions/gsd/guidance.ts +217 -0
  405. package/src/resources/extensions/gsd/guided-flow.ts +37 -28
  406. package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
  407. package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
  408. package/src/resources/extensions/gsd/mcp-tool-name.ts +6 -11
  409. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +1 -1
  410. package/src/resources/extensions/gsd/migrate/safety.ts +4 -1
  411. package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
  412. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
  413. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  414. package/src/resources/extensions/gsd/notification-store.ts +26 -3
  415. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -4
  416. package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
  417. package/src/resources/extensions/gsd/paths.ts +33 -0
  418. package/src/resources/extensions/gsd/pre-execution-checks.ts +109 -3
  419. package/src/resources/extensions/gsd/preferences-models.ts +12 -47
  420. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  421. package/src/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  422. package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
  423. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  424. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -2
  425. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  426. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  427. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  428. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  429. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  430. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  431. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  432. package/src/resources/extensions/gsd/prompts/run-uat.md +7 -5
  433. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  434. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  435. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  436. package/src/resources/extensions/gsd/provider-error-guidance.ts +4 -9
  437. package/src/resources/extensions/gsd/provider-switch-observer.ts +1 -1
  438. package/src/resources/extensions/gsd/publication.ts +122 -0
  439. package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
  440. package/src/resources/extensions/gsd/recovery-classification.ts +42 -96
  441. package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
  442. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  443. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  444. package/src/resources/extensions/gsd/state.ts +9 -21
  445. package/src/resources/extensions/gsd/stop-notice.ts +75 -0
  446. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
  447. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +198 -26
  448. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  449. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +236 -0
  450. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
  451. package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
  452. package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
  453. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  454. package/src/resources/extensions/gsd/tests/checkout-branch-stash-guard.test.ts +66 -1
  455. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -0
  456. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +8 -7
  457. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  458. package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
  459. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
  460. package/src/resources/extensions/gsd/tests/db-writer.test.ts +15 -4
  461. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
  462. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  463. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  464. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
  465. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
  466. package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
  467. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  468. package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
  469. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  470. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  471. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
  472. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
  473. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
  474. package/src/resources/extensions/gsd/tests/guidance.test.ts +148 -0
  475. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +2 -6
  476. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +53 -11
  477. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +73 -58
  478. package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
  479. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
  480. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  481. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
  482. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  483. package/src/resources/extensions/gsd/tests/notification-store.test.ts +32 -0
  484. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  485. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
  486. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +138 -0
  487. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  488. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  489. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +193 -1
  490. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
  491. package/src/resources/extensions/gsd/tests/provider-error-guidance.test.ts +3 -3
  492. package/src/resources/extensions/gsd/tests/publication.test.ts +120 -0
  493. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +157 -0
  494. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  495. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -1
  496. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +70 -0
  497. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  498. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
  499. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +8 -0
  500. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +155 -0
  501. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  502. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  503. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
  504. package/src/resources/extensions/gsd/tests/unit-closeout.test.ts +209 -0
  505. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +67 -2
  506. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +163 -0
  507. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  508. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  509. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
  510. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  511. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
  512. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  513. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +275 -40
  514. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
  515. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  516. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
  517. package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
  518. package/src/resources/extensions/gsd/tool-contract.ts +38 -3
  519. package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
  520. package/src/resources/extensions/gsd/tool-surface-readiness.ts +76 -0
  521. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  522. package/src/resources/extensions/gsd/tools/complete-slice.ts +22 -12
  523. package/src/resources/extensions/gsd/tools/complete-task.ts +3 -2
  524. package/src/resources/extensions/gsd/tools/exec-tool.ts +8 -7
  525. package/src/resources/extensions/gsd/tools/plan-slice.ts +14 -8
  526. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  527. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
  528. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  529. package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
  530. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  531. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  532. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
  533. package/src/resources/extensions/gsd/uat-policy.ts +62 -16
  534. package/src/resources/extensions/gsd/unit-closeout.ts +201 -0
  535. package/src/resources/extensions/gsd/unit-context-composer.ts +111 -1
  536. package/src/resources/extensions/gsd/unit-context-manifest.ts +4 -28
  537. package/src/resources/extensions/gsd/unit-registry.ts +412 -0
  538. package/src/resources/extensions/gsd/unit-tool-contracts.ts +27 -192
  539. package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
  540. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  541. package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
  542. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  543. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  544. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  545. package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
  546. package/src/resources/extensions/gsd/workflow-tool-surface.ts +4 -1
  547. package/src/resources/extensions/gsd/worktree-git-recovery.ts +15 -9
  548. package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
  549. package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
  550. package/src/resources/extensions/gsd/worktree-root.ts +12 -0
  551. package/src/resources/extensions/gsd/worktree-session-state.ts +3 -5
  552. package/src/resources/extensions/gsd/worktree.ts +7 -1
  553. package/src/resources/extensions/search-the-web/native-search.ts +5 -3
  554. package/src/resources/extensions/shared/browser-contract.ts +66 -0
  555. package/src/resources/extensions/shared/gsd-browser-cli.ts +141 -6
  556. package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
  557. package/src/resources/shared/package-manager-detection.ts +1 -1
  558. package/src/resources/shared/package.json +3 -0
  559. package/src/resources/skills/create-skill/SKILL.md +3 -0
  560. package/src/resources/skills/create-skill/references/executable-code.md +1 -1
  561. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  562. package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
  563. package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
  564. package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
  565. package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  566. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  567. package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  568. package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
  569. package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
  570. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  571. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
  572. package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
  573. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  574. /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → FBNo5cT_chy7YNoAQsU3o}/_buildManifest.js +0 -0
  575. /package/dist/web/standalone/.next/static/{C24pqUd-aru-l0Dp0gLZP → FBNo5cT_chy7YNoAQsU3o}/_ssgManifest.js +0 -0
@@ -118,6 +118,51 @@ function makeRepoWithMultipleStrandedMilestones(): string {
118
118
  return base;
119
119
  }
120
120
 
121
+ function makeRepoWithOnlySiblingStrandedAndLockedActive(): string {
122
+ // Locked milestone (M002) is the active row but has NO stranded
123
+ // milestone branch. A sibling milestone (M001) has a stranded branch.
124
+ // A parallel worker locked to M002 must skip the sibling's stranded
125
+ // action entirely — neither block on it nor adopt it.
126
+ const base = mkdtempSync(join(tmpdir(), "gsd-locked-no-stranded-bootstrap-"));
127
+ mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
128
+ mkdirSync(join(base, ".gsd", "milestones", "M002"), { recursive: true });
129
+ // M002 has CONTEXT so bootstrap's pre-planning gate doesn't route to
130
+ // showSmartEntry and the test reaches the post-lock session-init path.
131
+ writeFileSync(
132
+ join(base, ".gsd", "milestones", "M002", "M002-CONTEXT.md"),
133
+ "# M002 context\n",
134
+ );
135
+ writeFileSync(
136
+ join(base, ".gsd", "PREFERENCES.md"),
137
+ "---\ngit:\n isolation: \"none\"\n---\n",
138
+ );
139
+ runGit(base, ["init"]);
140
+ runGit(base, ["config", "user.email", "test@test.com"]);
141
+ runGit(base, ["config", "user.name", "Test"]);
142
+ writeFileSync(join(base, "README.md"), "# test\n");
143
+ runGit(base, ["add", "-A"]);
144
+ runGit(base, ["commit", "-m", "init"]);
145
+ runGit(base, ["branch", "-M", "main"]);
146
+
147
+ // Sibling M001 has stranded work on milestone/M001.
148
+ runGit(base, ["checkout", "-b", "milestone/M001"]);
149
+ writeFileSync(join(base, "m001.txt"), "sibling stranded work\n");
150
+ runGit(base, ["add", "-A"]);
151
+ runGit(base, ["commit", "-m", "feat: M001 in progress"]);
152
+ runGit(base, ["checkout", "main"]);
153
+
154
+ // M002 has no stranded branch at all.
155
+ openDatabase(join(base, ".gsd", "gsd.db"));
156
+ // Both milestones are open so the stranded audit produces a blocking
157
+ // action for the sibling (M001). M002 is the lock target and active
158
+ // row; getActiveMilestoneId honors the lock regardless of M001 order.
159
+ insertMilestone({ id: "M001", title: "Sibling milestone", status: "pending" });
160
+ insertMilestone({ id: "M002", title: "Locked milestone", status: "active" });
161
+ closeDatabase();
162
+
163
+ return base;
164
+ }
165
+
121
166
  function makeRepoWithActiveMismatchAndStrandedTarget(): string {
122
167
  const base = mkdtempSync(join(tmpdir(), "gsd-targeted-stranded-bootstrap-"));
123
168
  mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
@@ -455,6 +500,197 @@ test("bootstrap blocks active stranded recovery when another open milestone also
455
500
  }
456
501
  });
457
502
 
503
+ test("parallel worker recovers its locked stranded milestone despite stranded siblings", async () => {
504
+ const base = makeRepoWithMultipleStrandedMilestones();
505
+ const previousCwd = process.cwd();
506
+ const previousLock = process.env.GSD_MILESTONE_LOCK;
507
+ const previousWorker = process.env.GSD_PARALLEL_WORKER;
508
+ const s = new AutoSession();
509
+ const adoptCalls: Array<{ milestoneId: string; mode: string }> = [];
510
+ const notifications: Array<{ message: string; level?: string }> = [];
511
+
512
+ try {
513
+ process.env.GSD_PARALLEL_WORKER = "1";
514
+ process.env.GSD_MILESTONE_LOCK = "M002";
515
+
516
+ const ready = await bootstrapAutoSession(
517
+ s,
518
+ makeCtx(notifications) as any,
519
+ {
520
+ getThinkingLevel: () => "medium",
521
+ getActiveTools: () => [],
522
+ events: { emit: () => {} },
523
+ } as any,
524
+ base,
525
+ false,
526
+ false,
527
+ {
528
+ shouldUseWorktreeIsolation: () => false,
529
+ registerSigtermHandler: () => {},
530
+ registerAutoWorkerForSession: () => {},
531
+ lockBase: () => base,
532
+ buildLifecycle: () => ({
533
+ adoptSessionRoot: (sessionBase: string, originalBase?: string) => {
534
+ s.basePath = sessionBase;
535
+ if (originalBase !== undefined) {
536
+ s.originalBasePath = originalBase;
537
+ } else if (!s.originalBasePath) {
538
+ s.originalBasePath = sessionBase;
539
+ }
540
+ },
541
+ enterMilestone: () => ({ ok: true, mode: "none", path: base }),
542
+ adoptStrandedMilestone: (
543
+ milestoneId: string,
544
+ sessionBase: string,
545
+ _ctx: unknown,
546
+ opts: { mode: "worktree" | "branch" },
547
+ ) => {
548
+ adoptCalls.push({ milestoneId, mode: opts.mode });
549
+ s.basePath = sessionBase;
550
+ s.originalBasePath = sessionBase;
551
+ s.strandedRecoveryIsolationMode = opts.mode;
552
+ return { ok: true, mode: opts.mode, path: sessionBase };
553
+ },
554
+ adoptOrphanWorktree: <T extends { merged: boolean }>(
555
+ _mid: string,
556
+ _base: string,
557
+ run: () => T,
558
+ ): T => run(),
559
+ }) as any,
560
+ },
561
+ {
562
+ classification: "none",
563
+ lock: null,
564
+ pausedSession: null,
565
+ state: null,
566
+ recovery: null,
567
+ recoveryPrompt: null,
568
+ recoveryToolCallCount: 0,
569
+ artifactSatisfied: false,
570
+ hasResumableDiskState: false,
571
+ isBootstrapCrash: false,
572
+ },
573
+ );
574
+
575
+ const messages = notifications.map((entry) => entry.message).join("\n");
576
+ assert.equal(ready, true);
577
+ assert.deepEqual(adoptCalls, [{ milestoneId: "M002", mode: "branch" }]);
578
+ assert.equal(s.currentMilestoneId, "M002");
579
+ assert.match(messages, /Resuming saved milestone work for M002/);
580
+ assert.doesNotMatch(messages, /blocks auto-mode before M002/);
581
+ assert.doesNotMatch(messages, /\/gsd auto M001/);
582
+ } finally {
583
+ if (previousLock === undefined) delete process.env.GSD_MILESTONE_LOCK;
584
+ else process.env.GSD_MILESTONE_LOCK = previousLock;
585
+ if (previousWorker === undefined) delete process.env.GSD_PARALLEL_WORKER;
586
+ else process.env.GSD_PARALLEL_WORKER = previousWorker;
587
+ try {
588
+ closeDatabase();
589
+ } catch {}
590
+ process.chdir(previousCwd);
591
+ rmSync(base, { recursive: true, force: true });
592
+ }
593
+ });
594
+
595
+ test("locked worker with no own stranded action does not adopt sibling stranded action", async () => {
596
+ const base = makeRepoWithOnlySiblingStrandedAndLockedActive();
597
+ const previousCwd = process.cwd();
598
+ const previousLock = process.env.GSD_MILESTONE_LOCK;
599
+ const previousWorker = process.env.GSD_PARALLEL_WORKER;
600
+ const s = new AutoSession();
601
+ const adoptCalls: Array<{ milestoneId: string; mode: string }> = [];
602
+ const enterCalls: string[] = [];
603
+ const notifications: Array<{ message: string; level?: string }> = [];
604
+
605
+ try {
606
+ process.env.GSD_PARALLEL_WORKER = "1";
607
+ process.env.GSD_MILESTONE_LOCK = "M002";
608
+
609
+ const ready = await bootstrapAutoSession(
610
+ s,
611
+ makeCtx(notifications) as any,
612
+ {
613
+ getThinkingLevel: () => "medium",
614
+ getActiveTools: () => [],
615
+ events: { emit: () => {} },
616
+ } as any,
617
+ base,
618
+ false,
619
+ false,
620
+ {
621
+ shouldUseWorktreeIsolation: () => false,
622
+ registerSigtermHandler: () => {},
623
+ registerAutoWorkerForSession: () => {},
624
+ lockBase: () => base,
625
+ buildLifecycle: () => ({
626
+ adoptSessionRoot: (sessionBase: string, originalBase?: string) => {
627
+ s.basePath = sessionBase;
628
+ if (originalBase !== undefined) {
629
+ s.originalBasePath = originalBase;
630
+ } else if (!s.originalBasePath) {
631
+ s.originalBasePath = sessionBase;
632
+ }
633
+ },
634
+ enterMilestone: (mid: string) => {
635
+ enterCalls.push(mid);
636
+ return { ok: true, mode: "none", path: base };
637
+ },
638
+ adoptStrandedMilestone: (
639
+ milestoneId: string,
640
+ sessionBase: string,
641
+ _ctx: unknown,
642
+ opts: { mode: "worktree" | "branch" },
643
+ ) => {
644
+ adoptCalls.push({ milestoneId, mode: opts.mode });
645
+ s.basePath = sessionBase;
646
+ s.originalBasePath = sessionBase;
647
+ s.strandedRecoveryIsolationMode = opts.mode;
648
+ return { ok: true, mode: opts.mode, path: sessionBase };
649
+ },
650
+ adoptOrphanWorktree: <T extends { merged: boolean }>(
651
+ _mid: string,
652
+ _base: string,
653
+ run: () => T,
654
+ ): T => run(),
655
+ }) as any,
656
+ },
657
+ {
658
+ classification: "none",
659
+ lock: null,
660
+ pausedSession: null,
661
+ state: null,
662
+ recovery: null,
663
+ recoveryPrompt: null,
664
+ recoveryToolCallCount: 0,
665
+ artifactSatisfied: false,
666
+ hasResumableDiskState: false,
667
+ isBootstrapCrash: false,
668
+ },
669
+ );
670
+
671
+ const messages = notifications.map((entry) => entry.message).join("\n");
672
+ assert.equal(ready, true);
673
+ // Must not adopt M001 (the sibling stranded action) — the locked
674
+ // worker has no stranded action of its own, so adoption should not
675
+ // run at all. enterMilestone for M002 is also gated off by
676
+ // isolation=none with no stranded recoveryMode (#742 regression).
677
+ assert.deepEqual(adoptCalls, []);
678
+ assert.equal(s.currentMilestoneId, "M002");
679
+ assert.doesNotMatch(messages, /Resuming saved milestone work for M001/);
680
+ assert.doesNotMatch(messages, /blocks auto-mode before M002/);
681
+ } finally {
682
+ if (previousLock === undefined) delete process.env.GSD_MILESTONE_LOCK;
683
+ else process.env.GSD_MILESTONE_LOCK = previousLock;
684
+ if (previousWorker === undefined) delete process.env.GSD_PARALLEL_WORKER;
685
+ else process.env.GSD_PARALLEL_WORKER = previousWorker;
686
+ try {
687
+ closeDatabase();
688
+ } catch {}
689
+ process.chdir(previousCwd);
690
+ rmSync(base, { recursive: true, force: true });
691
+ }
692
+ });
693
+
458
694
  test("bootstrap honors explicit solo milestone lock when recovering stranded target worktree", async () => {
459
695
  const base = makeRepoWithActiveMismatchAndStrandedTarget();
460
696
  const previousCwd = process.cwd();
@@ -8,7 +8,10 @@ import { join } from "node:path";
8
8
 
9
9
  import {
10
10
  blockModel,
11
+ blockModelUntil,
12
+ clearTemporaryModelBlocksForTest,
11
13
  isModelBlocked,
14
+ isModelTemporarilyUnavailable,
12
15
  loadBlockedModels,
13
16
  } from "../blocked-models.ts";
14
17
 
@@ -96,3 +99,19 @@ test("blocked-models: file created under .gsd/runtime/", () => {
96
99
  rmSync(base, { recursive: true, force: true });
97
100
  }
98
101
  });
102
+
103
+ test("blocked-models: temporary rate-limit blocks expire without persisting", () => {
104
+ const base = mkBase();
105
+ try {
106
+ clearTemporaryModelBlocksForTest();
107
+ blockModelUntil(base, "openai-codex", "gpt-5.5", Date.now() + 60_000, "session limit");
108
+ assert.equal(isModelTemporarilyUnavailable(base, "openai-codex", "gpt-5.5"), true);
109
+ assert.equal(loadBlockedModels(base).length, 0, "rate-limit windows must not persist as account blocks");
110
+
111
+ blockModelUntil(base, "openai-codex", "gpt-5.5", Date.now() - 1, "expired");
112
+ assert.equal(isModelTemporarilyUnavailable(base, "openai-codex", "gpt-5.5"), false);
113
+ } finally {
114
+ clearTemporaryModelBlocksForTest();
115
+ rmSync(base, { recursive: true, force: true });
116
+ }
117
+ });
@@ -0,0 +1,39 @@
1
+ import assert from "node:assert/strict";
2
+
3
+ import {
4
+ getUatBrowserToolSupportError,
5
+ hasUatBrowserToolSurface,
6
+ type UatType,
7
+ } from "../uat-policy.ts";
8
+
9
+ export const BROWSER_AUTOMATION_CONTRACT_TOOLS = {
10
+ piProvider: ["read", "browser_navigate"],
11
+ externalMcpClient: ["read", "mcp__gsd-browser__browser_navigate"],
12
+ externalMcpWildcard: ["read", "mcp__gsd-browser__*"],
13
+ otherBrowserMcp: ["read", "mcp__browser-uat__*"],
14
+ workflowOnly: ["read", "mcp__gsd-workflow__*"],
15
+ withoutBrowser: ["read", "gsd_uat_exec"],
16
+ } as const;
17
+
18
+ export function assertBrowserAutomationContractAvailable(tools: readonly string[]): void {
19
+ assert.equal(hasUatBrowserToolSurface(tools), true, `${tools.join(", ")} should satisfy the Browser Automation Contract`);
20
+ }
21
+
22
+ export function assertBrowserAutomationContractMissing(tools: readonly string[] | undefined): void {
23
+ assert.equal(hasUatBrowserToolSurface(tools), false, `${tools?.join(", ") ?? "undefined"} should not satisfy the Browser Automation Contract`);
24
+ }
25
+
26
+ export function assertBrowserBackedUatCanDispatch(options: {
27
+ uatType: UatType;
28
+ activeTools: readonly string[] | undefined;
29
+ registeredTools?: readonly string[];
30
+ }): void {
31
+ assert.equal(
32
+ getUatBrowserToolSupportError({
33
+ ...options,
34
+ milestoneId: "M001",
35
+ sliceId: "S01",
36
+ }),
37
+ null,
38
+ );
39
+ }
@@ -0,0 +1,44 @@
1
+ import { describe, it } from "node:test";
2
+ import assert from "node:assert/strict";
3
+
4
+ import {
5
+ BROWSER_CONTRACT_TOOL_NAMES,
6
+ BROWSER_EVIDENCE_SIGNAL_TOOL_NAMES,
7
+ hasBrowserContractPrefix,
8
+ isBrowserContractToolName,
9
+ } from "../../shared/browser-contract.ts";
10
+ import { isUatBrowserToolName } from "../uat-policy.ts";
11
+ import { BROWSER_REQUIREMENT_RE, BROWSER_RUNTIME_RE } from "../browser-evidence.ts";
12
+
13
+ // Note: RUN_UAT_BROWSER_TOOL_NAMES and MANAGED_GSD_BROWSER_TOOL_NAMES are
14
+ // reference-equal aliases of BROWSER_CONTRACT_TOOL_NAMES, and the managed
15
+ // adapter's spec table is Record-keyed by BrowserContractToolName — both
16
+ // derivations are pinned by the type system, not by runtime assertions here.
17
+ describe("Browser Automation Contract parity", () => {
18
+ it("every contract name satisfies the UAT browser-tool predicate, bare and MCP-prefixed", () => {
19
+ for (const name of BROWSER_CONTRACT_TOOL_NAMES) {
20
+ assert.equal(isUatBrowserToolName(name), true, name);
21
+ assert.equal(isUatBrowserToolName(`mcp__gsd-browser__${name}`), true, `mcp__gsd-browser__${name}`);
22
+ }
23
+ });
24
+
25
+ it("contract names are canonical browser_* names with no duplicates", () => {
26
+ assert.equal(new Set(BROWSER_CONTRACT_TOOL_NAMES).size, BROWSER_CONTRACT_TOOL_NAMES.length);
27
+ for (const name of BROWSER_CONTRACT_TOOL_NAMES) {
28
+ assert.equal(hasBrowserContractPrefix(name), true, name);
29
+ assert.equal(isBrowserContractToolName(name), true, name);
30
+ }
31
+ assert.equal(isBrowserContractToolName("browser_not_a_real_tool"), false);
32
+ assert.equal(hasBrowserContractPrefix("gsd_uat_exec"), false);
33
+ });
34
+
35
+ it("evidence-signal names stay a subset of the contract and drive the detection regexes", () => {
36
+ for (const name of BROWSER_EVIDENCE_SIGNAL_TOOL_NAMES) {
37
+ assert.equal(isBrowserContractToolName(name), true, name);
38
+ // Identifier-shaped names keep the regex splice in browser-evidence.ts escape-free.
39
+ assert.match(name, /^browser_[a-z_]+$/);
40
+ assert.match(`Verified via ${name} call`, BROWSER_REQUIREMENT_RE);
41
+ assert.match(`Verified via ${name} call`, BROWSER_RUNTIME_RE);
42
+ }
43
+ });
44
+ });
@@ -0,0 +1,144 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+
4
+ import {
5
+ prepareBrowserDaemonForUat,
6
+ shouldWarmBrowserDaemonForUat,
7
+ } from "../browser-daemon-auto-prep.ts";
8
+ import { commitBrowserEngineResolution } from "../../browser-tools/engine/selection.ts";
9
+ import { resolveGsdBrowserCliAvailability } from "../../shared/gsd-browser-cli.ts";
10
+
11
+ const GSD_BROWSER_ENGINE = { GSD_BROWSER_ENGINE: "gsd-browser" } as const;
12
+
13
+ test("shouldWarmBrowserDaemonForUat skips artifact-driven UAT", () => {
14
+ assert.equal(
15
+ shouldWarmBrowserDaemonForUat({
16
+ uatType: "artifact-driven",
17
+ sessionProvider: "claude-code",
18
+ projectRoot: "/tmp/project",
19
+ }),
20
+ false,
21
+ );
22
+ });
23
+
24
+ test("shouldWarmBrowserDaemonForUat enables Claude Code browser UAT when gsd-browser is available", (t) => {
25
+ const availability = resolveGsdBrowserCliAvailability();
26
+ if (!availability.available) {
27
+ t.skip("bundled gsd-browser CLI unavailable");
28
+ }
29
+
30
+ assert.equal(
31
+ shouldWarmBrowserDaemonForUat({
32
+ uatType: "browser-executable",
33
+ sessionProvider: "claude-code",
34
+ sessionAuthMode: "externalCli",
35
+ projectRoot: "/tmp/project",
36
+ env: GSD_BROWSER_ENGINE,
37
+ }),
38
+ true,
39
+ );
40
+ });
41
+
42
+ test("shouldWarmBrowserDaemonForUat enables warm-up for Claude Code oauth/apiKey when engine is gsd-browser", (t) => {
43
+ const availability = resolveGsdBrowserCliAvailability();
44
+ if (!availability.available) {
45
+ t.skip("bundled gsd-browser CLI unavailable");
46
+ }
47
+
48
+ for (const sessionAuthMode of ["oauth", "apiKey"] as const) {
49
+ assert.equal(
50
+ shouldWarmBrowserDaemonForUat({
51
+ uatType: "browser-executable",
52
+ sessionProvider: "claude-code",
53
+ sessionAuthMode,
54
+ sessionBaseUrl: "https://api.anthropic.com",
55
+ projectRoot: "/tmp/project",
56
+ env: GSD_BROWSER_ENGINE,
57
+ }),
58
+ true,
59
+ `expected warm-up for sessionAuthMode=${sessionAuthMode}`,
60
+ );
61
+ }
62
+ });
63
+
64
+ test("shouldWarmBrowserDaemonForUat skips legacy Playwright engine for Claude Code", () => {
65
+ assert.equal(
66
+ shouldWarmBrowserDaemonForUat({
67
+ uatType: "browser-executable",
68
+ sessionProvider: "claude-code",
69
+ sessionAuthMode: "oauth",
70
+ projectRoot: "/tmp/project",
71
+ env: { GSD_BROWSER_ENGINE: "legacy" },
72
+ }),
73
+ false,
74
+ );
75
+ });
76
+
77
+ test("shouldWarmBrowserDaemonForUat uses session-committed ambient engine for non-Claude providers", () => {
78
+ const projectRoot = "/tmp/ambient-engine-project";
79
+ commitBrowserEngineResolution(projectRoot, {
80
+ engine: "legacy",
81
+ source: "probe",
82
+ reason: "gsd-browser daemon connect failed (test); using legacy Playwright",
83
+ });
84
+
85
+ assert.equal(
86
+ shouldWarmBrowserDaemonForUat({
87
+ uatType: "browser-executable",
88
+ sessionProvider: "openai",
89
+ projectRoot,
90
+ }),
91
+ false,
92
+ );
93
+ });
94
+
95
+ test("shouldWarmBrowserDaemonForUat skips when browser MCP is disabled", () => {
96
+ assert.equal(
97
+ shouldWarmBrowserDaemonForUat({
98
+ uatType: "browser-executable",
99
+ sessionProvider: "claude-code",
100
+ projectRoot: "/tmp/project",
101
+ env: { GSD_BROWSER_MCP_ENABLED: "0" },
102
+ }),
103
+ false,
104
+ );
105
+ });
106
+
107
+ test("shouldWarmBrowserDaemonForUat skips when warm-up is disabled", () => {
108
+ assert.equal(
109
+ shouldWarmBrowserDaemonForUat({
110
+ uatType: "browser-executable",
111
+ sessionProvider: "claude-code",
112
+ projectRoot: "/tmp/project",
113
+ env: { GSD_BROWSER_WARMUP: "0" },
114
+ }),
115
+ false,
116
+ );
117
+ });
118
+
119
+ test("prepareBrowserDaemonForUat returns null when warm-up is not required", () => {
120
+ assert.equal(
121
+ prepareBrowserDaemonForUat({
122
+ uatType: "artifact-driven",
123
+ sessionProvider: "claude-code",
124
+ sessionAuthMode: "externalCli",
125
+ projectRoot: "/tmp/example-project",
126
+ }),
127
+ null,
128
+ );
129
+ });
130
+
131
+ test("prepareBrowserDaemonForUat returns actionable error when daemon start fails", () => {
132
+ const error = prepareBrowserDaemonForUat({
133
+ uatType: "browser-executable",
134
+ sessionProvider: "claude-code",
135
+ sessionAuthMode: "externalCli",
136
+ projectRoot: "/tmp/example-project",
137
+ env: {
138
+ ...GSD_BROWSER_ENGINE,
139
+ GSD_BROWSER_MCP_COMMAND: "/definitely/missing/gsd-browser",
140
+ },
141
+ });
142
+
143
+ assert.match(error ?? "", /gsd-browser daemon failed to start/i);
144
+ });
@@ -5,7 +5,7 @@ import { mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSy
5
5
  import { join } from "node:path";
6
6
  import { tmpdir } from "node:os";
7
7
 
8
- import { checkoutBranchWithStashGuard } from "../auto-worktree.ts";
8
+ import { checkoutBranchWithStashGuard } from "../worktree-git-recovery.ts";
9
9
 
10
10
  function git(args: string[], cwd: string): string {
11
11
  return execFileSync("git", args, {
@@ -159,4 +159,69 @@ describe("checkoutBranchWithStashGuard", () => {
159
159
  const stashList = git(["stash", "list"], repo).trim();
160
160
  assert.equal(stashList, "");
161
161
  });
162
+
163
+ test("auto-resolves combined non-.gsd untracked collision and .gsd index conflict", (t) => {
164
+ // Regression for: gate checked nonGsdUnmerged.length === 0 but ignored
165
+ // .gsd/ index conflicts, so a failed pop with both an untracked non-.gsd/
166
+ // collision AND a .gsd/ tracked conflict would drop the stash while leaving
167
+ // .gsd/ index unmerged entries unresolved.
168
+ const repo = createRepo(t);
169
+ // Add .gsd/DECISIONS.md to base so both branches diverge from it
170
+ writeFileSync(join(repo, ".gsd", "DECISIONS.md"), "base\n");
171
+ git(["add", ".gsd/DECISIONS.md"], repo);
172
+ git(["commit", "-m", "add decisions"], repo);
173
+
174
+ git(["checkout", "-b", "milestone/M003"], repo);
175
+ // Branch has its own version of DECISIONS.md (non-JSONL .gsd/ file)
176
+ writeFileSync(join(repo, ".gsd", "DECISIONS.md"), "target-version\n");
177
+ mkdirSync(join(repo, ".harness"), { recursive: true });
178
+ writeFileSync(join(repo, ".harness", "settings.json"), "{\"theme\":\"dark\"}\n");
179
+ git(["add", ".gsd/DECISIONS.md", ".harness/settings.json"], repo);
180
+ git(["commit", "-m", "branch state"], repo);
181
+ git(["checkout", "main"], repo);
182
+
183
+ // On main: tracked .gsd/ change (creates unmerged index entry on pop) +
184
+ // untracked harness file (triggers "already exists, no checkout").
185
+ writeFileSync(join(repo, ".gsd", "DECISIONS.md"), "local-version\n");
186
+ mkdirSync(join(repo, ".harness"), { recursive: true });
187
+ writeFileSync(join(repo, ".harness", "settings.json"), "{\"theme\":\"light\"}\n");
188
+
189
+ checkoutBranchWithStashGuard(repo, "milestone/M003", "test-combined-gsd-conflict");
190
+
191
+ const branch = git(["branch", "--show-current"], repo).trim();
192
+ assert.equal(branch, "milestone/M003");
193
+ const decisions = readFileSync(join(repo, ".gsd", "DECISIONS.md"), "utf8");
194
+ assert.equal(decisions, "target-version\n");
195
+ assert.doesNotMatch(decisions, /<<<<<<<|=======|>>>>>>>/);
196
+ const status = git(["status", "--porcelain"], repo).trim();
197
+ assert.equal(status, "");
198
+ const stashList = git(["stash", "list"], repo).trim();
199
+ assert.equal(stashList, "");
200
+ });
201
+
202
+ test("auto-resolves non-.gsd untracked restore collisions (e.g. harness config outside .gsd/)", (t) => {
203
+ const repo = createRepo(t);
204
+ // Target branch has a harness config file committed; source (main) has it untracked.
205
+ // Use a path not affected by global gitignore rules (unlike .claude/settings.local.json).
206
+ git(["checkout", "-b", "milestone/M001"], repo);
207
+ mkdirSync(join(repo, ".harness"), { recursive: true });
208
+ writeFileSync(join(repo, ".harness", "settings.json"), "{\"theme\":\"dark\"}\n");
209
+ git(["add", ".harness/settings.json"], repo);
210
+ git(["commit", "-m", "add harness settings"], repo);
211
+ git(["checkout", "main"], repo);
212
+
213
+ mkdirSync(join(repo, ".harness"), { recursive: true });
214
+ writeFileSync(join(repo, ".harness", "settings.json"), "{\"theme\":\"light\"}\n");
215
+
216
+ checkoutBranchWithStashGuard(repo, "milestone/M001", "test-non-gsd-untracked-collision");
217
+
218
+ const branch = git(["branch", "--show-current"], repo).trim();
219
+ assert.equal(branch, "milestone/M001");
220
+ const wtContent = readFileSync(join(repo, ".harness", "settings.json"), "utf8");
221
+ assert.equal(wtContent, "{\"theme\":\"dark\"}\n");
222
+ const status = git(["status", "--porcelain"], repo).trim();
223
+ assert.equal(status, "");
224
+ const stashList = git(["stash", "list"], repo).trim();
225
+ assert.equal(stashList, "");
226
+ });
162
227
  });
@@ -74,6 +74,28 @@ describe("clear stale pending auto-start (#3667)", () => {
74
74
  );
75
75
  });
76
76
 
77
+ test("guided-flow recovers a finished-but-unconsumed discussion instead of dead-ending", () => {
78
+ // CONTEXT exists + no live turn means the discussion completed but the
79
+ // agent_end handoff never consumed the entry (e.g. an external-engine
80
+ // post-hoc gate re-arm wiped the depth verification after the save).
81
+ // Without recovery, every /gsd prints "Discussion already in progress"
82
+ // forever: the stale heuristic requires CONTEXT to be absent and
83
+ // discussPlanComplete requires a ROADMAP that planning never produced.
84
+ const source = readFileSync(join(__dirname, "..", "guided-flow.ts"), "utf-8");
85
+ assert.ok(
86
+ source.includes("milestoneHasContext && !isAgentTurnInFlight(ctx)"),
87
+ "pending-entry guard must have a recovery branch for CONTEXT-present, no-turn-in-flight entries",
88
+ );
89
+ assert.ok(
90
+ source.includes("extractDepthVerificationMilestoneId(pendingGateId) === entry.milestoneId"),
91
+ "recovery must only clear a pending gate belonging to the entry's own milestone",
92
+ );
93
+ assert.ok(
94
+ source.includes("if (checkAutoStartAfterDiscuss(basePath)) return;"),
95
+ "recovery must re-run the discuss→auto handoff after clearing the stale gate",
96
+ );
97
+ });
98
+
77
99
  test("guided-flow does not treat a live discuss turn as a stale pending entry", () => {
78
100
  const source = readFileSync(join(__dirname, "..", "guided-flow.ts"), "utf-8");
79
101
  assert.ok(
@@ -472,18 +472,19 @@ test("auto-dispatch needs-attention pause message references /gsd verdict", asyn
472
472
  }
473
473
  });
474
474
 
475
- test("state.ts needs-remediation blocker messages reference /gsd verdict", async () => {
475
+ test("guidance.ts needs-remediation blocker messages reference /gsd verdict", async () => {
476
476
  // We don't need to invoke deriveState — just assert the substring is in the
477
- // source. The blocker strings are constructed inline and shipped to the user
478
- // verbatim, so a static check is sufficient and avoids fragile DB setup.
479
- const stateSource = readFileSync(
480
- new URL("../state.ts", import.meta.url).pathname,
477
+ // source. The blocker strings are constructed in the guidance catalog and
478
+ // shipped to the user verbatim, so a static check is sufficient and avoids
479
+ // fragile DB setup.
480
+ const guidanceSource = readFileSync(
481
+ new URL("../guidance.ts", import.meta.url).pathname,
481
482
  "utf-8",
482
483
  );
483
- const occurrences = stateSource.match(/`\/gsd verdict /g) ?? [];
484
+ const occurrences = guidanceSource.match(/`\/gsd verdict /g) ?? [];
484
485
  assert.ok(
485
486
  occurrences.length >= 2,
486
- `expected at least 2 references to /gsd verdict in state.ts blockers, found ${occurrences.length}`,
487
+ `expected at least 2 references to /gsd verdict in guidance.ts blockers, found ${occurrences.length}`,
487
488
  );
488
489
  });
489
490