gsd-pi 2.80.0-dev.3065f7bfa → 2.80.0-dev.488219eb6

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 (376) hide show
  1. package/dist/claude-cli-check.d.ts +30 -0
  2. package/dist/claude-cli-check.js +18 -7
  3. package/dist/cli.js +0 -19
  4. package/dist/headless-query.d.ts +10 -0
  5. package/dist/headless-query.js +6 -4
  6. package/dist/loader-entrypoint.d.ts +8 -0
  7. package/dist/loader-entrypoint.js +27 -0
  8. package/dist/loader.js +2 -11
  9. package/dist/mcp-server.d.ts +1 -0
  10. package/dist/mcp-server.js +6 -3
  11. package/dist/resources/.managed-resources-content-hash +1 -1
  12. package/dist/resources/extensions/claude-code-cli/readiness.js +18 -7
  13. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +29 -0
  14. package/dist/resources/extensions/github-sync/sync.js +4 -1
  15. package/dist/resources/extensions/gsd/auto/loop.js +71 -8
  16. package/dist/resources/extensions/gsd/auto/phases.js +32 -8
  17. package/dist/resources/extensions/gsd/auto/resolve.js +12 -0
  18. package/dist/resources/extensions/gsd/auto/run-unit.js +3 -1
  19. package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
  20. package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
  21. package/dist/resources/extensions/gsd/auto-post-unit.js +81 -76
  22. package/dist/resources/extensions/gsd/auto-start.js +41 -6
  23. package/dist/resources/extensions/gsd/auto-worktree.js +98 -80
  24. package/dist/resources/extensions/gsd/auto.js +84 -29
  25. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +62 -13
  26. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +20 -26
  27. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +29 -12
  28. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +6 -9
  29. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +4 -7
  30. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +6 -10
  31. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +5 -9
  32. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +1 -1
  33. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +60 -26
  34. package/dist/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.js +4 -0
  35. package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
  36. package/dist/resources/extensions/gsd/commands-config.js +1 -1
  37. package/dist/resources/extensions/gsd/commands-eval-review.js +2 -2
  38. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  39. package/dist/resources/extensions/gsd/db/unit-dispatches.js +53 -0
  40. package/dist/resources/extensions/gsd/git-service.js +37 -1
  41. package/dist/resources/extensions/gsd/guided-flow.js +14 -4
  42. package/dist/resources/extensions/gsd/init-wizard.js +4 -1
  43. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -4
  44. package/dist/resources/extensions/gsd/slice-cadence.js +45 -2
  45. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +15 -9
  46. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -7
  47. package/dist/resources/extensions/gsd/tools/complete-task.js +1 -1
  48. package/dist/resources/extensions/gsd/worktree-resolver.js +22 -1
  49. package/dist/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
  50. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  51. package/dist/web/standalone/.next/BUILD_ID +1 -1
  52. package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
  53. package/dist/web/standalone/.next/build-manifest.json +3 -3
  54. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  55. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  56. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  57. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  58. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  66. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  67. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  68. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  69. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  74. package/dist/web/standalone/.next/server/app/index.html +1 -1
  75. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  76. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  77. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  78. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  82. package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
  83. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  84. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  85. package/dist/web/standalone/.next/server/middleware.js +3 -3
  86. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  87. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  88. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  89. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +10 -0
  90. package/dist/web/standalone/.next/static/chunks/app/{page-fab3ebb85b006001.js → page-752f1e2ebdaa3e45.js} +1 -1
  91. package/dist/web/standalone/.next/static/chunks/{webpack-0481f1221120a7c6.js → webpack-de742b64187e13fe.js} +1 -1
  92. package/dist/welcome-screen.d.ts +2 -0
  93. package/dist/welcome-screen.js +9 -7
  94. package/package.json +1 -1
  95. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +35 -13
  96. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  97. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +21 -11
  98. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -1
  99. package/packages/pi-ai/dist/providers/anthropic.d.ts +7 -0
  100. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  101. package/packages/pi-ai/dist/providers/anthropic.js +9 -7
  102. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  103. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +23 -14
  104. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -1
  105. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +48 -21
  106. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
  107. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +22 -21
  108. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -1
  109. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +22 -21
  110. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -1
  111. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +39 -25
  112. package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -22
  113. package/packages/pi-ai/src/providers/anthropic.ts +22 -9
  114. package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +34 -21
  115. package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +56 -22
  116. package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +24 -28
  117. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +24 -28
  118. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  119. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +3 -1
  120. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  121. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -2
  122. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  123. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  124. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +22 -56
  125. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -1
  126. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +1 -0
  127. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  128. package/packages/pi-coding-agent/dist/core/tools/bash.js +3 -1
  129. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  130. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts +2 -0
  131. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  132. package/packages/pi-coding-agent/dist/core/tools/edit.js +12 -1
  133. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  134. package/packages/pi-coding-agent/dist/core/tools/find.d.ts +2 -0
  135. package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
  136. package/packages/pi-coding-agent/dist/core/tools/find.js +14 -6
  137. package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
  138. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts +2 -0
  139. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
  140. package/packages/pi-coding-agent/dist/core/tools/grep.js +12 -3
  141. package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
  142. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts +2 -0
  143. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  144. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +3 -1
  145. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  146. package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -1
  147. package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
  148. package/packages/pi-coding-agent/dist/core/tools/index.js +1 -0
  149. package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
  150. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts +2 -0
  151. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
  152. package/packages/pi-coding-agent/dist/core/tools/ls.js +10 -3
  153. package/packages/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
  154. package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -0
  155. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  156. package/packages/pi-coding-agent/dist/core/tools/read.js +3 -1
  157. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  158. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +7 -62
  159. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -1
  160. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts +2 -0
  161. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts.map +1 -0
  162. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js +115 -0
  163. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js.map +1 -0
  164. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts +19 -0
  165. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts.map +1 -0
  166. package/packages/pi-coding-agent/dist/core/tools/tool-target.js +20 -0
  167. package/packages/pi-coding-agent/dist/core/tools/tool-target.js.map +1 -0
  168. package/packages/pi-coding-agent/dist/core/tools/write.d.ts +4 -0
  169. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  170. package/packages/pi-coding-agent/dist/core/tools/write.js +9 -1
  171. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  172. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +89 -2
  173. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  174. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +25 -1
  175. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  176. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +5 -0
  177. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  178. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +153 -8
  179. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  180. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  181. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +18 -1
  182. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  183. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +23 -5
  184. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  185. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
  186. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  187. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +19 -0
  188. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  189. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +23 -5
  190. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -1
  191. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +3 -1
  192. package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -1
  193. package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +22 -66
  194. package/packages/pi-coding-agent/src/core/tools/bash.ts +4 -1
  195. package/packages/pi-coding-agent/src/core/tools/edit.ts +13 -1
  196. package/packages/pi-coding-agent/src/core/tools/find.ts +15 -6
  197. package/packages/pi-coding-agent/src/core/tools/grep.ts +13 -3
  198. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +4 -1
  199. package/packages/pi-coding-agent/src/core/tools/index.ts +8 -0
  200. package/packages/pi-coding-agent/src/core/tools/ls.ts +11 -3
  201. package/packages/pi-coding-agent/src/core/tools/read.ts +4 -1
  202. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +11 -72
  203. package/packages/pi-coding-agent/src/core/tools/tool-target-metadata.test.ts +127 -0
  204. package/packages/pi-coding-agent/src/core/tools/tool-target.ts +48 -0
  205. package/packages/pi-coding-agent/src/core/tools/write.ts +14 -2
  206. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +119 -2
  207. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +31 -1
  208. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +177 -8
  209. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +24 -5
  210. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +17 -1
  211. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +21 -0
  212. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +25 -8
  213. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  214. package/src/resources/extensions/claude-code-cli/readiness.ts +25 -7
  215. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +30 -0
  216. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +26 -0
  217. package/src/resources/extensions/github-sync/sync.ts +8 -1
  218. package/src/resources/extensions/github-sync/tests/sync-source.test.ts +6 -18
  219. package/src/resources/extensions/gsd/auto/loop.ts +84 -8
  220. package/src/resources/extensions/gsd/auto/phases.ts +43 -8
  221. package/src/resources/extensions/gsd/auto/resolve.ts +19 -0
  222. package/src/resources/extensions/gsd/auto/run-unit.ts +3 -0
  223. package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
  224. package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
  225. package/src/resources/extensions/gsd/auto-post-unit.ts +93 -78
  226. package/src/resources/extensions/gsd/auto-start.ts +56 -6
  227. package/src/resources/extensions/gsd/auto-worktree.ts +118 -72
  228. package/src/resources/extensions/gsd/auto.ts +121 -29
  229. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +76 -12
  230. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +20 -26
  231. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +27 -12
  232. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +7 -9
  233. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +4 -7
  234. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +6 -10
  235. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +5 -9
  236. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +1 -1
  237. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +64 -26
  238. package/src/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.ts +4 -0
  239. package/src/resources/extensions/gsd/commands/handlers/ops.ts +4 -2
  240. package/src/resources/extensions/gsd/commands-config.ts +1 -1
  241. package/src/resources/extensions/gsd/commands-eval-review.ts +2 -2
  242. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  243. package/src/resources/extensions/gsd/db/unit-dispatches.ts +66 -0
  244. package/src/resources/extensions/gsd/git-service.ts +41 -2
  245. package/src/resources/extensions/gsd/guided-flow.ts +19 -4
  246. package/src/resources/extensions/gsd/init-wizard.ts +5 -1
  247. package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -4
  248. package/src/resources/extensions/gsd/slice-cadence.ts +49 -2
  249. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +23 -9
  250. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +59 -89
  251. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +47 -172
  252. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +0 -35
  253. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +35 -9
  254. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +15 -0
  255. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +80 -59
  256. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +3 -47
  257. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +76 -18
  258. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +106 -0
  259. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +54 -95
  260. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +67 -26
  261. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +32 -30
  262. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +32 -128
  263. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +20 -54
  264. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +20 -30
  265. package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +17 -29
  266. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +138 -0
  267. package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +21 -39
  268. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +15 -24
  269. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +44 -29
  270. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +39 -51
  271. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +1 -217
  272. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +15 -32
  273. package/src/resources/extensions/gsd/tests/browser-teardown.test.ts +0 -41
  274. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +34 -27
  275. package/src/resources/extensions/gsd/tests/cmux.test.ts +51 -53
  276. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +39 -61
  277. package/src/resources/extensions/gsd/tests/commands-config.test.ts +26 -19
  278. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +140 -0
  279. package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +29 -33
  280. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +45 -108
  281. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +35 -31
  282. package/src/resources/extensions/gsd/tests/cwd-fallback-hardening.test.ts +138 -0
  283. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +4 -68
  284. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +4 -9
  285. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +14 -65
  286. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +44 -37
  287. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +58 -40
  288. package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +25 -15
  289. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +35 -17
  290. package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +16 -21
  291. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +15 -82
  292. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -20
  293. package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +18 -26
  294. package/src/resources/extensions/gsd/tests/init-skip-git.test.ts +9 -12
  295. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +40 -0
  296. package/src/resources/extensions/gsd/tests/integration/commands-eval-review.integration.test.ts +4 -2
  297. package/src/resources/extensions/gsd/tests/integration/git-locale.test.ts +31 -20
  298. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +12 -0
  299. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +0 -47
  300. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +60 -202
  301. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +13 -59
  302. package/src/resources/extensions/gsd/tests/lazy-pi-tui-import.test.ts +44 -6
  303. package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +21 -35
  304. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +79 -98
  305. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +70 -278
  306. package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +37 -30
  307. package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +32 -28
  308. package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +24 -37
  309. package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +9 -24
  310. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +113 -0
  311. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +36 -22
  312. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +36 -30
  313. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +74 -4
  314. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +20 -22
  315. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +130 -32
  316. package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +18 -36
  317. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +35 -73
  318. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +76 -138
  319. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +70 -125
  320. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +59 -161
  321. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +33 -29
  322. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +22 -196
  323. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +23 -93
  324. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +50 -79
  325. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +27 -13
  326. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +151 -251
  327. package/src/resources/extensions/gsd/tests/resource-loader-import-path.test.ts +41 -29
  328. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +58 -90
  329. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +32 -164
  330. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +57 -41
  331. package/src/resources/extensions/gsd/tests/session-model-override.test.ts +14 -9
  332. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
  333. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +61 -1
  334. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +44 -42
  335. package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +56 -24
  336. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +51 -11
  337. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +23 -0
  338. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +66 -50
  339. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +68 -107
  340. package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +115 -42
  341. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +21 -97
  342. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +25 -116
  343. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +21 -57
  344. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +29 -76
  345. package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +33 -24
  346. package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +39 -30
  347. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +33 -47
  348. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +48 -46
  349. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +14 -102
  350. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +78 -232
  351. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +32 -35
  352. package/src/resources/extensions/gsd/tests/token-profile.test.ts +84 -309
  353. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +134 -341
  354. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +8 -25
  355. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +50 -1
  356. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +6 -101
  357. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +43 -36
  358. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -444
  359. package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
  360. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +44 -189
  361. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -57
  362. package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
  363. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +21 -44
  364. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +27 -26
  365. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +14 -13
  366. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -18
  367. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +36 -0
  368. package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -13
  369. package/src/resources/extensions/gsd/tools/complete-milestone.ts +14 -15
  370. package/src/resources/extensions/gsd/tools/complete-task.ts +1 -1
  371. package/src/resources/extensions/gsd/worktree-resolver.ts +34 -1
  372. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +86 -40
  373. package/src/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
  374. package/dist/web/standalone/.next/static/chunks/8336.631939fb583761fa.js +0 -10
  375. /package/dist/web/standalone/.next/static/{O2WvnXROue6l7nAp_4dhC → G68KoLv5claox_Dyd4pZn}/_buildManifest.js +0 -0
  376. /package/dist/web/standalone/.next/static/{O2WvnXROue6l7nAp_4dhC → G68KoLv5claox_Dyd4pZn}/_ssgManifest.js +0 -0
@@ -26,6 +26,58 @@ function isAlreadyActiveConstraintError(err) {
26
26
  }
27
27
  return /\bUNIQUE\b|\bconstraint failed\b/i.test(msg);
28
28
  }
29
+ function settleStaleActiveDispatchForUnit(input, now) {
30
+ const db = _getAdapter();
31
+ const active = db.prepare(`SELECT id, status, worker_id, milestone_lease_token
32
+ FROM unit_dispatches
33
+ WHERE unit_id = :unit_id
34
+ AND status IN ('claimed','running')
35
+ ORDER BY id DESC
36
+ LIMIT 1`).get({ ":unit_id": input.unitId });
37
+ if (!active)
38
+ return;
39
+ if (active.worker_id === input.workerId &&
40
+ active.milestone_lease_token === input.milestoneLeaseToken) {
41
+ return;
42
+ }
43
+ const reason = "stale-dispatch-lease-takeover";
44
+ const result = db.prepare(`UPDATE unit_dispatches
45
+ SET status = 'canceled',
46
+ ended_at = :ended_at,
47
+ exit_reason = :reason
48
+ WHERE id = :id
49
+ AND status IN ('claimed','running')
50
+ AND (worker_id != :worker_id OR milestone_lease_token != :token)`).run({
51
+ ":id": active.id,
52
+ ":ended_at": now,
53
+ ":reason": reason,
54
+ ":worker_id": input.workerId,
55
+ ":token": input.milestoneLeaseToken,
56
+ });
57
+ const changes = typeof result.changes === "number"
58
+ ? result.changes
59
+ : 0;
60
+ if (changes < 1)
61
+ return;
62
+ insertAuditEvent({
63
+ eventId: randomUUID(),
64
+ traceId: input.traceId,
65
+ turnId: input.turnId ?? undefined,
66
+ category: "orchestration",
67
+ type: "dispatch-stale-canceled",
68
+ ts: now,
69
+ payload: {
70
+ dispatchId: active.id,
71
+ unitId: input.unitId,
72
+ priorStatus: active.status,
73
+ priorWorkerId: active.worker_id,
74
+ priorMilestoneLeaseToken: active.milestone_lease_token,
75
+ takeoverWorkerId: input.workerId,
76
+ takeoverMilestoneLeaseToken: input.milestoneLeaseToken,
77
+ reason,
78
+ },
79
+ });
80
+ }
29
81
  /**
30
82
  * Insert a new dispatch row in `claimed` state. Atomic guard against
31
83
  * double-claim (B2): the partial unique index
@@ -58,6 +110,7 @@ export function recordDispatchClaim(input) {
58
110
  milestoneLeaseToken: input.milestoneLeaseToken,
59
111
  };
60
112
  }
113
+ settleStaleActiveDispatchForUnit(input, now);
61
114
  try {
62
115
  const result = db.prepare(`INSERT INTO unit_dispatches (
63
116
  trace_id, turn_id, worker_id, milestone_lease_token,
@@ -1,3 +1,5 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Git operations, commit-message formatting, and turn git actions.
1
3
  /**
2
4
  * GSD Git Service
3
5
  *
@@ -49,6 +51,10 @@ export function buildTaskCommitMessage(ctx) {
49
51
  .join("\n");
50
52
  bodyParts.push(fileLines);
51
53
  }
54
+ const contextLines = buildTaskCommitContextLines(ctx);
55
+ if (contextLines.length > 0) {
56
+ bodyParts.push(`GSD context:\n${contextLines.join("\n")}`);
57
+ }
52
58
  // Trailers: GSD-Task first, then Resolves
53
59
  bodyParts.push(`GSD-Task: ${ctx.taskId}`);
54
60
  if (ctx.issueNumber) {
@@ -56,6 +62,31 @@ export function buildTaskCommitMessage(ctx) {
56
62
  }
57
63
  return `${subject}\n\n${bodyParts.join("\n\n")}`;
58
64
  }
65
+ function buildTaskCommitContextLines(ctx) {
66
+ const lines = [];
67
+ const milestone = formatNamedContext(ctx.milestoneId, ctx.milestoneTitle);
68
+ const slice = formatNamedContext(ctx.sliceId, ctx.sliceTitle);
69
+ const taskId = ctx.taskDisplayId ?? ctx.taskId.split("/").pop();
70
+ const task = formatNamedContext(taskId, ctx.taskTitle);
71
+ if (milestone)
72
+ lines.push(`- Milestone: ${milestone}`);
73
+ if (slice)
74
+ lines.push(`- Slice: ${slice}`);
75
+ if (task)
76
+ lines.push(`- Task: ${task}`);
77
+ return lines;
78
+ }
79
+ function formatNamedContext(id, title) {
80
+ const cleanId = id?.trim();
81
+ const cleanTitle = title?.trim();
82
+ if (!cleanId && !cleanTitle)
83
+ return null;
84
+ if (!cleanId)
85
+ return cleanTitle ?? null;
86
+ if (!cleanTitle || cleanTitle === cleanId)
87
+ return cleanId;
88
+ return `${cleanId} - ${cleanTitle}`;
89
+ }
59
90
  function sanitizeCommitSubjectDescription(value) {
60
91
  const cleaned = value
61
92
  .replace(/[\x00-\x1F\x7F]+/g, " ")
@@ -855,7 +886,12 @@ export function createDraftPR(basePath, milestoneId, title, body, opts) {
855
886
  args.push("--head", opts.head);
856
887
  if (opts?.base)
857
888
  args.push("--base", opts.base);
858
- const result = execFileSync("gh", args, { cwd: basePath, encoding: "utf8", timeout: 30000, env: GIT_NO_PROMPT_ENV });
889
+ const result = execFileSync("gh", args, {
890
+ cwd: basePath,
891
+ encoding: "utf8",
892
+ timeout: 30000,
893
+ env: opts?.env ?? GIT_NO_PROMPT_ENV,
894
+ });
859
895
  return result.trim();
860
896
  }
861
897
  catch {
@@ -45,6 +45,9 @@ import { runPreparation, formatCodebaseBrief, formatPriorContextBrief, } from ".
45
45
  import { verifyExpectedArtifact } from "./auto-recovery.js";
46
46
  import { createWorkspace, scopeMilestone } from "./workspace.js";
47
47
  import { getPendingGate, extractDepthVerificationMilestoneId } from "./bootstrap/write-gate.js";
48
+ export function shouldSkipGitBootstrapAfterInit(result) {
49
+ return result.gitEnabled === false;
50
+ }
48
51
  // ─── Re-exports (preserve public API for existing importers) ────────────────
49
52
  export { MILESTONE_ID_RE, generateMilestoneSuffix, nextMilestoneId, extractMilestoneSeq, parseMilestoneId, milestoneIdSort, maxMilestoneNum, findMilestoneIds, reserveMilestoneId, claimReservedId, getReservedMilestoneIds, clearReservedMilestoneIds, } from "./milestone-ids.js";
50
53
  export { showQueue, handleQueueReorder, showQueueAdd, buildExistingMilestonesContext, } from "./guided-flow-queue.js";
@@ -131,6 +134,13 @@ function runPlanV2Gate(ctx, basePath, state) {
131
134
  }
132
135
  return "pass";
133
136
  }
137
+ export const _needsPlanV2GateForTest = needsPlanV2Gate;
138
+ export const _runPlanV2GateForTest = runPlanV2Gate;
139
+ export function _roadmapHasParseableSlicesForTest(roadmapContent) {
140
+ if (!roadmapContent)
141
+ return false;
142
+ return parseRoadmapSlices(roadmapContent).length > 0;
143
+ }
134
144
  // ─── Commit Instruction Helpers ──────────────────────────────────────────────
135
145
  /** Build commit instruction for planning prompts. .gsd/ is managed externally and always gitignored. */
136
146
  function buildDocsCommitInstruction(_message) {
@@ -154,7 +164,7 @@ const USER_DRIVEN_DEEP_SETUP_UNITS = new Set([
154
164
  "discuss-requirements",
155
165
  "research-decision",
156
166
  ]);
157
- const FOREGROUND_DEEP_SETUP_RULE_NAMES = new Set([
167
+ export const FOREGROUND_DEEP_SETUP_RULE_NAMES = new Set([
158
168
  "deep: pre-planning (no workflow prefs) → workflow-preferences",
159
169
  "deep: pre-planning (no PROJECT) → discuss-project",
160
170
  "deep: pre-planning (no REQUIREMENTS) → discuss-requirements",
@@ -898,6 +908,7 @@ async function dispatchWorkflow(pi, note, customType = "gsd-run", ctx, unitType)
898
908
  restoreGsdWorkflowTools(pi, savedTools);
899
909
  }
900
910
  }
911
+ export const _dispatchWorkflowForTest = dispatchWorkflow;
901
912
  function getStructuredQuestionsAvailability(pi, ctx) {
902
913
  if (!ctx)
903
914
  return "false";
@@ -1666,7 +1677,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
1666
1677
  const result = await showProjectInit(ctx, pi, basePath, detection);
1667
1678
  if (!result.completed)
1668
1679
  return; // User cancelled
1669
- skipGitBootstrap = result.gitEnabled === false;
1680
+ skipGitBootstrap = shouldSkipGitBootstrapAfterInit(result);
1670
1681
  // Init wizard bootstrapped .gsd/ — fall through to the normal flow below
1671
1682
  // which will detect "no milestones" and start the discuss prompt
1672
1683
  }
@@ -1984,8 +1995,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
1984
1995
  if (hasRoadmap) {
1985
1996
  const roadmapContent = await loadFile(roadmapFile);
1986
1997
  if (roadmapContent) {
1987
- const parsed = parseRoadmapSlices(roadmapContent);
1988
- roadmapHasSlices = parsed.length > 0;
1998
+ roadmapHasSlices = _roadmapHasParseableSlicesForTest(roadmapContent);
1989
1999
  }
1990
2000
  }
1991
2001
  if (!hasRoadmap || !roadmapHasSlices) {
@@ -15,6 +15,9 @@ import { assertSafeDirectory } from "./validate-directory.js";
15
15
  import { runSkillInstallStep } from "./skill-catalog.js";
16
16
  import { generateCodebaseMap, writeCodebaseMap } from "./codebase-generator.js";
17
17
  import { handlePrefsWizard, writePreferencesFile } from "./commands-prefs-wizard.js";
18
+ export function shouldWriteGitFiles(gitEnabled) {
19
+ return gitEnabled;
20
+ }
18
21
  // ─── Defaults ───────────────────────────────────────────────────────────────────
19
22
  const DEFAULT_PREFS = {
20
23
  mode: "solo",
@@ -247,7 +250,7 @@ export async function showProjectInit(ctx, pi, basePath, detection) {
247
250
  }
248
251
  // Ensure .gitignore only when git is active. A user who selected "Skip"
249
252
  // should not have git initialized or git-related files mutated later.
250
- if (gitEnabled) {
253
+ if (shouldWriteGitFiles(gitEnabled)) {
251
254
  ensureGitignore(basePath);
252
255
  untrackRuntimeFiles(basePath);
253
256
  }
@@ -16,7 +16,7 @@ Preloaded context includes roadmap, requirements, decisions, project context, an
16
16
 
17
17
  Start with what the excerpts give you. Read full files when the section heads signal richer context you need.
18
18
 
19
- **On-demand Read ordering:** Complete all slice SUMMARY Reads you need for cross-slice synthesis, the Decision Re-evaluation table, and LEARNINGS **before** calling `gsd_complete_milestone` (step 12). Once that tool runs, the milestone is marked complete in the DB, so it must be the final persistent milestone-closeout write.
19
+ **On-demand Read ordering:** Complete all slice SUMMARY Reads you need for cross-slice synthesis, the Decision Re-evaluation table, and LEARNINGS **before** calling `gsd_complete_milestone` (step 13). Once that tool runs, the milestone is marked complete in the DB, so it must be the final persistent milestone-closeout write.
20
20
 
21
21
  ### Closeout Review Mode
22
22
 
@@ -45,7 +45,7 @@ Subagents report only; they do not write user source. Fold any findings into Dec
45
45
 
46
46
  ### Verification Gate — STOP if verification failed
47
47
 
48
- **If ANY verification failure was recorded in steps 3, 4, or 5, you MUST follow the failure path below. Do NOT proceed with steps 913.**
48
+ **If ANY verification failure was recorded in steps 4, 5, or 6, you MUST follow the failure path below. Do NOT proceed with steps 1014.**
49
49
 
50
50
  **Failure path** (verification failed):
51
51
  - Do NOT call `gsd_complete_milestone`.
@@ -69,13 +69,15 @@ Subagents report only; they do not write user source. Fold any findings into Dec
69
69
  - `title` (string) — Milestone title
70
70
  - `oneLiner` (string) — One-sentence summary of what the milestone achieved
71
71
  - `narrative` (string) — Detailed narrative of what happened during the milestone
72
+ - `verificationPassed` (boolean) — Must be `true`; confirms code-change verification, success criteria, and definition-of-done checks all passed
73
+
74
+ **Recommended parameters** (the schema accepts these as optional, but always fill them in — omitted values render as placeholders such as "Not provided.", "None.", or "(none)"):
72
75
  - `successCriteriaResults` (string) — Markdown detailing how each success criterion was met or not met
73
76
  - `definitionOfDoneResults` (string) — Markdown detailing how each definition-of-done item was met
74
77
  - `requirementOutcomes` (string) — Markdown detailing requirement status transitions with evidence
75
78
  - `keyDecisions` (array of strings) — Key architectural/pattern decisions made during the milestone
76
79
  - `keyFiles` (array of strings) — Key files created or modified during the milestone
77
80
  - `lessonsLearned` (array of strings) — Lessons learned during the milestone
78
- - `verificationPassed` (boolean) — Must be `true`; confirms code-change verification, success criteria, and definition-of-done checks all passed
79
81
 
80
82
  **Optional parameters:**
81
83
  - `followUps` (string) — Follow-up items for future milestones
@@ -84,6 +86,6 @@ Subagents report only; they do not write user source. Fold any findings into Dec
84
86
  14. Do not commit manually — the system auto-commits your changes after this unit completes.
85
87
  - Say: "Milestone {{milestoneId}} complete."
86
88
 
87
- **Important:** Do NOT skip code-change, success-criteria, or definition-of-done verification (steps 3-5). The summary must reflect verified outcomes. Verification failures block completion; there is no override. If a verification tool fails, errors, or returns unexpected output, treat it as failure.
89
+ **Important:** Do NOT skip code-change, success-criteria, or definition-of-done verification (steps 4-6). The summary must reflect verified outcomes. Verification failures block completion; there is no override. If a verification tool fails, errors, or returns unexpected output, treat it as failure.
88
90
 
89
91
  **File system safety:** When scanning milestone directories for evidence, use `ls` or `find` first. Never pass a directory path (e.g. `tasks/`, `slices/`) to `read`; it only accepts file paths.
@@ -1,3 +1,5 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Slice-cadence merge and milestone resquash git operations.
1
3
  /**
2
4
  * Slice-cadence collapse — #4765.
3
5
  *
@@ -29,6 +31,7 @@ import { logWarning } from "./workflow-logger.js";
29
31
  import { emitSliceMerged, emitMilestoneResquash } from "./worktree-telemetry.js";
30
32
  import { loadEffectiveGSDPreferences } from "./preferences.js";
31
33
  import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
34
+ import { getMilestone, getSlice, isDbAvailable } from "./gsd-db.js";
32
35
  /**
33
36
  * Auto-worktree milestone branch name. Must match autoWorktreeBranch() in
34
37
  * auto-worktree.ts; duplicated here to avoid a cyclic import.
@@ -59,6 +62,46 @@ function cleanupMergeArtifacts(projectRoot) {
59
62
  logWarning("worktree", `merge artifact cleanup failed: ${err instanceof Error ? err.message : String(err)}`);
60
63
  }
61
64
  }
65
+ function stripKnownIdPrefix(value, id) {
66
+ const raw = String(value ?? "").trim();
67
+ if (!raw)
68
+ return undefined;
69
+ const lower = raw.toLowerCase();
70
+ const idLower = id.toLowerCase();
71
+ if (lower.startsWith(`${idLower}:`))
72
+ return raw.slice(id.length + 1).trim() || undefined;
73
+ return raw;
74
+ }
75
+ function getSliceMergeNames(milestoneId, sliceId) {
76
+ if (!isDbAvailable())
77
+ return {};
78
+ return {
79
+ milestoneTitle: stripKnownIdPrefix(getMilestone(milestoneId)?.title, milestoneId),
80
+ sliceTitle: stripKnownIdPrefix(getSlice(milestoneId, sliceId)?.title, sliceId),
81
+ };
82
+ }
83
+ function buildSliceMergeCommitMessage(milestoneId, sliceId, milestoneBranch) {
84
+ const names = getSliceMergeNames(milestoneId, sliceId);
85
+ const sliceLabel = names.sliceTitle ?? sliceId;
86
+ const subject = `feat: ${sliceLabel} - ${sliceId} of ${milestoneId} (slice-cadence)`;
87
+ const body = [
88
+ `Slice: ${sliceId}${names.sliceTitle ? ` - ${names.sliceTitle}` : ""}`,
89
+ `Milestone: ${milestoneId}${names.milestoneTitle ? ` - ${names.milestoneTitle}` : ""}`,
90
+ `GSD-Slice: ${sliceId}`,
91
+ `GSD-Milestone: ${milestoneId}`,
92
+ `Branch: ${milestoneBranch}`,
93
+ ];
94
+ return `${subject}\n\n${body.join("\n")}`;
95
+ }
96
+ function buildMilestoneResquashCommitMessage(milestoneId, sliceCount) {
97
+ const milestoneTitle = isDbAvailable()
98
+ ? stripKnownIdPrefix(getMilestone(milestoneId)?.title, milestoneId)
99
+ : undefined;
100
+ const subject = milestoneTitle
101
+ ? `feat: ${milestoneTitle} (${milestoneId}, ${sliceCount} slices re-squashed)`
102
+ : `feat: ${milestoneId} (${sliceCount} slices re-squashed)`;
103
+ return `${subject}\n\nMilestone: ${milestoneId}${milestoneTitle ? ` - ${milestoneTitle}` : ""}\nGSD-Milestone: ${milestoneId}`;
104
+ }
62
105
  function advanceMilestoneBranch(projectRoot, worktreeCwd, milestoneBranch, mainBranch) {
63
106
  let worktreeBranch = null;
64
107
  try {
@@ -173,7 +216,7 @@ export function mergeSliceToMain(projectRoot, milestoneId, sliceId) {
173
216
  throw new MergeConflictError(conflictedFiles, "squash", milestoneBranch, mainBranch);
174
217
  }
175
218
  // Commit the squash with a slice-scoped message
176
- const commitSha = nativeCommit(projectRoot, `gsd: merge ${sliceId} of ${milestoneId} (slice-cadence)`);
219
+ const commitSha = nativeCommit(projectRoot, buildSliceMergeCommitMessage(milestoneId, sliceId, milestoneBranch));
177
220
  // Advance the milestone branch to main so the next slice's commits start
178
221
  // from a clean base. When the milestone branch is checked out in an auto
179
222
  // worktree, Git refuses a project-root branch -f; reset from inside the
@@ -255,7 +298,7 @@ export function resquashMilestoneOnMain(projectRoot, milestoneId, startSha) {
255
298
  stdio: ["ignore", "pipe", "pipe"],
256
299
  encoding: "utf-8",
257
300
  });
258
- const newSha = nativeCommit(projectRoot, `gsd: complete milestone ${milestoneId} (${sliceCount} slices re-squashed)`, { allowEmpty: true });
301
+ const newSha = nativeCommit(projectRoot, buildMilestoneResquashCommitMessage(milestoneId, sliceCount), { allowEmpty: true });
259
302
  try {
260
303
  emitMilestoneResquash(projectRoot, milestoneId, {
261
304
  sliceCount,
@@ -33,6 +33,19 @@ let sliceState = null;
33
33
  const SLICE_ORCHESTRATOR_STATE_FILE = "slice-orchestrator.json";
34
34
  const TMP_SUFFIX = ".tmp";
35
35
  export const SLICE_WORKER_AUTO_ARGS = ["headless", "--json", "auto"];
36
+ export function _resolveSliceParallelMaxWorkersForTest(maxWorkers) {
37
+ return maxWorkers ?? 2;
38
+ }
39
+ export function _buildSliceWorkerEnvForTest(basePath, milestoneId, sliceId, workerToken, sourceEnv = process.env) {
40
+ return {
41
+ ...sourceEnv,
42
+ GSD_SLICE_LOCK: sliceId,
43
+ GSD_MILESTONE_LOCK: milestoneId,
44
+ GSD_PROJECT_ROOT: basePath,
45
+ GSD_PARALLEL_WORKER: "1",
46
+ GSD_SLICE_WORKER_TOKEN: workerToken,
47
+ };
48
+ }
36
49
  function sliceStateFilePath(basePath) {
37
50
  return join(gsdRoot(basePath), SLICE_ORCHESTRATOR_STATE_FILE);
38
51
  }
@@ -281,7 +294,7 @@ export async function startSliceParallel(basePath, milestoneId, eligibleSlices,
281
294
  if (process.env.GSD_PARALLEL_WORKER) {
282
295
  return { started: [], errors: [{ sid: "all", error: "Cannot start slice-parallel from within a parallel worker" }] };
283
296
  }
284
- const maxWorkers = opts.maxWorkers ?? 2;
297
+ const maxWorkers = _resolveSliceParallelMaxWorkersForTest(opts.maxWorkers);
285
298
  const budgetCeiling = opts.budgetCeiling;
286
299
  // Initialize orchestrator state
287
300
  sliceState = {
@@ -506,14 +519,7 @@ function spawnSliceWorker(basePath, milestoneId, sliceId) {
506
519
  try {
507
520
  child = spawn(process.execPath, [binPath, ...SLICE_WORKER_AUTO_ARGS], {
508
521
  cwd: worker.worktreePath,
509
- env: {
510
- ...process.env,
511
- GSD_SLICE_LOCK: sliceId,
512
- GSD_MILESTONE_LOCK: milestoneId,
513
- GSD_PROJECT_ROOT: basePath,
514
- GSD_PARALLEL_WORKER: "1",
515
- GSD_SLICE_WORKER_TOKEN: worker.workerToken,
516
- },
522
+ env: _buildSliceWorkerEnvForTest(basePath, milestoneId, sliceId, worker.workerToken),
517
523
  stdio: ["ignore", "pipe", "pipe"],
518
524
  detached: false,
519
525
  });
@@ -17,8 +17,7 @@ import { renderAllProjections, stripIdPrefix } from "../workflow-projections.js"
17
17
  import { writeManifest } from "../workflow-manifest.js";
18
18
  import { appendEvent } from "../workflow-events.js";
19
19
  import { logWarning, logError } from "../workflow-logger.js";
20
- function renderMilestoneSummaryMarkdown(params) {
21
- const now = new Date().toISOString();
20
+ function renderMilestoneSummaryMarkdown(params, completedAt) {
22
21
  const displayTitle = stripIdPrefix(params.title, params.milestoneId);
23
22
  // Apply defaults for optional enrichment fields (#2771)
24
23
  const keyDecisions = params.keyDecisions ?? [];
@@ -37,7 +36,7 @@ function renderMilestoneSummaryMarkdown(params) {
37
36
  id: ${params.milestoneId}
38
37
  title: "${displayTitle}"
39
38
  status: complete
40
- completed_at: ${now}
39
+ completed_at: ${completedAt}
41
40
  key_decisions:
42
41
  ${keyDecisionsYaml}
43
42
  key_files:
@@ -56,15 +55,15 @@ ${params.narrative}
56
55
 
57
56
  ## Success Criteria Results
58
57
 
59
- ${params.successCriteriaResults ?? "Not provided."}
58
+ ${params.successCriteriaResults || "Not provided."}
60
59
 
61
60
  ## Definition of Done Results
62
61
 
63
- ${params.definitionOfDoneResults ?? "Not provided."}
62
+ ${params.definitionOfDoneResults || "Not provided."}
64
63
 
65
64
  ## Requirement Outcomes
66
65
 
67
- ${params.requirementOutcomes ?? "Not provided."}
66
+ ${params.requirementOutcomes || "Not provided."}
68
67
 
69
68
  ## Deviations
70
69
 
@@ -131,7 +130,7 @@ export async function handleCompleteMilestone(params, basePath) {
131
130
  return { error: guardError };
132
131
  }
133
132
  // ── Filesystem operations (outside transaction) ─────────────────────────
134
- const summaryMd = renderMilestoneSummaryMarkdown(params);
133
+ const summaryMd = renderMilestoneSummaryMarkdown(params, completedAt);
135
134
  let summaryPath;
136
135
  const milestoneDir = resolveMilestonePath(basePath, params.milestoneId);
137
136
  if (milestoneDir) {
@@ -46,7 +46,7 @@ function taskGateFieldForId(id, params) {
46
46
  * Normalize a list parameter that may arrive as a string (newline-delimited
47
47
  * bullet list from the LLM) into a string array (#3361).
48
48
  */
49
- function normalizeListParam(value) {
49
+ export function normalizeListParam(value) {
50
50
  if (Array.isArray(value))
51
51
  return value.map(String);
52
52
  if (typeof value === "string" && value.trim()) {
@@ -360,19 +360,38 @@ export class WorktreeResolver {
360
360
  phase: "auto-commit-failed",
361
361
  error: err instanceof Error ? err.message : String(err),
362
362
  });
363
+ ctx.notify(`Auto-commit before exiting ${milestoneId} failed: ${err instanceof Error ? err.message : String(err)}. Branch ${this.deps.autoWorktreeBranch(milestoneId)} is preserved for recovery.`, "warning");
363
364
  }
365
+ if (this.s.originalBasePath) {
366
+ try {
367
+ process.chdir(this.s.originalBasePath);
368
+ }
369
+ catch (err) {
370
+ debugLog("WorktreeResolver", {
371
+ action: "exitMilestone",
372
+ milestoneId,
373
+ phase: "pre-teardown-chdir-failed",
374
+ originalBasePath: this.s.originalBasePath,
375
+ error: err instanceof Error ? err.message : String(err),
376
+ });
377
+ ctx.notify(`Could not leave milestone worktree before cleanup: ${err instanceof Error ? err.message : String(err)}. Branch ${this.deps.autoWorktreeBranch(milestoneId)} is preserved for recovery.`, "warning");
378
+ }
379
+ }
380
+ let teardownFailed = false;
364
381
  try {
365
382
  this.deps.teardownAutoWorktree(this.s.originalBasePath, milestoneId, {
366
383
  preserveBranch: opts?.preserveBranch ?? false,
367
384
  });
368
385
  }
369
386
  catch (err) {
387
+ teardownFailed = true;
370
388
  debugLog("WorktreeResolver", {
371
389
  action: "exitMilestone",
372
390
  milestoneId,
373
391
  phase: "teardown-failed",
374
392
  error: err instanceof Error ? err.message : String(err),
375
393
  });
394
+ ctx.notify(`Worktree cleanup failed for ${milestoneId}: ${err instanceof Error ? err.message : String(err)}. Branch ${this.deps.autoWorktreeBranch(milestoneId)} is preserved for recovery.`, "warning");
376
395
  }
377
396
  this.restoreToProjectRoot();
378
397
  debugLog("WorktreeResolver", {
@@ -381,7 +400,9 @@ export class WorktreeResolver {
381
400
  result: "done",
382
401
  basePath: this.s.basePath,
383
402
  });
384
- ctx.notify(`Exited worktree for ${milestoneId}`, "info");
403
+ ctx.notify(teardownFailed
404
+ ? `Worktree exit for ${milestoneId} needs manual cleanup.`
405
+ : `Exited worktree for ${milestoneId}`, teardownFailed ? "warning" : "info");
385
406
  }
386
407
  // ── Merge and Exit ─────────────────────────────────────────────────────
387
408
  /**