@opengsd/gsd-pi 1.3.0-dev.65546769 → 1.3.0-dev.72e3af2a

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 (357) hide show
  1. package/dist/resources/.managed-resources-content-hash +1 -1
  2. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +11 -2
  3. package/dist/resources/extensions/google-cli/stream-adapter.js +82 -15
  4. package/dist/resources/extensions/gsd/artifact-verification.js +427 -0
  5. package/dist/resources/extensions/gsd/auto/orchestrator.js +12 -3
  6. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  7. package/dist/resources/extensions/gsd/auto-artifact-paths.js +28 -1
  8. package/dist/resources/extensions/gsd/auto-dispatch.js +20 -19
  9. package/dist/resources/extensions/gsd/auto-prompts.js +26 -11
  10. package/dist/resources/extensions/gsd/auto-recovery.js +6 -507
  11. package/dist/resources/extensions/gsd/auto-runtime-state.js +4 -5
  12. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +3 -3
  13. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +103 -13
  14. package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +38 -0
  15. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +6 -1
  16. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -0
  17. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +10 -19
  18. package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -19
  19. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +68 -10
  20. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +1 -1
  21. package/dist/resources/extensions/gsd/commands-context.js +19 -1
  22. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +16 -10
  23. package/dist/resources/extensions/gsd/commands-worktree.js +12 -10
  24. package/dist/resources/extensions/gsd/dashboard-overlay.js +32 -3
  25. package/dist/resources/extensions/gsd/db/queries.js +60 -0
  26. package/dist/resources/extensions/gsd/db-workspace.js +55 -3
  27. package/dist/resources/extensions/gsd/doctor-providers.js +92 -8
  28. package/dist/resources/extensions/gsd/exec-sandbox.js +45 -9
  29. package/dist/resources/extensions/gsd/forensics.js +2 -32
  30. package/dist/resources/extensions/gsd/git-service.js +4 -4
  31. package/dist/resources/extensions/gsd/guided-flow-queue.js +66 -5
  32. package/dist/resources/extensions/gsd/health-widget.js +55 -29
  33. package/dist/resources/extensions/gsd/layout-policy.js +3 -1
  34. package/dist/resources/extensions/gsd/markdown-renderer.js +8 -9
  35. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +44 -21
  36. package/dist/resources/extensions/gsd/migration-auto-check.js +22 -0
  37. package/dist/resources/extensions/gsd/milestone-ids.js +32 -2
  38. package/dist/resources/extensions/gsd/milestone-implementation-evidence.js +26 -20
  39. package/dist/resources/extensions/gsd/prompts/code-review.md +6 -4
  40. package/dist/resources/extensions/gsd/quick.js +45 -2
  41. package/dist/resources/extensions/gsd/session-forensics.js +11 -1
  42. package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -1
  43. package/dist/resources/extensions/gsd/state/derive/cache.js +28 -0
  44. package/dist/resources/extensions/gsd/state/derive/db-open.js +39 -0
  45. package/dist/resources/extensions/gsd/state/derive/from-db.js +452 -0
  46. package/dist/resources/extensions/gsd/state/derive/index.js +75 -0
  47. package/dist/resources/extensions/gsd/state/derive/interrupted-work.js +21 -0
  48. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +45 -2
  49. package/dist/resources/extensions/gsd/state-reconciliation/index.js +48 -23
  50. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +32 -28
  51. package/dist/resources/extensions/gsd/state.js +12 -611
  52. package/dist/resources/extensions/gsd/tools/complete-slice.js +2 -2
  53. package/dist/resources/extensions/gsd/tools/complete-task.js +43 -14
  54. package/dist/resources/extensions/gsd/tools/exec-tool.js +7 -2
  55. package/dist/resources/extensions/gsd/unit-context-composer.js +23 -7
  56. package/dist/resources/extensions/gsd/unit-registry.js +32 -4
  57. package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +33 -3
  58. package/dist/resources/extensions/gsd/validation-block-guard.js +9 -4
  59. package/dist/resources/extensions/gsd/workflow-projections.js +19 -14
  60. package/dist/resources/extensions/gsd/workspace-git-preflight.js +30 -1
  61. package/dist/resources/extensions/gsd/worktree-manager.js +44 -2
  62. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  63. package/dist/web/standalone/.next/BUILD_ID +1 -1
  64. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  65. package/dist/web/standalone/.next/build-manifest.json +3 -3
  66. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  67. package/dist/web/standalone/.next/react-loadable-manifest.json +9 -9
  68. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  69. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  70. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  74. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  78. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  79. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  87. package/dist/web/standalone/.next/server/app/index.html +1 -1
  88. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  89. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  90. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  91. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  96. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  98. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  99. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  100. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  101. package/dist/web/standalone/.next/static/chunks/{2659.b7b129ee6a769448.js → 2659.58e950899a9bb82f.js} +1 -1
  102. package/dist/web/standalone/.next/static/chunks/2772.a7c1fcc69a4685ef.js +1 -0
  103. package/dist/web/standalone/.next/static/chunks/{3616.3c60753b8ffcbd2e.js → 3616.61a2af74bb8833c8.js} +1 -1
  104. package/dist/web/standalone/.next/static/chunks/{4283.8e446784528ed9dc.js → 4283.d0d9e0a955e441cb.js} +1 -1
  105. package/dist/web/standalone/.next/static/chunks/{5826.a46ecdd1cfe8dabc.js → 5826.5421d66c72b9f34e.js} +1 -1
  106. package/dist/web/standalone/.next/static/chunks/{8785.481aa5869991b760.js → 8785.e29b3134cab1d153.js} +1 -1
  107. package/dist/web/standalone/.next/static/chunks/8937.640dc9c2aaa1dfad.js +10 -0
  108. package/dist/web/standalone/.next/static/chunks/app/{page-6644fc6ee8ca1247.js → page-72a856634ad14c10.js} +1 -1
  109. package/dist/web/standalone/.next/static/chunks/webpack-9c401904f87ded16.js +1 -0
  110. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  111. package/package.json +1 -1
  112. package/packages/cloud-mcp-gateway/package.json +2 -2
  113. package/packages/contracts/dist/workflow.d.ts +1 -0
  114. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  115. package/packages/contracts/dist/workflow.js +2 -0
  116. package/packages/contracts/dist/workflow.js.map +1 -1
  117. package/packages/contracts/package.json +1 -1
  118. package/packages/daemon/package.json +4 -4
  119. package/packages/gsd-agent-core/dist/agent-session.d.ts +1 -0
  120. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  121. package/packages/gsd-agent-core/dist/agent-session.js +3 -0
  122. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  123. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts +41 -0
  124. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts.map +1 -0
  125. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js +62 -0
  126. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js.map +1 -0
  127. package/packages/gsd-agent-core/dist/index.d.ts +2 -0
  128. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  129. package/packages/gsd-agent-core/dist/index.js +2 -0
  130. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  131. package/packages/gsd-agent-core/dist/session/agent-session-events.js +1 -1
  132. package/packages/gsd-agent-core/dist/session/agent-session-events.js.map +1 -1
  133. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +1 -0
  134. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  135. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  136. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts +5 -0
  137. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  138. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +60 -3
  139. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  140. package/packages/gsd-agent-core/dist/transcript-store.d.ts +58 -0
  141. package/packages/gsd-agent-core/dist/transcript-store.d.ts.map +1 -0
  142. package/packages/gsd-agent-core/dist/transcript-store.js +132 -0
  143. package/packages/gsd-agent-core/dist/transcript-store.js.map +1 -0
  144. package/packages/gsd-agent-core/package.json +5 -5
  145. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  146. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  147. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +25 -11
  148. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  149. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts +4 -0
  150. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts.map +1 -0
  151. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js +7 -0
  152. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js.map +1 -0
  153. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -24
  154. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  155. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -829
  156. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  157. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts +58 -0
  158. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts.map +1 -0
  159. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js +312 -0
  160. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js.map +1 -0
  161. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts +31 -0
  162. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts.map +1 -0
  163. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js +130 -0
  164. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js.map +1 -0
  165. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts +15 -0
  166. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -0
  167. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +258 -0
  168. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -0
  169. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts +13 -0
  170. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts.map +1 -0
  171. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js +118 -0
  172. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js.map +1 -0
  173. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +9 -0
  174. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  175. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js +1 -1
  176. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  177. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts +54 -0
  178. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts.map +1 -0
  179. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js +20 -0
  180. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js.map +1 -0
  181. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +4 -1
  182. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  183. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +9 -0
  184. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  185. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts +56 -0
  186. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts.map +1 -0
  187. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js +44 -0
  188. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js.map +1 -0
  189. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts +5 -0
  190. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts.map +1 -0
  191. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js +77 -0
  192. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js.map +1 -0
  193. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  194. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +18 -0
  195. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  196. package/packages/gsd-agent-modes/package.json +7 -7
  197. package/packages/mcp-server/README.md +1 -1
  198. package/packages/mcp-server/dist/server.d.ts +1 -1
  199. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  200. package/packages/mcp-server/dist/server.js +3 -3
  201. package/packages/mcp-server/dist/server.js.map +1 -1
  202. package/packages/mcp-server/dist/workflow-tools.d.ts +13 -1
  203. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  204. package/packages/mcp-server/dist/workflow-tools.js +34 -20
  205. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  206. package/packages/mcp-server/package.json +4 -4
  207. package/packages/native/package.json +1 -1
  208. package/packages/pi-agent-core/package.json +1 -1
  209. package/packages/pi-ai/package.json +1 -1
  210. package/packages/pi-coding-agent/README.md +3 -2
  211. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts +9 -0
  212. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts.map +1 -0
  213. package/packages/pi-coding-agent/dist/core/session-manager-context.js +94 -0
  214. package/packages/pi-coding-agent/dist/core/session-manager-context.js.map +1 -0
  215. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts +8 -0
  216. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts.map +1 -0
  217. package/packages/pi-coding-agent/dist/core/session-manager-list.js +244 -0
  218. package/packages/pi-coding-agent/dist/core/session-manager-list.js.map +1 -0
  219. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts +12 -0
  220. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts.map +1 -0
  221. package/packages/pi-coding-agent/dist/core/session-manager-migration.js +84 -0
  222. package/packages/pi-coding-agent/dist/core/session-manager-migration.js.map +1 -0
  223. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +135 -0
  224. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -0
  225. package/packages/pi-coding-agent/dist/core/session-manager-types.js +2 -0
  226. package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -0
  227. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +6 -154
  228. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  229. package/packages/pi-coding-agent/dist/core/session-manager.js +22 -459
  230. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  231. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts +75 -75
  232. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts.map +1 -1
  233. package/packages/pi-coding-agent/dist/theme/theme-schema.js +1 -1
  234. package/packages/pi-coding-agent/dist/theme/theme-schema.js.map +1 -1
  235. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  236. package/packages/pi-coding-agent/dist/theme/theme.js +11 -7
  237. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  238. package/packages/pi-coding-agent/package.json +7 -7
  239. package/packages/pi-tui/package.json +2 -2
  240. package/packages/rpc-client/package.json +2 -2
  241. package/pkg/dist/theme/theme-schema.d.ts +75 -75
  242. package/pkg/dist/theme/theme-schema.d.ts.map +1 -1
  243. package/pkg/dist/theme/theme-schema.js +1 -1
  244. package/pkg/dist/theme/theme-schema.js.map +1 -1
  245. package/pkg/dist/theme/theme.d.ts.map +1 -1
  246. package/pkg/dist/theme/theme.js +11 -7
  247. package/pkg/dist/theme/theme.js.map +1 -1
  248. package/pkg/package.json +1 -1
  249. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +20 -2
  250. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +80 -0
  251. package/src/resources/extensions/google-cli/stream-adapter.ts +106 -19
  252. package/src/resources/extensions/gsd/artifact-verification.ts +464 -0
  253. package/src/resources/extensions/gsd/auto/orchestrator.ts +25 -11
  254. package/src/resources/extensions/gsd/auto/session.ts +5 -0
  255. package/src/resources/extensions/gsd/auto-artifact-paths.ts +47 -1
  256. package/src/resources/extensions/gsd/auto-dispatch.ts +21 -23
  257. package/src/resources/extensions/gsd/auto-prompts.ts +38 -12
  258. package/src/resources/extensions/gsd/auto-recovery.ts +10 -508
  259. package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -5
  260. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +3 -2
  261. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +125 -12
  262. package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +43 -0
  263. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +6 -1
  264. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -0
  265. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +11 -19
  266. package/src/resources/extensions/gsd/bootstrap/system-context.ts +52 -18
  267. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +74 -10
  268. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +1 -1
  269. package/src/resources/extensions/gsd/commands-context.ts +18 -1
  270. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +14 -9
  271. package/src/resources/extensions/gsd/commands-worktree.ts +12 -10
  272. package/src/resources/extensions/gsd/dashboard-overlay.ts +32 -3
  273. package/src/resources/extensions/gsd/db/queries.ts +79 -0
  274. package/src/resources/extensions/gsd/db-workspace.ts +61 -3
  275. package/src/resources/extensions/gsd/doctor-providers.ts +103 -9
  276. package/src/resources/extensions/gsd/exec-sandbox.ts +49 -9
  277. package/src/resources/extensions/gsd/forensics.ts +2 -33
  278. package/src/resources/extensions/gsd/git-service.ts +5 -5
  279. package/src/resources/extensions/gsd/guided-flow-queue.ts +89 -4
  280. package/src/resources/extensions/gsd/health-widget.ts +69 -32
  281. package/src/resources/extensions/gsd/layout-policy.ts +2 -1
  282. package/src/resources/extensions/gsd/markdown-renderer.ts +8 -11
  283. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +51 -19
  284. package/src/resources/extensions/gsd/migration-auto-check.ts +23 -0
  285. package/src/resources/extensions/gsd/milestone-ids.ts +31 -2
  286. package/src/resources/extensions/gsd/milestone-implementation-evidence.ts +35 -21
  287. package/src/resources/extensions/gsd/prompts/code-review.md +6 -4
  288. package/src/resources/extensions/gsd/quick.ts +43 -2
  289. package/src/resources/extensions/gsd/session-forensics.ts +11 -1
  290. package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -1
  291. package/src/resources/extensions/gsd/state/derive/cache.ts +46 -0
  292. package/src/resources/extensions/gsd/state/derive/db-open.ts +45 -0
  293. package/src/resources/extensions/gsd/state/derive/from-db.ts +561 -0
  294. package/src/resources/extensions/gsd/state/derive/index.ts +104 -0
  295. package/src/resources/extensions/gsd/state/derive/interrupted-work.ts +31 -0
  296. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +81 -7
  297. package/src/resources/extensions/gsd/state-reconciliation/index.ts +50 -24
  298. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +43 -28
  299. package/src/resources/extensions/gsd/state.ts +32 -732
  300. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +98 -1
  301. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +111 -1
  302. package/src/resources/extensions/gsd/tests/commands-context.test.ts +26 -0
  303. package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +1 -0
  304. package/src/resources/extensions/gsd/tests/commands-worktree-clean.test.ts +80 -0
  305. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +11 -0
  306. package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +48 -8
  307. package/src/resources/extensions/gsd/tests/complete-task.test.ts +75 -0
  308. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +55 -2
  309. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +26 -1
  310. package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +70 -2
  311. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +107 -0
  312. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +38 -0
  313. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +45 -1
  314. package/src/resources/extensions/gsd/tests/forensics-error-filter.test.ts +88 -0
  315. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +42 -0
  316. package/src/resources/extensions/gsd/tests/health-widget.test.ts +268 -3
  317. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +119 -1
  318. package/src/resources/extensions/gsd/tests/integration/queue-active-milestone-context-budget.test.ts +93 -0
  319. package/src/resources/extensions/gsd/tests/integration/quick-branch-lifecycle.test.ts +56 -9
  320. package/src/resources/extensions/gsd/tests/knowledge-cold-start.test.ts +14 -0
  321. package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +78 -0
  322. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +70 -0
  323. package/src/resources/extensions/gsd/tests/orchestrator-logs.test.ts +43 -1
  324. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +26 -0
  325. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +2 -1
  326. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +1 -1
  327. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +54 -1
  328. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +50 -14
  329. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +195 -1
  330. package/src/resources/extensions/gsd/tests/read-uat-gate-verdict.test.ts +185 -0
  331. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +87 -0
  332. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +7 -0
  333. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +56 -0
  334. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +191 -0
  335. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +151 -0
  336. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +26 -0
  337. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +193 -14
  338. package/src/resources/extensions/gsd/tests/unmerged-milestone-guard.test.ts +25 -0
  339. package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +79 -0
  340. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +66 -0
  341. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +151 -2
  342. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +39 -0
  343. package/src/resources/extensions/gsd/tools/complete-slice.ts +2 -2
  344. package/src/resources/extensions/gsd/tools/complete-task.ts +53 -15
  345. package/src/resources/extensions/gsd/tools/exec-tool.ts +7 -3
  346. package/src/resources/extensions/gsd/unit-context-composer.ts +33 -7
  347. package/src/resources/extensions/gsd/unit-registry.ts +32 -4
  348. package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +41 -5
  349. package/src/resources/extensions/gsd/validation-block-guard.ts +13 -7
  350. package/src/resources/extensions/gsd/workflow-projections.ts +20 -14
  351. package/src/resources/extensions/gsd/workspace-git-preflight.ts +31 -0
  352. package/src/resources/extensions/gsd/worktree-manager.ts +41 -1
  353. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +0 -1
  354. package/dist/web/standalone/.next/static/chunks/796.e0bdc932325d7e03.js +0 -10
  355. package/dist/web/standalone/.next/static/chunks/webpack-f46ea08200a0227e.js +0 -1
  356. /package/dist/web/standalone/.next/static/{BTKtGFF1Y-hvVJEGhBRo9 → O7xDYXO0r4zFhIzY1hrWV}/_buildManifest.js +0 -0
  357. /package/dist/web/standalone/.next/static/{BTKtGFF1Y-hvVJEGhBRo9 → O7xDYXO0r4zFhIzY1hrWV}/_ssgManifest.js +0 -0
@@ -21,7 +21,7 @@ import { classifyUatContent, escalatesArtifactUatToBrowser } from "../uat-policy
21
21
  import { invalidateStateCache } from "../state.js";
22
22
  import { renderRoadmapFromDb, roadmapRenderMarksSliceDone } from "../markdown-renderer.js";
23
23
  import { isStaleWrite } from "../auto/turn-epoch.js";
24
- import { flushWorkflowProjections } from "../projection-flush.js";
24
+ import { renderMilestoneShellProjections } from "../workflow-projections.js";
25
25
  import { writeManifest } from "../workflow-manifest.js";
26
26
  import { appendEvent } from "../workflow-events.js";
27
27
  import { logWarning, logError } from "../workflow-logger.js";
@@ -458,7 +458,7 @@ export async function handleCompleteSlice(params, basePath) {
458
458
  // Separate try/catch per step so a projection failure doesn't prevent
459
459
  // the event log entry (critical for worktree reconciliation).
460
460
  try {
461
- await flushWorkflowProjections(artifactBasePath, { milestoneId: params.milestoneId });
461
+ await renderMilestoneShellProjections(artifactBasePath, params.milestoneId);
462
462
  }
463
463
  catch (projErr) {
464
464
  logWarning("tool", `complete-slice projection warning for ${params.milestoneId}/${params.sliceId}: ${projErr.message}`);
@@ -5,13 +5,15 @@
5
5
  *
6
6
  * Validates inputs, writes task row and rendered SUMMARY.md to DB in a
7
7
  * transaction, then renders projections to disk and invalidates caches.
8
- * Projection write failures are reported as stale projections and do not roll
9
- * back committed DB state.
8
+ * If the critical task summary / plan projection write fails, the DB
9
+ * completion is compensated back to pending so DB state does not drift ahead
10
+ * of PLAN.md.
10
11
  */
11
- import { existsSync } from "node:fs";
12
+ import { existsSync, unlinkSync } from "node:fs";
12
13
  import { join } from "node:path";
13
14
  import { isClosedStatus } from "../status-guards.js";
14
15
  import { transaction, insertMilestone, insertSlice, insertTask, insertVerificationEvidence, getMilestone, getSlice, getTask, updateTaskStatus, deleteVerificationEvidence, saveGateResult, getPendingGatesForTurn, } from "../gsd-db.js";
16
+ import { getWorkflowDatabasePath, ensureWorkflowDbAtPath } from "../db-workspace.js";
15
17
  import { getGatesForTurn } from "../gate-registry.js";
16
18
  import { gsdProjectionRoot, clearPathCache, resolveMilestonePath, resolveSlicePath } from "../paths.js";
17
19
  import { resolveCanonicalMilestoneRoot } from "../worktree-manager.js";
@@ -19,8 +21,7 @@ import { checkOwnership, taskUnitKey } from "../unit-ownership.js";
19
21
  import { saveFile, clearParseCache } from "../files.js";
20
22
  import { invalidateStateCache } from "../state.js";
21
23
  import { renderPlanCheckboxes } from "../markdown-renderer.js";
22
- import { renderSummaryContent } from "../workflow-projections.js";
23
- import { flushWorkflowProjections } from "../projection-flush.js";
24
+ import { renderMilestoneShellProjections, renderSummaryContent, } from "../workflow-projections.js";
24
25
  import { writeManifest } from "../workflow-manifest.js";
25
26
  import { appendEvent } from "../workflow-events.js";
26
27
  import { logWarning, logError } from "../workflow-logger.js";
@@ -60,7 +61,7 @@ async function repairMissingTaskSummaryProjection(artifactBasePath, taskRow) {
60
61
  clearPathCache();
61
62
  clearParseCache();
62
63
  try {
63
- await flushWorkflowProjections(artifactBasePath, { milestoneId: taskRow.milestone_id });
64
+ await renderMilestoneShellProjections(artifactBasePath, taskRow.milestone_id);
64
65
  }
65
66
  catch (projErr) {
66
67
  logWarning("tool", `complete-task repair projection warning: ${projErr.message}`);
@@ -181,6 +182,7 @@ export async function handleCompleteTask(params, basePath) {
181
182
  let guardError = null;
182
183
  let summaryMd = "";
183
184
  let repairTaskSummaryRow = null;
185
+ const rollbackDbPath = getWorkflowDatabasePath();
184
186
  // ── ADR-011 Phase 2: validate escalation payload BEFORE any side effects ─
185
187
  // Building the artifact runs the full shape validation (2-4 options, unique
186
188
  // ids, recommendation references a real id). If the payload is malformed
@@ -317,20 +319,48 @@ export async function handleCompleteTask(params, basePath) {
317
319
  if (guardError) {
318
320
  return { error: guardError };
319
321
  }
320
- let projectionStale = false;
321
322
  // Resolve and write summary to disk
322
323
  const summaryPath = taskSummaryPath(artifactBasePath, params.milestoneId, params.sliceId, params.taskId);
323
324
  try {
324
325
  await saveFile(summaryPath, summaryMd);
325
326
  // Toggle or regenerate the plan projection from DB. Missing projection
326
327
  // files are rebuilt by the renderer instead of being skipped.
327
- await renderPlanCheckboxes(artifactBasePath, params.milestoneId, params.sliceId);
328
+ if (!ensureWorkflowDbAtPath(rollbackDbPath)) {
329
+ throw new Error(`database unavailable before plan projection render for ${params.milestoneId}/${params.sliceId}`);
330
+ }
331
+ const wrotePlan = await renderPlanCheckboxes(artifactBasePath, params.milestoneId, params.sliceId);
332
+ if (!wrotePlan) {
333
+ throw new Error(`plan projection write returned false for ${params.milestoneId}/${params.sliceId}`);
334
+ }
328
335
  }
329
336
  catch (renderErr) {
330
- projectionStale = true;
331
- logWarning("projection", `complete_task projection write failed for ${params.milestoneId}/${params.sliceId}/${params.taskId}; DB completion remains committed`, {
332
- error: renderErr.message,
333
- });
337
+ logWarning("projection", `complete_task projection write failed for ${params.milestoneId}/${params.sliceId}/${params.taskId}`, { error: renderErr.message });
338
+ let rollbackSucceeded = false;
339
+ try {
340
+ ensureWorkflowDbAtPath(rollbackDbPath);
341
+ deleteVerificationEvidence(params.milestoneId, params.sliceId, params.taskId);
342
+ updateTaskStatus(params.milestoneId, params.sliceId, params.taskId, "pending");
343
+ invalidateStateCache();
344
+ rollbackSucceeded = true;
345
+ }
346
+ catch (rollbackErr) {
347
+ logWarning("projection", `complete_task rollback failed after projection write failure for ${params.milestoneId}/${params.sliceId}/${params.taskId}: ${rollbackErr.message}`);
348
+ }
349
+ try {
350
+ if (existsSync(summaryPath))
351
+ unlinkSync(summaryPath);
352
+ }
353
+ catch (summaryErr) {
354
+ logWarning("projection", `complete_task could not remove SUMMARY.md after projection write failure for ${params.milestoneId}/${params.sliceId}/${params.taskId}: ${summaryErr.message}`);
355
+ }
356
+ // Clear path/parse caches regardless of rollback outcome so stale
357
+ // entries from the failed write attempt don't leak into subsequent calls.
358
+ clearPathCache();
359
+ clearParseCache();
360
+ const returnMsg = rollbackSucceeded
361
+ ? `complete_task projection write failed for ${params.milestoneId}/${params.sliceId}/${params.taskId}; rolled completion back to pending`
362
+ : `complete_task projection write failed for ${params.milestoneId}/${params.sliceId}/${params.taskId}; rollback also failed — task may remain complete with stale plan`;
363
+ return { error: returnMsg };
334
364
  }
335
365
  // ── Close gates owned by execute-task (Q5/Q6/Q7) for this task ────────
336
366
  // Each gate id maps to a specific params field via taskGateFieldForId.
@@ -435,7 +465,7 @@ export async function handleCompleteTask(params, basePath) {
435
465
  // Separate try/catch per step so a projection failure doesn't prevent
436
466
  // the event log entry (critical for worktree reconciliation).
437
467
  try {
438
- await flushWorkflowProjections(artifactBasePath, { milestoneId: params.milestoneId });
468
+ await renderMilestoneShellProjections(artifactBasePath, params.milestoneId);
439
469
  }
440
470
  catch (projErr) {
441
471
  logWarning("tool", `complete-task projection warning: ${projErr.message}`);
@@ -465,6 +495,5 @@ export async function handleCompleteTask(params, basePath) {
465
495
  milestoneId: params.milestoneId,
466
496
  summaryPath,
467
497
  ...(escalationMetadata ? { escalation: escalationMetadata } : {}),
468
- ...(projectionStale ? { stale: true } : {}),
469
498
  };
470
499
  }
@@ -144,7 +144,7 @@ export async function executeGsdExec(params, deps) {
144
144
  if (bashReferencesProjectRootOutsideWorktree(script, deps.baseDir)) {
145
145
  return paramError("script references the original project root while running inside a milestone worktree; use the active worktree path or relative paths");
146
146
  }
147
- const opts = buildExecOptions(deps.baseDir, deps.preferences?.context_mode, { env: deps.env, now: deps.now, generateId: deps.generateId });
147
+ const opts = buildExecOptions(deps.baseDir, deps.preferences?.context_mode, { env: deps.env, now: deps.now, generateId: deps.generateId, signal: deps.signal });
148
148
  const run = deps.run ?? runExecSandbox;
149
149
  try {
150
150
  const result = await run({
@@ -235,6 +235,7 @@ function formatResult(result) {
235
235
  exit_code: result.exit_code,
236
236
  signal: result.signal,
237
237
  timed_out: result.timed_out,
238
+ aborted: result.aborted === true,
238
239
  force_resolved: result.force_resolved,
239
240
  duration_ms: result.duration_ms,
240
241
  stdout_bytes: result.stdout_bytes,
@@ -245,12 +246,16 @@ function formatResult(result) {
245
246
  stderr_path: result.stderr_path,
246
247
  meta_path: result.meta_path,
247
248
  },
248
- isError: result.timed_out || result.signal !== null || result.exit_code !== 0,
249
+ isError: result.aborted === true || result.timed_out || result.signal !== null || result.exit_code !== 0,
249
250
  };
250
251
  }
251
252
  function formatExit(result) {
252
253
  // force_resolved means a non-closing (D-state) child was force-resolved past its
253
254
  // hard deadline rather than observed exiting; distinguish it from a clean timeout.
255
+ if (result.aborted && result.force_resolved)
256
+ return "aborted(force-killed)";
257
+ if (result.aborted)
258
+ return "aborted";
254
259
  if (result.force_resolved)
255
260
  return "timeout(force-killed)";
256
261
  if (result.timed_out)
@@ -92,13 +92,27 @@ const CONTEXT_MODE_GUIDANCE_BY_LANE = {
92
92
  orchestration: "Use `gsd_resume` before resuming orchestration, `gsd_exec_search` to reuse prior runs, and `gsd_exec` for noisy coordination checks.",
93
93
  docs: "Use `gsd_resume` for prior context, `gsd_exec_search` for saved evidence, and `gsd_exec` for noisy doc validation commands.",
94
94
  };
95
- // Per-unit overrides win over the lane default. run-uat's tool contract
96
- // forbids `gsd_exec`/`gsd_exec_search` (acceptance evidence must flow through
97
- // `gsd_uat_exec`) and Claude Code dispatch strips the tools entirely, so the
98
- // shared verification-lane guidance would steer the agent into calling an
99
- // unavailable tool.
100
- const CONTEXT_MODE_GUIDANCE_BY_UNIT = {
95
+ // Per-unit overrides win over the lane default. Some units intentionally run
96
+ // with narrower tool contracts than their shared Context Mode lane, so their
97
+ // guidance must name only tools the unit can actually call.
98
+ export const CONTEXT_MODE_GUIDANCE_BY_UNIT = {
99
+ "discuss-milestone": "Use `ask_user_questions` to continue the milestone interview, then persist outcomes with `gsd_summary_save`, `gsd_decision_save`, `gsd_requirement_save`, `gsd_requirement_update`, `gsd_plan_milestone`, or `gsd_milestone_generate_id` as appropriate.",
100
+ "discuss-slice": "Use `ask_user_questions` to continue the slice interview, then persist outcomes with `gsd_summary_save` or `gsd_decision_save` as appropriate.",
101
+ "discuss-project": "Use `ask_user_questions` to continue the project interview, then persist outcomes with `gsd_summary_save`, `gsd_decision_save`, or `gsd_requirement_save` as appropriate.",
102
+ "discuss-requirements": "Use `ask_user_questions` to continue the requirements interview, then persist outcomes with `gsd_requirement_save` or `gsd_summary_save` as appropriate.",
103
+ "replan-slice": "Use `gsd_replan_slice` to persist the revised slice plan, and `gsd_decision_save` for planning decisions that need durable rationale.",
104
+ "reassess-roadmap": "Use `gsd_milestone_status` to inspect current milestone state, then `gsd_reassess_roadmap` to persist the roadmap reassessment.",
101
105
  "run-uat": "Use `gsd_uat_exec` for acceptance checks so evidence is typed as UAT-owned, and `gsd_resume` after compaction or resume.",
106
+ "research-project": "Dispatch parallel scout subagents for stack, features, architecture, and pitfalls research; each writes one file under `.gsd/research/` (`STACK.md`, `FEATURES.md`, `ARCHITECTURE.md`, `PITFALLS.md`).",
107
+ "gate-evaluate": "Use `subagent` to dispatch tester agents, then persist each gate with `gsd_save_gate_result`; rely on testers for verification evidence.",
108
+ };
109
+ // Per-unit guidance for the nested render mode (renderMode: "nested"), used when this
110
+ // unit's Context Mode line is embedded into a subagent prompt — e.g. the tester prompts
111
+ // dispatched by gate-evaluate. Must instruct the subagent on what IT should do, not
112
+ // re-state the parent coordinator's dispatch instructions. Falls back to
113
+ // CONTEXT_MODE_GUIDANCE_BY_UNIT then the lane default when no nested entry exists.
114
+ export const CONTEXT_MODE_NESTED_GUIDANCE_BY_UNIT = {
115
+ "gate-evaluate": "Run verification checks to answer the gate question, then persist the verdict with `gsd_save_gate_result`.",
102
116
  };
103
117
  /**
104
118
  * Render the Context Mode instruction lane for a unit type. Unknown unit
@@ -112,7 +126,9 @@ export function composeContextModeInstructions(unitType, opts) {
112
126
  if (!manifest || manifest.contextMode === "none")
113
127
  return "";
114
128
  const lane = CONTEXT_MODE_LANE_LABELS[manifest.contextMode];
115
- const guidance = CONTEXT_MODE_GUIDANCE_BY_UNIT[unitType] ?? CONTEXT_MODE_GUIDANCE_BY_LANE[manifest.contextMode];
129
+ const guidance = (opts.renderMode === "nested" ? CONTEXT_MODE_NESTED_GUIDANCE_BY_UNIT[unitType] : undefined)
130
+ ?? CONTEXT_MODE_GUIDANCE_BY_UNIT[unitType]
131
+ ?? CONTEXT_MODE_GUIDANCE_BY_LANE[manifest.contextMode];
116
132
  if (opts.renderMode === "nested") {
117
133
  return `Context Mode (${lane} lane): ${guidance}`;
118
134
  }
@@ -51,7 +51,13 @@ export const UNIT_REGISTRY = {
51
51
  scopeClass: "standard",
52
52
  phaseChain: ["research"],
53
53
  toolContract: {
54
- allowedGsdTools: ["gsd_summary_save", "gsd_decision_save"],
54
+ allowedGsdTools: [
55
+ "gsd_summary_save",
56
+ "gsd_decision_save",
57
+ "gsd_exec",
58
+ "gsd_exec_search",
59
+ "gsd_resume",
60
+ ],
55
61
  requiredWorkflowTools: ["gsd_summary_save"],
56
62
  },
57
63
  },
@@ -107,7 +113,15 @@ export const UNIT_REGISTRY = {
107
113
  scopeClass: "section-close",
108
114
  phaseChain: ["validation", "planning"],
109
115
  toolContract: {
110
- allowedGsdTools: ["gsd_milestone_status", "gsd_validate_milestone", "gsd_reassess_roadmap", "subagent"],
116
+ allowedGsdTools: [
117
+ "gsd_milestone_status",
118
+ "gsd_exec",
119
+ "gsd_exec_search",
120
+ "gsd_resume",
121
+ "gsd_validate_milestone",
122
+ "gsd_reassess_roadmap",
123
+ "subagent",
124
+ ],
111
125
  requiredWorkflowTools: ["gsd_milestone_status", "gsd_validate_milestone", "gsd_reassess_roadmap"],
112
126
  },
113
127
  },
@@ -118,6 +132,9 @@ export const UNIT_REGISTRY = {
118
132
  toolContract: {
119
133
  allowedGsdTools: [
120
134
  "gsd_milestone_status",
135
+ "gsd_exec",
136
+ "gsd_exec_search",
137
+ "gsd_resume",
121
138
  "gsd_requirement_update",
122
139
  "gsd_summary_save",
123
140
  "gsd_complete_milestone",
@@ -197,6 +214,8 @@ export const UNIT_REGISTRY = {
197
214
  allowedGsdTools: [
198
215
  "gsd_milestone_status",
199
216
  "gsd_exec",
217
+ "gsd_exec_search",
218
+ "gsd_resume",
200
219
  "gsd_slice_complete",
201
220
  "gsd_task_reopen",
202
221
  "gsd_replan_slice",
@@ -279,7 +298,13 @@ export const UNIT_REGISTRY = {
279
298
  scopeClass: "execute-task",
280
299
  phaseChain: ["execution"],
281
300
  toolContract: {
282
- allowedGsdTools: ["gsd_task_complete", "gsd_summary_save", "gsd_decision_save"],
301
+ allowedGsdTools: [
302
+ "gsd_milestone_status",
303
+ "gsd_task_complete",
304
+ "gsd_exec",
305
+ "gsd_summary_save",
306
+ "gsd_decision_save",
307
+ ],
283
308
  requiredWorkflowTools: ["gsd_task_complete", "gsd_summary_save"],
284
309
  },
285
310
  },
@@ -366,12 +391,15 @@ export const UNIT_REGISTRY = {
366
391
  requiredWorkflowTools: ["ask_user_questions"],
367
392
  },
368
393
  },
394
+ // research-project dispatches 4 parallel scout subagents (Task calls); each scout
395
+ // writes one file under .gsd/research/ directly. The parent coordinator does not
396
+ // call gsd_summary_save or gsd_decision_save — the scouts own their own output.
369
397
  "research-project": {
370
398
  kind: "primary",
371
399
  scopeClass: "standard",
372
400
  phaseChain: ["research"],
373
401
  toolContract: {
374
- allowedGsdTools: ["gsd_summary_save", "gsd_decision_save"],
402
+ allowedGsdTools: [],
375
403
  requiredWorkflowTools: [],
376
404
  },
377
405
  },
@@ -1,12 +1,12 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: Block new workflow entry when completed milestone branches are still unmerged.
3
+ import { execFileSync } from "node:child_process";
3
4
  import { nativeBranchExists, nativeDetectMainBranch, nativeDiffNumstat, nativeIsAncestor, } from "./native-git-bridge.js";
4
5
  import { autoWorktreeBranch } from "./auto-worktree.js";
5
6
  import { ensureDbOpen } from "./bootstrap/dynamic-tools.js";
6
7
  import { getAllMilestones } from "./gsd-db.js";
7
8
  import { resolveMilestoneIntegrationBranch } from "./git-service.js";
8
9
  import { loadEffectiveGSDPreferences } from "./preferences.js";
9
- import { captureRootDirtySnapshot } from "./root-write-leak-guard.js";
10
10
  import { isClosedStatus } from "./status-guards.js";
11
11
  const BLOCKED_COMMANDS = new Set([
12
12
  "auto",
@@ -49,6 +49,33 @@ const UNMERGED_SAFE_PARALLEL_SUBCOMMANDS = new Set([
49
49
  function isRuntimePath(path) {
50
50
  return path === ".gsd" || path.startsWith(".gsd/");
51
51
  }
52
+ function captureDirtyPathStatusSnapshot(rootPath) {
53
+ const snapshot = new Map();
54
+ let status = "";
55
+ try {
56
+ status = execFileSync("git", ["status", "--porcelain", "--untracked-files=all"], {
57
+ cwd: rootPath,
58
+ stdio: ["ignore", "pipe", "pipe"],
59
+ encoding: "utf-8",
60
+ });
61
+ }
62
+ catch {
63
+ return snapshot;
64
+ }
65
+ for (const line of status.split("\n")) {
66
+ if (!line.trim())
67
+ continue;
68
+ const code = line.slice(0, 2);
69
+ const path = line.slice(3).replace(/^"|"$/g, "");
70
+ if (!path || isRuntimePath(path))
71
+ continue;
72
+ snapshot.set(path, {
73
+ path,
74
+ status: code.trim() || code,
75
+ });
76
+ }
77
+ return snapshot;
78
+ }
52
79
  function formatCommandLabel(attemptedCommand) {
53
80
  const trimmed = attemptedCommand.trim();
54
81
  return trimmed ? `/gsd ${trimmed}` : "/gsd";
@@ -109,7 +136,7 @@ export function isUnmergedMilestoneAllowedCommand(trimmed) {
109
136
  export async function findUnmergedCompletedMilestones(base) {
110
137
  await ensureDbOpen(base);
111
138
  const blockers = [];
112
- const dirtyByPath = captureRootDirtySnapshot(base);
139
+ let dirtyByPath = null;
113
140
  for (const milestone of getAllMilestones()) {
114
141
  if (!isClosedStatus(milestone.status))
115
142
  continue;
@@ -134,13 +161,16 @@ export async function findUnmergedCompletedMilestones(base) {
134
161
  const uniqueFiles = [...new Set(files)].sort();
135
162
  if (uniqueFiles.length === 0)
136
163
  continue;
164
+ if (!dirtyByPath)
165
+ dirtyByPath = captureDirtyPathStatusSnapshot(base);
166
+ const dirtySnapshot = dirtyByPath;
137
167
  blockers.push({
138
168
  milestoneId: milestone.id,
139
169
  branch,
140
170
  integrationBranch,
141
171
  files: uniqueFiles,
142
172
  dirtyOverlap: uniqueFiles
143
- .map((path) => dirtyByPath.get(path))
173
+ .map((path) => dirtySnapshot.get(path))
144
174
  .filter((entry) => Boolean(entry)),
145
175
  });
146
176
  }
@@ -5,7 +5,7 @@ import { getAutoWorktreePath, isInAutoWorktree } from "./auto-worktree.js";
5
5
  import { ensureDbOpen } from "./bootstrap/dynamic-tools.js";
6
6
  import { refreshWorkflowDatabaseFromDisk } from "./db-workspace.js";
7
7
  import { getIsolationMode } from "./preferences.js";
8
- import { deriveState } from "./state.js";
8
+ import { deriveState, invalidateStateCache } from "./state.js";
9
9
  import { detectWorktreeName } from "./worktree.js";
10
10
  const VALIDATION_BLOCK_RE = /milestone validation returned needs-(?:attention|remediation)|validation verdict is needs-(?:attention|remediation)/i;
11
11
  const VALIDATION_SAFE_DISPATCH_COMMANDS = new Set([
@@ -116,9 +116,7 @@ export function formatValidationBlockedMessage(state, attemptedCommand = "") {
116
116
  ...blockers,
117
117
  ].join("\n\n");
118
118
  }
119
- export async function getValidationBlockMessageForBase(base, attemptedCommand = "") {
120
- await ensureDbOpen(base);
121
- refreshWorkflowDatabaseFromDisk();
119
+ async function deriveValidationBlockState(base) {
122
120
  let state = await deriveState(base);
123
121
  if (state.activeMilestone &&
124
122
  getIsolationMode(base) === "worktree" &&
@@ -129,5 +127,12 @@ export async function getValidationBlockMessageForBase(base, attemptedCommand =
129
127
  state = await deriveState(wtPath);
130
128
  }
131
129
  }
130
+ return state;
131
+ }
132
+ export async function getValidationBlockMessageForBase(base, attemptedCommand = "") {
133
+ await ensureDbOpen(base);
134
+ refreshWorkflowDatabaseFromDisk();
135
+ invalidateStateCache();
136
+ const state = await deriveValidationBlockState(base);
132
137
  return formatValidationBlockedMessage(state, attemptedCommand);
133
138
  }
@@ -399,15 +399,13 @@ export async function renderStateProjection(basePath) {
399
399
  logWarning("projection", `renderStateProjection failed: ${err.message}`);
400
400
  }
401
401
  }
402
- // ─── renderAllProjections ───────────────────────────────────────────────
402
+ // ─── renderMilestoneShellProjections ─────────────────────────────────────
403
403
  /**
404
- * Regenerate all projection files for a milestone from DB state.
405
- * All calls are wrapped in try/catch projection failure is non-fatal per D-02.
404
+ * Regenerate milestone-level projections (roadmap, top-level views, STATE.md).
405
+ * Does not touch slice PLAN.md or task SUMMARY.md those have authoritative
406
+ * renderers in plan-slice / complete-task.
406
407
  */
407
- export async function renderAllProjections(basePath, milestoneId) {
408
- // Delegate to the authoritative roadmap renderer — the reduced
409
- // renderRoadmapProjection omits sections like ## Boundary Map and would
410
- // clobber the output written by plan-milestone / reassess-roadmap.
408
+ export async function renderMilestoneShellProjections(basePath, milestoneId) {
411
409
  try {
412
410
  await renderRoadmapFromDb(basePath, milestoneId);
413
411
  }
@@ -426,6 +424,20 @@ export async function renderAllProjections(basePath, milestoneId) {
426
424
  catch (err) {
427
425
  logWarning("projection", `renderTopLevelQueueFromDb failed: ${err.message}`);
428
426
  }
427
+ try {
428
+ await renderStateProjection(basePath);
429
+ }
430
+ catch (err) {
431
+ logWarning("projection", `renderStateProjection failed: ${err.message}`);
432
+ }
433
+ }
434
+ // ─── renderAllProjections ───────────────────────────────────────────────
435
+ /**
436
+ * Regenerate all projection files for a milestone from DB state.
437
+ * All calls are wrapped in try/catch — projection failure is non-fatal per D-02.
438
+ */
439
+ export async function renderAllProjections(basePath, milestoneId) {
440
+ await renderMilestoneShellProjections(basePath, milestoneId);
429
441
  // Query all slices for this milestone
430
442
  const sliceRows = getMilestoneSlices(milestoneId);
431
443
  for (const slice of sliceRows) {
@@ -445,13 +457,6 @@ export async function renderAllProjections(basePath, milestoneId) {
445
457
  }
446
458
  }
447
459
  }
448
- // Render STATE.md
449
- try {
450
- await renderStateProjection(basePath);
451
- }
452
- catch (err) {
453
- logWarning("projection", `renderStateProjection failed: ${err.message}`);
454
- }
455
460
  }
456
461
  // ─── regenerateIfMissing ────────────────────────────────────────────────
457
462
  /**
@@ -4,9 +4,11 @@ import { existsSync, realpathSync } from "node:fs";
4
4
  import { getAutoWorktreePath } from "./auto-worktree.js";
5
5
  import { isSafeToAutoResolve } from "./auto-worktree.js";
6
6
  import { ensureDbOpen } from "./bootstrap/dynamic-tools.js";
7
- import { probeGitConflictState, reconcileGitConflictsOnSignal, } from "./git-conflict-state.js";
7
+ import { listMergeStateBlockers, probeGitConflictState, reconcileGitConflictsOnSignal, } from "./git-conflict-state.js";
8
8
  import { deriveState } from "./state.js";
9
9
  import { resolveWorktreeProjectRoot } from "./worktree-root.js";
10
+ const CLEAN_TARGET_CACHE_TTL_MS = 10_000;
11
+ const cleanTargetProbeCache = new Map();
10
12
  function normalizeTargetPath(path) {
11
13
  try {
12
14
  return realpathSync(path);
@@ -77,6 +79,25 @@ function formatBlockReason(severity, conflictedPaths, targets) {
77
79
  }
78
80
  async function ensureTargetGitReady(target) {
79
81
  const fixesApplied = [];
82
+ const cacheKey = normalizeTargetPath(target);
83
+ const cachedCleanAt = cleanTargetProbeCache.get(cacheKey);
84
+ if (cachedCleanAt !== undefined) {
85
+ if (Date.now() - cachedCleanAt < CLEAN_TARGET_CACHE_TTL_MS) {
86
+ // Merge-state markers (MERGE_HEAD, rebase-apply, rebase-merge) are the most
87
+ // common way a repo transitions from clean to dirty within the TTL window,
88
+ // including when a non-git folder is initialized as a repo mid-TTL and a
89
+ // merge immediately introduces conflicts. Check them here — they are pure
90
+ // existsSync calls with no git subprocess — and fall through to a full probe
91
+ // only when markers are present.
92
+ if (listMergeStateBlockers(cacheKey).length === 0) {
93
+ return { ok: true, fixesApplied };
94
+ }
95
+ cleanTargetProbeCache.delete(cacheKey);
96
+ }
97
+ else {
98
+ cleanTargetProbeCache.delete(cacheKey);
99
+ }
100
+ }
80
101
  let probe = probeGitConflictState(target);
81
102
  for (let attempt = 0; attempt < 3 && probe.status === "dirty"; attempt++) {
82
103
  const beforeKey = JSON.stringify({
@@ -95,6 +116,7 @@ async function ensureTargetGitReady(target) {
95
116
  break;
96
117
  }
97
118
  if (probe.status === "unknown") {
119
+ cleanTargetProbeCache.delete(cacheKey);
98
120
  return {
99
121
  ok: false,
100
122
  reason: formatBlockReason("unrecoverable", [], [target]),
@@ -106,6 +128,7 @@ async function ensureTargetGitReady(target) {
106
128
  }
107
129
  const conflictedPaths = productConflictPaths(probe);
108
130
  if (conflictedPaths.length > 0 || probe.checkFailures.length > 0) {
131
+ cleanTargetProbeCache.delete(cacheKey);
109
132
  return {
110
133
  ok: false,
111
134
  reason: formatBlockReason("product-conflicts", conflictedPaths, [target]),
@@ -115,6 +138,12 @@ async function ensureTargetGitReady(target) {
115
138
  targets: [target],
116
139
  };
117
140
  }
141
+ if (probe.status === "clean") {
142
+ cleanTargetProbeCache.set(cacheKey, Date.now());
143
+ }
144
+ else {
145
+ cleanTargetProbeCache.delete(cacheKey);
146
+ }
118
147
  return { ok: true, fixesApplied };
119
148
  }
120
149
  /** Probe and heal a single git root (tests and headless paths). */
@@ -17,12 +17,12 @@
17
17
  * 3. merge() — LLM-guided reconciliation of .gsd/ artifacts back to main
18
18
  * 4. remove() — git worktree remove + branch cleanup
19
19
  */
20
- import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync, statSync } from "node:fs";
20
+ import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync, statSync, unlinkSync } from "node:fs";
21
21
  import { execFileSync } from "node:child_process";
22
22
  import { join, resolve, sep } from "node:path";
23
23
  import { GSDError, GSD_PARSE_ERROR, GSD_STALE_STATE, GSD_LOCK_HELD, GSD_GIT_ERROR, GSD_MERGE_CONFLICT } from "./errors.js";
24
24
  import { logWarning } from "./workflow-logger.js";
25
- import { nativeBranchList, nativeBranchDelete, nativeBranchExists, nativeBranchForceReset, nativeCommit, nativeDetectMainBranch, nativeDiffContent, nativeDiffNameStatus, nativeDiffNumstat, nativeGetCurrentBranch, nativeIsAncestor, nativeLogOneline, nativeMergeSquash, nativeWorktreeAdd, nativeWorktreeList, nativeWorktreePrune, nativeWorktreeRemove, } from "./native-git-bridge.js";
25
+ import { nativeBranchList, nativeBranchDelete, nativeBranchExists, nativeBranchForceReset, nativeCommit, nativeDetectMainBranch, nativeDiffContent, nativeDiffNameStatus, nativeDiffNumstat, nativeGetCurrentBranch, nativeIsAncestor, nativeLogOneline, nativeMergeAbort, nativeMergeSquash, nativeWorktreeAdd, nativeWorktreeList, nativeWorktreePrune, nativeWorktreeRemove, } from "./native-git-bridge.js";
26
26
  import { emitCanonicalRootRedirect } from "./worktree-telemetry.js";
27
27
  import { isGsdWorktreePath, normalizeWorktreePathForCompare, resolveWorktreeProjectRoot, } from "./worktree-root.js";
28
28
  import { MILESTONE_ID_RE } from "./milestone-ids.js";
@@ -37,6 +37,36 @@ function deleteBranchIfPresent(basePath, branch, warningPrefix) {
37
37
  logWarning("worktree", `${warningPrefix}: ${e.message}`);
38
38
  }
39
39
  }
40
+ function cleanupFailedSquashMergeState(basePath) {
41
+ try {
42
+ nativeMergeAbort(basePath);
43
+ }
44
+ catch (e) {
45
+ // Squash conflicts may not create MERGE_HEAD; this is expected.
46
+ logWarning("worktree", `merge abort skipped: ${e.message}`);
47
+ }
48
+ try {
49
+ execFileSync("git", ["reset", "--merge"], {
50
+ cwd: basePath,
51
+ stdio: ["ignore", "pipe", "pipe"],
52
+ encoding: "utf-8",
53
+ });
54
+ }
55
+ catch (e) {
56
+ logWarning("worktree", `failed squash merge reset failed: ${e.message}`);
57
+ }
58
+ const gitDir = resolveGitDir(basePath);
59
+ for (const marker of ["SQUASH_MSG", "MERGE_MSG", "MERGE_MODE", "MERGE_HEAD", "AUTO_MERGE"]) {
60
+ try {
61
+ const markerPath = join(gitDir, marker);
62
+ if (existsSync(markerPath))
63
+ unlinkSync(markerPath);
64
+ }
65
+ catch (e) {
66
+ logWarning("worktree", `failed squash merge marker cleanup failed (${marker}): ${e.message}`);
67
+ }
68
+ }
69
+ }
40
70
  // ─── Path Helpers ──────────────────────────────────────────────────────────
41
71
  function normalizePathForComparison(path) {
42
72
  const normalized = path
@@ -903,6 +933,18 @@ export function mergeWorktreeToMain(basePath, name, commitMessage, branchOverrid
903
933
  }
904
934
  const result = nativeMergeSquash(basePath, branch);
905
935
  if (!result.success) {
936
+ const dirtyWorkingTree = result.conflicts.includes("__dirty_working_tree__");
937
+ if (!dirtyWorkingTree) {
938
+ cleanupFailedSquashMergeState(basePath);
939
+ }
940
+ if (!dirtyWorkingTree && branch.startsWith("milestone/")) {
941
+ try {
942
+ removeWorktree(basePath, name, { branch, deleteBranch: true, force: true });
943
+ }
944
+ catch (e) {
945
+ logWarning("worktree", `failed milestone branch cleanup after squash merge failure: ${e.message}`);
946
+ }
947
+ }
906
948
  throw new GSDError(GSD_MERGE_CONFLICT, `Merge conflicts detected in: ${result.conflicts.join(", ")}`);
907
949
  }
908
950
  nativeCommit(basePath, commitMessage);