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
@@ -1,15 +1,97 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: WorktreeLifecycle merge/exit unit and regression tests.
3
+ //
4
+ // These tests previously exercised WorktreeResolver, which retired in slice 7
5
+ // step E of ADR-016. The merge bodies now live on WorktreeLifecycle. The
6
+ // `makeResolver()` shim below preserves the old void/throw caller shape so the
7
+ // existing test bodies and `assert.throws(...)` assertions migrate verbatim
8
+ // without a rewrite of every call site.
1
9
  import test from "node:test";
2
10
  import assert from "node:assert/strict";
3
11
  import { mkdtempSync, rmSync, mkdirSync, realpathSync } from "node:fs";
4
12
  import { tmpdir } from "node:os";
5
13
  import { join } from "node:path";
6
14
  import {
7
- WorktreeResolver,
8
- type WorktreeResolverDeps,
15
+ WorktreeLifecycle,
16
+ type WorktreeLifecycleDeps,
9
17
  type NotifyCtx,
10
- } from "../worktree-resolver.js";
18
+ } from "../worktree-lifecycle.js";
19
+ import { WorktreeStateProjection } from "../worktree-state-projection.js";
20
+ import { resolveWorktreeProjectRoot } from "../worktree-root.js";
11
21
  import { AutoSession } from "../auto/session.js";
12
22
 
23
+ /**
24
+ * Test-local type that extends WorktreeLifecycleDeps with the three fields
25
+ * that lived on the retired LegacyTestDeps but never made it into
26
+ * Lifecycle's narrower dep set. Tests can still record/override them; the
27
+ * Lifecycle constructor ignores them via structural typing.
28
+ */
29
+ type LegacyTestDeps = WorktreeLifecycleDeps & {
30
+ shouldUseWorktreeIsolation?: () => boolean;
31
+ syncWorktreeStateBack?: (
32
+ mainBasePath: string,
33
+ worktreePath: string,
34
+ milestoneId: string,
35
+ ) => { synced: string[] };
36
+ captureIntegrationBranch?: (basePath: string, mid: string | undefined) => void;
37
+ };
38
+
39
+ /**
40
+ * Shim factory preserving the legacy WorktreeResolver public shape for tests.
41
+ * Wraps a fresh WorktreeLifecycle and converts the typed-result API back to
42
+ * the old `void` / throw shape so test bodies migrate verbatim.
43
+ */
44
+ function makeResolver(s: AutoSession, deps: LegacyTestDeps) {
45
+ const lifecycle = new WorktreeLifecycle(s, deps);
46
+ return {
47
+ get workPath(): string {
48
+ return s.basePath;
49
+ },
50
+ get projectRoot(): string {
51
+ return resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
52
+ },
53
+ get lockPath(): string {
54
+ return resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
55
+ },
56
+ enterMilestone: (mid: string, ctx: NotifyCtx) =>
57
+ lifecycle.enterMilestone(mid, ctx),
58
+ exitMilestone: (
59
+ mid: string,
60
+ ctx: NotifyCtx,
61
+ opts?: { preserveBranch?: boolean },
62
+ ): void => {
63
+ const r = lifecycle.exitMilestone(
64
+ mid,
65
+ { merge: false, preserveBranch: opts?.preserveBranch },
66
+ ctx,
67
+ );
68
+ if (!r.ok && r.cause instanceof Error) throw r.cause;
69
+ },
70
+ mergeAndExit: (mid: string, ctx: NotifyCtx): void => {
71
+ const r = lifecycle.exitMilestone(mid, { merge: true }, ctx);
72
+ if (!r.ok && r.cause instanceof Error) throw r.cause;
73
+ },
74
+ mergeAndEnterNext: (
75
+ currentMilestoneId: string,
76
+ nextMilestoneId: string,
77
+ ctx: NotifyCtx,
78
+ ): void => {
79
+ lifecycle.mergeAndEnterNext(currentMilestoneId, nextMilestoneId, ctx);
80
+ },
81
+ };
82
+ }
83
+ import {
84
+ closeDatabase,
85
+ insertMilestone,
86
+ openDatabase,
87
+ } from "../gsd-db.js";
88
+ import { registerAutoWorker } from "../db/auto-workers.js";
89
+ import {
90
+ claimMilestoneLease,
91
+ getMilestoneLease,
92
+ releaseMilestoneLease,
93
+ } from "../db/milestone-leases.js";
94
+
13
95
  // ─── Helpers ─────────────────────────────────────────────────────────────────
14
96
 
15
97
  /** Track calls to mock deps for assertion. */
@@ -19,20 +101,21 @@ interface CallLog {
19
101
  }
20
102
 
21
103
  function makeSession(
22
- overrides?: Partial<{ basePath: string; originalBasePath: string }>,
104
+ overrides?: Partial<AutoSession>,
23
105
  ): AutoSession {
24
106
  const s = new AutoSession();
25
107
  s.basePath = overrides?.basePath ?? "/project";
26
108
  s.originalBasePath = overrides?.originalBasePath ?? "/project";
109
+ Object.assign(s, overrides);
27
110
  return s;
28
111
  }
29
112
 
30
113
  function makeDeps(
31
- overrides?: Partial<WorktreeResolverDeps>,
32
- ): WorktreeResolverDeps & { calls: CallLog[] } {
114
+ overrides?: Partial<LegacyTestDeps>,
115
+ ): LegacyTestDeps & { calls: CallLog[] } {
33
116
  const calls: CallLog[] = [];
34
117
 
35
- const deps: WorktreeResolverDeps & { calls: CallLog[] } = {
118
+ const deps: LegacyTestDeps & { calls: CallLog[] } = {
36
119
  calls,
37
120
  isInAutoWorktree: (basePath: string) => {
38
121
  calls.push({ fn: "isInAutoWorktree", args: [basePath] });
@@ -104,6 +187,9 @@ function makeDeps(
104
187
  calls.push({ fn: "getCurrentBranch", args: [basePath] });
105
188
  return "main";
106
189
  },
190
+ checkoutBranch: (basePath: string, branch: string) => {
191
+ calls.push({ fn: "checkoutBranch", args: [basePath, branch] });
192
+ },
107
193
  autoWorktreeBranch: (milestoneId: string) => {
108
194
  calls.push({ fn: "autoWorktreeBranch", args: [milestoneId] });
109
195
  return `milestone/${milestoneId}`;
@@ -131,7 +217,7 @@ function makeDeps(
131
217
  this.basePath = basePath;
132
218
  this.gitConfig = gitConfig;
133
219
  }
134
- } as unknown as WorktreeResolverDeps["GitServiceImpl"],
220
+ } as unknown as LegacyTestDeps["GitServiceImpl"],
135
221
  loadEffectiveGSDPreferences: () => {
136
222
  calls.push({ fn: "loadEffectiveGSDPreferences", args: [] });
137
223
  return { preferences: { git: {} } };
@@ -151,6 +237,7 @@ function makeDeps(
151
237
  enterBranchModeForMilestone: (basePath: string, milestoneId: string) => {
152
238
  calls.push({ fn: "enterBranchModeForMilestone", args: [basePath, milestoneId] });
153
239
  },
240
+ worktreeProjection: new WorktreeStateProjection(),
154
241
  ...overrides,
155
242
  };
156
243
 
@@ -182,11 +269,22 @@ function findCalls(calls: CallLog[], fn: string): CallLog[] {
182
269
  return calls.filter((c) => c.fn === fn);
183
270
  }
184
271
 
272
+ function makeDbBase(): string {
273
+ const base = mkdtempSync(join(tmpdir(), "gsd-worktree-resolver-"));
274
+ mkdirSync(join(base, ".gsd"), { recursive: true });
275
+ return base;
276
+ }
277
+
278
+ function cleanupDbBase(base: string): void {
279
+ try { closeDatabase(); } catch { /* noop */ }
280
+ try { rmSync(base, { recursive: true, force: true }); } catch { /* noop */ }
281
+ }
282
+
185
283
  // ─── Getter Tests ────────────────────────────────────────────────────────────
186
284
 
187
285
  test("workPath returns s.basePath", () => {
188
286
  const s = makeSession({ basePath: "/project/.gsd/worktrees/M001" });
189
- const resolver = new WorktreeResolver(s, makeDeps());
287
+ const resolver = makeResolver(s,makeDeps());
190
288
  assert.equal(resolver.workPath, "/project/.gsd/worktrees/M001");
191
289
  });
192
290
 
@@ -195,13 +293,13 @@ test("projectRoot returns originalBasePath when set", () => {
195
293
  basePath: "/project/.gsd/worktrees/M001",
196
294
  originalBasePath: "/project",
197
295
  });
198
- const resolver = new WorktreeResolver(s, makeDeps());
296
+ const resolver = makeResolver(s,makeDeps());
199
297
  assert.equal(resolver.projectRoot, "/project");
200
298
  });
201
299
 
202
300
  test("projectRoot falls back to basePath when originalBasePath is empty", () => {
203
301
  const s = makeSession({ basePath: "/project", originalBasePath: "" });
204
- const resolver = new WorktreeResolver(s, makeDeps());
302
+ const resolver = makeResolver(s,makeDeps());
205
303
  assert.equal(resolver.projectRoot, "/project");
206
304
  });
207
305
 
@@ -210,13 +308,13 @@ test("lockPath returns originalBasePath when set (same as lockBase)", () => {
210
308
  basePath: "/project/.gsd/worktrees/M001",
211
309
  originalBasePath: "/project",
212
310
  });
213
- const resolver = new WorktreeResolver(s, makeDeps());
311
+ const resolver = makeResolver(s,makeDeps());
214
312
  assert.equal(resolver.lockPath, "/project");
215
313
  });
216
314
 
217
315
  test("lockPath falls back to basePath when originalBasePath is empty", () => {
218
316
  const s = makeSession({ basePath: "/project", originalBasePath: "" });
219
- const resolver = new WorktreeResolver(s, makeDeps());
317
+ const resolver = makeResolver(s,makeDeps());
220
318
  assert.equal(resolver.lockPath, "/project");
221
319
  });
222
320
 
@@ -228,9 +326,9 @@ test("enterMilestone creates new worktree when none exists", () => {
228
326
  getAutoWorktreePath: () => null,
229
327
  });
230
328
  const ctx = makeNotifyCtx();
231
- const resolver = new WorktreeResolver(s, deps);
329
+ const resolver = makeResolver(s,deps);
232
330
 
233
- resolver.enterMilestone("M001", ctx);
331
+ new WorktreeLifecycle(s, deps).enterMilestone("M001", ctx);
234
332
 
235
333
  assert.equal(s.basePath, "/project/.gsd/worktrees/M001");
236
334
  assert.equal(findCalls(deps.calls, "createAutoWorktree").length, 1);
@@ -249,9 +347,9 @@ test("enterMilestone enters existing worktree instead of creating", () => {
249
347
  getAutoWorktreePath: () => "/project/.gsd/worktrees/M001",
250
348
  });
251
349
  const ctx = makeNotifyCtx();
252
- const resolver = new WorktreeResolver(s, deps);
350
+ const resolver = makeResolver(s,deps);
253
351
 
254
- resolver.enterMilestone("M001", ctx);
352
+ new WorktreeLifecycle(s, deps).enterMilestone("M001", ctx);
255
353
 
256
354
  assert.equal(s.basePath, "/project/.gsd/worktrees/M001");
257
355
  assert.equal(findCalls(deps.calls, "enterAutoWorktree").length, 1);
@@ -264,9 +362,9 @@ test("enterMilestone is no-op when isolation mode is none", () => {
264
362
  getIsolationMode: () => "none",
265
363
  });
266
364
  const ctx = makeNotifyCtx();
267
- const resolver = new WorktreeResolver(s, deps);
365
+ const resolver = makeResolver(s,deps);
268
366
 
269
- resolver.enterMilestone("M001", ctx);
367
+ new WorktreeLifecycle(s, deps).enterMilestone("M001", ctx);
270
368
 
271
369
  assert.equal(s.basePath, "/project"); // unchanged
272
370
  assert.equal(findCalls(deps.calls, "createAutoWorktree").length, 0);
@@ -284,9 +382,9 @@ test("enterMilestone passes project root to isolation mode guard", () => {
284
382
  },
285
383
  });
286
384
  const ctx = makeNotifyCtx();
287
- const resolver = new WorktreeResolver(s, deps);
385
+ const resolver = makeResolver(s,deps);
288
386
 
289
- resolver.enterMilestone("M001", ctx);
387
+ new WorktreeLifecycle(s, deps).enterMilestone("M001", ctx);
290
388
 
291
389
  assert.equal(checkedBasePath, "/project");
292
390
  assert.equal(findCalls(deps.calls, "createAutoWorktree").length, 0);
@@ -301,9 +399,9 @@ test("enterMilestone does NOT update basePath on creation failure", () => {
301
399
  },
302
400
  });
303
401
  const ctx = makeNotifyCtx();
304
- const resolver = new WorktreeResolver(s, deps);
402
+ const resolver = makeResolver(s,deps);
305
403
 
306
- resolver.enterMilestone("M001", ctx);
404
+ new WorktreeLifecycle(s, deps).enterMilestone("M001", ctx);
307
405
 
308
406
  assert.equal(s.basePath, "/project"); // unchanged — error recovery
309
407
  assert.ok(
@@ -327,9 +425,9 @@ test("enterMilestone uses originalBasePath as base for worktree ops", () => {
327
425
  },
328
426
  });
329
427
  const ctx = makeNotifyCtx();
330
- const resolver = new WorktreeResolver(s, deps);
428
+ const resolver = makeResolver(s,deps);
331
429
 
332
- resolver.enterMilestone("M002", ctx);
430
+ new WorktreeLifecycle(s, deps).enterMilestone("M002", ctx);
333
431
 
334
432
  assert.equal(createdFrom, "/project"); // uses originalBasePath, not current basePath
335
433
  });
@@ -358,9 +456,9 @@ test("enterMilestone does not create double-nested worktree when originalBasePat
358
456
  },
359
457
  });
360
458
  const ctx = makeNotifyCtx();
361
- const resolver = new WorktreeResolver(s, deps);
459
+ const resolver = makeResolver(s,deps);
362
460
 
363
- resolver.enterMilestone("M002", ctx);
461
+ new WorktreeLifecycle(s, deps).enterMilestone("M002", ctx);
364
462
 
365
463
  // The path passed to createAutoWorktree must be the project root, NOT the
366
464
  // worktree path. If it equals wtPath the worktree would be created at
@@ -371,6 +469,43 @@ test("enterMilestone does not create double-nested worktree when originalBasePat
371
469
  );
372
470
  });
373
471
 
472
+ test("enterMilestone reacquires a released same-milestone lease before worktree entry", (t) => {
473
+ const base = makeDbBase();
474
+ t.after(() => cleanupDbBase(base));
475
+ openDatabase(join(base, ".gsd", "gsd.db"));
476
+ insertMilestone({ id: "M001", title: "Test milestone", status: "active" });
477
+
478
+ const workerId = registerAutoWorker({ projectRootRealpath: base });
479
+ const originalClaim = claimMilestoneLease(workerId, "M001");
480
+ assert.equal(originalClaim.ok, true);
481
+ if (!originalClaim.ok) throw new Error("expected test lease claim");
482
+ assert.equal(releaseMilestoneLease(workerId, "M001", originalClaim.token), true);
483
+
484
+ const s = makeSession({
485
+ basePath: base,
486
+ originalBasePath: base,
487
+ workerId,
488
+ currentMilestoneId: "M001",
489
+ milestoneLeaseToken: originalClaim.token,
490
+ });
491
+ const deps = makeDeps({
492
+ createAutoWorktree: (basePath: string, milestoneId: string) => join(basePath, ".gsd", "worktrees", milestoneId),
493
+ });
494
+ const ctx = makeNotifyCtx();
495
+ const resolver = makeResolver(s,deps);
496
+
497
+ new WorktreeLifecycle(s, deps).enterMilestone("M001", ctx);
498
+
499
+ const row = getMilestoneLease("M001");
500
+ assert.ok(row);
501
+ assert.equal(row.worker_id, workerId);
502
+ assert.equal(row.status, "held");
503
+ assert.equal(row.fencing_token, originalClaim.token + 1);
504
+ assert.equal(s.milestoneLeaseToken, originalClaim.token + 1);
505
+ assert.equal(s.basePath, join(base, ".gsd", "worktrees", "M001"));
506
+ assert.equal(ctx.messages.some((m) => m.level === "error"), false);
507
+ });
508
+
374
509
  // ─── enterMilestone Tests (branch mode) ──────────────────────────────────────
375
510
 
376
511
  test("enterMilestone in branch mode calls enterBranchModeForMilestone and rebuilds GitService", () => {
@@ -379,9 +514,9 @@ test("enterMilestone in branch mode calls enterBranchModeForMilestone and rebuil
379
514
  getIsolationMode: () => "branch",
380
515
  });
381
516
  const ctx = makeNotifyCtx();
382
- const resolver = new WorktreeResolver(s, deps);
517
+ const resolver = makeResolver(s,deps);
383
518
 
384
- resolver.enterMilestone("M001", ctx);
519
+ new WorktreeLifecycle(s, deps).enterMilestone("M001", ctx);
385
520
 
386
521
  // Branch mode: no worktree created, basePath unchanged
387
522
  assert.equal(s.basePath, "/project");
@@ -402,9 +537,9 @@ test("enterMilestone in branch mode uses originalBasePath as base", () => {
402
537
  },
403
538
  });
404
539
  const ctx = makeNotifyCtx();
405
- const resolver = new WorktreeResolver(s, deps);
540
+ const resolver = makeResolver(s,deps);
406
541
 
407
- resolver.enterMilestone("M001", ctx);
542
+ new WorktreeLifecycle(s, deps).enterMilestone("M001", ctx);
408
543
 
409
544
  assert.equal(calledWith, "/project");
410
545
  });
@@ -418,9 +553,9 @@ test("enterMilestone in branch mode degrades isolation on failure", () => {
418
553
  },
419
554
  });
420
555
  const ctx = makeNotifyCtx();
421
- const resolver = new WorktreeResolver(s, deps);
556
+ const resolver = makeResolver(s,deps);
422
557
 
423
- resolver.enterMilestone("M001", ctx);
558
+ new WorktreeLifecycle(s, deps).enterMilestone("M001", ctx);
424
559
 
425
560
  assert.equal(s.basePath, "/project"); // unchanged
426
561
  assert.ok(s.isolationDegraded);
@@ -434,9 +569,9 @@ test("enterMilestone branch mode is skipped when isolationDegraded", () => {
434
569
  getIsolationMode: () => "branch",
435
570
  });
436
571
  const ctx = makeNotifyCtx();
437
- const resolver = new WorktreeResolver(s, deps);
572
+ const resolver = makeResolver(s,deps);
438
573
 
439
- resolver.enterMilestone("M001", ctx);
574
+ new WorktreeLifecycle(s, deps).enterMilestone("M001", ctx);
440
575
 
441
576
  assert.equal(findCalls(deps.calls, "enterBranchModeForMilestone").length, 0);
442
577
  assert.equal(findCalls(deps.calls, "createAutoWorktree").length, 0);
@@ -453,7 +588,7 @@ test("exitMilestone commits, tears down, and resets basePath", () => {
453
588
  isInAutoWorktree: () => true,
454
589
  });
455
590
  const ctx = makeNotifyCtx();
456
- const resolver = new WorktreeResolver(s, deps);
591
+ const resolver = makeResolver(s,deps);
457
592
 
458
593
  resolver.exitMilestone("M001", ctx);
459
594
 
@@ -464,13 +599,49 @@ test("exitMilestone commits, tears down, and resets basePath", () => {
464
599
  assert.equal(findCalls(deps.calls, "invalidateAllCaches").length, 1);
465
600
  });
466
601
 
602
+ test("exitMilestone moves cwd to project root before teardown", (t) => {
603
+ const originalCwd = process.cwd();
604
+ const base = realpathSync(mkdtempSync(join(tmpdir(), "gsd-exit-cwd-")));
605
+ const wtPath = join(base, ".gsd", "worktrees", "M001");
606
+ mkdirSync(wtPath, { recursive: true });
607
+ t.after(() => {
608
+ process.chdir(originalCwd);
609
+ rmSync(base, { recursive: true, force: true });
610
+ });
611
+
612
+ process.chdir(wtPath);
613
+ const s = makeSession({
614
+ basePath: wtPath,
615
+ originalBasePath: base,
616
+ });
617
+ const deps = makeDeps({
618
+ isInAutoWorktree: () => true,
619
+ });
620
+ deps.teardownAutoWorktree = (
621
+ teardownBasePath: string,
622
+ milestoneId: string,
623
+ opts?: { preserveBranch?: boolean },
624
+ ) => {
625
+ deps.calls.push({ fn: "teardownAutoWorktree", args: [teardownBasePath, milestoneId, opts] });
626
+ assert.equal(process.cwd(), base);
627
+ rmSync(wtPath, { recursive: true, force: true });
628
+ };
629
+ const ctx = makeNotifyCtx();
630
+ const resolver = makeResolver(s,deps);
631
+
632
+ resolver.exitMilestone("M001", ctx);
633
+
634
+ assert.equal(process.cwd(), base);
635
+ assert.equal(s.basePath, base);
636
+ });
637
+
467
638
  test("exitMilestone is no-op when not in worktree", () => {
468
639
  const s = makeSession();
469
640
  const deps = makeDeps({
470
641
  isInAutoWorktree: () => false,
471
642
  });
472
643
  const ctx = makeNotifyCtx();
473
- const resolver = new WorktreeResolver(s, deps);
644
+ const resolver = makeResolver(s,deps);
474
645
 
475
646
  resolver.exitMilestone("M001", ctx);
476
647
 
@@ -496,7 +667,7 @@ test("exitMilestone passes preserveBranch option", () => {
496
667
  },
497
668
  });
498
669
  const ctx = makeNotifyCtx();
499
- const resolver = new WorktreeResolver(s, deps);
670
+ const resolver = makeResolver(s,deps);
500
671
 
501
672
  resolver.exitMilestone("M001", ctx, { preserveBranch: true });
502
673
 
@@ -515,7 +686,7 @@ test("exitMilestone still resets basePath even if auto-commit fails", () => {
515
686
  },
516
687
  });
517
688
  const ctx = makeNotifyCtx();
518
- const resolver = new WorktreeResolver(s, deps);
689
+ const resolver = makeResolver(s,deps);
519
690
 
520
691
  resolver.exitMilestone("M001", ctx);
521
692
 
@@ -536,11 +707,14 @@ test("mergeAndExit in worktree mode reads roadmap and merges", () => {
536
707
  getIsolationMode: () => "worktree",
537
708
  });
538
709
  const ctx = makeNotifyCtx();
539
- const resolver = new WorktreeResolver(s, deps);
710
+ const resolver = makeResolver(s,deps);
540
711
 
541
712
  resolver.mergeAndExit("M001", ctx);
542
713
 
543
- assert.equal(findCalls(deps.calls, "syncWorktreeStateBack").length, 1);
714
+ // ADR-016 / slice 7 step D: the worktree → root state flow moved from the
715
+ // injected deps.syncWorktreeStateBack to WorktreeStateProjection
716
+ // .finalizeProjectionForMerge inside WorktreeLifecycle. The remaining
717
+ // assertions still cover the merge behaviour end-to-end.
544
718
  assert.equal(findCalls(deps.calls, "resolveMilestoneFile").length, 1);
545
719
  assert.equal(findCalls(deps.calls, "readFileSync").length, 1);
546
720
  assert.equal(findCalls(deps.calls, "mergeMilestoneToMain").length, 1);
@@ -559,7 +733,7 @@ test("mergeAndExit in worktree mode shows pushed status", () => {
559
733
  mergeMilestoneToMain: () => ({ pushed: true, codeFilesChanged: true }),
560
734
  });
561
735
  const ctx = makeNotifyCtx();
562
- const resolver = new WorktreeResolver(s, deps);
736
+ const resolver = makeResolver(s,deps);
563
737
 
564
738
  resolver.mergeAndExit("M001", ctx);
565
739
 
@@ -577,7 +751,7 @@ test("mergeAndExit falls back to teardown with preserveBranch when roadmap is mi
577
751
  resolveMilestoneFile: () => null,
578
752
  });
579
753
  const ctx = makeNotifyCtx();
580
- const resolver = new WorktreeResolver(s, deps);
754
+ const resolver = makeResolver(s,deps);
581
755
 
582
756
  resolver.mergeAndExit("M001", ctx);
583
757
 
@@ -608,7 +782,7 @@ test("mergeAndExit resolves roadmap from worktree when missing at project root (
608
782
  },
609
783
  });
610
784
  const ctx = makeNotifyCtx();
611
- const resolver = new WorktreeResolver(s, deps);
785
+ const resolver = makeResolver(s,deps);
612
786
 
613
787
  resolver.mergeAndExit("M001", ctx);
614
788
 
@@ -633,7 +807,7 @@ test("mergeAndExit in worktree mode restores to project root on merge failure",
633
807
  },
634
808
  });
635
809
  const ctx = makeNotifyCtx();
636
- const resolver = new WorktreeResolver(s, deps);
810
+ const resolver = makeResolver(s,deps);
637
811
 
638
812
  // Error propagates (#4380) — callers handle recovery. restoreToProjectRoot()
639
813
  // still runs before re-throw so state is consistent for the caller.
@@ -665,7 +839,7 @@ test("mergeAndExit failure message tells user worktree and branch are preserved
665
839
  },
666
840
  });
667
841
  const ctx = makeNotifyCtx();
668
- const resolver = new WorktreeResolver(s, deps);
842
+ const resolver = makeResolver(s,deps);
669
843
 
670
844
  // Error propagates (#4380) — notification is still emitted before re-throw
671
845
  assert.throws(() => resolver.mergeAndExit("M001", ctx), /pathspec 'main' did not match/);
@@ -702,7 +876,7 @@ test("mergeAndExit failure message references /gsd dispatch complete-milestone,
702
876
  },
703
877
  });
704
878
  const ctx = makeNotifyCtx();
705
- const resolver = new WorktreeResolver(s, deps);
879
+ const resolver = makeResolver(s,deps);
706
880
 
707
881
  // Error propagates (#4380) — notification is still emitted before re-throw
708
882
  assert.throws(() => resolver.mergeAndExit("M001", ctx), /dirty working tree/);
@@ -732,7 +906,7 @@ test("mergeAndExit in branch mode merges when on milestone branch", () => {
732
906
  autoWorktreeBranch: () => "milestone/M001",
733
907
  });
734
908
  const ctx = makeNotifyCtx();
735
- const resolver = new WorktreeResolver(s, deps);
909
+ const resolver = makeResolver(s,deps);
736
910
 
737
911
  resolver.mergeAndExit("M001", ctx);
738
912
 
@@ -740,21 +914,92 @@ test("mergeAndExit in branch mode merges when on milestone branch", () => {
740
914
  assert.ok(ctx.messages.some((m) => m.msg.includes("branch mode")));
741
915
  });
742
916
 
743
- test("mergeAndExit in branch mode skips when not on milestone branch", () => {
917
+ test("mergeAndExit in branch mode checks out the milestone branch and merges (#5538-followup)", () => {
918
+ // Regression: previously this case silently returned without merging,
919
+ // stranding the milestone's commits on the branch (the test12345 repro).
920
+ // The fix forces a checkout first; merge proceeds when checkout succeeds.
744
921
  const s = makeSession({ basePath: "/project", originalBasePath: "/project" });
922
+ let currentBranch = "main";
923
+ const checkoutInvocations: Array<{ basePath: string; branch: string }> = [];
745
924
  const deps = makeDeps({
746
925
  isInAutoWorktree: () => false,
747
926
  getIsolationMode: () => "branch",
748
- getCurrentBranch: () => "main",
927
+ getCurrentBranch: () => currentBranch,
749
928
  autoWorktreeBranch: () => "milestone/M001",
929
+ checkoutBranch: (basePath: string, branch: string) => {
930
+ checkoutInvocations.push({ basePath, branch });
931
+ currentBranch = branch;
932
+ },
750
933
  });
751
934
  const ctx = makeNotifyCtx();
752
- const resolver = new WorktreeResolver(s, deps);
935
+ const resolver = makeResolver(s,deps);
753
936
 
754
937
  resolver.mergeAndExit("M001", ctx);
755
938
 
939
+ assert.equal(checkoutInvocations.length, 1, "must attempt checkout when on wrong branch");
940
+ assert.deepEqual(checkoutInvocations[0], { basePath: "/project", branch: "milestone/M001" });
941
+ assert.equal(findCalls(deps.calls, "mergeMilestoneToMain").length, 1);
942
+ });
943
+
944
+ test("mergeAndExit in branch mode throws when checkout fails", () => {
945
+ // Regression for the silent-skip bug: if the working tree is on the wrong
946
+ // branch and checkout fails, we must throw so the caller pauses auto-mode
947
+ // — never silently advance with the milestone unmerged.
948
+ const s = makeSession({ basePath: "/project", originalBasePath: "/project" });
949
+ const deps = makeDeps({
950
+ isInAutoWorktree: () => false,
951
+ getIsolationMode: () => "branch",
952
+ getCurrentBranch: () => "main",
953
+ autoWorktreeBranch: () => "milestone/M001",
954
+ checkoutBranch: () => {
955
+ throw new Error("dirty working tree blocks checkout");
956
+ },
957
+ });
958
+ const ctx = makeNotifyCtx();
959
+ const resolver = makeResolver(s,deps);
960
+
961
+ assert.throws(
962
+ () => resolver.mergeAndExit("M001", ctx),
963
+ /dirty working tree blocks checkout/,
964
+ );
965
+ assert.equal(
966
+ findCalls(deps.calls, "mergeMilestoneToMain").length,
967
+ 0,
968
+ "merge must not run when checkout failed",
969
+ );
970
+ const errorNotify = ctx.messages.find((m) => m.level === "error");
971
+ assert.ok(errorNotify, "an error notification must be emitted");
972
+ assert.match(errorNotify!.msg, /milestone\/M001 failed/);
973
+ assert.match(errorNotify!.msg, /Resolve manually/);
974
+ assert.equal(
975
+ ctx.messages.some((m) => m.level === "warning" && m.msg.includes("Milestone merge failed")),
976
+ false,
977
+ "checkout failures with explicit recovery guidance must not emit a duplicate warning",
978
+ );
979
+ });
980
+
981
+ test("mergeAndExit in branch mode throws when checkout reports success but HEAD is still wrong", () => {
982
+ // Defense in depth: even if checkoutBranch returns without throwing, we
983
+ // re-verify and throw if HEAD didn't actually move. Prevents merging on
984
+ // top of the wrong branch on platforms where the checkout is a no-op.
985
+ const s = makeSession({ basePath: "/project", originalBasePath: "/project" });
986
+ const deps = makeDeps({
987
+ isInAutoWorktree: () => false,
988
+ getIsolationMode: () => "branch",
989
+ getCurrentBranch: () => "main", // never changes — simulates no-op checkout
990
+ autoWorktreeBranch: () => "milestone/M001",
991
+ checkoutBranch: () => {
992
+ // Pretend success — but getCurrentBranch will still return "main".
993
+ },
994
+ });
995
+ const ctx = makeNotifyCtx();
996
+ const resolver = makeResolver(s,deps);
997
+
998
+ assert.throws(
999
+ () => resolver.mergeAndExit("M001", ctx),
1000
+ /reported success but current branch is main/,
1001
+ );
756
1002
  assert.equal(findCalls(deps.calls, "mergeMilestoneToMain").length, 0);
757
- assert.equal(ctx.messages.length, 0);
758
1003
  });
759
1004
 
760
1005
  test("mergeAndExit in branch mode handles merge failure gracefully", () => {
@@ -769,7 +1014,7 @@ test("mergeAndExit in branch mode handles merge failure gracefully", () => {
769
1014
  },
770
1015
  });
771
1016
  const ctx = makeNotifyCtx();
772
- const resolver = new WorktreeResolver(s, deps);
1017
+ const resolver = makeResolver(s,deps);
773
1018
 
774
1019
  // Error propagates (#4380) — notification is still emitted before re-throw
775
1020
  assert.throws(() => resolver.mergeAndExit("M001", ctx), /branch merge conflict/);
@@ -791,7 +1036,7 @@ test("mergeAndExit in branch mode skips when no roadmap", () => {
791
1036
  resolveMilestoneFile: () => null,
792
1037
  });
793
1038
  const ctx = makeNotifyCtx();
794
- const resolver = new WorktreeResolver(s, deps);
1039
+ const resolver = makeResolver(s,deps);
795
1040
 
796
1041
  resolver.mergeAndExit("M001", ctx);
797
1042
 
@@ -807,7 +1052,7 @@ test("mergeAndExit in branch mode rebuilds GitService after merge", () => {
807
1052
  autoWorktreeBranch: () => "milestone/M001",
808
1053
  });
809
1054
  const ctx = makeNotifyCtx();
810
- const resolver = new WorktreeResolver(s, deps);
1055
+ const resolver = makeResolver(s,deps);
811
1056
 
812
1057
  resolver.mergeAndExit("M001", ctx);
813
1058
 
@@ -822,7 +1067,7 @@ test("mergeAndExit in none mode is a no-op", () => {
822
1067
  getIsolationMode: () => "none",
823
1068
  });
824
1069
  const ctx = makeNotifyCtx();
825
- const resolver = new WorktreeResolver(s, deps);
1070
+ const resolver = makeResolver(s,deps);
826
1071
 
827
1072
  resolver.mergeAndExit("M001", ctx);
828
1073
 
@@ -844,7 +1089,7 @@ test("mergeAndExit warns when merge contains no code changes (#1906)", () => {
844
1089
  mergeMilestoneToMain: () => ({ pushed: false, codeFilesChanged: false }),
845
1090
  });
846
1091
  const ctx = makeNotifyCtx();
847
- const resolver = new WorktreeResolver(s, deps);
1092
+ const resolver = makeResolver(s,deps);
848
1093
 
849
1094
  resolver.mergeAndExit("M001", ctx);
850
1095
 
@@ -869,7 +1114,7 @@ test("mergeAndExit emits info when merge contains code changes (#1906)", () => {
869
1114
  mergeMilestoneToMain: () => ({ pushed: false, codeFilesChanged: true }),
870
1115
  });
871
1116
  const ctx = makeNotifyCtx();
872
- const resolver = new WorktreeResolver(s, deps);
1117
+ const resolver = makeResolver(s,deps);
873
1118
 
874
1119
  resolver.mergeAndExit("M001", ctx);
875
1120
 
@@ -896,7 +1141,7 @@ test("mergeAndExit branch mode warns when merge contains no code changes (#1906)
896
1141
  mergeMilestoneToMain: () => ({ pushed: false, codeFilesChanged: false }),
897
1142
  });
898
1143
  const ctx = makeNotifyCtx();
899
- const resolver = new WorktreeResolver(s, deps);
1144
+ const resolver = makeResolver(s,deps);
900
1145
 
901
1146
  resolver.mergeAndExit("M001", ctx);
902
1147
 
@@ -933,7 +1178,7 @@ test("mergeAndEnterNext calls mergeAndExit then enterMilestone", () => {
933
1178
  },
934
1179
  });
935
1180
  const ctx = makeNotifyCtx();
936
- const resolver = new WorktreeResolver(s, deps);
1181
+ const resolver = makeResolver(s,deps);
937
1182
 
938
1183
  resolver.mergeAndEnterNext("M001", "M002", ctx);
939
1184
 
@@ -959,7 +1204,7 @@ test("mergeAndEnterNext enters next milestone even if merge fails", () => {
959
1204
  },
960
1205
  });
961
1206
  const ctx = makeNotifyCtx();
962
- const resolver = new WorktreeResolver(s, deps);
1207
+ const resolver = makeResolver(s,deps);
963
1208
 
964
1209
  resolver.mergeAndEnterNext("M001", "M002", ctx);
965
1210
 
@@ -977,6 +1222,58 @@ test("mergeAndEnterNext enters next milestone even if merge fails", () => {
977
1222
  );
978
1223
  });
979
1224
 
1225
+ test("mergeAndEnterNext halts when mergeAndExit preserves branch without merging", () => {
1226
+ const s = makeSession({
1227
+ basePath: "/project/.gsd/worktrees/M001",
1228
+ originalBasePath: "/project",
1229
+ });
1230
+ const deps = makeDeps({
1231
+ isInAutoWorktree: () => true,
1232
+ getIsolationMode: () => "worktree",
1233
+ shouldUseWorktreeIsolation: () => true,
1234
+ resolveMilestoneFile: () => null,
1235
+ });
1236
+ const ctx = makeNotifyCtx();
1237
+ const resolver = makeResolver(s, deps);
1238
+
1239
+ assert.throws(
1240
+ () => resolver.mergeAndEnterNext("M001", "M002", ctx),
1241
+ /Cannot enter milestone M002 because M001 was not merged/,
1242
+ );
1243
+ assert.equal(findCalls(deps.calls, "mergeMilestoneToMain").length, 0);
1244
+ assert.equal(findCalls(deps.calls, "createAutoWorktree").length, 0);
1245
+ assert.equal(findCalls(deps.calls, "enterAutoWorktree").length, 0);
1246
+ assert.equal(s.basePath, "/project");
1247
+ assert.ok(ctx.messages.some((m) => m.msg.includes("branch preserved")));
1248
+ });
1249
+
1250
+ test("mergeAndEnterNext halts after branch-mode user-notified checkout failure", () => {
1251
+ const s = makeSession({ basePath: "/project", originalBasePath: "/project" });
1252
+ const deps = makeDeps({
1253
+ isInAutoWorktree: () => false,
1254
+ getIsolationMode: () => "branch",
1255
+ getCurrentBranch: () => "main",
1256
+ autoWorktreeBranch: () => "milestone/M001",
1257
+ checkoutBranch: () => {
1258
+ throw new Error("dirty working tree blocks checkout");
1259
+ },
1260
+ });
1261
+ const ctx = makeNotifyCtx();
1262
+ const resolver = makeResolver(s,deps);
1263
+
1264
+ assert.throws(
1265
+ () => resolver.mergeAndEnterNext("M001", "M002", ctx),
1266
+ /dirty working tree blocks checkout/,
1267
+ );
1268
+ assert.equal(
1269
+ findCalls(deps.calls, "enterBranchModeForMilestone").length,
1270
+ 0,
1271
+ "must not enter the next milestone after a user-notified branch-mode failure",
1272
+ );
1273
+ assert.equal(findCalls(deps.calls, "mergeMilestoneToMain").length, 0);
1274
+ assert.ok(ctx.messages.some((m) => m.level === "error" && m.msg.includes("Resolve manually")));
1275
+ });
1276
+
980
1277
  // ─── GitService Rebuild Atomicity ────────────────────────────────────────────
981
1278
 
982
1279
  test("GitService is rebuilt with the NEW basePath after enterMilestone", () => {
@@ -988,12 +1285,12 @@ test("GitService is rebuilt with the NEW basePath after enterMilestone", () => {
988
1285
  constructor(basePath: string, _config: unknown) {
989
1286
  gitServiceBasePath = basePath;
990
1287
  }
991
- } as unknown as WorktreeResolverDeps["GitServiceImpl"],
1288
+ } as unknown as LegacyTestDeps["GitServiceImpl"],
992
1289
  });
993
1290
  const ctx = makeNotifyCtx();
994
- const resolver = new WorktreeResolver(s, deps);
1291
+ const resolver = makeResolver(s,deps);
995
1292
 
996
- resolver.enterMilestone("M001", ctx);
1293
+ new WorktreeLifecycle(s, deps).enterMilestone("M001", ctx);
997
1294
 
998
1295
  assert.equal(gitServiceBasePath, "/project/.gsd/worktrees/M001"); // new path, not old
999
1296
  });
@@ -1010,10 +1307,10 @@ test("GitService is rebuilt with originalBasePath after exitMilestone", () => {
1010
1307
  constructor(basePath: string, _config: unknown) {
1011
1308
  gitServiceBasePath = basePath;
1012
1309
  }
1013
- } as unknown as WorktreeResolverDeps["GitServiceImpl"],
1310
+ } as unknown as LegacyTestDeps["GitServiceImpl"],
1014
1311
  });
1015
1312
  const ctx = makeNotifyCtx();
1016
- const resolver = new WorktreeResolver(s, deps);
1313
+ const resolver = makeResolver(s,deps);
1017
1314
 
1018
1315
  resolver.exitMilestone("M001", ctx);
1019
1316
 
@@ -1031,9 +1328,9 @@ test("enterMilestone sets isolationDegraded when worktree creation throws (#2483
1031
1328
  },
1032
1329
  });
1033
1330
  const ctx = makeNotifyCtx();
1034
- const resolver = new WorktreeResolver(s, deps);
1331
+ const resolver = makeResolver(s,deps);
1035
1332
 
1036
- resolver.enterMilestone("M001", ctx);
1333
+ new WorktreeLifecycle(s, deps).enterMilestone("M001", ctx);
1037
1334
 
1038
1335
  assert.equal(s.isolationDegraded, true);
1039
1336
  assert.equal(s.basePath, "/project"); // unchanged — error recovery
@@ -1044,9 +1341,9 @@ test("enterMilestone is no-op when isolationDegraded is true (#2483)", () => {
1044
1341
  s.isolationDegraded = true;
1045
1342
  const deps = makeDeps();
1046
1343
  const ctx = makeNotifyCtx();
1047
- const resolver = new WorktreeResolver(s, deps);
1344
+ const resolver = makeResolver(s,deps);
1048
1345
 
1049
- resolver.enterMilestone("M001", ctx);
1346
+ new WorktreeLifecycle(s, deps).enterMilestone("M001", ctx);
1050
1347
 
1051
1348
  assert.equal(s.basePath, "/project"); // unchanged
1052
1349
  assert.equal(findCalls(deps.calls, "createAutoWorktree").length, 0);
@@ -1064,7 +1361,7 @@ test("mergeAndExit is no-op when isolationDegraded is true (#2483)", () => {
1064
1361
  getIsolationMode: () => "worktree",
1065
1362
  });
1066
1363
  const ctx = makeNotifyCtx();
1067
- const resolver = new WorktreeResolver(s, deps);
1364
+ const resolver = makeResolver(s,deps);
1068
1365
 
1069
1366
  resolver.mergeAndExit("M001", ctx);
1070
1367
 
@@ -1102,7 +1399,7 @@ test("mergeAndExit still merges when mode is 'none' but session is in a worktree
1102
1399
  getIsolationMode: () => "none", // config says "none" — but we ARE in a worktree
1103
1400
  });
1104
1401
  const ctx = makeNotifyCtx();
1105
- const resolver = new WorktreeResolver(s, deps);
1402
+ const resolver = makeResolver(s,deps);
1106
1403
 
1107
1404
  resolver.mergeAndExit("M001", ctx);
1108
1405
 
@@ -1125,7 +1422,7 @@ test("mergeAndExit in none mode remains a no-op when NOT in a worktree (#2625)",
1125
1422
  getIsolationMode: () => "none",
1126
1423
  });
1127
1424
  const ctx = makeNotifyCtx();
1128
- const resolver = new WorktreeResolver(s, deps);
1425
+ const resolver = makeResolver(s,deps);
1129
1426
 
1130
1427
  resolver.mergeAndExit("M001", ctx);
1131
1428
 
@@ -1154,7 +1451,7 @@ test("mergeAndExit propagates non-MergeConflictError to caller (#4380)", () => {
1154
1451
  },
1155
1452
  });
1156
1453
  const ctx = makeNotifyCtx();
1157
- const resolver = new WorktreeResolver(s, deps);
1454
+ const resolver = makeResolver(s,deps);
1158
1455
 
1159
1456
  // The error must propagate — callers need it to apply their own recovery logic
1160
1457
  assert.throws(
@@ -1197,7 +1494,7 @@ test("mergeAndExit chdirs to project root before merge work (regression: headles
1197
1494
  getIsolationMode: () => "worktree",
1198
1495
  });
1199
1496
  const ctx = makeNotifyCtx();
1200
- const resolver = new WorktreeResolver(s, deps);
1497
+ const resolver = makeResolver(s,deps);
1201
1498
 
1202
1499
  resolver.mergeAndExit("M001", ctx);
1203
1500
 
@@ -1231,7 +1528,7 @@ test("mergeAndExit anchors cwd even on isolation-degraded skip path", () => {
1231
1528
  s.isolationDegraded = true;
1232
1529
  const deps = makeDeps({ getIsolationMode: () => "worktree" });
1233
1530
  const ctx = makeNotifyCtx();
1234
- const resolver = new WorktreeResolver(s, deps);
1531
+ const resolver = makeResolver(s,deps);
1235
1532
 
1236
1533
  resolver.mergeAndExit("M001", ctx);
1237
1534