gsd-pi 2.80.0-dev.c5f2443b3 → 2.80.0-dev.d4fc28e6b

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 (580) hide show
  1. package/README.md +4 -2
  2. package/dist/cli.js +0 -19
  3. package/dist/resources/.managed-resources-content-hash +1 -1
  4. package/dist/resources/GSD-WORKFLOW.md +2 -2
  5. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +29 -0
  6. package/dist/resources/extensions/github-sync/templates.js +39 -8
  7. package/dist/resources/extensions/gsd/auto/loop.js +119 -18
  8. package/dist/resources/extensions/gsd/auto/phases.js +212 -135
  9. package/dist/resources/extensions/gsd/auto/resolve.js +29 -0
  10. package/dist/resources/extensions/gsd/auto/run-unit.js +41 -45
  11. package/dist/resources/extensions/gsd/auto/session.js +8 -0
  12. package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
  13. package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
  14. package/dist/resources/extensions/gsd/auto-dashboard.js +51 -15
  15. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  16. package/dist/resources/extensions/gsd/auto-dispatch.js +26 -0
  17. package/dist/resources/extensions/gsd/auto-post-unit.js +27 -14
  18. package/dist/resources/extensions/gsd/auto-prompts.js +214 -17
  19. package/dist/resources/extensions/gsd/auto-recovery.js +197 -9
  20. package/dist/resources/extensions/gsd/auto-start.js +199 -9
  21. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  22. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  23. package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
  24. package/dist/resources/extensions/gsd/auto.js +95 -27
  25. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +103 -3
  26. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +49 -36
  27. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +15 -5
  28. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +33 -20
  29. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +7 -1
  30. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +9 -3
  31. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +8 -2
  32. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +330 -55
  33. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  34. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +129 -1
  35. package/dist/resources/extensions/gsd/clean-root-preflight.js +65 -9
  36. package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
  37. package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
  38. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  39. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  40. package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
  41. package/dist/resources/extensions/gsd/custom-workflow-engine.js +22 -2
  42. package/dist/resources/extensions/gsd/db/unit-dispatches.js +92 -0
  43. package/dist/resources/extensions/gsd/db-base-schema.js +18 -2
  44. package/dist/resources/extensions/gsd/db-migration-steps.js +22 -0
  45. package/dist/resources/extensions/gsd/detection.js +106 -0
  46. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  47. package/dist/resources/extensions/gsd/git-service.js +36 -4
  48. package/dist/resources/extensions/gsd/graph.js +9 -3
  49. package/dist/resources/extensions/gsd/gsd-db.js +146 -13
  50. package/dist/resources/extensions/gsd/guided-flow.js +129 -44
  51. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  52. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  53. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  54. package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
  55. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  56. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  57. package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
  58. package/dist/resources/extensions/gsd/pr-evidence.js +57 -16
  59. package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
  60. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  61. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
  62. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  63. package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
  64. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  65. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  66. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  67. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  68. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  69. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  70. package/dist/resources/extensions/gsd/quick.js +34 -2
  71. package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
  72. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  73. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  74. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  75. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  76. package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
  77. package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
  78. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  79. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  80. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  81. package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
  82. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  83. package/dist/resources/extensions/gsd/working-output-messages.js +64 -0
  84. package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
  85. package/dist/resources/extensions/gsd/worktree-resolver.js +68 -21
  86. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  87. package/dist/web/standalone/.next/BUILD_ID +1 -1
  88. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  89. package/dist/web/standalone/.next/build-manifest.json +3 -3
  90. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  91. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  109. package/dist/web/standalone/.next/server/app/index.html +1 -1
  110. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  117. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  118. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  121. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  122. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  123. package/dist/web/standalone/.next/static/chunks/{8336.6f6f30e410419aff.js → 8336.631939fb583761fa.js} +1 -1
  124. package/dist/web/standalone/.next/static/chunks/{webpack-d82dbee6356c1733.js → webpack-0481f1221120a7c6.js} +1 -1
  125. package/dist/welcome-screen.d.ts +2 -0
  126. package/dist/welcome-screen.js +9 -7
  127. package/package.json +12 -8
  128. package/packages/contracts/package.json +1 -1
  129. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  130. package/packages/mcp-server/dist/workflow-tools.js +22 -17
  131. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  132. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  133. package/packages/mcp-server/src/workflow-tools.ts +30 -16
  134. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  135. package/packages/native/tsconfig.tsbuildinfo +1 -1
  136. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  137. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  138. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  139. package/packages/pi-agent-core/dist/agent.d.ts +5 -0
  140. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  141. package/packages/pi-agent-core/dist/agent.js +2 -0
  142. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  143. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  144. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  145. package/packages/pi-agent-core/dist/index.js +2 -0
  146. package/packages/pi-agent-core/dist/index.js.map +1 -1
  147. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  148. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  149. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  150. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  151. package/packages/pi-agent-core/dist/types.d.ts +9 -0
  152. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  153. package/packages/pi-agent-core/dist/types.js.map +1 -1
  154. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  155. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  156. package/packages/pi-agent-core/src/agent.ts +8 -0
  157. package/packages/pi-agent-core/src/index.ts +2 -0
  158. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  159. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  160. package/packages/pi-agent-core/src/types.ts +14 -0
  161. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  162. package/packages/pi-ai/dist/models/fake-model.d.ts +12 -0
  163. package/packages/pi-ai/dist/models/fake-model.d.ts.map +1 -0
  164. package/packages/pi-ai/dist/models/fake-model.js +27 -0
  165. package/packages/pi-ai/dist/models/fake-model.js.map +1 -0
  166. package/packages/pi-ai/dist/models/index.d.ts.map +1 -1
  167. package/packages/pi-ai/dist/models/index.js +8 -0
  168. package/packages/pi-ai/dist/models/index.js.map +1 -1
  169. package/packages/pi-ai/dist/providers/fake.d.ts +42 -0
  170. package/packages/pi-ai/dist/providers/fake.d.ts.map +1 -0
  171. package/packages/pi-ai/dist/providers/fake.js +319 -0
  172. package/packages/pi-ai/dist/providers/fake.js.map +1 -0
  173. package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
  174. package/packages/pi-ai/dist/providers/register-builtins.js +24 -0
  175. package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
  176. package/packages/pi-ai/src/models/fake-model.ts +30 -0
  177. package/packages/pi-ai/src/models/index.ts +9 -0
  178. package/packages/pi-ai/src/providers/fake.ts +376 -0
  179. package/packages/pi-ai/src/providers/register-builtins.ts +23 -0
  180. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  181. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
  182. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  183. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +18 -0
  184. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  185. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -0
  186. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  187. package/packages/pi-coding-agent/dist/core/agent-session.js +44 -7
  188. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +76 -0
  190. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  192. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  193. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  194. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  195. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  196. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  197. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  198. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  199. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
  200. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
  201. package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
  202. package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
  203. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
  204. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
  205. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
  206. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
  207. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  208. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  209. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  210. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +5 -0
  211. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  212. package/packages/pi-coding-agent/dist/core/extensions/runner.js +20 -7
  213. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  214. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +102 -3
  215. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  216. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +39 -1
  217. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  218. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  219. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  220. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  221. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  222. package/packages/pi-coding-agent/dist/core/model-registry.js +5 -0
  223. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  224. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  225. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  226. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  227. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  228. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  229. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  230. package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
  231. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  232. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +24 -0
  233. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  234. package/packages/pi-coding-agent/dist/core/settings-manager.js +33 -0
  235. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  236. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  237. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  238. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  239. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  240. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  242. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  243. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  244. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  245. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
  246. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
  247. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +54 -15
  248. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  249. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +26 -0
  250. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -0
  251. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +112 -0
  252. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -0
  253. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts +2 -0
  254. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts.map +1 -0
  255. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +51 -0
  256. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -0
  257. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  259. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  260. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +10 -9
  261. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  262. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +3 -0
  263. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  264. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +11 -0
  265. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  266. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +7 -6
  267. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +17 -0
  269. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  270. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +109 -17
  271. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  273. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +69 -2
  274. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +93 -1
  276. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  277. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -0
  278. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +1 -0
  280. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  282. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +3 -0
  283. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  284. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +26 -0
  285. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  286. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +20 -0
  288. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts +2 -0
  290. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts.map +1 -0
  291. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js +79 -0
  292. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js.map +1 -0
  293. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  294. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  295. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +13 -0
  296. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
  298. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  299. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +18 -1
  300. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  301. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  302. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
  303. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  304. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts +11 -0
  305. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts.map +1 -0
  306. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js +18 -0
  307. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js.map +1 -0
  308. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts +2 -0
  309. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts.map +1 -0
  310. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +48 -0
  311. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -0
  312. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
  313. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
  314. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +10 -0
  315. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
  316. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  317. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
  318. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  319. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
  320. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
  321. package/packages/pi-coding-agent/src/core/agent-session.ts +48 -7
  322. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +89 -0
  323. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  324. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  325. package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
  326. package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
  327. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  328. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +113 -3
  329. package/packages/pi-coding-agent/src/core/extensions/runner.ts +24 -6
  330. package/packages/pi-coding-agent/src/core/extensions/types.ts +42 -1
  331. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  332. package/packages/pi-coding-agent/src/core/model-registry.ts +4 -0
  333. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  334. package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
  335. package/packages/pi-coding-agent/src/core/settings-manager.ts +51 -1
  336. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  337. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  338. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  339. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
  340. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +78 -15
  341. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +59 -0
  342. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +160 -0
  343. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
  344. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +10 -9
  345. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  346. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +10 -9
  347. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +122 -17
  348. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +99 -1
  349. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +92 -3
  350. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -0
  351. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -1
  352. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +28 -0
  353. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.test.ts +95 -0
  354. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +24 -1
  355. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +13 -0
  356. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +32 -2
  357. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
  358. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +65 -0
  359. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.ts +29 -0
  360. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +14 -0
  361. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
  362. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  363. package/packages/pi-tui/dist/__tests__/style.test.d.ts +2 -0
  364. package/packages/pi-tui/dist/__tests__/style.test.d.ts.map +1 -0
  365. package/packages/pi-tui/dist/__tests__/style.test.js +63 -0
  366. package/packages/pi-tui/dist/__tests__/style.test.js.map +1 -0
  367. package/packages/pi-tui/dist/__tests__/tui.test.js +24 -3
  368. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  369. package/packages/pi-tui/dist/index.d.ts +1 -0
  370. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  371. package/packages/pi-tui/dist/index.js +2 -0
  372. package/packages/pi-tui/dist/index.js.map +1 -1
  373. package/packages/pi-tui/dist/style.d.ts +41 -0
  374. package/packages/pi-tui/dist/style.d.ts.map +1 -0
  375. package/packages/pi-tui/dist/style.js +158 -0
  376. package/packages/pi-tui/dist/style.js.map +1 -0
  377. package/packages/pi-tui/dist/tui.d.ts +0 -1
  378. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  379. package/packages/pi-tui/dist/tui.js +21 -16
  380. package/packages/pi-tui/dist/tui.js.map +1 -1
  381. package/packages/pi-tui/src/__tests__/style.test.ts +76 -0
  382. package/packages/pi-tui/src/__tests__/tui.test.ts +29 -3
  383. package/packages/pi-tui/src/index.ts +9 -0
  384. package/packages/pi-tui/src/style.ts +225 -0
  385. package/packages/pi-tui/src/tui.ts +23 -16
  386. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  387. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  388. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  389. package/pkg/dist/modes/interactive/theme/theme-schema.js +13 -0
  390. package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  391. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
  392. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  393. package/pkg/dist/modes/interactive/theme/theme.js +18 -1
  394. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  395. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  396. package/pkg/dist/modes/interactive/theme/themes.js +36 -27
  397. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  398. package/src/resources/GSD-WORKFLOW.md +2 -2
  399. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +30 -0
  400. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +26 -0
  401. package/src/resources/extensions/github-sync/templates.ts +38 -8
  402. package/src/resources/extensions/github-sync/tests/inline-code.test.ts +66 -0
  403. package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -2
  404. package/src/resources/extensions/gsd/auto/loop.ts +151 -26
  405. package/src/resources/extensions/gsd/auto/phases.ts +289 -196
  406. package/src/resources/extensions/gsd/auto/resolve.ts +42 -1
  407. package/src/resources/extensions/gsd/auto/run-unit.ts +52 -44
  408. package/src/resources/extensions/gsd/auto/session.ts +8 -0
  409. package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
  410. package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
  411. package/src/resources/extensions/gsd/auto-dashboard.ts +57 -8
  412. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
  413. package/src/resources/extensions/gsd/auto-dispatch.ts +33 -0
  414. package/src/resources/extensions/gsd/auto-post-unit.ts +28 -14
  415. package/src/resources/extensions/gsd/auto-prompts.ts +228 -16
  416. package/src/resources/extensions/gsd/auto-recovery.ts +207 -7
  417. package/src/resources/extensions/gsd/auto-start.ts +237 -15
  418. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  419. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  420. package/src/resources/extensions/gsd/auto-worktree.ts +123 -0
  421. package/src/resources/extensions/gsd/auto.ts +110 -22
  422. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +119 -2
  423. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +50 -36
  424. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +16 -5
  425. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +34 -19
  426. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +8 -1
  427. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +10 -3
  428. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +9 -2
  429. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +386 -55
  430. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  431. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +135 -1
  432. package/src/resources/extensions/gsd/clean-root-preflight.ts +72 -9
  433. package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
  434. package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
  435. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  436. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  437. package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
  438. package/src/resources/extensions/gsd/custom-workflow-engine.ts +24 -1
  439. package/src/resources/extensions/gsd/db/unit-dispatches.ts +107 -0
  440. package/src/resources/extensions/gsd/db-base-schema.ts +19 -2
  441. package/src/resources/extensions/gsd/db-migration-steps.ts +25 -0
  442. package/src/resources/extensions/gsd/detection.ts +128 -0
  443. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  444. package/src/resources/extensions/gsd/git-service.ts +46 -8
  445. package/src/resources/extensions/gsd/graph.ts +12 -5
  446. package/src/resources/extensions/gsd/gsd-db.ts +168 -13
  447. package/src/resources/extensions/gsd/guided-flow.ts +150 -51
  448. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  449. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  450. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  451. package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
  452. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  453. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  454. package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
  455. package/src/resources/extensions/gsd/pr-evidence.ts +63 -5
  456. package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
  457. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  458. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  459. package/src/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
  460. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  461. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  462. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  463. package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  464. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  465. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  466. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  467. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  468. package/src/resources/extensions/gsd/quick.ts +37 -2
  469. package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
  470. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +2 -2
  471. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +7 -1
  472. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +33 -0
  473. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +516 -15
  474. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +56 -13
  475. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +184 -2
  476. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +168 -6
  477. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +97 -2
  478. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
  479. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  480. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  481. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  482. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  483. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  484. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +55 -0
  485. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
  486. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +117 -7
  487. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +40 -2
  488. package/src/resources/extensions/gsd/tests/db-migration-steps.integration.test.ts +428 -0
  489. package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +2 -2
  490. package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
  491. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  492. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  493. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  494. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
  495. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  496. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
  497. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-basic.md +52 -0
  498. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-empty-optionals.md +42 -0
  499. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +55 -0
  500. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +60 -0
  501. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +10 -0
  502. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
  503. package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
  504. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +54 -0
  505. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +6 -3
  506. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +239 -1
  507. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  508. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  509. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  510. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
  511. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  512. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  513. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
  514. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  515. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
  516. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
  517. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  518. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  519. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
  520. package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
  521. package/src/resources/extensions/gsd/tests/pr-evidence-equivalence.test.ts +102 -0
  522. package/src/resources/extensions/gsd/tests/pr-evidence-hardening.test.ts +165 -0
  523. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
  524. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  525. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  526. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +19 -0
  527. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +3 -3
  528. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  529. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +38 -17
  530. package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
  531. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
  532. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  533. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  534. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
  535. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +166 -0
  536. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  537. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +38 -0
  538. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  539. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +101 -2
  540. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
  541. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +9 -0
  542. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  543. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  544. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
  545. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
  546. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +80 -1
  547. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
  548. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -4
  549. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  550. package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
  551. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  552. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  553. package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
  554. package/src/resources/extensions/gsd/tests/working-output-messages.test.ts +93 -0
  555. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +37 -6
  556. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
  557. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
  558. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
  559. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  560. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  561. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +167 -4
  562. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +179 -0
  563. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  564. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  565. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  566. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  567. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
  568. package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
  569. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  570. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  571. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  572. package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
  573. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  574. package/src/resources/extensions/gsd/working-output-messages.ts +120 -0
  575. package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
  576. package/src/resources/extensions/gsd/worktree-resolver.ts +85 -19
  577. package/packages/contracts/tsconfig.tsbuildinfo +0 -1
  578. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +0 -97
  579. /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → cWaxzf-sdbSSbbwYu8q7a}/_buildManifest.js +0 -0
  580. /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → cWaxzf-sdbSSbbwYu8q7a}/_ssgManifest.js +0 -0
@@ -34,6 +34,7 @@ import { snapshotSkills } from "./skill-discovery.js";
34
34
  import { isDbAvailable, getMilestone, openDatabase, getDbStatus } from "./gsd-db.js";
35
35
  import { isClosedStatus } from "./status-guards.js";
36
36
  import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
37
+ import { auditOrphanedPreflightStashes } from "./orphan-stash-audit.js";
37
38
  import { debugLog, enableDebug, isDebugEnabled, getDebugLogPath, } from "./debug-logger.js";
38
39
  import { logWarning, logError } from "./workflow-logger.js";
39
40
  import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, } from "node:fs";
@@ -224,6 +225,139 @@ export function auditOrphanedMilestoneBranches(basePath, isolationMode) {
224
225
  }
225
226
  return { recovered, warnings };
226
227
  }
228
+ /**
229
+ * Pure decision function for picking which orphan milestone the auto-loop
230
+ * should resume the merge transition for. Extracted so it can be unit-tested
231
+ * without spinning up a git repo or a SQLite DB.
232
+ *
233
+ * Returns the lexicographically-greatest milestone id (e.g. "M002" beats
234
+ * "M001") whose branch is unmerged AND has commits ahead of main AND whose
235
+ * status is `complete`. Lex-ordering matches the project's M00x convention,
236
+ * which is the most-recently-completed milestone in practice.
237
+ * `isComplete` errors propagate; `commitsAhead` errors are treated as 0.
238
+ */
239
+ export function _selectResumableMilestone(branchNames, mergedBranches, isComplete, commitsAhead) {
240
+ const candidates = [];
241
+ for (const branch of branchNames) {
242
+ if (!branch.startsWith("milestone/"))
243
+ continue;
244
+ const milestoneId = branch.slice("milestone/".length);
245
+ if (mergedBranches.has(branch))
246
+ continue;
247
+ if (!isComplete(milestoneId))
248
+ continue;
249
+ let ahead = 0;
250
+ try {
251
+ ahead = commitsAhead(branch);
252
+ }
253
+ catch {
254
+ continue;
255
+ }
256
+ if (ahead <= 0)
257
+ continue;
258
+ candidates.push(milestoneId);
259
+ }
260
+ if (candidates.length === 0)
261
+ return null;
262
+ candidates.sort();
263
+ return candidates[candidates.length - 1];
264
+ }
265
+ /**
266
+ * Find the most-recent completed milestone whose branch still has unmerged
267
+ * commits ahead of the integration branch. Used by `bootstrapAutoSession`
268
+ * to seed `s.currentMilestoneId` so the auto-loop's transition guard at
269
+ * `phases.ts:730` fires on the first iteration after a process restart —
270
+ * without this, the in-memory-only `s.currentMilestoneId` is `null` after
271
+ * restart, the guard short-circuits, and the orphaned milestone branch
272
+ * never gets merged into main (#5538-followup).
273
+ *
274
+ * Returns null when isolation is `none`, the DB is unavailable, or no
275
+ * orphan candidate exists. All git failures degrade silently — startup
276
+ * must never block on this defensive lookup.
277
+ */
278
+ export function findUnmergedCompletedMilestone(basePath, isolationMode) {
279
+ if (isolationMode === "none")
280
+ return null;
281
+ if (!isDbAvailable())
282
+ return null;
283
+ let milestoneBranches;
284
+ try {
285
+ milestoneBranches = nativeBranchList(basePath, "milestone/*");
286
+ }
287
+ catch {
288
+ return null;
289
+ }
290
+ if (milestoneBranches.length === 0)
291
+ return null;
292
+ let mainBranch;
293
+ try {
294
+ mainBranch = nativeDetectMainBranch(basePath);
295
+ }
296
+ catch {
297
+ mainBranch = "main";
298
+ }
299
+ let mergedBranches;
300
+ try {
301
+ mergedBranches = new Set(nativeBranchListMerged(basePath, mainBranch, "milestone/*"));
302
+ }
303
+ catch {
304
+ mergedBranches = new Set();
305
+ }
306
+ return _selectResumableMilestone(milestoneBranches, mergedBranches, (milestoneId) => {
307
+ const row = getMilestone(milestoneId);
308
+ return !!row && row.status === "complete";
309
+ }, (branch) => nativeCommitCountBetween(basePath, mainBranch, branch));
310
+ }
311
+ /**
312
+ * Run `mergeAndExit` for a milestone whose worktree/branch finalization
313
+ * never completed in a prior session — the active-milestone in phase
314
+ * `complete` with a survivor `milestone/<id>` branch still around.
315
+ *
316
+ * Wraps the call in try/catch so a thrown error from `_mergeBranchMode`
317
+ * (made fail-loud in commit 68ef58a3c) is converted into a user-facing
318
+ * error notify instead of an unhandled exception that propagates through
319
+ * `bootstrapAutoSession` to the slash-command caller's `.catch` block.
320
+ *
321
+ * Returns `{ merged: true }` on success; `{ merged: false, error }` on
322
+ * throw — caller decides whether to abort bootstrap.
323
+ */
324
+ export function _finalizeSurvivorBranch(resolver, milestoneId, ui) {
325
+ ui.notify(`Milestone ${milestoneId} is complete but branch/worktree was not finalized. Running merge now.`, "info");
326
+ try {
327
+ resolver.mergeAndExit(milestoneId, { notify: ui.notify.bind(ui) });
328
+ return { merged: true };
329
+ }
330
+ catch (err) {
331
+ const msg = err instanceof Error ? err.message : String(err);
332
+ ui.notify(`Survivor-branch finalization for ${milestoneId} failed: ${msg}. Resolve manually and re-run /gsd auto.`, "error");
333
+ return { merged: false, error: err };
334
+ }
335
+ }
336
+ /**
337
+ * Merge a milestone whose DB row is `complete` but whose branch is still
338
+ * unmerged into the integration branch. Called from `bootstrapAutoSession`
339
+ * for orphans surfaced by `findUnmergedCompletedMilestone`.
340
+ *
341
+ * Notifies the user before and after, swallowing errors so a transient git
342
+ * failure never blocks bootstrap. Returns `{ merged: true }` when the
343
+ * underlying `mergeAndExit` completes; `{ merged: false, error }` on throw.
344
+ *
345
+ * Extracted to keep `bootstrapAutoSession` testable: the merge call and the
346
+ * notify shape are exercised against a mock resolver in
347
+ * `tests/orphan-merge-bootstrap.test.ts`.
348
+ */
349
+ export function _mergeOrphanCompletedMilestone(resolver, orphanId, ui) {
350
+ ui.notify(`Detected unmerged completed milestone ${orphanId}. Merging now.`, "info");
351
+ try {
352
+ resolver.mergeAndExit(orphanId, { notify: ui.notify.bind(ui) });
353
+ return { merged: true };
354
+ }
355
+ catch (err) {
356
+ const msg = err instanceof Error ? err.message : String(err);
357
+ ui.notify(`Could not merge orphan milestone ${orphanId}: ${msg}. Resolve manually and re-run /gsd auto.`, "warning");
358
+ return { merged: false, error: err };
359
+ }
360
+ }
227
361
  export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, requestedStepMode, deps, interrupted) {
228
362
  const { shouldUseWorktreeIsolation, registerSigtermHandler, lockBase, buildResolver, } = deps;
229
363
  const dirCheck = validateDirectory(base);
@@ -420,6 +554,33 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
420
554
  // Non-fatal — the audit is defensive, never block bootstrap
421
555
  logWarning("bootstrap", `orphaned milestone branch audit failed: ${err instanceof Error ? err.message : String(err)}`);
422
556
  }
557
+ // ── Orphaned preflight-stash audit (#5538-followup) ──
558
+ // Reapplies pre-merge stashes whose milestone is now complete but whose
559
+ // postflight pop was skipped by an interrupted merge in a prior session.
560
+ // Uses `git stash apply` (not pop) so the entry remains as a backup.
561
+ try {
562
+ if (isDbAvailable()) {
563
+ const stashAudit = auditOrphanedPreflightStashes(base, (milestoneId) => {
564
+ const row = getMilestone(milestoneId);
565
+ return !!row && isClosedStatus(row.status);
566
+ });
567
+ for (const entry of stashAudit.applied) {
568
+ ctx.ui.notify(`Orphan audit: applied preflight stash ${entry.stashRef} for completed milestone ${entry.milestoneId}. The stash entry is preserved as a backup.`, "info");
569
+ }
570
+ for (const msg of stashAudit.warnings) {
571
+ ctx.ui.notify(`Orphan audit: ${msg}`, "warning");
572
+ }
573
+ if (stashAudit.applied.length > 0) {
574
+ debugLog("orphan-stash-audit", {
575
+ applied: stashAudit.applied,
576
+ warnings: stashAudit.warnings,
577
+ });
578
+ }
579
+ }
580
+ }
581
+ catch (err) {
582
+ logWarning("bootstrap", `orphaned preflight-stash audit failed: ${err instanceof Error ? err.message : String(err)}`);
583
+ }
423
584
  let state = await deriveState(base);
424
585
  // Stale worktree state recovery (#654)
425
586
  if (state.activeMilestone &&
@@ -476,20 +637,49 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
476
637
  // hasSurvivorBranch after a successful promotion.
477
638
  if (decideSurvivorAction(hasSurvivorBranch, state.phase) === "finalize") {
478
639
  const mid = state.activeMilestone.id;
479
- ctx.ui.notify(`Milestone ${mid} is complete but branch/worktree was not finalized. Running merge now.`, "info");
480
- const resolver = buildResolver();
481
- resolver.mergeAndExit(mid, {
482
- notify: ctx.ui.notify.bind(ctx.ui),
483
- });
640
+ // Commit 68ef58a3c made `_mergeBranchMode` throw on wrong-branch
641
+ // instead of returning false silently. Wrap the call so the throw is
642
+ // converted into an error notify + clean bootstrap abort, not an
643
+ // unhandled exception propagating to the slash-command caller (#5549
644
+ // post-merge audit, R2).
645
+ const finalize = _finalizeSurvivorBranch(buildResolver(), mid, ctx.ui);
646
+ if (!finalize.merged) {
647
+ return releaseLockAndReturn();
648
+ }
484
649
  invalidateAllCaches();
485
650
  state = await deriveState(base);
486
651
  // Clear survivor flag — finalization is done
487
652
  hasSurvivorBranch = false;
488
653
  }
654
+ // ── Orphan-completed-milestone merge (#5538-followup) ──
655
+ // A process killed between `complete-milestone` (DB flip + SUMMARY write)
656
+ // and the loop's transition-guard merge strands the milestone branch
657
+ // forever: `s.currentMilestoneId` is in-memory only, so on the next
658
+ // bootstrap the guard at phases.ts:730 sees `mid === s.currentMilestoneId`
659
+ // and short-circuits.
660
+ //
661
+ // The earlier attempt at this fix seeded `s.currentMilestoneId` to the
662
+ // orphan id pre-state-derivation, but the unconditional assignment at
663
+ // line 948 (`s.currentMilestoneId = state.activeMilestone?.id ?? null`)
664
+ // immediately overwrote the seed. Active-merge is the more durable fix:
665
+ // call `mergeAndExit` directly during bootstrap, then re-derive state so
666
+ // the loop's normal flow continues without an in-memory hint.
667
+ //
668
+ // Mirrors the survivor-finalize block above. Failures degrade to a
669
+ // warning notify so a transient git error doesn't block bootstrap.
670
+ {
671
+ const orphan = findUnmergedCompletedMilestone(base, getIsolationMode(base));
672
+ if (orphan && orphan !== state.activeMilestone?.id) {
673
+ const result = _mergeOrphanCompletedMilestone(buildResolver(), orphan, ctx.ui);
674
+ if (result.merged) {
675
+ invalidateAllCaches();
676
+ state = await deriveState(base);
677
+ }
678
+ }
679
+ }
489
680
  const effectivePrefs = loadEffectiveGSDPreferences(base)?.preferences;
490
- const deepProjectStagePending = !hasSurvivorBranch
491
- ? (await import("./auto-dispatch.js")).hasPendingDeepStage(effectivePrefs, base)
492
- : false;
681
+ const { shouldRunDeepProjectSetup } = await import("./auto-dispatch.js");
682
+ const deepProjectStagePending = shouldRunDeepProjectSetup(state, effectivePrefs, base, { hasSurvivorBranch });
493
683
  if (deepProjectStagePending) {
494
684
  // Deep project-level setup runs before the first milestone exists. Let
495
685
  // the auto loop dispatch workflow-preferences / project / requirements
@@ -591,7 +781,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
591
781
  s.resourceVersionOnStart = readResourceVersion();
592
782
  s.pendingQuickTasks = [];
593
783
  s.currentUnit = null;
594
- s.currentMilestoneId = deepProjectStagePending ? null : state.activeMilestone?.id ?? null;
784
+ s.currentMilestoneId ??= deepProjectStagePending ? null : state.activeMilestone?.id ?? null;
595
785
  s.originalModelId = startModelSnapshot?.id ?? ctx.model?.id ?? null;
596
786
  s.originalModelProvider = startModelSnapshot?.provider ?? ctx.model?.provider ?? null;
597
787
  s.originalThinkingLevel = startThinkingSnapshot ?? null;
@@ -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
  }
@@ -225,8 +239,16 @@ function synthesizePausedSessionRecovery(basePath, unitType, unitId, sessionFile
225
239
  export function _synthesizePausedSessionRecoveryForTest(basePath, unitType, unitId, sessionFile) {
226
240
  return synthesizePausedSessionRecovery(basePath, unitType, unitId, sessionFile);
227
241
  }
242
+ const DETACHED_AUTO_KEEPALIVE_INTERVAL_MS = 30_000;
243
+ function withDetachedAutoKeepalive(run) {
244
+ const keepAlive = setInterval(() => { }, DETACHED_AUTO_KEEPALIVE_INTERVAL_MS);
245
+ return run.finally(() => {
246
+ clearInterval(keepAlive);
247
+ });
248
+ }
249
+ export const _withDetachedAutoKeepaliveForTest = withDetachedAutoKeepalive;
228
250
  export function startAutoDetached(ctx, pi, base, verboseMode, options) {
229
- void startAuto(ctx, pi, base, verboseMode, options).catch((err) => {
251
+ void withDetachedAutoKeepalive(startAuto(ctx, pi, base, verboseMode, options)).catch((err) => {
230
252
  const message = getErrorMessage(err);
231
253
  ctx.ui.notify(`Auto-start failed: ${message}`, "error");
232
254
  logWarning("engine", `auto start error: ${message}`, { file: "auto.ts" });
@@ -264,9 +286,50 @@ export function shouldUseWorktreeIsolation(basePath) {
264
286
  */
265
287
  // Re-export budget utilities for external consumers
266
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
+ }
267
330
  /** Wrapper: register SIGTERM handler and store reference. */
268
331
  function registerSigtermHandler(currentBasePath) {
269
- s.sigtermHandler = _registerSigtermHandler(currentBasePath, s.sigtermHandler);
332
+ s.sigtermHandler = _registerSigtermHandler(currentBasePath, s.sigtermHandler, () => closeOutSignalInterruptedUnit(currentBasePath));
270
333
  }
271
334
  /** Wrapper: deregister SIGTERM handler and clear reference. */
272
335
  function deregisterSigtermHandler() {
@@ -658,6 +721,8 @@ export async function stopAuto(ctx, pi, reason) {
658
721
  if (s.workerId) {
659
722
  markWorkerStopping(s.workerId);
660
723
  }
724
+ s.workerId = null;
725
+ s.milestoneLeaseToken = null;
661
726
  }
662
727
  catch (e) {
663
728
  debugLog("stop-cleanup-coordination", { error: e instanceof Error ? e.message : String(e) });
@@ -790,6 +855,21 @@ export async function stopAuto(ctx, pi, reason) {
790
855
  catch (e) {
791
856
  debugLog("stop-cleanup-basepath", { error: e instanceof Error ? e.message : String(e) });
792
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
+ }
793
873
  // ── Step 8: Ledger notification ──
794
874
  try {
795
875
  const ledger = getLedger();
@@ -1038,6 +1118,7 @@ function buildResolverDeps() {
1038
1118
  getAutoWorktreePath,
1039
1119
  autoCommitCurrentBranch,
1040
1120
  getCurrentBranch,
1121
+ checkoutBranch: nativeCheckoutBranch,
1041
1122
  autoWorktreeBranch,
1042
1123
  resolveMilestoneFile,
1043
1124
  readFileSync: (path, encoding) => readFileSync(path, encoding),
@@ -1558,6 +1639,10 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
1558
1639
  : new URL("../../../resource-loader.js", import.meta.url).href;
1559
1640
  const { initResources } = await import(resourceLoaderPath);
1560
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();
1561
1646
  // Open the project DB before rebuild/derive so resume uses DB-backed
1562
1647
  // state instead of falling back to stale markdown parsing (#2940).
1563
1648
  await openProjectDbIfPresent(s.basePath);
@@ -1623,6 +1708,10 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
1623
1708
  lockBase,
1624
1709
  buildResolver,
1625
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);
1626
1715
  const ready = await bootstrapAutoSession(s, ctx, pi, base, verboseMode, requestedStepMode, bootstrapDeps, freshStartAssessment);
1627
1716
  if (!ready)
1628
1717
  return;
@@ -1740,28 +1829,7 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
1740
1829
  id: triggerUnitId,
1741
1830
  startedAt: hookStartedAt,
1742
1831
  };
1743
- // Ensure cwd matches basePath BEFORE newSession() captures it (#1389).
1744
- // newSession() snapshots process.cwd() during construction; chdir-ing
1745
- // afterward leaves the session rooted to whatever cwd was when the call
1746
- // was made. Must be synchronous — no awaits between chdir and newSession.
1747
- try {
1748
- if (process.cwd() !== s.basePath)
1749
- process.chdir(s.basePath);
1750
- }
1751
- catch (err) {
1752
- const msg = `Failed to chdir before hook newSession (basePath: ${s.basePath}): ${err instanceof Error ? err.message : String(err)}`;
1753
- logWarning("engine", msg, { file: "auto.ts", basePath: s.basePath, error: err instanceof Error ? err.message : String(err) });
1754
- ctx.ui.notify(`${msg}. Cancelling hook dispatch to avoid running in the wrong directory.`, "error");
1755
- if (wasActive) {
1756
- s.basePath = previousBasePath;
1757
- s.currentUnit = previousCurrentUnit;
1758
- }
1759
- else {
1760
- s.reset();
1761
- }
1762
- return false;
1763
- }
1764
- const result = await s.cmdCtx.newSession();
1832
+ const result = await s.cmdCtx.newSession({ workspaceRoot: s.basePath });
1765
1833
  if (result.cancelled) {
1766
1834
  await stopAuto(ctx, pi);
1767
1835
  return false;