gsd-pi 2.80.0-dev.96f4d89d5 → 2.80.0-dev.b0acf17e9

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 (667) hide show
  1. package/README.md +4 -2
  2. package/dist/claude-cli-check.d.ts +30 -0
  3. package/dist/claude-cli-check.js +18 -7
  4. package/dist/cli.js +0 -19
  5. package/dist/headless-query.d.ts +10 -0
  6. package/dist/headless-query.js +6 -4
  7. package/dist/loader-entrypoint.d.ts +8 -0
  8. package/dist/loader-entrypoint.js +27 -0
  9. package/dist/loader.js +2 -11
  10. package/dist/mcp-server.d.ts +1 -0
  11. package/dist/mcp-server.js +6 -3
  12. package/dist/resources/.managed-resources-content-hash +1 -1
  13. package/dist/resources/GSD-WORKFLOW.md +2 -2
  14. package/dist/resources/extensions/claude-code-cli/readiness.js +18 -7
  15. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +29 -0
  16. package/dist/resources/extensions/github-sync/sync.js +4 -1
  17. package/dist/resources/extensions/gsd/auto/loop.js +103 -9
  18. package/dist/resources/extensions/gsd/auto/phases.js +240 -139
  19. package/dist/resources/extensions/gsd/auto/resolve.js +29 -0
  20. package/dist/resources/extensions/gsd/auto/run-unit.js +22 -30
  21. package/dist/resources/extensions/gsd/auto/session.js +8 -0
  22. package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
  23. package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
  24. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  25. package/dist/resources/extensions/gsd/auto-dispatch.js +26 -0
  26. package/dist/resources/extensions/gsd/auto-post-unit.js +103 -86
  27. package/dist/resources/extensions/gsd/auto-prompts.js +214 -17
  28. package/dist/resources/extensions/gsd/auto-recovery.js +197 -9
  29. package/dist/resources/extensions/gsd/auto-start.js +240 -15
  30. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  31. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  32. package/dist/resources/extensions/gsd/auto-worktree.js +165 -28
  33. package/dist/resources/extensions/gsd/auto.js +165 -45
  34. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +99 -10
  35. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +50 -37
  36. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +35 -10
  37. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +36 -20
  38. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +10 -1
  39. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +12 -4
  40. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +11 -3
  41. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +1 -1
  42. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +330 -55
  43. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  44. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +129 -1
  45. package/dist/resources/extensions/gsd/clean-root-preflight.js +65 -9
  46. package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
  47. package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
  48. package/dist/resources/extensions/gsd/commands-config.js +1 -1
  49. package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
  50. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  51. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  52. package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
  53. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  54. package/dist/resources/extensions/gsd/db/unit-dispatches.js +92 -0
  55. package/dist/resources/extensions/gsd/db-base-schema.js +18 -2
  56. package/dist/resources/extensions/gsd/db-migration-steps.js +22 -0
  57. package/dist/resources/extensions/gsd/detection.js +106 -0
  58. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  59. package/dist/resources/extensions/gsd/git-service.js +73 -5
  60. package/dist/resources/extensions/gsd/gsd-db.js +146 -13
  61. package/dist/resources/extensions/gsd/guided-flow.js +143 -48
  62. package/dist/resources/extensions/gsd/init-wizard.js +4 -1
  63. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  64. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  65. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  66. package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
  67. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  68. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  69. package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
  70. package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
  71. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  72. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
  73. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  74. package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
  75. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  76. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  77. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  78. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  79. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  80. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  81. package/dist/resources/extensions/gsd/quick.js +34 -2
  82. package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
  83. package/dist/resources/extensions/gsd/slice-cadence.js +45 -2
  84. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +15 -9
  85. package/dist/resources/extensions/gsd/tools/complete-task.js +1 -1
  86. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  87. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  88. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  89. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  90. package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
  91. package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
  92. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  93. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  94. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  95. package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
  96. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  97. package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
  98. package/dist/resources/extensions/gsd/worktree-resolver.js +90 -22
  99. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  100. package/dist/web/standalone/.next/BUILD_ID +1 -1
  101. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  102. package/dist/web/standalone/.next/build-manifest.json +3 -3
  103. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  104. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  105. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  106. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  116. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/index.html +1 -1
  124. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  125. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  126. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  127. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  132. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/middleware.js +3 -3
  135. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  136. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  137. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  138. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +10 -0
  139. package/dist/web/standalone/.next/static/chunks/app/{page-fab3ebb85b006001.js → page-752f1e2ebdaa3e45.js} +1 -1
  140. package/dist/web/standalone/.next/static/chunks/{webpack-0481f1221120a7c6.js → webpack-de742b64187e13fe.js} +1 -1
  141. package/dist/welcome-screen.d.ts +2 -0
  142. package/dist/welcome-screen.js +9 -7
  143. package/package.json +6 -4
  144. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  145. package/packages/mcp-server/dist/workflow-tools.js +22 -17
  146. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  147. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  148. package/packages/mcp-server/src/workflow-tools.ts +30 -16
  149. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  150. package/packages/native/tsconfig.tsbuildinfo +1 -1
  151. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  152. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  153. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  154. package/packages/pi-agent-core/dist/agent.d.ts +5 -0
  155. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  156. package/packages/pi-agent-core/dist/agent.js +2 -0
  157. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  158. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  159. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  160. package/packages/pi-agent-core/dist/index.js +2 -0
  161. package/packages/pi-agent-core/dist/index.js.map +1 -1
  162. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  163. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  164. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  165. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  166. package/packages/pi-agent-core/dist/types.d.ts +9 -0
  167. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  168. package/packages/pi-agent-core/dist/types.js.map +1 -1
  169. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  170. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  171. package/packages/pi-agent-core/src/agent.ts +8 -0
  172. package/packages/pi-agent-core/src/index.ts +2 -0
  173. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  174. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  175. package/packages/pi-agent-core/src/types.ts +14 -0
  176. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  177. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +35 -13
  178. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  179. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +21 -11
  180. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -1
  181. package/packages/pi-ai/dist/providers/anthropic.d.ts +7 -0
  182. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  183. package/packages/pi-ai/dist/providers/anthropic.js +9 -7
  184. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  185. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +23 -14
  186. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -1
  187. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +48 -21
  188. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
  189. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +22 -21
  190. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -1
  191. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +22 -21
  192. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -1
  193. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +39 -25
  194. package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -22
  195. package/packages/pi-ai/src/providers/anthropic.ts +22 -9
  196. package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +34 -21
  197. package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +56 -22
  198. package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +24 -28
  199. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +24 -28
  200. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  201. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
  202. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  203. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +18 -0
  204. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  205. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -0
  206. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  207. package/packages/pi-coding-agent/dist/core/agent-session.js +44 -7
  208. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  209. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +78 -0
  210. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  211. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  212. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  213. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  214. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  215. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  216. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  217. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  218. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  219. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
  220. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
  221. package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
  222. package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
  223. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
  224. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
  225. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
  226. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
  227. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  228. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  229. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  230. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +5 -0
  231. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  232. package/packages/pi-coding-agent/dist/core/extensions/runner.js +20 -7
  233. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  234. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +102 -3
  235. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  236. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +41 -3
  237. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  238. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  239. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  240. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  242. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  243. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  244. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  245. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  246. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  247. package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
  248. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  249. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
  250. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  251. package/packages/pi-coding-agent/dist/core/settings-manager.js +25 -0
  252. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  253. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  254. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  255. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  256. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  257. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  258. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  259. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +22 -56
  260. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -1
  261. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +1 -0
  262. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  263. package/packages/pi-coding-agent/dist/core/tools/bash.js +3 -1
  264. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  265. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts +2 -0
  266. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  267. package/packages/pi-coding-agent/dist/core/tools/edit.js +12 -1
  268. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/tools/find.d.ts +2 -0
  270. package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
  271. package/packages/pi-coding-agent/dist/core/tools/find.js +14 -6
  272. package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts +2 -0
  274. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/tools/grep.js +12 -3
  276. package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts +2 -0
  278. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +3 -1
  280. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -1
  282. package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/tools/index.js +1 -0
  284. package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts +2 -0
  286. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/tools/ls.js +10 -3
  288. package/packages/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -0
  290. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/tools/read.js +3 -1
  292. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +7 -62
  294. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts +2 -0
  296. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts.map +1 -0
  297. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js +115 -0
  298. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js.map +1 -0
  299. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts +19 -0
  300. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts.map +1 -0
  301. package/packages/pi-coding-agent/dist/core/tools/tool-target.js +20 -0
  302. package/packages/pi-coding-agent/dist/core/tools/tool-target.js.map +1 -0
  303. package/packages/pi-coding-agent/dist/core/tools/write.d.ts +4 -0
  304. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  305. package/packages/pi-coding-agent/dist/core/tools/write.js +9 -1
  306. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  307. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
  308. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
  309. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +137 -19
  310. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  311. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +2 -2
  312. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -1
  313. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  314. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  315. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  316. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +2 -1
  317. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  318. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +7 -6
  319. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +18 -0
  321. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  322. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +225 -16
  323. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  324. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  325. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +85 -2
  326. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  327. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +71 -0
  328. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  329. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  330. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +3 -0
  331. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  332. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  333. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
  334. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  335. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +21 -0
  336. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -1
  337. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
  338. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
  339. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +28 -0
  340. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
  341. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  342. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
  343. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  344. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
  345. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
  346. package/packages/pi-coding-agent/src/core/agent-session.ts +48 -7
  347. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +91 -0
  348. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  349. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  350. package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
  351. package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
  352. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  353. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +113 -3
  354. package/packages/pi-coding-agent/src/core/extensions/runner.ts +24 -6
  355. package/packages/pi-coding-agent/src/core/extensions/types.ts +44 -2
  356. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  357. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  358. package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
  359. package/packages/pi-coding-agent/src/core/settings-manager.ts +39 -1
  360. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  361. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  362. package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +22 -66
  363. package/packages/pi-coding-agent/src/core/tools/bash.ts +4 -1
  364. package/packages/pi-coding-agent/src/core/tools/edit.ts +13 -1
  365. package/packages/pi-coding-agent/src/core/tools/find.ts +15 -6
  366. package/packages/pi-coding-agent/src/core/tools/grep.ts +13 -3
  367. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +4 -1
  368. package/packages/pi-coding-agent/src/core/tools/index.ts +8 -0
  369. package/packages/pi-coding-agent/src/core/tools/ls.ts +11 -3
  370. package/packages/pi-coding-agent/src/core/tools/read.ts +4 -1
  371. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +11 -72
  372. package/packages/pi-coding-agent/src/core/tools/tool-target-metadata.test.ts +127 -0
  373. package/packages/pi-coding-agent/src/core/tools/tool-target.ts +48 -0
  374. package/packages/pi-coding-agent/src/core/tools/write.ts +14 -2
  375. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
  376. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +185 -19
  377. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +2 -2
  378. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
  379. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +2 -1
  380. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +10 -9
  381. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +260 -16
  382. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +75 -0
  383. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +107 -3
  384. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +3 -0
  385. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
  386. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +25 -0
  387. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +31 -0
  388. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
  389. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  390. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  391. package/packages/pi-tui/dist/tui.js +18 -8
  392. package/packages/pi-tui/dist/tui.js.map +1 -1
  393. package/packages/pi-tui/src/tui.ts +20 -8
  394. package/packages/pi-tui/tsconfig.tsbuildinfo +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/readiness.ts +25 -7
  400. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +30 -0
  401. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +26 -0
  402. package/src/resources/extensions/github-sync/sync.ts +8 -1
  403. package/src/resources/extensions/github-sync/tests/sync-source.test.ts +6 -18
  404. package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -2
  405. package/src/resources/extensions/gsd/auto/loop.ts +134 -16
  406. package/src/resources/extensions/gsd/auto/phases.ts +328 -200
  407. package/src/resources/extensions/gsd/auto/resolve.ts +42 -1
  408. package/src/resources/extensions/gsd/auto/run-unit.ts +28 -30
  409. package/src/resources/extensions/gsd/auto/session.ts +8 -0
  410. package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
  411. package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
  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 +116 -88
  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 +293 -21
  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 +199 -30
  421. package/src/resources/extensions/gsd/auto.ts +216 -40
  422. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +120 -8
  423. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +51 -37
  424. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +35 -10
  425. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +38 -19
  426. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +11 -1
  427. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +13 -4
  428. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +12 -3
  429. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +1 -1
  430. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +386 -55
  431. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  432. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +135 -1
  433. package/src/resources/extensions/gsd/clean-root-preflight.ts +72 -9
  434. package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
  435. package/src/resources/extensions/gsd/commands/handlers/ops.ts +4 -2
  436. package/src/resources/extensions/gsd/commands-config.ts +1 -1
  437. package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
  438. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  439. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  440. package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
  441. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  442. package/src/resources/extensions/gsd/db/unit-dispatches.ts +107 -0
  443. package/src/resources/extensions/gsd/db-base-schema.ts +19 -2
  444. package/src/resources/extensions/gsd/db-migration-steps.ts +25 -0
  445. package/src/resources/extensions/gsd/detection.ts +128 -0
  446. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  447. package/src/resources/extensions/gsd/git-service.ts +87 -10
  448. package/src/resources/extensions/gsd/gsd-db.ts +168 -13
  449. package/src/resources/extensions/gsd/guided-flow.ts +169 -55
  450. package/src/resources/extensions/gsd/init-wizard.ts +5 -1
  451. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  452. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  453. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  454. package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
  455. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  456. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  457. package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
  458. package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
  459. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  460. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  461. package/src/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
  462. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  463. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  464. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  465. package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  466. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  467. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  468. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  469. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  470. package/src/resources/extensions/gsd/quick.ts +37 -2
  471. package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
  472. package/src/resources/extensions/gsd/slice-cadence.ts +49 -2
  473. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +23 -9
  474. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +59 -89
  475. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +47 -172
  476. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +0 -35
  477. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +35 -9
  478. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +433 -11
  479. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +80 -59
  480. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +3 -47
  481. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +76 -18
  482. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +160 -11
  483. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +54 -95
  484. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +67 -26
  485. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +184 -2
  486. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +32 -30
  487. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +32 -128
  488. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +20 -54
  489. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +20 -30
  490. package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +17 -29
  491. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +138 -0
  492. package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +21 -39
  493. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +15 -24
  494. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +44 -29
  495. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +39 -51
  496. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +159 -213
  497. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +15 -32
  498. package/src/resources/extensions/gsd/tests/browser-teardown.test.ts +0 -41
  499. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +97 -2
  500. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +34 -27
  501. package/src/resources/extensions/gsd/tests/cmux.test.ts +42 -53
  502. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +39 -61
  503. package/src/resources/extensions/gsd/tests/commands-config.test.ts +26 -19
  504. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
  505. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  506. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  507. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  508. package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +29 -33
  509. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +45 -108
  510. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  511. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  512. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +90 -31
  513. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
  514. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +5 -1
  515. package/src/resources/extensions/gsd/tests/cwd-fallback-hardening.test.ts +138 -0
  516. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +4 -68
  517. package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +2 -2
  518. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +4 -9
  519. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +14 -65
  520. package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
  521. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +44 -37
  522. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +58 -40
  523. package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +25 -15
  524. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  525. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +35 -17
  526. package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +16 -21
  527. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +15 -82
  528. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  529. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  530. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
  531. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  532. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
  533. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -20
  534. package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +18 -26
  535. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
  536. package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
  537. package/src/resources/extensions/gsd/tests/init-skip-git.test.ts +9 -12
  538. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +35 -0
  539. package/src/resources/extensions/gsd/tests/integration/git-locale.test.ts +31 -20
  540. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +66 -0
  541. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +0 -47
  542. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +60 -202
  543. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +13 -56
  544. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +239 -1
  545. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  546. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  547. package/src/resources/extensions/gsd/tests/lazy-pi-tui-import.test.ts +44 -6
  548. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  549. package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +21 -35
  550. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
  551. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  552. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  553. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
  554. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +79 -98
  555. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +70 -278
  556. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  557. package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +37 -30
  558. package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +32 -28
  559. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
  560. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
  561. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  562. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  563. package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +24 -37
  564. package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +9 -24
  565. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +91 -75
  566. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
  567. package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
  568. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +36 -22
  569. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +36 -30
  570. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
  571. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +20 -22
  572. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +130 -32
  573. package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +18 -36
  574. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +35 -73
  575. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +76 -138
  576. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  577. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  578. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +70 -106
  579. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +59 -161
  580. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +33 -29
  581. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +22 -196
  582. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +23 -93
  583. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  584. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +50 -79
  585. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +27 -13
  586. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +151 -251
  587. package/src/resources/extensions/gsd/tests/resource-loader-import-path.test.ts +41 -29
  588. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +58 -69
  589. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +32 -164
  590. package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
  591. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +57 -41
  592. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
  593. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  594. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  595. package/src/resources/extensions/gsd/tests/session-model-override.test.ts +14 -9
  596. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
  597. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +166 -0
  598. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +44 -42
  599. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  600. package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +56 -24
  601. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +51 -11
  602. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +23 -0
  603. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +66 -50
  604. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +68 -107
  605. package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +115 -42
  606. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +21 -59
  607. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +25 -116
  608. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +21 -57
  609. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +29 -76
  610. package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +33 -24
  611. package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +39 -30
  612. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  613. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +101 -2
  614. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
  615. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +35 -40
  616. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +36 -45
  617. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +14 -102
  618. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +78 -232
  619. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +32 -35
  620. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  621. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  622. package/src/resources/extensions/gsd/tests/token-profile.test.ts +84 -309
  623. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
  624. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +134 -341
  625. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
  626. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +8 -25
  627. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +80 -1
  628. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
  629. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -99
  630. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +43 -36
  631. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -444
  632. package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
  633. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +44 -189
  634. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -57
  635. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  636. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  637. package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
  638. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +21 -44
  639. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +27 -26
  640. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +38 -6
  641. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
  642. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -18
  643. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
  644. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
  645. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  646. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  647. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +203 -4
  648. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +179 -0
  649. package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -13
  650. package/src/resources/extensions/gsd/tools/complete-task.ts +1 -1
  651. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  652. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  653. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  654. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  655. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
  656. package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
  657. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  658. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  659. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  660. package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
  661. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  662. package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
  663. package/src/resources/extensions/gsd/worktree-resolver.ts +119 -20
  664. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +86 -40
  665. package/dist/web/standalone/.next/static/chunks/8336.631939fb583761fa.js +0 -10
  666. /package/dist/web/standalone/.next/static/{y7d--cnc6Cibuva-Lzzw_ → naNyn5ToUBzCQtuLbEYXC}/_buildManifest.js +0 -0
  667. /package/dist/web/standalone/.next/static/{y7d--cnc6Cibuva-Lzzw_ → naNyn5ToUBzCQtuLbEYXC}/_ssgManifest.js +0 -0
@@ -1,3 +1,5 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Auto-mode bootstrap, worktree recovery, and fresh-start initialization.
1
3
  /**
2
4
  * Auto-mode bootstrap — fresh-start initialization path.
3
5
  *
@@ -34,6 +36,7 @@ import { snapshotSkills } from "./skill-discovery.js";
34
36
  import { isDbAvailable, getMilestone, openDatabase, getDbStatus } from "./gsd-db.js";
35
37
  import { isClosedStatus } from "./status-guards.js";
36
38
  import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
39
+ import { auditOrphanedPreflightStashes } from "./orphan-stash-audit.js";
37
40
  import { debugLog, enableDebug, isDebugEnabled, getDebugLogPath, } from "./debug-logger.js";
38
41
  import { logWarning, logError } from "./workflow-logger.js";
39
42
  import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, } from "node:fs";
@@ -43,6 +46,11 @@ import { resolveProjectRootDbPath } from "./bootstrap/dynamic-tools.js";
43
46
  import { validateDirectory } from "./validate-directory.js";
44
47
  import { isCustomProvider, resolveDefaultSessionModel, resolveDynamicRoutingConfig, } from "./preferences-models.js";
45
48
  import { getSessionModelOverride } from "./session-model-override.js";
49
+ export function resolveIsolationNoneBranchCheckout(currentBranch, integrationBranch, isolationMode, isRepo) {
50
+ if (!isRepo || isolationMode !== "none")
51
+ return null;
52
+ return currentBranch.startsWith("milestone/") ? integrationBranch : null;
53
+ }
46
54
  /**
47
55
  * Bootstrap a fresh auto-mode session. Handles everything from git init
48
56
  * through secrets collection, returning when ready for the first
@@ -54,6 +62,12 @@ import { getSessionModelOverride } from "./session-model-override.js";
54
62
  // Guard constant for consecutive bootstrap attempts that found phase === "complete".
55
63
  // Counter moved to AutoSession.consecutiveCompleteBootstraps so s.reset() clears it.
56
64
  const MAX_CONSECUTIVE_COMPLETE_BOOTSTRAPS = 2;
65
+ export function hasGitIndexLockForTest(basePath) {
66
+ return existsSync(join(basePath, ".git", "index.lock"));
67
+ }
68
+ export function _shouldAbortBootstrapForUnavailableDbForTest(gsdDbPath, dbAvailable, pathExists = existsSync) {
69
+ return pathExists(gsdDbPath) && !dbAvailable;
70
+ }
57
71
  export async function openProjectDbIfPresent(basePath) {
58
72
  const gsdDbPath = resolveProjectRootDbPath(basePath);
59
73
  if (!existsSync(gsdDbPath) || isDbAvailable())
@@ -224,6 +238,139 @@ export function auditOrphanedMilestoneBranches(basePath, isolationMode) {
224
238
  }
225
239
  return { recovered, warnings };
226
240
  }
241
+ /**
242
+ * Pure decision function for picking which orphan milestone the auto-loop
243
+ * should resume the merge transition for. Extracted so it can be unit-tested
244
+ * without spinning up a git repo or a SQLite DB.
245
+ *
246
+ * Returns the lexicographically-greatest milestone id (e.g. "M002" beats
247
+ * "M001") whose branch is unmerged AND has commits ahead of main AND whose
248
+ * status is `complete`. Lex-ordering matches the project's M00x convention,
249
+ * which is the most-recently-completed milestone in practice.
250
+ * `isComplete` errors propagate; `commitsAhead` errors are treated as 0.
251
+ */
252
+ export function _selectResumableMilestone(branchNames, mergedBranches, isComplete, commitsAhead) {
253
+ const candidates = [];
254
+ for (const branch of branchNames) {
255
+ if (!branch.startsWith("milestone/"))
256
+ continue;
257
+ const milestoneId = branch.slice("milestone/".length);
258
+ if (mergedBranches.has(branch))
259
+ continue;
260
+ if (!isComplete(milestoneId))
261
+ continue;
262
+ let ahead = 0;
263
+ try {
264
+ ahead = commitsAhead(branch);
265
+ }
266
+ catch {
267
+ continue;
268
+ }
269
+ if (ahead <= 0)
270
+ continue;
271
+ candidates.push(milestoneId);
272
+ }
273
+ if (candidates.length === 0)
274
+ return null;
275
+ candidates.sort();
276
+ return candidates[candidates.length - 1];
277
+ }
278
+ /**
279
+ * Find the most-recent completed milestone whose branch still has unmerged
280
+ * commits ahead of the integration branch. Used by `bootstrapAutoSession`
281
+ * to seed `s.currentMilestoneId` so the auto-loop's transition guard at
282
+ * `phases.ts:730` fires on the first iteration after a process restart —
283
+ * without this, the in-memory-only `s.currentMilestoneId` is `null` after
284
+ * restart, the guard short-circuits, and the orphaned milestone branch
285
+ * never gets merged into main (#5538-followup).
286
+ *
287
+ * Returns null when isolation is `none`, the DB is unavailable, or no
288
+ * orphan candidate exists. All git failures degrade silently — startup
289
+ * must never block on this defensive lookup.
290
+ */
291
+ export function findUnmergedCompletedMilestone(basePath, isolationMode) {
292
+ if (isolationMode === "none")
293
+ return null;
294
+ if (!isDbAvailable())
295
+ return null;
296
+ let milestoneBranches;
297
+ try {
298
+ milestoneBranches = nativeBranchList(basePath, "milestone/*");
299
+ }
300
+ catch {
301
+ return null;
302
+ }
303
+ if (milestoneBranches.length === 0)
304
+ return null;
305
+ let mainBranch;
306
+ try {
307
+ mainBranch = nativeDetectMainBranch(basePath);
308
+ }
309
+ catch {
310
+ mainBranch = "main";
311
+ }
312
+ let mergedBranches;
313
+ try {
314
+ mergedBranches = new Set(nativeBranchListMerged(basePath, mainBranch, "milestone/*"));
315
+ }
316
+ catch {
317
+ mergedBranches = new Set();
318
+ }
319
+ return _selectResumableMilestone(milestoneBranches, mergedBranches, (milestoneId) => {
320
+ const row = getMilestone(milestoneId);
321
+ return !!row && row.status === "complete";
322
+ }, (branch) => nativeCommitCountBetween(basePath, mainBranch, branch));
323
+ }
324
+ /**
325
+ * Run `mergeAndExit` for a milestone whose worktree/branch finalization
326
+ * never completed in a prior session — the active-milestone in phase
327
+ * `complete` with a survivor `milestone/<id>` branch still around.
328
+ *
329
+ * Wraps the call in try/catch so a thrown error from `_mergeBranchMode`
330
+ * (made fail-loud in commit 68ef58a3c) is converted into a user-facing
331
+ * error notify instead of an unhandled exception that propagates through
332
+ * `bootstrapAutoSession` to the slash-command caller's `.catch` block.
333
+ *
334
+ * Returns `{ merged: true }` on success; `{ merged: false, error }` on
335
+ * throw — caller decides whether to abort bootstrap.
336
+ */
337
+ export function _finalizeSurvivorBranch(resolver, milestoneId, ui) {
338
+ ui.notify(`Milestone ${milestoneId} is complete but branch/worktree was not finalized. Running merge now.`, "info");
339
+ try {
340
+ resolver.mergeAndExit(milestoneId, { notify: ui.notify.bind(ui) });
341
+ return { merged: true };
342
+ }
343
+ catch (err) {
344
+ const msg = err instanceof Error ? err.message : String(err);
345
+ ui.notify(`Survivor-branch finalization for ${milestoneId} failed: ${msg}. Resolve manually and re-run /gsd auto.`, "error");
346
+ return { merged: false, error: err };
347
+ }
348
+ }
349
+ /**
350
+ * Merge a milestone whose DB row is `complete` but whose branch is still
351
+ * unmerged into the integration branch. Called from `bootstrapAutoSession`
352
+ * for orphans surfaced by `findUnmergedCompletedMilestone`.
353
+ *
354
+ * Notifies the user before and after, swallowing errors so a transient git
355
+ * failure never blocks bootstrap. Returns `{ merged: true }` when the
356
+ * underlying `mergeAndExit` completes; `{ merged: false, error }` on throw.
357
+ *
358
+ * Extracted to keep `bootstrapAutoSession` testable: the merge call and the
359
+ * notify shape are exercised against a mock resolver in
360
+ * `tests/orphan-merge-bootstrap.test.ts`.
361
+ */
362
+ export function _mergeOrphanCompletedMilestone(resolver, orphanId, ui) {
363
+ ui.notify(`Detected unmerged completed milestone ${orphanId}. Merging now.`, "info");
364
+ try {
365
+ resolver.mergeAndExit(orphanId, { notify: ui.notify.bind(ui) });
366
+ return { merged: true };
367
+ }
368
+ catch (err) {
369
+ const msg = err instanceof Error ? err.message : String(err);
370
+ ui.notify(`Could not merge orphan milestone ${orphanId}: ${msg}. Resolve manually and re-run /gsd auto.`, "warning");
371
+ return { merged: false, error: err };
372
+ }
373
+ }
227
374
  export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, requestedStepMode, deps, interrupted) {
228
375
  const { shouldUseWorktreeIsolation, registerSigtermHandler, lockBase, buildResolver, } = deps;
229
376
  const dirCheck = validateDirectory(base);
@@ -420,6 +567,33 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
420
567
  // Non-fatal — the audit is defensive, never block bootstrap
421
568
  logWarning("bootstrap", `orphaned milestone branch audit failed: ${err instanceof Error ? err.message : String(err)}`);
422
569
  }
570
+ // ── Orphaned preflight-stash audit (#5538-followup) ──
571
+ // Reapplies pre-merge stashes whose milestone is now complete but whose
572
+ // postflight pop was skipped by an interrupted merge in a prior session.
573
+ // Uses `git stash apply` (not pop) so the entry remains as a backup.
574
+ try {
575
+ if (isDbAvailable()) {
576
+ const stashAudit = auditOrphanedPreflightStashes(base, (milestoneId) => {
577
+ const row = getMilestone(milestoneId);
578
+ return !!row && isClosedStatus(row.status);
579
+ });
580
+ for (const entry of stashAudit.applied) {
581
+ ctx.ui.notify(`Orphan audit: applied preflight stash ${entry.stashRef} for completed milestone ${entry.milestoneId}. The stash entry is preserved as a backup.`, "info");
582
+ }
583
+ for (const msg of stashAudit.warnings) {
584
+ ctx.ui.notify(`Orphan audit: ${msg}`, "warning");
585
+ }
586
+ if (stashAudit.applied.length > 0) {
587
+ debugLog("orphan-stash-audit", {
588
+ applied: stashAudit.applied,
589
+ warnings: stashAudit.warnings,
590
+ });
591
+ }
592
+ }
593
+ }
594
+ catch (err) {
595
+ logWarning("bootstrap", `orphaned preflight-stash audit failed: ${err instanceof Error ? err.message : String(err)}`);
596
+ }
423
597
  let state = await deriveState(base);
424
598
  // Stale worktree state recovery (#654)
425
599
  if (state.activeMilestone &&
@@ -476,20 +650,68 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
476
650
  // hasSurvivorBranch after a successful promotion.
477
651
  if (decideSurvivorAction(hasSurvivorBranch, state.phase) === "finalize") {
478
652
  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
- });
653
+ // Commit 68ef58a3c made `_mergeBranchMode` throw on wrong-branch
654
+ // instead of returning false silently. Wrap the call so the throw is
655
+ // converted into an error notify + clean bootstrap abort, not an
656
+ // unhandled exception propagating to the slash-command caller (#5549
657
+ // post-merge audit, R2).
658
+ const finalize = _finalizeSurvivorBranch(buildResolver(), mid, ctx.ui);
659
+ if (!finalize.merged) {
660
+ return releaseLockAndReturn();
661
+ }
484
662
  invalidateAllCaches();
485
663
  state = await deriveState(base);
486
664
  // Clear survivor flag — finalization is done
487
665
  hasSurvivorBranch = false;
488
666
  }
667
+ // ── Orphan-completed-milestone merge (#5538-followup) ──
668
+ // A process killed between `complete-milestone` (DB flip + SUMMARY write)
669
+ // and the loop's transition-guard merge strands the milestone branch
670
+ // forever: `s.currentMilestoneId` is in-memory only, so on the next
671
+ // bootstrap the guard at phases.ts:730 sees `mid === s.currentMilestoneId`
672
+ // and short-circuits.
673
+ //
674
+ // The earlier attempt at this fix seeded `s.currentMilestoneId` to the
675
+ // orphan id pre-state-derivation, but the unconditional assignment at
676
+ // line 948 (`s.currentMilestoneId = state.activeMilestone?.id ?? null`)
677
+ // immediately overwrote the seed. Active-merge is the more durable fix:
678
+ // call `mergeAndExit` directly during bootstrap, then re-derive state so
679
+ // the loop's normal flow continues without an in-memory hint.
680
+ //
681
+ // Mirrors the survivor-finalize block above. Failures degrade to a
682
+ // warning notify so a transient git error doesn't block bootstrap.
683
+ {
684
+ const orphan = findUnmergedCompletedMilestone(base, getIsolationMode(base));
685
+ if (orphan && orphan !== state.activeMilestone?.id) {
686
+ const priorBasePath = s.basePath;
687
+ const priorOriginalBasePath = s.originalBasePath;
688
+ s.originalBasePath = base;
689
+ s.basePath = getAutoWorktreePath(base, orphan) ?? base;
690
+ const result = _mergeOrphanCompletedMilestone(buildResolver(), orphan, ctx.ui);
691
+ if (!result.merged) {
692
+ s.basePath = base;
693
+ s.originalBasePath = base;
694
+ try {
695
+ process.chdir(base);
696
+ }
697
+ catch (err) {
698
+ logWarning("bootstrap", `could not restore cwd after orphan merge failure: ${err instanceof Error ? err.message : String(err)}`);
699
+ }
700
+ return releaseLockAndReturn();
701
+ }
702
+ if (!s.active) {
703
+ s.basePath = priorBasePath || base;
704
+ s.originalBasePath = priorOriginalBasePath || base;
705
+ }
706
+ if (result.merged) {
707
+ invalidateAllCaches();
708
+ state = await deriveState(base);
709
+ }
710
+ }
711
+ }
489
712
  const effectivePrefs = loadEffectiveGSDPreferences(base)?.preferences;
490
- const deepProjectStagePending = !hasSurvivorBranch
491
- ? (await import("./auto-dispatch.js")).hasPendingDeepStage(effectivePrefs, base)
492
- : false;
713
+ const { shouldRunDeepProjectSetup } = await import("./auto-dispatch.js");
714
+ const deepProjectStagePending = shouldRunDeepProjectSetup(state, effectivePrefs, base, { hasSurvivorBranch });
493
715
  if (deepProjectStagePending) {
494
716
  // Deep project-level setup runs before the first milestone exists. Let
495
717
  // the auto loop dispatch workflow-preferences / project / requirements
@@ -591,7 +813,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
591
813
  s.resourceVersionOnStart = readResourceVersion();
592
814
  s.pendingQuickTasks = [];
593
815
  s.currentUnit = null;
594
- s.currentMilestoneId = deepProjectStagePending ? null : state.activeMilestone?.id ?? null;
816
+ s.currentMilestoneId ??= deepProjectStagePending ? null : state.activeMilestone?.id ?? null;
595
817
  s.originalModelId = startModelSnapshot?.id ?? ctx.model?.id ?? null;
596
818
  s.originalModelProvider = startModelSnapshot?.provider ?? ctx.model?.provider ?? null;
597
819
  s.originalThinkingLevel = startThinkingSnapshot ?? null;
@@ -607,13 +829,16 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
607
829
  // Guard against stale milestone branch when isolation:none (#3613).
608
830
  // A prior session with isolation:branch/worktree may have left HEAD on
609
831
  // milestone/<MID>. Auto-checkout back to the integration branch.
610
- if (getIsolationMode(base) === "none" && nativeIsRepo(base)) {
832
+ const isolationMode = getIsolationMode(base);
833
+ const isRepo = nativeIsRepo(base);
834
+ if (isolationMode === "none" && isRepo) {
611
835
  try {
612
836
  const currentBranch = nativeGetCurrentBranch(base);
613
- if (currentBranch.startsWith("milestone/")) {
614
- const integrationBranch = nativeDetectMainBranch(base);
615
- nativeCheckoutBranch(base, integrationBranch);
616
- logWarning("bootstrap", `Returned to "${integrationBranch}" — HEAD was on stale milestone branch "${currentBranch}" (isolation: none does not use milestone branches).`);
837
+ const integrationBranch = nativeDetectMainBranch(base);
838
+ const branchToCheckout = resolveIsolationNoneBranchCheckout(currentBranch, integrationBranch, isolationMode, isRepo);
839
+ if (branchToCheckout) {
840
+ nativeCheckoutBranch(base, branchToCheckout);
841
+ logWarning("bootstrap", `Returned to "${branchToCheckout}" — HEAD was on stale milestone branch "${currentBranch}" (isolation: none does not use milestone branches).`);
617
842
  }
618
843
  }
619
844
  catch (err) {
@@ -658,7 +883,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
658
883
  logError("engine", `failed to initialize project database: ${err.message}`);
659
884
  }
660
885
  }
661
- if (existsSync(gsdDbPath) && !isDbAvailable()) {
886
+ if (_shouldAbortBootstrapForUnavailableDbForTest(gsdDbPath, isDbAvailable())) {
662
887
  try {
663
888
  const { openDatabase: openDb } = await import("./gsd-db.js");
664
889
  openDb(gsdDbPath);
@@ -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";
@@ -10,7 +10,7 @@
10
10
  import { existsSync, cpSync, readFileSync, readdirSync, mkdirSync, realpathSync, rmSync, unlinkSync, statSync, lstatSync as lstatSyncFn, } from "node:fs";
11
11
  import { isAbsolute, join, relative, sep as pathSep } from "node:path";
12
12
  import { GSDError, GSD_IO_ERROR, GSD_GIT_ERROR } from "./errors.js";
13
- import { reconcileWorktreeDb, isDbAvailable, getMilestone, getMilestoneSlices, closeDatabase, openDatabase, getDbPath, } from "./gsd-db.js";
13
+ import { reconcileWorktreeDb, isDbAvailable, getMilestone, getMilestoneSlices, getSliceTasks, closeDatabase, openDatabase, getDbPath, } from "./gsd-db.js";
14
14
  import { execFileSync } from "node:child_process";
15
15
  import { safeCopy, safeCopyRecursive } from "./safe-fs.js";
16
16
  import { gsdRoot, resolveGsdPathContract } from "./paths.js";
@@ -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";
@@ -135,6 +135,35 @@ function isSamePath(a, b) {
135
135
  return false;
136
136
  }
137
137
  }
138
+ export function _isSamePathForTest(a, b) {
139
+ return isSamePath(a, b);
140
+ }
141
+ export function _resolveAutoWorktreeStartPointForTest(integrationBranch, gitMainBranch, branchExists) {
142
+ if (integrationBranch)
143
+ return integrationBranch;
144
+ return gitMainBranch &&
145
+ typeof gitMainBranch === "string" &&
146
+ gitMainBranch.length > 0 &&
147
+ branchExists(gitMainBranch)
148
+ ? gitMainBranch
149
+ : undefined;
150
+ }
151
+ export function _shouldReconcileWorktreeDbForTest(worktreeDbPath, mainDbPath, pathExists = existsSync, samePath = isSamePath) {
152
+ return pathExists(worktreeDbPath) && !samePath(worktreeDbPath, mainDbPath);
153
+ }
154
+ export function _isExpectedWorktreeUnlinkErrorForTest(code) {
155
+ return code === "ENOENT" || code === "EISDIR";
156
+ }
157
+ function stripGsdDisplayPrefix(value, id) {
158
+ const raw = String(value ?? "").trim();
159
+ if (!raw)
160
+ return undefined;
161
+ const lower = raw.toLowerCase();
162
+ const idLower = id.toLowerCase();
163
+ if (lower.startsWith(`${idLower}:`))
164
+ return raw.slice(id.length + 1).trim() || undefined;
165
+ return raw;
166
+ }
138
167
  // ─── ASSESSMENT Force-Sync Helper (#2821) ─────────────────────────────────
139
168
  /** Regex matching YAML frontmatter `verdict:` field. */
140
169
  const VERDICT_RE = /verdict:\s*[\w-]+/i;
@@ -288,7 +317,7 @@ function clearProjectRootStateFiles(basePath, milestoneId) {
288
317
  catch (err) {
289
318
  // ENOENT/EISDIR are expected for already-removed or directory entries (#3597)
290
319
  const code = err.code;
291
- if (code !== "ENOENT" && code !== "EISDIR") {
320
+ if (!_isExpectedWorktreeUnlinkErrorForTest(code)) {
292
321
  logWarning("worktree", `untracked file unlink failed: ${err instanceof Error ? err.message : String(err)}`);
293
322
  }
294
323
  }
@@ -945,17 +974,7 @@ export function enterBranchModeForMilestone(basePath, milestoneId) {
945
974
  // Create the milestone branch from the integration branch start-point.
946
975
  const integrationBranch = readIntegrationBranch(basePath, milestoneId) ?? undefined;
947
976
  const gitPrefs = loadEffectiveGSDPreferences()?.preferences?.git;
948
- // Validate main_branch preference exists in the repo before using it —
949
- // a stale preference (e.g. "master" when repo uses "main") would cause
950
- // nativeBranchForceReset to fail with a bad start-point reference.
951
- const validatedPrefBranch = gitPrefs?.main_branch &&
952
- typeof gitPrefs.main_branch === "string" &&
953
- gitPrefs.main_branch.length > 0 &&
954
- nativeBranchExists(basePath, gitPrefs.main_branch)
955
- ? gitPrefs.main_branch
956
- : undefined;
957
- const startPoint = integrationBranch ??
958
- validatedPrefBranch ??
977
+ const startPoint = _resolveAutoWorktreeStartPointForTest(integrationBranch, gitPrefs?.main_branch, (branchName) => nativeBranchExists(basePath, branchName)) ??
959
978
  nativeDetectMainBranch(basePath);
960
979
  // TOCTOU ancestry guard (Issue #4980 HIGH-3).
961
980
  //
@@ -1018,6 +1037,111 @@ export function enterBranchModeForMilestone(basePath, milestoneId) {
1018
1037
  * for both reads and writes. copyPlanningArtifacts and reconcilePlanCheckboxes
1019
1038
  * (both formerly here) became dead.
1020
1039
  */
1040
+ /**
1041
+ * True when `branch` is checked out in any worktree listed by
1042
+ * `git worktree list --porcelain`. Used to gate ref updates that would
1043
+ * otherwise leave a concurrent worktree's HEAD inconsistent with its
1044
+ * index/working tree (Codex peer-review of #5538-followup).
1045
+ *
1046
+ * Best-effort: a `nativeWorktreeList` failure returns true so we err on
1047
+ * the side of NOT moving the ref. Better to skip a fast-forward than to
1048
+ * silently corrupt another worktree.
1049
+ */
1050
+ export function _isBranchCheckedOutElsewhere(basePath, branch) {
1051
+ try {
1052
+ const entries = nativeWorktreeList(basePath);
1053
+ return entries.some((entry) => entry.branch === branch);
1054
+ }
1055
+ catch {
1056
+ return true;
1057
+ }
1058
+ }
1059
+ /**
1060
+ * Resolve the integration branch using the same 3-tier fallback as the
1061
+ * fresh-create path: META.json → git.main_branch preference → detected
1062
+ * main branch. Returns null when no usable target exists.
1063
+ */
1064
+ function _resolveIntegrationBranchForReuse(basePath, milestoneId) {
1065
+ const fromMeta = readIntegrationBranch(basePath, milestoneId);
1066
+ if (fromMeta)
1067
+ return fromMeta;
1068
+ const gitPrefs = loadEffectiveGSDPreferences()?.preferences?.git;
1069
+ const fromPref = gitPrefs?.main_branch &&
1070
+ typeof gitPrefs.main_branch === "string" &&
1071
+ gitPrefs.main_branch.length > 0 &&
1072
+ nativeBranchExists(basePath, gitPrefs.main_branch)
1073
+ ? gitPrefs.main_branch
1074
+ : null;
1075
+ if (fromPref)
1076
+ return fromPref;
1077
+ try {
1078
+ return nativeDetectMainBranch(basePath);
1079
+ }
1080
+ catch {
1081
+ return null;
1082
+ }
1083
+ }
1084
+ /**
1085
+ * When reusing an existing milestone branch, fast-forward it onto the
1086
+ * integration branch when that's safe (branch is a strict ancestor of
1087
+ * integration — no commits would be lost). Skips when the branch has its
1088
+ * own commits ahead of integration, when the integration branch can't be
1089
+ * resolved, or when any git operation fails — the merge gate at milestone
1090
+ * completion will surface real divergence as a conflict.
1091
+ *
1092
+ * The previous behavior re-attached the worktree to whatever stale tip
1093
+ * the branch held, which caused new milestone work to fork from a base
1094
+ * missing prior milestones' merges (#5538-followup).
1095
+ */
1096
+ export function fastForwardReusedMilestoneBranchIfSafe(basePath, milestoneId, branch) {
1097
+ try {
1098
+ const integrationBranch = _resolveIntegrationBranchForReuse(basePath, milestoneId);
1099
+ if (!integrationBranch || integrationBranch === branch)
1100
+ return;
1101
+ if (!nativeBranchExists(basePath, integrationBranch))
1102
+ return;
1103
+ // Pure fast-forward only: branch must be a strict ancestor of integration.
1104
+ // If the branch has its own commits ahead, leave it alone.
1105
+ if (!nativeIsAncestor(basePath, branch, integrationBranch)) {
1106
+ debugLog("createAutoWorktree", {
1107
+ phase: "skip-ff-branch-not-ancestor",
1108
+ milestoneId,
1109
+ branch,
1110
+ integration: integrationBranch,
1111
+ });
1112
+ return;
1113
+ }
1114
+ // Codex peer-review: `nativeUpdateRef` succeeds even when the branch is
1115
+ // currently checked out in another worktree, leaving that worktree's HEAD
1116
+ // inconsistent with its index/work tree. Skip the fast-forward if any
1117
+ // listed worktree has this branch checked out — the merge gate at
1118
+ // milestone-completion will surface stale-base divergence as a conflict
1119
+ // instead of silently corrupting the other worktree's state.
1120
+ if (_isBranchCheckedOutElsewhere(basePath, branch)) {
1121
+ debugLog("createAutoWorktree", {
1122
+ phase: "skip-ff-branch-checked-out-elsewhere",
1123
+ milestoneId,
1124
+ branch,
1125
+ });
1126
+ return;
1127
+ }
1128
+ nativeUpdateRef(basePath, `refs/heads/${branch}`, integrationBranch);
1129
+ debugLog("createAutoWorktree", {
1130
+ phase: "fast-forward-reused-branch",
1131
+ milestoneId,
1132
+ branch,
1133
+ integration: integrationBranch,
1134
+ });
1135
+ }
1136
+ catch (err) {
1137
+ debugLog("createAutoWorktree", {
1138
+ phase: "fast-forward-reused-branch-failed",
1139
+ milestoneId,
1140
+ branch,
1141
+ error: err instanceof Error ? err.message : String(err),
1142
+ });
1143
+ }
1144
+ }
1021
1145
  export function createAutoWorktree(basePath, milestoneId) {
1022
1146
  basePath = resolveWorktreeProjectRoot(basePath);
1023
1147
  // Check if repo has commits — git worktree requires a valid HEAD
@@ -1035,6 +1159,11 @@ export function createAutoWorktree(basePath, milestoneId) {
1035
1159
  const branchExists = nativeBranchExists(basePath, branch);
1036
1160
  let info;
1037
1161
  if (branchExists) {
1162
+ // #5538-followup: fast-forward the reused branch onto the integration
1163
+ // branch when safe so the next milestone forks from up-to-date code.
1164
+ // Without this, a milestone that was created before another milestone
1165
+ // merged into main would carry a stale base into its worktree.
1166
+ fastForwardReusedMilestoneBranchIfSafe(basePath, milestoneId, branch);
1038
1167
  // Re-attach worktree to the existing milestone branch (preserving commits)
1039
1168
  info = createWorktree(basePath, milestoneId, {
1040
1169
  branch,
@@ -1051,13 +1180,7 @@ export function createAutoWorktree(basePath, milestoneId) {
1051
1180
  // would fork worktrees from the wrong (stale) branch.
1052
1181
  const integrationBranch = readIntegrationBranch(basePath, milestoneId) ?? undefined;
1053
1182
  const gitPrefs = loadEffectiveGSDPreferences()?.preferences?.git;
1054
- const validatedPrefBranch = gitPrefs?.main_branch &&
1055
- typeof gitPrefs.main_branch === "string" &&
1056
- gitPrefs.main_branch.length > 0 &&
1057
- nativeBranchExists(basePath, gitPrefs.main_branch)
1058
- ? gitPrefs.main_branch
1059
- : undefined;
1060
- const startPoint = integrationBranch ?? validatedPrefBranch ?? undefined;
1183
+ const startPoint = _resolveAutoWorktreeStartPointForTest(integrationBranch, gitPrefs?.main_branch, (branchName) => nativeBranchExists(basePath, branchName));
1061
1184
  info = createWorktree(basePath, milestoneId, {
1062
1185
  branch,
1063
1186
  startPoint,
@@ -1134,7 +1257,7 @@ export function teardownAutoWorktree(originalBasePath, milestoneId, opts = {}) {
1134
1257
  const contract = resolveGsdPathContract(previousCwd, originalBasePath);
1135
1258
  const worktreeDbPath = join(contract.worktreeGsd ?? join(previousCwd, ".gsd"), "gsd.db");
1136
1259
  const mainDbPath = contract.projectDb;
1137
- if (existsSync(worktreeDbPath) && !isSamePath(worktreeDbPath, mainDbPath)) {
1260
+ if (_shouldReconcileWorktreeDbForTest(worktreeDbPath, mainDbPath)) {
1138
1261
  reconcileWorktreeDb(mainDbPath, worktreeDbPath);
1139
1262
  }
1140
1263
  }
@@ -1384,7 +1507,7 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1384
1507
  const contract = resolveGsdPathContract(worktreeCwd, originalBasePath_);
1385
1508
  const worktreeDbPath = join(contract.worktreeGsd ?? join(worktreeCwd, ".gsd"), "gsd.db");
1386
1509
  const mainDbPath = contract.projectDb;
1387
- if (existsSync(worktreeDbPath) && !isSamePath(worktreeDbPath, mainDbPath)) {
1510
+ if (_shouldReconcileWorktreeDbForTest(worktreeDbPath, mainDbPath)) {
1388
1511
  reconcileWorktreeDb(mainDbPath, worktreeDbPath);
1389
1512
  }
1390
1513
  }
@@ -1398,14 +1521,21 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1398
1521
  if (isDbAvailable()) {
1399
1522
  completedSlices = getMilestoneSlices(milestoneId)
1400
1523
  .filter(s => s.status === "complete")
1401
- .map(s => ({ id: s.id, title: s.title }));
1524
+ .map(s => ({
1525
+ id: s.id,
1526
+ title: stripGsdDisplayPrefix(s.title, s.id) ?? s.id,
1527
+ tasks: getSliceTasks(milestoneId, s.id).map((task) => ({
1528
+ id: task.id,
1529
+ title: stripGsdDisplayPrefix(task.title, task.id) ?? task.id,
1530
+ })),
1531
+ }));
1402
1532
  }
1403
1533
  // Fallback: parse roadmap content when DB is unavailable
1404
1534
  if (completedSlices.length === 0 && roadmapContent) {
1405
1535
  const sliceRe = /- \[x\] \*\*(\w+):\s*(.+?)\*\*/gi;
1406
1536
  let m;
1407
1537
  while ((m = sliceRe.exec(roadmapContent)) !== null) {
1408
- completedSlices.push({ id: m[1], title: m[2] });
1538
+ completedSlices.push({ id: m[1], title: m[2], tasks: [] });
1409
1539
  }
1410
1540
  }
1411
1541
  // 3. chdir to original base
@@ -1462,7 +1592,7 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1462
1592
  }
1463
1593
  // 6. Build rich commit message
1464
1594
  const dbMilestone = getMilestone(milestoneId);
1465
- let milestoneTitle = (dbMilestone?.title ?? "").replace(/^M\d+:\s*/, "").trim();
1595
+ let milestoneTitle = stripGsdDisplayPrefix(dbMilestone?.title, milestoneId) ?? "";
1466
1596
  // Fallback: parse title from roadmap content header (e.g. "# M020: Backend foundation")
1467
1597
  if (!milestoneTitle && roadmapContent) {
1468
1598
  const titleMatch = roadmapContent.match(new RegExp(`^#\\s+${milestoneId}:\\s*(.+)`, "m"));
@@ -1471,15 +1601,22 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1471
1601
  }
1472
1602
  milestoneTitle = milestoneTitle || milestoneId;
1473
1603
  const subject = `feat: ${milestoneTitle}`;
1604
+ const milestoneContext = milestoneTitle === milestoneId
1605
+ ? `Milestone: ${milestoneId}`
1606
+ : `Milestone: ${milestoneId} - ${milestoneTitle}`;
1474
1607
  let body = "";
1475
1608
  if (completedSlices.length > 0) {
1476
1609
  const sliceLines = completedSlices
1477
1610
  .map((s) => `- ${s.id}: ${s.title}`)
1478
1611
  .join("\n");
1479
- body = `\n\nCompleted slices:\n${sliceLines}\n\nGSD-Milestone: ${milestoneId}\nBranch: ${milestoneBranch}`;
1612
+ const taskLines = completedSlices
1613
+ .flatMap((s) => s.tasks.map((task) => `- ${s.id}/${task.id}: ${task.title}`))
1614
+ .join("\n");
1615
+ const taskBlock = taskLines ? `\n\nCompleted tasks:\n${taskLines}` : "";
1616
+ body = `\n\nCompleted slices:\n${sliceLines}${taskBlock}\n\n${milestoneContext}\nGSD-Milestone: ${milestoneId}\nBranch: ${milestoneBranch}`;
1480
1617
  }
1481
1618
  else {
1482
- body = `\n\nGSD-Milestone: ${milestoneId}\nBranch: ${milestoneBranch}`;
1619
+ body = `\n\n${milestoneContext}\nGSD-Milestone: ${milestoneId}\nBranch: ${milestoneBranch}`;
1483
1620
  }
1484
1621
  const commitMessage = subject + body;
1485
1622
  // 6b. Reconcile worktree HEAD with milestone branch ref (#1846).