gsd-pi 2.80.0-dev.fbe7c8c6f → 2.81.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 (786) hide show
  1. package/README.md +35 -59
  2. package/dist/claude-cli-check.d.ts +30 -0
  3. package/dist/claude-cli-check.js +18 -7
  4. package/dist/cli.js +0 -19
  5. package/dist/headless-query.d.ts +10 -0
  6. package/dist/headless-query.js +6 -4
  7. package/dist/loader-entrypoint.d.ts +8 -0
  8. package/dist/loader-entrypoint.js +27 -0
  9. package/dist/loader.js +2 -11
  10. package/dist/mcp-server.d.ts +1 -0
  11. package/dist/mcp-server.js +6 -3
  12. package/dist/resources/.managed-resources-content-hash +1 -1
  13. package/dist/resources/extensions/claude-code-cli/readiness.js +18 -7
  14. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +40 -3
  15. package/dist/resources/extensions/github-sync/sync.js +4 -1
  16. package/dist/resources/extensions/gsd/auto/contracts.js +2 -0
  17. package/dist/resources/extensions/gsd/auto/loop.js +103 -9
  18. package/dist/resources/extensions/gsd/auto/orchestrator.js +48 -4
  19. package/dist/resources/extensions/gsd/auto/phases.js +282 -132
  20. package/dist/resources/extensions/gsd/auto/resolve.js +29 -0
  21. package/dist/resources/extensions/gsd/auto/run-unit.js +22 -30
  22. package/dist/resources/extensions/gsd/auto/session.js +9 -1
  23. package/dist/resources/extensions/gsd/auto/unit-runner-events.js +7 -0
  24. package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
  25. package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
  26. package/dist/resources/extensions/gsd/auto-dashboard.js +18 -0
  27. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  28. package/dist/resources/extensions/gsd/auto-dispatch.js +16 -0
  29. package/dist/resources/extensions/gsd/auto-post-unit.js +112 -78
  30. package/dist/resources/extensions/gsd/auto-prompts.js +103 -16
  31. package/dist/resources/extensions/gsd/auto-recovery.js +43 -1
  32. package/dist/resources/extensions/gsd/auto-start.js +252 -14
  33. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  34. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  35. package/dist/resources/extensions/gsd/auto-worktree.js +229 -336
  36. package/dist/resources/extensions/gsd/auto.js +264 -86
  37. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +122 -11
  38. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +44 -37
  39. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -10
  40. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +30 -20
  41. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +4 -1
  42. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +6 -4
  43. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +5 -3
  44. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +1 -1
  45. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +330 -54
  46. package/dist/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.js +4 -0
  47. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  48. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +19 -2
  49. package/dist/resources/extensions/gsd/clean-root-preflight.js +24 -6
  50. package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
  51. package/dist/resources/extensions/gsd/commands-config.js +1 -1
  52. package/dist/resources/extensions/gsd/commands-eval-review.js +2 -2
  53. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  54. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  55. package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
  56. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  57. package/dist/resources/extensions/gsd/db/unit-dispatches.js +92 -0
  58. package/dist/resources/extensions/gsd/db-base-schema.js +4 -2
  59. package/dist/resources/extensions/gsd/db-migration-steps.js +6 -0
  60. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  61. package/dist/resources/extensions/gsd/git-service.js +73 -5
  62. package/dist/resources/extensions/gsd/gsd-db.js +46 -13
  63. package/dist/resources/extensions/gsd/guided-flow.js +119 -42
  64. package/dist/resources/extensions/gsd/health-widget.js +3 -0
  65. package/dist/resources/extensions/gsd/init-wizard.js +4 -1
  66. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  67. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  68. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  69. package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
  70. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  71. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  72. package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
  73. package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
  74. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  75. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +22 -17
  76. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  77. package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
  78. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  79. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  80. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  81. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  82. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  83. package/dist/resources/extensions/gsd/quick.js +34 -2
  84. package/dist/resources/extensions/gsd/recovery-classification.js +94 -0
  85. package/dist/resources/extensions/gsd/slice-cadence.js +45 -2
  86. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +15 -9
  87. package/dist/resources/extensions/gsd/state-reconciliation.js +27 -0
  88. package/dist/resources/extensions/gsd/tool-contract.js +50 -0
  89. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -7
  90. package/dist/resources/extensions/gsd/tools/complete-task.js +1 -1
  91. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  92. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  93. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  94. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  95. package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
  96. package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
  97. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  98. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  99. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  100. package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
  101. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  102. package/dist/resources/extensions/gsd/worktree-lifecycle.js +958 -0
  103. package/dist/resources/extensions/gsd/worktree-safety.js +119 -0
  104. package/dist/resources/extensions/gsd/worktree-state-projection.js +317 -0
  105. package/dist/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
  106. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  107. package/dist/web/standalone/.next/BUILD_ID +1 -1
  108. package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
  109. package/dist/web/standalone/.next/build-manifest.json +4 -4
  110. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  111. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  112. package/dist/web/standalone/.next/required-server-files.json +3 -3
  113. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  114. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  124. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  126. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  128. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  140. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  152. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  172. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  182. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  188. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  204. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
  208. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/app/index.html +1 -1
  218. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  219. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  220. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  221. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  222. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  223. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  224. package/dist/web/standalone/.next/server/app/page.js +2 -2
  225. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/app-paths-manifest.json +14 -14
  227. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  228. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  229. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  230. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  231. package/dist/web/standalone/.next/server/middleware.js +3 -3
  232. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  233. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  234. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  235. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  236. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  237. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +10 -0
  238. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-f2a7482d42a5614b.js → page-2f24283c162b6ab3.js} +1 -1
  239. package/dist/web/standalone/.next/static/chunks/app/{layout-a16c7a7ecdf0c2cf.js → layout-9ecfd95f343793f0.js} +1 -1
  240. package/dist/web/standalone/.next/static/chunks/app/page-200592a7f3baf579.js +1 -0
  241. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +1 -0
  242. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +1 -0
  243. package/dist/web/standalone/.next/static/chunks/{webpack-0481f1221120a7c6.js → webpack-de742b64187e13fe.js} +1 -1
  244. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  245. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  246. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  247. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  248. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  249. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  250. package/dist/web/standalone/server.js +1 -1
  251. package/dist/welcome-screen.d.ts +2 -0
  252. package/dist/welcome-screen.js +9 -7
  253. package/package.json +3 -3
  254. package/packages/daemon/package.json +2 -2
  255. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  256. package/packages/mcp-server/dist/workflow-tools.js +22 -17
  257. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  258. package/packages/mcp-server/package.json +2 -2
  259. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  260. package/packages/mcp-server/src/workflow-tools.ts +30 -16
  261. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  262. package/packages/native/package.json +1 -1
  263. package/packages/native/tsconfig.tsbuildinfo +1 -1
  264. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  265. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  266. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  267. package/packages/pi-agent-core/dist/agent.d.ts +9 -2
  268. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  269. package/packages/pi-agent-core/dist/agent.js +43 -11
  270. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  271. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  272. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  273. package/packages/pi-agent-core/dist/index.js +2 -0
  274. package/packages/pi-agent-core/dist/index.js.map +1 -1
  275. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  276. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  277. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  278. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  279. package/packages/pi-agent-core/dist/types.d.ts +31 -0
  280. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  281. package/packages/pi-agent-core/dist/types.js.map +1 -1
  282. package/packages/pi-agent-core/package.json +1 -1
  283. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  284. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  285. package/packages/pi-agent-core/src/agent.ts +52 -11
  286. package/packages/pi-agent-core/src/index.ts +2 -0
  287. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  288. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  289. package/packages/pi-agent-core/src/types.ts +26 -10
  290. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  291. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +35 -13
  292. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  293. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +21 -11
  294. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -1
  295. package/packages/pi-ai/dist/providers/anthropic.d.ts +7 -0
  296. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  297. package/packages/pi-ai/dist/providers/anthropic.js +9 -7
  298. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  299. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +23 -14
  300. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -1
  301. package/packages/pi-ai/dist/types.d.ts +2 -0
  302. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  303. package/packages/pi-ai/dist/types.js.map +1 -1
  304. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +48 -21
  305. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
  306. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +22 -21
  307. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -1
  308. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +22 -21
  309. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -1
  310. package/packages/pi-ai/package.json +1 -1
  311. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +39 -25
  312. package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -22
  313. package/packages/pi-ai/src/providers/anthropic.ts +22 -9
  314. package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +34 -21
  315. package/packages/pi-ai/src/types.ts +3 -0
  316. package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +56 -22
  317. package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +24 -28
  318. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +24 -28
  319. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  320. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +36 -1
  321. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  322. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +30 -1
  323. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  324. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +21 -2
  325. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  326. package/packages/pi-coding-agent/dist/core/agent-session.js +94 -16
  327. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  328. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +6 -2
  329. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  330. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  331. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  332. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  333. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  334. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  335. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  336. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  337. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  338. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
  339. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
  340. package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
  341. package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
  342. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
  343. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
  344. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
  345. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
  346. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  347. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  348. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  349. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +3 -0
  350. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  351. package/packages/pi-coding-agent/dist/core/extensions/runner.js +6 -6
  352. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  353. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +5 -3
  354. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  355. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +60 -4
  356. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  357. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  358. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  359. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  360. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  361. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  362. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  363. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  364. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  365. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  366. package/packages/pi-coding-agent/dist/core/sdk.js +81 -4
  367. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  368. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
  369. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  370. package/packages/pi-coding-agent/dist/core/settings-manager.js +25 -0
  371. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  372. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  373. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  374. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  375. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  376. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  377. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  378. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +22 -56
  379. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -1
  380. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +1 -0
  381. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  382. package/packages/pi-coding-agent/dist/core/tools/bash.js +3 -1
  383. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  384. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts +2 -0
  385. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  386. package/packages/pi-coding-agent/dist/core/tools/edit.js +12 -1
  387. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  388. package/packages/pi-coding-agent/dist/core/tools/find.d.ts +2 -0
  389. package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
  390. package/packages/pi-coding-agent/dist/core/tools/find.js +14 -6
  391. package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
  392. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts +2 -0
  393. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
  394. package/packages/pi-coding-agent/dist/core/tools/grep.js +12 -3
  395. package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
  396. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts +2 -0
  397. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  398. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +3 -1
  399. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  400. package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -1
  401. package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
  402. package/packages/pi-coding-agent/dist/core/tools/index.js +1 -0
  403. package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
  404. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts +2 -0
  405. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
  406. package/packages/pi-coding-agent/dist/core/tools/ls.js +10 -3
  407. package/packages/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
  408. package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -0
  409. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  410. package/packages/pi-coding-agent/dist/core/tools/read.js +3 -1
  411. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  412. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +7 -62
  413. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -1
  414. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts +2 -0
  415. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts.map +1 -0
  416. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js +115 -0
  417. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js.map +1 -0
  418. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts +19 -0
  419. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts.map +1 -0
  420. package/packages/pi-coding-agent/dist/core/tools/tool-target.js +20 -0
  421. package/packages/pi-coding-agent/dist/core/tools/tool-target.js.map +1 -0
  422. package/packages/pi-coding-agent/dist/core/tools/write.d.ts +4 -0
  423. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  424. package/packages/pi-coding-agent/dist/core/tools/write.js +9 -1
  425. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  426. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +89 -2
  427. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  428. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +25 -1
  429. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  430. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +6 -0
  431. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  432. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +155 -7
  433. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  434. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  435. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +31 -6
  436. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  437. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +71 -0
  438. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  439. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  440. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  441. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +25 -3
  442. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  443. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
  444. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  445. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
  446. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
  447. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +28 -0
  448. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
  449. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  450. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
  451. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  452. package/packages/pi-coding-agent/package.json +1 -1
  453. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +40 -1
  454. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +40 -1
  455. package/packages/pi-coding-agent/src/core/agent-session.ts +102 -16
  456. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +6 -2
  457. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  458. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  459. package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
  460. package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
  461. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  462. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +5 -3
  463. package/packages/pi-coding-agent/src/core/extensions/runner.ts +8 -5
  464. package/packages/pi-coding-agent/src/core/extensions/types.ts +63 -2
  465. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  466. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  467. package/packages/pi-coding-agent/src/core/sdk.ts +92 -4
  468. package/packages/pi-coding-agent/src/core/settings-manager.ts +39 -1
  469. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  470. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  471. package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +22 -66
  472. package/packages/pi-coding-agent/src/core/tools/bash.ts +4 -1
  473. package/packages/pi-coding-agent/src/core/tools/edit.ts +13 -1
  474. package/packages/pi-coding-agent/src/core/tools/find.ts +15 -6
  475. package/packages/pi-coding-agent/src/core/tools/grep.ts +13 -3
  476. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +4 -1
  477. package/packages/pi-coding-agent/src/core/tools/index.ts +8 -0
  478. package/packages/pi-coding-agent/src/core/tools/ls.ts +11 -3
  479. package/packages/pi-coding-agent/src/core/tools/read.ts +4 -1
  480. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +11 -72
  481. package/packages/pi-coding-agent/src/core/tools/tool-target-metadata.test.ts +127 -0
  482. package/packages/pi-coding-agent/src/core/tools/tool-target.ts +48 -0
  483. package/packages/pi-coding-agent/src/core/tools/write.ts +14 -2
  484. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +119 -2
  485. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +31 -1
  486. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +180 -7
  487. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +75 -0
  488. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +39 -8
  489. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +27 -3
  490. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +1 -1
  491. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +31 -0
  492. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
  493. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  494. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  495. package/packages/pi-tui/dist/tui.js +18 -8
  496. package/packages/pi-tui/dist/tui.js.map +1 -1
  497. package/packages/pi-tui/package.json +1 -1
  498. package/packages/pi-tui/src/tui.ts +20 -8
  499. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  500. package/packages/rpc-client/README.md +7 -0
  501. package/packages/rpc-client/package.json +1 -1
  502. package/pkg/package.json +1 -1
  503. package/src/resources/extensions/claude-code-cli/readiness.ts +25 -7
  504. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +42 -3
  505. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +67 -0
  506. package/src/resources/extensions/github-sync/sync.ts +8 -1
  507. package/src/resources/extensions/github-sync/tests/sync-source.test.ts +6 -18
  508. package/src/resources/extensions/gsd/auto/contracts.ts +19 -2
  509. package/src/resources/extensions/gsd/auto/loop-deps.ts +10 -11
  510. package/src/resources/extensions/gsd/auto/loop.ts +134 -16
  511. package/src/resources/extensions/gsd/auto/orchestrator.ts +52 -4
  512. package/src/resources/extensions/gsd/auto/phases.ts +393 -200
  513. package/src/resources/extensions/gsd/auto/resolve.ts +42 -1
  514. package/src/resources/extensions/gsd/auto/run-unit.ts +28 -30
  515. package/src/resources/extensions/gsd/auto/session.ts +9 -1
  516. package/src/resources/extensions/gsd/auto/types.ts +3 -0
  517. package/src/resources/extensions/gsd/auto/unit-runner-events.ts +15 -0
  518. package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
  519. package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
  520. package/src/resources/extensions/gsd/auto-dashboard.ts +20 -0
  521. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
  522. package/src/resources/extensions/gsd/auto-dispatch.ts +16 -0
  523. package/src/resources/extensions/gsd/auto-post-unit.ts +124 -80
  524. package/src/resources/extensions/gsd/auto-prompts.ts +112 -15
  525. package/src/resources/extensions/gsd/auto-recovery.ts +54 -0
  526. package/src/resources/extensions/gsd/auto-start.ts +319 -19
  527. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  528. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  529. package/src/resources/extensions/gsd/auto-worktree.ts +259 -360
  530. package/src/resources/extensions/gsd/auto.ts +324 -88
  531. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +147 -11
  532. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +45 -37
  533. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +36 -10
  534. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +32 -19
  535. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +5 -1
  536. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +7 -4
  537. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +6 -3
  538. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +1 -1
  539. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +379 -54
  540. package/src/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.ts +4 -0
  541. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  542. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +19 -2
  543. package/src/resources/extensions/gsd/clean-root-preflight.ts +32 -7
  544. package/src/resources/extensions/gsd/commands/handlers/ops.ts +4 -2
  545. package/src/resources/extensions/gsd/commands-config.ts +1 -1
  546. package/src/resources/extensions/gsd/commands-eval-review.ts +2 -2
  547. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  548. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  549. package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
  550. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  551. package/src/resources/extensions/gsd/db/unit-dispatches.ts +107 -0
  552. package/src/resources/extensions/gsd/db-base-schema.ts +4 -2
  553. package/src/resources/extensions/gsd/db-migration-steps.ts +8 -0
  554. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  555. package/src/resources/extensions/gsd/git-service.ts +87 -10
  556. package/src/resources/extensions/gsd/gsd-db.ts +50 -13
  557. package/src/resources/extensions/gsd/guided-flow.ts +148 -49
  558. package/src/resources/extensions/gsd/health-widget.ts +3 -0
  559. package/src/resources/extensions/gsd/init-wizard.ts +5 -1
  560. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  561. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  562. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  563. package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
  564. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  565. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  566. package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
  567. package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
  568. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  569. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  570. package/src/resources/extensions/gsd/prompts/complete-milestone.md +22 -17
  571. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  572. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  573. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  574. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  575. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  576. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  577. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  578. package/src/resources/extensions/gsd/quick.ts +37 -2
  579. package/src/resources/extensions/gsd/recovery-classification.ts +122 -0
  580. package/src/resources/extensions/gsd/slice-cadence.ts +49 -2
  581. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +23 -9
  582. package/src/resources/extensions/gsd/state-reconciliation.ts +57 -0
  583. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +59 -89
  584. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +47 -172
  585. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +0 -35
  586. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +35 -9
  587. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +543 -40
  588. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +80 -59
  589. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +119 -2
  590. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +3 -47
  591. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +76 -18
  592. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +175 -11
  593. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +54 -95
  594. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +67 -26
  595. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +14 -1
  596. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +32 -30
  597. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +32 -128
  598. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +20 -54
  599. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +20 -30
  600. package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +17 -29
  601. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +142 -0
  602. package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +21 -39
  603. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +15 -24
  604. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +44 -29
  605. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +39 -51
  606. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +159 -213
  607. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +15 -32
  608. package/src/resources/extensions/gsd/tests/browser-teardown.test.ts +0 -41
  609. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +15 -6
  610. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +34 -27
  611. package/src/resources/extensions/gsd/tests/cmux.test.ts +51 -53
  612. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +39 -61
  613. package/src/resources/extensions/gsd/tests/commands-config.test.ts +26 -19
  614. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  615. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  616. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +140 -0
  617. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  618. package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +29 -33
  619. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +45 -108
  620. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  621. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  622. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +90 -31
  623. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
  624. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +18 -10
  625. package/src/resources/extensions/gsd/tests/cwd-fallback-hardening.test.ts +138 -0
  626. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +4 -68
  627. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +6 -11
  628. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +14 -65
  629. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +44 -37
  630. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +58 -40
  631. package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +25 -15
  632. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  633. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +35 -17
  634. package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +16 -21
  635. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +15 -82
  636. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  637. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  638. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
  639. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  640. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +151 -0
  641. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -20
  642. package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +18 -26
  643. package/src/resources/extensions/gsd/tests/init-skip-git.test.ts +9 -12
  644. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +40 -0
  645. package/src/resources/extensions/gsd/tests/integration/commands-eval-review.integration.test.ts +4 -2
  646. package/src/resources/extensions/gsd/tests/integration/git-locale.test.ts +31 -20
  647. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +66 -0
  648. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +0 -47
  649. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +60 -202
  650. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +13 -56
  651. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +248 -10
  652. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  653. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  654. package/src/resources/extensions/gsd/tests/lazy-pi-tui-import.test.ts +44 -6
  655. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  656. package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +21 -35
  657. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +37 -7
  658. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  659. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  660. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +267 -0
  661. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +88 -98
  662. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +70 -278
  663. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  664. package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +37 -30
  665. package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +32 -28
  666. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +44 -9
  667. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +144 -0
  668. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  669. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  670. package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +24 -37
  671. package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +9 -24
  672. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +95 -75
  673. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
  674. package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
  675. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +36 -22
  676. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +36 -30
  677. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
  678. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +74 -4
  679. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +20 -22
  680. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +130 -32
  681. package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +18 -36
  682. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +35 -73
  683. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +76 -138
  684. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  685. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  686. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +70 -106
  687. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +59 -161
  688. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +33 -29
  689. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +22 -196
  690. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +23 -93
  691. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  692. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +50 -79
  693. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +27 -13
  694. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +151 -251
  695. package/src/resources/extensions/gsd/tests/resource-loader-import-path.test.ts +41 -29
  696. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +58 -69
  697. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +32 -164
  698. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +57 -41
  699. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +91 -0
  700. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  701. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  702. package/src/resources/extensions/gsd/tests/session-model-override.test.ts +14 -9
  703. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
  704. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +222 -0
  705. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +44 -42
  706. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  707. package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +56 -24
  708. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +51 -11
  709. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +23 -0
  710. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +66 -50
  711. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +68 -107
  712. package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +115 -42
  713. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +21 -77
  714. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +25 -116
  715. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +21 -57
  716. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +29 -76
  717. package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +33 -24
  718. package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +39 -30
  719. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  720. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +55 -0
  721. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +6 -4
  722. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +35 -40
  723. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +48 -46
  724. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +14 -102
  725. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +78 -232
  726. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +32 -35
  727. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  728. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  729. package/src/resources/extensions/gsd/tests/token-profile.test.ts +84 -309
  730. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
  731. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +134 -341
  732. package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +210 -0
  733. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
  734. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +8 -25
  735. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +80 -1
  736. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
  737. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -99
  738. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +43 -36
  739. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -444
  740. package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
  741. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +44 -189
  742. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -57
  743. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  744. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  745. package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
  746. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +21 -44
  747. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +27 -26
  748. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +14 -13
  749. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +50 -31
  750. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +434 -0
  751. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -18
  752. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  753. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  754. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +373 -76
  755. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +327 -0
  756. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +120 -0
  757. package/src/resources/extensions/gsd/tests/write-gate.test.ts +40 -1
  758. package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -13
  759. package/src/resources/extensions/gsd/tool-contract.ts +82 -0
  760. package/src/resources/extensions/gsd/tools/complete-milestone.ts +14 -15
  761. package/src/resources/extensions/gsd/tools/complete-task.ts +1 -1
  762. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  763. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  764. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  765. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  766. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
  767. package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
  768. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  769. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  770. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  771. package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
  772. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  773. package/src/resources/extensions/gsd/worktree-lifecycle.ts +1255 -0
  774. package/src/resources/extensions/gsd/worktree-safety.ts +282 -0
  775. package/src/resources/extensions/gsd/worktree-state-projection.ts +404 -0
  776. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +86 -40
  777. package/src/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
  778. package/dist/resources/extensions/gsd/worktree-resolver.js +0 -733
  779. package/dist/web/standalone/.next/static/chunks/8336.631939fb583761fa.js +0 -10
  780. package/dist/web/standalone/.next/static/chunks/app/page-fab3ebb85b006001.js +0 -1
  781. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +0 -1
  782. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +0 -1
  783. package/src/resources/extensions/gsd/tests/sync-layer-scope.test.ts +0 -434
  784. package/src/resources/extensions/gsd/worktree-resolver.ts +0 -909
  785. /package/dist/web/standalone/.next/static/{yTuahMMuJzVnsov5PreWl → drLMkgfHQ8lzS229_HWYR}/_buildManifest.js +0 -0
  786. /package/dist/web/standalone/.next/static/{yTuahMMuJzVnsov5PreWl → drLMkgfHQ8lzS229_HWYR}/_ssgManifest.js +0 -0
@@ -7,12 +7,11 @@
7
7
  * manual `/worktree` which uses `worktree/<name>` branches). This module
8
8
  * manages create, enter, detect, and teardown for auto-mode worktrees.
9
9
  */
10
- import { existsSync, cpSync, readFileSync, readdirSync, mkdirSync, realpathSync, rmSync, unlinkSync, statSync, lstatSync as lstatSyncFn, } from "node:fs";
10
+ import { existsSync, cpSync, readFileSync, readdirSync, mkdirSync, realpathSync, rmSync, unlinkSync, lstatSync as lstatSyncFn, } from "node:fs";
11
11
  import { isAbsolute, join, relative, sep as pathSep } from "node:path";
12
12
  import { GSDError, GSD_IO_ERROR, GSD_GIT_ERROR } from "./errors.js";
13
- import { reconcileWorktreeDb, isDbAvailable, getMilestone, getMilestoneSlices, closeDatabase, openDatabase, getDbPath, } from "./gsd-db.js";
13
+ import { reconcileWorktreeDb, isDbAvailable, getMilestone, getMilestoneSlices, getSliceTasks, closeDatabase, openDatabase, getDbPath, } from "./gsd-db.js";
14
14
  import { execFileSync } from "node:child_process";
15
- import { safeCopy, safeCopyRecursive } from "./safe-fs.js";
16
15
  import { gsdRoot, resolveGsdPathContract } from "./paths.js";
17
16
  import { createWorktree, removeWorktree, resolveGitDir, worktreePath, isInsideWorktreesDir, } from "./worktree-manager.js";
18
17
  import { detectWorktreeName, nudgeGitBranchCache, } from "./worktree.js";
@@ -23,9 +22,10 @@ import { debugLog } from "./debug-logger.js";
23
22
  import { logWarning, logError } from "./workflow-logger.js";
24
23
  import { loadEffectiveGSDPreferences } from "./preferences.js";
25
24
  import { MILESTONE_ID_RE } from "./milestone-ids.js";
26
- import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeWorkingTreeStatus, nativeAddAllWithExclusions, nativeCommit, nativeCheckoutBranch, nativeMergeSquash, nativeConflictFiles, nativeCheckoutTheirs, nativeAddPaths, nativeRmForce, nativeBranchDelete, nativeBranchForceReset, nativeBranchExists, nativeDiffNumstat, nativeUpdateRef, nativeIsAncestor, nativeMergeAbort, } from "./native-git-bridge.js";
25
+ import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeWorkingTreeStatus, nativeAddAllWithExclusions, nativeCommit, nativeCheckoutBranch, nativeMergeSquash, nativeConflictFiles, nativeCheckoutTheirs, nativeAddPaths, nativeRmForce, nativeBranchDelete, nativeBranchForceReset, nativeBranchExists, nativeDiffNumstat, nativeUpdateRef, nativeIsAncestor, nativeMergeAbort, nativeWorktreeList, } from "./native-git-bridge.js";
27
26
  import { gsdHome } from "./gsd-home.js";
28
27
  import { createWorkspace } from "./workspace.js";
28
+ import { _finalizeProjectionForMergeImpl, _projectRootToWorktreeImpl, _projectWorktreeToRootImpl, } from "./worktree-state-projection.js";
29
29
  const PROJECT_PREFERENCES_FILE = "PREFERENCES.md";
30
30
  const LEGACY_PROJECT_PREFERENCES_FILE = "preferences.md";
31
31
  const LEGACY_DEEP_SETUP_RUNTIME_UNIT_FILES = new Set([
@@ -55,10 +55,6 @@ const ROOT_STATE_FILES = [
55
55
  // Back-sync (worktree → main) must NEVER overwrite the project root's copy
56
56
  // because the project root is authoritative for preferences (#2684).
57
57
  ];
58
- const ROOT_DIAGNOSTIC_FILES = [
59
- "completed-units.json",
60
- "metrics.json",
61
- ];
62
58
  /**
63
59
  * Pop a stash entry by tracking the unique marker embedded in its message so
64
60
  * concurrent stash operations against the same project root cannot cause us to
@@ -135,67 +131,34 @@ function isSamePath(a, b) {
135
131
  return false;
136
132
  }
137
133
  }
138
- // ─── ASSESSMENT Force-Sync Helper (#2821) ─────────────────────────────────
139
- /** Regex matching YAML frontmatter `verdict:` field. */
140
- const VERDICT_RE = /verdict:\s*[\w-]+/i;
141
- /**
142
- * Walk a milestone directory and force-overwrite ASSESSMENT files in the
143
- * destination when the source copy contains a `verdict:` field.
144
- *
145
- * This is the targeted fix for the UAT stuck-loop (#2821): the main
146
- * safeCopyRecursive uses force:false to protect worktree-local projection
147
- * files (#1886), but ASSESSMENT files written by run-uat must be
148
- * forward-synced when the project root has a verdict. Without this,
149
- * the worktree retains a stale FAIL or missing ASSESSMENT and
150
- * checkNeedsRunUat re-dispatches run-uat indefinitely.
151
- *
152
- * Only overwrites when the source has a verdict — never clobbers a
153
- * worktree ASSESSMENT with a verdictless project-root copy.
154
- */
155
- function forceOverwriteAssessmentsWithVerdict(srcMilestoneDir, dstMilestoneDir) {
156
- if (!existsSync(srcMilestoneDir))
157
- return;
158
- // Walk slices/<SID>/ looking for *-ASSESSMENT.md files
159
- const slicesDir = join(srcMilestoneDir, "slices");
160
- if (!existsSync(slicesDir))
161
- return;
162
- try {
163
- for (const sliceEntry of readdirSync(slicesDir, { withFileTypes: true })) {
164
- if (!sliceEntry.isDirectory())
165
- continue;
166
- const srcSliceDir = join(slicesDir, sliceEntry.name);
167
- const dstSliceDir = join(dstMilestoneDir, "slices", sliceEntry.name);
168
- try {
169
- for (const fileEntry of readdirSync(srcSliceDir, { withFileTypes: true })) {
170
- if (!fileEntry.isFile())
171
- continue;
172
- if (!fileEntry.name.endsWith("-ASSESSMENT.md"))
173
- continue;
174
- const srcFile = join(srcSliceDir, fileEntry.name);
175
- try {
176
- const srcContent = readFileSync(srcFile, "utf-8");
177
- if (!VERDICT_RE.test(srcContent))
178
- continue; // no verdict in source — skip
179
- // Source has a verdict — force-copy into worktree
180
- mkdirSync(dstSliceDir, { recursive: true });
181
- safeCopy(srcFile, join(dstSliceDir, fileEntry.name), { force: true });
182
- }
183
- catch (err) {
184
- /* non-fatal per file */
185
- logWarning("worktree", `assessment force-copy failed: ${err instanceof Error ? err.message : String(err)}`);
186
- }
187
- }
188
- }
189
- catch (err) {
190
- /* non-fatal per slice */
191
- logWarning("worktree", `assessment slice scan failed: ${err instanceof Error ? err.message : String(err)}`);
192
- }
193
- }
194
- }
195
- catch (err) {
196
- /* non-fatal */
197
- logWarning("worktree", `assessment sync failed: ${err instanceof Error ? err.message : String(err)}`);
198
- }
134
+ export function _isSamePath(a, b) {
135
+ return isSamePath(a, b);
136
+ }
137
+ export function _resolveAutoWorktreeStartPoint(integrationBranch, gitMainBranch, branchExists) {
138
+ if (integrationBranch)
139
+ return integrationBranch;
140
+ return gitMainBranch &&
141
+ typeof gitMainBranch === "string" &&
142
+ gitMainBranch.length > 0 &&
143
+ branchExists(gitMainBranch)
144
+ ? gitMainBranch
145
+ : undefined;
146
+ }
147
+ export function _shouldReconcileWorktreeDb(worktreeDbPath, mainDbPath, pathExists = existsSync, samePath = isSamePath) {
148
+ return pathExists(worktreeDbPath) && !samePath(worktreeDbPath, mainDbPath);
149
+ }
150
+ export function _isExpectedWorktreeUnlinkError(code) {
151
+ return code === "ENOENT" || code === "EISDIR";
152
+ }
153
+ function stripGsdDisplayPrefix(value, id) {
154
+ const raw = String(value ?? "").trim();
155
+ if (!raw)
156
+ return undefined;
157
+ const lower = raw.toLowerCase();
158
+ const idLower = id.toLowerCase();
159
+ if (lower.startsWith(`${idLower}:`))
160
+ return raw.slice(id.length + 1).trim() || undefined;
161
+ return raw;
199
162
  }
200
163
  // ─── Module State ──────────────────────────────────────────────────────────
201
164
  /** Active workspace registry — replaces the legacy `originalBase` singleton. */
@@ -288,7 +251,7 @@ function clearProjectRootStateFiles(basePath, milestoneId) {
288
251
  catch (err) {
289
252
  // ENOENT/EISDIR are expected for already-removed or directory entries (#3597)
290
253
  const code = err.code;
291
- if (code !== "ENOENT" && code !== "EISDIR") {
254
+ if (!_isExpectedWorktreeUnlinkError(code)) {
292
255
  logWarning("worktree", `untracked file unlink failed: ${err instanceof Error ? err.message : String(err)}`);
293
256
  }
294
257
  }
@@ -317,6 +280,44 @@ export const SAFE_AUTO_RESOLVE_PATTERNS = [
317
280
  * Covers `.gsd/` state files and common build artifacts. */
318
281
  export const isSafeToAutoResolve = (filePath) => filePath.startsWith(".gsd/") ||
319
282
  SAFE_AUTO_RESOLVE_PATTERNS.some((re) => re.test(filePath));
283
+ function removeMergeStateFiles(basePath, contextLabel) {
284
+ try {
285
+ const gitDir_ = resolveGitDir(basePath);
286
+ for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
287
+ const p = join(gitDir_, f);
288
+ if (existsSync(p))
289
+ unlinkSync(p);
290
+ }
291
+ }
292
+ catch (err) {
293
+ logError("worktree", `${contextLabel} merge state cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
294
+ }
295
+ }
296
+ function cleanupSquashConflictState(basePath) {
297
+ // `git merge --squash` conflicts can leave unmerged index entries without
298
+ // MERGE_HEAD, so merge-abort alone is not enough. Reset the merge index, then
299
+ // remove merge message files that native/libgit2 paths may have created.
300
+ try {
301
+ nativeMergeAbort(basePath);
302
+ }
303
+ catch (err) {
304
+ // Expected for squash conflicts when MERGE_HEAD was never written.
305
+ debugLog("squash-conflict-cleanup:merge-abort-skipped", {
306
+ error: err instanceof Error ? err.message : String(err),
307
+ });
308
+ }
309
+ try {
310
+ execFileSync("git", ["reset", "--merge"], {
311
+ cwd: basePath,
312
+ stdio: ["ignore", "pipe", "pipe"],
313
+ encoding: "utf-8",
314
+ });
315
+ }
316
+ catch (err) {
317
+ logError("worktree", `git reset --merge failed after squash conflict: ${err instanceof Error ? err.message : String(err)}`);
318
+ }
319
+ removeMergeStateFiles(basePath, "squash conflict");
320
+ }
320
321
  // ─── Dispatch-Level Sync (project root ↔ worktree) ──────────────────────────
321
322
  /**
322
323
  * Sync milestone artifacts from project root INTO worktree before deriveState.
@@ -326,156 +327,21 @@ export const isSafeToAutoResolve = (filePath) => filePath.startsWith(".gsd/") ||
326
327
  * Non-fatal — sync failure should never block dispatch.
327
328
  */
328
329
  /**
329
- * Scope-typed variant of syncProjectRootToWorktree.
330
- *
331
- * Takes an explicit (rootScope, worktreeScope) pair where rootScope is the
332
- * project root and worktreeScope is the auto-worktree. Direction is encoded
333
- * in argument order. Asserts both scopes belong to the same workspace identity
334
- * to prevent silent mismatch bugs.
335
- */
336
- export function syncProjectRootToWorktreeByScope(rootScope, worktreeScope) {
337
- if (rootScope.workspace.identityKey !== worktreeScope.workspace.identityKey) {
338
- throw new Error(`syncProjectRootToWorktreeByScope: scope identity mismatch — ` +
339
- `rootScope.identityKey="${rootScope.workspace.identityKey}" ` +
340
- `worktreeScope.identityKey="${worktreeScope.workspace.identityKey}"`);
341
- }
342
- if (rootScope.milestoneId !== worktreeScope.milestoneId) {
343
- throw new Error(`syncProjectRootToWorktreeByScope: milestoneId mismatch — ` +
344
- `rootScope.milestoneId="${rootScope.milestoneId}" worktreeScope.milestoneId="${worktreeScope.milestoneId}"`);
345
- }
346
- const projectRoot = rootScope.workspace.projectRoot;
347
- const worktreePath_ = worktreeScope.workspace.worktreeRoot ?? worktreeScope.workspace.projectRoot;
348
- const milestoneId = rootScope.milestoneId;
349
- syncProjectRootToWorktree(projectRoot, worktreePath_, milestoneId);
350
- }
351
- /**
352
- * @deprecated Use syncProjectRootToWorktreeByScope instead.
353
- * TODO(C-future): remove once all callers migrated.
330
+ * Path-string entry point to WorktreeStateProjection.projectRootToWorktree.
331
+ * Production code goes through the Module class; this delegator survives so
332
+ * the projection-invariant tests (#1886, #2184, #2478, #2821) can exercise
333
+ * the bodies with raw paths.
354
334
  */
355
335
  export function syncProjectRootToWorktree(projectRoot, worktreePath_, milestoneId) {
356
- if (!worktreePath_ || !projectRoot || worktreePath_ === projectRoot)
357
- return;
358
- if (!milestoneId)
359
- return;
360
- const contract = resolveGsdPathContract(worktreePath_, projectRoot);
361
- const prGsd = contract.projectGsd;
362
- const wtGsd = contract.worktreeGsd ?? join(worktreePath_, ".gsd");
363
- // When .gsd is a symlink to the same external directory in both locations,
364
- // cpSync rejects the copy because source === destination (ERR_FS_CP_EINVAL).
365
- // Compare realpaths and skip when they resolve to the same physical path (#2184).
366
- if (isSamePath(prGsd, wtGsd))
367
- return;
368
- // Copy milestone directory from project root to worktree — additive only.
369
- // force:false prevents cpSync from overwriting existing worktree files.
370
- // Without this, worktree-local files (e.g. VALIDATION.md written
371
- // by validate-milestone) get clobbered by stale project root copies,
372
- // causing an infinite re-validation loop (#1886).
373
- safeCopyRecursive(join(prGsd, "milestones", milestoneId), join(wtGsd, "milestones", milestoneId), { force: false });
374
- // Force-sync ASSESSMENT files that have a verdict from project root (#2821).
375
- // The additive-only copy above preserves worktree-local files, but
376
- // ASSESSMENT files are special: after run-uat writes a verdict and post-unit
377
- // syncs it to the project root, the worktree may retain a stale copy (e.g.
378
- // verdict:fail while the project root has verdict:pass from a retry). On
379
- // session resume the DB is rebuilt from disk, and if the stale ASSESSMENT
380
- // persists, checkNeedsRunUat finds no passing verdict → re-dispatches
381
- // run-uat indefinitely (stuck-loop ×9).
382
- forceOverwriteAssessmentsWithVerdict(join(prGsd, "milestones", milestoneId), join(wtGsd, "milestones", milestoneId));
383
- // Forward-sync completed-units.json from project root to worktree.
384
- // Project root is authoritative for completion state after crash recovery;
385
- // without this, the worktree re-dispatches already-completed units (#1886).
386
- safeCopy(join(prGsd, "completed-units.json"), join(wtGsd, "completed-units.json"), { force: true });
387
- // Delete a legacy worktree-local gsd.db ONLY if it is empty (0 bytes).
388
- // Runtime opens contract.projectDb; this cleanup only removes corrupt
389
- // pre-upgrade local DB projections.
390
- try {
391
- const wtDb = join(wtGsd, "gsd.db");
392
- let deleteSidecars = false;
393
- if (existsSync(wtDb)) {
394
- const size = statSync(wtDb).size;
395
- if (size === 0) {
396
- unlinkSync(wtDb);
397
- deleteSidecars = true;
398
- }
399
- }
400
- else {
401
- // Main DB already missing — sidecars are orphaned from a previous
402
- // partial cleanup and must still be removed.
403
- deleteSidecars = true;
404
- }
405
- // Always clean up WAL/SHM sidecar files when the main DB was deleted
406
- // or is already missing. Orphaned WAL/SHM files cause SQLite WAL
407
- // recovery on next open, which triggers a CPU spin on Node 24's
408
- // node:sqlite DatabaseSync implementation (#2478).
409
- if (deleteSidecars) {
410
- for (const suffix of ["-wal", "-shm"]) {
411
- const f = wtDb + suffix;
412
- if (existsSync(f)) {
413
- unlinkSync(f);
414
- }
415
- }
416
- }
417
- }
418
- catch (err) {
419
- /* non-fatal */
420
- logWarning("worktree", `worktree DB cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
421
- }
422
- }
423
- /**
424
- * Scope-typed variant of syncStateToProjectRoot.
425
- *
426
- * Takes an explicit (worktreeScope, rootScope) pair. Direction is encoded in
427
- * argument order (worktree → root). Asserts both scopes belong to the same
428
- * workspace identity to prevent silent mismatch bugs.
429
- */
430
- export function syncStateToProjectRootByScope(worktreeScope, rootScope) {
431
- if (worktreeScope.workspace.identityKey !== rootScope.workspace.identityKey) {
432
- throw new Error(`syncStateToProjectRootByScope: scope identity mismatch — ` +
433
- `worktreeScope.identityKey="${worktreeScope.workspace.identityKey}" ` +
434
- `rootScope.identityKey="${rootScope.workspace.identityKey}"`);
435
- }
436
- if (worktreeScope.milestoneId !== rootScope.milestoneId) {
437
- throw new Error(`syncStateToProjectRootByScope: milestoneId mismatch — ` +
438
- `worktreeScope.milestoneId="${worktreeScope.milestoneId}" rootScope.milestoneId="${rootScope.milestoneId}"`);
439
- }
440
- const worktreePath_ = worktreeScope.workspace.worktreeRoot ?? worktreeScope.workspace.projectRoot;
441
- const projectRoot = rootScope.workspace.projectRoot;
442
- const milestoneId = worktreeScope.milestoneId;
443
- syncStateToProjectRoot(worktreePath_, projectRoot, milestoneId);
336
+ _projectRootToWorktreeImpl(projectRoot, worktreePath_, milestoneId);
444
337
  }
445
338
  /**
446
- * Sync worktree diagnostics from worktree to project root.
447
- * Only runs when inside an auto-worktree (worktreePath differs from projectRoot).
448
- * DB/project-root state remains authoritative; markdown projections are not
449
- * copied from the worktree back to the project root.
450
- * Non-fatal — sync failure should never block dispatch.
451
- * @deprecated Use syncStateToProjectRootByScope instead.
452
- * TODO(C-future): remove once all callers migrated.
339
+ * Path-string entry point to WorktreeStateProjection.projectWorktreeToRoot.
340
+ * Production code goes through the Module class; this delegator survives so
341
+ * the projection-invariant tests can exercise the body with raw paths.
453
342
  */
454
343
  export function syncStateToProjectRoot(worktreePath_, projectRoot, milestoneId) {
455
- if (!worktreePath_ || !projectRoot || worktreePath_ === projectRoot)
456
- return;
457
- if (!milestoneId)
458
- return;
459
- const contract = resolveGsdPathContract(worktreePath_, projectRoot);
460
- const wtGsd = contract.worktreeGsd ?? join(worktreePath_, ".gsd");
461
- const prGsd = contract.projectGsd;
462
- // When .gsd is a symlink to the same external directory in both locations,
463
- // cpSync rejects the copy because source === destination (ERR_FS_CP_EINVAL).
464
- // Compare realpaths and skip when they resolve to the same physical path (#2184).
465
- if (isSamePath(wtGsd, prGsd))
466
- return;
467
- // metrics.json — session cost/token tracking (#2313).
468
- // Without this, metrics accumulated in the worktree are invisible from the
469
- // project root and never appear in the dashboard or skill-health reports.
470
- safeCopy(join(wtGsd, "metrics.json"), join(prGsd, "metrics.json"), { force: true });
471
- // completed-units.json — runtime completion diagnostics used to avoid
472
- // re-dispatching work already completed in an isolated worktree.
473
- safeCopy(join(wtGsd, "completed-units.json"), join(prGsd, "completed-units.json"), { force: true });
474
- // Runtime records — unit dispatch diagnostics used by selfHealRuntimeRecords().
475
- // Without this, a crash during a unit leaves the runtime record only in the
476
- // worktree. If the next session resolves basePath before worktree re-entry,
477
- // selfHeal can't find or clear the stale record (#769).
478
- safeCopyRecursive(join(wtGsd, "runtime", "units"), join(prGsd, "runtime", "units"), { force: true });
344
+ _projectWorktreeToRootImpl(worktreePath_, projectRoot, milestoneId);
479
345
  }
480
346
  // ─── Resource Staleness ───────────────────────────────────────────────────
481
347
  /**
@@ -816,50 +682,7 @@ export function syncGsdStateToWorktree(mainBasePath, worktreePath_) {
816
682
  * the shared project DB or the pre-upgrade DB reconciliation path above.
817
683
  */
818
684
  export function syncWorktreeStateBack(mainBasePath, worktreePath, milestoneId) {
819
- const contract = resolveGsdPathContract(worktreePath, mainBasePath);
820
- const mainGsd = contract.projectGsd;
821
- const wtGsd = contract.worktreeGsd ?? join(worktreePath, ".gsd");
822
- const synced = [];
823
- // If both resolve to the same directory (symlink), no sync needed
824
- if (isSamePath(mainGsd, wtGsd))
825
- return { synced };
826
- if (!existsSync(wtGsd) || !existsSync(mainGsd))
827
- return { synced };
828
- // ── 0. Pre-upgrade worktree DB reconciliation ────────────────────────
829
- // If the worktree has its own gsd.db (copied before the WAL transition),
830
- // reconcile its hierarchy data into the project root DB before syncing
831
- // files. This handles in-flight worktrees that were created before the
832
- // upgrade to shared WAL mode.
833
- const wtLocalDb = join(wtGsd, "gsd.db");
834
- const mainDb = contract.projectDb;
835
- if (existsSync(wtLocalDb) && existsSync(mainDb)) {
836
- try {
837
- reconcileWorktreeDb(mainDb, wtLocalDb);
838
- synced.push("gsd.db (pre-upgrade reconcile)");
839
- }
840
- catch (err) {
841
- // Non-fatal — file sync below is the fallback
842
- logError("worktree", `DB reconciliation failed: ${err instanceof Error ? err.message : String(err)}`);
843
- }
844
- }
845
- // ── 1. Sync root-level diagnostic files back ─────────────────────────
846
- // Markdown/JSON state projections remain project-root/DB authoritative.
847
- // These diagnostic files are copied for observability only.
848
- for (const f of ROOT_DIAGNOSTIC_FILES) {
849
- const src = join(wtGsd, f);
850
- const dst = join(mainGsd, f);
851
- if (existsSync(src)) {
852
- try {
853
- cpSync(src, dst, { force: true });
854
- synced.push(f);
855
- }
856
- catch (err) {
857
- /* non-fatal */
858
- logWarning("worktree", `state file copy-back failed (${f}): ${err instanceof Error ? err.message : String(err)}`);
859
- }
860
- }
861
- }
862
- return { synced };
685
+ return _finalizeProjectionForMergeImpl(mainBasePath, worktreePath, milestoneId);
863
686
  }
864
687
  // ─── Worktree Post-Create Hook (#597) ────────────────────────────────────────
865
688
  /**
@@ -945,17 +768,7 @@ export function enterBranchModeForMilestone(basePath, milestoneId) {
945
768
  // Create the milestone branch from the integration branch start-point.
946
769
  const integrationBranch = readIntegrationBranch(basePath, milestoneId) ?? undefined;
947
770
  const gitPrefs = loadEffectiveGSDPreferences()?.preferences?.git;
948
- // Validate main_branch preference exists in the repo before using it —
949
- // a stale preference (e.g. "master" when repo uses "main") would cause
950
- // nativeBranchForceReset to fail with a bad start-point reference.
951
- const validatedPrefBranch = gitPrefs?.main_branch &&
952
- typeof gitPrefs.main_branch === "string" &&
953
- gitPrefs.main_branch.length > 0 &&
954
- nativeBranchExists(basePath, gitPrefs.main_branch)
955
- ? gitPrefs.main_branch
956
- : undefined;
957
- const startPoint = integrationBranch ??
958
- validatedPrefBranch ??
771
+ const startPoint = _resolveAutoWorktreeStartPoint(integrationBranch, gitPrefs?.main_branch, (branchName) => nativeBranchExists(basePath, branchName)) ??
959
772
  nativeDetectMainBranch(basePath);
960
773
  // TOCTOU ancestry guard (Issue #4980 HIGH-3).
961
774
  //
@@ -1018,6 +831,111 @@ export function enterBranchModeForMilestone(basePath, milestoneId) {
1018
831
  * for both reads and writes. copyPlanningArtifacts and reconcilePlanCheckboxes
1019
832
  * (both formerly here) became dead.
1020
833
  */
834
+ /**
835
+ * True when `branch` is checked out in any worktree listed by
836
+ * `git worktree list --porcelain`. Used to gate ref updates that would
837
+ * otherwise leave a concurrent worktree's HEAD inconsistent with its
838
+ * index/working tree (Codex peer-review of #5538-followup).
839
+ *
840
+ * Best-effort: a `nativeWorktreeList` failure returns true so we err on
841
+ * the side of NOT moving the ref. Better to skip a fast-forward than to
842
+ * silently corrupt another worktree.
843
+ */
844
+ export function _isBranchCheckedOutElsewhere(basePath, branch) {
845
+ try {
846
+ const entries = nativeWorktreeList(basePath);
847
+ return entries.some((entry) => entry.branch === branch);
848
+ }
849
+ catch {
850
+ return true;
851
+ }
852
+ }
853
+ /**
854
+ * Resolve the integration branch using the same 3-tier fallback as the
855
+ * fresh-create path: META.json → git.main_branch preference → detected
856
+ * main branch. Returns null when no usable target exists.
857
+ */
858
+ function _resolveIntegrationBranchForReuse(basePath, milestoneId) {
859
+ const fromMeta = readIntegrationBranch(basePath, milestoneId);
860
+ if (fromMeta)
861
+ return fromMeta;
862
+ const gitPrefs = loadEffectiveGSDPreferences()?.preferences?.git;
863
+ const fromPref = gitPrefs?.main_branch &&
864
+ typeof gitPrefs.main_branch === "string" &&
865
+ gitPrefs.main_branch.length > 0 &&
866
+ nativeBranchExists(basePath, gitPrefs.main_branch)
867
+ ? gitPrefs.main_branch
868
+ : null;
869
+ if (fromPref)
870
+ return fromPref;
871
+ try {
872
+ return nativeDetectMainBranch(basePath);
873
+ }
874
+ catch {
875
+ return null;
876
+ }
877
+ }
878
+ /**
879
+ * When reusing an existing milestone branch, fast-forward it onto the
880
+ * integration branch when that's safe (branch is a strict ancestor of
881
+ * integration — no commits would be lost). Skips when the branch has its
882
+ * own commits ahead of integration, when the integration branch can't be
883
+ * resolved, or when any git operation fails — the merge gate at milestone
884
+ * completion will surface real divergence as a conflict.
885
+ *
886
+ * The previous behavior re-attached the worktree to whatever stale tip
887
+ * the branch held, which caused new milestone work to fork from a base
888
+ * missing prior milestones' merges (#5538-followup).
889
+ */
890
+ export function fastForwardReusedMilestoneBranchIfSafe(basePath, milestoneId, branch) {
891
+ try {
892
+ const integrationBranch = _resolveIntegrationBranchForReuse(basePath, milestoneId);
893
+ if (!integrationBranch || integrationBranch === branch)
894
+ return;
895
+ if (!nativeBranchExists(basePath, integrationBranch))
896
+ return;
897
+ // Pure fast-forward only: branch must be a strict ancestor of integration.
898
+ // If the branch has its own commits ahead, leave it alone.
899
+ if (!nativeIsAncestor(basePath, branch, integrationBranch)) {
900
+ debugLog("createAutoWorktree", {
901
+ phase: "skip-ff-branch-not-ancestor",
902
+ milestoneId,
903
+ branch,
904
+ integration: integrationBranch,
905
+ });
906
+ return;
907
+ }
908
+ // Codex peer-review: `nativeUpdateRef` succeeds even when the branch is
909
+ // currently checked out in another worktree, leaving that worktree's HEAD
910
+ // inconsistent with its index/work tree. Skip the fast-forward if any
911
+ // listed worktree has this branch checked out — the merge gate at
912
+ // milestone-completion will surface stale-base divergence as a conflict
913
+ // instead of silently corrupting the other worktree's state.
914
+ if (_isBranchCheckedOutElsewhere(basePath, branch)) {
915
+ debugLog("createAutoWorktree", {
916
+ phase: "skip-ff-branch-checked-out-elsewhere",
917
+ milestoneId,
918
+ branch,
919
+ });
920
+ return;
921
+ }
922
+ nativeUpdateRef(basePath, `refs/heads/${branch}`, integrationBranch);
923
+ debugLog("createAutoWorktree", {
924
+ phase: "fast-forward-reused-branch",
925
+ milestoneId,
926
+ branch,
927
+ integration: integrationBranch,
928
+ });
929
+ }
930
+ catch (err) {
931
+ debugLog("createAutoWorktree", {
932
+ phase: "fast-forward-reused-branch-failed",
933
+ milestoneId,
934
+ branch,
935
+ error: err instanceof Error ? err.message : String(err),
936
+ });
937
+ }
938
+ }
1021
939
  export function createAutoWorktree(basePath, milestoneId) {
1022
940
  basePath = resolveWorktreeProjectRoot(basePath);
1023
941
  // Check if repo has commits — git worktree requires a valid HEAD
@@ -1035,6 +953,11 @@ export function createAutoWorktree(basePath, milestoneId) {
1035
953
  const branchExists = nativeBranchExists(basePath, branch);
1036
954
  let info;
1037
955
  if (branchExists) {
956
+ // #5538-followup: fast-forward the reused branch onto the integration
957
+ // branch when safe so the next milestone forks from up-to-date code.
958
+ // Without this, a milestone that was created before another milestone
959
+ // merged into main would carry a stale base into its worktree.
960
+ fastForwardReusedMilestoneBranchIfSafe(basePath, milestoneId, branch);
1038
961
  // Re-attach worktree to the existing milestone branch (preserving commits)
1039
962
  info = createWorktree(basePath, milestoneId, {
1040
963
  branch,
@@ -1051,13 +974,7 @@ export function createAutoWorktree(basePath, milestoneId) {
1051
974
  // would fork worktrees from the wrong (stale) branch.
1052
975
  const integrationBranch = readIntegrationBranch(basePath, milestoneId) ?? undefined;
1053
976
  const gitPrefs = loadEffectiveGSDPreferences()?.preferences?.git;
1054
- const validatedPrefBranch = gitPrefs?.main_branch &&
1055
- typeof gitPrefs.main_branch === "string" &&
1056
- gitPrefs.main_branch.length > 0 &&
1057
- nativeBranchExists(basePath, gitPrefs.main_branch)
1058
- ? gitPrefs.main_branch
1059
- : undefined;
1060
- const startPoint = integrationBranch ?? validatedPrefBranch ?? undefined;
977
+ const startPoint = _resolveAutoWorktreeStartPoint(integrationBranch, gitPrefs?.main_branch, (branchName) => nativeBranchExists(basePath, branchName));
1061
978
  info = createWorktree(basePath, milestoneId, {
1062
979
  branch,
1063
980
  startPoint,
@@ -1134,7 +1051,7 @@ export function teardownAutoWorktree(originalBasePath, milestoneId, opts = {}) {
1134
1051
  const contract = resolveGsdPathContract(previousCwd, originalBasePath);
1135
1052
  const worktreeDbPath = join(contract.worktreeGsd ?? join(previousCwd, ".gsd"), "gsd.db");
1136
1053
  const mainDbPath = contract.projectDb;
1137
- if (existsSync(worktreeDbPath) && !isSamePath(worktreeDbPath, mainDbPath)) {
1054
+ if (_shouldReconcileWorktreeDb(worktreeDbPath, mainDbPath)) {
1138
1055
  reconcileWorktreeDb(mainDbPath, worktreeDbPath);
1139
1056
  }
1140
1057
  }
@@ -1280,6 +1197,15 @@ export function enterAutoWorktree(basePath, milestoneId) {
1280
1197
  export function getAutoWorktreeOriginalBase() {
1281
1198
  return getActiveWorkspace()?.projectRoot ?? null;
1282
1199
  }
1200
+ /**
1201
+ * Test-only — resets the module-level `activeWorkspace` registry between
1202
+ * runs. Production code never clears the registry directly; tests call this
1203
+ * in `beforeEach`/`afterEach` to isolate registry-mutating cases. Renaming
1204
+ * the underscore-prefixed `_*ForTest` exports it joins (slice 7 / step G of
1205
+ * ADR-016) was deliberate: those wrapped real production helpers and lost
1206
+ * the suffix; this one stays as the only legitimate test-scaffolding export
1207
+ * because it has no production caller.
1208
+ */
1283
1209
  export function _resetAutoWorktreeOriginalBaseForTests() {
1284
1210
  setActiveWorkspace(null);
1285
1211
  }
@@ -1384,7 +1310,7 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1384
1310
  const contract = resolveGsdPathContract(worktreeCwd, originalBasePath_);
1385
1311
  const worktreeDbPath = join(contract.worktreeGsd ?? join(worktreeCwd, ".gsd"), "gsd.db");
1386
1312
  const mainDbPath = contract.projectDb;
1387
- if (existsSync(worktreeDbPath) && !isSamePath(worktreeDbPath, mainDbPath)) {
1313
+ if (_shouldReconcileWorktreeDb(worktreeDbPath, mainDbPath)) {
1388
1314
  reconcileWorktreeDb(mainDbPath, worktreeDbPath);
1389
1315
  }
1390
1316
  }
@@ -1398,14 +1324,23 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1398
1324
  if (isDbAvailable()) {
1399
1325
  completedSlices = getMilestoneSlices(milestoneId)
1400
1326
  .filter(s => s.status === "complete")
1401
- .map(s => ({ id: s.id, title: s.title }));
1327
+ .map(s => ({
1328
+ id: s.id,
1329
+ title: stripGsdDisplayPrefix(s.title, s.id) ?? s.id,
1330
+ tasks: getSliceTasks(milestoneId, s.id)
1331
+ .filter((task) => task.status === "complete")
1332
+ .map((task) => ({
1333
+ id: task.id,
1334
+ title: stripGsdDisplayPrefix(task.title, task.id) ?? task.id,
1335
+ })),
1336
+ }));
1402
1337
  }
1403
1338
  // Fallback: parse roadmap content when DB is unavailable
1404
1339
  if (completedSlices.length === 0 && roadmapContent) {
1405
1340
  const sliceRe = /- \[x\] \*\*(\w+):\s*(.+?)\*\*/gi;
1406
1341
  let m;
1407
1342
  while ((m = sliceRe.exec(roadmapContent)) !== null) {
1408
- completedSlices.push({ id: m[1], title: m[2] });
1343
+ completedSlices.push({ id: m[1], title: m[2], tasks: [] });
1409
1344
  }
1410
1345
  }
1411
1346
  // 3. chdir to original base
@@ -1462,7 +1397,7 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1462
1397
  }
1463
1398
  // 6. Build rich commit message
1464
1399
  const dbMilestone = getMilestone(milestoneId);
1465
- let milestoneTitle = (dbMilestone?.title ?? "").replace(/^M\d+:\s*/, "").trim();
1400
+ let milestoneTitle = stripGsdDisplayPrefix(dbMilestone?.title, milestoneId) ?? "";
1466
1401
  // Fallback: parse title from roadmap content header (e.g. "# M020: Backend foundation")
1467
1402
  if (!milestoneTitle && roadmapContent) {
1468
1403
  const titleMatch = roadmapContent.match(new RegExp(`^#\\s+${milestoneId}:\\s*(.+)`, "m"));
@@ -1471,15 +1406,22 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1471
1406
  }
1472
1407
  milestoneTitle = milestoneTitle || milestoneId;
1473
1408
  const subject = `feat: ${milestoneTitle}`;
1409
+ const milestoneContext = milestoneTitle === milestoneId
1410
+ ? `Milestone: ${milestoneId}`
1411
+ : `Milestone: ${milestoneId} - ${milestoneTitle}`;
1474
1412
  let body = "";
1475
1413
  if (completedSlices.length > 0) {
1476
1414
  const sliceLines = completedSlices
1477
1415
  .map((s) => `- ${s.id}: ${s.title}`)
1478
1416
  .join("\n");
1479
- body = `\n\nCompleted slices:\n${sliceLines}\n\nGSD-Milestone: ${milestoneId}\nBranch: ${milestoneBranch}`;
1417
+ const taskLines = completedSlices
1418
+ .flatMap((s) => s.tasks.map((task) => `- ${s.id}/${task.id}: ${task.title}`))
1419
+ .join("\n");
1420
+ const taskBlock = taskLines ? `\n\nCompleted tasks:\n${taskLines}` : "";
1421
+ body = `\n\nCompleted slices:\n${sliceLines}${taskBlock}\n\n${milestoneContext}\nGSD-Milestone: ${milestoneId}\nBranch: ${milestoneBranch}`;
1480
1422
  }
1481
1423
  else {
1482
- body = `\n\nGSD-Milestone: ${milestoneId}\nBranch: ${milestoneBranch}`;
1424
+ body = `\n\n${milestoneContext}\nGSD-Milestone: ${milestoneId}\nBranch: ${milestoneBranch}`;
1483
1425
  }
1484
1426
  const commitMessage = subject + body;
1485
1427
  // 6b. Reconcile worktree HEAD with milestone branch ref (#1846).
@@ -1680,17 +1622,7 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1680
1622
  // or interrupted operation) causes `git merge --squash` to refuse with
1681
1623
  // "fatal: You have not concluded your merge (MERGE_HEAD exists)".
1682
1624
  // Defensively remove merge artifacts before starting.
1683
- try {
1684
- const gitDir_ = resolveGitDir(originalBasePath_);
1685
- for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
1686
- const p = join(gitDir_, f);
1687
- if (existsSync(p))
1688
- unlinkSync(p);
1689
- }
1690
- }
1691
- catch (err) { /* best-effort */
1692
- logError("worktree", `merge state cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
1693
- }
1625
+ removeMergeStateFiles(originalBasePath_, "pre-merge");
1694
1626
  // 8. Squash merge — auto-resolve .gsd/ state file conflicts (#530)
1695
1627
  const mergeResult = nativeMergeSquash(originalBasePath_, milestoneBranch);
1696
1628
  if (!mergeResult.success) {
@@ -1700,17 +1632,7 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1700
1632
  if (mergeResult.conflicts.includes("__dirty_working_tree__")) {
1701
1633
  // Defensively clean merge state — the native path may leave MERGE_HEAD
1702
1634
  // even when the merge is rejected (#2912).
1703
- try {
1704
- const gitDir_ = resolveGitDir(originalBasePath_);
1705
- for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
1706
- const p = join(gitDir_, f);
1707
- if (existsSync(p))
1708
- unlinkSync(p);
1709
- }
1710
- }
1711
- catch (err) { /* best-effort */
1712
- logError("worktree", `merge state cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
1713
- }
1635
+ removeMergeStateFiles(originalBasePath_, "dirty-tree rejection");
1714
1636
  // Pop stash before throwing so local work is not lost.
1715
1637
  if (stashed) {
1716
1638
  try {
@@ -1759,26 +1681,7 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1759
1681
  }
1760
1682
  // If there are still real code conflicts, escalate
1761
1683
  if (codeConflicts.length > 0) {
1762
- // Abort merge state so MERGE_HEAD is not left on disk (#2912).
1763
- // libgit2's merge creates MERGE_HEAD even for squash merges; if left
1764
- // dangling, subsequent merges fail and doctor reports corrupt state.
1765
- try {
1766
- nativeMergeAbort(originalBasePath_);
1767
- }
1768
- catch (err) { /* best-effort */
1769
- logError("worktree", `git merge-abort failed: ${err instanceof Error ? err.message : String(err)}`);
1770
- }
1771
- try {
1772
- const gitDir_ = resolveGitDir(originalBasePath_);
1773
- for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
1774
- const p = join(gitDir_, f);
1775
- if (existsSync(p))
1776
- unlinkSync(p);
1777
- }
1778
- }
1779
- catch (err) { /* best-effort */
1780
- logError("worktree", `merge state file cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
1781
- }
1684
+ cleanupSquashConflictState(originalBasePath_);
1782
1685
  // Pop stash before throwing so local work is not lost (#2151).
1783
1686
  if (stashed) {
1784
1687
  try {
@@ -1809,17 +1712,7 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1809
1712
  // of which trigger git's SQUASH_MSG cleanup. MERGE_HEAD is created by
1810
1713
  // libgit2's merge even in squash mode and is not removed by nativeCommit.
1811
1714
  // If left on disk, doctor reports `corrupt_merge_state` on every subsequent run.
1812
- try {
1813
- const gitDir_ = resolveGitDir(originalBasePath_);
1814
- for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
1815
- const p = join(gitDir_, f);
1816
- if (existsSync(p))
1817
- unlinkSync(p);
1818
- }
1819
- }
1820
- catch (err) { /* best-effort */
1821
- logError("worktree", `post-commit merge state cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
1822
- }
1715
+ removeMergeStateFiles(originalBasePath_, "post-commit");
1823
1716
  // 9a-ii. Restore stashed files now that the merge+commit is complete (#2151).
1824
1717
  // Pop after commit so stashed changes do not interfere with the squash merge
1825
1718
  // or the commit content. Conflict on pop is non-fatal — the stash entry is