gsd-pi 2.80.0-dev.2848d9009 → 2.80.0-dev.3065f7bfa

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 (377) hide show
  1. package/README.md +4 -2
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/gsd/auto/loop.js +32 -1
  4. package/dist/resources/extensions/gsd/auto/phases.js +178 -108
  5. package/dist/resources/extensions/gsd/auto/resolve.js +17 -0
  6. package/dist/resources/extensions/gsd/auto/run-unit.js +20 -30
  7. package/dist/resources/extensions/gsd/auto/session.js +8 -0
  8. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  9. package/dist/resources/extensions/gsd/auto-dispatch.js +16 -0
  10. package/dist/resources/extensions/gsd/auto-post-unit.js +17 -4
  11. package/dist/resources/extensions/gsd/auto-prompts.js +103 -16
  12. package/dist/resources/extensions/gsd/auto-recovery.js +43 -1
  13. package/dist/resources/extensions/gsd/auto-start.js +197 -6
  14. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  15. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  16. package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
  17. package/dist/resources/extensions/gsd/auto.js +86 -26
  18. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +42 -2
  19. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +49 -36
  20. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +15 -5
  21. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +33 -20
  22. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +7 -1
  23. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +9 -3
  24. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +8 -2
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +259 -28
  26. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  27. package/dist/resources/extensions/gsd/clean-root-preflight.js +24 -6
  28. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  29. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  30. package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
  31. package/dist/resources/extensions/gsd/db/unit-dispatches.js +39 -0
  32. package/dist/resources/extensions/gsd/db-base-schema.js +4 -2
  33. package/dist/resources/extensions/gsd/db-migration-steps.js +6 -0
  34. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  35. package/dist/resources/extensions/gsd/git-service.js +36 -4
  36. package/dist/resources/extensions/gsd/gsd-db.js +46 -13
  37. package/dist/resources/extensions/gsd/guided-flow.js +99 -38
  38. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  39. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  40. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  41. package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
  42. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  43. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  44. package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
  45. package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
  46. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  47. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +16 -13
  48. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  49. package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
  50. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  51. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  52. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  53. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  54. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  55. package/dist/resources/extensions/gsd/quick.js +34 -2
  56. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  57. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  58. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  59. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  60. package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
  61. package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
  62. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  63. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  64. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  65. package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
  66. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  67. package/dist/resources/extensions/gsd/worktree-resolver.js +68 -21
  68. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  69. package/dist/web/standalone/.next/BUILD_ID +1 -1
  70. package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
  71. package/dist/web/standalone/.next/build-manifest.json +2 -2
  72. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  73. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  74. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  82. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/index.html +1 -1
  90. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
  97. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  98. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  99. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  100. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  101. package/package.json +3 -3
  102. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  103. package/packages/mcp-server/dist/workflow-tools.js +22 -17
  104. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  105. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  106. package/packages/mcp-server/src/workflow-tools.ts +30 -16
  107. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  108. package/packages/native/tsconfig.tsbuildinfo +1 -1
  109. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  110. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  111. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  112. package/packages/pi-agent-core/dist/agent.d.ts +5 -0
  113. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  114. package/packages/pi-agent-core/dist/agent.js +2 -0
  115. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  116. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  117. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  118. package/packages/pi-agent-core/dist/index.js +2 -0
  119. package/packages/pi-agent-core/dist/index.js.map +1 -1
  120. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  121. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  122. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  123. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  124. package/packages/pi-agent-core/dist/types.d.ts +9 -0
  125. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  126. package/packages/pi-agent-core/dist/types.js.map +1 -1
  127. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  128. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  129. package/packages/pi-agent-core/src/agent.ts +8 -0
  130. package/packages/pi-agent-core/src/index.ts +2 -0
  131. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  132. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  133. package/packages/pi-agent-core/src/types.ts +14 -0
  134. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  135. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
  136. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  137. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +18 -0
  138. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  139. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -0
  140. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  141. package/packages/pi-coding-agent/dist/core/agent-session.js +44 -7
  142. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  143. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +3 -1
  144. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  145. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  146. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  147. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  148. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  149. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  150. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  151. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  152. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  153. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
  154. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
  155. package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
  156. package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
  157. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
  158. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
  159. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
  160. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
  161. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  162. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  163. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  164. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +3 -0
  165. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  166. package/packages/pi-coding-agent/dist/core/extensions/runner.js +6 -6
  167. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  168. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +5 -3
  169. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  170. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +39 -1
  171. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  172. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  173. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  174. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  175. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  176. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  177. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  178. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  179. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  180. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  181. package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
  182. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  183. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
  184. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  185. package/packages/pi-coding-agent/dist/core/settings-manager.js +25 -0
  186. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  187. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  188. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  190. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  192. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  193. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +1 -0
  194. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  195. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +3 -0
  196. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  197. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  198. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +13 -5
  199. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  200. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +53 -0
  201. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  202. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  203. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +3 -0
  204. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  205. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
  206. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
  207. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +10 -0
  208. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
  209. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  210. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
  211. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  212. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
  213. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
  214. package/packages/pi-coding-agent/src/core/agent-session.ts +48 -7
  215. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +3 -1
  216. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  217. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  218. package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
  219. package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
  220. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  221. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +5 -3
  222. package/packages/pi-coding-agent/src/core/extensions/runner.ts +8 -5
  223. package/packages/pi-coding-agent/src/core/extensions/types.ts +42 -1
  224. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  225. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  226. package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
  227. package/packages/pi-coding-agent/src/core/settings-manager.ts +39 -1
  228. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  229. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  230. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +4 -0
  231. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +56 -0
  232. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +22 -7
  233. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +3 -0
  234. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +14 -0
  235. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
  236. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  237. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  238. package/packages/pi-tui/dist/tui.js +18 -8
  239. package/packages/pi-tui/dist/tui.js.map +1 -1
  240. package/packages/pi-tui/src/tui.ts +20 -8
  241. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  242. package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -2
  243. package/src/resources/extensions/gsd/auto/loop.ts +50 -8
  244. package/src/resources/extensions/gsd/auto/phases.ts +251 -172
  245. package/src/resources/extensions/gsd/auto/resolve.ts +23 -1
  246. package/src/resources/extensions/gsd/auto/run-unit.ts +25 -30
  247. package/src/resources/extensions/gsd/auto/session.ts +8 -0
  248. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
  249. package/src/resources/extensions/gsd/auto-dispatch.ts +16 -0
  250. package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
  251. package/src/resources/extensions/gsd/auto-prompts.ts +112 -15
  252. package/src/resources/extensions/gsd/auto-recovery.ts +54 -0
  253. package/src/resources/extensions/gsd/auto-start.ts +230 -9
  254. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  255. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  256. package/src/resources/extensions/gsd/auto-worktree.ts +123 -0
  257. package/src/resources/extensions/gsd/auto.ts +98 -21
  258. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +49 -1
  259. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +50 -36
  260. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +16 -5
  261. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +34 -19
  262. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +8 -1
  263. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +10 -3
  264. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +9 -2
  265. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +305 -28
  266. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  267. package/src/resources/extensions/gsd/clean-root-preflight.ts +32 -7
  268. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  269. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  270. package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
  271. package/src/resources/extensions/gsd/db/unit-dispatches.ts +41 -0
  272. package/src/resources/extensions/gsd/db-base-schema.ts +4 -2
  273. package/src/resources/extensions/gsd/db-migration-steps.ts +8 -0
  274. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  275. package/src/resources/extensions/gsd/git-service.ts +46 -8
  276. package/src/resources/extensions/gsd/gsd-db.ts +50 -13
  277. package/src/resources/extensions/gsd/guided-flow.ts +123 -45
  278. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  279. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  280. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  281. package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
  282. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  283. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  284. package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
  285. package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
  286. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  287. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  288. package/src/resources/extensions/gsd/prompts/complete-milestone.md +16 -13
  289. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  290. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  291. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  292. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  293. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  294. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  295. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  296. package/src/resources/extensions/gsd/quick.ts +37 -2
  297. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +2 -2
  298. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +417 -10
  299. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +56 -13
  300. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +14 -1
  301. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +168 -6
  302. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +15 -6
  303. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  304. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  305. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  306. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  307. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  308. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +55 -0
  309. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
  310. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +5 -1
  311. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  312. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  313. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  314. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
  315. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  316. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
  317. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +54 -0
  318. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +6 -3
  319. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +239 -1
  320. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  321. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  322. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  323. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
  324. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  325. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  326. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
  327. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  328. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
  329. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
  330. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  331. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  332. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
  333. package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
  334. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
  335. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  336. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  337. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +19 -0
  338. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +3 -3
  339. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  340. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +38 -17
  341. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  342. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  343. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +106 -0
  344. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  345. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +20 -0
  346. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  347. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +55 -0
  348. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
  349. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +9 -0
  350. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  351. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  352. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
  353. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
  354. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +30 -0
  355. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
  356. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -4
  357. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  358. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  359. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
  360. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  361. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  362. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +167 -4
  363. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  364. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  365. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  366. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  367. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
  368. package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
  369. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  370. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  371. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  372. package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
  373. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  374. package/src/resources/extensions/gsd/worktree-resolver.ts +85 -19
  375. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +0 -97
  376. /package/dist/web/standalone/.next/static/{vaQ47E8aNlbbNEDoeME6G → O2WvnXROue6l7nAp_4dhC}/_buildManifest.js +0 -0
  377. /package/dist/web/standalone/.next/static/{vaQ47E8aNlbbNEDoeME6G → O2WvnXROue6l7nAp_4dhC}/_ssgManifest.js +0 -0
@@ -24,7 +24,7 @@ let _currentSigtermHandler = null;
24
24
  *
25
25
  * Returns the new handler so the caller can store and deregister it later.
26
26
  */
27
- export function registerSigtermHandler(currentBasePath, previousHandler) {
27
+ export function registerSigtermHandler(currentBasePath, previousHandler, onSignalCleanup) {
28
28
  // Remove the explicitly-passed previous handler
29
29
  if (previousHandler) {
30
30
  for (const sig of CLEANUP_SIGNALS)
@@ -37,6 +37,13 @@ export function registerSigtermHandler(currentBasePath, previousHandler) {
37
37
  process.off(sig, _currentSigtermHandler);
38
38
  }
39
39
  const handler = () => {
40
+ try {
41
+ onSignalCleanup?.();
42
+ }
43
+ catch {
44
+ void 0;
45
+ // Signal cleanup is best-effort; lock cleanup and process exit still run.
46
+ }
40
47
  clearLock(currentBasePath);
41
48
  releaseSessionLock(currentBasePath);
42
49
  process.exit(0);
@@ -35,13 +35,13 @@ export async function recoverTimedOutUnit(ctx, pi, unitType, unitId, reason, rct
35
35
  writeUnitRuntimeRecord(basePath, unitType, unitId, currentUnitStartedAt, {
36
36
  recovery: status,
37
37
  });
38
- const durableComplete = status.summaryExists && status.taskChecked && status.nextActionAdvanced;
38
+ const durableComplete = status.dbComplete || (status.summaryExists && status.taskChecked && status.nextActionAdvanced);
39
39
  if (durableComplete) {
40
40
  writeUnitRuntimeRecord(basePath, unitType, unitId, currentUnitStartedAt, {
41
41
  phase: "finalized",
42
42
  recovery: status,
43
43
  });
44
- ctx.ui.notify(`${reason === "idle" ? "Idle" : "Timeout"} recovery: ${unitType} ${unitId} already completed on disk. Continuing auto-mode. (attempt ${attemptNumber})`, "info");
44
+ ctx.ui.notify(`${reason === "idle" ? "Idle" : "Timeout"} recovery: ${unitType} ${unitId} already completed. Continuing auto-mode. (attempt ${attemptNumber})`, "info");
45
45
  unitRecoveryCount.delete(recoveryKey);
46
46
  bumpAndResolveSynthetic(`timeout-recovery:${reason}:${unitType}/${unitId}`);
47
47
  return "recovered";
@@ -23,7 +23,7 @@ import { debugLog } from "./debug-logger.js";
23
23
  import { logWarning, logError } from "./workflow-logger.js";
24
24
  import { loadEffectiveGSDPreferences } from "./preferences.js";
25
25
  import { MILESTONE_ID_RE } from "./milestone-ids.js";
26
- import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeWorkingTreeStatus, nativeAddAllWithExclusions, nativeCommit, nativeCheckoutBranch, nativeMergeSquash, nativeConflictFiles, nativeCheckoutTheirs, nativeAddPaths, nativeRmForce, nativeBranchDelete, nativeBranchForceReset, nativeBranchExists, nativeDiffNumstat, nativeUpdateRef, nativeIsAncestor, nativeMergeAbort, } from "./native-git-bridge.js";
26
+ import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeWorkingTreeStatus, nativeAddAllWithExclusions, nativeCommit, nativeCheckoutBranch, nativeMergeSquash, nativeConflictFiles, nativeCheckoutTheirs, nativeAddPaths, nativeRmForce, nativeBranchDelete, nativeBranchForceReset, nativeBranchExists, nativeDiffNumstat, nativeUpdateRef, nativeIsAncestor, nativeMergeAbort, nativeWorktreeList, } from "./native-git-bridge.js";
27
27
  import { gsdHome } from "./gsd-home.js";
28
28
  import { createWorkspace } from "./workspace.js";
29
29
  const PROJECT_PREFERENCES_FILE = "PREFERENCES.md";
@@ -1018,6 +1018,111 @@ export function enterBranchModeForMilestone(basePath, milestoneId) {
1018
1018
  * for both reads and writes. copyPlanningArtifacts and reconcilePlanCheckboxes
1019
1019
  * (both formerly here) became dead.
1020
1020
  */
1021
+ /**
1022
+ * True when `branch` is checked out in any worktree listed by
1023
+ * `git worktree list --porcelain`. Used to gate ref updates that would
1024
+ * otherwise leave a concurrent worktree's HEAD inconsistent with its
1025
+ * index/working tree (Codex peer-review of #5538-followup).
1026
+ *
1027
+ * Best-effort: a `nativeWorktreeList` failure returns true so we err on
1028
+ * the side of NOT moving the ref. Better to skip a fast-forward than to
1029
+ * silently corrupt another worktree.
1030
+ */
1031
+ export function _isBranchCheckedOutElsewhere(basePath, branch) {
1032
+ try {
1033
+ const entries = nativeWorktreeList(basePath);
1034
+ return entries.some((entry) => entry.branch === branch);
1035
+ }
1036
+ catch {
1037
+ return true;
1038
+ }
1039
+ }
1040
+ /**
1041
+ * Resolve the integration branch using the same 3-tier fallback as the
1042
+ * fresh-create path: META.json → git.main_branch preference → detected
1043
+ * main branch. Returns null when no usable target exists.
1044
+ */
1045
+ function _resolveIntegrationBranchForReuse(basePath, milestoneId) {
1046
+ const fromMeta = readIntegrationBranch(basePath, milestoneId);
1047
+ if (fromMeta)
1048
+ return fromMeta;
1049
+ const gitPrefs = loadEffectiveGSDPreferences()?.preferences?.git;
1050
+ const fromPref = gitPrefs?.main_branch &&
1051
+ typeof gitPrefs.main_branch === "string" &&
1052
+ gitPrefs.main_branch.length > 0 &&
1053
+ nativeBranchExists(basePath, gitPrefs.main_branch)
1054
+ ? gitPrefs.main_branch
1055
+ : null;
1056
+ if (fromPref)
1057
+ return fromPref;
1058
+ try {
1059
+ return nativeDetectMainBranch(basePath);
1060
+ }
1061
+ catch {
1062
+ return null;
1063
+ }
1064
+ }
1065
+ /**
1066
+ * When reusing an existing milestone branch, fast-forward it onto the
1067
+ * integration branch when that's safe (branch is a strict ancestor of
1068
+ * integration — no commits would be lost). Skips when the branch has its
1069
+ * own commits ahead of integration, when the integration branch can't be
1070
+ * resolved, or when any git operation fails — the merge gate at milestone
1071
+ * completion will surface real divergence as a conflict.
1072
+ *
1073
+ * The previous behavior re-attached the worktree to whatever stale tip
1074
+ * the branch held, which caused new milestone work to fork from a base
1075
+ * missing prior milestones' merges (#5538-followup).
1076
+ */
1077
+ export function fastForwardReusedMilestoneBranchIfSafe(basePath, milestoneId, branch) {
1078
+ try {
1079
+ const integrationBranch = _resolveIntegrationBranchForReuse(basePath, milestoneId);
1080
+ if (!integrationBranch || integrationBranch === branch)
1081
+ return;
1082
+ if (!nativeBranchExists(basePath, integrationBranch))
1083
+ return;
1084
+ // Pure fast-forward only: branch must be a strict ancestor of integration.
1085
+ // If the branch has its own commits ahead, leave it alone.
1086
+ if (!nativeIsAncestor(basePath, branch, integrationBranch)) {
1087
+ debugLog("createAutoWorktree", {
1088
+ phase: "skip-ff-branch-not-ancestor",
1089
+ milestoneId,
1090
+ branch,
1091
+ integration: integrationBranch,
1092
+ });
1093
+ return;
1094
+ }
1095
+ // Codex peer-review: `nativeUpdateRef` succeeds even when the branch is
1096
+ // currently checked out in another worktree, leaving that worktree's HEAD
1097
+ // inconsistent with its index/work tree. Skip the fast-forward if any
1098
+ // listed worktree has this branch checked out — the merge gate at
1099
+ // milestone-completion will surface stale-base divergence as a conflict
1100
+ // instead of silently corrupting the other worktree's state.
1101
+ if (_isBranchCheckedOutElsewhere(basePath, branch)) {
1102
+ debugLog("createAutoWorktree", {
1103
+ phase: "skip-ff-branch-checked-out-elsewhere",
1104
+ milestoneId,
1105
+ branch,
1106
+ });
1107
+ return;
1108
+ }
1109
+ nativeUpdateRef(basePath, `refs/heads/${branch}`, integrationBranch);
1110
+ debugLog("createAutoWorktree", {
1111
+ phase: "fast-forward-reused-branch",
1112
+ milestoneId,
1113
+ branch,
1114
+ integration: integrationBranch,
1115
+ });
1116
+ }
1117
+ catch (err) {
1118
+ debugLog("createAutoWorktree", {
1119
+ phase: "fast-forward-reused-branch-failed",
1120
+ milestoneId,
1121
+ branch,
1122
+ error: err instanceof Error ? err.message : String(err),
1123
+ });
1124
+ }
1125
+ }
1021
1126
  export function createAutoWorktree(basePath, milestoneId) {
1022
1127
  basePath = resolveWorktreeProjectRoot(basePath);
1023
1128
  // Check if repo has commits — git worktree requires a valid HEAD
@@ -1035,6 +1140,11 @@ export function createAutoWorktree(basePath, milestoneId) {
1035
1140
  const branchExists = nativeBranchExists(basePath, branch);
1036
1141
  let info;
1037
1142
  if (branchExists) {
1143
+ // #5538-followup: fast-forward the reused branch onto the integration
1144
+ // branch when safe so the next milestone forks from up-to-date code.
1145
+ // Without this, a milestone that was created before another milestone
1146
+ // merged into main would carry a stale base into its worktree.
1147
+ fastForwardReusedMilestoneBranchIfSafe(basePath, milestoneId, branch);
1038
1148
  // Re-attach worktree to the existing milestone branch (preserving commits)
1039
1149
  info = createWorktree(basePath, milestoneId, {
1040
1150
  branch,
@@ -20,7 +20,7 @@ import { gsdRoot, resolveMilestoneFile, resolveMilestonePath, resolveDir, milest
20
20
  import { invalidateAllCaches } from "./cache.js";
21
21
  import { clearActivityLogState } from "./activity-log.js";
22
22
  import { synthesizeCrashRecovery, getDeepDiagnostic, readActiveMilestoneId, } from "./session-forensics.js";
23
- import { writeLock, clearLock, readCrashLock, isLockProcessAlive, formatCrashInfo, emitCrashRecoveredUnitEnd, } from "./crash-recovery.js";
23
+ import { writeLock, clearLock, readCrashLock, isLockProcessAlive, formatCrashInfo, emitCrashRecoveredUnitEnd, emitOpenUnitEndForUnit, } from "./crash-recovery.js";
24
24
  import { acquireSessionLock, getSessionLockStatus, releaseSessionLock, updateSessionLock, } from "./session-lock.js";
25
25
  import { resolveAutoSupervisorConfig, loadEffectiveGSDPreferences, getIsolationMode, } from "./preferences.js";
26
26
  import { sendDesktopNotification } from "./notifications.js";
@@ -45,6 +45,7 @@ import { readFileSync, existsSync, mkdirSync } from "node:fs";
45
45
  import { atomicWriteSync } from "./atomic-write.js";
46
46
  import { autoCommitCurrentBranch, captureIntegrationBranch, detectWorktreeName, getCurrentBranch, getMainBranch, setActiveMilestoneId, resolveProjectRoot, } from "./worktree.js";
47
47
  import { GitServiceImpl } from "./git-service.js";
48
+ import { nativeCheckoutBranch } from "./native-git-bridge.js";
48
49
  import { getPriorSliceCompletionBlocker } from "./dispatch-guard.js";
49
50
  import { createAutoWorktree, enterAutoWorktree, enterBranchModeForMilestone, teardownAutoWorktree, isInAutoWorktree, getAutoWorktreePath, mergeMilestoneToMain, autoWorktreeBranch, syncWorktreeStateBack, syncProjectRootToWorktree, checkResourcesStale, escapeStaleWorktree, } from "./auto-worktree.js";
50
51
  import { pruneQueueOrder } from "./queue-order.js";
@@ -61,6 +62,8 @@ import { isClosedStatus } from "./status-guards.js";
61
62
  import { updateProgressWidget as _updateProgressWidget, updateSliceProgressCache, clearSliceProgressCache, } from "./auto-dashboard.js";
62
63
  import { registerSigtermHandler as _registerSigtermHandler, deregisterSigtermHandler as _deregisterSigtermHandler, } from "./auto-supervisor.js";
63
64
  import { isDbAvailable, getMilestone } from "./gsd-db.js";
65
+ import { markLatestActiveForWorkerCanceled } from "./db/unit-dispatches.js";
66
+ import { writeUnitRuntimeRecord } from "./unit-runtime.js";
64
67
  import { countPendingCaptures } from "./captures.js";
65
68
  import { CMUX_CHANNELS } from "../shared/cmux-events.js";
66
69
  import { ensureDbOpen } from "./bootstrap/dynamic-tools.js";
@@ -85,6 +88,16 @@ import { validateDirectory } from "./validate-directory.js";
85
88
  import { createAutoOrchestrator } from "./auto/orchestrator.js";
86
89
  import { WorktreeResolver, } from "./worktree-resolver.js";
87
90
  import { reorderForCaching } from "./prompt-ordering.js";
91
+ import { initTokenCounter } from "./token-counter.js";
92
+ // Warm the tiktoken encoder at extension startup so context-budget computations
93
+ // can use accurate token counts via countTokensSync without paying the load
94
+ // cost mid-prompt-build. Fire-and-forget — failure falls back to the
95
+ // provider-aware char-ratio estimator already used by getCharsPerToken().
96
+ // Catch rejections explicitly: an unhandled rejection at module-import time
97
+ // can destabilize startup before the engine logger is configured.
98
+ void initTokenCounter().catch((err) => {
99
+ logWarning("engine", `token counter warm-up failed: ${err instanceof Error ? err.message : String(err)}`);
100
+ });
88
101
  export { STUB_RECOVERY_THRESHOLD, NEW_SESSION_TIMEOUT_MS, } from "./auto/session.js";
89
102
  import { autoSession as s } from "./auto-runtime-state.js";
90
103
  import { gsdHome } from "./gsd-home.js";
@@ -112,11 +125,12 @@ const STATE_REBUILD_MIN_INTERVAL_MS = 30_000;
112
125
  * the DB is unavailable (e.g. fresh project before init) we skip registration
113
126
  * silently rather than blocking session start.
114
127
  */
115
- function registerAutoWorkerForSession(session) {
128
+ function registerAutoWorkerForSession(session, projectRootOverride) {
116
129
  if (session.workerId)
117
130
  return; // already registered (e.g. resume re-runs)
118
131
  try {
119
- const projectRootRealpath = normalizeRealPath(session.scope?.workspace.projectRoot
132
+ const projectRootRealpath = normalizeRealPath(projectRootOverride
133
+ ?? session.scope?.workspace.projectRoot
120
134
  ?? (session.originalBasePath || session.basePath));
121
135
  session.workerId = registerAutoWorker({ projectRootRealpath });
122
136
  }
@@ -272,9 +286,50 @@ export function shouldUseWorktreeIsolation(basePath) {
272
286
  */
273
287
  // Re-export budget utilities for external consumers
274
288
  export { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, } from "./auto-budget.js";
289
+ function closeOutSignalInterruptedUnit(currentBasePath) {
290
+ const currentUnit = s.currentUnit;
291
+ if (!currentUnit)
292
+ return;
293
+ const reason = "Auto-mode process received a termination signal";
294
+ const errorContext = {
295
+ message: reason,
296
+ category: "aborted",
297
+ isTransient: false,
298
+ };
299
+ const basePath = s.basePath || currentBasePath;
300
+ try {
301
+ emitOpenUnitEndForUnit(basePath, currentUnit.type, currentUnit.id, "cancelled", errorContext);
302
+ }
303
+ catch (err) {
304
+ logWarning("engine", `signal unit-end cleanup failed: ${getErrorMessage(err)}`, { file: "auto.ts" });
305
+ }
306
+ try {
307
+ writeUnitRuntimeRecord(basePath, currentUnit.type, currentUnit.id, currentUnit.startedAt, {
308
+ phase: "crashed",
309
+ lastProgressAt: Date.now(),
310
+ lastProgressKind: "signal",
311
+ });
312
+ }
313
+ catch (err) {
314
+ logWarning("engine", `signal runtime cleanup failed: ${getErrorMessage(err)}`, { file: "auto.ts" });
315
+ }
316
+ try {
317
+ if (s.workerId)
318
+ markLatestActiveForWorkerCanceled(s.workerId, "signal-exit");
319
+ }
320
+ catch (err) {
321
+ logWarning("engine", `signal dispatch cleanup failed: ${getErrorMessage(err)}`, { file: "auto.ts" });
322
+ }
323
+ try {
324
+ resolveAgentEndCancelled(errorContext);
325
+ }
326
+ catch (err) {
327
+ logWarning("engine", `signal resolve cleanup failed: ${getErrorMessage(err)}`, { file: "auto.ts" });
328
+ }
329
+ }
275
330
  /** Wrapper: register SIGTERM handler and store reference. */
276
331
  function registerSigtermHandler(currentBasePath) {
277
- s.sigtermHandler = _registerSigtermHandler(currentBasePath, s.sigtermHandler);
332
+ s.sigtermHandler = _registerSigtermHandler(currentBasePath, s.sigtermHandler, () => closeOutSignalInterruptedUnit(currentBasePath));
278
333
  }
279
334
  /** Wrapper: deregister SIGTERM handler and clear reference. */
280
335
  function deregisterSigtermHandler() {
@@ -666,6 +721,8 @@ export async function stopAuto(ctx, pi, reason) {
666
721
  if (s.workerId) {
667
722
  markWorkerStopping(s.workerId);
668
723
  }
724
+ s.workerId = null;
725
+ s.milestoneLeaseToken = null;
669
726
  }
670
727
  catch (e) {
671
728
  debugLog("stop-cleanup-coordination", { error: e instanceof Error ? e.message : String(e) });
@@ -798,6 +855,21 @@ export async function stopAuto(ctx, pi, reason) {
798
855
  catch (e) {
799
856
  debugLog("stop-cleanup-basepath", { error: e instanceof Error ? e.message : String(e) });
800
857
  }
858
+ // Re-root the active command session/tool runtime after worktree teardown.
859
+ // mergeAndExit restores process.cwd(), but AgentSession has already captured
860
+ // its own cwd for tools and system prompt; refresh it before returning to the
861
+ // user so follow-up commands do not target a removed milestone worktree.
862
+ if (s.originalBasePath && ctx && s.cmdCtx) {
863
+ try {
864
+ const result = await s.cmdCtx.newSession({ workspaceRoot: s.basePath });
865
+ if (result.cancelled) {
866
+ logWarning("engine", "post-stop session re-root was cancelled", { file: "auto.ts", basePath: s.basePath });
867
+ }
868
+ }
869
+ catch (err) {
870
+ logWarning("engine", `post-stop session re-root failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts", basePath: s.basePath });
871
+ }
872
+ }
801
873
  // ── Step 8: Ledger notification ──
802
874
  try {
803
875
  const ledger = getLedger();
@@ -1046,6 +1118,7 @@ function buildResolverDeps() {
1046
1118
  getAutoWorktreePath,
1047
1119
  autoCommitCurrentBranch,
1048
1120
  getCurrentBranch,
1121
+ checkoutBranch: nativeCheckoutBranch,
1049
1122
  autoWorktreeBranch,
1050
1123
  resolveMilestoneFile,
1051
1124
  readFileSync: (path, encoding) => readFileSync(path, encoding),
@@ -1566,6 +1639,10 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
1566
1639
  : new URL("../../../resource-loader.js", import.meta.url).href;
1567
1640
  const { initResources } = await import(resourceLoaderPath);
1568
1641
  initResources(agentDir);
1642
+ // initResources() uses synchronous fs APIs, so the prompt-template cache
1643
+ // can be primed immediately — no need for the legacy 1s setTimeout deferral.
1644
+ const { primeCache } = await import("./prompt-loader.js");
1645
+ primeCache();
1569
1646
  // Open the project DB before rebuild/derive so resume uses DB-backed
1570
1647
  // state instead of falling back to stale markdown parsing (#2940).
1571
1648
  await openProjectDbIfPresent(s.basePath);
@@ -1631,6 +1708,10 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
1631
1708
  lockBase,
1632
1709
  buildResolver,
1633
1710
  };
1711
+ // Register the worker before bootstrap enters a milestone worktree.
1712
+ // This ensures enterMilestone can claim a lease and seed dispatch claims
1713
+ // for crash-recovery fidelity (#5405).
1714
+ registerAutoWorkerForSession(s, base);
1634
1715
  const ready = await bootstrapAutoSession(s, ctx, pi, base, verboseMode, requestedStepMode, bootstrapDeps, freshStartAssessment);
1635
1716
  if (!ready)
1636
1717
  return;
@@ -1748,28 +1829,7 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
1748
1829
  id: triggerUnitId,
1749
1830
  startedAt: hookStartedAt,
1750
1831
  };
1751
- // Ensure cwd matches basePath BEFORE newSession() captures it (#1389).
1752
- // newSession() snapshots process.cwd() during construction; chdir-ing
1753
- // afterward leaves the session rooted to whatever cwd was when the call
1754
- // was made. Must be synchronous — no awaits between chdir and newSession.
1755
- try {
1756
- if (process.cwd() !== s.basePath)
1757
- process.chdir(s.basePath);
1758
- }
1759
- catch (err) {
1760
- const msg = `Failed to chdir before hook newSession (basePath: ${s.basePath}): ${err instanceof Error ? err.message : String(err)}`;
1761
- logWarning("engine", msg, { file: "auto.ts", basePath: s.basePath, error: err instanceof Error ? err.message : String(err) });
1762
- ctx.ui.notify(`${msg}. Cancelling hook dispatch to avoid running in the wrong directory.`, "error");
1763
- if (wasActive) {
1764
- s.basePath = previousBasePath;
1765
- s.currentUnit = previousCurrentUnit;
1766
- }
1767
- else {
1768
- s.reset();
1769
- }
1770
- return false;
1771
- }
1772
- const result = await s.cmdCtx.newSession();
1832
+ const result = await s.cmdCtx.newSession({ workspaceRoot: s.basePath });
1773
1833
  if (result.cancelled) {
1774
1834
  await stopAuto(ctx, pi);
1775
1835
  return false;
@@ -53,6 +53,44 @@ export function isUserInitiatedAbortMessage(message) {
53
53
  return false;
54
54
  return /\b(?:claude code process aborted by user|request aborted by user|process aborted by user)\b/i.test(message);
55
55
  }
56
+ /**
57
+ * Resolve an agent_end event observed while a session switch is in flight.
58
+ *
59
+ * #5538-followup: When `newSession()` aborts an in-flight stream as part of a
60
+ * session transition (run-unit.ts:63 → _settleCurrentTurnForSessionTransition
61
+ * → agent.abort()), the SDK emits "Claude Code process aborted by user" or
62
+ * "Request aborted by user" against the previous unit's turn. The previous
63
+ * code path treated that as a user cancellation and propagated it to the next
64
+ * unit via the pending-switch-cancellation queue, killing auto-mode with
65
+ * "Auto-mode stopped — Unit aborted: Claude Code process aborted by user"
66
+ * even though no user input occurred.
67
+ *
68
+ * The user-abort branch is intentionally ignored when the abort fires while
69
+ * the session-switch is in flight: the abort is the expected side-effect of
70
+ * the transition, not a user signal. Other branches (genuine `stopReason ===
71
+ * "aborted"` with content/errorMessage) preserve the prior behavior.
72
+ */
73
+ export function _handleSessionSwitchAgentEnd(lastMsg, resolveCancelled) {
74
+ if (!lastMsg || typeof lastMsg !== "object")
75
+ return;
76
+ const m = lastMsg;
77
+ if (m.stopReason === "error") {
78
+ const rawErrorMsg = m.errorMessage ? String(m.errorMessage) : "";
79
+ if (isUserInitiatedAbortMessage(rawErrorMsg)) {
80
+ // Internal abort from in-flight session transition — drop on the floor.
81
+ return;
82
+ }
83
+ return;
84
+ }
85
+ if (m.stopReason === "aborted") {
86
+ const content = m.content;
87
+ const hasEmptyContent = Array.isArray(content) && content.length === 0;
88
+ const hasErrorMessage = !!m.errorMessage;
89
+ if (!hasEmptyContent || hasErrorMessage) {
90
+ resolveCancelled(_buildAbortedPauseContext(m));
91
+ }
92
+ }
93
+ }
56
94
  async function pauseTransientWithBackoff(cls, pi, ctx, errorDetail, isRateLimit) {
57
95
  retryState.consecutiveTransientCount += 1;
58
96
  const baseRetryAfterMs = "retryAfterMs" in cls ? cls.retryAfterMs : 15_000;
@@ -118,9 +156,11 @@ export async function handleAgentEnd(pi, event, ctx) {
118
156
  return;
119
157
  if (!isAutoActive())
120
158
  return;
121
- if (isSessionSwitchInFlight())
122
- return;
123
159
  const lastMsg = event.messages[event.messages.length - 1];
160
+ if (isSessionSwitchInFlight()) {
161
+ _handleSessionSwitchAgentEnd(lastMsg, resolveAgentEndCancelled);
162
+ return;
163
+ }
124
164
  if (lastMsg && "stopReason" in lastMsg && lastMsg.stopReason === "aborted") {
125
165
  // Empty content with aborted stopReason is a non-fatal agent stop (the LLM
126
166
  // chose to end without producing output). Only pause on genuine fatal aborts