@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
@@ -182,6 +182,70 @@ test("prefs wizard save path preserves every known preference key", async () =>
182
182
  }
183
183
  });
184
184
 
185
+ test("verification wizard prompts for per-unit cost cap and persists it (regression #1121)", async () => {
186
+ // Regression for #1121: the `/gsd prefs` Verification category never prompted for
187
+ // `per_unit_cost_cap_usd`, so the per-unit cost cap could only be set by hand-editing
188
+ // PREFERENCES.md. Drive the wizard into Verification, answer the cap prompt, and assert
189
+ // the prompt exists and the entered value is serialized + round-trips back as a number.
190
+ const dir = mkdtempSync(join(tmpdir(), "gsd-prefs-wizard-"));
191
+ const prefsPath = join(dir, "PREFERENCES.md");
192
+
193
+ const inputLabels: string[] = [];
194
+ let topMenuVisits = 0;
195
+
196
+ const ctx = {
197
+ ui: {
198
+ notify() {},
199
+ select: async (label: string, options: string[]) => {
200
+ if (label === "GSD Preferences") {
201
+ topMenuVisits += 1;
202
+ if (topMenuVisits === 1) {
203
+ const verification = options.find((o) => o.startsWith("Verification"));
204
+ assert.ok(verification, "wizard menu must offer a Verification category");
205
+ return verification;
206
+ }
207
+ return "── Save & Exit ──";
208
+ }
209
+ // verification_commands string-list sub-menu — leave it untouched
210
+ if (options.includes("Done")) return "Done";
211
+ // boolean/enum prompts within the category — keep the current value
212
+ if (options.includes("(keep current)")) return "(keep current)";
213
+ return options[options.length - 1];
214
+ },
215
+ input: async (label: string) => {
216
+ inputLabels.push(label);
217
+ if (label.includes("Per-unit cost cap")) return "12.5";
218
+ return null; // escape every other numeric/string prompt (no change)
219
+ },
220
+ },
221
+ waitForIdle: async () => {},
222
+ reload: async () => {},
223
+ } as any;
224
+
225
+ try {
226
+ await handlePrefsWizard(ctx, "project", {}, { pathOverride: prefsPath });
227
+
228
+ // The Verification wizard must actually ask for the per-unit cost cap.
229
+ assert.ok(
230
+ inputLabels.some((l) => l.includes("Per-unit cost cap")),
231
+ `Verification wizard must prompt for the per-unit cost cap; prompts seen:\n${inputLabels.join("\n")}`,
232
+ );
233
+
234
+ // The entered value must be serialized to PREFERENCES.md...
235
+ const saved = readFileSync(prefsPath, "utf-8");
236
+ assert.match(saved, /per_unit_cost_cap_usd:\s*12\.5(\s|$)/m);
237
+
238
+ // ...and round-trip back through the parser/validator as a number.
239
+ const parsed = parsePreferencesMarkdown(saved);
240
+ assert.notEqual(parsed, null);
241
+ const { errors, preferences } = validatePreferences(parsed!);
242
+ assert.deepEqual(errors, []);
243
+ assert.equal(preferences.per_unit_cost_cap_usd, 12.5);
244
+ } finally {
245
+ rmSync(dir, { recursive: true, force: true });
246
+ }
247
+ });
248
+
185
249
  test("category summaries expose the wizard menu surface for configured prefs", () => {
186
250
  const summaries = buildCategorySummaries(PREF_SAMPLE_VALUES);
187
251
  assert.deepEqual(
@@ -203,11 +267,14 @@ test("category summaries expose the wizard menu surface for configured prefs", (
203
267
  "timeouts",
204
268
  "uok",
205
269
  "verification",
270
+ "workspace",
206
271
  ],
207
272
  );
208
273
  assert.match(summaries.models, /phase/);
209
274
  assert.match(summaries.integrations, /remote: C123/);
210
275
  assert.match(summaries.verification, /1 cmd/);
276
+ assert.match(summaries.workspace, /mode: parent/);
277
+ assert.match(summaries.workspace, /1 repo/);
211
278
  });
212
279
 
213
280
  test("models wizard offers discovered models for enabled providers", async () => {
@@ -276,3 +343,78 @@ test("models wizard offers discovered models for enabled providers", async () =>
276
343
  rmSync(dir, { recursive: true, force: true });
277
344
  }
278
345
  });
346
+
347
+ test("workspace wizard category configures parent mode with a declared repository", async () => {
348
+ const dir = mkdtempSync(join(tmpdir(), "gsd-prefs-wizard-workspace-"));
349
+ const prefsPath = join(dir, "PREFERENCES.md");
350
+ try {
351
+ // Drive: Workspace → parent mode → Add repository (id=frontend, path=frontend,
352
+ // role=ui, verification=npm test, commit policy auto) → Done → Save & Exit.
353
+ const selects = [
354
+ "Workspace (single-repo)", // pick the Workspace category
355
+ "parent", // promptEnum: workspace mode
356
+ "Add repository", // sub-menu
357
+ "(keep current)", // promptEnum: commit policy -> keep auto default
358
+ "Done", // exit repo sub-menu
359
+ "── Save & Exit ──", // exit wizard
360
+ ];
361
+ const inputs = [
362
+ "frontend", // repository id
363
+ "frontend", // repository path
364
+ "ui", // role
365
+ "npm test", // verification commands
366
+ ];
367
+ const ctx = {
368
+ ui: {
369
+ notify() {},
370
+ select: async () => selects.shift(),
371
+ input: async () => inputs.shift(),
372
+ },
373
+ waitForIdle: async () => {},
374
+ reload: async () => {},
375
+ } as any;
376
+
377
+ await handlePrefsWizard(ctx, "project", {}, { pathOverride: prefsPath });
378
+
379
+ const saved = readFileSync(prefsPath, "utf-8");
380
+ assert.match(saved, /mode: parent/);
381
+ assert.match(saved, /frontend:/);
382
+ assert.match(saved, /path: frontend/);
383
+ assert.match(saved, /role: ui/);
384
+ assert.match(saved, /npm test/);
385
+ assert.equal(selects.length, 0, "all queued selects should be consumed");
386
+ assert.equal(inputs.length, 0, "all queued inputs should be consumed");
387
+ } finally {
388
+ rmSync(dir, { recursive: true, force: true });
389
+ }
390
+ });
391
+
392
+ test("workspace wizard does not save parent mode when no repository is declared", async () => {
393
+ const dir = mkdtempSync(join(tmpdir(), "gsd-prefs-wizard-workspace-empty-"));
394
+ const prefsPath = join(dir, "PREFERENCES.md");
395
+ try {
396
+ // parent mode with no repos added → should warn and not persist workspace.
397
+ const selects = [
398
+ "Workspace (single-repo)",
399
+ "parent",
400
+ "Done", // add nothing
401
+ "── Save & Exit ──",
402
+ ];
403
+ const ctx = {
404
+ ui: {
405
+ notify() {},
406
+ select: async () => selects.shift(),
407
+ input: async () => "",
408
+ },
409
+ waitForIdle: async () => {},
410
+ reload: async () => {},
411
+ } as any;
412
+
413
+ await handlePrefsWizard(ctx, "project", {}, { pathOverride: prefsPath });
414
+
415
+ const saved = readFileSync(prefsPath, "utf-8");
416
+ assert.doesNotMatch(saved, /mode: parent/, "parent mode must not persist without a declared repo");
417
+ } finally {
418
+ rmSync(dir, { recursive: true, force: true });
419
+ }
420
+ });
@@ -17,7 +17,8 @@ import {
17
17
  getSlice,
18
18
  } from "../gsd-db.ts";
19
19
  import { autoHealSketchFlags } from "../state-reconciliation/drift/sketch-flag.ts";
20
- import { deriveState, deriveStateFromDb } from "../state.ts";
20
+ import { deriveState, deriveStateFromDb, invalidateStateCache } from "../state.ts";
21
+ import { reconcileBeforeDispatch } from "../state-reconciliation.ts";
21
22
  import { resolveDispatch } from "../auto-dispatch.ts";
22
23
  import type { DispatchContext } from "../auto-dispatch.ts";
23
24
 
@@ -174,7 +175,7 @@ test("ADR-011: refining + flag flipped OFF mid-milestone → falls through to pl
174
175
  }
175
176
  });
176
177
 
177
- test("ADR-011: existing PLAN heals stale sketch flag via deriveStateFromDb (progressive_planning ON)", async (t) => {
178
+ test("ADR-011: existing PLAN + stale sketch flag heals via reconcileBeforeDispatch, then dispatch routes past refining (progressive_planning ON)", async (t) => {
178
179
  const originalCwd = process.cwd();
179
180
  const base = makeFixtureBase();
180
181
  t.after(() => cleanup(base, originalCwd));
@@ -188,11 +189,22 @@ test("ADR-011: existing PLAN heals stale sketch flag via deriveStateFromDb (prog
188
189
  );
189
190
  process.chdir(base);
190
191
 
191
- // deriveStateFromDb auto-heals the stale sketch flag when PLAN.md exists,
192
- // regardless of the progressive_planning preference.
192
+ // Derivation is pure (ADR-017): a stale sketch flag (PLAN on disk but
193
+ // is_sketch=1) yields 'refining' and must NOT mutate the DB. Healing is
194
+ // owned by reconcileBeforeDispatch, which runs before every dispatch.
195
+ invalidateStateCache();
196
+ const beforeReconcile = await deriveStateFromDb(base);
197
+ assert.equal(beforeReconcile.activeSlice?.id, "S02");
198
+ assert.equal(beforeReconcile.phase, "refining", "derive alone must not heal the stale sketch flag");
199
+ assert.equal(getSlice("M001", "S02")?.is_sketch, 1, "derive must not mutate is_sketch");
200
+
201
+ const reconcile = await reconcileBeforeDispatch(base);
202
+ assert.equal(reconcile.ok, true);
203
+ assert.equal(getSlice("M001", "S02")?.is_sketch, 0, "reconcile clears the stale sketch flag once PLAN exists");
204
+
205
+ invalidateStateCache();
193
206
  const state = await deriveStateFromDb(base);
194
- assert.equal(getSlice("M001", "S02")?.is_sketch, 0, "derive: flag cleared when PLAN exists");
195
- assert.equal(state.phase, "planning", "derive: phase advances past refining once flag is healed");
207
+ assert.equal(state.phase, "planning", "re-derive advances past refining once the flag is healed");
196
208
 
197
209
  const ctx: DispatchContext = {
198
210
  basePath: base,
@@ -229,7 +241,7 @@ test("ADR-011: autoHealSketchFlags flips is_sketch=0 when PLAN file exists", asy
229
241
  assert.equal(getSlice("M001", "S02")?.is_sketch, 0, "post-heal: flag cleared");
230
242
  });
231
243
 
232
- test("ADR-011: deriveStateFromDb auto-heals stale sketch flag when PLAN exists", async (t) => {
244
+ test("ADR-011: reconcileBeforeDispatch auto-heals stale sketch flag when PLAN exists", async (t) => {
233
245
  const originalCwd = process.cwd();
234
246
  const base = makeFixtureBase();
235
247
  t.after(() => cleanup(base, originalCwd));
@@ -244,12 +256,23 @@ test("ADR-011: deriveStateFromDb auto-heals stale sketch flag when PLAN exists",
244
256
  );
245
257
  process.chdir(base);
246
258
 
247
- const state = await deriveStateFromDb(base);
248
- assert.equal(getSlice("M001", "S02")?.is_sketch, 0, "derive should clear stale is_sketch");
249
- assert.equal(state.phase, "planning", "state should advance past refining once stale flag is healed");
259
+ // Pure derivation reports the stale flag as 'refining' without repairing it.
260
+ invalidateStateCache();
261
+ const stale = await deriveStateFromDb(base);
262
+ assert.equal(stale.phase, "refining", "derive alone must not heal the stale flag");
263
+ assert.equal(getSlice("M001", "S02")?.is_sketch, 1, "is_sketch unchanged before reconcile");
264
+
265
+ // Reconciliation owns the repair (ADR-017 stale-sketch-flag drift handler).
266
+ const reconcile = await reconcileBeforeDispatch(base);
267
+ assert.equal(reconcile.ok, true);
268
+ assert.equal(getSlice("M001", "S02")?.is_sketch, 0, "reconcile should clear stale is_sketch");
269
+
270
+ invalidateStateCache();
271
+ const healed = await deriveStateFromDb(base);
272
+ assert.equal(healed.phase, "planning", "state advances past refining once the stale flag is healed");
250
273
  });
251
274
 
252
- test("ADR-011: deriveState uses canonical artifact root for sketch-flag healing", async (t) => {
275
+ test("ADR-011: deriveState stays pure across worktree/canonical-root; healing belongs to reconcile at the canonical artifact root", async (t) => {
253
276
  const originalCwd = process.cwd();
254
277
  const base = makeFixtureBase();
255
278
  t.after(() => cleanup(base, originalCwd));
@@ -265,9 +288,22 @@ test("ADR-011: deriveState uses canonical artifact root for sketch-flag healing"
265
288
  mkdirSync(worktreePath, { recursive: true });
266
289
  process.chdir(worktreePath);
267
290
 
268
- const state = await deriveState(worktreePath, { projectRootForReads: base });
269
- assert.equal(getSlice("M001", "S02")?.is_sketch, 0, "deriveState should heal from canonical artifact root");
270
- assert.equal(state.phase, "planning", "state should advance past refining when PLAN exists at canonical root");
291
+ // Deriving from the worktree with reads routed to the canonical artifact
292
+ // root resolves DB state but never mutates it (ADR-017: derive is pure).
293
+ // The legacy projectRootForReads-driven heal is gone; healing now happens
294
+ // in reconcileBeforeDispatch, which auto runs against canonicalProjectRoot.
295
+ invalidateStateCache();
296
+ const beforeReconcile = await deriveState(worktreePath, { projectRootForReads: base });
297
+ assert.equal(beforeReconcile.phase, "refining", "derive alone must not heal, even via projectRootForReads");
298
+ assert.equal(getSlice("M001", "S02")?.is_sketch, 1, "derive must not mutate is_sketch");
299
+
300
+ const reconcile = await reconcileBeforeDispatch(base);
301
+ assert.equal(reconcile.ok, true);
302
+ assert.equal(getSlice("M001", "S02")?.is_sketch, 0, "reconcile at the canonical root heals the stale flag");
303
+
304
+ invalidateStateCache();
305
+ const healed = await deriveState(worktreePath, { projectRootForReads: base });
306
+ assert.equal(healed.phase, "planning", "re-derive advances past refining once healed at the canonical root");
271
307
  });
272
308
 
273
309
  test("ADR-011: schema v16 is idempotent — re-opening DB preserves is_sketch and sketch_scope columns", async (t) => {
@@ -72,6 +72,25 @@ function setupDependencyFixture(
72
72
  mkdirSync(targetSliceDir, { recursive: true });
73
73
  }
74
74
 
75
+ function setupFlatPhaseSlicePlan(base: string): void {
76
+ const phaseDir = join(base, ".gsd", "phases", "01-flat-phase");
77
+ mkdirSync(phaseDir, { recursive: true });
78
+ writeFileSync(
79
+ join(phaseDir, "01-01-PLAN.md"),
80
+ [
81
+ "# S01: Flat phase slice",
82
+ "",
83
+ "## Tasks",
84
+ "",
85
+ "- [ ] **T01: Flat task** `est:15m`",
86
+ "",
87
+ "## Verification",
88
+ "",
89
+ "- Rendered prompt points at this slice plan.",
90
+ ].join("\n"),
91
+ );
92
+ }
93
+
75
94
  // ─── inlineDependencySummaries truncation ─────────────────────────────────────
76
95
 
77
96
  describe("prompt-budget: inlineDependencySummaries truncation", () => {
@@ -412,6 +431,26 @@ describe("prompt-budget: execute-task template", () => {
412
431
  }
413
432
  });
414
433
 
434
+ it("flat-phase execute-task fallback points at the slice plan", async () => {
435
+ const base = createFixtureBase();
436
+ try {
437
+ setupFlatPhaseSlicePlan(base);
438
+
439
+ const prompt = await buildExecuteTaskPrompt("M001", "S01", "Slice", "T01", "Task", base, {
440
+ level: "minimal",
441
+ sessionContextWindow: 128_000,
442
+ });
443
+
444
+ assert.match(
445
+ prompt,
446
+ /Task plan not found at dispatch time\. Read `\.gsd\/phases\/01-flat-phase\/01-01-PLAN\.md` before executing\./,
447
+ );
448
+ assert.doesNotMatch(prompt, /\.gsd\/phases\/01-flat-phase\/tasks\/T01-PLAN\.md/);
449
+ } finally {
450
+ cleanup(base);
451
+ }
452
+ });
453
+
415
454
  it("verificationBudget format varies with context window size", () => {
416
455
  const budget128K = computeBudgets(128_000);
417
456
  const budget1M = computeBudgets(1_000_000);
@@ -566,6 +605,25 @@ describe("prompt-budget: execute-task builder truncation pattern", () => {
566
605
  });
567
606
 
568
607
  describe("prompt-budget: reactive-execute builder", () => {
608
+ it("flat-phase subagent fallback points at the slice plan", async () => {
609
+ const base = createFixtureBase();
610
+ try {
611
+ setupFlatPhaseSlicePlan(base);
612
+
613
+ const prompt = await buildReactiveExecutePrompt("M001", "Milestone", "S01", "Slice", ["T01"], base, undefined, {
614
+ sessionContextWindow: 128_000,
615
+ });
616
+
617
+ assert.match(
618
+ prompt,
619
+ /Task plan not found at dispatch time\. Read `\.gsd\/phases\/01-flat-phase\/01-01-PLAN\.md` before executing\./,
620
+ );
621
+ assert.doesNotMatch(prompt, /\.gsd\/phases\/01-flat-phase\/tasks\/T01-PLAN\.md/);
622
+ } finally {
623
+ cleanup(base);
624
+ }
625
+ });
626
+
569
627
  it("caps dependency carry-forward per ready subagent", async () => {
570
628
  const base = createFixtureBase();
571
629
  try {
@@ -533,6 +533,7 @@ test("plan-milestone prompt references DB-backed planning tool and explicitly fo
533
533
  assert.match(prompt, /Do \*\*not\*\* write `?\{\{outputPath\}\}`?, `?ROADMAP\.md`?, or other planning artifacts manually/i);
534
534
  assert.match(prompt, /NEVER call `gsd_plan_milestone` with only `milestoneId` and `sliceId`/);
535
535
  assert.match(prompt, /gsd_plan_slice/);
536
+ assert.match(prompt, /gsd_plan_task/);
536
537
  });
537
538
 
538
539
  test("discuss prompts forbid gsd_plan_milestone slice-only tool args", () => {
@@ -548,12 +549,12 @@ test("plan-slice prompt no longer frames direct PLAN writes as the source of tru
548
549
  assert.match(prompt, /Do \*\*not\*\* rely on direct `PLAN\.md` writes as the source of truth/i);
549
550
  });
550
551
 
551
- test("plan-slice prompt explicitly names gsd_plan_slice as DB-backed planning tool", () => {
552
+ test("plan-slice prompt explicitly names incremental DB-backed planning tools", () => {
552
553
  const prompt = readPrompt("plan-slice");
553
554
  assert.match(prompt, /gsd_plan_slice/);
554
555
  assert.match(prompt, /gsd_plan_task/);
555
- // The prompt should describe the DB-backed tool as the canonical write path
556
- assert.match(prompt, /DB-backed tool is the canonical write path/i);
556
+ assert.match(prompt, /Persist incrementally through DB-backed tools/i);
557
+ assert.match(prompt, /DB-backed tools are the canonical write path/i);
557
558
  });
558
559
 
559
560
  test("plan-slice prompt does not instruct direct file writes as a primary step", () => {
@@ -562,11 +563,12 @@ test("plan-slice prompt does not instruct direct file writes as a primary step",
562
563
  assert.doesNotMatch(prompt, /^\d+\.\s+Write `?\{\{outputPath\}\}`?\s*$/m);
563
564
  });
564
565
 
565
- test("plan-slice prompt clarifies gsd_plan_slice handles task persistence", () => {
566
+ test("plan-slice prompt requires per-task incremental persistence", () => {
566
567
  const prompt = readPrompt("plan-slice");
567
- // gsd_plan_slice persists tasks in its transaction — no separate gsd_plan_task calls needed
568
568
  assert.match(prompt, /gsd_plan_task/);
569
- assert.match(prompt, /gsd_plan_slice` handles task persistence/i);
569
+ assert.match(prompt, /omit `tasks` for this metadata call/i);
570
+ assert.match(prompt, /call `gsd_plan_task` once per task/i);
571
+ assert.doesNotMatch(prompt, /do not call `gsd_plan_task`/i);
570
572
  });
571
573
 
572
574
  test("plan-slice prompt references web app UAT guidance when planning browser work", () => {
@@ -227,7 +227,7 @@ test("plan-slice verify-fail logs a recovery warning when the tasks dir is missi
227
227
  }
228
228
  });
229
229
 
230
- test("plan-slice verify-fail logs a recovery warning when an individual task plan file is missing", () => {
230
+ test("plan-slice verify-fail logs a recovery warning when an individual task artifact is missing", () => {
231
231
  const base = createFixtureBase("gsd-recovery-logs-taskplan-");
232
232
  try {
233
233
  const dir = sliceDir(base, "M001", "S01");
@@ -236,17 +236,17 @@ test("plan-slice verify-fail logs a recovery warning when an individual task pla
236
236
  "# S01: Has task\n\n## Tasks\n\n- [ ] **T01: A** `est:15m`\n",
237
237
  "utf-8",
238
238
  );
239
- // Create the tasks dir but NOT the T01-PLAN.md file inside it.
239
+ // Create the tasks dir but NOT any T01 task artifact inside it.
240
240
  mkdirSync(join(dir, "tasks"), { recursive: true });
241
241
 
242
242
  const { result, logs } = verifyAndCaptureLogs("plan-slice", "M001/S01", base);
243
243
 
244
- assert.equal(result, false, "a missing task plan file must fail verification");
244
+ assert.equal(result, false, "a missing task artifact must fail verification");
245
245
  const recovery = findRecovery(logs);
246
246
  assert.ok(recovery, "a recovery warning must be logged");
247
247
  assert.match(
248
248
  recovery!.message,
249
- /verify-fail plan-slice M001\/S01: task plan missing .*T01-PLAN\.md/u,
249
+ /verify-fail plan-slice M001\/S01: task artifact missing for T01/u,
250
250
  );
251
251
  } finally {
252
252
  rmSync(base, { recursive: true, force: true });
@@ -0,0 +1,56 @@
1
+ // redact-secrets.test.ts
2
+ // Verifies secret-shaped substrings are replaced while benign text and JSON
3
+ // structure are preserved.
4
+ //
5
+ // Fake secrets are assembled from fragments at runtime so external secret
6
+ // scanners (GitGuardian) and the repo secret-scan never see a literal
7
+ // secret-shaped string in this source file — the runtime value still matches
8
+ // the redaction patterns, which is what the test exercises.
9
+
10
+ import { test } from "node:test";
11
+ import assert from "node:assert/strict";
12
+ import { redactSecrets } from "../redact-secrets.js";
13
+
14
+ const PLACEHOLDER = "«redacted»";
15
+
16
+ // Fragment-built fakes (never a full secret literal in source).
17
+ const FAKE = {
18
+ github: "gh" + "p_" + "A".repeat(36), // GitHub PAT shape: ghp_ + 36 chars
19
+ aws: "AKIA" + "IOSFODNN7EXAMPL0", // AWS access key id shape: AKIA + 16 chars
20
+ anthropic: "sk-" + "ant-" + "x".repeat(28), // Anthropic key shape
21
+ bearer: "sk-" + "b".repeat(24), // generic sk- token
22
+ };
23
+
24
+ test("redacts a Bearer authorization token", () => {
25
+ const out = redactSecrets(`Authorization: Bearer ${FAKE.bearer}`);
26
+ assert.ok(out.includes("Authorization:"), "keeps the label context");
27
+ assert.ok(out.includes(PLACEHOLDER), "redacts the token");
28
+ assert.ok(!out.includes(FAKE.bearer), "raw token is gone");
29
+ });
30
+
31
+ test("redacts key=value style secrets", () => {
32
+ const anth = redactSecrets(`ANTHROPIC_API_KEY="${FAKE.anthropic}"`);
33
+ assert.ok(anth.includes(PLACEHOLDER) && !anth.includes(FAKE.anthropic));
34
+ const gh = redactSecrets(`"token": "${FAKE.github}"`);
35
+ assert.ok(gh.includes(PLACEHOLDER) && !gh.includes(FAKE.github));
36
+ });
37
+
38
+ test("redacts an AWS access key id", () => {
39
+ const out = redactSecrets(`aws key ${FAKE.aws} in output`);
40
+ assert.ok(out.includes(PLACEHOLDER) && !out.includes(FAKE.aws));
41
+ });
42
+
43
+ test("leaves benign text mentioning 'token' untouched", () => {
44
+ const line = "The token is passed to the next unit for processing.";
45
+ assert.equal(redactSecrets(line), line);
46
+ });
47
+
48
+ test("redacting a JSON string keeps it valid JSON", () => {
49
+ const original = JSON.stringify({ msg: "using key=SECRETVALUE here", auth: FAKE.github });
50
+ const redacted = redactSecrets(original);
51
+ // Must still parse.
52
+ const parsed = JSON.parse(redacted) as { msg: string; auth: string };
53
+ // The bare GitHub token is redacted; the non-keyword "key=..." stays (no false structure break).
54
+ assert.ok(!redacted.includes(FAKE.github));
55
+ assert.equal(parsed.auth, PLACEHOLDER);
56
+ });
@@ -0,0 +1,73 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Verifies session bootstrap fails closed when flat-phase migration cannot complete.
3
+
4
+ import test from "node:test";
5
+ import assert from "node:assert/strict";
6
+ import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
7
+ import { join } from "node:path";
8
+ import { tmpdir } from "node:os";
9
+
10
+ import { registerHooks } from "../bootstrap/register-hooks.ts";
11
+ import { closeDatabase, insertMilestone, openDatabase } from "../gsd-db.ts";
12
+
13
+ type HookHandler = (event: unknown, ctx: any) => Promise<void> | void;
14
+
15
+ function createSessionStartHandler(): HookHandler {
16
+ const handlers = new Map<string, HookHandler>();
17
+ const pi = {
18
+ on(event: string, handler: HookHandler) {
19
+ handlers.set(event, handler);
20
+ },
21
+ };
22
+
23
+ registerHooks(pi as any, []);
24
+ const sessionStart = handlers.get("session_start");
25
+ assert.ok(sessionStart, "session_start handler should be registered");
26
+ return sessionStart;
27
+ }
28
+
29
+ function makeContext(basePath: string) {
30
+ return {
31
+ cwd: basePath,
32
+ hasUI: false,
33
+ ui: {
34
+ notify: () => {},
35
+ setStatus: () => {},
36
+ setWidget: () => {},
37
+ setWorkingMessage: () => {},
38
+ onTerminalInput: () => () => {},
39
+ },
40
+ model: null,
41
+ modelRegistry: {
42
+ setDisabledModelProviders: () => {},
43
+ },
44
+ sessionManager: {
45
+ getSessionId: () => null,
46
+ },
47
+ setCompactionThresholdOverride: () => {},
48
+ };
49
+ }
50
+
51
+ test("session_start rejects when required flat-phase migration fails", async (t) => {
52
+ const base = mkdtempSync(join(tmpdir(), "gsd-bootstrap-flat-migration-"));
53
+ t.after(() => {
54
+ closeDatabase();
55
+ rmSync(base, { recursive: true, force: true });
56
+ });
57
+
58
+ mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
59
+ writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-CONTEXT.md"), "# M001: Foundation\n", "utf-8");
60
+ openDatabase(join(base, ".gsd", "gsd.db"));
61
+ insertMilestone({ id: "M001", title: "Foundation", status: "active" });
62
+ closeDatabase();
63
+
64
+ writeFileSync(join(base, ".gsd-backups"), "not a directory\n", "utf-8");
65
+
66
+ const sessionStart = createSessionStartHandler();
67
+
68
+ await assert.rejects(
69
+ () => Promise.resolve(sessionStart({}, makeContext(base))),
70
+ /flat-phase migration/,
71
+ );
72
+ assert.ok(existsSync(join(base, ".gsd", "milestones", "M001")), "legacy layout should remain for recovery");
73
+ });