@opengsd/gsd-pi 1.2.0-dev.5457a158 → 1.2.0-dev.822c9439

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (489) hide show
  1. package/dist/headless-events.js +7 -5
  2. package/dist/mcp-server.js +2 -1
  3. package/dist/resource-loader.d.ts +9 -5
  4. package/dist/resource-loader.js +114 -6
  5. package/dist/resources/.managed-resources-content-hash +1 -1
  6. package/dist/resources/GSD-WORKFLOW.md +5 -4
  7. package/dist/resources/extensions/async-jobs/async-bash-tool.js +30 -64
  8. package/dist/resources/extensions/async-jobs/await-tool.js +80 -12
  9. package/dist/resources/extensions/async-jobs/index.js +65 -0
  10. package/dist/resources/extensions/async-jobs/job-manager.js +12 -1
  11. package/dist/resources/extensions/bg-shell/bg-shell-command.js +6 -6
  12. package/dist/resources/extensions/bg-shell/bg-shell-tool.js +10 -7
  13. package/dist/resources/extensions/bg-shell/overlay.js +9 -6
  14. package/dist/resources/extensions/bg-shell/process-manager.js +54 -25
  15. package/dist/resources/extensions/bg-shell/readiness-detector.js +11 -0
  16. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +209 -88
  17. package/dist/resources/extensions/browser-tools/engine/selection.js +73 -5
  18. package/dist/resources/extensions/browser-tools/index.js +69 -12
  19. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +3 -2
  20. package/dist/resources/extensions/gsd/auto/custom-verify-retry-store.js +17 -2
  21. package/dist/resources/extensions/gsd/auto/detect-stuck.js +33 -13
  22. package/dist/resources/extensions/gsd/auto/dispatch-history.js +105 -0
  23. package/dist/resources/extensions/gsd/auto/dispatch-key.js +37 -0
  24. package/dist/resources/extensions/gsd/auto/loop.js +4 -1
  25. package/dist/resources/extensions/gsd/auto/orchestrator.js +89 -54
  26. package/dist/resources/extensions/gsd/auto/phases.js +49 -6
  27. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  28. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -34
  29. package/dist/resources/extensions/gsd/auto-dispatch.js +50 -58
  30. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -13
  31. package/dist/resources/extensions/gsd/auto-post-unit.js +30 -12
  32. package/dist/resources/extensions/gsd/auto-prompts.js +78 -19
  33. package/dist/resources/extensions/gsd/auto-start.js +12 -12
  34. package/dist/resources/extensions/gsd/auto-unit-closeout.js +45 -21
  35. package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +5 -4
  36. package/dist/resources/extensions/gsd/auto-verification.js +23 -30
  37. package/dist/resources/extensions/gsd/auto-worktree.js +14 -1
  38. package/dist/resources/extensions/gsd/auto.js +37 -1
  39. package/dist/resources/extensions/gsd/blocked-models.js +28 -0
  40. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +26 -6
  41. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +23 -6
  42. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -2
  43. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +19 -0
  44. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +172 -59
  45. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +302 -80
  46. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +83 -0
  47. package/dist/resources/extensions/gsd/browser-evidence.js +8 -2
  48. package/dist/resources/extensions/gsd/closeout-wizard.js +92 -0
  49. package/dist/resources/extensions/gsd/commands/context.js +16 -2
  50. package/dist/resources/extensions/gsd/commands-handlers.js +46 -3
  51. package/dist/resources/extensions/gsd/consent-question.js +353 -0
  52. package/dist/resources/extensions/gsd/consent-verdict.js +63 -0
  53. package/dist/resources/extensions/gsd/constants.js +0 -2
  54. package/dist/resources/extensions/gsd/crash-recovery.js +8 -3
  55. package/dist/resources/extensions/gsd/db/queries.js +26 -0
  56. package/dist/resources/extensions/gsd/dispatch-guard.js +10 -35
  57. package/dist/resources/extensions/gsd/doctor-engine-checks.js +5 -5
  58. package/dist/resources/extensions/gsd/doctor-git-checks.js +2 -18
  59. package/dist/resources/extensions/gsd/engine-hook-contract.js +70 -0
  60. package/dist/resources/extensions/gsd/exec-sandbox.js +30 -10
  61. package/dist/resources/extensions/gsd/files.js +33 -19
  62. package/dist/resources/extensions/gsd/gsd-command-home.js +22 -12
  63. package/dist/resources/extensions/gsd/gsd-db.js +2 -1
  64. package/dist/resources/extensions/gsd/guidance.js +60 -0
  65. package/dist/resources/extensions/gsd/guided-flow.js +6 -3
  66. package/dist/resources/extensions/gsd/markdown-renderer.js +10 -0
  67. package/dist/resources/extensions/gsd/mcp-filter.js +2 -19
  68. package/dist/resources/extensions/gsd/milestone-closeout.js +85 -24
  69. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +2 -2
  70. package/dist/resources/extensions/gsd/milestone-reopen-events.js +3 -5
  71. package/dist/resources/extensions/gsd/parsers-legacy.js +16 -4
  72. package/dist/resources/extensions/gsd/preferences-models.js +2 -2
  73. package/dist/resources/extensions/gsd/projection-flush.js +7 -0
  74. package/dist/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  75. package/dist/resources/extensions/gsd/prompts/execute-task.md +1 -1
  76. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  77. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  78. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -1
  79. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  80. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  81. package/dist/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  82. package/dist/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  83. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -1
  84. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  85. package/dist/resources/extensions/gsd/prompts/run-uat.md +7 -5
  86. package/dist/resources/extensions/gsd/prompts/system.md +5 -2
  87. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  88. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  89. package/dist/resources/extensions/gsd/reactive-graph.js +8 -1
  90. package/dist/resources/extensions/gsd/roadmap-slices.js +25 -3
  91. package/dist/resources/extensions/gsd/safety/destructive-confirmation.js +108 -0
  92. package/dist/resources/extensions/gsd/session-lock.js +1 -1
  93. package/dist/resources/extensions/gsd/state.js +5 -0
  94. package/dist/resources/extensions/gsd/tool-contract.js +14 -3
  95. package/dist/resources/extensions/gsd/tool-presentation-plan.js +4 -4
  96. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -2
  97. package/dist/resources/extensions/gsd/tools/complete-slice.js +22 -12
  98. package/dist/resources/extensions/gsd/tools/complete-task.js +3 -2
  99. package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -0
  100. package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -2
  101. package/dist/resources/extensions/gsd/tools/plan-task.js +2 -2
  102. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +2 -2
  103. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +2 -2
  104. package/dist/resources/extensions/gsd/tools/reopen-slice.js +2 -2
  105. package/dist/resources/extensions/gsd/tools/reopen-task.js +2 -2
  106. package/dist/resources/extensions/gsd/tools/replan-slice.js +2 -2
  107. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +67 -2
  108. package/dist/resources/extensions/gsd/uat-policy.js +42 -16
  109. package/dist/resources/extensions/gsd/unit-context-composer.js +65 -0
  110. package/dist/resources/extensions/gsd/unit-registry.js +7 -20
  111. package/dist/resources/extensions/gsd/verdict-parser.js +1 -1
  112. package/dist/resources/extensions/gsd/verification-verdict.js +2 -1
  113. package/dist/resources/extensions/gsd/web-app-uat.js +45 -8
  114. package/dist/resources/extensions/gsd/workflow-event-ledger.js +91 -0
  115. package/dist/resources/extensions/gsd/workflow-event-vocabulary.js +46 -0
  116. package/dist/resources/extensions/gsd/workflow-events.js +6 -18
  117. package/dist/resources/extensions/gsd/workflow-reconcile.js +21 -56
  118. package/dist/resources/extensions/gsd/worktree-lifecycle.js +3 -2
  119. package/dist/resources/extensions/gsd/worktree-manager.js +7 -1
  120. package/dist/resources/extensions/gsd/worktree.js +8 -1
  121. package/dist/resources/extensions/search-the-web/native-search.js +5 -3
  122. package/dist/resources/extensions/shared/browser-contract.js +59 -0
  123. package/dist/resources/extensions/shared/gsd-browser-cli.js +116 -6
  124. package/dist/resources/shared/gsd-browser-path-sync.js +214 -0
  125. package/dist/resources/shared/package-manager-detection.js +1 -1
  126. package/dist/resources/shared/package.json +3 -0
  127. package/dist/resources/skills/create-skill/SKILL.md +3 -0
  128. package/dist/resources/skills/create-skill/references/executable-code.md +1 -1
  129. package/dist/resources/skills/create-skill/references/skill-structure.md +1 -0
  130. package/dist/resources/skills/create-skill/workflows/add-reference.md +8 -3
  131. package/dist/resources/skills/create-skill/workflows/add-script.md +4 -2
  132. package/dist/resources/skills/create-skill/workflows/add-template.md +3 -1
  133. package/dist/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  134. package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  135. package/dist/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  136. package/dist/resources/skills/spike-wrap-up/SKILL.md +9 -9
  137. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  138. package/dist/update-check.d.ts +2 -0
  139. package/dist/update-check.js +24 -1
  140. package/dist/update-cmd.js +20 -3
  141. package/dist/web/standalone/.next/BUILD_ID +1 -1
  142. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  143. package/dist/web/standalone/.next/build-manifest.json +3 -3
  144. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  145. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  146. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  147. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  151. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  152. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  153. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  154. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  155. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  156. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  157. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  158. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  159. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  160. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  161. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  162. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/update/route.js.nft.json +1 -1
  164. package/dist/web/standalone/.next/server/app/index.html +1 -1
  165. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  166. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  167. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  169. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  170. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  171. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  172. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  173. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  176. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  177. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  178. package/dist/web/standalone/.next/static/chunks/{796.cf859a427a2cb2ac.js → 796.e0bdc932325d7e03.js} +1 -1
  179. package/dist/web/standalone/.next/static/chunks/{webpack-fbea77b5f9953368.js → webpack-f0285ce91d4ec9ef.js} +1 -1
  180. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  181. package/dist/web/standalone/package.json +1 -1
  182. package/package.json +1 -1
  183. package/packages/cloud-mcp-gateway/package.json +2 -2
  184. package/packages/contracts/dist/rpc.d.ts +1 -0
  185. package/packages/contracts/dist/rpc.d.ts.map +1 -1
  186. package/packages/contracts/dist/rpc.js.map +1 -1
  187. package/packages/contracts/package.json +1 -1
  188. package/packages/daemon/package.json +4 -4
  189. package/packages/gsd-agent-core/package.json +5 -5
  190. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +5 -0
  191. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  192. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +5 -0
  193. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  194. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  195. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +7 -0
  196. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  197. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  198. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js +8 -1
  199. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  200. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.d.ts.map +1 -1
  201. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js +11 -1
  202. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-chat-render.js.map +1 -1
  203. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  204. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +4 -4
  205. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  206. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  207. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +3 -1
  208. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  209. package/packages/gsd-agent-modes/package.json +7 -7
  210. package/packages/mcp-server/dist/cli.js +10 -5
  211. package/packages/mcp-server/dist/cli.js.map +1 -1
  212. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts +29 -0
  213. package/packages/mcp-server/dist/moonshot-tool-schema.d.ts.map +1 -0
  214. package/packages/mcp-server/dist/moonshot-tool-schema.js +50 -0
  215. package/packages/mcp-server/dist/moonshot-tool-schema.js.map +1 -0
  216. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  217. package/packages/mcp-server/dist/server.js +4 -0
  218. package/packages/mcp-server/dist/server.js.map +1 -1
  219. package/packages/mcp-server/dist/workflow-tools.d.ts +18 -18
  220. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  221. package/packages/mcp-server/dist/workflow-tools.js +99 -38
  222. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  223. package/packages/mcp-server/package.json +5 -4
  224. package/packages/native/package.json +1 -1
  225. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts +1 -0
  226. package/packages/pi-agent-core/dist/harness/env/nodejs.d.ts.map +1 -1
  227. package/packages/pi-agent-core/dist/harness/env/nodejs.js +34 -3
  228. package/packages/pi-agent-core/dist/harness/env/nodejs.js.map +1 -1
  229. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  230. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  231. package/packages/pi-agent-core/dist/index.js +3 -0
  232. package/packages/pi-agent-core/dist/index.js.map +1 -1
  233. package/packages/pi-agent-core/package.json +1 -1
  234. package/packages/pi-ai/README.md +1 -0
  235. package/packages/pi-ai/dist/image-models.generated.d.ts +2 -2
  236. package/packages/pi-ai/dist/image-models.generated.js +6 -6
  237. package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
  238. package/packages/pi-ai/dist/index.d.ts +2 -0
  239. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  240. package/packages/pi-ai/dist/index.js +2 -0
  241. package/packages/pi-ai/dist/index.js.map +1 -1
  242. package/packages/pi-ai/dist/models.generated.d.ts +239 -153
  243. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  244. package/packages/pi-ai/dist/models.generated.js +256 -145
  245. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  246. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  247. package/packages/pi-ai/dist/providers/anthropic.js +12 -7
  248. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  249. package/packages/pi-ai/dist/providers/google-shared.d.ts +5 -0
  250. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  251. package/packages/pi-ai/dist/providers/google-shared.js +12 -3
  252. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  253. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  254. package/packages/pi-ai/dist/providers/openai-completions.js +7 -3
  255. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  256. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts +9 -0
  257. package/packages/pi-ai/dist/utils/moonshot-tool-schema.d.ts.map +1 -0
  258. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js +34 -0
  259. package/packages/pi-ai/dist/utils/moonshot-tool-schema.js.map +1 -0
  260. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  261. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +6 -2
  262. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  263. package/packages/pi-ai/package.json +3 -2
  264. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +2 -2
  265. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/core/auth-storage.js +19 -13
  267. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/core/provider-readiness.d.ts.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/provider-readiness.js +13 -6
  270. package/packages/pi-coding-agent/dist/core/provider-readiness.js.map +1 -1
  271. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +11 -0
  272. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/tools/bash.js +53 -11
  274. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  276. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/index.js +1 -1
  278. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/utils/shell.d.ts +28 -2
  280. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/utils/shell.js +56 -10
  282. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  283. package/packages/pi-coding-agent/package.json +7 -7
  284. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  285. package/packages/pi-tui/dist/tui.js +9 -0
  286. package/packages/pi-tui/dist/tui.js.map +1 -1
  287. package/packages/pi-tui/package.json +2 -2
  288. package/packages/rpc-client/package.json +2 -2
  289. package/pkg/package.json +1 -1
  290. package/src/resources/GSD-WORKFLOW.md +5 -4
  291. package/src/resources/extensions/async-jobs/async-bash-cancel.test.ts +360 -0
  292. package/src/resources/extensions/async-jobs/async-bash-tool.ts +33 -56
  293. package/src/resources/extensions/async-jobs/await-tool.test.ts +139 -0
  294. package/src/resources/extensions/async-jobs/await-tool.ts +82 -12
  295. package/src/resources/extensions/async-jobs/index.ts +79 -0
  296. package/src/resources/extensions/async-jobs/job-manager.ts +21 -1
  297. package/src/resources/extensions/bg-shell/bg-shell-command.ts +6 -6
  298. package/src/resources/extensions/bg-shell/bg-shell-tool.ts +10 -6
  299. package/src/resources/extensions/bg-shell/overlay.ts +9 -5
  300. package/src/resources/extensions/bg-shell/process-manager.ts +50 -25
  301. package/src/resources/extensions/bg-shell/readiness-detector.ts +12 -0
  302. package/src/resources/extensions/bg-shell/tests/lifecycle-and-utilities.test.ts +48 -1
  303. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +265 -98
  304. package/src/resources/extensions/browser-tools/engine/selection.ts +90 -4
  305. package/src/resources/extensions/browser-tools/index.ts +71 -13
  306. package/src/resources/extensions/browser-tools/tests/browser-engine-selection.test.mjs +83 -13
  307. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +40 -1
  308. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +136 -0
  309. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +3 -2
  310. package/src/resources/extensions/gsd/auto/custom-verify-retry-store.ts +21 -3
  311. package/src/resources/extensions/gsd/auto/detect-stuck.ts +32 -9
  312. package/src/resources/extensions/gsd/auto/dispatch-history.ts +152 -0
  313. package/src/resources/extensions/gsd/auto/dispatch-key.ts +39 -0
  314. package/src/resources/extensions/gsd/auto/loop.ts +4 -1
  315. package/src/resources/extensions/gsd/auto/orchestrator.ts +98 -56
  316. package/src/resources/extensions/gsd/auto/phases.ts +65 -26
  317. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  318. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +18 -48
  319. package/src/resources/extensions/gsd/auto-dispatch.ts +48 -61
  320. package/src/resources/extensions/gsd/auto-model-selection.ts +41 -12
  321. package/src/resources/extensions/gsd/auto-post-unit.ts +33 -12
  322. package/src/resources/extensions/gsd/auto-prompts.ts +115 -35
  323. package/src/resources/extensions/gsd/auto-start.ts +12 -14
  324. package/src/resources/extensions/gsd/auto-unit-closeout.ts +83 -28
  325. package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +4 -4
  326. package/src/resources/extensions/gsd/auto-verification.ts +26 -28
  327. package/src/resources/extensions/gsd/auto-worktree.ts +14 -1
  328. package/src/resources/extensions/gsd/auto.ts +44 -1
  329. package/src/resources/extensions/gsd/blocked-models.ts +49 -0
  330. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -5
  331. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +23 -6
  332. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -2
  333. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +24 -0
  334. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +211 -59
  335. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +350 -86
  336. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +108 -0
  337. package/src/resources/extensions/gsd/browser-evidence.ts +18 -2
  338. package/src/resources/extensions/gsd/closeout-wizard.ts +102 -0
  339. package/src/resources/extensions/gsd/commands/context.ts +16 -2
  340. package/src/resources/extensions/gsd/commands-handlers.ts +46 -3
  341. package/src/resources/extensions/gsd/consent-question.ts +431 -0
  342. package/src/resources/extensions/gsd/consent-verdict.ts +86 -0
  343. package/src/resources/extensions/gsd/constants.ts +0 -3
  344. package/src/resources/extensions/gsd/crash-recovery.ts +10 -2
  345. package/src/resources/extensions/gsd/db/queries.ts +37 -0
  346. package/src/resources/extensions/gsd/dispatch-guard.ts +8 -31
  347. package/src/resources/extensions/gsd/doctor-engine-checks.ts +5 -4
  348. package/src/resources/extensions/gsd/doctor-git-checks.ts +2 -19
  349. package/src/resources/extensions/gsd/engine-hook-contract.ts +79 -0
  350. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  351. package/src/resources/extensions/gsd/files.ts +33 -12
  352. package/src/resources/extensions/gsd/gsd-command-home.ts +13 -3
  353. package/src/resources/extensions/gsd/gsd-db.ts +4 -3
  354. package/src/resources/extensions/gsd/guidance.ts +78 -0
  355. package/src/resources/extensions/gsd/guided-flow.ts +21 -26
  356. package/src/resources/extensions/gsd/markdown-renderer.ts +11 -0
  357. package/src/resources/extensions/gsd/mcp-filter.ts +2 -23
  358. package/src/resources/extensions/gsd/milestone-closeout.ts +109 -24
  359. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +2 -2
  360. package/src/resources/extensions/gsd/milestone-reopen-events.ts +3 -6
  361. package/src/resources/extensions/gsd/parsers-legacy.ts +16 -4
  362. package/src/resources/extensions/gsd/preferences-models.ts +2 -1
  363. package/src/resources/extensions/gsd/projection-flush.ts +20 -0
  364. package/src/resources/extensions/gsd/prompts/complete-slice.md +3 -3
  365. package/src/resources/extensions/gsd/prompts/execute-task.md +1 -1
  366. package/src/resources/extensions/gsd/prompts/plan-milestone.md +1 -1
  367. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  368. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -1
  369. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +1 -1
  370. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  371. package/src/resources/extensions/gsd/prompts/replan-slice.md +1 -1
  372. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  373. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  374. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +1 -1
  375. package/src/resources/extensions/gsd/prompts/run-uat.md +7 -5
  376. package/src/resources/extensions/gsd/prompts/system.md +5 -2
  377. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -1
  378. package/src/resources/extensions/gsd/prompts/validate-milestone.md +1 -1
  379. package/src/resources/extensions/gsd/reactive-graph.ts +11 -1
  380. package/src/resources/extensions/gsd/roadmap-slices.ts +28 -3
  381. package/src/resources/extensions/gsd/safety/destructive-confirmation.ts +134 -0
  382. package/src/resources/extensions/gsd/session-lock.ts +1 -1
  383. package/src/resources/extensions/gsd/state.ts +5 -0
  384. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +97 -1
  385. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +198 -26
  386. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +65 -3
  387. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +19 -0
  388. package/src/resources/extensions/gsd/tests/browser-automation-contract-fixture.ts +39 -0
  389. package/src/resources/extensions/gsd/tests/browser-contract.test.ts +44 -0
  390. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +144 -0
  391. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +42 -0
  392. package/src/resources/extensions/gsd/tests/consent-question.test.ts +351 -0
  393. package/src/resources/extensions/gsd/tests/custom-verify-retry-store.test.ts +67 -0
  394. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +10 -10
  395. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +303 -0
  396. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +12 -2
  397. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +273 -0
  398. package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +2 -1
  399. package/src/resources/extensions/gsd/tests/doctor-git-checks-terminal.test.ts +73 -0
  400. package/src/resources/extensions/gsd/tests/dynamic-bash-no-cap.test.ts +132 -0
  401. package/src/resources/extensions/gsd/tests/engine-hook-contract.test.ts +148 -0
  402. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +193 -0
  403. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +29 -1
  404. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +35 -1
  405. package/src/resources/extensions/gsd/tests/gsd-command-home.test.ts +120 -0
  406. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +27 -0
  407. package/src/resources/extensions/gsd/tests/guidance.test.ts +23 -0
  408. package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +2 -6
  409. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +7 -11
  410. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +20 -58
  411. package/src/resources/extensions/gsd/tests/integration/gsd-integration-fixture.ts +80 -0
  412. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +199 -0
  413. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +3 -1
  414. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +95 -4
  415. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +32 -1
  416. package/src/resources/extensions/gsd/tests/oauth-api-model-routing.test.ts +167 -0
  417. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +18 -0
  418. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +138 -0
  419. package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +242 -0
  420. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +63 -2
  421. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +124 -6
  422. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +68 -0
  423. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +19 -1
  424. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +17 -0
  425. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +76 -0
  426. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +33 -0
  427. package/src/resources/extensions/gsd/tests/transport-gate-double-complete.test.ts +139 -0
  428. package/src/resources/extensions/gsd/tests/uat-policy.test.ts +112 -29
  429. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +44 -0
  430. package/src/resources/extensions/gsd/tests/uok-audit-unified.test.ts +8 -0
  431. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +2 -0
  432. package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +44 -1
  433. package/src/resources/extensions/gsd/tests/workflow-events.test.ts +19 -0
  434. package/src/resources/extensions/gsd/tests/workflow-reconcile.test.ts +20 -0
  435. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +273 -38
  436. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +22 -0
  437. package/src/resources/extensions/gsd/tests/worktree.test.ts +18 -0
  438. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +358 -0
  439. package/src/resources/extensions/gsd/tests/write-gate.test.ts +67 -1
  440. package/src/resources/extensions/gsd/tool-contract.ts +38 -3
  441. package/src/resources/extensions/gsd/tool-presentation-plan.ts +4 -4
  442. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  443. package/src/resources/extensions/gsd/tools/complete-slice.ts +22 -12
  444. package/src/resources/extensions/gsd/tools/complete-task.ts +3 -2
  445. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -0
  446. package/src/resources/extensions/gsd/tools/plan-slice.ts +2 -2
  447. package/src/resources/extensions/gsd/tools/plan-task.ts +2 -2
  448. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +2 -2
  449. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +2 -2
  450. package/src/resources/extensions/gsd/tools/reopen-slice.ts +2 -2
  451. package/src/resources/extensions/gsd/tools/reopen-task.ts +2 -2
  452. package/src/resources/extensions/gsd/tools/replan-slice.ts +2 -2
  453. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +81 -2
  454. package/src/resources/extensions/gsd/uat-policy.ts +62 -16
  455. package/src/resources/extensions/gsd/unit-context-composer.ts +99 -0
  456. package/src/resources/extensions/gsd/unit-registry.ts +7 -20
  457. package/src/resources/extensions/gsd/verdict-parser.ts +1 -1
  458. package/src/resources/extensions/gsd/verification-verdict.ts +4 -2
  459. package/src/resources/extensions/gsd/web-app-uat.ts +51 -8
  460. package/src/resources/extensions/gsd/workflow-event-ledger.ts +131 -0
  461. package/src/resources/extensions/gsd/workflow-event-vocabulary.ts +59 -0
  462. package/src/resources/extensions/gsd/workflow-events.ts +12 -20
  463. package/src/resources/extensions/gsd/workflow-reconcile.ts +29 -62
  464. package/src/resources/extensions/gsd/worktree-lifecycle.ts +3 -8
  465. package/src/resources/extensions/gsd/worktree-manager.ts +6 -1
  466. package/src/resources/extensions/gsd/worktree.ts +7 -1
  467. package/src/resources/extensions/search-the-web/native-search.ts +5 -3
  468. package/src/resources/extensions/shared/browser-contract.ts +66 -0
  469. package/src/resources/extensions/shared/gsd-browser-cli.ts +141 -6
  470. package/src/resources/shared/gsd-browser-path-sync.ts +273 -0
  471. package/src/resources/shared/package-manager-detection.ts +1 -1
  472. package/src/resources/shared/package.json +3 -0
  473. package/src/resources/skills/create-skill/SKILL.md +3 -0
  474. package/src/resources/skills/create-skill/references/executable-code.md +1 -1
  475. package/src/resources/skills/create-skill/references/skill-structure.md +1 -0
  476. package/src/resources/skills/create-skill/workflows/add-reference.md +8 -3
  477. package/src/resources/skills/create-skill/workflows/add-script.md +4 -2
  478. package/src/resources/skills/create-skill/workflows/add-template.md +3 -1
  479. package/src/resources/skills/create-skill/workflows/add-workflow.md +8 -3
  480. package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +10 -5
  481. package/src/resources/skills/create-skill/workflows/verify-skill.md +9 -4
  482. package/src/resources/skills/spike-wrap-up/SKILL.md +9 -9
  483. package/dist/resources/extensions/gsd/user-input-boundary.js +0 -218
  484. package/dist/resources/skills/gsd-browser/SKILL.md +0 -41
  485. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +0 -173
  486. package/src/resources/extensions/gsd/user-input-boundary.ts +0 -216
  487. package/src/resources/skills/gsd-browser/SKILL.md +0 -41
  488. /package/dist/web/standalone/.next/static/{2p9Rv9pQflAxCBbGVI2vb → yWwBo-w09Y_W-nmeeWFRp}/_buildManifest.js +0 -0
  489. /package/dist/web/standalone/.next/static/{2p9Rv9pQflAxCBbGVI2vb → yWwBo-w09Y_W-nmeeWFRp}/_ssgManifest.js +0 -0
@@ -4,10 +4,13 @@
4
4
  import test from "node:test";
5
5
  import assert from "node:assert/strict";
6
6
  import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
7
+ import { execFileSync } from "node:child_process";
7
8
  import { join } from "node:path";
8
9
  import { tmpdir } from "node:os";
9
10
 
10
11
  import { buildGsdHomeModel, showGsdHome } from "../gsd-command-home.ts";
12
+ import { buildIdleMenuSummary, detectIdleMilestoneResidueHint } from "../closeout-wizard.ts";
13
+ import { closeDatabase, insertMilestone, openDatabase } from "../gsd-db.ts";
11
14
  import type { GSDState } from "../types.ts";
12
15
 
13
16
  function baseState(overrides: Partial<GSDState> = {}): GSDState {
@@ -118,6 +121,123 @@ test("/gsd home recommends start or configure after all milestones complete", ()
118
121
  assert.match(model.summary.join("\n"), /All milestones complete/);
119
122
  });
120
123
 
124
+ test("/gsd home recommends fix or recover when milestone git residue is stranded", () => {
125
+ const model = buildGsdHomeModel(baseState({
126
+ activeMilestone: null,
127
+ activeSlice: null,
128
+ activeTask: null,
129
+ phase: "complete",
130
+ nextAction: "All milestones complete.",
131
+ }), {
132
+ strandedQuick: null,
133
+ unmergedMilestones: [],
134
+ idleResidueHint: {
135
+ milestoneIds: ["M008"],
136
+ message:
137
+ "Stranded milestone git residue detected (M008: worktree dir and/or milestone/* branch). " +
138
+ "Run /gsd dispatch complete-milestone M008 or /gsd status to recover closeout before starting new work.",
139
+ },
140
+ });
141
+
142
+ assert.equal(action(model, "fix_recover").recommended, true);
143
+ assert.equal(action(model, "fix_recover").enabled, true);
144
+ assert.match(model.summary[0], /Stranded milestone git residue/);
145
+ assert.equal(action(model, "continue_step").enabled, false);
146
+ });
147
+
148
+ test("detectIdleMilestoneResidueHint reports missing workflow database in a git repo", () => {
149
+ const base = mkdtempSync(join(tmpdir(), "gsd-home-residue-"));
150
+ try {
151
+ execFileSync("git", ["init", "-b", "main"], { cwd: base, stdio: "ignore" });
152
+ const hint = detectIdleMilestoneResidueHint(base);
153
+ assert.ok(hint);
154
+ assert.match(hint!.message, /\.gsd\/gsd\.db/);
155
+ } finally {
156
+ rmSync(base, { recursive: true, force: true });
157
+ }
158
+ });
159
+
160
+ test("detectIdleMilestoneResidueHint matches unique-format milestone ids (M###-abc123)", () => {
161
+ const base = mkdtempSync(join(tmpdir(), "gsd-home-residue-unique-"));
162
+ try {
163
+ execFileSync("git", ["init", "-b", "main"], { cwd: base, stdio: "ignore" });
164
+ mkdirSync(join(base, ".gsd-worktrees", "M042-abc123"), { recursive: true });
165
+ mkdirSync(join(base, ".gsd"), { recursive: true });
166
+
167
+ openDatabase(join(base, ".gsd", "gsd.db"));
168
+ try {
169
+ // Closed milestone with lingering worktree dir — classic residue.
170
+ insertMilestone({ id: "M042-abc123", title: "Closed Unique", status: "complete" });
171
+ const hint = detectIdleMilestoneResidueHint(base);
172
+ assert.ok(hint, "unique-format closed milestone with worktree should be detected");
173
+ assert.deepEqual(hint!.milestoneIds, ["M042-abc123"]);
174
+ assert.match(hint!.message, /M042-abc123/);
175
+ } finally {
176
+ closeDatabase();
177
+ }
178
+ } finally {
179
+ rmSync(base, { recursive: true, force: true });
180
+ }
181
+ });
182
+
183
+ test("detectIdleMilestoneResidueHint ignores in-flight milestones with worktree artifacts", () => {
184
+ const base = mkdtempSync(join(tmpdir(), "gsd-home-residue-active-"));
185
+ try {
186
+ execFileSync("git", ["init", "-b", "main"], { cwd: base, stdio: "ignore" });
187
+ mkdirSync(join(base, ".gsd-worktrees", "M001"), { recursive: true });
188
+ mkdirSync(join(base, ".gsd-worktrees", "M002-abc123"), { recursive: true });
189
+ mkdirSync(join(base, ".gsd"), { recursive: true });
190
+
191
+ openDatabase(join(base, ".gsd", "gsd.db"));
192
+ try {
193
+ // Active and pending milestones must not be flagged as stranded residue.
194
+ insertMilestone({ id: "M001", title: "Active milestone", status: "active" });
195
+ insertMilestone({ id: "M002-abc123", title: "Pending milestone", status: "pending" });
196
+ const hint = detectIdleMilestoneResidueHint(base);
197
+ assert.equal(hint, null, "active/pending milestone worktrees must not be classified as residue");
198
+ } finally {
199
+ closeDatabase();
200
+ }
201
+ } finally {
202
+ rmSync(base, { recursive: true, force: true });
203
+ }
204
+ });
205
+
206
+ test("buildIdleMenuSummary surfaces idle residue hint even when phase is complete", () => {
207
+ const summary = buildIdleMenuSummary(
208
+ {
209
+ activeMilestone: null,
210
+ activeSlice: null,
211
+ activeTask: null,
212
+ phase: "complete",
213
+ recentDecisions: [],
214
+ blockers: [],
215
+ nextAction: "All milestones complete.",
216
+ lastCompletedMilestone: { id: "M001", title: "Menu Cleanup" },
217
+ registry: [{ id: "M001", title: "Menu Cleanup", status: "complete" }],
218
+ requirements: { active: 0, validated: 0, deferred: 0, outOfScope: 0, blocked: 0, total: 0 },
219
+ progress: {
220
+ milestones: { done: 1, total: 1 },
221
+ slices: { done: 0, total: 0 },
222
+ tasks: { done: 0, total: 0 },
223
+ },
224
+ },
225
+ {
226
+ strandedQuick: null,
227
+ unmergedMilestones: [],
228
+ idleResidueHint: {
229
+ milestoneIds: ["M008"],
230
+ message:
231
+ "Stranded milestone git residue detected (M008: worktree dir and/or milestone/* branch). " +
232
+ "Run /gsd dispatch complete-milestone M008 or /gsd status to recover closeout before starting new work.",
233
+ },
234
+ },
235
+ );
236
+
237
+ assert.match(summary[0] ?? "", /Stranded milestone git residue/);
238
+ assert.doesNotMatch(summary.join("\n"), /All milestones complete/);
239
+ });
240
+
121
241
  test("showGsdHome renders the five-slot home text without an interactive TUI", async () => {
122
242
  const base = mkdtempSync(join(tmpdir(), "gsd-home-"));
123
243
  const notifications: Array<{ message: string; level: string }> = [];
@@ -30,6 +30,8 @@ import {
30
30
  insertTask,
31
31
  getTask,
32
32
  getSliceTasks,
33
+ getMilestoneSliceSummaries,
34
+ getClosedSliceIds,
33
35
  getActiveMilestoneFromDb,
34
36
  deleteMilestone,
35
37
  clearEngineHierarchy,
@@ -947,6 +949,31 @@ describe('gsd-db', () => {
947
949
  closeDatabase();
948
950
  });
949
951
 
952
+ test('gsd-db: slice summaries use the canonical closed vocabulary; getClosedSliceIds filters to closed ids', () => {
953
+ openDatabase(':memory:');
954
+ insertMilestone({ id: 'M001', status: 'active' });
955
+ insertSlice({ milestoneId: 'M001', id: 'S01', title: 'Complete', status: 'complete', depends: [], sequence: 1 });
956
+ insertSlice({ milestoneId: 'M001', id: 'S02', title: 'Done', status: 'done', depends: ['S01'], sequence: 2 });
957
+ insertSlice({ milestoneId: 'M001', id: 'S03', title: 'Skipped', status: 'skipped', depends: [], sequence: 3 });
958
+ insertSlice({ milestoneId: 'M001', id: 'S04', title: 'Closed', status: 'closed', depends: [], sequence: 4 });
959
+ insertSlice({ milestoneId: 'M001', id: 'S05', title: 'Active', status: 'active', depends: [], sequence: 5 });
960
+ insertSlice({ milestoneId: 'M001', id: 'S06', title: 'Pending', status: 'pending', depends: ['S05'], sequence: 6 });
961
+
962
+ const summaries = getMilestoneSliceSummaries('M001');
963
+ assert.deepStrictEqual(summaries[0], { id: 'S01', title: 'Complete', done: true, depends: [] });
964
+ assert.deepStrictEqual(summaries[5], { id: 'S06', title: 'Pending', done: false, depends: ['S05'] });
965
+ assert.deepStrictEqual(
966
+ summaries.map((s) => s.done),
967
+ [true, true, true, true, false, false],
968
+ 'complete/done/skipped/closed are closed; active/pending are not',
969
+ );
970
+
971
+ assert.deepStrictEqual(getClosedSliceIds('M001'), ['S01', 'S02', 'S03', 'S04']);
972
+ assert.deepStrictEqual(getClosedSliceIds('M999'), [], 'unknown milestone yields no closed ids');
973
+
974
+ closeDatabase();
975
+ });
976
+
950
977
  test('gsd-db: FTS5 unavailable warning normalizes provider typo', () => {
951
978
  const previousStderr = setStderrLoggingEnabled(false);
952
979
  _resetLogs();
@@ -10,6 +10,8 @@ import {
10
10
  recoveryRemediation,
11
11
  needsAttentionBlockerGuidance,
12
12
  needsRemediationBlockerGuidance,
13
+ uatSignoffBlockerGuidance,
14
+ worktreeCreationFailedGuidance,
13
15
  crashResumeHint,
14
16
  doctorFixHint,
15
17
  type RecoveryGuidanceKey,
@@ -95,6 +97,27 @@ describe("milestone blocker guidance", () => {
95
97
  assert.match(text, /\/gsd status/);
96
98
  assert.match(text, /\/gsd validate-milestone/);
97
99
  });
100
+
101
+ test("UAT sign-off guidance explains direct dispatch target", () => {
102
+ const missing = uatSignoffBlockerGuidance("M007", "S02");
103
+ const failing = uatSignoffBlockerGuidance("M007", "S02", "FAIL");
104
+
105
+ for (const text of [missing, failing]) {
106
+ assert.match(text, /Manual UAT sign-off \(PASS\) is required before milestone closure/);
107
+ assert.match(text, /\/gsd dispatch uat/);
108
+ assert.match(text, /most recently completed slice/);
109
+ assert.match(text, /re-run UAT for S02/);
110
+ assert.match(text, /gsd_uat_result_save/);
111
+ }
112
+ });
113
+
114
+ test("worktree creation failure guidance does not claim bootstrap continues", () => {
115
+ const text = worktreeCreationFailedGuidance("M007", "boom");
116
+
117
+ assert.match(text, /Auto-worktree creation for M007 failed: boom\. Continuing in project root\./);
118
+ assert.match(text, /Worktree isolation is degraded for this session\./);
119
+ assert.doesNotMatch(text, /work continues in the project root/i);
120
+ });
98
121
  });
99
122
 
100
123
  describe("crash resume hints", () => {
@@ -77,12 +77,8 @@ test("guided dispatch passes the explicit project root through model and compati
77
77
  seen.modelRoot = projectRoot;
78
78
  return { routing: null, appliedModel: null };
79
79
  },
80
- getTransportSupportError: (
81
- _provider: string | undefined,
82
- _requiredTools: string[],
83
- options?: { projectRoot?: string },
84
- ) => {
85
- seen.compatibilityRoot = options?.projectRoot ?? "";
80
+ getDispatchReadinessError: (input: { projectRoot?: string }) => {
81
+ seen.compatibilityRoot = input.projectRoot ?? "";
86
82
  return null;
87
83
  },
88
84
  },
@@ -35,6 +35,7 @@ import {
35
35
  insertTask,
36
36
  openDatabase,
37
37
  } from "../../gsd-db.ts";
38
+ import { createGsdIntegrationProject } from "./gsd-integration-fixture.ts";
38
39
 
39
40
  function run(cmd: string, cwd: string): string {
40
41
  // Safe: all inputs are hardcoded test strings, not user input
@@ -42,17 +43,12 @@ function run(cmd: string, cwd: string): string {
42
43
  }
43
44
 
44
45
  function createTempRepo(): string {
45
- const dir = realpathSync(mkdtempSync(join(tmpdir(), "wt-ms-merge-test-")));
46
- run("git init", dir);
47
- run("git config user.email test@test.com", dir);
48
- run("git config user.name Test", dir);
49
- writeFileSync(join(dir, "README.md"), "# test\n");
50
- mkdirSync(join(dir, ".gsd"), { recursive: true });
51
- writeFileSync(join(dir, ".gsd", "STATE.md"), "# State\n");
52
- run("git add .", dir);
53
- run("git commit -m init", dir);
54
- run("git branch -M main", dir);
55
- return dir;
46
+ return createGsdIntegrationProject({
47
+ prefix: "wt-ms-merge-test-",
48
+ initialFiles: {
49
+ ".gsd/STATE.md": "# State\n",
50
+ },
51
+ }).root;
56
52
  }
57
53
 
58
54
  function createTempRepoWithExternalGsd(): { repo: string; externalState: string } {
@@ -11,6 +11,11 @@ import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, realpathSync
11
11
  import { join } from "node:path";
12
12
  import { tmpdir } from "node:os";
13
13
  import { execSync } from "node:child_process";
14
+ import {
15
+ commitAll,
16
+ createGsdIntegrationProject,
17
+ writeGsdMilestoneContext,
18
+ } from "./gsd-integration-fixture.ts";
14
19
 
15
20
  import {
16
21
  createAutoWorktree,
@@ -32,17 +37,12 @@ function run(command: string, cwd: string): string {
32
37
  }
33
38
 
34
39
  function createTempRepo(): string {
35
- const dir = realpathSync(mkdtempSync(join(tmpdir(), "auto-wt-test-")));
36
- run("git init", dir);
37
- run("git config user.email test@test.com", dir);
38
- run("git config user.name Test", dir);
39
- // Create initial commit on main
40
- writeFileSync(join(dir, "README.md"), "# test\n");
41
- run("git add .", dir);
42
- run("git commit -m init", dir);
43
- // Ensure branch is called main
44
- run("git branch -M main", dir);
45
- return dir;
40
+ return createGsdIntegrationProject("auto-wt-test-").root;
41
+ }
42
+
43
+ function commitMilestoneContext(repo: string, milestoneId: string): void {
44
+ writeGsdMilestoneContext(repo, milestoneId);
45
+ commitAll(repo, "add milestone");
46
46
  }
47
47
 
48
48
  describe("auto-worktree lifecycle", () => {
@@ -59,13 +59,7 @@ describe("auto-worktree lifecycle", () => {
59
59
 
60
60
  test("create → detect → teardown", () => {
61
61
  tempDir = createTempRepo();
62
-
63
- // Create .gsd/milestones/M003 with a dummy file (simulates planning artifacts)
64
- const msDir = join(tempDir, ".gsd", "milestones", "M003");
65
- mkdirSync(msDir, { recursive: true });
66
- writeFileSync(join(msDir, "CONTEXT.md"), "# M003 Context\n");
67
- run("git add .", tempDir);
68
- run("git commit -m \"add milestone\"", tempDir);
62
+ commitMilestoneContext(tempDir, "M003");
69
63
 
70
64
  // ─── createAutoWorktree ──────────────────────────────────────────
71
65
  const wtPath = createAutoWorktree(tempDir, "M003");
@@ -112,11 +106,7 @@ describe("auto-worktree lifecycle", () => {
112
106
 
113
107
  test("re-entry: create again, exit without teardown, re-enter", () => {
114
108
  tempDir = createTempRepo();
115
- const msDir = join(tempDir, ".gsd", "milestones", "M003");
116
- mkdirSync(msDir, { recursive: true });
117
- writeFileSync(join(msDir, "CONTEXT.md"), "# M003 Context\n");
118
- run("git add .", tempDir);
119
- run("git commit -m \"add milestone\"", tempDir);
109
+ commitMilestoneContext(tempDir, "M003");
120
110
 
121
111
  const wtPath2 = createAutoWorktree(tempDir, "M003");
122
112
  assert.ok(existsSync(wtPath2), "worktree re-created");
@@ -247,11 +237,7 @@ describe("auto-worktree lifecycle", () => {
247
237
 
248
238
  test("coexistence with manual worktree", async () => {
249
239
  tempDir = createTempRepo();
250
- const msDir = join(tempDir, ".gsd", "milestones", "M003");
251
- mkdirSync(msDir, { recursive: true });
252
- writeFileSync(join(msDir, "CONTEXT.md"), "# M003 Context\n");
253
- run("git add .", tempDir);
254
- run("git commit -m \"add milestone\"", tempDir);
240
+ commitMilestoneContext(tempDir, "M003");
255
241
 
256
242
  // Import createWorktree directly for manual worktree
257
243
  const { createWorktree } = await import("../../worktree-manager.ts");
@@ -274,11 +260,7 @@ describe("auto-worktree lifecycle", () => {
274
260
 
275
261
  test("split-brain prevention: originalBase cleared after teardown", () => {
276
262
  tempDir = createTempRepo();
277
- const msDir = join(tempDir, ".gsd", "milestones", "M003");
278
- mkdirSync(msDir, { recursive: true });
279
- writeFileSync(join(msDir, "CONTEXT.md"), "# M003 Context\n");
280
- run("git add .", tempDir);
281
- run("git commit -m \"add milestone\"", tempDir);
263
+ commitMilestoneContext(tempDir, "M003");
282
264
 
283
265
  createAutoWorktree(tempDir, "M003");
284
266
  teardownAutoWorktree(tempDir, "M003");
@@ -288,11 +270,7 @@ describe("auto-worktree lifecycle", () => {
288
270
 
289
271
  test("#1526: getMainBranch returns milestone/<MID> in auto-worktree", async () => {
290
272
  tempDir = createTempRepo();
291
- const msDir = join(tempDir, ".gsd", "milestones", "M005");
292
- mkdirSync(msDir, { recursive: true });
293
- writeFileSync(join(msDir, "CONTEXT.md"), "# M005 Context\n");
294
- run("git add .", tempDir);
295
- run("git commit -m \"add milestone\"", tempDir);
273
+ commitMilestoneContext(tempDir, "M005");
296
274
 
297
275
  const { GitServiceImpl } = await import("../../git-service.ts");
298
276
 
@@ -312,11 +290,7 @@ describe("auto-worktree lifecycle", () => {
312
290
 
313
291
  test("#1713: stale worktree directory without .git file", async () => {
314
292
  tempDir = createTempRepo();
315
- const msDir = join(tempDir, ".gsd", "milestones", "M010");
316
- mkdirSync(msDir, { recursive: true });
317
- writeFileSync(join(msDir, "CONTEXT.md"), "# M010 Context\n");
318
- run("git add .", tempDir);
319
- run("git commit -m \"add milestone\"", tempDir);
293
+ commitMilestoneContext(tempDir, "M010");
320
294
 
321
295
  // Simulate a crash leaving a stale directory with no .git file.
322
296
  const { worktreePath } = await import("../../worktree-manager.ts");
@@ -337,11 +311,7 @@ describe("auto-worktree lifecycle", () => {
337
311
 
338
312
  test("#778: re-attach does not reconcile plan checkboxes into a worktree-local .gsd projection", async () => {
339
313
  tempDir = createTempRepo();
340
- const msDir = join(tempDir, ".gsd", "milestones", "M003");
341
- mkdirSync(msDir, { recursive: true });
342
- writeFileSync(join(msDir, "CONTEXT.md"), "# M003 Context\n");
343
- run("git add .", tempDir);
344
- run("git commit -m \"add milestone\"", tempDir);
314
+ commitMilestoneContext(tempDir, "M003");
345
315
 
346
316
  const planRelPath = join(".gsd", "milestones", "M004", "slices", "S01", "S01-PLAN.md");
347
317
  const planDir = join(tempDir, ".gsd", "milestones", "M004", "slices", "S01");
@@ -401,11 +371,7 @@ describe("auto-worktree lifecycle", () => {
401
371
 
402
372
  test("#2791: mcp.json is not copied into worktree on creation after copyPlanningArtifacts removal", () => {
403
373
  tempDir = createTempRepo();
404
- const msDir = join(tempDir, ".gsd", "milestones", "M003");
405
- mkdirSync(msDir, { recursive: true });
406
- writeFileSync(join(msDir, "CONTEXT.md"), "# M003 Context\n");
407
- run("git add .", tempDir);
408
- run("git commit -m \"add milestone\"", tempDir);
374
+ commitMilestoneContext(tempDir, "M003");
409
375
 
410
376
  // Create mcp.json in .gsd/ AFTER the commit (untracked, like real usage).
411
377
  // Phase C removed copyPlanningArtifacts, so creation should not seed a
@@ -430,11 +396,7 @@ describe("auto-worktree lifecycle", () => {
430
396
 
431
397
  test("#2791: mcp.json synced via syncGsdStateToWorktree (ROOT_STATE_FILES)", () => {
432
398
  tempDir = createTempRepo();
433
- const msDir = join(tempDir, ".gsd", "milestones", "M003");
434
- mkdirSync(msDir, { recursive: true });
435
- writeFileSync(join(msDir, "CONTEXT.md"), "# M003 Context\n");
436
- run("git add .", tempDir);
437
- run("git commit -m \"add milestone\"", tempDir);
399
+ commitMilestoneContext(tempDir, "M003");
438
400
 
439
401
  // Create worktree first (no mcp.json yet)
440
402
  const wtPath = createAutoWorktree(tempDir, "M003");
@@ -0,0 +1,80 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { dirname, join } from "node:path";
5
+
6
+ export type GsdIntegrationProject = {
7
+ root: string;
8
+ };
9
+
10
+ export type CreateGsdIntegrationProjectOptions = {
11
+ prefix?: string;
12
+ initialFiles?: Record<string, string>;
13
+ };
14
+
15
+ export function projectRoot(project: GsdIntegrationProject | string): string {
16
+ return typeof project === "string" ? project : project.root;
17
+ }
18
+
19
+ export function git(project: GsdIntegrationProject | string, ...args: string[]): string {
20
+ return execFileSync("git", args, {
21
+ cwd: projectRoot(project),
22
+ encoding: "utf-8",
23
+ stdio: ["ignore", "pipe", "pipe"],
24
+ }).trim();
25
+ }
26
+
27
+ export function createGsdIntegrationProject(
28
+ options: CreateGsdIntegrationProjectOptions | string = {},
29
+ ): GsdIntegrationProject {
30
+ const resolvedOptions = typeof options === "string" ? { prefix: options } : options;
31
+ const prefix = resolvedOptions.prefix ?? "gsd-integration-";
32
+ const root = realpathSync(mkdtempSync(join(tmpdir(), prefix)));
33
+
34
+ git(root, "init");
35
+ git(root, "config", "user.email", "test@test.com");
36
+ git(root, "config", "user.name", "Test");
37
+ git(root, "config", "core.autocrlf", "false");
38
+
39
+ writeProjectFile(root, "README.md", "# test\n");
40
+ for (const [relativePath, content] of Object.entries(resolvedOptions.initialFiles ?? {})) {
41
+ writeProjectFile(root, relativePath, content);
42
+ }
43
+ git(root, "add", ".");
44
+ git(root, "commit", "-m", "init");
45
+ git(root, "branch", "-M", "main");
46
+
47
+ return { root };
48
+ }
49
+
50
+ export function writeProjectFile(
51
+ project: GsdIntegrationProject | string,
52
+ relativePath: string,
53
+ content: string,
54
+ ): string {
55
+ const filePath = join(projectRoot(project), relativePath);
56
+ mkdirSync(dirname(filePath), { recursive: true });
57
+ writeFileSync(filePath, content, "utf-8");
58
+ return filePath;
59
+ }
60
+
61
+ export function writeGsdMilestoneContext(
62
+ project: GsdIntegrationProject | string,
63
+ milestoneId: string,
64
+ content = `# ${milestoneId} Context\n`,
65
+ ): string {
66
+ return writeProjectFile(
67
+ project,
68
+ join(".gsd", "milestones", milestoneId, "CONTEXT.md"),
69
+ content,
70
+ );
71
+ }
72
+
73
+ export function commitAll(project: GsdIntegrationProject | string, message: string): void {
74
+ git(project, "add", ".");
75
+ git(project, "commit", "-m", message);
76
+ }
77
+
78
+ export function cleanupGsdIntegrationProject(project: GsdIntegrationProject | string): void {
79
+ rmSync(projectRoot(project), { recursive: true, force: true });
80
+ }