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
@@ -14,7 +14,7 @@ import { appendEvent } from "./workflow-events.js";
14
14
  import { atomicWriteSync } from "./atomic-write.js";
15
15
  import { clearParseCache } from "./files.js";
16
16
  import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from "./parsers-legacy.js";
17
- import { isDbAvailable, getTask, getSlice, getSliceTasks, getPendingGates, updateTaskStatus, updateSliceStatus, insertSlice, getMilestone, refreshOpenDatabaseFromDisk } from "./gsd-db.js";
17
+ import { isDbAvailable, getTask, getSlice, getSliceTasks, getPendingGates, updateTaskStatus, updateSliceStatus, insertSlice, getMilestone, refreshOpenDatabaseFromDisk, getCompletedMilestoneTaskFileHints, getMilestoneCommitAttributionShas, recordMilestoneCommitAttribution } from "./gsd-db.js";
18
18
  import { isValidationTerminal } from "./state.js";
19
19
  import { getErrorMessage } from "./error-utils.js";
20
20
  import { logWarning, logError } from "./workflow-logger.js";
@@ -67,6 +67,60 @@ export {
67
67
 
68
68
  // ─── Artifact Resolution & Verification ───────────────────────────────────────
69
69
 
70
+ export type ArtifactRecoveryDbRefreshResult =
71
+ | { ok: true }
72
+ | { ok: false; fatal: boolean; message: string; reason: string };
73
+
74
+ export function refreshRecoveryDbForArtifact(
75
+ unitType: string,
76
+ unitId: string,
77
+ ): ArtifactRecoveryDbRefreshResult {
78
+ if (unitType !== "plan-slice" && unitType !== "execute-task") return { ok: true };
79
+ if (!isDbAvailable()) return { ok: true };
80
+
81
+ if (!refreshOpenDatabaseFromDisk()) {
82
+ return {
83
+ ok: false,
84
+ fatal: unitType === "execute-task",
85
+ reason: `${unitType}-db-refresh-failed`,
86
+ message: `Stuck recovery found ${unitType} ${unitId} artifacts, but the DB refresh failed.`,
87
+ };
88
+ }
89
+
90
+ if (unitType !== "execute-task") return { ok: true };
91
+
92
+ const { milestone: mid, slice: sid, task: tid } = parseUnitId(unitId);
93
+ if (!mid || !sid || !tid) {
94
+ return {
95
+ ok: false,
96
+ fatal: true,
97
+ reason: "execute-task-invalid-unit-id",
98
+ message: `Stuck recovery found execute-task ${unitId} artifacts, but the unit id could not be parsed for DB verification.`,
99
+ };
100
+ }
101
+
102
+ const task = getTask(mid, sid, tid);
103
+ if (!task) {
104
+ return {
105
+ ok: false,
106
+ fatal: true,
107
+ reason: "execute-task-artifact-db-missing",
108
+ message: `Stuck recovery found execute-task ${unitId} artifacts, but no matching DB task row exists after refresh.`,
109
+ };
110
+ }
111
+
112
+ if (!isClosedStatus(task.status)) {
113
+ return {
114
+ ok: false,
115
+ fatal: true,
116
+ reason: "execute-task-artifact-db-mismatch",
117
+ message: `Stuck recovery found execute-task ${unitId} artifacts, but the DB task status is still '${task.status}' after refresh.`,
118
+ };
119
+ }
120
+
121
+ return { ok: true };
122
+ }
123
+
70
124
  function hasCapturedWorkflowPrefs(base: string): boolean {
71
125
  const prefsPath = resolveExpectedArtifactPath("workflow-preferences", "WORKFLOW-PREFS", base);
72
126
  if (!prefsPath || !existsSync(prefsPath)) return false;
@@ -147,15 +201,29 @@ export function hasImplementationArtifacts(basePath: string, milestoneId?: strin
147
201
  // milestone commits instead of treating the self-diff as proof of no work.
148
202
  if (changedFiles.length === 0) {
149
203
  if (milestoneId && currentBranch === integrationBranch) {
150
- const tagged = getChangedFilesFromMilestoneTaggedCommits(basePath, milestoneId);
151
- if (!tagged.ok) return "unknown";
152
- if (tagged.matched) return classifyImplementationFiles(tagged.files);
204
+ const milestoneEvidence = getChangedFilesFromMilestoneEvidence(basePath, milestoneId);
205
+ if (!milestoneEvidence.ok) return "unknown";
206
+ if (milestoneEvidence.matched) return classifyImplementationFiles(milestoneEvidence.files);
153
207
  }
154
208
  if (currentBranch && currentBranch !== "HEAD") return "absent";
155
209
  return "unknown";
156
210
  }
157
211
 
158
- return classifyImplementationFiles(changedFiles);
212
+ const branchClassification = classifyImplementationFiles(changedFiles);
213
+ if (branchClassification === "present") return "present";
214
+
215
+ // A completing milestone branch can have a non-empty diff containing only
216
+ // .gsd/ closeout files after implementation commits already landed on the
217
+ // recorded integration branch. In that topology, the branch diff alone is
218
+ // insufficient; use the same milestone-tagged evidence fallback as the
219
+ // self-diff retry path before declaring the milestone implementation-free.
220
+ if (milestoneId) {
221
+ const milestoneEvidence = getChangedFilesFromMilestoneEvidence(basePath, milestoneId);
222
+ if (!milestoneEvidence.ok) return "unknown";
223
+ if (milestoneEvidence.matched) return classifyImplementationFiles(milestoneEvidence.files);
224
+ }
225
+
226
+ return "absent";
159
227
  } catch (e) {
160
228
  // Non-fatal — if git operations fail, return unknown so callers can decide
161
229
  logWarning("recovery", `implementation artifact check failed: ${(e as Error).message}`);
@@ -185,6 +253,10 @@ function isImplementationPath(file: string): boolean {
185
253
  return !file.startsWith(".gsd/") && !file.startsWith(".gsd\\");
186
254
  }
187
255
 
256
+ function normalizeRepoPath(file: string): string {
257
+ return file.trim().replace(/\\/g, "/").replace(/^\.\/+/, "");
258
+ }
259
+
188
260
  /**
189
261
  * Detect the main/master branch name.
190
262
  */
@@ -263,7 +335,7 @@ function getChangedFilesFromMilestoneTaggedCommits(
263
335
  "log", "--format=%H%x1f%B%x1e", "HEAD", "--", `.gsd/milestones/${milestoneId}`,
264
336
  ]);
265
337
  if (!scoped.ok) return scoped;
266
- if (scoped.matched) return scoped;
338
+ if (scoped.matched && classifyImplementationFiles(scoped.files) === "present") return scoped;
267
339
 
268
340
  // Fallback (#5033): when .gsd/ is gitignored / external / untracked, the
269
341
  // path-scoped scan matches no commits even though GSD-tagged commits
@@ -274,9 +346,137 @@ function getChangedFilesFromMilestoneTaggedCommits(
274
346
  // Intentionally unbounded — symmetric with the primary scan, and avoids
275
347
  // reintroducing the rolling-depth failure class removed in #4699 where
276
348
  // milestone evidence aged out behind unrelated activity.
277
- return scanGsdTaggedCommits(basePath, milestoneId, [
349
+ const unscoped = scanGsdTaggedCommits(basePath, milestoneId, [
278
350
  "log", "--format=%H%x1f%B%x1e", "HEAD",
279
351
  ]);
352
+ if (!unscoped.ok) return scoped.matched ? scoped : unscoped;
353
+ if (!unscoped.matched) return scoped;
354
+
355
+ return {
356
+ ok: true,
357
+ matched: true,
358
+ files: [...new Set([...scoped.files, ...unscoped.files])],
359
+ };
360
+ }
361
+
362
+ function getChangedFilesFromMilestoneEvidence(
363
+ basePath: string,
364
+ milestoneId: string,
365
+ ): { ok: boolean; matched: boolean; files: string[] } {
366
+ const tagged = getChangedFilesFromMilestoneTaggedCommits(basePath, milestoneId);
367
+ if (!tagged.ok) return tagged;
368
+ if (tagged.matched && classifyImplementationFiles(tagged.files) === "present") return tagged;
369
+
370
+ const attributed = getChangedFilesFromAttributedMilestoneCommits(basePath, milestoneId);
371
+ if (!attributed.ok) return tagged.matched ? tagged : attributed;
372
+ if (attributed.matched && classifyImplementationFiles(attributed.files) === "present") return attributed;
373
+
374
+ const backfilled = backfillChangedFilesFromUntaggedMilestoneCommits(basePath, milestoneId);
375
+ if (!backfilled.ok) return tagged.matched ? tagged : attributed.matched ? attributed : backfilled;
376
+ if (!backfilled.matched) {
377
+ if (tagged.matched) return tagged;
378
+ return attributed.matched ? attributed : backfilled;
379
+ }
380
+
381
+ return {
382
+ ok: true,
383
+ matched: true,
384
+ files: [...new Set([...tagged.files, ...attributed.files, ...backfilled.files])],
385
+ };
386
+ }
387
+
388
+ function getChangedFilesFromAttributedMilestoneCommits(
389
+ basePath: string,
390
+ milestoneId: string,
391
+ ): { ok: boolean; matched: boolean; files: string[] } {
392
+ try {
393
+ const shas = getMilestoneCommitAttributionShas(milestoneId);
394
+ if (shas.length === 0) return { ok: true, matched: false, files: [] };
395
+
396
+ const files = new Set<string>();
397
+ let matched = false;
398
+ for (const sha of shas) {
399
+ if (!isFullCommitSha(sha)) continue;
400
+ const commitFiles = getChangedFilesForCommit(basePath, sha);
401
+ if (commitFiles.length === 0) continue;
402
+ matched = true;
403
+ for (const file of commitFiles) files.add(file);
404
+ }
405
+ return { ok: true, matched, files: [...files] };
406
+ } catch (e) {
407
+ logWarning("recovery", `milestone attribution scan failed: ${(e as Error).message}`);
408
+ return { ok: false, matched: false, files: [] };
409
+ }
410
+ }
411
+
412
+ function backfillChangedFilesFromUntaggedMilestoneCommits(
413
+ basePath: string,
414
+ milestoneId: string,
415
+ ): { ok: boolean; matched: boolean; files: string[] } {
416
+ try {
417
+ const milestone = getMilestone(milestoneId);
418
+ const milestoneStartedAt = milestone?.created_at ? Math.floor(Date.parse(milestone.created_at) / 1000) * 1000 : NaN;
419
+ if (!Number.isFinite(milestoneStartedAt)) return { ok: true, matched: false, files: [] };
420
+
421
+ const taskFileHints = getCompletedMilestoneTaskFileHints(milestoneId);
422
+ if (taskFileHints.length === 0) return { ok: true, matched: false, files: [] };
423
+
424
+ const hintSet = new Set(taskFileHints.map(normalizeRepoPath).filter(Boolean));
425
+ if (hintSet.size === 0) return { ok: true, matched: false, files: [] };
426
+
427
+ const records = getCommitRecords(basePath);
428
+ const files = new Set<string>();
429
+ let matched = false;
430
+ for (const record of records) {
431
+ if (!isFullCommitSha(record.hash)) continue;
432
+ if (Date.parse(record.committedAt) < milestoneStartedAt) continue;
433
+ if (record.parents.trim().split(/\s+/).filter(Boolean).length > 1) continue;
434
+ if (commitMessageHasGsdTrailer(record.message)) continue;
435
+
436
+ const commitFiles = getChangedFilesForCommit(basePath, record.hash);
437
+ const implementationFiles = commitFiles.map(normalizeRepoPath).filter(isImplementationPath);
438
+ if (implementationFiles.length === 0) continue;
439
+ if (!implementationFiles.some((file) => hintSet.has(file))) continue;
440
+
441
+ matched = true;
442
+ for (const file of implementationFiles) files.add(file);
443
+ recordMilestoneCommitAttribution({
444
+ commitSha: record.hash,
445
+ milestoneId,
446
+ source: "backfill",
447
+ confidence: 0.8,
448
+ files: implementationFiles,
449
+ createdAt: new Date().toISOString(),
450
+ });
451
+ }
452
+
453
+ return { ok: true, matched, files: [...files] };
454
+ } catch (e) {
455
+ logWarning("recovery", `milestone attribution backfill failed: ${(e as Error).message}`);
456
+ return { ok: false, matched: false, files: [] };
457
+ }
458
+ }
459
+
460
+ function getCommitRecords(basePath: string): Array<{ hash: string; parents: string; committedAt: string; message: string }> {
461
+ const logOutput = execFileSync("git", ["log", "--format=%H%x1f%P%x1f%cI%x1f%B%x1e", "HEAD"], {
462
+ cwd: basePath,
463
+ stdio: ["ignore", "pipe", "pipe"],
464
+ encoding: "utf-8",
465
+ });
466
+ return logOutput
467
+ .split("\x1e")
468
+ .map((record) => record.trim())
469
+ .filter(Boolean)
470
+ .flatMap((record) => {
471
+ const parts = record.split("\x1f");
472
+ if (parts.length < 4) return [];
473
+ const [hash, parents, committedAt, ...messageParts] = parts;
474
+ return [{ hash: hash.trim(), parents: parents.trim(), committedAt: committedAt.trim(), message: messageParts.join("\x1f") }];
475
+ });
476
+ }
477
+
478
+ function isFullCommitSha(value: string): boolean {
479
+ return /^[0-9a-f]{40}$/i.test(value);
280
480
  }
281
481
 
282
482
  function scanGsdTaggedCommits(
@@ -65,6 +65,7 @@ import { snapshotSkills } from "./skill-discovery.js";
65
65
  import { isDbAvailable, getMilestone, openDatabase, getDbStatus } from "./gsd-db.js";
66
66
  import { isClosedStatus } from "./status-guards.js";
67
67
  import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
68
+ import { auditOrphanedPreflightStashes } from "./orphan-stash-audit.js";
68
69
 
69
70
  import {
70
71
  debugLog,
@@ -332,6 +333,165 @@ export function auditOrphanedMilestoneBranches(
332
333
  return { recovered, warnings };
333
334
  }
334
335
 
336
+ /**
337
+ * Pure decision function for picking which orphan milestone the auto-loop
338
+ * should resume the merge transition for. Extracted so it can be unit-tested
339
+ * without spinning up a git repo or a SQLite DB.
340
+ *
341
+ * Returns the lexicographically-greatest milestone id (e.g. "M002" beats
342
+ * "M001") whose branch is unmerged AND has commits ahead of main AND whose
343
+ * status is `complete`. Lex-ordering matches the project's M00x convention,
344
+ * which is the most-recently-completed milestone in practice.
345
+ * `isComplete` errors propagate; `commitsAhead` errors are treated as 0.
346
+ */
347
+ export function _selectResumableMilestone(
348
+ branchNames: readonly string[],
349
+ mergedBranches: ReadonlySet<string>,
350
+ isComplete: (milestoneId: string) => boolean,
351
+ commitsAhead: (branch: string) => number,
352
+ ): string | null {
353
+ const candidates: string[] = [];
354
+ for (const branch of branchNames) {
355
+ if (!branch.startsWith("milestone/")) continue;
356
+ const milestoneId = branch.slice("milestone/".length);
357
+ if (mergedBranches.has(branch)) continue;
358
+ if (!isComplete(milestoneId)) continue;
359
+ let ahead = 0;
360
+ try {
361
+ ahead = commitsAhead(branch);
362
+ } catch {
363
+ continue;
364
+ }
365
+ if (ahead <= 0) continue;
366
+ candidates.push(milestoneId);
367
+ }
368
+ if (candidates.length === 0) return null;
369
+ candidates.sort();
370
+ return candidates[candidates.length - 1];
371
+ }
372
+
373
+ /**
374
+ * Find the most-recent completed milestone whose branch still has unmerged
375
+ * commits ahead of the integration branch. Used by `bootstrapAutoSession`
376
+ * to seed `s.currentMilestoneId` so the auto-loop's transition guard at
377
+ * `phases.ts:730` fires on the first iteration after a process restart —
378
+ * without this, the in-memory-only `s.currentMilestoneId` is `null` after
379
+ * restart, the guard short-circuits, and the orphaned milestone branch
380
+ * never gets merged into main (#5538-followup).
381
+ *
382
+ * Returns null when isolation is `none`, the DB is unavailable, or no
383
+ * orphan candidate exists. All git failures degrade silently — startup
384
+ * must never block on this defensive lookup.
385
+ */
386
+ export function findUnmergedCompletedMilestone(
387
+ basePath: string,
388
+ isolationMode: "worktree" | "branch" | "none",
389
+ ): string | null {
390
+ if (isolationMode === "none") return null;
391
+ if (!isDbAvailable()) return null;
392
+
393
+ let milestoneBranches: string[];
394
+ try {
395
+ milestoneBranches = nativeBranchList(basePath, "milestone/*");
396
+ } catch {
397
+ return null;
398
+ }
399
+ if (milestoneBranches.length === 0) return null;
400
+
401
+ let mainBranch: string;
402
+ try {
403
+ mainBranch = nativeDetectMainBranch(basePath);
404
+ } catch {
405
+ mainBranch = "main";
406
+ }
407
+
408
+ let mergedBranches: Set<string>;
409
+ try {
410
+ mergedBranches = new Set(
411
+ nativeBranchListMerged(basePath, mainBranch, "milestone/*"),
412
+ );
413
+ } catch {
414
+ mergedBranches = new Set();
415
+ }
416
+
417
+ return _selectResumableMilestone(
418
+ milestoneBranches,
419
+ mergedBranches,
420
+ (milestoneId) => {
421
+ const row = getMilestone(milestoneId);
422
+ return !!row && row.status === "complete";
423
+ },
424
+ (branch) => nativeCommitCountBetween(basePath, mainBranch, branch),
425
+ );
426
+ }
427
+
428
+ /**
429
+ * Run `mergeAndExit` for a milestone whose worktree/branch finalization
430
+ * never completed in a prior session — the active-milestone in phase
431
+ * `complete` with a survivor `milestone/<id>` branch still around.
432
+ *
433
+ * Wraps the call in try/catch so a thrown error from `_mergeBranchMode`
434
+ * (made fail-loud in commit 68ef58a3c) is converted into a user-facing
435
+ * error notify instead of an unhandled exception that propagates through
436
+ * `bootstrapAutoSession` to the slash-command caller's `.catch` block.
437
+ *
438
+ * Returns `{ merged: true }` on success; `{ merged: false, error }` on
439
+ * throw — caller decides whether to abort bootstrap.
440
+ */
441
+ export function _finalizeSurvivorBranch(
442
+ resolver: WorktreeResolver,
443
+ milestoneId: string,
444
+ ui: { notify: (msg: string, level?: "info" | "warning" | "error" | "success") => void },
445
+ ): { merged: boolean; error?: unknown } {
446
+ ui.notify(
447
+ `Milestone ${milestoneId} is complete but branch/worktree was not finalized. Running merge now.`,
448
+ "info",
449
+ );
450
+ try {
451
+ resolver.mergeAndExit(milestoneId, { notify: ui.notify.bind(ui) });
452
+ return { merged: true };
453
+ } catch (err) {
454
+ const msg = err instanceof Error ? err.message : String(err);
455
+ ui.notify(
456
+ `Survivor-branch finalization for ${milestoneId} failed: ${msg}. Resolve manually and re-run /gsd auto.`,
457
+ "error",
458
+ );
459
+ return { merged: false, error: err };
460
+ }
461
+ }
462
+
463
+ /**
464
+ * Merge a milestone whose DB row is `complete` but whose branch is still
465
+ * unmerged into the integration branch. Called from `bootstrapAutoSession`
466
+ * for orphans surfaced by `findUnmergedCompletedMilestone`.
467
+ *
468
+ * Notifies the user before and after, swallowing errors so a transient git
469
+ * failure never blocks bootstrap. Returns `{ merged: true }` when the
470
+ * underlying `mergeAndExit` completes; `{ merged: false, error }` on throw.
471
+ *
472
+ * Extracted to keep `bootstrapAutoSession` testable: the merge call and the
473
+ * notify shape are exercised against a mock resolver in
474
+ * `tests/orphan-merge-bootstrap.test.ts`.
475
+ */
476
+ export function _mergeOrphanCompletedMilestone(
477
+ resolver: WorktreeResolver,
478
+ orphanId: string,
479
+ ui: { notify: (msg: string, level?: "info" | "warning" | "error" | "success") => void },
480
+ ): { merged: boolean; error?: unknown } {
481
+ ui.notify(`Detected unmerged completed milestone ${orphanId}. Merging now.`, "info");
482
+ try {
483
+ resolver.mergeAndExit(orphanId, { notify: ui.notify.bind(ui) });
484
+ return { merged: true };
485
+ } catch (err) {
486
+ const msg = err instanceof Error ? err.message : String(err);
487
+ ui.notify(
488
+ `Could not merge orphan milestone ${orphanId}: ${msg}. Resolve manually and re-run /gsd auto.`,
489
+ "warning",
490
+ );
491
+ return { merged: false, error: err };
492
+ }
493
+ }
494
+
335
495
  export async function bootstrapAutoSession(
336
496
  s: AutoSession,
337
497
  ctx: ExtensionCommandContext,
@@ -577,6 +737,39 @@ export async function bootstrapAutoSession(
577
737
  logWarning("bootstrap", `orphaned milestone branch audit failed: ${err instanceof Error ? err.message : String(err)}`);
578
738
  }
579
739
 
740
+ // ── Orphaned preflight-stash audit (#5538-followup) ──
741
+ // Reapplies pre-merge stashes whose milestone is now complete but whose
742
+ // postflight pop was skipped by an interrupted merge in a prior session.
743
+ // Uses `git stash apply` (not pop) so the entry remains as a backup.
744
+ try {
745
+ if (isDbAvailable()) {
746
+ const stashAudit = auditOrphanedPreflightStashes(base, (milestoneId) => {
747
+ const row = getMilestone(milestoneId);
748
+ return !!row && isClosedStatus(row.status);
749
+ });
750
+ for (const entry of stashAudit.applied) {
751
+ ctx.ui.notify(
752
+ `Orphan audit: applied preflight stash ${entry.stashRef} for completed milestone ${entry.milestoneId}. The stash entry is preserved as a backup.`,
753
+ "info",
754
+ );
755
+ }
756
+ for (const msg of stashAudit.warnings) {
757
+ ctx.ui.notify(`Orphan audit: ${msg}`, "warning");
758
+ }
759
+ if (stashAudit.applied.length > 0) {
760
+ debugLog("orphan-stash-audit", {
761
+ applied: stashAudit.applied,
762
+ warnings: stashAudit.warnings,
763
+ });
764
+ }
765
+ }
766
+ } catch (err) {
767
+ logWarning(
768
+ "bootstrap",
769
+ `orphaned preflight-stash audit failed: ${err instanceof Error ? err.message : String(err)}`,
770
+ );
771
+ }
772
+
580
773
  let state = await deriveState(base);
581
774
 
582
775
  // Stale worktree state recovery (#654)
@@ -649,27 +842,56 @@ export async function bootstrapAutoSession(
649
842
  // hasSurvivorBranch after a successful promotion.
650
843
  if (decideSurvivorAction(hasSurvivorBranch, state.phase) === "finalize") {
651
844
  const mid = state.activeMilestone!.id;
652
- ctx.ui.notify(
653
- `Milestone ${mid} is complete but branch/worktree was not finalized. Running merge now.`,
654
- "info",
655
- );
656
- const resolver = buildResolver();
657
- resolver.mergeAndExit(mid, {
658
- notify: ctx.ui.notify.bind(ctx.ui),
659
- });
845
+ // Commit 68ef58a3c made `_mergeBranchMode` throw on wrong-branch
846
+ // instead of returning false silently. Wrap the call so the throw is
847
+ // converted into an error notify + clean bootstrap abort, not an
848
+ // unhandled exception propagating to the slash-command caller (#5549
849
+ // post-merge audit, R2).
850
+ const finalize = _finalizeSurvivorBranch(buildResolver(), mid, ctx.ui);
851
+ if (!finalize.merged) {
852
+ return releaseLockAndReturn();
853
+ }
660
854
  invalidateAllCaches();
661
855
  state = await deriveState(base);
662
856
  // Clear survivor flag — finalization is done
663
857
  hasSurvivorBranch = false;
664
858
  }
665
859
 
860
+ // ── Orphan-completed-milestone merge (#5538-followup) ──
861
+ // A process killed between `complete-milestone` (DB flip + SUMMARY write)
862
+ // and the loop's transition-guard merge strands the milestone branch
863
+ // forever: `s.currentMilestoneId` is in-memory only, so on the next
864
+ // bootstrap the guard at phases.ts:730 sees `mid === s.currentMilestoneId`
865
+ // and short-circuits.
866
+ //
867
+ // The earlier attempt at this fix seeded `s.currentMilestoneId` to the
868
+ // orphan id pre-state-derivation, but the unconditional assignment at
869
+ // line 948 (`s.currentMilestoneId = state.activeMilestone?.id ?? null`)
870
+ // immediately overwrote the seed. Active-merge is the more durable fix:
871
+ // call `mergeAndExit` directly during bootstrap, then re-derive state so
872
+ // the loop's normal flow continues without an in-memory hint.
873
+ //
874
+ // Mirrors the survivor-finalize block above. Failures degrade to a
875
+ // warning notify so a transient git error doesn't block bootstrap.
876
+ {
877
+ const orphan = findUnmergedCompletedMilestone(base, getIsolationMode(base));
878
+ if (orphan && orphan !== state.activeMilestone?.id) {
879
+ const result = _mergeOrphanCompletedMilestone(buildResolver(), orphan, ctx.ui);
880
+ if (result.merged) {
881
+ invalidateAllCaches();
882
+ state = await deriveState(base);
883
+ }
884
+ }
885
+ }
886
+
666
887
  const effectivePrefs = loadEffectiveGSDPreferences(base)?.preferences;
667
- const deepProjectStagePending = !hasSurvivorBranch
668
- ? (await import("./auto-dispatch.js")).hasPendingDeepStage(
669
- effectivePrefs,
670
- base,
671
- )
672
- : false;
888
+ const { shouldRunDeepProjectSetup } = await import("./auto-dispatch.js");
889
+ const deepProjectStagePending = shouldRunDeepProjectSetup(
890
+ state,
891
+ effectivePrefs,
892
+ base,
893
+ { hasSurvivorBranch },
894
+ );
673
895
 
674
896
  if (deepProjectStagePending) {
675
897
  // Deep project-level setup runs before the first milestone exists. Let
@@ -789,7 +1011,7 @@ export async function bootstrapAutoSession(
789
1011
  s.resourceVersionOnStart = readResourceVersion();
790
1012
  s.pendingQuickTasks = [];
791
1013
  s.currentUnit = null;
792
- s.currentMilestoneId = deepProjectStagePending ? null : state.activeMilestone?.id ?? null;
1014
+ s.currentMilestoneId ??= deepProjectStagePending ? null : state.activeMilestone?.id ?? null;
793
1015
  s.originalModelId = startModelSnapshot?.id ?? ctx.model?.id ?? null;
794
1016
  s.originalModelProvider = startModelSnapshot?.provider ?? ctx.model?.provider ?? null;
795
1017
  s.originalThinkingLevel = startThinkingSnapshot ?? null;
@@ -32,6 +32,7 @@ let _currentSigtermHandler: (() => void) | null = null;
32
32
  export function registerSigtermHandler(
33
33
  currentBasePath: string,
34
34
  previousHandler: (() => void) | null,
35
+ onSignalCleanup?: () => void,
35
36
  ): () => void {
36
37
  // Remove the explicitly-passed previous handler
37
38
  if (previousHandler) {
@@ -43,6 +44,12 @@ export function registerSigtermHandler(
43
44
  for (const sig of CLEANUP_SIGNALS) process.off(sig, _currentSigtermHandler);
44
45
  }
45
46
  const handler = () => {
47
+ try {
48
+ onSignalCleanup?.();
49
+ } catch {
50
+ void 0;
51
+ // Signal cleanup is best-effort; lock cleanup and process exit still run.
52
+ }
46
53
  clearLock(currentBasePath);
47
54
  releaseSessionLock(currentBasePath);
48
55
  process.exit(0);
@@ -71,14 +71,14 @@ export async function recoverTimedOutUnit(
71
71
  recovery: status,
72
72
  });
73
73
 
74
- const durableComplete = status.summaryExists && status.taskChecked && status.nextActionAdvanced;
74
+ const durableComplete = status.dbComplete || (status.summaryExists && status.taskChecked && status.nextActionAdvanced);
75
75
  if (durableComplete) {
76
76
  writeUnitRuntimeRecord(basePath, unitType, unitId, currentUnitStartedAt, {
77
77
  phase: "finalized",
78
78
  recovery: status,
79
79
  });
80
80
  ctx.ui.notify(
81
- `${reason === "idle" ? "Idle" : "Timeout"} recovery: ${unitType} ${unitId} already completed on disk. Continuing auto-mode. (attempt ${attemptNumber})`,
81
+ `${reason === "idle" ? "Idle" : "Timeout"} recovery: ${unitType} ${unitId} already completed. Continuing auto-mode. (attempt ${attemptNumber})`,
82
82
  "info",
83
83
  );
84
84
  unitRecoveryCount.delete(recoveryKey);