@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
@@ -29,21 +29,22 @@ test("#2007 bug 1: MAX_ARTIFACT_VERIFICATION_RETRIES constant is defined", () =>
29
29
  assert.equal(MAX_ARTIFACT_VERIFICATION_RETRIES, 3);
30
30
  });
31
31
 
32
- test("#2007 bug 1: retry state can represent each allowed attempt before exhaustion", () => {
32
+ test("#2007 bug 1: retry state keeps attempt separate from failure context", () => {
33
33
  const s = new AutoSession();
34
34
  const retryKey = "execute-task:M001/S01/T01";
35
+ const failureContext = "Missing expected artifact";
35
36
 
36
37
  for (let attempt = 1; attempt <= MAX_ARTIFACT_VERIFICATION_RETRIES; attempt++) {
37
38
  s.verificationRetryCount.set(retryKey, attempt);
38
39
  s.pendingVerificationRetry = {
39
40
  unitId: "M001/S01/T01",
40
- failureContext: `Missing expected artifact (attempt ${attempt}/${MAX_ARTIFACT_VERIFICATION_RETRIES}).`,
41
+ failureContext,
41
42
  attempt,
42
43
  };
43
44
 
44
45
  assert.equal(s.verificationRetryCount.get(retryKey), attempt);
45
46
  assert.equal(s.pendingVerificationRetry.attempt, attempt);
46
- assert.match(s.pendingVerificationRetry.failureContext, /attempt \d\/3/);
47
+ assert.equal(s.pendingVerificationRetry.failureContext, failureContext);
47
48
  }
48
49
  });
49
50
 
@@ -4,7 +4,7 @@ import { mkdtempSync, mkdirSync, realpathSync, rmSync, writeFileSync } from "nod
4
4
  import { join } from "node:path";
5
5
  import { tmpdir } from "node:os";
6
6
 
7
- import { resolveExpectedArtifactPath } from "../auto-artifact-paths.ts";
7
+ import { resolveExpectedArtifactPath, resolveSliceResearchLocation, resolveExistingSliceResearchPath } from "../auto-artifact-paths.ts";
8
8
  import { clearPathCache, _clearGsdRootCache, isLegacyMilestonesLayout, milestonesDir } from "../paths.ts";
9
9
 
10
10
  test("worktree artifact resolution falls back to project .gsd artifacts", () => {
@@ -359,3 +359,100 @@ test("canonical worktree + project-root legacy dir produces legacy filename (#bu
359
359
  rmSync(root, { recursive: true, force: true });
360
360
  }
361
361
  });
362
+
363
+ // ── resolveSliceResearchLocation / resolveExistingSliceResearchPath ───────────
364
+ //
365
+ // Added in the code-quality consolidation PR as the shared dual-path resolver
366
+ // for slice RESEARCH files (worktree projection first, then canonical path
367
+ // fallback). These tests guard: missing file → null pair; existing legacy-
368
+ // layout file → correct absolute and relative paths.
369
+
370
+ test("resolveSliceResearchLocation returns null pair when no RESEARCH file exists", () => {
371
+ const root = realpathSync(mkdtempSync(join(tmpdir(), "gsd-research-missing-")));
372
+ try {
373
+ const milestoneDir = join(root, ".gsd", "milestones", "M001");
374
+ mkdirSync(join(milestoneDir, "slices", "S01"), { recursive: true });
375
+ // Content-bearing dir so it is not treated as META-only, but no RESEARCH file.
376
+ writeFileSync(join(milestoneDir, "M001-CONTEXT.md"), "# context\n");
377
+
378
+ _clearGsdRootCache();
379
+ clearPathCache();
380
+
381
+ const result = resolveSliceResearchLocation(root, "M001", "S01");
382
+ assert.strictEqual(result.absolutePath, null, "absolutePath must be null when no RESEARCH exists");
383
+ assert.strictEqual(result.relativePath, null, "relativePath must be null when no RESEARCH exists");
384
+ } finally {
385
+ _clearGsdRootCache();
386
+ clearPathCache();
387
+ rmSync(root, { recursive: true, force: true });
388
+ }
389
+ });
390
+
391
+ test("resolveExistingSliceResearchPath returns null when no RESEARCH file exists", () => {
392
+ const root = realpathSync(mkdtempSync(join(tmpdir(), "gsd-research-null-")));
393
+ try {
394
+ const milestoneDir = join(root, ".gsd", "milestones", "M001");
395
+ mkdirSync(join(milestoneDir, "slices", "S01"), { recursive: true });
396
+ writeFileSync(join(milestoneDir, "M001-CONTEXT.md"), "# context\n");
397
+
398
+ _clearGsdRootCache();
399
+ clearPathCache();
400
+
401
+ assert.strictEqual(
402
+ resolveExistingSliceResearchPath(root, "M001", "S01"),
403
+ null,
404
+ "must return null when RESEARCH file is absent",
405
+ );
406
+ } finally {
407
+ _clearGsdRootCache();
408
+ clearPathCache();
409
+ rmSync(root, { recursive: true, force: true });
410
+ }
411
+ });
412
+
413
+ test("resolveSliceResearchLocation finds existing RESEARCH in legacy layout", () => {
414
+ const root = realpathSync(mkdtempSync(join(tmpdir(), "gsd-research-legacy-")));
415
+ try {
416
+ const milestoneDir = join(root, ".gsd", "milestones", "M001");
417
+ const sliceDir = join(milestoneDir, "slices", "S01");
418
+ mkdirSync(sliceDir, { recursive: true });
419
+ writeFileSync(join(milestoneDir, "M001-CONTEXT.md"), "# context\n");
420
+ const researchFile = join(sliceDir, "S01-RESEARCH.md");
421
+ writeFileSync(researchFile, "# slice research\n");
422
+
423
+ _clearGsdRootCache();
424
+ clearPathCache();
425
+
426
+ const result = resolveSliceResearchLocation(root, "M001", "S01");
427
+ assert.ok(result.absolutePath !== null, "absolutePath must be non-null when RESEARCH exists");
428
+ assert.ok(result.relativePath !== null, "relativePath must be non-null when RESEARCH exists");
429
+ assert.equal(result.absolutePath, researchFile, "absolutePath must point to the RESEARCH file");
430
+ } finally {
431
+ _clearGsdRootCache();
432
+ clearPathCache();
433
+ rmSync(root, { recursive: true, force: true });
434
+ }
435
+ });
436
+
437
+ test("resolveExistingSliceResearchPath returns absolute path when RESEARCH exists (legacy layout)", () => {
438
+ const root = realpathSync(mkdtempSync(join(tmpdir(), "gsd-research-existing-")));
439
+ try {
440
+ const milestoneDir = join(root, ".gsd", "milestones", "M001");
441
+ const sliceDir = join(milestoneDir, "slices", "S01");
442
+ mkdirSync(sliceDir, { recursive: true });
443
+ writeFileSync(join(milestoneDir, "M001-CONTEXT.md"), "# context\n");
444
+ const researchFile = join(sliceDir, "S01-RESEARCH.md");
445
+ writeFileSync(researchFile, "# research\n");
446
+
447
+ _clearGsdRootCache();
448
+ clearPathCache();
449
+
450
+ const result = resolveExistingSliceResearchPath(root, "M001", "S01");
451
+ assert.ok(result !== null, "must return non-null when RESEARCH exists");
452
+ assert.equal(result, researchFile, "must return the absolute path to the RESEARCH file");
453
+ } finally {
454
+ _clearGsdRootCache();
455
+ clearPathCache();
456
+ rmSync(root, { recursive: true, force: true });
457
+ }
458
+ });
@@ -8,6 +8,7 @@ import {
8
8
  getNewBudgetAlertLevel,
9
9
  resolveCompactionThresholdPercent,
10
10
  shouldRerootStepSessionForContext,
11
+ shouldWarnStepSessionForContext,
11
12
  } from "../auto.js";
12
13
  import {
13
14
  getUnitCostSpikeAction,
@@ -73,11 +74,19 @@ test("resolveCompactionThresholdPercent defaults to 60 and accepts ratio prefs",
73
74
  assert.equal(resolveCompactionThresholdPercent(0.4), 60);
74
75
  });
75
76
 
76
- test("shouldRerootStepSessionForContext uses compaction threshold pref", () => {
77
- assert.equal(shouldRerootStepSessionForContext(59.9, 0.6), false);
78
- assert.equal(shouldRerootStepSessionForContext(60, 0.6), true);
79
- assert.equal(shouldRerootStepSessionForContext(273.8, 0.6), true);
80
- assert.equal(shouldRerootStepSessionForContext(undefined, 0.6), false);
77
+ test("shouldWarnStepSessionForContext uses compaction threshold pref", () => {
78
+ assert.equal(shouldWarnStepSessionForContext(59.9, 0.6), false);
79
+ assert.equal(shouldWarnStepSessionForContext(60, 0.6), true);
80
+ assert.equal(shouldWarnStepSessionForContext(72, 0.6), true);
81
+ assert.equal(shouldWarnStepSessionForContext(undefined, 0.6), false);
82
+ });
83
+
84
+ test("shouldRerootStepSessionForContext only fires at the hard context threshold", () => {
85
+ assert.equal(shouldRerootStepSessionForContext(72), false);
86
+ assert.equal(shouldRerootStepSessionForContext(89.9), false);
87
+ assert.equal(shouldRerootStepSessionForContext(90), true);
88
+ assert.equal(shouldRerootStepSessionForContext(273.8), true);
89
+ assert.equal(shouldRerootStepSessionForContext(undefined), false);
81
90
  });
82
91
 
83
92
  test("resolveUnitCostSpikeMultiplier disables the spike pause for burn-max", () => {
@@ -49,6 +49,24 @@ test("recoverFailedMigration returns false when both .gsd and .gsd.migrating exi
49
49
  assert.ok(existsSync(join(base, ".gsd.migrating")), ".gsd.migrating must still exist");
50
50
  });
51
51
 
52
+ test("recoverFailedMigration removes orphan when .gsd is a real intact directory", (t) => {
53
+ const base = mkdtempSync(join(tmpdir(), "gsd-migrating-real-orphan-"));
54
+ t.after(() => rmSync(base, { recursive: true, force: true }));
55
+
56
+ const localGsd = join(base, ".gsd");
57
+ mkdirSync(join(localGsd, "phases"), { recursive: true });
58
+ mkdirSync(join(localGsd, "activity"), { recursive: true });
59
+ writeFileSync(join(localGsd, "STATE.md"), "# State\n", "utf-8");
60
+ writeFileSync(join(localGsd, "gsd.db"), "not empty\n", "utf-8");
61
+ mkdirSync(join(base, ".gsd.migrating"), { recursive: true });
62
+
63
+ const recovered = recoverFailedMigration(base);
64
+
65
+ assert.equal(recovered, true, "expected orphan cleanup to succeed");
66
+ assert.ok(existsSync(localGsd), ".gsd real directory must remain");
67
+ assert.ok(!existsSync(join(base, ".gsd.migrating")), ".gsd.migrating orphan must be removed");
68
+ });
69
+
52
70
  test("recoverFailedMigration removes orphan when .gsd is an intact external-state junction", (t) => {
53
71
  const base = mkdtempSync(join(tmpdir(), "gsd-migrating-orphan-"));
54
72
  const stateDir = mkdtempSync(join(tmpdir(), "gsd-migrating-state-"));
@@ -63,6 +63,62 @@ test("resolvePreferredModelConfig synthesizes heavy routing ceiling when models
63
63
  }
64
64
  });
65
65
 
66
+ test("resolvePreferredModelConfig treats token-profile model defaults as synthesized routing", () => {
67
+ const originalCwd = process.cwd();
68
+ const originalGsdHome = process.env.GSD_HOME;
69
+ const tempProject = makeTempDir("gsd-routing-profile-project-");
70
+ const tempGsdHome = makeTempDir("gsd-routing-profile-home-");
71
+
72
+ try {
73
+ mkdirSync(join(tempProject, ".gsd"), { recursive: true });
74
+ writeFileSync(
75
+ join(tempProject, ".gsd", "PREFERENCES.md"),
76
+ [
77
+ "---",
78
+ "token_profile: quality",
79
+ "dynamic_routing:",
80
+ " enabled: true",
81
+ " tier_models:",
82
+ " light: claude-haiku-4-5",
83
+ " standard: claude-sonnet-4-6",
84
+ " heavy: claude-opus-4-6",
85
+ "---",
86
+ ].join("\n"),
87
+ "utf-8",
88
+ );
89
+ process.env.GSD_HOME = tempGsdHome;
90
+ process.chdir(tempProject);
91
+
92
+ const config = resolvePreferredModelConfig(
93
+ "plan-slice",
94
+ {
95
+ provider: "anthropic",
96
+ id: "claude-sonnet-4-6",
97
+ },
98
+ true,
99
+ tempProject,
100
+ [
101
+ "anthropic/claude-haiku-4-5",
102
+ "anthropic/claude-sonnet-4-6",
103
+ "anthropic/claude-opus-4-6",
104
+ ],
105
+ "anthropic/claude-sonnet-4-6",
106
+ );
107
+
108
+ assert.deepEqual(config, {
109
+ primary: "claude-opus-4-6",
110
+ fallbacks: [],
111
+ source: "synthesized",
112
+ });
113
+ } finally {
114
+ process.chdir(originalCwd);
115
+ if (originalGsdHome === undefined) delete process.env.GSD_HOME;
116
+ else process.env.GSD_HOME = originalGsdHome;
117
+ rmSync(tempProject, { recursive: true, force: true });
118
+ rmSync(tempGsdHome, { recursive: true, force: true });
119
+ }
120
+ });
121
+
66
122
  test("resolvePreferredModelConfig falls back to auto start model when heavy tier is absent", () => {
67
123
  const originalCwd = process.cwd();
68
124
  const originalGsdHome = process.env.GSD_HOME;
@@ -152,6 +208,128 @@ test("resolvePreferredModelConfig keeps explicit phase models as the ceiling", (
152
208
  }
153
209
  });
154
210
 
211
+ // #1115 regression: a token_profile with dynamic_routing enabled but NO
212
+ // tier_models pins must still resolve the profile's per-phase model as a
213
+ // synthesized routing ceiling. Before the fix, resolvePreferredModelConfig
214
+ // bailed to undefined here (explicit detection skips profile defaults, and the
215
+ // synthesis path required tier_models), so auto dispatch fell back to the
216
+ // start model for every unit and silently discarded the profile.
217
+ test("resolvePreferredModelConfig resolves profile per-phase models as synthesized when tier_models are absent", () => {
218
+ const originalCwd = process.cwd();
219
+ const originalGsdHome = process.env.GSD_HOME;
220
+ const tempProject = makeTempDir("gsd-routing-profile-notier-");
221
+ const tempGsdHome = makeTempDir("gsd-routing-profile-notier-home-");
222
+
223
+ try {
224
+ mkdirSync(join(tempProject, ".gsd"), { recursive: true });
225
+ writeFileSync(
226
+ join(tempProject, ".gsd", "PREFERENCES.md"),
227
+ [
228
+ "---",
229
+ "token_profile: budget",
230
+ "dynamic_routing:",
231
+ " enabled: true",
232
+ "---",
233
+ ].join("\n"),
234
+ "utf-8",
235
+ );
236
+ process.env.GSD_HOME = tempGsdHome;
237
+ process.chdir(tempProject);
238
+
239
+ const availableModelIds = [
240
+ "anthropic/claude-haiku-4-5",
241
+ "anthropic/claude-sonnet-4-6",
242
+ "anthropic/claude-opus-4-6",
243
+ ];
244
+ const start = { provider: "anthropic", id: "claude-sonnet-4-6" };
245
+ // preferredModelId is intentionally left undefined so profile tier
246
+ // resolution is exercised rather than pinning every tier to the session
247
+ // model (a heavy session model can satisfy every tier).
248
+ const resolve = (unitType: string) =>
249
+ resolvePreferredModelConfig(unitType, start, true, tempProject, availableModelIds);
250
+
251
+ // budget profile: research=light, planning=standard, execution=standard,
252
+ // execution_simple=light, completion=light (PROFILE_TIER_MAP).
253
+ assert.deepEqual(resolve("research-milestone"), {
254
+ primary: "claude-haiku-4-5",
255
+ fallbacks: [],
256
+ source: "synthesized",
257
+ });
258
+ assert.deepEqual(resolve("plan-milestone"), {
259
+ primary: "claude-sonnet-4-6",
260
+ fallbacks: [],
261
+ source: "synthesized",
262
+ });
263
+ assert.deepEqual(resolve("execute-task"), {
264
+ primary: "claude-sonnet-4-6",
265
+ fallbacks: [],
266
+ source: "synthesized",
267
+ });
268
+ assert.deepEqual(resolve("execute-task-simple"), {
269
+ primary: "claude-haiku-4-5",
270
+ fallbacks: [],
271
+ source: "synthesized",
272
+ });
273
+ assert.deepEqual(resolve("complete-slice"), {
274
+ primary: "claude-haiku-4-5",
275
+ fallbacks: [],
276
+ source: "synthesized",
277
+ });
278
+ } finally {
279
+ process.chdir(originalCwd);
280
+ if (originalGsdHome === undefined) delete process.env.GSD_HOME;
281
+ else process.env.GSD_HOME = originalGsdHome;
282
+ rmSync(tempProject, { recursive: true, force: true });
283
+ rmSync(tempGsdHome, { recursive: true, force: true });
284
+ }
285
+ });
286
+
287
+ // #1115 guard: the explicit flat-rate opt-out must suppress synthesized routing
288
+ // even on the profile-derived (no tier_models) path — the opt-out moved ahead
289
+ // of both synthesis branches, so a flat-rate start model with
290
+ // allow_flat_rate_providers:false yields no config (start model is used as-is).
291
+ test("resolvePreferredModelConfig honors flat-rate opt-out on the profile path (no tier_models)", () => {
292
+ const originalCwd = process.cwd();
293
+ const originalGsdHome = process.env.GSD_HOME;
294
+ const tempProject = makeTempDir("gsd-routing-flatrate-notier-");
295
+ const tempGsdHome = makeTempDir("gsd-routing-flatrate-notier-home-");
296
+
297
+ try {
298
+ mkdirSync(join(tempProject, ".gsd"), { recursive: true });
299
+ writeFileSync(
300
+ join(tempProject, ".gsd", "PREFERENCES.md"),
301
+ [
302
+ "---",
303
+ "token_profile: budget",
304
+ "dynamic_routing:",
305
+ " enabled: true",
306
+ " allow_flat_rate_providers: false",
307
+ "---",
308
+ ].join("\n"),
309
+ "utf-8",
310
+ );
311
+ process.env.GSD_HOME = tempGsdHome;
312
+ process.chdir(tempProject);
313
+
314
+ const config = resolvePreferredModelConfig(
315
+ "execute-task",
316
+ // claude-code is a built-in flat-rate provider.
317
+ { provider: "claude-code", id: "claude-opus-4-6" },
318
+ true,
319
+ tempProject,
320
+ ["anthropic/claude-haiku-4-5", "anthropic/claude-sonnet-4-6", "anthropic/claude-opus-4-6"],
321
+ );
322
+
323
+ assert.equal(config, undefined);
324
+ } finally {
325
+ process.chdir(originalCwd);
326
+ if (originalGsdHome === undefined) delete process.env.GSD_HOME;
327
+ else process.env.GSD_HOME = originalGsdHome;
328
+ rmSync(tempProject, { recursive: true, force: true });
329
+ rmSync(tempGsdHome, { recursive: true, force: true });
330
+ }
331
+ });
332
+
155
333
  test("selectAndApplyModel honors explicit phase models without downgrading (#3617)", async () => {
156
334
  const originalCwd = process.cwd();
157
335
  const originalGsdHome = process.env.GSD_HOME;
@@ -14,6 +14,7 @@ import { capturePauseAutoUnitIdentity, pauseAuto, isAutoActive } from "../auto.t
14
14
  import { _resetPendingResolve, _setCurrentResolve } from "../auto/resolve.ts";
15
15
  import { autoSession } from "../auto-runtime-state.ts";
16
16
  import { _isPauseOriginCancelledResult } from "../auto/phase-helpers.ts";
17
+ import { handleAutoCommand } from "../commands/handlers/auto.ts";
17
18
 
18
19
  test("pauseAuto sets s.active = false synchronously before first await (blocks concurrent re-entry)", async () => {
19
20
  const base = mkdtempSync(join(tmpdir(), "gsd-double-pause-guard-"));
@@ -80,6 +81,41 @@ test("pauseAuto marks paused and cancels the in-flight unit before first await",
80
81
  }
81
82
  });
82
83
 
84
+ test("/gsd pause aborts the active pi turn before first await", async () => {
85
+ autoSession.reset();
86
+ autoSession.active = true;
87
+ let abortCount = 0;
88
+ const ctx = {
89
+ hasUI: false,
90
+ isIdle: () => false,
91
+ abort: () => {
92
+ abortCount += 1;
93
+ },
94
+ sessionManager: {
95
+ getSessionFile: () => null,
96
+ },
97
+ ui: {
98
+ setStatus() {},
99
+ setWidget() {},
100
+ notify() {},
101
+ },
102
+ } as any;
103
+
104
+ try {
105
+ const pausePromise = handleAutoCommand("pause", ctx, {} as any);
106
+
107
+ assert.equal(
108
+ abortCount,
109
+ 1,
110
+ "pauseAuto must abort the active pi turn before reporting auto-mode paused",
111
+ );
112
+
113
+ await pausePromise.catch(() => {});
114
+ } finally {
115
+ autoSession.reset();
116
+ }
117
+ });
118
+
83
119
  test("transient-abort errorContext is not classified as pause-origin cancellation", () => {
84
120
  // The phases.ts fix passes unitResult.errorContext to pauseAuto for transient aborts.
85
121
  // _isPauseOriginCancelledResult must return false when errorContext is present, ensuring
@@ -3,13 +3,14 @@
3
3
  import { test } from "node:test";
4
4
  import assert from "node:assert/strict";
5
5
  import { execFileSync } from "node:child_process";
6
- import { mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "node:fs";
6
+ import { existsSync, mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "node:fs";
7
7
  import { tmpdir } from "node:os";
8
8
  import { join, dirname } from "node:path";
9
9
 
10
10
  import {
11
11
  anchorProcessCwdForAutoResume,
12
12
  cleanupAfterLoopExit,
13
+ maybeRerootStepSessionForHighContext,
13
14
  pauseAuto,
14
15
  rerootCommandSession,
15
16
  stopAuto,
@@ -478,8 +479,8 @@ test("cleanupAfterLoopExit preserves step-mode surface and worktree session afte
478
479
  }
479
480
  });
480
481
 
481
- test("cleanupAfterLoopExit re-roots step-mode session when context exceeds compaction threshold", async (t) => {
482
- const base = mkdtempSync(join(tmpdir(), "gsd-step-reroot-"));
482
+ test("cleanupAfterLoopExit warns but does not re-root step-mode session at soft compaction threshold", async (t) => {
483
+ const base = mkdtempSync(join(tmpdir(), "gsd-step-soft-context-"));
483
484
  const worktree = join(base, ".gsd", "worktrees", "M001");
484
485
  const previousCwd = process.cwd();
485
486
  const newSessionWorkspaces: string[] = [];
@@ -515,7 +516,59 @@ test("cleanupAfterLoopExit re-roots step-mode session when context exceeds compa
515
516
  },
516
517
  } as any);
517
518
 
518
- assert.deepEqual(newSessionWorkspaces, [worktree], "hot step-mode cleanup should re-root in the active worktree");
519
+ assert.deepEqual(newSessionWorkspaces, [], "soft context pressure must not force a new command session");
520
+ assert.equal(
521
+ notifyMessages.some((msg) => msg.includes("context at 72.0%") && msg.includes("Use /compact")),
522
+ true,
523
+ "soft threshold should warn with a non-disruptive compaction prompt",
524
+ );
525
+ assert.equal(autoSession.basePath, worktree);
526
+ assert.equal(realpathSync(process.cwd()), realpathSync(worktree));
527
+ } finally {
528
+ autoSession.reset();
529
+ process.chdir(previousCwd);
530
+ rmSync(base, { recursive: true, force: true });
531
+ }
532
+ });
533
+
534
+ test("cleanupAfterLoopExit re-roots step-mode session at hard context threshold", async (t) => {
535
+ const base = mkdtempSync(join(tmpdir(), "gsd-step-reroot-"));
536
+ const worktree = join(base, ".gsd", "worktrees", "M001");
537
+ const previousCwd = process.cwd();
538
+ const newSessionWorkspaces: string[] = [];
539
+ const notifyMessages: string[] = [];
540
+
541
+ t.mock.method(WorktreeLifecycle.prototype, "restoreToProjectRoot", function () {});
542
+
543
+ mkdirSync(worktree, { recursive: true });
544
+ process.chdir(worktree);
545
+ autoSession.reset();
546
+ autoSession.active = true;
547
+ autoSession.paused = false;
548
+ autoSession.stepMode = true;
549
+ autoSession.preserveStepSurfaceAfterLoopExit = true;
550
+ autoSession.basePath = worktree;
551
+ autoSession.originalBasePath = base;
552
+ autoSession.cmdCtx = {
553
+ getContextUsage: () => ({ percent: 92, tokens: 920_000, contextWindow: 1_000_000 }),
554
+ newSession: async ({ workspaceRoot }: { workspaceRoot: string }) => {
555
+ newSessionWorkspaces.push(workspaceRoot);
556
+ return { cancelled: false };
557
+ },
558
+ } as any;
559
+
560
+ try {
561
+ await cleanupAfterLoopExit({
562
+ hasUI: true,
563
+ ui: {
564
+ setStatus: () => {},
565
+ setWidget: () => {},
566
+ setHeader: () => {},
567
+ notify: (_msg: string) => notifyMessages.push(_msg),
568
+ },
569
+ } as any);
570
+
571
+ assert.deepEqual(newSessionWorkspaces, [worktree], "critical context pressure should re-root in the active worktree");
519
572
  assert.equal(
520
573
  notifyMessages.some((msg) => msg.includes("Fresh session ready for /gsd next")),
521
574
  true,
@@ -530,6 +583,131 @@ test("cleanupAfterLoopExit re-roots step-mode session when context exceeds compa
530
583
  }
531
584
  });
532
585
 
586
+ test("maybeRerootStepSessionForHighContext re-roots at the hard threshold even when the soft pref is set above it", async () => {
587
+ // Regression: the hard 90% re-root must not be gated behind the configurable
588
+ // soft warn threshold, which is allowed up to 0.95. At 92% usage with a 0.95
589
+ // soft pref the soft warn predicate is false, but the session must still
590
+ // re-root because usage crossed the fixed hard boundary.
591
+ const dir = mkdtempSync(join(tmpdir(), "gsd-hard-reroot-high-soft-"));
592
+ const project = join(dir, "project");
593
+ const gsdHomeDir = join(dir, "home");
594
+ const previousCwd = process.cwd();
595
+ const previousGsdHome = process.env.GSD_HOME;
596
+
597
+ mkdirSync(join(project, ".gsd"), { recursive: true });
598
+ mkdirSync(gsdHomeDir, { recursive: true });
599
+ writeFileSync(
600
+ join(project, ".gsd", "PREFERENCES.md"),
601
+ ["---", "version: 1", "context_management:", " compaction_threshold_percent: 0.95", "---", ""].join("\n"),
602
+ "utf-8",
603
+ );
604
+
605
+ process.env.GSD_HOME = gsdHomeDir;
606
+ process.chdir(project);
607
+
608
+ const newSessionWorkspaces: string[] = [];
609
+ const notifyMessages: string[] = [];
610
+ const cmdCtx = {
611
+ getContextUsage: () => ({ percent: 92, tokens: 920_000, contextWindow: 1_000_000 }),
612
+ newSession: async ({ workspaceRoot }: { workspaceRoot: string }) => {
613
+ newSessionWorkspaces.push(workspaceRoot);
614
+ return { cancelled: false };
615
+ },
616
+ } as any;
617
+ const ctx = { ui: { notify: (msg: string) => notifyMessages.push(msg) } } as any;
618
+
619
+ try {
620
+ const result = await maybeRerootStepSessionForHighContext(ctx, project, cmdCtx, project);
621
+
622
+ assert.equal(result.rerooted, true, "92% usage must re-root even when the soft pref is 95%");
623
+ assert.deepEqual(newSessionWorkspaces, [project], "hard context pressure must re-root the command session");
624
+ const rerootMessage = notifyMessages.find((msg) => msg.includes("Fresh session ready for /gsd next"));
625
+ assert.ok(rerootMessage, "hard re-root should notify the user");
626
+ // The re-root was triggered by the 90% hard limit, so the notification must
627
+ // cite that limit and not the configured 95% soft compaction threshold.
628
+ assert.match(
629
+ rerootMessage,
630
+ /hard threshold: 90%/,
631
+ "hard re-root notification must cite the 90% hard threshold",
632
+ );
633
+ assert.equal(
634
+ rerootMessage.includes("95%"),
635
+ false,
636
+ "hard re-root notification must not cite the configured soft compaction threshold",
637
+ );
638
+ } finally {
639
+ process.chdir(previousCwd);
640
+ if (previousGsdHome === undefined) delete process.env.GSD_HOME;
641
+ else process.env.GSD_HOME = previousGsdHome;
642
+ rmSync(dir, { recursive: true, force: true });
643
+ }
644
+ });
645
+
646
+ test("maybeRerootStepSessionForHighContext writes a compaction snapshot only at the hard boundary", async () => {
647
+ // Regression: the snapshot is reserved for the hard re-root. Soft-only
648
+ // pressure must warn without writing a compaction snapshot.
649
+ const dir = mkdtempSync(join(tmpdir(), "gsd-soft-no-snapshot-"));
650
+ const project = join(dir, "project");
651
+ const gsdHomeDir = join(dir, "home");
652
+ const previousCwd = process.cwd();
653
+ const previousGsdHome = process.env.GSD_HOME;
654
+
655
+ mkdirSync(join(project, ".gsd"), { recursive: true });
656
+ mkdirSync(gsdHomeDir, { recursive: true });
657
+ writeFileSync(
658
+ join(project, ".gsd", "PREFERENCES.md"),
659
+ ["---", "version: 1", "context_management:", " compaction_threshold_percent: 0.6", "---", ""].join("\n"),
660
+ "utf-8",
661
+ );
662
+
663
+ process.env.GSD_HOME = gsdHomeDir;
664
+ process.chdir(project);
665
+
666
+ const newSessionWorkspaces: string[] = [];
667
+ const notifyMessages: string[] = [];
668
+ let contextPercent = 72;
669
+ const cmdCtx = {
670
+ getContextUsage: () => ({ percent: contextPercent, tokens: contextPercent * 10_000, contextWindow: 1_000_000 }),
671
+ newSession: async ({ workspaceRoot }: { workspaceRoot: string }) => {
672
+ newSessionWorkspaces.push(workspaceRoot);
673
+ return { cancelled: false };
674
+ },
675
+ } as any;
676
+ const ctx = { ui: { notify: (msg: string) => notifyMessages.push(msg) } } as any;
677
+ const snapshotPath = join(project, ".gsd", "last-snapshot.md");
678
+
679
+ try {
680
+ const softResult = await maybeRerootStepSessionForHighContext(ctx, project, cmdCtx, project);
681
+ assert.equal(softResult.rerooted, false, "soft pressure must not re-root");
682
+ assert.deepEqual(newSessionWorkspaces, [], "soft pressure must not open a new session");
683
+ assert.equal(
684
+ existsSync(snapshotPath),
685
+ false,
686
+ "soft-only pressure must not write a compaction snapshot",
687
+ );
688
+ assert.equal(
689
+ notifyMessages.some((msg) => msg.includes("context at 72.0%") && msg.includes("Use /compact")),
690
+ true,
691
+ "soft threshold should warn with a non-disruptive compaction prompt",
692
+ );
693
+
694
+ contextPercent = 92;
695
+ const hardResult = await maybeRerootStepSessionForHighContext(ctx, project, cmdCtx, project);
696
+ assert.equal(hardResult.rerooted, true, "hard pressure must re-root");
697
+ assert.deepEqual(newSessionWorkspaces, [project], "hard pressure should re-root once");
698
+ assert.equal(
699
+ existsSync(snapshotPath),
700
+ true,
701
+ "hard boundary must write the compaction snapshot",
702
+ );
703
+ } finally {
704
+ process.chdir(previousCwd);
705
+ if (previousGsdHome === undefined) delete process.env.GSD_HOME;
706
+ else process.env.GSD_HOME = previousGsdHome;
707
+ rmSync(dir, { recursive: true, force: true });
708
+ }
709
+ });
710
+
533
711
  test("cleanupAfterLoopExit restores project root through lifecycle and preserves chdir", async (t) => {
534
712
  const base = mkdtempSync(join(tmpdir(), "gsd-cleanup-lifecycle-"));
535
713
  const worktree = join(base, ".gsd", "worktrees", "M001");