@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
@@ -2,12 +2,17 @@
2
2
  // File Purpose: Tests the one-time migration from nested to flat-phase layout.
3
3
  import test, { afterEach } from "node:test";
4
4
  import assert from "node:assert/strict";
5
- import { mkdtempSync, mkdirSync, rmSync, writeFileSync, existsSync, readdirSync, readFileSync } from "node:fs";
5
+ import { mkdtempSync, mkdirSync, renameSync, rmSync, writeFileSync, existsSync, readdirSync, readFileSync, utimesSync } from "node:fs";
6
6
  import { join } from "node:path";
7
7
  import { tmpdir } from "node:os";
8
8
  import { randomUUID } from "node:crypto";
9
9
 
10
- import { migrateToFlatPhase, needsFlatPhaseMigration } from "../flat-phase-migration.ts";
10
+ import {
11
+ _setFlatPhaseMigrationFsOpsForTest,
12
+ migrateToFlatPhase,
13
+ needsFlatPhaseMigration,
14
+ pruneStaleFlatPhaseBackups,
15
+ } from "../flat-phase-migration.ts";
11
16
  import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertTask, getAllMilestones, getMilestoneSlices, getSliceTasks } from "../gsd-db.ts";
12
17
 
13
18
  const tmpDirs: string[] = [];
@@ -60,6 +65,42 @@ test("migrateToFlatPhase moves content from milestones/ to phases/", async () =>
60
65
  assert.ok(!existsSync(join(base, ".gsd", "milestones")), "milestones/ should be removed");
61
66
  });
62
67
 
68
+ test("migrateToFlatPhase ignores and removes stale phase dirs from prior aborted runs", async () => {
69
+ const base = makeTmp();
70
+ const stalePhaseDir = join(base, ".gsd", "phases", "99-stale-aborted-run");
71
+ mkdirSync(stalePhaseDir, { recursive: true });
72
+
73
+ await migrateToFlatPhase(base);
74
+
75
+ assert.ok(existsSync(join(base, ".gsd", "phases", "01-foundation")), "current DB phase should render");
76
+ assert.equal(existsSync(stalePhaseDir), false, "stale pre-existing phase dir should be removed");
77
+ });
78
+
79
+ test("migrateToFlatPhase falls back to copy-delete when legacy rename is blocked", async (t) => {
80
+ const base = makeTmp();
81
+ const milestonesPath = join(base, ".gsd", "milestones");
82
+ const migratingPath = join(base, ".gsd", "milestones.migrating");
83
+ let blockedRenameAttempts = 0;
84
+
85
+ const restoreFsOps = _setFlatPhaseMigrationFsOpsForTest({
86
+ renameSync(src, dst) {
87
+ if (src === milestonesPath && dst === migratingPath) {
88
+ blockedRenameAttempts++;
89
+ throw Object.assign(new Error("simulated busy handle"), { code: "EPERM" });
90
+ }
91
+ return renameSync(src, dst);
92
+ },
93
+ });
94
+ t.after(restoreFsOps);
95
+
96
+ await migrateToFlatPhase(base);
97
+
98
+ assert.equal(blockedRenameAttempts, 1, "test should exercise the rename fallback path");
99
+ assert.ok(existsSync(join(base, ".gsd", "phases", "01-foundation")), "flat phase should render");
100
+ assert.equal(existsSync(milestonesPath), false, "legacy milestones dir should be removed");
101
+ assert.equal(existsSync(migratingPath), false, "staging dir should be removed after success");
102
+ });
103
+
63
104
  test("migrateToFlatPhase creates a backup", async () => {
64
105
  const base = makeTmp();
65
106
  await migrateToFlatPhase(base);
@@ -112,3 +153,34 @@ test("migrateToFlatPhase preserves slice sidecar artifacts and skips recovery pl
112
153
  "recovery placeholder PLAN should not be promoted when no DB tasks can render a real plan",
113
154
  );
114
155
  });
156
+
157
+ test("pruneStaleFlatPhaseBackups removes migrate-* dirs older than retention window", async () => {
158
+ const base = makeTmp();
159
+ await migrateToFlatPhase(base);
160
+
161
+ const backupRoot = join(base, ".gsd-backups");
162
+ assert.ok(existsSync(backupRoot), "backup should exist immediately after migration");
163
+
164
+ const staleDir = join(backupRoot, "migrate-stale");
165
+ mkdirSync(staleDir, { recursive: true });
166
+ writeFileSync(join(staleDir, "marker.txt"), "old backup\n", "utf-8");
167
+ const staleDate = new Date(Date.now() - 31 * 24 * 60 * 60 * 1000);
168
+ utimesSync(staleDir, staleDate, staleDate);
169
+
170
+ const removed = pruneStaleFlatPhaseBackups(base);
171
+ assert.equal(removed, 1, "stale migrate-* dir should be pruned");
172
+ assert.equal(existsSync(staleDir), false, "stale backup dir should be gone");
173
+ assert.ok(existsSync(backupRoot), "fresh migration backup should remain");
174
+ });
175
+
176
+ test("pruneStaleFlatPhaseBackups is a no-op while flat-phase migration is still needed", () => {
177
+ const base = makeTmp();
178
+ const backupRoot = join(base, ".gsd-backups", "migrate-stale");
179
+ mkdirSync(backupRoot, { recursive: true });
180
+ writeFileSync(join(backupRoot, "marker.txt"), "old backup\n", "utf-8");
181
+ const staleDate = new Date(Date.now() - 31 * 24 * 60 * 60 * 1000);
182
+ utimesSync(backupRoot, staleDate, staleDate);
183
+
184
+ assert.equal(pruneStaleFlatPhaseBackups(base), 0, "must not prune while migration is pending");
185
+ assert.ok(existsSync(backupRoot), "backup must remain until migration completes");
186
+ });
@@ -1,7 +1,6 @@
1
1
  /**
2
- * Regression test for #3453: dynamic model routing must be disabled for
3
- * flat-rate providers like GitHub Copilot where all models cost the same
4
- * per request — routing only degrades quality with no cost benefit.
2
+ * Regression tests for flat-rate provider detection and the explicit opt-out
3
+ * that suppresses dynamic routing for subscription providers.
5
4
  */
6
5
 
7
6
  import { describe, test } from "node:test";
@@ -9,7 +8,7 @@ import assert from "node:assert/strict";
9
8
  import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
10
9
  import { tmpdir } from "node:os";
11
10
  import { join } from "node:path";
12
- import { buildFlatRateContext, isFlatRateProvider, resolvePreferredModelConfig } from "../auto-model-selection.ts";
11
+ import { buildFlatRateContext, isFlatRateProvider, resolvePreferredModelConfig, selectAndApplyModel } from "../auto-model-selection.ts";
13
12
 
14
13
  describe("flat-rate provider routing guard (#3453)", () => {
15
14
 
@@ -35,23 +34,18 @@ describe("flat-rate provider routing guard (#3453)", () => {
35
34
  assert.equal(isFlatRateProvider("openai"), false);
36
35
  });
37
36
 
38
- test("resolvePreferredModelConfig returns undefined for copilot start model", () => {
37
+ test("resolvePreferredModelConfig synthesizes routing config for copilot start model when routing is enabled", () => {
39
38
  const originalCwd = process.cwd();
40
39
  const originalGsdHome = process.env.GSD_HOME;
41
40
  const tempProject = mkdtempSync(join(tmpdir(), "gsd-flat-rate-project-"));
42
41
  const tempGsdHome = mkdtempSync(join(tmpdir(), "gsd-flat-rate-home-"));
43
42
 
44
- // When the user's start model is on a flat-rate provider,
45
- // resolvePreferredModelConfig should not synthesize a routing
46
- // config from tier_models — it should return undefined so the
47
- // user's selected model is preserved.
48
43
  try {
49
44
  mkdirSync(join(tempProject, ".gsd"), { recursive: true });
50
45
  writeFileSync(
51
46
  join(tempProject, ".gsd", "PREFERENCES.md"),
52
47
  [
53
48
  "---",
54
- "token_profile: burn-max",
55
49
  "dynamic_routing:",
56
50
  " enabled: true",
57
51
  " tier_models:",
@@ -70,10 +64,83 @@ describe("flat-rate provider routing guard (#3453)", () => {
70
64
  id: "claude-sonnet-4",
71
65
  });
72
66
 
73
- // Should be undefined (no routing config created for flat-rate)
74
- // Note: this only tests the synthesis guard — explicit per-unit config
75
- // still takes precedence when the user configured one.
76
- assert.equal(result, undefined, "Should not create routing config for copilot");
67
+ assert.deepEqual(result, {
68
+ primary: "claude-opus-4-6",
69
+ fallbacks: [],
70
+ source: "synthesized",
71
+ });
72
+ } finally {
73
+ process.chdir(originalCwd);
74
+ if (originalGsdHome === undefined) delete process.env.GSD_HOME;
75
+ else process.env.GSD_HOME = originalGsdHome;
76
+ rmSync(tempProject, { recursive: true, force: true });
77
+ rmSync(tempGsdHome, { recursive: true, force: true });
78
+ }
79
+ });
80
+
81
+ test("selectAndApplyModel runs synthesized dynamic routing for flat-rate start model", async () => {
82
+ const originalCwd = process.cwd();
83
+ const originalGsdHome = process.env.GSD_HOME;
84
+ const tempProject = mkdtempSync(join(tmpdir(), "gsd-flat-rate-project-"));
85
+ const tempGsdHome = mkdtempSync(join(tmpdir(), "gsd-flat-rate-home-"));
86
+ const setModelCalls: string[] = [];
87
+
88
+ try {
89
+ mkdirSync(join(tempProject, ".gsd"), { recursive: true });
90
+ writeFileSync(
91
+ join(tempProject, ".gsd", "PREFERENCES.md"),
92
+ [
93
+ "---",
94
+ "dynamic_routing:",
95
+ " enabled: true",
96
+ " hooks: false",
97
+ " budget_pressure: false",
98
+ " tier_models:",
99
+ " light: claude-haiku-4-5",
100
+ " standard: claude-sonnet-4-6",
101
+ " heavy: claude-opus-4-6",
102
+ "---",
103
+ ].join("\n"),
104
+ "utf-8",
105
+ );
106
+ process.env.GSD_HOME = tempGsdHome;
107
+ process.chdir(tempProject);
108
+
109
+ const availableModels = [
110
+ { id: "claude-haiku-4-5", provider: "claude-code", api: "anthropic-messages" },
111
+ { id: "claude-sonnet-4-6", provider: "claude-code", api: "anthropic-messages" },
112
+ { id: "claude-opus-4-6", provider: "claude-code", api: "anthropic-messages" },
113
+ ];
114
+
115
+ const result = await selectAndApplyModel(
116
+ {
117
+ modelRegistry: { getAvailable: () => availableModels },
118
+ sessionManager: { getSessionId: () => "test-session" },
119
+ ui: { notify: () => {} },
120
+ model: { provider: "claude-code", id: "claude-opus-4-6", api: "anthropic-messages" },
121
+ } as any,
122
+ {
123
+ setModel: async (model: { provider: string; id: string }) => {
124
+ setModelCalls.push(`${model.provider}/${model.id}`);
125
+ return true;
126
+ },
127
+ emitBeforeModelSelect: async () => undefined,
128
+ getActiveTools: () => [],
129
+ emitAdjustToolSet: async () => undefined,
130
+ setActiveTools: () => {},
131
+ } as any,
132
+ "execute-task",
133
+ "M001/S01/T01",
134
+ tempProject,
135
+ undefined,
136
+ false,
137
+ { provider: "claude-code", id: "claude-opus-4-6" },
138
+ undefined,
139
+ true,
140
+ );
141
+
142
+ assert.deepEqual(setModelCalls, ["claude-code/claude-sonnet-4-6"]);
143
+ assert.deepEqual(result.routing, { tier: "standard", modelDowngraded: true });
77
144
  } finally {
78
145
  process.chdir(originalCwd);
79
146
  if (originalGsdHome === undefined) delete process.env.GSD_HOME;
@@ -220,9 +287,9 @@ describe("buildFlatRateContext()", () => {
220
287
  });
221
288
  });
222
289
 
223
- // ─── #4386: allow_flat_rate_providers opt-in ────────────────────────────────
290
+ // ─── #4386/#1115: allow_flat_rate_providers override ────────────────────────
224
291
 
225
- describe("flat-rate routing opt-in (#4386)", () => {
292
+ describe("flat-rate routing override (#4386/#1115)", () => {
226
293
  function withPrefs(prefsYaml: string, fn: () => void): void {
227
294
  const originalCwd = process.cwd();
228
295
  const originalGsdHome = process.env.GSD_HOME;
@@ -247,7 +314,7 @@ describe("flat-rate routing opt-in (#4386)", () => {
247
314
  }
248
315
  }
249
316
 
250
- test("default (opt-in absent): flat-rate start model still returns undefined", () => {
317
+ test("default (allow absent): flat-rate start model still synthesizes routing config", () => {
251
318
  withPrefs(
252
319
  [
253
320
  "dynamic_routing:",
@@ -260,12 +327,13 @@ describe("flat-rate routing opt-in (#4386)", () => {
260
327
  provider: "claude-code",
261
328
  id: "claude-opus-4-6",
262
329
  });
263
- assert.equal(result, undefined, "default must preserve #3453 bypass");
330
+ assert.ok(result, "routing config should be synthesized");
331
+ assert.equal(result!.primary, "claude-opus-4-6");
264
332
  },
265
333
  );
266
334
  });
267
335
 
268
- test("opt-in: synthesizes a routing config for flat-rate start model", () => {
336
+ test("explicit allow: synthesizes a routing config for flat-rate start model", () => {
269
337
  withPrefs(
270
338
  [
271
339
  "dynamic_routing:",
@@ -14,6 +14,7 @@ import { tmpdir } from "node:os";
14
14
 
15
15
  import {
16
16
  checkAutoStartAfterDiscuss,
17
+ _getPendingAutoStart,
17
18
  setPendingAutoStart,
18
19
  clearPendingAutoStart,
19
20
  } from "../guided-flow.ts";
@@ -21,6 +22,7 @@ import { drainLogs } from "../workflow-logger.ts";
21
22
  import {
22
23
  openDatabase,
23
24
  closeDatabase,
25
+ getMilestone,
24
26
  insertMilestone,
25
27
  } from "../gsd-db.ts";
26
28
 
@@ -59,6 +61,12 @@ function mkBase(): string {
59
61
  return base;
60
62
  }
61
63
 
64
+ function mkFlatBase(): string {
65
+ const base = mkdtempSync(join(tmpdir(), "gsd-gate1b-flat-"));
66
+ mkdirSync(join(base, ".gsd", "phases", "01-m001"), { recursive: true });
67
+ return base;
68
+ }
69
+
62
70
  function writeContext(base: string): void {
63
71
  writeFileSync(
64
72
  join(base, ".gsd", "milestones", "M001", "M001-CONTEXT.md"),
@@ -66,6 +74,13 @@ function writeContext(base: string): void {
66
74
  );
67
75
  }
68
76
 
77
+ function writeFlatContext(base: string): void {
78
+ writeFileSync(
79
+ join(base, ".gsd", "phases", "01-m001", "01-CONTEXT.md"),
80
+ "# M001: Test Milestone\n\nContext written by discuss phase.\n",
81
+ );
82
+ }
83
+
69
84
  describe("Gate 1b discussion handoff in checkAutoStartAfterDiscuss", () => {
70
85
  let base: string;
71
86
  let cap: MockCapture;
@@ -142,4 +157,78 @@ describe("Gate 1b discussion handoff in checkAutoStartAfterDiscuss", () => {
142
157
  );
143
158
  assert.equal(gate1bLog, undefined, "Gate 1b must not log when CONTEXT.md is absent");
144
159
  });
160
+
161
+ test("flat-phase CONTEXT.md accepts handoff without a legacy milestone context file", () => {
162
+ base = mkFlatBase();
163
+ openDatabase(":memory:");
164
+ insertMilestone({ id: "M001", title: "Test Milestone", status: "queued" });
165
+ writeFlatContext(base);
166
+
167
+ cap = mkCapture();
168
+ setPendingAutoStart(base, {
169
+ basePath: base,
170
+ milestoneId: "M001",
171
+ startAuto: false,
172
+ ctx: mkCtx(cap),
173
+ pi: mkPi(cap),
174
+ });
175
+
176
+ const result = checkAutoStartAfterDiscuss();
177
+
178
+ assert.equal(result, true, "flat-phase context must be found by the handoff");
179
+ assert.equal(cap.messages.length, 0, "startAuto=false must suppress scheduling");
180
+ assert.deepEqual(cap.notifies[0], {
181
+ msg: "Milestone M001 context captured. Continuing the planning pipeline.",
182
+ level: "success",
183
+ });
184
+ });
185
+
186
+ test("DB-unavailable recovery blocks handoff instead of reporting success", () => {
187
+ base = mkFlatBase();
188
+ writeFlatContext(base);
189
+
190
+ cap = mkCapture();
191
+ setPendingAutoStart(base, {
192
+ basePath: base,
193
+ milestoneId: "M001",
194
+ startAuto: false,
195
+ ctx: mkCtx(cap),
196
+ pi: mkPi(cap),
197
+ });
198
+
199
+ const result = checkAutoStartAfterDiscuss();
200
+
201
+ assert.equal(result, false, "handoff must fail closed when the DB row cannot be confirmed");
202
+ assert.equal(cap.messages.length, 0, "must not schedule auto-start when DB is unavailable");
203
+ assert.equal(
204
+ cap.notifies.some(n => n.level === "success"),
205
+ false,
206
+ "must not report a successful handoff when DB recovery was skipped",
207
+ );
208
+ assert.ok(_getPendingAutoStart(base), "pending handoff should remain for a later recovery attempt");
209
+ });
210
+
211
+ test("missing DB row with CONTEXT.md inserts a queued row and accepts handoff", () => {
212
+ base = mkFlatBase();
213
+ openDatabase(":memory:");
214
+ writeFlatContext(base);
215
+
216
+ cap = mkCapture();
217
+ setPendingAutoStart(base, {
218
+ basePath: base,
219
+ milestoneId: "M001",
220
+ startAuto: false,
221
+ ctx: mkCtx(cap),
222
+ pi: mkPi(cap),
223
+ });
224
+
225
+ const result = checkAutoStartAfterDiscuss();
226
+
227
+ assert.equal(result, true, "successful insert should recover the missing row");
228
+ assert.equal(getMilestone("M001")?.status, "queued");
229
+ assert.deepEqual(cap.notifies[0], {
230
+ msg: "Milestone M001 context captured. Continuing the planning pipeline.",
231
+ level: "success",
232
+ });
233
+ });
145
234
  });
@@ -40,6 +40,10 @@ describe('ensureGitignore writes .bg-shell/ baseline (#4902)', () => {
40
40
  lines.has('.bg-shell/'),
41
41
  `.gitignore should include .bg-shell/. Got:\n${ignore}`,
42
42
  );
43
+ assert.ok(
44
+ lines.has('.gsd-backups/'),
45
+ `.gitignore should include .gsd-backups/. Got:\n${ignore}`,
46
+ );
43
47
  } finally {
44
48
  cleanup(dir);
45
49
  }
@@ -20,6 +20,7 @@ import {
20
20
  clearPendingAutoStart,
21
21
  checkAutoStartAfterDiscuss,
22
22
  } from "../guided-flow.ts";
23
+ import { closeDatabase, openDatabase } from "../gsd-db.ts";
23
24
 
24
25
  function pendingInput(basePath: string, milestoneId: string) {
25
26
  return {
@@ -34,6 +35,7 @@ function pendingInput(basePath: string, milestoneId: string) {
34
35
 
35
36
  describe("#2985 Bug 3 — concurrent discuss sessions must be independent", () => {
36
37
  beforeEach(() => {
38
+ closeDatabase();
37
39
  clearPendingAutoStart();
38
40
  });
39
41
 
@@ -75,6 +77,7 @@ describe("#2985 Bug 3 — concurrent discuss sessions must be independent", () =
75
77
 
76
78
  describe("#2985 Bug 4 — getDiscussionMilestoneId must be keyed by basePath", () => {
77
79
  beforeEach(() => {
80
+ closeDatabase();
78
81
  clearPendingAutoStart();
79
82
  });
80
83
 
@@ -110,6 +113,7 @@ describe("#2985 Bug 4 — getDiscussionMilestoneId must be keyed by basePath", (
110
113
  test("checkAutoStartAfterDiscuss ignores missing manifest for single-milestone discuss on established project", () => {
111
114
  const base = mkdtempSync(join(tmpdir(), "gsd-auto-start-manifest-"));
112
115
  try {
116
+ openDatabase(":memory:");
113
117
  const gsdDir = join(base, ".gsd");
114
118
  const milestoneDir = join(gsdDir, "milestones", "M001");
115
119
  mkdirSync(milestoneDir, { recursive: true });
@@ -132,6 +136,7 @@ test("checkAutoStartAfterDiscuss ignores missing manifest for single-milestone d
132
136
  const started = checkAutoStartAfterDiscuss();
133
137
  assert.equal(started, true, "project history alone should not require a manifest");
134
138
  } finally {
139
+ closeDatabase();
135
140
  clearPendingAutoStart();
136
141
  rmSync(base, { recursive: true, force: true });
137
142
  }
@@ -151,6 +156,7 @@ test("checkAutoStartAfterDiscuss(basePath) selects the matching pending entry wh
151
156
  }
152
157
 
153
158
  try {
159
+ openDatabase(":memory:");
154
160
  clearPendingAutoStart();
155
161
  writeReadyArtifacts(projectA, "M001");
156
162
  writeReadyArtifacts(projectB, "M002");
@@ -172,6 +178,7 @@ test("checkAutoStartAfterDiscuss(basePath) selects the matching pending entry wh
172
178
  assert.equal(getDiscussionMilestoneId(projectA), "M001", "projectA should remain pending");
173
179
  assert.equal(getDiscussionMilestoneId(projectB), null, "projectB should be cleared after start");
174
180
  } finally {
181
+ closeDatabase();
175
182
  clearPendingAutoStart();
176
183
  rmSync(projectA, { recursive: true, force: true });
177
184
  rmSync(projectB, { recursive: true, force: true });
@@ -183,6 +190,7 @@ test("checkAutoStartAfterDiscuss can accept context handoff without scheduling a
183
190
  let waitForIdleCalls = 0;
184
191
  const notifications: string[] = [];
185
192
  try {
193
+ openDatabase(":memory:");
186
194
  const gsdDir = join(base, ".gsd");
187
195
  const milestoneDir = join(gsdDir, "milestones", "M001");
188
196
  mkdirSync(milestoneDir, { recursive: true });
@@ -215,6 +223,7 @@ test("checkAutoStartAfterDiscuss can accept context handoff without scheduling a
215
223
  assert.equal(waitForIdleCalls, 0, "headless-owned auto start must not schedule guided-flow auto");
216
224
  assert.equal(getDiscussionMilestoneId(base), null, "accepted handoff should still be cleared");
217
225
  } finally {
226
+ closeDatabase();
218
227
  clearPendingAutoStart();
219
228
  rmSync(base, { recursive: true, force: true });
220
229
  }
@@ -294,12 +294,13 @@ describe('git-service', async () => {
294
294
 
295
295
  assert.deepStrictEqual(
296
296
  RUNTIME_EXCLUSION_PATHS.length,
297
- 17,
298
- "exactly 17 runtime exclusion paths"
297
+ 18,
298
+ "exactly 18 runtime exclusion paths"
299
299
  );
300
300
 
301
301
  const expectedPaths = [
302
302
  ".gsd-worktrees/",
303
+ ".gsd-backups/**",
303
304
  ".gsd/activity/",
304
305
  ".gsd/audit/",
305
306
  ".gsd/forensics/",
@@ -1623,11 +1624,13 @@ process.exit(result.status ?? 0);
1623
1624
  // Create and track runtime files (simulates pre-.gitignore state)
1624
1625
  mkdirSync(join(repo, ".gsd", "activity"), { recursive: true });
1625
1626
  mkdirSync(join(repo, ".gsd", "runtime"), { recursive: true });
1627
+ mkdirSync(join(repo, ".gsd-backups", "migrate-old"), { recursive: true });
1626
1628
  writeFileSync(join(repo, ".gsd", "completed-units.json"), '["u1"]');
1627
1629
  writeFileSync(join(repo, ".gsd", "metrics.json"), '{}');
1628
1630
  writeFileSync(join(repo, ".gsd", "STATE.md"), "# State");
1629
1631
  writeFileSync(join(repo, ".gsd", "activity", "log.jsonl"), "{}");
1630
1632
  writeFileSync(join(repo, ".gsd", "runtime", "data.json"), "{}");
1633
+ writeFileSync(join(repo, ".gsd-backups", "migrate-old", "marker.txt"), "backup");
1631
1634
  writeFileSync(join(repo, "src.ts"), "code");
1632
1635
  runGit(repo, ["add", "-A"]);
1633
1636
  runGit(repo, ["commit", "-m", "init"]);
@@ -1636,6 +1639,8 @@ process.exit(result.status ?? 0);
1636
1639
  const trackedBefore = run("git ls-files .gsd/", repo);
1637
1640
  assert.ok(trackedBefore.includes("completed-units.json"), "untrack: precondition — completed-units tracked");
1638
1641
  assert.ok(trackedBefore.includes("metrics.json"), "untrack: precondition — metrics tracked");
1642
+ const backupTrackedBefore = run("git ls-files .gsd-backups/", repo);
1643
+ assert.ok(backupTrackedBefore.includes("marker.txt"), "untrack: precondition — migration backup tracked");
1639
1644
 
1640
1645
  // Run untrackRuntimeFiles
1641
1646
  untrackRuntimeFiles(repo);
@@ -1643,6 +1648,8 @@ process.exit(result.status ?? 0);
1643
1648
  // Runtime files should be removed from the index
1644
1649
  const trackedAfter = run("git ls-files .gsd/", repo);
1645
1650
  assert.deepStrictEqual(trackedAfter, "", "untrack: all runtime files removed from index");
1651
+ const backupTrackedAfter = run("git ls-files .gsd-backups/", repo);
1652
+ assert.deepStrictEqual(backupTrackedAfter, "", "untrack: migration backups removed from index");
1646
1653
 
1647
1654
  // Non-runtime files remain tracked
1648
1655
  const srcTracked = run("git ls-files src.ts", repo);
@@ -1653,6 +1660,8 @@ process.exit(result.status ?? 0);
1653
1660
  "untrack: completed-units.json still on disk");
1654
1661
  assert.ok(existsSync(join(repo, ".gsd", "metrics.json")),
1655
1662
  "untrack: metrics.json still on disk");
1663
+ assert.ok(existsSync(join(repo, ".gsd-backups", "migrate-old", "marker.txt")),
1664
+ "untrack: migration backup still on disk");
1656
1665
 
1657
1666
  // Idempotent — running again doesn't error
1658
1667
  untrackRuntimeFiles(repo);
@@ -90,6 +90,8 @@ import { clearPathCache } from "../../paths.ts";
90
90
  // Fixture Helpers
91
91
  // ═══════════════════════════════════════════════════════════════════════════
92
92
 
93
+ const UAT_VERDICT_GATE_RULE_NAME = "uat-verdict-gate (non-PASS observed; closeout enforces)";
94
+
93
95
  function makeTempDir(): string {
94
96
  return mkdtempSync(join(tmpdir(), "gsd-edge-cases-"));
95
97
  }
@@ -280,7 +282,7 @@ function buildDispatchCtx(
280
282
 
281
283
  function getUatVerdictGate(): import("../../auto-dispatch.ts").DispatchRule {
282
284
  const rule = DISPATCH_RULES.find(
283
- r => r.name === "uat-verdict-gate (non-PASS blocks progression)",
285
+ r => r.name === UAT_VERDICT_GATE_RULE_NAME,
284
286
  );
285
287
  assert.ok(rule, "uat-verdict-gate rule should be registered");
286
288
  return rule;
@@ -867,7 +869,7 @@ describe("dispatch failure modes", () => {
867
869
  // Verify critical ordering constraints
868
870
  const summarizeIdx = ruleNames.indexOf("summarizing → complete-slice");
869
871
  const runUatIdx = ruleNames.indexOf("run-uat (post-completion)");
870
- const uatGateIdx = ruleNames.indexOf("uat-verdict-gate (non-PASS blocks progression)");
872
+ const uatGateIdx = ruleNames.indexOf(UAT_VERDICT_GATE_RULE_NAME);
871
873
  const executeIdx = ruleNames.indexOf("executing → execute-task");
872
874
 
873
875
  // summarizing should come before execute-task
@@ -19,6 +19,7 @@ import { tmpdir } from "node:os";
19
19
 
20
20
  import {
21
21
  saveJsonFile,
22
+ saveJsonFileCompact,
22
23
  loadJsonFile,
23
24
  writeJsonFileAtomic,
24
25
  } from "../json-persistence.ts";
@@ -56,6 +57,37 @@ test("saveJsonFile creates file with valid JSON content", () => {
56
57
  }
57
58
  });
58
59
 
60
+ test("saveJsonFile keeps pretty-printed output for human-readable state", () => {
61
+ const dir = makeTempDir();
62
+ const filePath = join(dir, "pretty.json");
63
+
64
+ try {
65
+ const data = { foo: "bar", nested: { count: 42 } };
66
+ saveJsonFile(filePath, data);
67
+
68
+ const content = readFileSync(filePath, "utf-8");
69
+ assert.equal(content, JSON.stringify(data, null, 2) + "\n");
70
+ } finally {
71
+ cleanup(dir);
72
+ }
73
+ });
74
+
75
+ test("saveJsonFileCompact writes valid compact JSON content", () => {
76
+ const dir = makeTempDir();
77
+ const filePath = join(dir, "compact.json");
78
+
79
+ try {
80
+ const data = { foo: "bar", nested: { count: 42 } };
81
+ saveJsonFileCompact(filePath, data);
82
+
83
+ const content = readFileSync(filePath, "utf-8");
84
+ assert.equal(content, JSON.stringify(data) + "\n");
85
+ assert.deepEqual(JSON.parse(content), data);
86
+ } finally {
87
+ cleanup(dir);
88
+ }
89
+ });
90
+
59
91
  test("saveJsonFile does not leave .tmp files on success", () => {
60
92
  const dir = makeTempDir();
61
93
  const filePath = join(dir, "clean.json");
@@ -72,6 +104,21 @@ test("saveJsonFile does not leave .tmp files on success", () => {
72
104
  }
73
105
  });
74
106
 
107
+ test("saveJsonFileCompact does not leave .tmp files on success", () => {
108
+ const dir = makeTempDir();
109
+ const filePath = join(dir, "compact-clean.json");
110
+
111
+ try {
112
+ saveJsonFileCompact(filePath, { test: true });
113
+
114
+ const files = readdirSync(dir);
115
+ const tmpFiles = files.filter(f => f.includes(".tmp"));
116
+ assert.equal(tmpFiles.length, 0, `Unexpected .tmp files: ${tmpFiles.join(", ")}`);
117
+ } finally {
118
+ cleanup(dir);
119
+ }
120
+ });
121
+
75
122
  test("saveJsonFile creates parent directories", () => {
76
123
  const dir = makeTempDir();
77
124
  const filePath = join(dir, "deep", "nested", "data.json");
@@ -161,6 +161,41 @@ test("backfill is idempotent — second run on the same file is a no-op", () =>
161
161
  }
162
162
  });
163
163
 
164
+ test("backfill skips a knowledge row whose memory insert throws and continues later rows", () => {
165
+ const base = makeTmpBase();
166
+ try {
167
+ writeKnowledgeMd(base, FIXTURE);
168
+
169
+ const adapter = _getAdapter();
170
+ assert.ok(adapter);
171
+ adapter.exec(`
172
+ CREATE TRIGGER fail_p002_memory_insert
173
+ BEFORE INSERT ON memories
174
+ WHEN json_extract(NEW.structured_fields, '$.sourceKnowledgeId') = 'P002'
175
+ BEGIN
176
+ SELECT RAISE(ABORT, 'poison knowledge P002');
177
+ END
178
+ `);
179
+
180
+ const written = backfillKnowledgeToMemories(base);
181
+ assert.equal(written, 2, "one poisoned row should not abort the batch");
182
+
183
+ const rows = adapter
184
+ .prepare(
185
+ "SELECT structured_fields FROM memories WHERE structured_fields LIKE '%\"sourceKnowledgeId\":\"%' ORDER BY seq",
186
+ )
187
+ .all() as Array<{ structured_fields: string }>;
188
+
189
+ assert.deepEqual(
190
+ rows.map((row) => JSON.parse(row.structured_fields).sourceKnowledgeId),
191
+ ["P001", "L001"],
192
+ "rows after the poisoned knowledge entry should still be migrated",
193
+ );
194
+ } finally {
195
+ cleanup(base);
196
+ }
197
+ });
198
+
164
199
  test("backfill returns 0 when KNOWLEDGE.md is absent", () => {
165
200
  const base = makeTmpBase();
166
201
  try {