@opengsd/gsd-pi 1.3.0-dev.eed73bea → 1.4.0

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 (505) hide show
  1. package/README.md +10 -10
  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/gsd/artifact-verification.js +427 -0
  10. package/dist/resources/extensions/gsd/auto/session.js +11 -0
  11. package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +1 -1
  12. package/dist/resources/extensions/gsd/auto-artifact-paths.js +28 -1
  13. package/dist/resources/extensions/gsd/auto-budget.js +5 -1
  14. package/dist/resources/extensions/gsd/auto-dispatch.js +17 -6
  15. package/dist/resources/extensions/gsd/auto-post-unit.js +1 -1
  16. package/dist/resources/extensions/gsd/auto-prompts.js +8 -24
  17. package/dist/resources/extensions/gsd/auto-recovery.js +9 -517
  18. package/dist/resources/extensions/gsd/auto-runtime-state.js +4 -5
  19. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +3 -3
  20. package/dist/resources/extensions/gsd/auto-verification.js +5 -2
  21. package/dist/resources/extensions/gsd/auto.js +19 -10
  22. package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +39 -0
  23. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +5 -4
  24. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -18
  26. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +48 -36
  27. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +15 -4
  28. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +3 -1
  29. package/dist/resources/extensions/gsd/commands/handlers/auto.js +1 -1
  30. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
  31. package/dist/resources/extensions/gsd/commands-usage.js +1 -1
  32. package/dist/resources/extensions/gsd/db/engine.js +4 -1
  33. package/dist/resources/extensions/gsd/db-memory-fts-schema.js +34 -0
  34. package/dist/resources/extensions/gsd/db-workspace.js +55 -3
  35. package/dist/resources/extensions/gsd/delegation-policy.js +1 -1
  36. package/dist/resources/extensions/gsd/docs/preferences-reference.md +2 -2
  37. package/dist/resources/extensions/gsd/doctor-engine-checks.js +192 -4
  38. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +3 -0
  39. package/dist/resources/extensions/gsd/exec-sandbox.js +8 -2
  40. package/dist/resources/extensions/gsd/flat-phase-migration.js +45 -0
  41. package/dist/resources/extensions/gsd/git-service.js +57 -0
  42. package/dist/resources/extensions/gsd/gitignore.js +4 -1
  43. package/dist/resources/extensions/gsd/guided-flow-queue.js +20 -13
  44. package/dist/resources/extensions/gsd/json-persistence.js +20 -0
  45. package/dist/resources/extensions/gsd/knowledge-backfill.js +18 -11
  46. package/dist/resources/extensions/gsd/layout-policy.js +3 -1
  47. package/dist/resources/extensions/gsd/markdown-renderer.js +2 -7
  48. package/dist/resources/extensions/gsd/memory-backfill.js +28 -21
  49. package/dist/resources/extensions/gsd/metrics.js +4 -4
  50. package/dist/resources/extensions/gsd/migrate-external.js +11 -2
  51. package/dist/resources/extensions/gsd/migration-auto-check.js +22 -0
  52. package/dist/resources/extensions/gsd/milestone-ids.js +32 -2
  53. package/dist/resources/extensions/gsd/orphan-stash-audit.js +92 -16
  54. package/dist/resources/extensions/gsd/prompts/code-review.md +6 -4
  55. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  56. package/dist/resources/extensions/gsd/prompts/plan-slice.md +3 -3
  57. package/dist/resources/extensions/gsd/root-write-leak-guard.js +7 -1
  58. package/dist/resources/extensions/gsd/safety/destructive-guard.js +8 -1
  59. package/dist/resources/extensions/gsd/safety/evidence-collector.js +16 -1
  60. package/dist/resources/extensions/gsd/safety/file-change-validator.js +5 -2
  61. package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -1
  62. package/dist/resources/extensions/gsd/state/derive/cache.js +28 -0
  63. package/dist/resources/extensions/gsd/state/derive/db-open.js +39 -0
  64. package/dist/resources/extensions/gsd/state/derive/from-db.js +452 -0
  65. package/dist/resources/extensions/gsd/state/derive/index.js +75 -0
  66. package/dist/resources/extensions/gsd/state/derive/interrupted-work.js +21 -0
  67. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +27 -33
  68. package/dist/resources/extensions/gsd/state-reconciliation/index.js +48 -23
  69. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +32 -28
  70. package/dist/resources/extensions/gsd/state.js +12 -611
  71. package/dist/resources/extensions/gsd/tools/complete-milestone.js +4 -2
  72. package/dist/resources/extensions/gsd/tools/complete-slice.js +3 -34
  73. package/dist/resources/extensions/gsd/tools/complete-task.js +8 -41
  74. package/dist/resources/extensions/gsd/tools/plan-slice.js +59 -44
  75. package/dist/resources/extensions/gsd/tools/plan-task.js +28 -5
  76. package/dist/resources/extensions/gsd/undo.js +43 -6
  77. package/dist/resources/extensions/gsd/unit-registry.js +11 -3
  78. package/dist/resources/extensions/gsd/verification-gate.js +7 -0
  79. package/dist/resources/extensions/gsd/workflow-manifest.js +126 -13
  80. package/dist/resources/extensions/gsd/workflow-projections.js +19 -14
  81. package/dist/resources/extensions/gsd/worktree-manager.js +44 -2
  82. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  83. package/dist/web/standalone/.next/BUILD_ID +1 -1
  84. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  85. package/dist/web/standalone/.next/build-manifest.json +4 -4
  86. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  87. package/dist/web/standalone/.next/react-loadable-manifest.json +9 -9
  88. package/dist/web/standalone/.next/required-server-files.json +3 -3
  89. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  90. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  100. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  116. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  128. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  150. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  160. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  166. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  182. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  186. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/index.html +1 -1
  196. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  197. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  198. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  199. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  200. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  201. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  202. package/dist/web/standalone/.next/server/app/page.js +2 -2
  203. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  205. package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
  206. package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
  207. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/middleware.js +3 -3
  210. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  211. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  212. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  213. package/dist/web/standalone/.next/static/chunks/{2659.b7b129ee6a769448.js → 2659.58e950899a9bb82f.js} +1 -1
  214. package/dist/web/standalone/.next/static/chunks/2772.a7c1fcc69a4685ef.js +1 -0
  215. package/dist/web/standalone/.next/static/chunks/{3616.3c60753b8ffcbd2e.js → 3616.61a2af74bb8833c8.js} +1 -1
  216. package/dist/web/standalone/.next/static/chunks/{4283.8e446784528ed9dc.js → 4283.d0d9e0a955e441cb.js} +1 -1
  217. package/dist/web/standalone/.next/static/chunks/{5826.a46ecdd1cfe8dabc.js → 5826.5421d66c72b9f34e.js} +1 -1
  218. package/dist/web/standalone/.next/static/chunks/{8785.481aa5869991b760.js → 8785.e29b3134cab1d153.js} +1 -1
  219. package/dist/web/standalone/.next/static/chunks/8937.640dc9c2aaa1dfad.js +10 -0
  220. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +1 -0
  221. package/dist/web/standalone/.next/static/chunks/app/{layout-4ae2d68984392bbf.js → layout-b35cbfff38aaf4cf.js} +1 -1
  222. package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +1 -0
  223. package/dist/web/standalone/.next/static/chunks/{main-app-90d1d8d5e5d2dc6b.js → main-app-590a74400e35f685.js} +1 -1
  224. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +1 -0
  225. package/dist/web/standalone/.next/static/chunks/webpack-9c401904f87ded16.js +1 -0
  226. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  227. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  228. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  229. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  230. package/dist/web/standalone/server.js +1 -1
  231. package/package.json +6 -6
  232. package/packages/cloud-mcp-gateway/package.json +2 -2
  233. package/packages/contracts/package.json +1 -1
  234. package/packages/daemon/package.json +4 -4
  235. package/packages/gsd-agent-core/dist/agent-session.d.ts +1 -0
  236. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  237. package/packages/gsd-agent-core/dist/agent-session.js +3 -0
  238. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  239. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts +41 -0
  240. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts.map +1 -0
  241. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js +62 -0
  242. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js.map +1 -0
  243. package/packages/gsd-agent-core/dist/index.d.ts +2 -0
  244. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  245. package/packages/gsd-agent-core/dist/index.js +2 -0
  246. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  247. package/packages/gsd-agent-core/dist/session/agent-session-events.js +1 -1
  248. package/packages/gsd-agent-core/dist/session/agent-session-events.js.map +1 -1
  249. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +1 -0
  250. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  251. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  252. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts +5 -0
  253. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  254. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +60 -3
  255. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  256. package/packages/gsd-agent-core/dist/transcript-store.d.ts +58 -0
  257. package/packages/gsd-agent-core/dist/transcript-store.d.ts.map +1 -0
  258. package/packages/gsd-agent-core/dist/transcript-store.js +132 -0
  259. package/packages/gsd-agent-core/dist/transcript-store.js.map +1 -0
  260. package/packages/gsd-agent-core/package.json +5 -5
  261. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  262. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  263. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +25 -11
  264. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  265. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts +4 -0
  266. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts.map +1 -0
  267. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js +7 -0
  268. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js.map +1 -0
  269. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -24
  270. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  271. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -841
  272. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  273. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts +58 -0
  274. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts.map +1 -0
  275. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js +312 -0
  276. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js.map +1 -0
  277. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts +31 -0
  278. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts.map +1 -0
  279. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js +130 -0
  280. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js.map +1 -0
  281. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts +15 -0
  282. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -0
  283. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +258 -0
  284. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -0
  285. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts +13 -0
  286. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts.map +1 -0
  287. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js +118 -0
  288. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js.map +1 -0
  289. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +9 -0
  290. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  291. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js +1 -1
  292. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  293. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts +54 -0
  294. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts.map +1 -0
  295. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js +20 -0
  296. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js.map +1 -0
  297. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +4 -1
  298. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  299. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +9 -0
  300. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  301. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts +56 -0
  302. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts.map +1 -0
  303. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js +44 -0
  304. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js.map +1 -0
  305. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts +5 -0
  306. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts.map +1 -0
  307. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js +77 -0
  308. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js.map +1 -0
  309. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts +2 -0
  310. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  311. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +23 -5
  312. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
  313. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  314. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +18 -0
  315. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  316. package/packages/gsd-agent-modes/package.json +7 -7
  317. package/packages/mcp-server/dist/workflow-tools.js +1 -1
  318. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  319. package/packages/mcp-server/package.json +4 -4
  320. package/packages/native/package.json +1 -1
  321. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  322. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  323. package/packages/pi-agent-core/package.json +1 -1
  324. package/packages/pi-ai/dist/models.generated.d.ts +46 -0
  325. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  326. package/packages/pi-ai/dist/models.generated.js +38 -0
  327. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  328. package/packages/pi-ai/package.json +1 -1
  329. package/packages/pi-coding-agent/README.md +3 -2
  330. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts +9 -0
  331. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts.map +1 -0
  332. package/packages/pi-coding-agent/dist/core/session-manager-context.js +94 -0
  333. package/packages/pi-coding-agent/dist/core/session-manager-context.js.map +1 -0
  334. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts +8 -0
  335. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts.map +1 -0
  336. package/packages/pi-coding-agent/dist/core/session-manager-list.js +244 -0
  337. package/packages/pi-coding-agent/dist/core/session-manager-list.js.map +1 -0
  338. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts +12 -0
  339. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts.map +1 -0
  340. package/packages/pi-coding-agent/dist/core/session-manager-migration.js +84 -0
  341. package/packages/pi-coding-agent/dist/core/session-manager-migration.js.map +1 -0
  342. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +135 -0
  343. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -0
  344. package/packages/pi-coding-agent/dist/core/session-manager-types.js +2 -0
  345. package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -0
  346. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +6 -154
  347. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  348. package/packages/pi-coding-agent/dist/core/session-manager.js +22 -459
  349. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  350. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts +75 -75
  351. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts.map +1 -1
  352. package/packages/pi-coding-agent/dist/theme/theme-schema.js +1 -1
  353. package/packages/pi-coding-agent/dist/theme/theme-schema.js.map +1 -1
  354. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  355. package/packages/pi-coding-agent/dist/theme/theme.js +11 -7
  356. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  357. package/packages/pi-coding-agent/package.json +7 -7
  358. package/packages/pi-tui/package.json +2 -2
  359. package/packages/rpc-client/package.json +2 -2
  360. package/pkg/dist/theme/theme-schema.d.ts +75 -75
  361. package/pkg/dist/theme/theme-schema.d.ts.map +1 -1
  362. package/pkg/dist/theme/theme-schema.js +1 -1
  363. package/pkg/dist/theme/theme-schema.js.map +1 -1
  364. package/pkg/dist/theme/theme.d.ts.map +1 -1
  365. package/pkg/dist/theme/theme.js +11 -7
  366. package/pkg/dist/theme/theme.js.map +1 -1
  367. package/pkg/package.json +1 -1
  368. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  369. package/src/resources/extensions/claude-code-cli/tests/index.test.ts +14 -0
  370. package/src/resources/extensions/gsd/artifact-verification.ts +464 -0
  371. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  372. package/src/resources/extensions/gsd/auto/session.ts +14 -0
  373. package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +3 -1
  374. package/src/resources/extensions/gsd/auto-artifact-paths.ts +47 -1
  375. package/src/resources/extensions/gsd/auto-budget.ts +12 -1
  376. package/src/resources/extensions/gsd/auto-dispatch.ts +17 -7
  377. package/src/resources/extensions/gsd/auto-post-unit.ts +1 -1
  378. package/src/resources/extensions/gsd/auto-prompts.ts +7 -23
  379. package/src/resources/extensions/gsd/auto-recovery.ts +13 -518
  380. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -5
  381. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +3 -2
  382. package/src/resources/extensions/gsd/auto-verification.ts +5 -1
  383. package/src/resources/extensions/gsd/auto.ts +23 -8
  384. package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +44 -0
  385. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +5 -4
  386. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  387. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +43 -18
  388. package/src/resources/extensions/gsd/bootstrap/tests/write-gate-basepath.test.ts +49 -1
  389. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +50 -37
  390. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +16 -4
  391. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +2 -1
  392. package/src/resources/extensions/gsd/commands/handlers/auto.ts +1 -1
  393. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
  394. package/src/resources/extensions/gsd/commands-usage.ts +1 -1
  395. package/src/resources/extensions/gsd/db/engine.ts +8 -1
  396. package/src/resources/extensions/gsd/db-memory-fts-schema.ts +45 -0
  397. package/src/resources/extensions/gsd/db-workspace.ts +61 -3
  398. package/src/resources/extensions/gsd/delegation-policy.ts +1 -1
  399. package/src/resources/extensions/gsd/docs/preferences-reference.md +2 -2
  400. package/src/resources/extensions/gsd/doctor-engine-checks.ts +233 -5
  401. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +3 -0
  402. package/src/resources/extensions/gsd/doctor-types.ts +3 -0
  403. package/src/resources/extensions/gsd/exec-sandbox.ts +7 -2
  404. package/src/resources/extensions/gsd/flat-phase-migration.ts +44 -0
  405. package/src/resources/extensions/gsd/git-service.ts +64 -0
  406. package/src/resources/extensions/gsd/gitignore.ts +4 -1
  407. package/src/resources/extensions/gsd/guided-flow-queue.ts +20 -13
  408. package/src/resources/extensions/gsd/json-persistence.ts +20 -0
  409. package/src/resources/extensions/gsd/knowledge-backfill.ts +16 -10
  410. package/src/resources/extensions/gsd/layout-policy.ts +2 -1
  411. package/src/resources/extensions/gsd/markdown-renderer.ts +2 -10
  412. package/src/resources/extensions/gsd/memory-backfill.ts +26 -20
  413. package/src/resources/extensions/gsd/metrics.ts +4 -4
  414. package/src/resources/extensions/gsd/migrate-external.ts +8 -2
  415. package/src/resources/extensions/gsd/migration-auto-check.ts +23 -0
  416. package/src/resources/extensions/gsd/milestone-ids.ts +31 -2
  417. package/src/resources/extensions/gsd/orphan-stash-audit.ts +108 -20
  418. package/src/resources/extensions/gsd/prompts/code-review.md +6 -4
  419. package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  420. package/src/resources/extensions/gsd/prompts/plan-slice.md +3 -3
  421. package/src/resources/extensions/gsd/root-write-leak-guard.ts +13 -1
  422. package/src/resources/extensions/gsd/safety/destructive-guard.ts +9 -1
  423. package/src/resources/extensions/gsd/safety/evidence-collector.ts +16 -1
  424. package/src/resources/extensions/gsd/safety/file-change-validator.ts +8 -2
  425. package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -1
  426. package/src/resources/extensions/gsd/state/derive/cache.ts +46 -0
  427. package/src/resources/extensions/gsd/state/derive/db-open.ts +45 -0
  428. package/src/resources/extensions/gsd/state/derive/from-db.ts +561 -0
  429. package/src/resources/extensions/gsd/state/derive/index.ts +104 -0
  430. package/src/resources/extensions/gsd/state/derive/interrupted-work.ts +31 -0
  431. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +36 -30
  432. package/src/resources/extensions/gsd/state-reconciliation/index.ts +50 -24
  433. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +43 -28
  434. package/src/resources/extensions/gsd/state.ts +32 -732
  435. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +4 -3
  436. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +98 -1
  437. package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +14 -5
  438. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +36 -0
  439. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +182 -4
  440. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +35 -0
  441. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +30 -0
  442. package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +1 -0
  443. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +28 -0
  444. package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +69 -0
  445. package/src/resources/extensions/gsd/tests/db-memory-fts-schema.test.ts +58 -3
  446. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +51 -0
  447. package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +44 -0
  448. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +143 -0
  449. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +239 -2
  450. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +16 -0
  451. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +40 -0
  452. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +37 -2
  453. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +4 -0
  454. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +11 -2
  455. package/src/resources/extensions/gsd/tests/json-persistence-atomic.test.ts +47 -0
  456. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +35 -0
  457. package/src/resources/extensions/gsd/tests/memory-store.test.ts +48 -0
  458. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +31 -1
  459. package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +6 -0
  460. package/src/resources/extensions/gsd/tests/metrics.test.ts +1 -0
  461. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +57 -0
  462. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +70 -0
  463. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +91 -7
  464. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -1
  465. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +10 -0
  466. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +103 -4
  467. package/src/resources/extensions/gsd/tests/plan-task.test.ts +44 -1
  468. package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +4 -2
  469. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +50 -14
  470. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +58 -0
  471. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -6
  472. package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +103 -0
  473. package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +20 -1
  474. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +15 -3
  475. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +56 -0
  476. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +115 -0
  477. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +140 -0
  478. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +6 -3
  479. package/src/resources/extensions/gsd/tests/undo.test.ts +74 -0
  480. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +38 -0
  481. package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +69 -4
  482. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +96 -15
  483. package/src/resources/extensions/gsd/tests/workflow-mcp-preflight.test.ts +1 -0
  484. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +8 -4
  485. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +6 -5
  486. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +39 -0
  487. package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
  488. package/src/resources/extensions/gsd/tools/complete-slice.ts +3 -30
  489. package/src/resources/extensions/gsd/tools/complete-task.ts +7 -39
  490. package/src/resources/extensions/gsd/tools/plan-slice.ts +60 -47
  491. package/src/resources/extensions/gsd/tools/plan-task.ts +30 -5
  492. package/src/resources/extensions/gsd/undo.ts +47 -6
  493. package/src/resources/extensions/gsd/unit-registry.ts +11 -3
  494. package/src/resources/extensions/gsd/verification-gate.ts +8 -0
  495. package/src/resources/extensions/gsd/workflow-manifest.ts +141 -7
  496. package/src/resources/extensions/gsd/workflow-projections.ts +20 -14
  497. package/src/resources/extensions/gsd/worktree-manager.ts +41 -1
  498. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +0 -1
  499. package/dist/web/standalone/.next/static/chunks/796.3976108148518f7d.js +0 -10
  500. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +0 -1
  501. package/dist/web/standalone/.next/static/chunks/app/page-6644fc6ee8ca1247.js +0 -1
  502. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +0 -1
  503. package/dist/web/standalone/.next/static/chunks/webpack-7c1d97e39be2da11.js +0 -1
  504. /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → zQLcXm0Za8lexoXtgDpMG}/_buildManifest.js +0 -0
  505. /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → zQLcXm0Za8lexoXtgDpMG}/_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).
@@ -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);
@@ -654,8 +654,9 @@ export function registerDbTools(pi) {
654
654
  promptSnippet: "Plan a slice via DB write + PLAN render + cache invalidation",
655
655
  promptGuidelines: [
656
656
  "Use gsd_plan_slice for slice planning instead of writing S##-PLAN.md or task PLAN files directly.",
657
- "Keep parameters flat and provide the full slice planning payload, including tasks.",
658
- "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.",
659
660
  "Use the canonical name gsd_plan_slice; gsd_slice_plan is only an alias.",
660
661
  ],
661
662
  parameters: Type.Object({
@@ -663,7 +664,7 @@ export function registerDbTools(pi) {
663
664
  milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
664
665
  sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
665
666
  goal: Type.String({ description: "Slice goal" }),
666
- tasks: Type.Array(Type.Object({
667
+ tasks: Type.Optional(Type.Array(Type.Object({
667
668
  taskId: Type.String({ description: "Task ID (e.g. T01)" }),
668
669
  title: Type.String({ description: "Task title" }),
669
670
  description: Type.String({ description: "Task description / steps block" }),
@@ -673,7 +674,7 @@ export function registerDbTools(pi) {
673
674
  inputs: Type.Array(Type.String(), { description: "Array<string> of input files or references; pass [\"path\"] or [], never a single string" }),
674
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" }),
675
676
  observabilityImpact: Type.Optional(Type.String({ description: "Task observability impact" })),
676
- }), { 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." })),
677
678
  // ── Enrichment metadata (optional — defaults to empty) ────────────
678
679
  successCriteria: Type.Optional(Type.String({ description: "Slice success criteria block" })),
679
680
  proofLevel: Type.Optional(Type.String({ description: "Slice proof level" })),
@@ -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 = [];
@@ -14,7 +14,8 @@ import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from
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
  }
@@ -449,6 +436,16 @@ function deferApprovalGateFromSnapshot(gateId, basePath, snapshot) {
449
436
  function contextBasePath(ctx) {
450
437
  return typeof ctx?.cwd === "string" ? ctx.cwd : process.cwd();
451
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
+ }
452
449
  function beginSourceObservationStoreForCurrentUnit(ctx) {
453
450
  if (!isAutoActive())
454
451
  return null;
@@ -717,6 +714,12 @@ export function registerHooks(pi, ecosystemHandlers) {
717
714
  }
718
715
  }
719
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
+ }
720
723
  }
721
724
  catch (err) {
722
725
  safetyLogWarning("bootstrap", `flat-phase migration: ${err instanceof Error ? err.message : String(err)}`);
@@ -874,6 +877,17 @@ export function registerHooks(pi, ecosystemHandlers) {
874
877
  const { handleAgentEnd } = await import("./agent-end-recovery.js");
875
878
  const agentEndBasePath = contextBasePath(ctx);
876
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
+ }
877
891
  await handleAgentEnd(pi, event, ctx);
878
892
  }
879
893
  finally {
@@ -1063,7 +1077,7 @@ export function registerHooks(pi, ecosystemHandlers) {
1063
1077
  // ── Loop guard: block repeated identical tool calls ──
1064
1078
  const loopCheck = checkToolCallLoop(toolName, event.input);
1065
1079
  if (loopCheck.block) {
1066
- return { block: true, reason: loopCheck.reason };
1080
+ return { block: true, reason: formatLoopGuardBlockReason(loopCheck.reason) };
1067
1081
  }
1068
1082
  const deferredGateGuard = shouldBlockDeferredApprovalTool(toolName, event.input, discussionBasePath);
1069
1083
  if (deferredGateGuard.block) {
@@ -1269,6 +1283,7 @@ export function registerHooks(pi, ecosystemHandlers) {
1269
1283
  }
1270
1284
  }
1271
1285
  if (!event.isError) {
1286
+ recordToolCallLoopMutation(toolName);
1272
1287
  refreshSourceObservationAfterMutation(toolName, event.input, ctx);
1273
1288
  clearSourceObservationsAfterShell(toolName);
1274
1289
  }
@@ -1,24 +1,29 @@
1
1
  /**
2
2
  * Tool-call loop guard.
3
3
  *
4
- * Detects when a model calls the same tool with identical arguments
5
- * repeatedly within a single agent turn. Works in both auto-mode and
6
- * interactive sessions by hooking into the `tool_call` event, which
7
- * fires before execution and can block the call.
4
+ * Detects when a model repeats tool calls within a single Agent Turn.
5
+ * Works in both auto-mode and interactive sessions by hooking into the
6
+ * native engine's `tool_call` event, which fires before execution and can
7
+ * block the call.
8
8
  *
9
- * The guard uses a sliding window: it tracks the last N tool signatures
10
- * and blocks when the same signature appears more than MAX_CONSECUTIVE
11
- * times in a row. Resets on each agent turn (session_start, agent_end)
12
- * and when a different tool call breaks the streak.
9
+ * The guard has two independent checks: a sliding window for identical
10
+ * tool signatures, and a per-tool-name cap for repeated calls with varied
11
+ * arguments. State resets at Agent Turn boundaries (session_start,
12
+ * agent_end) and the identical-signature streak also resets when a
13
+ * different tool call breaks the streak. Block messages instruct the model
14
+ * to stop tooling for the rest of that turn and answer in text.
13
15
  *
14
- * A second, independent check (#783 Brief C) tracks per-tool-name call
15
- * counts within a turn regardless of args. This catches improvisation
16
+ * The per-tool-name check (#783 Brief C) tracks call counts within a
17
+ * turn regardless of args, decaying after successful state-mutating tools.
18
+ * This catches improvisation
16
19
  * loops where the model attempts the same missing workflow tool through
17
20
  * varied surfaces (bash → `node -e` → CLI), each with a different
18
- * signature, so the identical-args streak never trips. Whichever guard
21
+ * signature, so the identical-args streak never trips, while allowing
22
+ * tool-heavy turns that are making file-mutation progress. Whichever guard
19
23
  * trips first blocks.
20
24
  */
21
25
  import { createHash } from "node:crypto";
26
+ import { INHERENTLY_REPEATABLE_TOOL_SET } from "./core-session-tools.js";
22
27
  const MAX_CONSECUTIVE_IDENTICAL_CALLS = 4;
23
28
  /** Interactive/user-facing tools where even 1 duplicate is confusing. */
24
29
  const STRICT_LOOP_TOOLS = new Set(["ask_user_questions"]);
@@ -35,32 +40,16 @@ const MAX_CONSECUTIVE_STRICT = 1;
35
40
  */
36
41
  const PER_TOOL_DEFAULT_CAP = 6;
37
42
  const PER_TOOL_REPEATABLE_CAP = 15;
38
- /**
39
- * Inherently-repeatable tools: called many times per turn in normal work
40
- * (reading/writing several files, running several commands, searching). These
41
- * get PER_TOOL_REPEATABLE_CAP rather than the default. Keep this list
42
- * conservative — a tool here can be invoked up to PER_TOOL_REPEATABLE_CAP times
43
- * per turn before the guard blocks.
44
- */
45
- const REPEATABLE_TOOLS = new Set([
46
- "read",
47
- "write",
48
- "edit",
49
- "multi_edit",
50
- "bash",
51
- "grep",
52
- "glob",
53
- "search-the-web",
54
- "fetch_page",
55
- "todo_write",
56
- "notebook_edit",
57
- ]);
43
+ const PER_TOOL_CAP_EXEMPT_TOOLS = new Set(["find", "glob", "grep", "ls", "read", "search_and_read"]);
44
+ const STATE_MUTATING_TOOL_SET = new Set(["edit", "write", "multi_edit", "notebook_edit"]);
58
45
  let consecutiveCount = 0;
59
46
  let lastSignature = "";
60
47
  let lastToolName = "";
61
48
  let enabled = true;
62
49
  /** Per-tool-name call counts within the current turn (#783 Brief C). */
63
50
  const perToolCounts = new Map();
51
+ let mutationEpoch = 0;
52
+ const perToolLastMutationEpoch = new Map();
64
53
  /** Hash tool name + args into a compact signature for comparison. */
65
54
  function hashToolCall(toolName, args) {
66
55
  const h = createHash("sha256");
@@ -84,7 +73,8 @@ function hashToolCall(toolName, args) {
84
73
  * 1. Identical-signature streak (MAX_CONSECUTIVE_IDENTICAL_CALLS, strict for
85
74
  * ask_user_questions).
86
75
  * 2. Per-tool-name cap (PER_TOOL_DEFAULT_CAP / PER_TOOL_REPEATABLE_CAP),
87
- * independent of args catches improvisation loops (#783).
76
+ * independent of args, reset after file-mutation progress — catches
77
+ * improvisation loops (#783).
88
78
  */
89
79
  export function checkToolCallLoop(toolName, args) {
90
80
  if (!enabled)
@@ -107,16 +97,25 @@ export function checkToolCallLoop(toolName, args) {
107
97
  block: true,
108
98
  reason: `Tool loop detected (identical args): ${toolName} called ${consecutiveCount} times ` +
109
99
  `with identical arguments. Blocking to prevent infinite loop. ` +
110
- `Try a different approach or modify your arguments.`,
100
+ `Do not retry this tool or call other tools this turn — stop and respond to the user in text.`,
111
101
  count: consecutiveCount,
112
102
  };
113
103
  }
114
104
  // ── Guard 2: per-tool-name cap, independent of args (#783 Brief C) ──
115
105
  // Catches improvisation loops where the same tool is invoked many times with
116
106
  // varied args (e.g. retrying a missing workflow tool via bash/node -e/CLI).
117
- const perToolCount = (perToolCounts.get(toolName) ?? 0) + 1;
107
+ const priorPerToolCount = (perToolLastMutationEpoch.get(toolName) ?? mutationEpoch) < mutationEpoch
108
+ ? 0
109
+ : (perToolCounts.get(toolName) ?? 0);
110
+ const perToolCount = priorPerToolCount + 1;
118
111
  perToolCounts.set(toolName, perToolCount);
119
- const perToolCap = REPEATABLE_TOOLS.has(toolName)
112
+ perToolLastMutationEpoch.set(toolName, mutationEpoch);
113
+ // Read-only navigation tools are normal context gathering; Guard 1 still
114
+ // catches true reread loops with identical arguments.
115
+ if (PER_TOOL_CAP_EXEMPT_TOOLS.has(toolName)) {
116
+ return { block: false, count: consecutiveCount };
117
+ }
118
+ const perToolCap = INHERENTLY_REPEATABLE_TOOL_SET.has(toolName)
120
119
  ? PER_TOOL_REPEATABLE_CAP
121
120
  : PER_TOOL_DEFAULT_CAP;
122
121
  if (perToolCount > perToolCap) {
@@ -124,12 +123,21 @@ export function checkToolCallLoop(toolName, args) {
124
123
  block: true,
125
124
  reason: `Tool loop detected (repeated tool): ${toolName} called ${perToolCount} times ` +
126
125
  `this turn (cap ${perToolCap}). Blocking to prevent infinite loop. ` +
127
- `The tool may be unavailable or failing repeatedly try a different approach.`,
126
+ `The tool may be unavailable or failing repeatedly. ` +
127
+ `Do not retry this tool or pivot to other tools this turn — stop and respond to the user in text.`,
128
128
  count: perToolCount,
129
129
  };
130
130
  }
131
131
  return { block: false, count: consecutiveCount };
132
132
  }
133
+ /** Record successful mutation progress so Guard 2 can decay on the next count. */
134
+ export function recordToolCallLoopMutation(toolName) {
135
+ if (!enabled)
136
+ return;
137
+ if (!STATE_MUTATING_TOOL_SET.has(toolName))
138
+ return;
139
+ mutationEpoch++;
140
+ }
133
141
  /** Reset the guard state. Call at agent turn boundaries. */
134
142
  export function resetToolCallLoopGuard() {
135
143
  consecutiveCount = 0;
@@ -137,6 +145,8 @@ export function resetToolCallLoopGuard() {
137
145
  lastToolName = "";
138
146
  enabled = true;
139
147
  perToolCounts.clear();
148
+ mutationEpoch = 0;
149
+ perToolLastMutationEpoch.clear();
140
150
  }
141
151
  /** Disable the guard (e.g. during shutdown). */
142
152
  export function disableToolCallLoopGuard() {
@@ -145,6 +155,8 @@ export function disableToolCallLoopGuard() {
145
155
  lastSignature = "";
146
156
  lastToolName = "";
147
157
  perToolCounts.clear();
158
+ mutationEpoch = 0;
159
+ perToolLastMutationEpoch.clear();
148
160
  }
149
161
  /** Get current consecutive count for diagnostics. */
150
162
  export function getToolCallLoopCount() {
@@ -81,8 +81,18 @@ function createEmptyWriteGateState() {
81
81
  };
82
82
  }
83
83
  const writeGateStatesByBasePath = new Map();
84
+ /**
85
+ * Write-gate snapshots are project-scoped, not worktree-scoped. When auto-mode
86
+ * routes MCP tool writes to `.gsd-worktrees/<MID>/`, depth verification still
87
+ * lands in the authoritative project `.gsd/runtime/` tree (or external-state
88
+ * symlink target). Without this canonicalization, `loadWriteGateSnapshot(worktree)`
89
+ * sees an empty snapshot and CONTEXT saves loop forever (#M020 gate loop).
90
+ */
91
+ function resolveWriteGateSnapshotRoot(basePath) {
92
+ return resolve(resolveWorktreeProjectRoot(basePath));
93
+ }
84
94
  function writeGateStateKey(basePath) {
85
- return resolve(basePath);
95
+ return resolveWriteGateSnapshotRoot(basePath);
86
96
  }
87
97
  function getWriteGateState(basePath = process.cwd()) {
88
98
  const key = writeGateStateKey(basePath);
@@ -123,16 +133,17 @@ function shouldPersistWriteGateSnapshot(env = process.env) {
123
133
  return v !== "0" && v !== "false";
124
134
  }
125
135
  function writeGateSnapshotPath(basePath) {
126
- return join(basePath, ".gsd", "runtime", "write-gate-state.json");
136
+ return join(resolveWriteGateSnapshotRoot(basePath), ".gsd", "runtime", "write-gate-state.json");
127
137
  }
128
138
  function ensureWriteGateSnapshotDirectory(basePath) {
129
- const gsdPath = join(basePath, ".gsd");
139
+ const snapshotRoot = resolveWriteGateSnapshotRoot(basePath);
140
+ const gsdPath = join(snapshotRoot, ".gsd");
130
141
  if (!existsSync(gsdPath)) {
131
142
  try {
132
143
  const stat = lstatSync(gsdPath);
133
144
  if (stat.isSymbolicLink()) {
134
145
  const target = readlinkSync(gsdPath);
135
- mkdirSync(isAbsolute(target) ? target : resolve(basePath, target), { recursive: true });
146
+ mkdirSync(isAbsolute(target) ? target : resolve(snapshotRoot, target), { recursive: true });
136
147
  }
137
148
  }
138
149
  catch {
@@ -4,7 +4,7 @@ import { existsSync, mkdirSync, unlinkSync, writeFileSync } from "node:fs";
4
4
  import { dirname, join } from "node:path";
5
5
  import { getLatestAssessmentByScope, getMilestone, getMilestoneSlices, getPendingGates, getSliceTasks, insertAssessment, isDbAvailable, transaction, } from "./gsd-db.js";
6
6
  import { getWorkflowDatabasePath, refreshWorkflowDatabaseFromDisk, } from "./db-workspace.js";
7
- import { isClosedStatus } from "./status-guards.js";
7
+ import { isClosedStatus, isDeferredStatus } from "./status-guards.js";
8
8
  import { closeQualityGatesFromEvidence } from "./quality-gate-closure.js";
9
9
  import { insertMilestoneValidationGates } from "./milestone-validation-gates.js";
10
10
  import { relMilestoneFile, resolveSliceFile } from "./paths.js";
@@ -144,6 +144,8 @@ export function checkCloseoutConsistencyGate(milestoneId, options = {}) {
144
144
  });
145
145
  }
146
146
  for (const slice of slices) {
147
+ if (isDeferredStatus(slice.status))
148
+ continue;
147
149
  if (!isClosedStatus(slice.status)) {
148
150
  return blocked("slice-open", `Closeout consistency blocked for ${milestoneId}: slice ${slice.id} status is "${slice.status}".`);
149
151
  }
@@ -190,7 +190,7 @@ export async function handleAutoCommand(trimmed, ctx, pi) {
190
190
  }
191
191
  return true;
192
192
  }
193
- await pauseAuto(ctx, pi);
193
+ await pauseAuto(ctx, pi, undefined, { abortActiveTurn: true });
194
194
  return true;
195
195
  }
196
196
  if (trimmed === "rate" || trimmed.startsWith("rate ")) {
@@ -1164,7 +1164,7 @@ async function configureContextCodebase(ctx, prefs) {
1164
1164
  cm.observation_mask_turns = maskTurns;
1165
1165
  else if (maskTurns === "clear")
1166
1166
  delete cm.observation_mask_turns;
1167
- const thresh = await promptNumber(ctx, "Compaction threshold percent (0.5–0.95)", cm.compaction_threshold_percent, "0.60");
1167
+ const thresh = await promptNumber(ctx, "Soft context warning threshold percent (0.5–0.95)", cm.compaction_threshold_percent, "0.60");
1168
1168
  if (thresh !== undefined && thresh !== "clear")
1169
1169
  cm.compaction_threshold_percent = thresh;
1170
1170
  else if (thresh === "clear")
@@ -83,7 +83,7 @@ function formatThresholdLines() {
83
83
  }
84
84
  const compactionThreshold = prefs?.context_management?.compaction_threshold_percent;
85
85
  if (typeof compactionThreshold === "number") {
86
- lines.push(`Compaction: ${Math.round(compactionThreshold * 100)}%`);
86
+ lines.push(`Soft context warning: ${Math.round(compactionThreshold * 100)}%`);
87
87
  }
88
88
  return lines;
89
89
  }
@@ -19,7 +19,7 @@ import { createCoordinationTablesV24 } from "../db-coordination-schema.js";
19
19
  import { createDbConnectionCache } from "../db-connection-cache.js";
20
20
  import { backupDatabaseBeforeMigration, isMigrationBackupError } from "../db-migration-backup.js";
21
21
  import { applyMigrationV2Artifacts, applyMigrationV3Memories, applyMigrationV4DecisionMadeBy, applyMigrationV5HierarchyTables, applyMigrationV6SliceSummaries, applyMigrationV7Dependencies, applyMigrationV8PlanningFields, applyMigrationV9Ordering, applyMigrationV10ReplanTrigger, applyMigrationV11TaskPlanning, applyMigrationV12QualityGates, applyMigrationV13HotPathIndexes, applyMigrationV14SliceDependencies, applyMigrationV15AuditTables, applyMigrationV16EscalationSource, applyMigrationV17TaskEscalation, applyMigrationV18MemorySources, applyMigrationV19MemoryFts, applyMigrationV20MemoryRelations, applyMigrationV21StructuredMemories, applyMigrationV22QualityGateRepair, applyMigrationV23MilestoneQueue, applyMigrationV26MilestoneCommitAttributions, applyMigrationV27ArtifactHash, applyMigrationV28MemoryLastHitAt, applyMigrationV29RepositoryTargets, } from "../db-migration-steps.js";
22
- import { isMemoriesFtsAvailableSchema, tryCreateMemoriesFtsSchema } from "../db-memory-fts-schema.js";
22
+ import { isMemoriesFtsAvailableSchema, rebuildMemoriesFtsSchemaOnce, tryCreateMemoriesFtsSchema, } from "../db-memory-fts-schema.js";
23
23
  import { createDbOpenState } from "../db-open-state.js";
24
24
  import { createRuntimeKvTableV25 } from "../db-runtime-kv-schema.js";
25
25
  import { getCurrentSchemaVersion, recordSchemaVersion } from "../db-schema-metadata.js";
@@ -101,6 +101,9 @@ function initSchema(db, fileBacked, dbPath) {
101
101
  throw err;
102
102
  }
103
103
  migrateSchema(db, dbPath);
104
+ rebuildMemoriesFtsSchemaOnce(db, {
105
+ onRebuildFailed: (message) => logWarning("db", message),
106
+ });
104
107
  }
105
108
  export function _isLikelyWslDrvFsPathForTest(dbPath) {
106
109
  if (!dbPath || process.platform !== "linux")
@@ -1,5 +1,7 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: Memory FTS5 SQLite schema helpers for the GSD database facade.
3
+ import { createRuntimeKvTableV25 } from "./db-runtime-kv-schema.js";
4
+ export const MEMORIES_FTS_REBUILT_KEY = "memories_fts_rebuilt_at";
3
5
  function formatFtsUnavailableError(err) {
4
6
  const message = err instanceof Error ? err.message : String(err);
5
7
  return message.replace(/\bmoduel\s*:\s*/gi, "module: ");
@@ -54,3 +56,35 @@ export function isMemoriesFtsAvailableSchema(db) {
54
56
  return false;
55
57
  }
56
58
  }
59
+ export function rebuildMemoriesFtsSchemaOnce(db, options = {}) {
60
+ if (!isMemoriesFtsAvailableSchema(db))
61
+ return;
62
+ createRuntimeKvTableV25(db);
63
+ const marker = db.prepare("SELECT 1 as present FROM runtime_kv WHERE scope = 'global' AND scope_id = '' AND key = :key").get({ ":key": MEMORIES_FTS_REBUILT_KEY });
64
+ if (marker)
65
+ return;
66
+ const now = new Date().toISOString();
67
+ try {
68
+ db.exec("BEGIN");
69
+ db.exec("INSERT INTO memories_fts(memories_fts) VALUES('rebuild')");
70
+ db.prepare(`INSERT INTO runtime_kv (scope, scope_id, key, value_json, updated_at)
71
+ VALUES ('global', '', :key, :value_json, :updated_at)
72
+ ON CONFLICT (scope, scope_id, key) DO UPDATE SET
73
+ value_json = excluded.value_json,
74
+ updated_at = excluded.updated_at`).run({
75
+ ":key": MEMORIES_FTS_REBUILT_KEY,
76
+ ":value_json": JSON.stringify(now),
77
+ ":updated_at": now,
78
+ });
79
+ db.exec("COMMIT");
80
+ }
81
+ catch (err) {
82
+ try {
83
+ db.exec("ROLLBACK");
84
+ }
85
+ catch {
86
+ // Best effort: leave startup alive and retry the rebuild on next open.
87
+ }
88
+ options.onRebuildFailed?.(`FTS5 rebuild failed: ${err.message}`);
89
+ }
90
+ }