@opengsd/gsd-pi 1.3.0-dev.eed73bea → 1.4.0-dev.5fc22c6f

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 (550) hide show
  1. package/README.md +11 -11
  2. package/dist/cli.js +17 -4
  3. package/dist/headless-answers.js +1 -1
  4. package/dist/headless-ui.d.ts +1 -1
  5. package/dist/headless-ui.js +1 -1
  6. package/dist/headless.js +1 -1
  7. package/dist/onboarding.js +11 -0
  8. package/dist/resources/.managed-resources-content-hash +1 -1
  9. package/dist/resources/GSD-WORKFLOW.md +20 -25
  10. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  11. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +61 -50
  12. package/dist/resources/extensions/cursor-cli/index.js +16 -0
  13. package/dist/resources/extensions/cursor-cli/models.js +63 -0
  14. package/dist/resources/extensions/cursor-cli/package.json +11 -0
  15. package/dist/resources/extensions/cursor-cli/readiness.js +128 -0
  16. package/dist/resources/extensions/cursor-cli/stream-adapter.js +353 -0
  17. package/dist/resources/extensions/gsd/activity-log.js +4 -1
  18. package/dist/resources/extensions/gsd/artifact-verification.js +431 -0
  19. package/dist/resources/extensions/gsd/auto/session.js +11 -0
  20. package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +1 -1
  21. package/dist/resources/extensions/gsd/auto-artifact-paths.js +28 -1
  22. package/dist/resources/extensions/gsd/auto-budget.js +5 -1
  23. package/dist/resources/extensions/gsd/auto-dispatch.js +32 -11
  24. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -18
  25. package/dist/resources/extensions/gsd/auto-post-unit.js +1 -1
  26. package/dist/resources/extensions/gsd/auto-prompts.js +83 -25
  27. package/dist/resources/extensions/gsd/auto-recovery.js +9 -517
  28. package/dist/resources/extensions/gsd/auto-runtime-state.js +4 -5
  29. package/dist/resources/extensions/gsd/auto-start.js +4 -3
  30. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +7 -3
  31. package/dist/resources/extensions/gsd/auto-verification.js +5 -2
  32. package/dist/resources/extensions/gsd/auto-worktree.js +38 -11
  33. package/dist/resources/extensions/gsd/auto.js +32 -10
  34. package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +39 -0
  35. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +8 -4
  36. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  37. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +147 -23
  38. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +56 -36
  39. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +29 -5
  40. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +3 -1
  41. package/dist/resources/extensions/gsd/codebase-generator.js +157 -19
  42. package/dist/resources/extensions/gsd/commands/handlers/auto.js +1 -1
  43. package/dist/resources/extensions/gsd/commands/handlers/core.js +40 -4
  44. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +154 -2
  45. package/dist/resources/extensions/gsd/commands-usage.js +1 -1
  46. package/dist/resources/extensions/gsd/commands-worktree.js +11 -2
  47. package/dist/resources/extensions/gsd/db/engine.js +4 -1
  48. package/dist/resources/extensions/gsd/db/queries.js +39 -0
  49. package/dist/resources/extensions/gsd/db-memory-fts-schema.js +34 -0
  50. package/dist/resources/extensions/gsd/db-workspace.js +55 -3
  51. package/dist/resources/extensions/gsd/delegation-policy.js +1 -1
  52. package/dist/resources/extensions/gsd/discussion-handoff.js +8 -3
  53. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -4
  54. package/dist/resources/extensions/gsd/doctor-engine-checks.js +227 -5
  55. package/dist/resources/extensions/gsd/doctor-providers.js +38 -10
  56. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +3 -0
  57. package/dist/resources/extensions/gsd/doctor.js +93 -3
  58. package/dist/resources/extensions/gsd/exec-sandbox.js +14 -4
  59. package/dist/resources/extensions/gsd/flat-phase-migration.js +119 -23
  60. package/dist/resources/extensions/gsd/git-service.js +61 -8
  61. package/dist/resources/extensions/gsd/gitignore.js +4 -1
  62. package/dist/resources/extensions/gsd/guidance.js +1 -0
  63. package/dist/resources/extensions/gsd/guided-flow-queue.js +20 -13
  64. package/dist/resources/extensions/gsd/guided-flow.js +40 -2
  65. package/dist/resources/extensions/gsd/json-persistence.js +20 -0
  66. package/dist/resources/extensions/gsd/key-manager.js +1 -0
  67. package/dist/resources/extensions/gsd/knowledge-backfill.js +18 -11
  68. package/dist/resources/extensions/gsd/layout-policy.js +3 -1
  69. package/dist/resources/extensions/gsd/markdown-renderer.js +27 -15
  70. package/dist/resources/extensions/gsd/memory-backfill.js +28 -21
  71. package/dist/resources/extensions/gsd/metrics.js +4 -4
  72. package/dist/resources/extensions/gsd/migrate-external.js +22 -5
  73. package/dist/resources/extensions/gsd/migration-auto-check.js +22 -0
  74. package/dist/resources/extensions/gsd/milestone-ids.js +32 -2
  75. package/dist/resources/extensions/gsd/orphan-stash-audit.js +92 -16
  76. package/dist/resources/extensions/gsd/preferences-diagnostics.js +24 -1
  77. package/dist/resources/extensions/gsd/preferences-models.js +6 -4
  78. package/dist/resources/extensions/gsd/preferences-validation.js +25 -2
  79. package/dist/resources/extensions/gsd/preferences.js +29 -2
  80. package/dist/resources/extensions/gsd/prompts/code-review.md +6 -4
  81. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  82. package/dist/resources/extensions/gsd/prompts/plan-slice.md +5 -3
  83. package/dist/resources/extensions/gsd/redact-secrets.js +37 -0
  84. package/dist/resources/extensions/gsd/repository-registry.js +6 -1
  85. package/dist/resources/extensions/gsd/root-write-leak-guard.js +7 -1
  86. package/dist/resources/extensions/gsd/safe-fs.js +23 -2
  87. package/dist/resources/extensions/gsd/safety/destructive-guard.js +8 -1
  88. package/dist/resources/extensions/gsd/safety/evidence-collector.js +16 -1
  89. package/dist/resources/extensions/gsd/safety/file-change-validator.js +5 -2
  90. package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
  91. package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +2 -1
  92. package/dist/resources/extensions/gsd/state/derive/cache.js +28 -0
  93. package/dist/resources/extensions/gsd/state/derive/db-open.js +39 -0
  94. package/dist/resources/extensions/gsd/state/derive/from-db.js +452 -0
  95. package/dist/resources/extensions/gsd/state/derive/index.js +75 -0
  96. package/dist/resources/extensions/gsd/state/derive/interrupted-work.js +21 -0
  97. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +27 -33
  98. package/dist/resources/extensions/gsd/state-reconciliation/index.js +48 -23
  99. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +32 -28
  100. package/dist/resources/extensions/gsd/state.js +12 -611
  101. package/dist/resources/extensions/gsd/tools/complete-milestone.js +4 -2
  102. package/dist/resources/extensions/gsd/tools/complete-slice.js +3 -34
  103. package/dist/resources/extensions/gsd/tools/complete-task.js +8 -41
  104. package/dist/resources/extensions/gsd/tools/plan-slice.js +59 -44
  105. package/dist/resources/extensions/gsd/tools/plan-task.js +103 -12
  106. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +40 -0
  107. package/dist/resources/extensions/gsd/undo.js +43 -6
  108. package/dist/resources/extensions/gsd/unit-context-manifest.js +5 -4
  109. package/dist/resources/extensions/gsd/unit-registry.js +11 -3
  110. package/dist/resources/extensions/gsd/unit-runtime.js +21 -0
  111. package/dist/resources/extensions/gsd/verification-gate.js +7 -0
  112. package/dist/resources/extensions/gsd/workflow-manifest.js +126 -13
  113. package/dist/resources/extensions/gsd/workflow-projections.js +19 -14
  114. package/dist/resources/extensions/gsd/workspace.js +26 -8
  115. package/dist/resources/extensions/gsd/worktree-manager.js +140 -5
  116. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  117. package/dist/web/standalone/.next/BUILD_ID +1 -1
  118. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  119. package/dist/web/standalone/.next/build-manifest.json +3 -3
  120. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  121. package/dist/web/standalone/.next/react-loadable-manifest.json +9 -9
  122. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  133. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  141. package/dist/web/standalone/.next/server/app/index.html +1 -1
  142. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  143. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  144. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  145. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  150. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  151. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  154. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  155. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  156. package/dist/web/standalone/.next/static/chunks/{2659.b7b129ee6a769448.js → 2659.58e950899a9bb82f.js} +1 -1
  157. package/dist/web/standalone/.next/static/chunks/2772.a7c1fcc69a4685ef.js +1 -0
  158. package/dist/web/standalone/.next/static/chunks/{3616.3c60753b8ffcbd2e.js → 3616.61a2af74bb8833c8.js} +1 -1
  159. package/dist/web/standalone/.next/static/chunks/{4283.8e446784528ed9dc.js → 4283.d0d9e0a955e441cb.js} +1 -1
  160. package/dist/web/standalone/.next/static/chunks/{5826.a46ecdd1cfe8dabc.js → 5826.5421d66c72b9f34e.js} +1 -1
  161. package/dist/web/standalone/.next/static/chunks/{8785.481aa5869991b760.js → 8785.e29b3134cab1d153.js} +1 -1
  162. package/dist/web/standalone/.next/static/chunks/8937.640dc9c2aaa1dfad.js +10 -0
  163. package/dist/web/standalone/.next/static/chunks/app/{page-6644fc6ee8ca1247.js → page-72a856634ad14c10.js} +1 -1
  164. package/dist/web/standalone/.next/static/chunks/webpack-9c401904f87ded16.js +1 -0
  165. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  166. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  167. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  168. package/dist/wizard.d.ts +8 -0
  169. package/dist/wizard.js +8 -1
  170. package/integrations/hermes/__init__.py +31 -0
  171. package/integrations/hermes/tests/test_directory_loader.py +37 -0
  172. package/package.json +8 -8
  173. package/packages/cloud-mcp-gateway/dist/auth-store.d.ts +1 -0
  174. package/packages/cloud-mcp-gateway/dist/auth-store.d.ts.map +1 -1
  175. package/packages/cloud-mcp-gateway/dist/auth-store.js +21 -1
  176. package/packages/cloud-mcp-gateway/dist/auth-store.js.map +1 -1
  177. package/packages/cloud-mcp-gateway/dist/auth-store.test.js +34 -0
  178. package/packages/cloud-mcp-gateway/dist/auth-store.test.js.map +1 -1
  179. package/packages/cloud-mcp-gateway/package.json +2 -2
  180. package/packages/contracts/package.json +1 -1
  181. package/packages/daemon/dist/cloud-runtime.d.ts +2 -0
  182. package/packages/daemon/dist/cloud-runtime.d.ts.map +1 -1
  183. package/packages/daemon/dist/cloud-runtime.js +25 -1
  184. package/packages/daemon/dist/cloud-runtime.js.map +1 -1
  185. package/packages/daemon/dist/cloud-runtime.test.js +51 -0
  186. package/packages/daemon/dist/cloud-runtime.test.js.map +1 -1
  187. package/packages/daemon/dist/message-batcher.d.ts +7 -0
  188. package/packages/daemon/dist/message-batcher.d.ts.map +1 -1
  189. package/packages/daemon/dist/message-batcher.js +13 -0
  190. package/packages/daemon/dist/message-batcher.js.map +1 -1
  191. package/packages/daemon/dist/message-batcher.test.js +48 -0
  192. package/packages/daemon/dist/message-batcher.test.js.map +1 -1
  193. package/packages/daemon/package.json +5 -5
  194. package/packages/gsd-agent-core/dist/agent-session.d.ts +1 -0
  195. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  196. package/packages/gsd-agent-core/dist/agent-session.js +3 -0
  197. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  198. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts +13 -1
  199. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
  200. package/packages/gsd-agent-core/dist/compaction/compaction.js +15 -1
  201. package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
  202. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts +41 -0
  203. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts.map +1 -0
  204. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js +62 -0
  205. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js.map +1 -0
  206. package/packages/gsd-agent-core/dist/index.d.ts +2 -0
  207. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  208. package/packages/gsd-agent-core/dist/index.js +2 -0
  209. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  210. package/packages/gsd-agent-core/dist/session/agent-session-events.js +1 -1
  211. package/packages/gsd-agent-core/dist/session/agent-session-events.js.map +1 -1
  212. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +1 -0
  213. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  214. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  215. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts +5 -0
  216. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  217. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +60 -3
  218. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  219. package/packages/gsd-agent-core/dist/transcript-store.d.ts +58 -0
  220. package/packages/gsd-agent-core/dist/transcript-store.d.ts.map +1 -0
  221. package/packages/gsd-agent-core/dist/transcript-store.js +132 -0
  222. package/packages/gsd-agent-core/dist/transcript-store.js.map +1 -0
  223. package/packages/gsd-agent-core/package.json +5 -5
  224. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  225. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  226. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +25 -11
  227. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  228. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts +4 -0
  229. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts.map +1 -0
  230. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js +7 -0
  231. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js.map +1 -0
  232. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -24
  233. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  234. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -841
  235. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  236. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts +58 -0
  237. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts.map +1 -0
  238. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js +312 -0
  239. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js.map +1 -0
  240. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts +31 -0
  241. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts.map +1 -0
  242. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js +130 -0
  243. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js.map +1 -0
  244. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts +15 -0
  245. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -0
  246. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +259 -0
  247. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -0
  248. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts +13 -0
  249. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts.map +1 -0
  250. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js +118 -0
  251. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js.map +1 -0
  252. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +9 -0
  253. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  254. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js +1 -1
  255. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  256. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts +54 -0
  257. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts.map +1 -0
  258. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js +20 -0
  259. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js.map +1 -0
  260. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +4 -1
  261. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  262. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +9 -0
  263. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  264. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts +56 -0
  265. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts.map +1 -0
  266. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js +44 -0
  267. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js.map +1 -0
  268. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts +5 -0
  269. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts.map +1 -0
  270. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js +77 -0
  271. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js.map +1 -0
  272. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts +2 -0
  273. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  274. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +24 -6
  275. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
  276. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  277. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +18 -0
  278. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  279. package/packages/gsd-agent-modes/package.json +7 -7
  280. package/packages/mcp-server/dist/workflow-tools.js +1 -1
  281. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  282. package/packages/mcp-server/package.json +4 -4
  283. package/packages/native/package.json +1 -1
  284. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  285. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  286. package/packages/pi-agent-core/package.json +1 -1
  287. package/packages/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  288. package/packages/pi-ai/dist/env-api-keys.js +3 -0
  289. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  290. package/packages/pi-ai/dist/models.generated.d.ts +46 -0
  291. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  292. package/packages/pi-ai/dist/models.generated.js +38 -0
  293. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  294. package/packages/pi-ai/dist/types.d.ts +2 -2
  295. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  296. package/packages/pi-ai/dist/types.js.map +1 -1
  297. package/packages/pi-ai/package.json +1 -1
  298. package/packages/pi-coding-agent/README.md +3 -2
  299. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  300. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  301. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  302. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts +9 -0
  303. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts.map +1 -0
  304. package/packages/pi-coding-agent/dist/core/session-manager-context.js +94 -0
  305. package/packages/pi-coding-agent/dist/core/session-manager-context.js.map +1 -0
  306. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts +8 -0
  307. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts.map +1 -0
  308. package/packages/pi-coding-agent/dist/core/session-manager-list.js +244 -0
  309. package/packages/pi-coding-agent/dist/core/session-manager-list.js.map +1 -0
  310. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts +12 -0
  311. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts.map +1 -0
  312. package/packages/pi-coding-agent/dist/core/session-manager-migration.js +84 -0
  313. package/packages/pi-coding-agent/dist/core/session-manager-migration.js.map +1 -0
  314. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +135 -0
  315. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -0
  316. package/packages/pi-coding-agent/dist/core/session-manager-types.js +2 -0
  317. package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -0
  318. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +6 -154
  319. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  320. package/packages/pi-coding-agent/dist/core/session-manager.js +22 -459
  321. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  322. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts +75 -75
  323. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts.map +1 -1
  324. package/packages/pi-coding-agent/dist/theme/theme-schema.js +1 -1
  325. package/packages/pi-coding-agent/dist/theme/theme-schema.js.map +1 -1
  326. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  327. package/packages/pi-coding-agent/dist/theme/theme.js +11 -7
  328. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  329. package/packages/pi-coding-agent/package.json +7 -7
  330. package/packages/pi-tui/package.json +2 -2
  331. package/packages/rpc-client/dist/rpc-client.js +1 -1
  332. package/packages/rpc-client/dist/rpc-client.js.map +1 -1
  333. package/packages/rpc-client/package.json +2 -2
  334. package/pkg/dist/theme/theme-schema.d.ts +75 -75
  335. package/pkg/dist/theme/theme-schema.d.ts.map +1 -1
  336. package/pkg/dist/theme/theme-schema.js +1 -1
  337. package/pkg/dist/theme/theme-schema.js.map +1 -1
  338. package/pkg/dist/theme/theme.d.ts.map +1 -1
  339. package/pkg/dist/theme/theme.js +11 -7
  340. package/pkg/dist/theme/theme.js.map +1 -1
  341. package/pkg/package.json +1 -1
  342. package/scripts/link-workspace-packages.cjs +14 -4
  343. package/src/resources/GSD-WORKFLOW.md +20 -25
  344. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  345. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +67 -49
  346. package/src/resources/extensions/claude-code-cli/tests/index.test.ts +14 -0
  347. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +159 -0
  348. package/src/resources/extensions/cursor-cli/index.ts +18 -0
  349. package/src/resources/extensions/cursor-cli/models.ts +65 -0
  350. package/src/resources/extensions/cursor-cli/package.json +11 -0
  351. package/src/resources/extensions/cursor-cli/readiness.ts +143 -0
  352. package/src/resources/extensions/cursor-cli/stream-adapter.ts +440 -0
  353. package/src/resources/extensions/cursor-cli/tests/index.test.ts +54 -0
  354. package/src/resources/extensions/cursor-cli/tests/readiness.test.ts +29 -0
  355. package/src/resources/extensions/cursor-cli/tests/stream-adapter.test.ts +166 -0
  356. package/src/resources/extensions/gsd/activity-log.ts +4 -1
  357. package/src/resources/extensions/gsd/artifact-verification.ts +468 -0
  358. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  359. package/src/resources/extensions/gsd/auto/session.ts +14 -0
  360. package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +3 -1
  361. package/src/resources/extensions/gsd/auto-artifact-paths.ts +47 -1
  362. package/src/resources/extensions/gsd/auto-budget.ts +12 -1
  363. package/src/resources/extensions/gsd/auto-dispatch.ts +34 -12
  364. package/src/resources/extensions/gsd/auto-model-selection.ts +49 -18
  365. package/src/resources/extensions/gsd/auto-post-unit.ts +1 -1
  366. package/src/resources/extensions/gsd/auto-prompts.ts +80 -25
  367. package/src/resources/extensions/gsd/auto-recovery.ts +13 -518
  368. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -5
  369. package/src/resources/extensions/gsd/auto-start.ts +4 -3
  370. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +7 -2
  371. package/src/resources/extensions/gsd/auto-verification.ts +5 -1
  372. package/src/resources/extensions/gsd/auto-worktree.ts +50 -11
  373. package/src/resources/extensions/gsd/auto.ts +36 -8
  374. package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +44 -0
  375. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +8 -4
  376. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  377. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +171 -23
  378. package/src/resources/extensions/gsd/bootstrap/tests/write-gate-basepath.test.ts +49 -1
  379. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +60 -37
  380. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +39 -5
  381. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +2 -1
  382. package/src/resources/extensions/gsd/codebase-generator.ts +179 -18
  383. package/src/resources/extensions/gsd/commands/handlers/auto.ts +1 -1
  384. package/src/resources/extensions/gsd/commands/handlers/core.ts +39 -3
  385. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +136 -2
  386. package/src/resources/extensions/gsd/commands-usage.ts +1 -1
  387. package/src/resources/extensions/gsd/commands-worktree.ts +13 -2
  388. package/src/resources/extensions/gsd/db/engine.ts +8 -1
  389. package/src/resources/extensions/gsd/db/queries.ts +40 -0
  390. package/src/resources/extensions/gsd/db-memory-fts-schema.ts +45 -0
  391. package/src/resources/extensions/gsd/db-workspace.ts +61 -3
  392. package/src/resources/extensions/gsd/delegation-policy.ts +1 -1
  393. package/src/resources/extensions/gsd/discussion-handoff.ts +10 -2
  394. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -4
  395. package/src/resources/extensions/gsd/doctor-engine-checks.ts +275 -5
  396. package/src/resources/extensions/gsd/doctor-providers.ts +39 -10
  397. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +3 -0
  398. package/src/resources/extensions/gsd/doctor-types.ts +8 -1
  399. package/src/resources/extensions/gsd/doctor.ts +95 -3
  400. package/src/resources/extensions/gsd/exec-sandbox.ts +13 -4
  401. package/src/resources/extensions/gsd/flat-phase-migration.ts +142 -22
  402. package/src/resources/extensions/gsd/git-service.ts +70 -9
  403. package/src/resources/extensions/gsd/gitignore.ts +4 -1
  404. package/src/resources/extensions/gsd/guidance.ts +2 -0
  405. package/src/resources/extensions/gsd/guided-flow-queue.ts +20 -13
  406. package/src/resources/extensions/gsd/guided-flow.ts +45 -2
  407. package/src/resources/extensions/gsd/json-persistence.ts +20 -0
  408. package/src/resources/extensions/gsd/key-manager.ts +1 -0
  409. package/src/resources/extensions/gsd/knowledge-backfill.ts +16 -10
  410. package/src/resources/extensions/gsd/layout-policy.ts +2 -1
  411. package/src/resources/extensions/gsd/markdown-renderer.ts +27 -17
  412. package/src/resources/extensions/gsd/memory-backfill.ts +26 -20
  413. package/src/resources/extensions/gsd/metrics.ts +4 -4
  414. package/src/resources/extensions/gsd/migrate-external.ts +17 -4
  415. package/src/resources/extensions/gsd/migration-auto-check.ts +23 -0
  416. package/src/resources/extensions/gsd/milestone-ids.ts +31 -2
  417. package/src/resources/extensions/gsd/model-router.ts +4 -5
  418. package/src/resources/extensions/gsd/orphan-stash-audit.ts +108 -20
  419. package/src/resources/extensions/gsd/preferences-diagnostics.ts +24 -0
  420. package/src/resources/extensions/gsd/preferences-models.ts +6 -3
  421. package/src/resources/extensions/gsd/preferences-validation.ts +28 -2
  422. package/src/resources/extensions/gsd/preferences.ts +38 -4
  423. package/src/resources/extensions/gsd/prompts/code-review.md +6 -4
  424. package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  425. package/src/resources/extensions/gsd/prompts/plan-slice.md +5 -3
  426. package/src/resources/extensions/gsd/redact-secrets.ts +40 -0
  427. package/src/resources/extensions/gsd/repository-registry.ts +7 -1
  428. package/src/resources/extensions/gsd/root-write-leak-guard.ts +13 -1
  429. package/src/resources/extensions/gsd/safe-fs.ts +22 -2
  430. package/src/resources/extensions/gsd/safety/destructive-guard.ts +9 -1
  431. package/src/resources/extensions/gsd/safety/evidence-collector.ts +16 -1
  432. package/src/resources/extensions/gsd/safety/file-change-validator.ts +8 -2
  433. package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
  434. package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +2 -1
  435. package/src/resources/extensions/gsd/state/derive/cache.ts +46 -0
  436. package/src/resources/extensions/gsd/state/derive/db-open.ts +45 -0
  437. package/src/resources/extensions/gsd/state/derive/from-db.ts +561 -0
  438. package/src/resources/extensions/gsd/state/derive/index.ts +104 -0
  439. package/src/resources/extensions/gsd/state/derive/interrupted-work.ts +31 -0
  440. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +36 -30
  441. package/src/resources/extensions/gsd/state-reconciliation/index.ts +50 -24
  442. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +43 -28
  443. package/src/resources/extensions/gsd/state.ts +32 -732
  444. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +4 -3
  445. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +98 -1
  446. package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +14 -5
  447. package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +18 -0
  448. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +178 -0
  449. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +36 -0
  450. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +182 -4
  451. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +35 -0
  452. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +41 -0
  453. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +30 -0
  454. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +41 -0
  455. package/src/resources/extensions/gsd/tests/auto-session-scope.test.ts +4 -4
  456. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +3 -0
  457. package/src/resources/extensions/gsd/tests/auto-timeout-recovery-harness-abort.test.ts +55 -0
  458. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +8 -0
  459. package/src/resources/extensions/gsd/tests/batch-task-query.test.ts +85 -0
  460. package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +29 -0
  461. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +365 -0
  462. package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +1 -0
  463. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +62 -1
  464. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +28 -0
  465. package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +69 -0
  466. package/src/resources/extensions/gsd/tests/db-memory-fts-schema.test.ts +58 -3
  467. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +51 -0
  468. package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +44 -0
  469. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +143 -0
  470. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +138 -1
  471. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +296 -2
  472. package/src/resources/extensions/gsd/tests/doctor-workspace.test.ts +207 -0
  473. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +16 -0
  474. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +40 -0
  475. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +74 -2
  476. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +87 -19
  477. package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +89 -0
  478. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +4 -0
  479. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +9 -0
  480. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +11 -2
  481. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
  482. package/src/resources/extensions/gsd/tests/json-persistence-atomic.test.ts +47 -0
  483. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +35 -0
  484. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +122 -0
  485. package/src/resources/extensions/gsd/tests/memory-store.test.ts +48 -0
  486. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +31 -1
  487. package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +6 -0
  488. package/src/resources/extensions/gsd/tests/metrics.test.ts +1 -0
  489. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +57 -0
  490. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +70 -0
  491. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +91 -7
  492. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -1
  493. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +2 -2
  494. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +27 -0
  495. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +103 -4
  496. package/src/resources/extensions/gsd/tests/plan-task.test.ts +307 -1
  497. package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +4 -2
  498. package/src/resources/extensions/gsd/tests/preferences.test.ts +150 -0
  499. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +142 -0
  500. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +50 -14
  501. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +58 -0
  502. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -6
  503. package/src/resources/extensions/gsd/tests/recovery-verify-logs.test.ts +4 -4
  504. package/src/resources/extensions/gsd/tests/redact-secrets.test.ts +56 -0
  505. package/src/resources/extensions/gsd/tests/register-hooks-flat-phase-migration.test.ts +73 -0
  506. package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +378 -0
  507. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +41 -2
  508. package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +55 -0
  509. package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +20 -1
  510. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +15 -3
  511. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +105 -0
  512. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +115 -0
  513. package/src/resources/extensions/gsd/tests/status-per-repo.test.ts +94 -0
  514. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +35 -0
  515. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +203 -0
  516. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +6 -3
  517. package/src/resources/extensions/gsd/tests/undo.test.ts +74 -0
  518. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +66 -18
  519. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +30 -0
  520. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +90 -0
  521. package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +53 -1
  522. package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +69 -4
  523. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +96 -15
  524. package/src/resources/extensions/gsd/tests/workflow-mcp-preflight.test.ts +1 -0
  525. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +8 -4
  526. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +214 -6
  527. package/src/resources/extensions/gsd/tests/workspace.test.ts +18 -4
  528. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +39 -0
  529. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +31 -1
  530. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +32 -0
  531. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  532. package/src/resources/extensions/gsd/tools/complete-slice.ts +3 -30
  533. package/src/resources/extensions/gsd/tools/complete-task.ts +7 -39
  534. package/src/resources/extensions/gsd/tools/plan-slice.ts +60 -47
  535. package/src/resources/extensions/gsd/tools/plan-task.ts +135 -12
  536. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +58 -0
  537. package/src/resources/extensions/gsd/undo.ts +47 -6
  538. package/src/resources/extensions/gsd/unit-context-manifest.ts +11 -5
  539. package/src/resources/extensions/gsd/unit-registry.ts +11 -3
  540. package/src/resources/extensions/gsd/unit-runtime.ts +42 -0
  541. package/src/resources/extensions/gsd/verification-gate.ts +8 -0
  542. package/src/resources/extensions/gsd/workflow-manifest.ts +141 -7
  543. package/src/resources/extensions/gsd/workflow-projections.ts +20 -14
  544. package/src/resources/extensions/gsd/workspace.ts +42 -8
  545. package/src/resources/extensions/gsd/worktree-manager.ts +183 -5
  546. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +0 -1
  547. package/dist/web/standalone/.next/static/chunks/796.3976108148518f7d.js +0 -10
  548. package/dist/web/standalone/.next/static/chunks/webpack-7c1d97e39be2da11.js +0 -1
  549. /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → kIEFsCryyGy6RzifULbJl}/_buildManifest.js +0 -0
  550. /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → kIEFsCryyGy6RzifULbJl}/_ssgManifest.js +0 -0
@@ -65,14 +65,18 @@ test("auto execute-task requires canonical task completion tool", () => {
65
65
  assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("execute-task"), expected);
66
66
  });
67
67
 
68
- test("plan-slice requires planning and roadmap reassessment tools", () => {
69
- const expected = ["gsd_plan_slice", "gsd_reassess_roadmap"];
68
+ test("plan-slice requires slice + incremental task planning and roadmap reassessment tools", () => {
69
+ // Incremental planning (#1027): gsd_plan_slice persists metadata, then
70
+ // gsd_plan_task adds tasks one at a time, so both must be on the surface.
71
+ const expected = ["gsd_plan_slice", "gsd_plan_task", "gsd_reassess_roadmap"];
70
72
  assert.deepEqual(getRequiredWorkflowToolsForGuidedUnit("plan-slice"), expected);
71
73
  assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("plan-slice"), expected);
72
74
  });
73
75
 
74
- test("plan-milestone requires status, roadmap, and single-slice planning tools", () => {
75
- const expected = ["gsd_milestone_status", "gsd_plan_milestone", "gsd_plan_slice"];
76
+ test("plan-milestone requires status, roadmap, and slice + task planning tools", () => {
77
+ // gsd_plan_task is required alongside gsd_plan_slice for incremental
78
+ // milestone planning (#1027).
79
+ const expected = ["gsd_milestone_status", "gsd_plan_milestone", "gsd_plan_slice", "gsd_plan_task"];
76
80
  assert.deepEqual(getRequiredWorkflowToolsForGuidedUnit("plan-milestone"), expected);
77
81
  assert.deepEqual(getRequiredWorkflowToolsForAutoUnit("plan-milestone"), expected);
78
82
  });
@@ -12,6 +12,7 @@ import {
12
12
  getArtifact,
13
13
  getAssessment,
14
14
  insertAssessment,
15
+ insertGateRow,
15
16
  insertMilestone,
16
17
  upsertRequirement,
17
18
  getAllMilestones,
@@ -21,6 +22,7 @@ import { claimMilestoneLease, getMilestoneLease } from "../db/milestone-leases.t
21
22
  import { deriveState, invalidateStateCache } from "../state.ts";
22
23
  import { autoSession } from "../auto-runtime-state.ts";
23
24
  import { normalizeRealPath } from "../paths.ts";
25
+ import { recordUnitHarnessAbort } from "../unit-runtime.ts";
24
26
  import { markApprovalGateVerified, markDepthVerified, clearDiscussionFlowState, loadWriteGateSnapshot, setPendingGate } from "../bootstrap/write-gate.ts";
25
27
  import {
26
28
  executeCompleteMilestone,
@@ -37,6 +39,11 @@ import {
37
39
  executeValidateMilestone,
38
40
  executeUatResultSave,
39
41
  } from "../tools/workflow-tool-executors.ts";
42
+ import {
43
+ initNotificationStore,
44
+ readNotifications,
45
+ _resetNotificationStore,
46
+ } from "../notification-store.ts";
40
47
 
41
48
  function makeTmpBase(): string {
42
49
  const base = join(tmpdir(), `gsd-workflow-executors-${randomUUID()}`);
@@ -781,22 +788,23 @@ test("executePlanSlice writes task planning state and rendered plan artifacts",
781
788
  }
782
789
  });
783
790
 
784
- test("executePlanSlice marks validation failures with isError", async () => {
791
+ test("executePlanSlice accepts metadata-only incremental planning payloads", async () => {
785
792
  const base = makeTmpBase();
786
793
  try {
787
794
  openTestDb(base);
795
+ await inProjectDir(base, () => executePlanMilestone(validMilestonePlan(), base));
788
796
 
789
797
  const result = await inProjectDir(base, () => executePlanSlice({
790
798
  milestoneId: "M001",
791
799
  sliceId: "S01",
792
- goal: "Trigger validation failure for empty tasks.",
800
+ goal: "Persist slice metadata before tasks.",
793
801
  tasks: [],
794
802
  }, base));
795
803
 
796
- assert.equal(result.isError, true);
797
804
  assert.equal(result.details.operation, "plan_slice");
798
- assert.match(String(result.details.error), /validation failed: tasks must be a non-empty array/);
799
- assert.match(result.content[0].text, /Error planning slice:/);
805
+ assert.equal(result.details.sliceId, "S01");
806
+ assert.equal(result.isError, undefined);
807
+ assert.match(result.content[0].text, /Planned slice S01/);
800
808
  } finally {
801
809
  closeDatabase();
802
810
  cleanup(base);
@@ -909,6 +917,104 @@ test("executeUatResultSave accepts gsd_uat_exec evidence written in a milestone
909
917
  }
910
918
  });
911
919
 
920
+ test("executeUatResultSave leaves UAT pending after a harness-aborted turn", async () => {
921
+ const base = makeTmpBase();
922
+ const worktree = join(base, ".gsd", "worktrees", "M001");
923
+ const worktreeExecDir = join(worktree, ".gsd", "exec");
924
+ const evidenceId = "harness-aborted-uat-evidence";
925
+ const startedAt = Date.now();
926
+ try {
927
+ openTestDb(base);
928
+ seedMilestone("M001", "Milestone One");
929
+ seedSlice("M001", "S04", "complete");
930
+ mkdirSync(worktreeExecDir, { recursive: true });
931
+ writeFileSync(
932
+ join(worktreeExecDir, `${evidenceId}.meta.json`),
933
+ JSON.stringify({
934
+ id: evidenceId,
935
+ metadata: {
936
+ kind: "uat_exec",
937
+ milestoneId: "M001",
938
+ sliceId: "S04",
939
+ checkId: "UAT-01",
940
+ intent: "uat-runtime-check",
941
+ },
942
+ }),
943
+ "utf-8",
944
+ );
945
+ _getAdapter()!.prepare(
946
+ `INSERT INTO quality_gates (milestone_id, slice_id, gate_id, scope, task_id, status)
947
+ VALUES (?, ?, ?, ?, ?, ?)`,
948
+ ).run("M001", "S04", "UAT", "slice", "", "pending");
949
+ autoSession.reset();
950
+ autoSession.active = true;
951
+ autoSession.basePath = base;
952
+ autoSession.currentUnit = { type: "run-uat", id: "M001/S04", startedAt, workspaceRoot: worktree };
953
+ recordUnitHarnessAbort(base, "run-uat", "M001/S04", startedAt, {
954
+ kind: "tool-loop-guard",
955
+ reason: "Tool loop detected (repeated tool): browser_click called 7 times this turn.",
956
+ toolName: "browser_click",
957
+ count: 7,
958
+ });
959
+
960
+ const result = await inProjectDir(worktree, () => executeUatResultSave({
961
+ milestoneId: "M001",
962
+ sliceId: "S04",
963
+ uatType: "runtime-executable",
964
+ verdict: "FAIL",
965
+ checks: [{
966
+ id: "UAT-01",
967
+ description: "Runtime behavior could not be fully evaluated before harness abort",
968
+ mode: "runtime",
969
+ result: "FAIL",
970
+ evidence: [{ kind: "gsd_uat_exec", ref: evidenceId }],
971
+ notes: "Partial failure should be retried because the harness aborted the turn.",
972
+ }],
973
+ presentation: {
974
+ surface: "mcp",
975
+ presentedTools: [
976
+ "gsd_uat_exec",
977
+ "gsd_uat_result_save",
978
+ "gsd_resume",
979
+ "gsd_milestone_status",
980
+ "gsd_journal_query",
981
+ ],
982
+ blockedTools: [
983
+ { name: "gsd_exec", reason: "forbidden during run-uat" },
984
+ { name: "gsd_summary_save", reason: "forbidden during run-uat" },
985
+ { name: "gsd_save_gate_result", reason: "forbidden during run-uat" },
986
+ ],
987
+ },
988
+ notes: "Partial UAT result after harness abort.",
989
+ }, worktree));
990
+
991
+ assert.equal(result.isError, true);
992
+ assert.equal(result.details.operation, "save_uat_result");
993
+ assert.equal(result.details.error, "harness_aborted_needs_retry");
994
+ assert.equal(result.details.retryable, true);
995
+ assert.equal(result.details.harnessAbortKind, "tool-loop-guard");
996
+ assert.equal(
997
+ existsSync(join(base, ".gsd", "uat", "M001", "S04", "attempt-1.json")),
998
+ false,
999
+ "harness-aborted UAT should not persist an attempt artifact",
1000
+ );
1001
+ assert.equal(
1002
+ existsSync(join(base, ".gsd", "phases", "01-m001", "01-04-ASSESSMENT.md")),
1003
+ false,
1004
+ "harness-aborted UAT should not write an ASSESSMENT verdict",
1005
+ );
1006
+ const row = _getAdapter()!.prepare(
1007
+ "SELECT status, verdict FROM quality_gates WHERE milestone_id = ? AND slice_id = ? AND gate_id = ?",
1008
+ ).get("M001", "S04", "UAT") as Record<string, unknown>;
1009
+ assert.equal(row.status, "pending");
1010
+ assert.equal(row.verdict, "");
1011
+ } finally {
1012
+ autoSession.reset();
1013
+ closeDatabase();
1014
+ cleanup(base);
1015
+ }
1016
+ });
1017
+
912
1018
  test("executeUatResultSave supplies canonical presentation and normalizes verdict casing", async () => {
913
1019
  const base = makeTmpBase();
914
1020
  const worktree = join(base, ".gsd", "worktrees", "M001");
@@ -1099,13 +1205,14 @@ test("executeUatResultSave merges canonical plan ID and read-only tools when pre
1099
1205
  }
1100
1206
  });
1101
1207
 
1102
- test("executeUatResultSave surfaces the worktree validation path for NEEDS-HUMAN checks", async () => {
1208
+ test("executeUatResultSave surfaces the worktree validation path and notification for NEEDS-HUMAN checks", async () => {
1103
1209
  const base = makeTmpBase();
1104
1210
  const worktree = join(base, ".gsd", "worktrees", "M001");
1105
1211
  const worktreeExecDir = join(worktree, ".gsd", "exec");
1106
1212
  const evidenceId = "uat-human-validation-evidence";
1107
1213
  try {
1108
1214
  openTestDb(base);
1215
+ initNotificationStore(base);
1109
1216
  seedMilestone("M001", "Milestone One");
1110
1217
  seedSlice("M001", "S07", "complete");
1111
1218
  mkdirSync(worktreeExecDir, { recursive: true });
@@ -1165,7 +1272,17 @@ test("executeUatResultSave surfaces the worktree validation path for NEEDS-HUMAN
1165
1272
  assert.match(assessment, /## Manual Validation/);
1166
1273
  assert.ok(assessment.includes(worktree), "assessment should include the worktree checkout path");
1167
1274
  assert.match(assessment, /git worktree/);
1275
+
1276
+ const notifications = readNotifications(base, { kind: "uat-needs-human", scope: "M001/S07" });
1277
+ assert.equal(notifications.length, 1);
1278
+ assert.equal(notifications[0].severity, "warning");
1279
+ assert.equal(notifications[0].source, "notify");
1280
+ assert.equal(
1281
+ notifications[0].message,
1282
+ "UAT for M001/S07 has NEEDS-HUMAN checks awaiting human validation",
1283
+ );
1168
1284
  } finally {
1285
+ _resetNotificationStore();
1169
1286
  closeDatabase();
1170
1287
  cleanup(base);
1171
1288
  }
@@ -1756,6 +1873,97 @@ test("executeSaveGateResult validates inputs and persists verdicts", async () =>
1756
1873
  }
1757
1874
  });
1758
1875
 
1876
+ test("executeSaveGateResult leaves quality gates pending after a retryable tool error", async () => {
1877
+ const base = makeTmpBase();
1878
+ const startedAt = Date.now();
1879
+ try {
1880
+ openTestDb(base);
1881
+ seedMilestone("M005", "Milestone Five");
1882
+ seedSlice("M005", "S05", "pending");
1883
+ insertGateRow({ milestoneId: "M005", sliceId: "S05", gateId: "Q3", scope: "slice" });
1884
+ autoSession.reset();
1885
+ autoSession.active = true;
1886
+ autoSession.basePath = base;
1887
+ autoSession.currentUnit = { type: "plan-slice", id: "M005/S05", startedAt };
1888
+ recordUnitHarnessAbort(base, "plan-slice", "M005/S05", startedAt, {
1889
+ kind: "tool-error",
1890
+ reason: "Input validation error: selector is required",
1891
+ toolName: "browser_click",
1892
+ });
1893
+
1894
+ const result = await inProjectDir(base, () => executeSaveGateResult({
1895
+ milestoneId: "M005",
1896
+ sliceId: "S05",
1897
+ gateId: "Q3",
1898
+ verdict: "flag",
1899
+ rationale: "Partial gate failure after harness abort.",
1900
+ findings: "This should not be persisted as a product-quality finding.",
1901
+ }, base));
1902
+
1903
+ assert.equal(result.isError, true);
1904
+ assert.equal(result.details.operation, "save_gate_result");
1905
+ assert.equal(result.details.error, "harness_aborted_needs_retry");
1906
+ assert.equal(result.details.retryable, true);
1907
+ assert.equal(result.details.harnessAbortKind, "tool-error");
1908
+ const row = _getAdapter()!.prepare(
1909
+ "SELECT status, verdict, rationale, findings FROM quality_gates WHERE milestone_id = ? AND slice_id = ? AND gate_id = ? AND task_id = ''",
1910
+ ).get("M005", "S05", "Q3") as Record<string, unknown>;
1911
+ assert.equal(row.status, "pending");
1912
+ assert.equal(row.verdict, "");
1913
+ assert.equal(row.rationale, "");
1914
+ assert.equal(row.findings, "");
1915
+ } finally {
1916
+ autoSession.reset();
1917
+ closeDatabase();
1918
+ cleanup(base);
1919
+ }
1920
+ });
1921
+
1922
+ test("executeSaveGateResult leaves quality gates pending after a turn abort", async () => {
1923
+ const base = makeTmpBase();
1924
+ const startedAt = Date.now();
1925
+ try {
1926
+ openTestDb(base);
1927
+ seedMilestone("M005", "Milestone Five");
1928
+ seedSlice("M005", "S05", "pending");
1929
+ insertGateRow({ milestoneId: "M005", sliceId: "S05", gateId: "Q3", scope: "slice" });
1930
+ autoSession.reset();
1931
+ autoSession.active = true;
1932
+ autoSession.basePath = base;
1933
+ autoSession.currentUnit = { type: "plan-slice", id: "M005/S05", startedAt };
1934
+ recordUnitHarnessAbort(base, "plan-slice", "M005/S05", startedAt, {
1935
+ kind: "turn-abort",
1936
+ reason: "Agent turn aborted before the gate evaluation completed. origin=timeout stopReason=aborted",
1937
+ });
1938
+
1939
+ const result = await inProjectDir(base, () => executeSaveGateResult({
1940
+ milestoneId: "M005",
1941
+ sliceId: "S05",
1942
+ gateId: "Q3",
1943
+ verdict: "flag",
1944
+ rationale: "Partial gate failure after a turn abort.",
1945
+ findings: "This should not be persisted as a product-quality finding.",
1946
+ }, base));
1947
+
1948
+ assert.equal(result.isError, true);
1949
+ assert.equal(result.details.operation, "save_gate_result");
1950
+ assert.equal(result.details.error, "harness_aborted_needs_retry");
1951
+ assert.equal(result.details.retryable, true);
1952
+ assert.equal(result.details.harnessAbortKind, "turn-abort");
1953
+ const row = _getAdapter()!.prepare(
1954
+ "SELECT status, verdict, rationale, findings FROM quality_gates WHERE milestone_id = ? AND slice_id = ? AND gate_id = ? AND task_id = ''",
1955
+ ).get("M005", "S05", "Q3") as Record<string, unknown>;
1956
+ assert.equal(row.status, "pending");
1957
+ assert.equal(row.verdict, "");
1958
+ assert.equal(row.rationale, "");
1959
+ assert.equal(row.findings, "");
1960
+ } finally {
1961
+ autoSession.reset();
1962
+ closeDatabase();
1963
+ cleanup(base);
1964
+ }
1965
+ });
1966
+
1759
1967
  test("executeSaveGateResult fails when no canonical gate row is updated", async () => {
1760
1968
  const base = makeTmpBase();
1761
1969
  try {
@@ -8,6 +8,7 @@ import {
8
8
  rmSync,
9
9
  realpathSync,
10
10
  symlinkSync,
11
+ writeFileSync,
11
12
  } from "node:fs";
12
13
  import { tmpdir } from "node:os";
13
14
  import { join } from "node:path";
@@ -118,17 +119,17 @@ describe("scopeMilestone path methods", () => {
118
119
  rmSync(projectDir, { recursive: true, force: true });
119
120
  });
120
121
 
121
- test("produces correct paths for a known milestone ID", () => {
122
+ test("produces flat-phase paths for a known milestone ID", () => {
122
123
  const ws = createWorkspace(projectDir);
123
124
  const scope = scopeMilestone(ws, MID);
124
125
  const gsd = ws.contract.projectGsd;
125
126
 
126
127
  assert.equal(scope.milestoneId, MID);
127
- assert.equal(scope.contextFile(), join(gsd, "milestones", MID, `${MID}-CONTEXT.md`));
128
- assert.equal(scope.roadmapFile(), join(gsd, "milestones", MID, `${MID}-ROADMAP.md`));
128
+ assert.equal(scope.contextFile(), join(gsd, "phases", "01-m001", "01-CONTEXT.md"));
129
+ assert.equal(scope.roadmapFile(), join(gsd, "phases", "01-m001", "01-ROADMAP.md"));
129
130
  assert.equal(scope.stateFile(), join(gsd, "STATE.md"));
130
131
  assert.equal(scope.dbPath(), ws.contract.projectDb);
131
- assert.equal(scope.milestoneDir(), join(gsd, "milestones", MID));
132
+ assert.equal(scope.milestoneDir(), join(gsd, "phases", "01-m001"));
132
133
  assert.equal(scope.metaJson(), join(gsd, `${MID}-META.json`));
133
134
  });
134
135
 
@@ -144,6 +145,19 @@ describe("scopeMilestone path methods", () => {
144
145
  assert.equal(scope1.milestoneDir(), scope2.milestoneDir());
145
146
  assert.equal(scope1.metaJson(), scope2.metaJson());
146
147
  });
148
+
149
+ test("uses legacy milestone paths when legacy content exists", () => {
150
+ const legacyDir = join(projectDir, ".gsd", "milestones", MID);
151
+ mkdirSync(legacyDir, { recursive: true });
152
+ writeFileSync(join(legacyDir, `${MID}-CONTEXT.md`), "# Legacy context\n");
153
+
154
+ const ws = createWorkspace(projectDir);
155
+ const scope = scopeMilestone(ws, MID);
156
+
157
+ assert.equal(scope.contextFile(), join(legacyDir, `${MID}-CONTEXT.md`));
158
+ assert.equal(scope.roadmapFile(), join(legacyDir, `${MID}-ROADMAP.md`));
159
+ assert.equal(scope.milestoneDir(), legacyDir);
160
+ });
147
161
  });
148
162
 
149
163
  describe("createWorkspace: contract.projectGsd is realpath-canonicalized when basePath is a symlink", () => {
@@ -13,6 +13,7 @@ import {
13
13
  diffWorktreeNumstat,
14
14
  getWorktreeGSDDiff,
15
15
  getWorktreeLog,
16
+ mergeWorktreeToMain,
16
17
  worktreeBranchName,
17
18
  worktreePath,
18
19
  pruneEphemeralGhostWorktreeDirectories,
@@ -333,6 +334,44 @@ describe("getWorktreeLog", () => {
333
334
  });
334
335
  });
335
336
 
337
+ // ─── mergeWorktreeToMain ─────────────────────────────────────────────────────
338
+
339
+ describe("mergeWorktreeToMain", () => {
340
+ let base: string;
341
+ let wtPath: string;
342
+
343
+ beforeEach(() => {
344
+ base = makeBaseRepo();
345
+ wtPath = worktreePath(base, "M900");
346
+ mkdirSync(join(base, ".gsd-worktrees"), { recursive: true });
347
+ run(`git worktree add -b milestone/M900 "${wtPath}"`, base);
348
+ });
349
+
350
+ afterEach(() => { rmSync(base, { recursive: true, force: true }); });
351
+
352
+ test("cleans failed milestone squash state and deletes orphan branch", () => {
353
+ writeFileSync(join(wtPath, "README.md"), "# Milestone change\n", "utf-8");
354
+ run("git add README.md", wtPath);
355
+ run('git commit -m "feat: milestone change"', wtPath);
356
+
357
+ writeFileSync(join(base, "README.md"), "# Main change\n", "utf-8");
358
+ run("git add README.md", base);
359
+ run('git commit -m "feat: main change"', base);
360
+
361
+ assert.throws(
362
+ () => mergeWorktreeToMain(base, "M900", "feat: merge M900", "milestone/M900"),
363
+ /Merge conflicts detected/,
364
+ );
365
+
366
+ assert.equal(run("git status --porcelain", base), "", "failed squash cleanup should leave main clean");
367
+ assert.ok(!existsSync(wtPath), "failed milestone worktree should be removed");
368
+ assert.ok(
369
+ !run("git branch", base).includes("milestone/M900"),
370
+ "failed milestone branch should be deleted after worktree removal",
371
+ );
372
+ });
373
+ });
374
+
336
375
  // ─── removeWorktree ───────────────────────────────────────────────────────────
337
376
 
338
377
  describe("removeWorktree", () => {
@@ -23,7 +23,7 @@
23
23
  * - syncWorktreeStateBack skips non-standard milestone projection dir names
24
24
  */
25
25
 
26
- import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, readFileSync } from 'node:fs';
26
+ import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, readFileSync, statSync } from 'node:fs';
27
27
  import { join } from 'node:path';
28
28
  import { tmpdir } from 'node:os';
29
29
 
@@ -148,6 +148,36 @@ describe('worktree-sync-milestones', async () => {
148
148
  }
149
149
  }
150
150
 
151
+ // ─── 3c. artifact file/dir collisions preserve existing worktree files ─
152
+ console.log('\n=== 3c. artifact file/dir collisions preserve existing worktree files (#1157) ===');
153
+ {
154
+ const mainBase = createBase('main');
155
+ const wtBase = createBase('wt');
156
+
157
+ try {
158
+ const mainSliceDir = join(mainBase, '.gsd', 'milestones', 'M001', 'slices', 'S01');
159
+ mkdirSync(join(mainSliceDir, 'S01-SUMMARY.md'), { recursive: true });
160
+ mkdirSync(join(mainSliceDir, 'S01-ASSESSMENT.md'), { recursive: true });
161
+
162
+ const wtSliceDir = join(wtBase, '.gsd', 'milestones', 'M001', 'slices', 'S01');
163
+ mkdirSync(wtSliceDir, { recursive: true });
164
+ writeFileSync(join(wtSliceDir, 'S01-SUMMARY.md'), '# Valid summary\n');
165
+ writeFileSync(join(wtSliceDir, 'S01-ASSESSMENT.md'), '---\nverdict: pass\n---\n# Valid assessment\n');
166
+
167
+ syncProjectRootToWorktree(mainBase, wtBase, 'M001');
168
+
169
+ const summaryPath = join(wtSliceDir, 'S01-SUMMARY.md');
170
+ const assessmentPath = join(wtSliceDir, 'S01-ASSESSMENT.md');
171
+ assert.ok(statSync(summaryPath).isFile(), 'existing SUMMARY.md stays a file');
172
+ assert.ok(statSync(assessmentPath).isFile(), 'existing ASSESSMENT.md stays a file');
173
+ assert.equal(readFileSync(summaryPath, 'utf-8'), '# Valid summary\n');
174
+ assert.equal(readFileSync(assessmentPath, 'utf-8'), '---\nverdict: pass\n---\n# Valid assessment\n');
175
+ } finally {
176
+ cleanup(mainBase);
177
+ cleanup(wtBase);
178
+ }
179
+ }
180
+
151
181
  // ─── 4. No-op when paths are equal ────────────────────────────────────
152
182
  console.log('\n=== 4. no-op when paths are equal ===');
153
183
  {
@@ -20,6 +20,7 @@ import {
20
20
  existsSync,
21
21
  realpathSync,
22
22
  readFileSync,
23
+ readdirSync,
23
24
  } from "node:fs";
24
25
  import { join } from "node:path";
25
26
  import { tmpdir } from "node:os";
@@ -132,6 +133,37 @@ describe("worktree-teardown-safety", () => {
132
133
  );
133
134
  });
134
135
 
136
+ it("removeWorktree quarantines dirty worktree contents before forced cleanup", () => {
137
+ const tempDir = createTempRepo();
138
+ dirs.push(tempDir);
139
+
140
+ const wt = createWorktree(tempDir, "dirty-wt");
141
+ writeFileSync(join(wt.path, "generated-feature.ts"), "export const answer = 42;\n");
142
+ writeFileSync(join(wt.path, "README.md"), "# changed in worktree\n");
143
+
144
+ removeWorktree(tempDir, "dirty-wt", { deleteBranch: false });
145
+
146
+ assertTrue(!existsSync(wt.path), "original dirty worktree path removed after quarantine");
147
+ const quarantineRoot = join(tempDir, ".gsd", "quarantine", "worktrees");
148
+ const entries = readdirSync(quarantineRoot).filter((entry) => entry.startsWith("dirty-wt-"));
149
+ assertEq(entries.length, 1, "dirty worktree snapshot quarantined");
150
+ const quarantineDir = join(quarantineRoot, entries[0]!);
151
+ assertEq(
152
+ readFileSync(join(quarantineDir, "generated-feature.ts"), "utf-8"),
153
+ "export const answer = 42;\n",
154
+ "untracked source file survives in quarantine",
155
+ );
156
+ assertEq(
157
+ readFileSync(join(quarantineDir, "README.md"), "utf-8"),
158
+ "# changed in worktree\n",
159
+ "modified tracked file survives in quarantine",
160
+ );
161
+ assertTrue(
162
+ existsSync(join(quarantineDir, ".gsd-quarantine.json")),
163
+ "quarantine metadata written",
164
+ );
165
+ });
166
+
135
167
  it("worktreePath always returns paths under .gsd/worktrees/", () => {
136
168
  const tempDir = createTempRepo();
137
169
  dirs.push(tempDir);
@@ -23,7 +23,7 @@ import {
23
23
  } from "../gsd-db.js";
24
24
  import { gsdProjectionRoot, clearPathCache, relMilestoneFile } from "../paths.js";
25
25
  import { resolveCanonicalMilestoneRoot } from "../worktree-manager.js";
26
- import { isClosedStatus } from "../status-guards.js";
26
+ import { isClosedStatus, isDeferredStatus } from "../status-guards.js";
27
27
  import { saveFile, clearParseCache } from "../files.js";
28
28
  import { invalidateStateCache } from "../state.js";
29
29
  import { stripIdPrefix } from "../workflow-projections.js";
@@ -180,7 +180,7 @@ export async function handleCompleteMilestone(
180
180
  return;
181
181
  }
182
182
 
183
- const incompleteSlices = slices.filter(s => !isClosedStatus(s.status));
183
+ const incompleteSlices = slices.filter(s => !isClosedStatus(s.status) && !isDeferredStatus(s.status));
184
184
  if (incompleteSlices.length > 0) {
185
185
  const incompleteIds = incompleteSlices.map(s => `${s.id} (status: ${s.status})`).join(", ");
186
186
  guardError = `incomplete slices: ${incompleteIds}`;
@@ -189,6 +189,7 @@ export async function handleCompleteMilestone(
189
189
 
190
190
  // Deep check: verify all tasks in all slices are complete
191
191
  for (const slice of slices) {
192
+ if (isDeferredStatus(slice.status)) continue;
192
193
  const tasks = getSliceTasks(params.milestoneId, slice.id);
193
194
  const incompleteTasks = tasks.filter(t => !isClosedStatus(t.status));
194
195
  if (incompleteTasks.length > 0) {
@@ -30,7 +30,7 @@ import { classifyUatContent, escalatesArtifactUatToBrowser } from "../uat-policy
30
30
  import { invalidateStateCache } from "../state.js";
31
31
  import { renderRoadmapFromDb, roadmapRenderMarksSliceDone } from "../markdown-renderer.js";
32
32
  import { isStaleWrite } from "../auto/turn-epoch.js";
33
- import { renderStateProjection, renderTopLevelQueueFromDb, renderTopLevelRoadmapFromDb } from "../workflow-projections.js";
33
+ import { renderMilestoneShellProjections } from "../workflow-projections.js";
34
34
  import { writeManifest } from "../workflow-manifest.js";
35
35
  import { appendEvent } from "../workflow-events.js";
36
36
  import { logWarning, logError } from "../workflow-logger.js";
@@ -539,37 +539,10 @@ export async function handleCompleteSlice(
539
539
  // ── Post-mutation hook: projections, manifest, event log ───────────────
540
540
  // Separate try/catch per step so a projection failure doesn't prevent
541
541
  // the event log entry (critical for worktree reconciliation).
542
- //
543
- // If the primary summary/UAT/roadmap write block failed (projectionStale),
544
- // retry the milestone-level roadmap here so ROADMAP.md is not left stale
545
- // after a committed slice completion. This restores the recovery that the
546
- // removed flushWorkflowProjections/renderAllProjections provided.
547
- if (projectionStale) {
548
- try {
549
- await renderRoadmapFromDb(artifactBasePath, params.milestoneId);
550
- } catch (projErr) {
551
- logWarning("tool", `complete-slice milestone roadmap retry warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
552
- }
553
- }
554
- try {
555
- await renderRoadmapFromDb(artifactBasePath, params.milestoneId);
556
- } catch (projErr) {
557
- logWarning("tool", `complete-slice milestone roadmap projection warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
558
- }
559
- try {
560
- renderTopLevelRoadmapFromDb(artifactBasePath);
561
- } catch (projErr) {
562
- logWarning("tool", `complete-slice roadmap projection warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
563
- }
564
- try {
565
- renderTopLevelQueueFromDb(artifactBasePath);
566
- } catch (projErr) {
567
- logWarning("tool", `complete-slice queue projection warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
568
- }
569
542
  try {
570
- await renderStateProjection(artifactBasePath);
543
+ await renderMilestoneShellProjections(artifactBasePath, params.milestoneId);
571
544
  } catch (projErr) {
572
- logWarning("tool", `complete-slice state projection warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
545
+ logWarning("tool", `complete-slice projection warning for ${params.milestoneId}/${params.sliceId}: ${(projErr as Error).message}`);
573
546
  }
574
547
  try {
575
548
  writeManifest(artifactBasePath);