@opengsd/gsd-pi 1.3.0-dev.65546769 → 1.3.0-dev.738160b9

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 (488) hide show
  1. package/README.md +1 -1
  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/resources/.managed-resources-content-hash +1 -1
  8. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  9. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +11 -2
  10. package/dist/resources/extensions/google-cli/stream-adapter.js +82 -15
  11. package/dist/resources/extensions/gsd/artifact-verification.js +427 -0
  12. package/dist/resources/extensions/gsd/auto/orchestrator.js +12 -3
  13. package/dist/resources/extensions/gsd/auto/session.js +11 -0
  14. package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +1 -1
  15. package/dist/resources/extensions/gsd/auto-artifact-paths.js +28 -1
  16. package/dist/resources/extensions/gsd/auto-budget.js +5 -1
  17. package/dist/resources/extensions/gsd/auto-dispatch.js +34 -20
  18. package/dist/resources/extensions/gsd/auto-post-unit.js +1 -1
  19. package/dist/resources/extensions/gsd/auto-prompts.js +29 -14
  20. package/dist/resources/extensions/gsd/auto-recovery.js +9 -510
  21. package/dist/resources/extensions/gsd/auto-runtime-state.js +4 -5
  22. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +3 -3
  23. package/dist/resources/extensions/gsd/auto-verification.js +5 -2
  24. package/dist/resources/extensions/gsd/auto.js +19 -10
  25. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +103 -13
  26. package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +39 -0
  27. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +11 -5
  28. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -0
  29. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  30. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +41 -21
  31. package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -19
  32. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +96 -10
  33. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +1 -1
  34. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +3 -1
  35. package/dist/resources/extensions/gsd/commands/handlers/auto.js +1 -1
  36. package/dist/resources/extensions/gsd/commands-context.js +19 -1
  37. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +17 -11
  38. package/dist/resources/extensions/gsd/commands-usage.js +1 -1
  39. package/dist/resources/extensions/gsd/commands-worktree.js +12 -10
  40. package/dist/resources/extensions/gsd/dashboard-overlay.js +32 -3
  41. package/dist/resources/extensions/gsd/db/engine.js +4 -1
  42. package/dist/resources/extensions/gsd/db/queries.js +60 -0
  43. package/dist/resources/extensions/gsd/db-memory-fts-schema.js +34 -0
  44. package/dist/resources/extensions/gsd/db-workspace.js +55 -3
  45. package/dist/resources/extensions/gsd/delegation-policy.js +1 -1
  46. package/dist/resources/extensions/gsd/docs/preferences-reference.md +2 -2
  47. package/dist/resources/extensions/gsd/doctor-engine-checks.js +192 -4
  48. package/dist/resources/extensions/gsd/doctor-providers.js +92 -8
  49. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +3 -0
  50. package/dist/resources/extensions/gsd/exec-sandbox.js +53 -11
  51. package/dist/resources/extensions/gsd/flat-phase-migration.js +45 -0
  52. package/dist/resources/extensions/gsd/forensics.js +2 -32
  53. package/dist/resources/extensions/gsd/git-service.js +61 -4
  54. package/dist/resources/extensions/gsd/gitignore.js +4 -1
  55. package/dist/resources/extensions/gsd/guided-flow-queue.js +66 -5
  56. package/dist/resources/extensions/gsd/health-widget.js +55 -29
  57. package/dist/resources/extensions/gsd/json-persistence.js +20 -0
  58. package/dist/resources/extensions/gsd/knowledge-backfill.js +18 -11
  59. package/dist/resources/extensions/gsd/layout-policy.js +3 -1
  60. package/dist/resources/extensions/gsd/markdown-renderer.js +8 -9
  61. package/dist/resources/extensions/gsd/memory-backfill.js +28 -21
  62. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +44 -21
  63. package/dist/resources/extensions/gsd/metrics.js +4 -4
  64. package/dist/resources/extensions/gsd/migrate-external.js +11 -2
  65. package/dist/resources/extensions/gsd/migration-auto-check.js +22 -0
  66. package/dist/resources/extensions/gsd/milestone-ids.js +32 -2
  67. package/dist/resources/extensions/gsd/milestone-implementation-evidence.js +26 -20
  68. package/dist/resources/extensions/gsd/orphan-stash-audit.js +92 -16
  69. package/dist/resources/extensions/gsd/prompts/code-review.md +6 -4
  70. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  71. package/dist/resources/extensions/gsd/prompts/plan-slice.md +3 -3
  72. package/dist/resources/extensions/gsd/quick.js +45 -2
  73. package/dist/resources/extensions/gsd/root-write-leak-guard.js +7 -1
  74. package/dist/resources/extensions/gsd/safety/destructive-guard.js +8 -1
  75. package/dist/resources/extensions/gsd/safety/evidence-collector.js +16 -1
  76. package/dist/resources/extensions/gsd/safety/file-change-validator.js +5 -2
  77. package/dist/resources/extensions/gsd/session-forensics.js +11 -1
  78. package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -1
  79. package/dist/resources/extensions/gsd/state/derive/cache.js +28 -0
  80. package/dist/resources/extensions/gsd/state/derive/db-open.js +39 -0
  81. package/dist/resources/extensions/gsd/state/derive/from-db.js +452 -0
  82. package/dist/resources/extensions/gsd/state/derive/index.js +75 -0
  83. package/dist/resources/extensions/gsd/state/derive/interrupted-work.js +21 -0
  84. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +45 -2
  85. package/dist/resources/extensions/gsd/state-reconciliation/index.js +48 -23
  86. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +32 -28
  87. package/dist/resources/extensions/gsd/state.js +12 -611
  88. package/dist/resources/extensions/gsd/tools/complete-milestone.js +4 -2
  89. package/dist/resources/extensions/gsd/tools/complete-slice.js +2 -2
  90. package/dist/resources/extensions/gsd/tools/complete-task.js +43 -14
  91. package/dist/resources/extensions/gsd/tools/exec-tool.js +7 -2
  92. package/dist/resources/extensions/gsd/tools/plan-slice.js +59 -44
  93. package/dist/resources/extensions/gsd/tools/plan-task.js +28 -5
  94. package/dist/resources/extensions/gsd/undo.js +43 -6
  95. package/dist/resources/extensions/gsd/unit-context-composer.js +23 -7
  96. package/dist/resources/extensions/gsd/unit-registry.js +36 -6
  97. package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +33 -3
  98. package/dist/resources/extensions/gsd/validation-block-guard.js +9 -4
  99. package/dist/resources/extensions/gsd/verification-gate.js +7 -0
  100. package/dist/resources/extensions/gsd/workflow-manifest.js +126 -13
  101. package/dist/resources/extensions/gsd/workflow-projections.js +19 -14
  102. package/dist/resources/extensions/gsd/workspace-git-preflight.js +30 -1
  103. package/dist/resources/extensions/gsd/worktree-manager.js +44 -2
  104. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  105. package/dist/web/standalone/.next/BUILD_ID +1 -1
  106. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  107. package/dist/web/standalone/.next/build-manifest.json +3 -3
  108. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  109. package/dist/web/standalone/.next/react-loadable-manifest.json +9 -9
  110. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  129. package/dist/web/standalone/.next/server/app/index.html +1 -1
  130. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  131. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  132. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  133. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  138. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  139. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  140. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  142. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  143. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  144. package/dist/web/standalone/.next/static/chunks/{2659.b7b129ee6a769448.js → 2659.58e950899a9bb82f.js} +1 -1
  145. package/dist/web/standalone/.next/static/chunks/2772.a7c1fcc69a4685ef.js +1 -0
  146. package/dist/web/standalone/.next/static/chunks/{3616.3c60753b8ffcbd2e.js → 3616.61a2af74bb8833c8.js} +1 -1
  147. package/dist/web/standalone/.next/static/chunks/{4283.8e446784528ed9dc.js → 4283.d0d9e0a955e441cb.js} +1 -1
  148. package/dist/web/standalone/.next/static/chunks/{5826.a46ecdd1cfe8dabc.js → 5826.5421d66c72b9f34e.js} +1 -1
  149. package/dist/web/standalone/.next/static/chunks/{8785.481aa5869991b760.js → 8785.e29b3134cab1d153.js} +1 -1
  150. package/dist/web/standalone/.next/static/chunks/8937.640dc9c2aaa1dfad.js +10 -0
  151. package/dist/web/standalone/.next/static/chunks/app/{page-6644fc6ee8ca1247.js → page-72a856634ad14c10.js} +1 -1
  152. package/dist/web/standalone/.next/static/chunks/webpack-9c401904f87ded16.js +1 -0
  153. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  154. package/package.json +1 -1
  155. package/packages/cloud-mcp-gateway/package.json +2 -2
  156. package/packages/contracts/dist/workflow.d.ts +1 -0
  157. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  158. package/packages/contracts/dist/workflow.js +2 -0
  159. package/packages/contracts/dist/workflow.js.map +1 -1
  160. package/packages/contracts/package.json +1 -1
  161. package/packages/daemon/package.json +4 -4
  162. package/packages/gsd-agent-core/dist/agent-session.d.ts +1 -0
  163. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  164. package/packages/gsd-agent-core/dist/agent-session.js +3 -0
  165. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  166. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts +41 -0
  167. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts.map +1 -0
  168. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js +62 -0
  169. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js.map +1 -0
  170. package/packages/gsd-agent-core/dist/index.d.ts +2 -0
  171. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  172. package/packages/gsd-agent-core/dist/index.js +2 -0
  173. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  174. package/packages/gsd-agent-core/dist/session/agent-session-events.js +1 -1
  175. package/packages/gsd-agent-core/dist/session/agent-session-events.js.map +1 -1
  176. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +1 -0
  177. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  178. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  179. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts +5 -0
  180. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  181. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +60 -3
  182. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  183. package/packages/gsd-agent-core/dist/transcript-store.d.ts +58 -0
  184. package/packages/gsd-agent-core/dist/transcript-store.d.ts.map +1 -0
  185. package/packages/gsd-agent-core/dist/transcript-store.js +132 -0
  186. package/packages/gsd-agent-core/dist/transcript-store.js.map +1 -0
  187. package/packages/gsd-agent-core/package.json +5 -5
  188. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  189. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  190. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +25 -11
  191. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  192. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts +4 -0
  193. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts.map +1 -0
  194. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js +7 -0
  195. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js.map +1 -0
  196. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -24
  197. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  198. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -829
  199. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  200. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts +58 -0
  201. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts.map +1 -0
  202. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js +312 -0
  203. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js.map +1 -0
  204. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts +31 -0
  205. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts.map +1 -0
  206. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js +130 -0
  207. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js.map +1 -0
  208. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts +15 -0
  209. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -0
  210. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +258 -0
  211. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -0
  212. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts +13 -0
  213. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts.map +1 -0
  214. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js +118 -0
  215. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js.map +1 -0
  216. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +9 -0
  217. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  218. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js +1 -1
  219. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  220. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts +54 -0
  221. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts.map +1 -0
  222. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js +20 -0
  223. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js.map +1 -0
  224. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +4 -1
  225. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  226. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +9 -0
  227. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  228. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts +56 -0
  229. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts.map +1 -0
  230. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js +44 -0
  231. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js.map +1 -0
  232. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts +5 -0
  233. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts.map +1 -0
  234. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js +77 -0
  235. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js.map +1 -0
  236. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts +2 -0
  237. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  238. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +23 -5
  239. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
  240. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  241. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +18 -0
  242. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  243. package/packages/gsd-agent-modes/package.json +7 -7
  244. package/packages/mcp-server/README.md +1 -1
  245. package/packages/mcp-server/dist/server.d.ts +1 -1
  246. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  247. package/packages/mcp-server/dist/server.js +3 -3
  248. package/packages/mcp-server/dist/server.js.map +1 -1
  249. package/packages/mcp-server/dist/workflow-tools.d.ts +13 -1
  250. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  251. package/packages/mcp-server/dist/workflow-tools.js +35 -21
  252. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  253. package/packages/mcp-server/package.json +4 -4
  254. package/packages/native/package.json +1 -1
  255. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  256. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  257. package/packages/pi-agent-core/package.json +1 -1
  258. package/packages/pi-ai/dist/models.generated.d.ts +46 -0
  259. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  260. package/packages/pi-ai/dist/models.generated.js +38 -0
  261. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  262. package/packages/pi-ai/package.json +1 -1
  263. package/packages/pi-coding-agent/README.md +3 -2
  264. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts +9 -0
  265. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts.map +1 -0
  266. package/packages/pi-coding-agent/dist/core/session-manager-context.js +94 -0
  267. package/packages/pi-coding-agent/dist/core/session-manager-context.js.map +1 -0
  268. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts +8 -0
  269. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts.map +1 -0
  270. package/packages/pi-coding-agent/dist/core/session-manager-list.js +244 -0
  271. package/packages/pi-coding-agent/dist/core/session-manager-list.js.map +1 -0
  272. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts +12 -0
  273. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts.map +1 -0
  274. package/packages/pi-coding-agent/dist/core/session-manager-migration.js +84 -0
  275. package/packages/pi-coding-agent/dist/core/session-manager-migration.js.map +1 -0
  276. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +135 -0
  277. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -0
  278. package/packages/pi-coding-agent/dist/core/session-manager-types.js +2 -0
  279. package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -0
  280. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +6 -154
  281. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  282. package/packages/pi-coding-agent/dist/core/session-manager.js +22 -459
  283. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  284. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts +75 -75
  285. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts.map +1 -1
  286. package/packages/pi-coding-agent/dist/theme/theme-schema.js +1 -1
  287. package/packages/pi-coding-agent/dist/theme/theme-schema.js.map +1 -1
  288. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/theme/theme.js +11 -7
  290. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  291. package/packages/pi-coding-agent/package.json +7 -7
  292. package/packages/pi-tui/package.json +2 -2
  293. package/packages/rpc-client/package.json +2 -2
  294. package/pkg/dist/theme/theme-schema.d.ts +75 -75
  295. package/pkg/dist/theme/theme-schema.d.ts.map +1 -1
  296. package/pkg/dist/theme/theme-schema.js +1 -1
  297. package/pkg/dist/theme/theme-schema.js.map +1 -1
  298. package/pkg/dist/theme/theme.d.ts.map +1 -1
  299. package/pkg/dist/theme/theme.js +11 -7
  300. package/pkg/dist/theme/theme.js.map +1 -1
  301. package/pkg/package.json +1 -1
  302. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  303. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +20 -2
  304. package/src/resources/extensions/claude-code-cli/tests/index.test.ts +14 -0
  305. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +80 -0
  306. package/src/resources/extensions/google-cli/stream-adapter.ts +106 -19
  307. package/src/resources/extensions/gsd/artifact-verification.ts +464 -0
  308. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  309. package/src/resources/extensions/gsd/auto/orchestrator.ts +25 -11
  310. package/src/resources/extensions/gsd/auto/session.ts +14 -0
  311. package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +3 -1
  312. package/src/resources/extensions/gsd/auto-artifact-paths.ts +47 -1
  313. package/src/resources/extensions/gsd/auto-budget.ts +12 -1
  314. package/src/resources/extensions/gsd/auto-dispatch.ts +35 -24
  315. package/src/resources/extensions/gsd/auto-post-unit.ts +1 -1
  316. package/src/resources/extensions/gsd/auto-prompts.ts +41 -15
  317. package/src/resources/extensions/gsd/auto-recovery.ts +13 -511
  318. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -5
  319. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +3 -2
  320. package/src/resources/extensions/gsd/auto-verification.ts +5 -1
  321. package/src/resources/extensions/gsd/auto.ts +23 -8
  322. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +125 -12
  323. package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +44 -0
  324. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +11 -5
  325. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -0
  326. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  327. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +52 -21
  328. package/src/resources/extensions/gsd/bootstrap/system-context.ts +52 -18
  329. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +104 -10
  330. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +1 -1
  331. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +2 -1
  332. package/src/resources/extensions/gsd/commands/handlers/auto.ts +1 -1
  333. package/src/resources/extensions/gsd/commands-context.ts +18 -1
  334. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +15 -10
  335. package/src/resources/extensions/gsd/commands-usage.ts +1 -1
  336. package/src/resources/extensions/gsd/commands-worktree.ts +12 -10
  337. package/src/resources/extensions/gsd/dashboard-overlay.ts +32 -3
  338. package/src/resources/extensions/gsd/db/engine.ts +8 -1
  339. package/src/resources/extensions/gsd/db/queries.ts +79 -0
  340. package/src/resources/extensions/gsd/db-memory-fts-schema.ts +45 -0
  341. package/src/resources/extensions/gsd/db-workspace.ts +61 -3
  342. package/src/resources/extensions/gsd/delegation-policy.ts +1 -1
  343. package/src/resources/extensions/gsd/docs/preferences-reference.md +2 -2
  344. package/src/resources/extensions/gsd/doctor-engine-checks.ts +233 -5
  345. package/src/resources/extensions/gsd/doctor-providers.ts +103 -9
  346. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +3 -0
  347. package/src/resources/extensions/gsd/doctor-types.ts +3 -0
  348. package/src/resources/extensions/gsd/exec-sandbox.ts +56 -11
  349. package/src/resources/extensions/gsd/flat-phase-migration.ts +44 -0
  350. package/src/resources/extensions/gsd/forensics.ts +2 -33
  351. package/src/resources/extensions/gsd/git-service.ts +69 -5
  352. package/src/resources/extensions/gsd/gitignore.ts +4 -1
  353. package/src/resources/extensions/gsd/guided-flow-queue.ts +89 -4
  354. package/src/resources/extensions/gsd/health-widget.ts +69 -32
  355. package/src/resources/extensions/gsd/json-persistence.ts +20 -0
  356. package/src/resources/extensions/gsd/knowledge-backfill.ts +16 -10
  357. package/src/resources/extensions/gsd/layout-policy.ts +2 -1
  358. package/src/resources/extensions/gsd/markdown-renderer.ts +8 -11
  359. package/src/resources/extensions/gsd/memory-backfill.ts +26 -20
  360. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +51 -19
  361. package/src/resources/extensions/gsd/metrics.ts +4 -4
  362. package/src/resources/extensions/gsd/migrate-external.ts +8 -2
  363. package/src/resources/extensions/gsd/migration-auto-check.ts +23 -0
  364. package/src/resources/extensions/gsd/milestone-ids.ts +31 -2
  365. package/src/resources/extensions/gsd/milestone-implementation-evidence.ts +35 -21
  366. package/src/resources/extensions/gsd/orphan-stash-audit.ts +108 -20
  367. package/src/resources/extensions/gsd/prompts/code-review.md +6 -4
  368. package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  369. package/src/resources/extensions/gsd/prompts/plan-slice.md +3 -3
  370. package/src/resources/extensions/gsd/quick.ts +43 -2
  371. package/src/resources/extensions/gsd/root-write-leak-guard.ts +13 -1
  372. package/src/resources/extensions/gsd/safety/destructive-guard.ts +9 -1
  373. package/src/resources/extensions/gsd/safety/evidence-collector.ts +16 -1
  374. package/src/resources/extensions/gsd/safety/file-change-validator.ts +8 -2
  375. package/src/resources/extensions/gsd/session-forensics.ts +11 -1
  376. package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -1
  377. package/src/resources/extensions/gsd/state/derive/cache.ts +46 -0
  378. package/src/resources/extensions/gsd/state/derive/db-open.ts +45 -0
  379. package/src/resources/extensions/gsd/state/derive/from-db.ts +561 -0
  380. package/src/resources/extensions/gsd/state/derive/index.ts +104 -0
  381. package/src/resources/extensions/gsd/state/derive/interrupted-work.ts +31 -0
  382. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +81 -7
  383. package/src/resources/extensions/gsd/state-reconciliation/index.ts +50 -24
  384. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +43 -28
  385. package/src/resources/extensions/gsd/state.ts +32 -732
  386. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +4 -3
  387. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +98 -1
  388. package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +14 -5
  389. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +36 -0
  390. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +182 -4
  391. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +146 -1
  392. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +30 -0
  393. package/src/resources/extensions/gsd/tests/commands-context.test.ts +26 -0
  394. package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +1 -0
  395. package/src/resources/extensions/gsd/tests/commands-worktree-clean.test.ts +80 -0
  396. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +28 -0
  397. package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +69 -0
  398. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +11 -0
  399. package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +48 -8
  400. package/src/resources/extensions/gsd/tests/complete-task.test.ts +75 -0
  401. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +55 -2
  402. package/src/resources/extensions/gsd/tests/db-memory-fts-schema.test.ts +58 -3
  403. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +51 -0
  404. package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +44 -0
  405. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +143 -0
  406. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +26 -1
  407. package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +70 -2
  408. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +107 -0
  409. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +239 -2
  410. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +38 -0
  411. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +16 -0
  412. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +45 -1
  413. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +40 -0
  414. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +37 -2
  415. package/src/resources/extensions/gsd/tests/forensics-error-filter.test.ts +88 -0
  416. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +4 -0
  417. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +42 -0
  418. package/src/resources/extensions/gsd/tests/health-widget.test.ts +268 -3
  419. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +130 -3
  420. package/src/resources/extensions/gsd/tests/integration/queue-active-milestone-context-budget.test.ts +93 -0
  421. package/src/resources/extensions/gsd/tests/integration/quick-branch-lifecycle.test.ts +56 -9
  422. package/src/resources/extensions/gsd/tests/json-persistence-atomic.test.ts +47 -0
  423. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +35 -0
  424. package/src/resources/extensions/gsd/tests/knowledge-cold-start.test.ts +14 -0
  425. package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +78 -0
  426. package/src/resources/extensions/gsd/tests/memory-store.test.ts +48 -0
  427. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +31 -1
  428. package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +6 -0
  429. package/src/resources/extensions/gsd/tests/metrics.test.ts +1 -0
  430. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +57 -0
  431. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +70 -0
  432. package/src/resources/extensions/gsd/tests/orchestrator-logs.test.ts +43 -1
  433. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +91 -7
  434. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +26 -0
  435. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -1
  436. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +1 -1
  437. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +10 -0
  438. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +103 -4
  439. package/src/resources/extensions/gsd/tests/plan-task.test.ts +44 -1
  440. package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +4 -2
  441. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +54 -1
  442. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +50 -14
  443. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +58 -0
  444. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -6
  445. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +195 -1
  446. package/src/resources/extensions/gsd/tests/read-uat-gate-verdict.test.ts +185 -0
  447. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +87 -0
  448. package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +103 -0
  449. package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +20 -1
  450. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +15 -3
  451. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +56 -0
  452. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +191 -0
  453. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +208 -0
  454. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +32 -3
  455. package/src/resources/extensions/gsd/tests/undo.test.ts +74 -0
  456. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +193 -14
  457. package/src/resources/extensions/gsd/tests/unmerged-milestone-guard.test.ts +25 -0
  458. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +38 -0
  459. package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +79 -0
  460. package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +69 -4
  461. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +66 -0
  462. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +96 -15
  463. package/src/resources/extensions/gsd/tests/workflow-mcp-preflight.test.ts +1 -0
  464. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +8 -4
  465. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +6 -5
  466. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +151 -2
  467. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +39 -0
  468. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  469. package/src/resources/extensions/gsd/tools/complete-slice.ts +2 -2
  470. package/src/resources/extensions/gsd/tools/complete-task.ts +53 -15
  471. package/src/resources/extensions/gsd/tools/exec-tool.ts +7 -3
  472. package/src/resources/extensions/gsd/tools/plan-slice.ts +60 -47
  473. package/src/resources/extensions/gsd/tools/plan-task.ts +30 -5
  474. package/src/resources/extensions/gsd/undo.ts +47 -6
  475. package/src/resources/extensions/gsd/unit-context-composer.ts +33 -7
  476. package/src/resources/extensions/gsd/unit-registry.ts +36 -6
  477. package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +41 -5
  478. package/src/resources/extensions/gsd/validation-block-guard.ts +13 -7
  479. package/src/resources/extensions/gsd/verification-gate.ts +8 -0
  480. package/src/resources/extensions/gsd/workflow-manifest.ts +141 -7
  481. package/src/resources/extensions/gsd/workflow-projections.ts +20 -14
  482. package/src/resources/extensions/gsd/workspace-git-preflight.ts +31 -0
  483. package/src/resources/extensions/gsd/worktree-manager.ts +41 -1
  484. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +0 -1
  485. package/dist/web/standalone/.next/static/chunks/796.e0bdc932325d7e03.js +0 -10
  486. package/dist/web/standalone/.next/static/chunks/webpack-f46ea08200a0227e.js +0 -1
  487. /package/dist/web/standalone/.next/static/{BTKtGFF1Y-hvVJEGhBRo9 → 2A_WqqCS-EoYZxN9_v3d2}/_buildManifest.js +0 -0
  488. /package/dist/web/standalone/.next/static/{BTKtGFF1Y-hvVJEGhBRo9 → 2A_WqqCS-EoYZxN9_v3d2}/_ssgManifest.js +0 -0
@@ -97,8 +97,10 @@ import {
97
97
  getNewBudgetAlertLevel,
98
98
  getBudgetEnforcementAction,
99
99
  getContextPauseAction,
100
+ HARD_CONTEXT_REROOT_THRESHOLD_PERCENT,
100
101
  resolveCompactionThresholdPercent,
101
102
  shouldRerootStepSessionForContext,
103
+ shouldWarnStepSessionForContext,
102
104
  } from "./auto-budget.js";
103
105
  import {
104
106
  markToolStart as _markToolStart,
@@ -701,6 +703,7 @@ export {
701
703
  getContextPauseAction,
702
704
  resolveCompactionThresholdPercent,
703
705
  shouldRerootStepSessionForContext,
706
+ shouldWarnStepSessionForContext,
704
707
  } from "./auto-budget.js";
705
708
 
706
709
  function closeOutSignalInterruptedUnit(currentBasePath: string): void {
@@ -1375,9 +1378,10 @@ export async function rerootCommandSession(
1375
1378
  }
1376
1379
 
1377
1380
  /**
1378
- * After a completed step-mode unit, reclaim context headroom when usage is at
1379
- * or above the compaction threshold. Writes a context-mode snapshot first, then
1380
- * re-roots the visible command session while leaving the NEXT progress surface.
1381
+ * After a completed step-mode unit, warn when usage reaches the configurable
1382
+ * soft context threshold. At the fixed hard boundary, write a context-mode
1383
+ * snapshot and re-root the visible command session while leaving the NEXT
1384
+ * progress surface.
1381
1385
  */
1382
1386
  export async function maybeRerootStepSessionForHighContext(
1383
1387
  ctx: ExtensionContext,
@@ -1392,7 +1396,19 @@ export async function maybeRerootStepSessionForHighContext(
1392
1396
  const prefs = loadEffectiveGSDPreferences(workspaceRoot);
1393
1397
  const compactionThreshold = prefs?.preferences.context_management?.compaction_threshold_percent;
1394
1398
 
1395
- if (!shouldRerootStepSessionForContext(contextPercent, compactionThreshold)) {
1399
+ const shouldWarn = shouldWarnStepSessionForContext(contextPercent, compactionThreshold);
1400
+ const shouldReroot = shouldRerootStepSessionForContext(contextPercent);
1401
+ if (!shouldWarn && !shouldReroot) {
1402
+ return { rerooted: false };
1403
+ }
1404
+
1405
+ const displayPercent = (contextPercent as number).toFixed(1);
1406
+ const thresholdDisplay = resolveCompactionThresholdPercent(compactionThreshold).toFixed(0);
1407
+ if (!shouldReroot) {
1408
+ ctx.ui.notify(
1409
+ `Step complete — context at ${displayPercent}% (soft threshold: ${thresholdDisplay}%). Use /compact when convenient; continuing in this session is still safe.`,
1410
+ "info",
1411
+ );
1396
1412
  return { rerooted: false };
1397
1413
  }
1398
1414
 
@@ -1401,12 +1417,10 @@ export async function maybeRerootStepSessionForHighContext(
1401
1417
  const { writeContextModeCompactionSnapshot } = await import("./context-mode-snapshot.js");
1402
1418
  await writeContextModeCompactionSnapshot(snapshotBase);
1403
1419
 
1404
- const displayPercent = (contextPercent as number).toFixed(1);
1405
- const thresholdDisplay = resolveCompactionThresholdPercent(compactionThreshold).toFixed(0);
1406
1420
  const result = await rerootCommandSession(cmdCtx, workspaceRoot);
1407
1421
  if (result.status === "ok") {
1408
1422
  ctx.ui.notify(
1409
- `Step complete — context at ${displayPercent}% (threshold: ${thresholdDisplay}%). Fresh session ready for /gsd next.`,
1423
+ `Step complete — context at ${displayPercent}% (hard threshold: ${HARD_CONTEXT_REROOT_THRESHOLD_PERCENT}%). Fresh session ready for /gsd next.`,
1410
1424
  "info",
1411
1425
  );
1412
1426
  return { rerooted: true };
@@ -2102,7 +2116,7 @@ export function _selectStopAutoWorktreeExit(args: {
2102
2116
  /**
2103
2117
  * Pause auto-mode without destroying state. Context is preserved.
2104
2118
  * The user can interact with the agent, then `/gsd auto` resumes
2105
- * from disk state. Called when the user presses Escape during auto-mode.
2119
+ * from disk state. Called when the user presses Escape or runs `/gsd pause`.
2106
2120
  */
2107
2121
  export async function pauseAuto(
2108
2122
  ctx?: ExtensionContext,
@@ -2129,6 +2143,7 @@ export async function pauseAuto(
2129
2143
 
2130
2144
  s.active = false;
2131
2145
  s.paused = true;
2146
+ if (options.abortActiveTurn && ctx && !ctx.isIdle()) ctx.abort();
2132
2147
  clearUnitTimeout();
2133
2148
  stopAutoCommandPolling();
2134
2149
 
@@ -1,6 +1,8 @@
1
1
  // gsd-pi + src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts - Handles provider and agent-end recovery for GSD auto-mode.
2
2
 
3
3
  import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
4
+ import { mkdirSync, readdirSync, writeFileSync } from "node:fs";
5
+ import { join } from "node:path";
4
6
 
5
7
  import type { AgentEndEvent, ErrorContext } from "../auto/types.js";
6
8
  import { logWarning } from "../workflow-logger.js";
@@ -11,7 +13,7 @@ import {
11
13
  maybeHandleEmptyIntentTurn,
12
14
  resetEmptyTurnCounter,
13
15
  } from "../guided-flow.js";
14
- import { clearPathCache } from "../paths.js";
16
+ import { clearPathCache, gsdRoot } from "../paths.js";
15
17
  import {
16
18
  getAutoDashboardData,
17
19
  getAutoModeStartModel,
@@ -34,7 +36,7 @@ import { resolveModelId } from "../auto-model-selection.js";
34
36
  import { resolveProjectRoot } from "../worktree.js";
35
37
  import { clearDiscussionFlowState } from "./write-gate.js";
36
38
  import { scheduleFallbackContinuation } from "./fallback-continuation.js";
37
- import { clearGuidedUnitContext } from "../guided-unit-context.js";
39
+ import { clearGuidedUnitContext, getGuidedUnitContext, type GuidedUnitContext } from "../guided-unit-context.js";
38
40
  import { resumeAutoAfterProviderDelay } from "./provider-error-resume.js";
39
41
  import {
40
42
  classifyError,
@@ -116,9 +118,14 @@ export function isUserInitiatedAbortMessage(message: string | undefined | null):
116
118
  export function shouldDeferTransientErrorToCoreRetry(
117
119
  cls: ErrorClass,
118
120
  rawErrorMsg: string,
121
+ deferCheckMsg: string = rawErrorMsg,
119
122
  ): boolean {
120
123
  if (!isTransient(cls) || cls.kind === "rate-limit") return false;
121
- return !/retry failed after \d+ attempts:/i.test(rawErrorMsg);
124
+ // Empty rawErrorMsg means the SDK terminated the session without providing an
125
+ // error string — core is done, not mid-retry. GSD must schedule its own
126
+ // retry rather than silently deferring to a core that has already exited.
127
+ if (!rawErrorMsg) return false;
128
+ return !/retry failed after \d+ attempts:/i.test(deferCheckMsg);
122
129
  }
123
130
 
124
131
  type ProviderModelFallbackParams = {
@@ -388,6 +395,108 @@ export function suppressTerminalDeletedWorktreeMessageEnd(event: MessageEndLike)
388
395
  return true;
389
396
  }
390
397
 
398
+ function modelLabel(ctx: ExtensionContext): string {
399
+ const provider = ctx.model?.provider;
400
+ const id = ctx.model?.id;
401
+ return provider && id ? `${provider}/${id}` : "unknown model";
402
+ }
403
+
404
+ function isFatalManualGuidedTerminalFailure(lastMsg: unknown): boolean {
405
+ if (!isObjectRecord(lastMsg) || !("stopReason" in lastMsg)) return false;
406
+ if (lastMsg.stopReason === "error") {
407
+ const rawErrorMsg = ("errorMessage" in lastMsg && lastMsg.errorMessage) ? String(lastMsg.errorMessage) : "";
408
+ if (isUserInitiatedAbortMessage(rawErrorMsg)) return false;
409
+ return true;
410
+ }
411
+ if (lastMsg.stopReason !== "aborted") return false;
412
+
413
+ const content = "content" in lastMsg ? lastMsg.content : undefined;
414
+ const hasErrorMessage = "errorMessage" in lastMsg && !!lastMsg.errorMessage;
415
+ return hasErrorMessage || !_hasEmptyAgentEndContent(content);
416
+ }
417
+
418
+ function terminalFailureDetail(lastMsg: unknown): string {
419
+ if (!isObjectRecord(lastMsg)) return "Provider turn ended with an unknown terminal error.";
420
+ const rawErrorMsg = ("errorMessage" in lastMsg && lastMsg.errorMessage) ? String(lastMsg.errorMessage) : "";
421
+ const content = "content" in lastMsg ? lastMsg.content : undefined;
422
+ const displayMsg = resolveAgentEndErrorDisplay(rawErrorMsg, content).replace(/\s+/g, " ").trim();
423
+ if (displayMsg) return displayMsg.length > 300 ? `${displayMsg.slice(0, 300)}...` : displayMsg;
424
+ return lastMsg.stopReason === "aborted"
425
+ ? "Provider turn aborted with error context."
426
+ : "Provider stream ended with stopReason=error.";
427
+ }
428
+
429
+ function nextManualActivitySequence(activityDir: string): string {
430
+ let maxSeq = 0;
431
+ try {
432
+ for (const file of readdirSync(activityDir)) {
433
+ const match = /^(\d+)-/.exec(file);
434
+ if (match) maxSeq = Math.max(maxSeq, Number.parseInt(match[1]!, 10));
435
+ }
436
+ } catch {
437
+ return "001";
438
+ }
439
+ return String(maxSeq + 1).padStart(3, "0");
440
+ }
441
+
442
+ function writeManualGuidedTerminalErrorActivity(
443
+ basePath: string,
444
+ unitType: string,
445
+ model: string,
446
+ detail: string,
447
+ stopReason: unknown,
448
+ ): void {
449
+ const activityDir = join(gsdRoot(basePath), "activity");
450
+ mkdirSync(activityDir, { recursive: true });
451
+ const seq = nextManualActivitySequence(activityDir);
452
+ const safeUnitType = unitType.replace(/[^a-z0-9_.-]+/gi, "-");
453
+ const markerPath = join(activityDir, `${seq}-${safeUnitType}-manual-terminal-provider-error.jsonl`);
454
+ const message = `Manual guided ${unitType} turn ended with provider ${String(stopReason)} on ${model}: ${detail}`;
455
+ writeFileSync(
456
+ markerPath,
457
+ JSON.stringify({
458
+ type: "message",
459
+ message: {
460
+ role: "toolResult",
461
+ toolCallId: "manual-guided-terminal-provider-error",
462
+ toolName: "provider",
463
+ isError: true,
464
+ content: [{ type: "text", text: message }],
465
+ },
466
+ }) + "\n",
467
+ "utf-8",
468
+ );
469
+ }
470
+
471
+ function observeManualDiscussTerminalError(
472
+ ctx: ExtensionContext,
473
+ lastMsg: unknown,
474
+ guidedUnit: GuidedUnitContext | null,
475
+ ): void {
476
+ if (!guidedUnit?.unitType.startsWith("discuss-")) return;
477
+ if (!isFatalManualGuidedTerminalFailure(lastMsg)) return;
478
+
479
+ const model = modelLabel(ctx);
480
+ const detail = terminalFailureDetail(lastMsg);
481
+ ctx.ui.notify(
482
+ `Manual /gsd discuss ${guidedUnit.unitType} ended with a provider error on ${model}: ${detail}`,
483
+ "warning",
484
+ );
485
+
486
+ try {
487
+ writeManualGuidedTerminalErrorActivity(
488
+ guidedUnit.basePath,
489
+ guidedUnit.unitType,
490
+ model,
491
+ detail,
492
+ isObjectRecord(lastMsg) ? lastMsg.stopReason : "unknown",
493
+ );
494
+ } catch (err) {
495
+ const message = err instanceof Error ? err.message : String(err);
496
+ logWarning("bootstrap", `Failed to write manual guided terminal-error activity marker: ${message}`);
497
+ }
498
+ }
499
+
391
500
  async function pauseTransientWithBackoff(
392
501
  cls: ErrorClass,
393
502
  pi: ExtensionAPI,
@@ -437,7 +546,9 @@ export async function handleAgentEnd(
437
546
  // rejected" loop even though the files are on disk.
438
547
  clearPathCache();
439
548
  const basePath = resolveAgentEndBasePath();
440
- clearGuidedUnitContext(basePath);
549
+ const lastMsg = event.messages[event.messages.length - 1];
550
+ const guidedUnit = basePath ? getGuidedUnitContext(basePath) ?? getGuidedUnitContext() : getGuidedUnitContext();
551
+ clearGuidedUnitContext(guidedUnit?.basePath ?? basePath);
441
552
 
442
553
  try {
443
554
  if (await checkDeepProjectSetupAfterTurn(event, ctx, basePath)) {
@@ -466,13 +577,15 @@ export async function handleAgentEnd(
466
577
  // discussions (where isAutoActive may be false) still get recovered.
467
578
  if (maybeHandleEmptyIntentTurn(event, isAutoActive(), basePath)) return;
468
579
 
469
- if (!isAutoActive()) return;
580
+ if (!isAutoActive()) {
581
+ observeManualDiscussTerminalError(ctx, lastMsg, guidedUnit);
582
+ return;
583
+ }
470
584
 
471
585
  if (shouldIgnoreAgentEndForActiveUnit(event)) {
472
586
  return;
473
587
  }
474
588
 
475
- const lastMsg = event.messages[event.messages.length - 1];
476
589
  if (isSessionSwitchInFlight()) {
477
590
  _handleSessionSwitchAgentEnd(lastMsg, resolveAgentEndCancelled);
478
591
  return;
@@ -555,9 +668,9 @@ export async function handleAgentEnd(
555
668
  });
556
669
  return;
557
670
  }
558
- // #3588: When errorMessage is uninformative, extract the real error from
559
- // the assistant message text content for display purposes only.
560
- // Classification still uses rawErrorMsg to avoid false positives from prose.
671
+ // #3588/#956: When errorMessage is uninformative, extract the real error
672
+ // from assistant text. Prefer rawErrorMsg for classification to avoid
673
+ // prose false-positives, but use display text when rawErrorMsg is empty.
561
674
  const displayMsg = resolveAgentEndErrorDisplay(
562
675
  rawErrorMsg,
563
676
  "content" in lastMsg ? lastMsg.content : undefined,
@@ -576,8 +689,8 @@ export async function handleAgentEnd(
576
689
  const errorDetail = displayMsg ? `: ${displayMsg}` : "";
577
690
  const explicitRetryAfterMs = ("retryAfterMs" in lastMsg && typeof lastMsg.retryAfterMs === "number") ? lastMsg.retryAfterMs : undefined;
578
691
 
579
- // ── 1. Classify using rawErrorMsg to avoid prose false-positives ────
580
- const cls = classifyError(rawErrorMsg, explicitRetryAfterMs);
692
+ // ── 1. Classify, preserving non-empty errorMessage precedence ──────
693
+ const cls = classifyError(rawErrorMsg || displayMsg, explicitRetryAfterMs);
581
694
 
582
695
  // ── 1a. Unsupported-model: provider rejected this model for the current
583
696
  // account/plan at request time (#4513). Persist a block so the
@@ -655,7 +768,7 @@ export async function handleAgentEnd(
655
768
  // Core retries transient failures in-session after this handler.
656
769
  // Keep that behavior for non-rate-limit classes to avoid pause/retry races,
657
770
  // but let rate-limit continue into model fallback logic below (#4373).
658
- if (shouldDeferTransientErrorToCoreRetry(cls, rawErrorMsg)) {
771
+ if (shouldDeferTransientErrorToCoreRetry(cls, rawErrorMsg, rawErrorMsg || displayMsg)) {
659
772
  return;
660
773
  }
661
774
 
@@ -0,0 +1,44 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Canonical core session tool surface shared by auto-mode scoping and loop guards.
3
+
4
+ /** Base tools available during auto-mode execution before unit-specific GSD tools are added. */
5
+ export const MINIMAL_AUTO_BASE_TOOL_NAMES = [
6
+ "ask_user_questions",
7
+ "bash",
8
+ "bg_shell",
9
+ "edit",
10
+ "find",
11
+ "glob",
12
+ "grep",
13
+ "fetch_page",
14
+ "search-the-web",
15
+ "ls",
16
+ "read",
17
+ "subagent",
18
+ "write",
19
+ "ToolSearch",
20
+ ] as const;
21
+
22
+ /** Tools excluded from the high per-turn loop-guard cap (strict or orchestration). */
23
+ const NON_REPEATABLE_FROM_MINIMAL_BASE = new Set<string>([
24
+ "ask_user_questions",
25
+ "subagent",
26
+ "ToolSearch",
27
+ ]);
28
+
29
+ /** Additional core tools not in MINIMAL_AUTO_BASE but routinely multi-called per turn. */
30
+ const EXTRA_INHERENTLY_REPEATABLE = [
31
+ "gsd_exec",
32
+ "multi_edit",
33
+ "todo_write",
34
+ "notebook_edit",
35
+ "search_and_read",
36
+ ] as const;
37
+
38
+ /** Core session tools that may be invoked many times per agent turn. */
39
+ export const INHERENTLY_REPEATABLE_TOOL_NAMES = [
40
+ ...MINIMAL_AUTO_BASE_TOOL_NAMES.filter((name) => !NON_REPEATABLE_FROM_MINIMAL_BASE.has(name)),
41
+ ...EXTRA_INHERENTLY_REPEATABLE,
42
+ ] as const;
43
+
44
+ export const INHERENTLY_REPEATABLE_TOOL_SET = new Set<string>(INHERENTLY_REPEATABLE_TOOL_NAMES);
@@ -3,6 +3,7 @@
3
3
  import { Type, StringEnum } from "@gsd/pi-ai";
4
4
  import type { ExtensionAPI } from "@gsd/pi-coding-agent";
5
5
  import { Text } from "@gsd/pi-tui";
6
+ import { SUMMARY_SAVE_CONTENT_MAX_LENGTH } from "@opengsd/contracts";
6
7
 
7
8
  import { loadEffectiveGSDPreferences } from "../preferences.js";
8
9
  import { ensureDbOpen, resolveCtxCwd, resolveWorkflowToolBasePath } from "./dynamic-tools.js";
@@ -392,13 +393,17 @@ export function registerDbTools(pi: ExtensionAPI): void {
392
393
  "Root-level artifact paths are PROJECT.md, PROJECT-DRAFT.md, REQUIREMENTS.md, and REQUIREMENTS-DRAFT.md.",
393
394
  "artifact_type must be one of: SUMMARY, RESEARCH, CONTEXT, ASSESSMENT, CONTEXT-DRAFT, PROJECT, PROJECT-DRAFT, REQUIREMENTS, REQUIREMENTS-DRAFT.",
394
395
  "Use CONTEXT-DRAFT for incremental draft persistence; use CONTEXT for the final milestone context after depth verification.",
396
+ `Keep each content payload under ${SUMMARY_SAVE_CONTENT_MAX_LENGTH} characters; save large context incrementally with CONTEXT-DRAFT/PROJECT-DRAFT/REQUIREMENTS-DRAFT instead of one oversized call.`,
395
397
  ],
396
398
  parameters: Type.Object({
397
399
  milestone_id: Type.Optional(Type.String({ description: "Milestone ID (e.g. M001). Omit only for root-level PROJECT/PROJECT-DRAFT/REQUIREMENTS/REQUIREMENTS-DRAFT artifacts." })),
398
400
  slice_id: Type.Optional(Type.String({ description: "Slice ID (e.g. S01)" })),
399
401
  task_id: Type.Optional(Type.String({ description: "Task ID (e.g. T01)" })),
400
402
  artifact_type: StringEnum(["SUMMARY", "RESEARCH", "CONTEXT", "ASSESSMENT", "CONTEXT-DRAFT", "PROJECT", "PROJECT-DRAFT", "REQUIREMENTS", "REQUIREMENTS-DRAFT"], { description: "Artifact type to save" }),
401
- content: Type.String({ description: "The full markdown content of the artifact" }),
403
+ content: Type.String({
404
+ description: `The full markdown content of the artifact. Maximum ${SUMMARY_SAVE_CONTENT_MAX_LENGTH} characters per save.`,
405
+ maxLength: SUMMARY_SAVE_CONTENT_MAX_LENGTH,
406
+ }),
402
407
  }),
403
408
  execute: summarySaveExecute,
404
409
  renderCall(args: any, theme: any) {
@@ -685,8 +690,9 @@ export function registerDbTools(pi: ExtensionAPI): void {
685
690
  promptSnippet: "Plan a slice via DB write + PLAN render + cache invalidation",
686
691
  promptGuidelines: [
687
692
  "Use gsd_plan_slice for slice planning instead of writing S##-PLAN.md or task PLAN files directly.",
688
- "Keep parameters flat and provide the full slice planning payload, including tasks.",
689
- "The tool validates input, requires an existing parent slice, writes slice/task planning data, renders PLAN.md and task plan files from DB, and clears both state and parse caches after success.",
693
+ "For incremental planning, call gsd_plan_slice with slice metadata only, then call gsd_plan_task once per task.",
694
+ "When tasks is omitted or empty, the tool writes only slice planning metadata and preserves existing tasks.",
695
+ "When tasks is non-empty, the tool validates input, requires an existing parent slice, writes slice/task planning data, renders PLAN.md and task plan files from DB, and clears both state and parse caches after success.",
690
696
  "Use the canonical name gsd_plan_slice; gsd_slice_plan is only an alias.",
691
697
  ],
692
698
  parameters: Type.Object({
@@ -694,7 +700,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
694
700
  milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
695
701
  sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
696
702
  goal: Type.String({ description: "Slice goal" }),
697
- tasks: Type.Array(Type.Object({
703
+ tasks: Type.Optional(Type.Array(Type.Object({
698
704
  taskId: Type.String({ description: "Task ID (e.g. T01)" }),
699
705
  title: Type.String({ description: "Task title" }),
700
706
  description: Type.String({ description: "Task description / steps block" }),
@@ -704,7 +710,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
704
710
  inputs: Type.Array(Type.String(), { description: "Array<string> of input files or references; pass [\"path\"] or [], never a single string" }),
705
711
  expectedOutput: Type.Array(Type.String(), { description: "Array<string> of files this task creates or overwrites; pass [\"path\"] or [], never prose or a single string" }),
706
712
  observabilityImpact: Type.Optional(Type.String({ description: "Task observability impact" })),
707
- }), { description: "Planned tasks for the slice" }),
713
+ }), { description: "Optional full task replacement for the slice. Omit for incremental planning, then call gsd_plan_task once per task." })),
708
714
  // ── Enrichment metadata (optional — defaults to empty) ────────────
709
715
  successCriteria: Type.Optional(Type.String({ description: "Slice success criteria block" })),
710
716
  proofLevel: Type.Optional(Type.String({ description: "Slice proof level" })),
@@ -72,6 +72,7 @@ export function registerExecTools(pi: ExtensionAPI): void {
72
72
  return executeUatExec(params as Parameters<typeof executeUatExec>[0], {
73
73
  baseDir,
74
74
  preferences: await loadContextModePreferences(baseDir),
75
+ signal: _signal,
75
76
  });
76
77
  },
77
78
  });
@@ -119,6 +120,7 @@ export function registerExecTools(pi: ExtensionAPI): void {
119
120
  return executeGsdExec(params as Parameters<typeof executeGsdExec>[0], {
120
121
  baseDir,
121
122
  preferences: await loadContextModePreferences(baseDir),
123
+ signal: _signal,
122
124
  });
123
125
  },
124
126
  });
@@ -18,6 +18,7 @@ import { registerShortcuts } from "./register-shortcuts.js";
18
18
  import { writeCrashLog } from "./crash-log.js";
19
19
  import { logWarning, isGsdExtensionStderrEnabled } from "../workflow-logger.js";
20
20
  import { UNIT_TOOL_CONTRACTS } from "../unit-tool-contracts.js";
21
+ import { installManifestFlushOnProcessTeardown } from "../workflow-manifest.js";
21
22
  // Static import so cmux event listeners are registered synchronously during
22
23
  // extension bootstrap. Prior implementation used `void import().then()` which
23
24
  // queued listener registration as a microtask — any CMUX_CHANNELS emit fired
@@ -196,6 +197,7 @@ export function registerGsdExtension(pi: ExtensionAPI): void {
196
197
  });
197
198
 
198
199
  installEpipeGuard();
200
+ installManifestFlushOnProcessTeardown();
199
201
 
200
202
  // Ecosystem handlers captured by the GSDExtensionAPI wrapper for the
201
203
  // GSD-owned `before_agent_start` dispatch step (#3338).
@@ -13,7 +13,7 @@ import type { GSDEcosystemBeforeAgentStartHandler } from "../ecosystem/gsd-exten
13
13
  import { updateSnapshot } from "../ecosystem/gsd-extension-api.js";
14
14
 
15
15
  import { buildMilestoneFileName, canonicalPhaseDirName, clearPathCache, milestonesDir, legacyMilestonesDir, resolveMilestonePath, resolveSliceFile, resolveSlicePath } from "../paths.js";
16
- import { applyAskUserQuestionsGateResult, clearDiscussionFlowState, formatPendingAskUserQuestionsGateMessage, formatTimedOutAskUserQuestionsGateMessage, hostWriteGateAdapter, isApprovalGateVerifiedInSnapshot, isDepthConfirmationAnswer, isMilestoneDepthVerified, isMilestoneDepthVerifiedInSnapshot, isQueuePhaseActive, resetWriteGateState, shouldBlockContextWrite, shouldBlockPlanningUnit, shouldBlockQueueExecution, shouldBlockWorktreeBash, shouldBlockWorktreeWrite, isGateQuestionId, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
16
+ import { applyAskUserQuestionsGateResult, clearDiscussionFlowState, currentWriteGateSnapshot, formatPendingAskUserQuestionsGateMessage, formatTimedOutAskUserQuestionsGateMessage, hostWriteGateAdapter, isApprovalGateVerifiedInSnapshot, isDepthConfirmationAnswer, isMilestoneDepthVerifiedInSnapshot, isQueuePhaseActive, resetWriteGateState, shouldBlockContextWrite, shouldBlockPlanningUnit, shouldBlockQueueExecution, shouldBlockWorktreeBash, shouldBlockWorktreeWrite, isGateQuestionId, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId, type WriteGateSnapshot } from "./write-gate.js";
17
17
  import { canonicalToolName } from "../engine-hook-contract.js";
18
18
  import { resolveManifest } from "../unit-context-manifest.js";
19
19
  import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
@@ -34,7 +34,8 @@ import {
34
34
  } from "../auto-runtime-state.js";
35
35
  import { applyProviderPayloadPolicy } from "../provider-payload-policy.js";
36
36
 
37
- import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
37
+ import { checkToolCallLoop, recordToolCallLoopMutation, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
38
+ import { MINIMAL_AUTO_BASE_TOOL_NAMES } from "./core-session-tools.js";
38
39
  import { maybePauseAutoForApprovalGate, resetPendingGatePauseGuard } from "./pending-gate-pause.js";
39
40
  import { saveActivityLog } from "../activity-log.js";
40
41
  import { recordToolCall as safetyRecordToolCall, recordToolResult as safetyRecordToolResult, saveEvidenceToDisk } from "../safety/evidence-collector.js";
@@ -75,6 +76,7 @@ import { supportsSourceObservationsForUnit } from "../source-observations.js";
75
76
  import { clearPendingAutoStart } from "../pending-auto-start.js";
76
77
  import { resolveWorkflowToolBasePath } from "./dynamic-tools.js";
77
78
  import { getRequiredWorkflowToolsForUnit } from "../unit-tool-contracts.js";
79
+ import { flushAllManifests } from "../workflow-manifest.js";
78
80
 
79
81
  let approvalQuestionAbortInFlight = false;
80
82
 
@@ -178,22 +180,7 @@ export const MINIMAL_GSD_TOOL_NAMES = [
178
180
  "gsd_capture_thought",
179
181
  ] as const;
180
182
 
181
- export const MINIMAL_AUTO_BASE_TOOL_NAMES = [
182
- "ask_user_questions",
183
- "bash",
184
- "bg_shell",
185
- "edit",
186
- "find",
187
- "glob",
188
- "grep",
189
- "fetch_page",
190
- "search-the-web",
191
- "ls",
192
- "read",
193
- "subagent",
194
- "write",
195
- "ToolSearch",
196
- ] as const;
183
+ export { MINIMAL_AUTO_BASE_TOOL_NAMES } from "./core-session-tools.js";
197
184
 
198
185
  function withPreservedShimTools(toolNames: readonly string[]): string[] {
199
186
  return [...new Set([...toolNames, ...ALWAYS_PRESERVED_SHIM_TOOL_NAMES])];
@@ -583,6 +570,10 @@ function deferApprovalGate(gateId: string, basePath: string): void {
583
570
  // workflow MCP child already verified this gate, deferring would block
584
571
  // tools for a gate that can never legitimately arm.
585
572
  const snapshot = hostWriteGateAdapter.readState(basePath);
573
+ deferApprovalGateFromSnapshot(gateId, basePath, snapshot);
574
+ }
575
+
576
+ function deferApprovalGateFromSnapshot(gateId: string, basePath: string, snapshot: WriteGateSnapshot): void {
586
577
  if (isApprovalGateVerifiedInSnapshot(snapshot, gateId)) return;
587
578
  const milestoneId = extractDepthVerificationMilestoneId(gateId);
588
579
  if (milestoneId && isMilestoneDepthVerifiedInSnapshot(snapshot, milestoneId)) return;
@@ -593,6 +584,21 @@ function contextBasePath(ctx?: { cwd?: string }): string {
593
584
  return typeof ctx?.cwd === "string" ? ctx.cwd : process.cwd();
594
585
  }
595
586
 
587
+ const LOOP_GUARD_INTERACTIVE_INSTRUCTIONS = [
588
+ "Do not retry this tool or call other tools this turn — stop and respond to the user in text.",
589
+ "Do not retry this tool or pivot to other tools this turn — stop and respond to the user in text.",
590
+ ];
591
+ const LOOP_GUARD_AUTO_INSTRUCTION =
592
+ "Do not re-issue this blocked tool. In /gsd auto, stop tool calls for this turn and return control to the auto-mode recovery/replan path.";
593
+
594
+ function formatLoopGuardBlockReason(reason: string | undefined): string | undefined {
595
+ if (!reason || !getAutoRuntimeSnapshot().active) return reason;
596
+ return LOOP_GUARD_INTERACTIVE_INSTRUCTIONS.reduce(
597
+ (formatted, instruction) => formatted.replace(instruction, LOOP_GUARD_AUTO_INSTRUCTION),
598
+ reason,
599
+ );
600
+ }
601
+
596
602
  function beginSourceObservationStoreForCurrentUnit(
597
603
  ctx?: { cwd?: string },
598
604
  ): ReturnType<typeof getSourceObservationStore> | null {
@@ -916,6 +922,15 @@ export function registerHooks(
916
922
  }
917
923
  }
918
924
  }
925
+ const projectRoot = resolveWorktreeProjectRoot(basePath);
926
+ const { pruneStaleFlatPhaseBackups } = await import("../flat-phase-migration.js");
927
+ const pruned = pruneStaleFlatPhaseBackups(projectRoot);
928
+ if (pruned > 0) {
929
+ safetyLogWarning(
930
+ "bootstrap",
931
+ `pruned ${pruned} stale flat-phase migration backup(s) from .gsd-backups/ (retention exceeded)`,
932
+ );
933
+ }
919
934
  } catch (err) {
920
935
  safetyLogWarning("bootstrap", `flat-phase migration: ${err instanceof Error ? err.message : String(err)}`);
921
936
  }
@@ -1081,6 +1096,19 @@ export function registerHooks(
1081
1096
  const { handleAgentEnd } = await import("./agent-end-recovery.js");
1082
1097
  const agentEndBasePath = contextBasePath(ctx);
1083
1098
  try {
1099
+ // The manifest is a non-critical projection (the append-only event log is
1100
+ // the authoritative recovery source), so a flush failure must not skip
1101
+ // agent_end recovery. drainManifestWrites still propagates write failures
1102
+ // to explicit flush callers; here we deliberately log and continue so
1103
+ // handleAgentEnd (and the finally below) always run.
1104
+ try {
1105
+ await flushAllManifests();
1106
+ } catch (err) {
1107
+ safetyLogWarning(
1108
+ "manifest",
1109
+ `flushAllManifests on agent_end failed: ${err instanceof Error ? err.message : String(err)}`,
1110
+ );
1111
+ }
1084
1112
  await handleAgentEnd(pi, event, ctx);
1085
1113
  } finally {
1086
1114
  activateDeferredApprovalGate(agentEndBasePath);
@@ -1233,13 +1261,15 @@ export function registerHooks(
1233
1261
 
1234
1262
  const gateId = approvalGateIdForUnit(unitType, unitId);
1235
1263
  if (gateId) {
1264
+ const basePath = contextBasePath(ctx);
1265
+ const gateSnapshot = currentWriteGateSnapshot(basePath);
1236
1266
  // Skip the gate if this milestone is already depth-verified — the approval
1237
1267
  // pattern matched again on post-verification text (a false-positive re-trigger).
1238
1268
  // Without this guard, the second firing blocks gsd_plan_milestone in the same
1239
1269
  // turn and leaves CONTEXT.md on disk with no DB row (#discuss-milestone-no-db).
1240
1270
  const gateMilestoneId = extractDepthVerificationMilestoneId(gateId);
1241
- if (gateMilestoneId && isMilestoneDepthVerified(gateMilestoneId, contextBasePath(ctx))) return;
1242
- deferApprovalGate(gateId, contextBasePath(ctx));
1271
+ if (gateMilestoneId && isMilestoneDepthVerifiedInSnapshot(gateSnapshot, gateMilestoneId)) return;
1272
+ deferApprovalGateFromSnapshot(gateId, basePath, gateSnapshot);
1243
1273
  }
1244
1274
 
1245
1275
  approvalQuestionAbortInFlight = true;
@@ -1285,7 +1315,7 @@ export function registerHooks(
1285
1315
  // ── Loop guard: block repeated identical tool calls ──
1286
1316
  const loopCheck = checkToolCallLoop(toolName, event.input as Record<string, unknown>);
1287
1317
  if (loopCheck.block) {
1288
- return { block: true, reason: loopCheck.reason };
1318
+ return { block: true, reason: formatLoopGuardBlockReason(loopCheck.reason) };
1289
1319
  }
1290
1320
 
1291
1321
  const deferredGateGuard = shouldBlockDeferredApprovalTool(
@@ -1557,6 +1587,7 @@ export function registerHooks(
1557
1587
  }
1558
1588
  }
1559
1589
  if (!event.isError) {
1590
+ recordToolCallLoopMutation(toolName);
1560
1591
  refreshSourceObservationAfterMutation(toolName, event.input, ctx);
1561
1592
  clearSourceObservationsAfterShell(toolName);
1562
1593
  }