@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
@@ -27,7 +27,7 @@ import { writeLock, clearLock, clearStaleWorkerLock, readCrashLock, isLockProces
27
27
  import { acquireSessionLock, getSessionLockStatus, releaseSessionLock, updateSessionLock, } from "./session-lock.js";
28
28
  import { resolveAutoSupervisorConfig, loadEffectiveGSDPreferences, loadEffectiveGSDPreferencesWithRegistry, resolveProfileAnchorProvider, getIsolationMode, resolveEffectiveUnitIsolationMode, } from "./preferences.js";
29
29
  import { playNotificationBell, sendDesktopNotification } from "./notifications.js";
30
- import { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, resolveCompactionThresholdPercent, shouldRerootStepSessionForContext, } from "./auto-budget.js";
30
+ import { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, HARD_CONTEXT_REROOT_THRESHOLD_PERCENT, resolveCompactionThresholdPercent, shouldRerootStepSessionForContext, shouldWarnStepSessionForContext, } from "./auto-budget.js";
31
31
  import { markToolStart as _markToolStart, markToolEnd as _markToolEnd, getOldestInFlightToolAgeMs as _getOldestInFlightToolAgeMs, clearInFlightTools, isToolInvocationError, isQueuedUserMessageSkip, isDeterministicPolicyError, } from "./auto-tool-tracking.js";
32
32
  import { closeoutUnit } from "./auto-unit-closeout.js";
33
33
  import { selectAndApplyModel, resolveModelId, clearToolBaseline } from "./auto-model-selection.js";
@@ -369,7 +369,7 @@ function getEffectiveUnitIsolationMode(basePath) {
369
369
  * running suspiciously long (e.g., a Bash command hung because `&` kept stdout open).
370
370
  */
371
371
  // Re-export budget utilities for external consumers
372
- export { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, getContextPauseAction, resolveCompactionThresholdPercent, shouldRerootStepSessionForContext, } from "./auto-budget.js";
372
+ export { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, getContextPauseAction, resolveCompactionThresholdPercent, shouldRerootStepSessionForContext, shouldWarnStepSessionForContext, } from "./auto-budget.js";
373
373
  function closeOutSignalInterruptedUnit(currentBasePath) {
374
374
  const currentUnit = s.currentUnit;
375
375
  if (!currentUnit)
@@ -904,9 +904,10 @@ export async function rerootCommandSession(cmdCtx, workspaceRoot) {
904
904
  }
905
905
  }
906
906
  /**
907
- * After a completed step-mode unit, reclaim context headroom when usage is at
908
- * or above the compaction threshold. Writes a context-mode snapshot first, then
909
- * re-roots the visible command session while leaving the NEXT progress surface.
907
+ * After a completed step-mode unit, warn when usage reaches the configurable
908
+ * soft context threshold. At the fixed hard boundary, write a context-mode
909
+ * snapshot and re-root the visible command session while leaving the NEXT
910
+ * progress surface.
910
911
  */
911
912
  export async function maybeRerootStepSessionForHighContext(ctx, workspaceRoot, cmdCtx, originalBasePath) {
912
913
  if (!cmdCtx)
@@ -915,18 +916,24 @@ export async function maybeRerootStepSessionForHighContext(ctx, workspaceRoot, c
915
916
  const { loadEffectiveGSDPreferences } = await import("./preferences.js");
916
917
  const prefs = loadEffectiveGSDPreferences(workspaceRoot);
917
918
  const compactionThreshold = prefs?.preferences.context_management?.compaction_threshold_percent;
918
- if (!shouldRerootStepSessionForContext(contextPercent, compactionThreshold)) {
919
+ const shouldWarn = shouldWarnStepSessionForContext(contextPercent, compactionThreshold);
920
+ const shouldReroot = shouldRerootStepSessionForContext(contextPercent);
921
+ if (!shouldWarn && !shouldReroot) {
922
+ return { rerooted: false };
923
+ }
924
+ const displayPercent = contextPercent.toFixed(1);
925
+ const thresholdDisplay = resolveCompactionThresholdPercent(compactionThreshold).toFixed(0);
926
+ if (!shouldReroot) {
927
+ ctx.ui.notify(`Step complete — context at ${displayPercent}% (soft threshold: ${thresholdDisplay}%). Use /compact when convenient; continuing in this session is still safe.`, "info");
919
928
  return { rerooted: false };
920
929
  }
921
930
  const { resolveWorktreeProjectRoot } = await import("./worktree-root.js");
922
931
  const snapshotBase = resolveWorktreeProjectRoot(workspaceRoot, originalBasePath);
923
932
  const { writeContextModeCompactionSnapshot } = await import("./context-mode-snapshot.js");
924
933
  await writeContextModeCompactionSnapshot(snapshotBase);
925
- const displayPercent = contextPercent.toFixed(1);
926
- const thresholdDisplay = resolveCompactionThresholdPercent(compactionThreshold).toFixed(0);
927
934
  const result = await rerootCommandSession(cmdCtx, workspaceRoot);
928
935
  if (result.status === "ok") {
929
- ctx.ui.notify(`Step complete — context at ${displayPercent}% (threshold: ${thresholdDisplay}%). Fresh session ready for /gsd next.`, "info");
936
+ ctx.ui.notify(`Step complete — context at ${displayPercent}% (hard threshold: ${HARD_CONTEXT_REROOT_THRESHOLD_PERCENT}%). Fresh session ready for /gsd next.`, "info");
930
937
  return { rerooted: true };
931
938
  }
932
939
  if (result.status === "cancelled") {
@@ -1545,7 +1552,7 @@ export function _selectStopAutoWorktreeExit(args) {
1545
1552
  /**
1546
1553
  * Pause auto-mode without destroying state. Context is preserved.
1547
1554
  * The user can interact with the agent, then `/gsd auto` resumes
1548
- * from disk state. Called when the user presses Escape during auto-mode.
1555
+ * from disk state. Called when the user presses Escape or runs `/gsd pause`.
1549
1556
  */
1550
1557
  export async function pauseAuto(ctx, _pi, _errorContext, options = {}) {
1551
1558
  if (!s.active)
@@ -1564,6 +1571,8 @@ export async function pauseAuto(ctx, _pi, _errorContext, options = {}) {
1564
1571
  ].filter((path) => Boolean(path)));
1565
1572
  s.active = false;
1566
1573
  s.paused = true;
1574
+ if (options.abortActiveTurn && ctx && !ctx.isIdle())
1575
+ ctx.abort();
1567
1576
  clearUnitTimeout();
1568
1577
  stopAutoCommandPolling();
1569
1578
  // Flush queued follow-up messages (#3512).
@@ -1,7 +1,9 @@
1
1
  // gsd-pi + src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts - Handles provider and agent-end recovery for GSD auto-mode.
2
+ import { mkdirSync, readdirSync, writeFileSync } from "node:fs";
3
+ import { join } from "node:path";
2
4
  import { logWarning } from "../workflow-logger.js";
3
5
  import { checkDeepProjectSetupAfterTurn, checkAutoStartAfterDiscuss, maybeHandleReadyPhraseWithoutFiles, maybeHandleEmptyIntentTurn, resetEmptyTurnCounter, } from "../guided-flow.js";
4
- import { clearPathCache } from "../paths.js";
6
+ import { clearPathCache, gsdRoot } from "../paths.js";
5
7
  import { getAutoDashboardData, getAutoModeStartModel, isAutoActive, isAutoCompletionStopInProgress, pauseAuto, setCurrentDispatchedModelId, setCurrentUnitModelForRecovery, } from "../auto.js";
6
8
  import { getNextFallbackModel, resolveModelWithFallbacksForUnit } from "../preferences.js";
7
9
  import { pauseAutoForProviderError } from "../provider-error-pause.js";
@@ -11,7 +13,7 @@ import { resolveModelId } from "../auto-model-selection.js";
11
13
  import { resolveProjectRoot } from "../worktree.js";
12
14
  import { clearDiscussionFlowState } from "./write-gate.js";
13
15
  import { scheduleFallbackContinuation } from "./fallback-continuation.js";
14
- import { clearGuidedUnitContext } from "../guided-unit-context.js";
16
+ import { clearGuidedUnitContext, getGuidedUnitContext } from "../guided-unit-context.js";
15
17
  import { resumeAutoAfterProviderDelay } from "./provider-error-resume.js";
16
18
  import { classifyError, createRetryState, resetRetryState, isTransient, } from "../error-classifier.js";
17
19
  import { blockModel, blockModelUntil, isModelBlocked, isModelTemporarilyUnavailable } from "../blocked-models.js";
@@ -78,10 +80,15 @@ export function isUserInitiatedAbortMessage(message) {
78
80
  return false;
79
81
  return /\b(?:claude code process aborted by user|request aborted by user|process aborted by user)\b/i.test(message);
80
82
  }
81
- export function shouldDeferTransientErrorToCoreRetry(cls, rawErrorMsg) {
83
+ export function shouldDeferTransientErrorToCoreRetry(cls, rawErrorMsg, deferCheckMsg = rawErrorMsg) {
82
84
  if (!isTransient(cls) || cls.kind === "rate-limit")
83
85
  return false;
84
- return !/retry failed after \d+ attempts:/i.test(rawErrorMsg);
86
+ // Empty rawErrorMsg means the SDK terminated the session without providing an
87
+ // error string — core is done, not mid-retry. GSD must schedule its own
88
+ // retry rather than silently deferring to a core that has already exited.
89
+ if (!rawErrorMsg)
90
+ return false;
91
+ return !/retry failed after \d+ attempts:/i.test(deferCheckMsg);
85
92
  }
86
93
  /** Try configured fallbacks, then the auto-mode start model. Returns true if switched. */
87
94
  async function tryProviderModelFallback(params) {
@@ -277,6 +284,86 @@ export function suppressTerminalDeletedWorktreeMessageEnd(event) {
277
284
  logWarning("bootstrap", `Suppressing stale deleted-worktree provider error during terminal completion reroot: ${displayMsg || rawErrorMsg}`);
278
285
  return true;
279
286
  }
287
+ function modelLabel(ctx) {
288
+ const provider = ctx.model?.provider;
289
+ const id = ctx.model?.id;
290
+ return provider && id ? `${provider}/${id}` : "unknown model";
291
+ }
292
+ function isFatalManualGuidedTerminalFailure(lastMsg) {
293
+ if (!isObjectRecord(lastMsg) || !("stopReason" in lastMsg))
294
+ return false;
295
+ if (lastMsg.stopReason === "error") {
296
+ const rawErrorMsg = ("errorMessage" in lastMsg && lastMsg.errorMessage) ? String(lastMsg.errorMessage) : "";
297
+ if (isUserInitiatedAbortMessage(rawErrorMsg))
298
+ return false;
299
+ return true;
300
+ }
301
+ if (lastMsg.stopReason !== "aborted")
302
+ return false;
303
+ const content = "content" in lastMsg ? lastMsg.content : undefined;
304
+ const hasErrorMessage = "errorMessage" in lastMsg && !!lastMsg.errorMessage;
305
+ return hasErrorMessage || !_hasEmptyAgentEndContent(content);
306
+ }
307
+ function terminalFailureDetail(lastMsg) {
308
+ if (!isObjectRecord(lastMsg))
309
+ return "Provider turn ended with an unknown terminal error.";
310
+ const rawErrorMsg = ("errorMessage" in lastMsg && lastMsg.errorMessage) ? String(lastMsg.errorMessage) : "";
311
+ const content = "content" in lastMsg ? lastMsg.content : undefined;
312
+ const displayMsg = resolveAgentEndErrorDisplay(rawErrorMsg, content).replace(/\s+/g, " ").trim();
313
+ if (displayMsg)
314
+ return displayMsg.length > 300 ? `${displayMsg.slice(0, 300)}...` : displayMsg;
315
+ return lastMsg.stopReason === "aborted"
316
+ ? "Provider turn aborted with error context."
317
+ : "Provider stream ended with stopReason=error.";
318
+ }
319
+ function nextManualActivitySequence(activityDir) {
320
+ let maxSeq = 0;
321
+ try {
322
+ for (const file of readdirSync(activityDir)) {
323
+ const match = /^(\d+)-/.exec(file);
324
+ if (match)
325
+ maxSeq = Math.max(maxSeq, Number.parseInt(match[1], 10));
326
+ }
327
+ }
328
+ catch {
329
+ return "001";
330
+ }
331
+ return String(maxSeq + 1).padStart(3, "0");
332
+ }
333
+ function writeManualGuidedTerminalErrorActivity(basePath, unitType, model, detail, stopReason) {
334
+ const activityDir = join(gsdRoot(basePath), "activity");
335
+ mkdirSync(activityDir, { recursive: true });
336
+ const seq = nextManualActivitySequence(activityDir);
337
+ const safeUnitType = unitType.replace(/[^a-z0-9_.-]+/gi, "-");
338
+ const markerPath = join(activityDir, `${seq}-${safeUnitType}-manual-terminal-provider-error.jsonl`);
339
+ const message = `Manual guided ${unitType} turn ended with provider ${String(stopReason)} on ${model}: ${detail}`;
340
+ writeFileSync(markerPath, JSON.stringify({
341
+ type: "message",
342
+ message: {
343
+ role: "toolResult",
344
+ toolCallId: "manual-guided-terminal-provider-error",
345
+ toolName: "provider",
346
+ isError: true,
347
+ content: [{ type: "text", text: message }],
348
+ },
349
+ }) + "\n", "utf-8");
350
+ }
351
+ function observeManualDiscussTerminalError(ctx, lastMsg, guidedUnit) {
352
+ if (!guidedUnit?.unitType.startsWith("discuss-"))
353
+ return;
354
+ if (!isFatalManualGuidedTerminalFailure(lastMsg))
355
+ return;
356
+ const model = modelLabel(ctx);
357
+ const detail = terminalFailureDetail(lastMsg);
358
+ ctx.ui.notify(`Manual /gsd discuss ${guidedUnit.unitType} ended with a provider error on ${model}: ${detail}`, "warning");
359
+ try {
360
+ writeManualGuidedTerminalErrorActivity(guidedUnit.basePath, guidedUnit.unitType, model, detail, isObjectRecord(lastMsg) ? lastMsg.stopReason : "unknown");
361
+ }
362
+ catch (err) {
363
+ const message = err instanceof Error ? err.message : String(err);
364
+ logWarning("bootstrap", `Failed to write manual guided terminal-error activity marker: ${message}`);
365
+ }
366
+ }
280
367
  async function pauseTransientWithBackoff(cls, pi, ctx, errorDetail, isRateLimit) {
281
368
  retryState.consecutiveTransientCount += 1;
282
369
  const baseRetryAfterMs = "retryAfterMs" in cls ? cls.retryAfterMs : 15_000;
@@ -315,7 +402,9 @@ export async function handleAgentEnd(pi, event, ctx) {
315
402
  // rejected" loop even though the files are on disk.
316
403
  clearPathCache();
317
404
  const basePath = resolveAgentEndBasePath();
318
- clearGuidedUnitContext(basePath);
405
+ const lastMsg = event.messages[event.messages.length - 1];
406
+ const guidedUnit = basePath ? getGuidedUnitContext(basePath) ?? getGuidedUnitContext() : getGuidedUnitContext();
407
+ clearGuidedUnitContext(guidedUnit?.basePath ?? basePath);
319
408
  try {
320
409
  if (await checkDeepProjectSetupAfterTurn(event, ctx, basePath)) {
321
410
  return;
@@ -342,12 +431,13 @@ export async function handleAgentEnd(pi, event, ctx) {
342
431
  // discussions (where isAutoActive may be false) still get recovered.
343
432
  if (maybeHandleEmptyIntentTurn(event, isAutoActive(), basePath))
344
433
  return;
345
- if (!isAutoActive())
434
+ if (!isAutoActive()) {
435
+ observeManualDiscussTerminalError(ctx, lastMsg, guidedUnit);
346
436
  return;
437
+ }
347
438
  if (shouldIgnoreAgentEndForActiveUnit(event)) {
348
439
  return;
349
440
  }
350
- const lastMsg = event.messages[event.messages.length - 1];
351
441
  if (isSessionSwitchInFlight()) {
352
442
  _handleSessionSwitchAgentEnd(lastMsg, resolveAgentEndCancelled);
353
443
  return;
@@ -435,9 +525,9 @@ export async function handleAgentEnd(pi, event, ctx) {
435
525
  });
436
526
  return;
437
527
  }
438
- // #3588: When errorMessage is uninformative, extract the real error from
439
- // the assistant message text content for display purposes only.
440
- // Classification still uses rawErrorMsg to avoid false positives from prose.
528
+ // #3588/#956: When errorMessage is uninformative, extract the real error
529
+ // from assistant text. Prefer rawErrorMsg for classification to avoid
530
+ // prose false-positives, but use display text when rawErrorMsg is empty.
441
531
  const displayMsg = resolveAgentEndErrorDisplay(rawErrorMsg, "content" in lastMsg ? lastMsg.content : undefined);
442
532
  if (isAutoCompletionStopInProgress() &&
443
533
  isTerminalDeletedWorktreeProviderError(`${rawErrorMsg}\n${displayMsg}`)) {
@@ -447,8 +537,8 @@ export async function handleAgentEnd(pi, event, ctx) {
447
537
  }
448
538
  const errorDetail = displayMsg ? `: ${displayMsg}` : "";
449
539
  const explicitRetryAfterMs = ("retryAfterMs" in lastMsg && typeof lastMsg.retryAfterMs === "number") ? lastMsg.retryAfterMs : undefined;
450
- // ── 1. Classify using rawErrorMsg to avoid prose false-positives ────
451
- const cls = classifyError(rawErrorMsg, explicitRetryAfterMs);
540
+ // ── 1. Classify, preserving non-empty errorMessage precedence ──────
541
+ const cls = classifyError(rawErrorMsg || displayMsg, explicitRetryAfterMs);
452
542
  // ── 1a. Unsupported-model: provider rejected this model for the current
453
543
  // account/plan at request time (#4513). Persist a block so the
454
544
  // same dead model isn't reselected on the next /gsd auto restart,
@@ -517,7 +607,7 @@ export async function handleAgentEnd(pi, event, ctx) {
517
607
  // Core retries transient failures in-session after this handler.
518
608
  // Keep that behavior for non-rate-limit classes to avoid pause/retry races,
519
609
  // but let rate-limit continue into model fallback logic below (#4373).
520
- if (shouldDeferTransientErrorToCoreRetry(cls, rawErrorMsg)) {
610
+ if (shouldDeferTransientErrorToCoreRetry(cls, rawErrorMsg, rawErrorMsg || displayMsg)) {
521
611
  return;
522
612
  }
523
613
  // ── Tool-schema overload: the active model repeatedly emitted tool-call
@@ -0,0 +1,39 @@
1
+ // Project/App: gsd-pi
2
+ // File Purpose: Canonical core session tool surface shared by auto-mode scoping and loop guards.
3
+ /** Base tools available during auto-mode execution before unit-specific GSD tools are added. */
4
+ export const MINIMAL_AUTO_BASE_TOOL_NAMES = [
5
+ "ask_user_questions",
6
+ "bash",
7
+ "bg_shell",
8
+ "edit",
9
+ "find",
10
+ "glob",
11
+ "grep",
12
+ "fetch_page",
13
+ "search-the-web",
14
+ "ls",
15
+ "read",
16
+ "subagent",
17
+ "write",
18
+ "ToolSearch",
19
+ ];
20
+ /** Tools excluded from the high per-turn loop-guard cap (strict or orchestration). */
21
+ const NON_REPEATABLE_FROM_MINIMAL_BASE = new Set([
22
+ "ask_user_questions",
23
+ "subagent",
24
+ "ToolSearch",
25
+ ]);
26
+ /** Additional core tools not in MINIMAL_AUTO_BASE but routinely multi-called per turn. */
27
+ const EXTRA_INHERENTLY_REPEATABLE = [
28
+ "gsd_exec",
29
+ "multi_edit",
30
+ "todo_write",
31
+ "notebook_edit",
32
+ "search_and_read",
33
+ ];
34
+ /** Core session tools that may be invoked many times per agent turn. */
35
+ export const INHERENTLY_REPEATABLE_TOOL_NAMES = [
36
+ ...MINIMAL_AUTO_BASE_TOOL_NAMES.filter((name) => !NON_REPEATABLE_FROM_MINIMAL_BASE.has(name)),
37
+ ...EXTRA_INHERENTLY_REPEATABLE,
38
+ ];
39
+ export const INHERENTLY_REPEATABLE_TOOL_SET = new Set(INHERENTLY_REPEATABLE_TOOL_NAMES);
@@ -2,6 +2,7 @@
2
2
  // File Purpose: Registers DB-backed GSD workflow tools and compatibility aliases.
3
3
  import { Type, StringEnum } from "@gsd/pi-ai";
4
4
  import { Text } from "@gsd/pi-tui";
5
+ import { SUMMARY_SAVE_CONTENT_MAX_LENGTH } from "@opengsd/contracts";
5
6
  import { loadEffectiveGSDPreferences } from "../preferences.js";
6
7
  import { ensureDbOpen, resolveCtxCwd, resolveWorkflowToolBasePath } from "./dynamic-tools.js";
7
8
  import { importWorkflowExecutorsModule } from "../workflow-mcp.js";
@@ -373,13 +374,17 @@ export function registerDbTools(pi) {
373
374
  "Root-level artifact paths are PROJECT.md, PROJECT-DRAFT.md, REQUIREMENTS.md, and REQUIREMENTS-DRAFT.md.",
374
375
  "artifact_type must be one of: SUMMARY, RESEARCH, CONTEXT, ASSESSMENT, CONTEXT-DRAFT, PROJECT, PROJECT-DRAFT, REQUIREMENTS, REQUIREMENTS-DRAFT.",
375
376
  "Use CONTEXT-DRAFT for incremental draft persistence; use CONTEXT for the final milestone context after depth verification.",
377
+ `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.`,
376
378
  ],
377
379
  parameters: Type.Object({
378
380
  milestone_id: Type.Optional(Type.String({ description: "Milestone ID (e.g. M001). Omit only for root-level PROJECT/PROJECT-DRAFT/REQUIREMENTS/REQUIREMENTS-DRAFT artifacts." })),
379
381
  slice_id: Type.Optional(Type.String({ description: "Slice ID (e.g. S01)" })),
380
382
  task_id: Type.Optional(Type.String({ description: "Task ID (e.g. T01)" })),
381
383
  artifact_type: StringEnum(["SUMMARY", "RESEARCH", "CONTEXT", "ASSESSMENT", "CONTEXT-DRAFT", "PROJECT", "PROJECT-DRAFT", "REQUIREMENTS", "REQUIREMENTS-DRAFT"], { description: "Artifact type to save" }),
382
- content: Type.String({ description: "The full markdown content of the artifact" }),
384
+ content: Type.String({
385
+ description: `The full markdown content of the artifact. Maximum ${SUMMARY_SAVE_CONTENT_MAX_LENGTH} characters per save.`,
386
+ maxLength: SUMMARY_SAVE_CONTENT_MAX_LENGTH,
387
+ }),
383
388
  }),
384
389
  execute: summarySaveExecute,
385
390
  renderCall(args, theme) {
@@ -649,8 +654,9 @@ export function registerDbTools(pi) {
649
654
  promptSnippet: "Plan a slice via DB write + PLAN render + cache invalidation",
650
655
  promptGuidelines: [
651
656
  "Use gsd_plan_slice for slice planning instead of writing S##-PLAN.md or task PLAN files directly.",
652
- "Keep parameters flat and provide the full slice planning payload, including tasks.",
653
- "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.",
657
+ "For incremental planning, call gsd_plan_slice with slice metadata only, then call gsd_plan_task once per task.",
658
+ "When tasks is omitted or empty, the tool writes only slice planning metadata and preserves existing tasks.",
659
+ "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.",
654
660
  "Use the canonical name gsd_plan_slice; gsd_slice_plan is only an alias.",
655
661
  ],
656
662
  parameters: Type.Object({
@@ -658,7 +664,7 @@ export function registerDbTools(pi) {
658
664
  milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
659
665
  sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
660
666
  goal: Type.String({ description: "Slice goal" }),
661
- tasks: Type.Array(Type.Object({
667
+ tasks: Type.Optional(Type.Array(Type.Object({
662
668
  taskId: Type.String({ description: "Task ID (e.g. T01)" }),
663
669
  title: Type.String({ description: "Task title" }),
664
670
  description: Type.String({ description: "Task description / steps block" }),
@@ -668,7 +674,7 @@ export function registerDbTools(pi) {
668
674
  inputs: Type.Array(Type.String(), { description: "Array<string> of input files or references; pass [\"path\"] or [], never a single string" }),
669
675
  expectedOutput: Type.Array(Type.String(), { description: "Array<string> of files this task creates or overwrites; pass [\"path\"] or [], never prose or a single string" }),
670
676
  observabilityImpact: Type.Optional(Type.String({ description: "Task observability impact" })),
671
- }), { description: "Planned tasks for the slice" }),
677
+ }), { description: "Optional full task replacement for the slice. Omit for incremental planning, then call gsd_plan_task once per task." })),
672
678
  // ── Enrichment metadata (optional — defaults to empty) ────────────
673
679
  successCriteria: Type.Optional(Type.String({ description: "Slice success criteria block" })),
674
680
  proofLevel: Type.Optional(Type.String({ description: "Slice proof level" })),
@@ -60,6 +60,7 @@ export function registerExecTools(pi) {
60
60
  return executeUatExec(params, {
61
61
  baseDir,
62
62
  preferences: await loadContextModePreferences(baseDir),
63
+ signal: _signal,
63
64
  });
64
65
  },
65
66
  });
@@ -99,6 +100,7 @@ export function registerExecTools(pi) {
99
100
  return executeGsdExec(params, {
100
101
  baseDir,
101
102
  preferences: await loadContextModePreferences(baseDir),
103
+ signal: _signal,
102
104
  });
103
105
  },
104
106
  });
@@ -14,6 +14,7 @@ import { registerShortcuts } from "./register-shortcuts.js";
14
14
  import { writeCrashLog } from "./crash-log.js";
15
15
  import { logWarning, isGsdExtensionStderrEnabled } from "../workflow-logger.js";
16
16
  import { UNIT_TOOL_CONTRACTS } from "../unit-tool-contracts.js";
17
+ import { installManifestFlushOnProcessTeardown } from "../workflow-manifest.js";
17
18
  // Static import so cmux event listeners are registered synchronously during
18
19
  // extension bootstrap. Prior implementation used `void import().then()` which
19
20
  // queued listener registration as a microtask — any CMUX_CHANNELS emit fired
@@ -177,6 +178,7 @@ export function registerGsdExtension(pi) {
177
178
  process.stderr.write(`[gsd] Failed to bootstrap hook-emitter bridge: ${err instanceof Error ? err.stack ?? err.message : String(err)}\n`);
178
179
  });
179
180
  installEpipeGuard();
181
+ installManifestFlushOnProcessTeardown();
180
182
  // Ecosystem handlers captured by the GSDExtensionAPI wrapper for the
181
183
  // GSD-owned `before_agent_start` dispatch step (#3338).
182
184
  const ecosystemHandlers = [];
@@ -7,14 +7,15 @@ import { isToolCallEventType } from "@gsd/pi-coding-agent";
7
7
  import { ALWAYS_PRESERVED_SHIM_TOOL_NAMES } from "@gsd/pi-ai";
8
8
  import { updateSnapshot } from "../ecosystem/gsd-extension-api.js";
9
9
  import { buildMilestoneFileName, canonicalPhaseDirName, clearPathCache, milestonesDir, legacyMilestonesDir, resolveMilestonePath, resolveSliceFile, resolveSlicePath } from "../paths.js";
10
- 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";
10
+ import { applyAskUserQuestionsGateResult, clearDiscussionFlowState, currentWriteGateSnapshot, formatPendingAskUserQuestionsGateMessage, formatTimedOutAskUserQuestionsGateMessage, hostWriteGateAdapter, isApprovalGateVerifiedInSnapshot, isDepthConfirmationAnswer, isMilestoneDepthVerifiedInSnapshot, isQueuePhaseActive, resetWriteGateState, shouldBlockContextWrite, shouldBlockPlanningUnit, shouldBlockQueueExecution, shouldBlockWorktreeBash, shouldBlockWorktreeWrite, isGateQuestionId, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
11
11
  import { canonicalToolName } from "../engine-hook-contract.js";
12
12
  import { resolveManifest } from "../unit-context-manifest.js";
13
13
  import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
14
14
  import { loadFile, saveFile, formatContinue } from "../files.js";
15
15
  import { clearAutoCompletionStopInProgress, clearToolInvocationError, getAutoRuntimeSnapshot, getSourceObservationStore, isAutoActive, isAutoCompletionStopInProgress, isAutoPaused, isInteractiveElicitationInFlight, markToolEnd, markToolStart, recordAutoToolSurfaceSnapshot, recordToolInvocationError, } from "../auto-runtime-state.js";
16
16
  import { applyProviderPayloadPolicy } from "../provider-payload-policy.js";
17
- import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
17
+ import { checkToolCallLoop, recordToolCallLoopMutation, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
18
+ import { MINIMAL_AUTO_BASE_TOOL_NAMES } from "./core-session-tools.js";
18
19
  import { maybePauseAutoForApprovalGate, resetPendingGatePauseGuard } from "./pending-gate-pause.js";
19
20
  import { saveActivityLog } from "../activity-log.js";
20
21
  import { recordToolCall as safetyRecordToolCall, recordToolResult as safetyRecordToolResult, saveEvidenceToDisk } from "../safety/evidence-collector.js";
@@ -42,6 +43,7 @@ import { supportsSourceObservationsForUnit } from "../source-observations.js";
42
43
  import { clearPendingAutoStart } from "../pending-auto-start.js";
43
44
  import { resolveWorkflowToolBasePath } from "./dynamic-tools.js";
44
45
  import { getRequiredWorkflowToolsForUnit } from "../unit-tool-contracts.js";
46
+ import { flushAllManifests } from "../workflow-manifest.js";
45
47
  let approvalQuestionAbortInFlight = false;
46
48
  async function loadWelcomeScreenModule() {
47
49
  const candidates = [];
@@ -138,22 +140,7 @@ export const MINIMAL_GSD_TOOL_NAMES = [
138
140
  "capture_thought",
139
141
  "gsd_capture_thought",
140
142
  ];
141
- export const MINIMAL_AUTO_BASE_TOOL_NAMES = [
142
- "ask_user_questions",
143
- "bash",
144
- "bg_shell",
145
- "edit",
146
- "find",
147
- "glob",
148
- "grep",
149
- "fetch_page",
150
- "search-the-web",
151
- "ls",
152
- "read",
153
- "subagent",
154
- "write",
155
- "ToolSearch",
156
- ];
143
+ export { MINIMAL_AUTO_BASE_TOOL_NAMES } from "./core-session-tools.js";
157
144
  function withPreservedShimTools(toolNames) {
158
145
  return [...new Set([...toolNames, ...ALWAYS_PRESERVED_SHIM_TOOL_NAMES])];
159
146
  }
@@ -436,6 +423,9 @@ function deferApprovalGate(gateId, basePath) {
436
423
  // workflow MCP child already verified this gate, deferring would block
437
424
  // tools for a gate that can never legitimately arm.
438
425
  const snapshot = hostWriteGateAdapter.readState(basePath);
426
+ deferApprovalGateFromSnapshot(gateId, basePath, snapshot);
427
+ }
428
+ function deferApprovalGateFromSnapshot(gateId, basePath, snapshot) {
439
429
  if (isApprovalGateVerifiedInSnapshot(snapshot, gateId))
440
430
  return;
441
431
  const milestoneId = extractDepthVerificationMilestoneId(gateId);
@@ -446,6 +436,16 @@ function deferApprovalGate(gateId, basePath) {
446
436
  function contextBasePath(ctx) {
447
437
  return typeof ctx?.cwd === "string" ? ctx.cwd : process.cwd();
448
438
  }
439
+ const LOOP_GUARD_INTERACTIVE_INSTRUCTIONS = [
440
+ "Do not retry this tool or call other tools this turn — stop and respond to the user in text.",
441
+ "Do not retry this tool or pivot to other tools this turn — stop and respond to the user in text.",
442
+ ];
443
+ const LOOP_GUARD_AUTO_INSTRUCTION = "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.";
444
+ function formatLoopGuardBlockReason(reason) {
445
+ if (!reason || !getAutoRuntimeSnapshot().active)
446
+ return reason;
447
+ return LOOP_GUARD_INTERACTIVE_INSTRUCTIONS.reduce((formatted, instruction) => formatted.replace(instruction, LOOP_GUARD_AUTO_INSTRUCTION), reason);
448
+ }
449
449
  function beginSourceObservationStoreForCurrentUnit(ctx) {
450
450
  if (!isAutoActive())
451
451
  return null;
@@ -714,6 +714,12 @@ export function registerHooks(pi, ecosystemHandlers) {
714
714
  }
715
715
  }
716
716
  }
717
+ const projectRoot = resolveWorktreeProjectRoot(basePath);
718
+ const { pruneStaleFlatPhaseBackups } = await import("../flat-phase-migration.js");
719
+ const pruned = pruneStaleFlatPhaseBackups(projectRoot);
720
+ if (pruned > 0) {
721
+ safetyLogWarning("bootstrap", `pruned ${pruned} stale flat-phase migration backup(s) from .gsd-backups/ (retention exceeded)`);
722
+ }
717
723
  }
718
724
  catch (err) {
719
725
  safetyLogWarning("bootstrap", `flat-phase migration: ${err instanceof Error ? err.message : String(err)}`);
@@ -871,6 +877,17 @@ export function registerHooks(pi, ecosystemHandlers) {
871
877
  const { handleAgentEnd } = await import("./agent-end-recovery.js");
872
878
  const agentEndBasePath = contextBasePath(ctx);
873
879
  try {
880
+ // The manifest is a non-critical projection (the append-only event log is
881
+ // the authoritative recovery source), so a flush failure must not skip
882
+ // agent_end recovery. drainManifestWrites still propagates write failures
883
+ // to explicit flush callers; here we deliberately log and continue so
884
+ // handleAgentEnd (and the finally below) always run.
885
+ try {
886
+ await flushAllManifests();
887
+ }
888
+ catch (err) {
889
+ safetyLogWarning("manifest", `flushAllManifests on agent_end failed: ${err instanceof Error ? err.message : String(err)}`);
890
+ }
874
891
  await handleAgentEnd(pi, event, ctx);
875
892
  }
876
893
  finally {
@@ -1009,14 +1026,16 @@ export function registerHooks(pi, ecosystemHandlers) {
1009
1026
  return;
1010
1027
  const gateId = approvalGateIdForUnit(unitType, unitId);
1011
1028
  if (gateId) {
1029
+ const basePath = contextBasePath(ctx);
1030
+ const gateSnapshot = currentWriteGateSnapshot(basePath);
1012
1031
  // Skip the gate if this milestone is already depth-verified — the approval
1013
1032
  // pattern matched again on post-verification text (a false-positive re-trigger).
1014
1033
  // Without this guard, the second firing blocks gsd_plan_milestone in the same
1015
1034
  // turn and leaves CONTEXT.md on disk with no DB row (#discuss-milestone-no-db).
1016
1035
  const gateMilestoneId = extractDepthVerificationMilestoneId(gateId);
1017
- if (gateMilestoneId && isMilestoneDepthVerified(gateMilestoneId, contextBasePath(ctx)))
1036
+ if (gateMilestoneId && isMilestoneDepthVerifiedInSnapshot(gateSnapshot, gateMilestoneId))
1018
1037
  return;
1019
- deferApprovalGate(gateId, contextBasePath(ctx));
1038
+ deferApprovalGateFromSnapshot(gateId, basePath, gateSnapshot);
1020
1039
  }
1021
1040
  approvalQuestionAbortInFlight = true;
1022
1041
  ctx.ui.notify(`${unitType ?? "The discussion"}${unitId ? ` ${unitId}` : ""} is waiting for your approval - pausing before more tool calls run.`, "info");
@@ -1058,7 +1077,7 @@ export function registerHooks(pi, ecosystemHandlers) {
1058
1077
  // ── Loop guard: block repeated identical tool calls ──
1059
1078
  const loopCheck = checkToolCallLoop(toolName, event.input);
1060
1079
  if (loopCheck.block) {
1061
- return { block: true, reason: loopCheck.reason };
1080
+ return { block: true, reason: formatLoopGuardBlockReason(loopCheck.reason) };
1062
1081
  }
1063
1082
  const deferredGateGuard = shouldBlockDeferredApprovalTool(toolName, event.input, discussionBasePath);
1064
1083
  if (deferredGateGuard.block) {
@@ -1264,6 +1283,7 @@ export function registerHooks(pi, ecosystemHandlers) {
1264
1283
  }
1265
1284
  }
1266
1285
  if (!event.isError) {
1286
+ recordToolCallLoopMutation(toolName);
1267
1287
  refreshSourceObservationAfterMutation(toolName, event.input, ctx);
1268
1288
  clearSourceObservationsAfterShell(toolName);
1269
1289
  }