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
@@ -18,6 +18,8 @@ import { bumpTurnGeneration } from "./turn-epoch.js";
18
18
  let _currentResolve = null;
19
19
  let _sessionSwitchInFlight = false;
20
20
  let _pendingSwitchCancellation = null;
21
+ let _sessionSwitchAbortGraceUntil = 0;
22
+ const DEFAULT_SESSION_SWITCH_ABORT_GRACE_MS = 2_000;
21
23
  // ─── Setters (needed for cross-module mutation) ─────────────────────────────
22
24
  export function _setCurrentResolve(fn) {
23
25
  _currentResolve = fn;
@@ -25,6 +27,15 @@ export function _setCurrentResolve(fn) {
25
27
  export function _setSessionSwitchInFlight(v) {
26
28
  _sessionSwitchInFlight = v;
27
29
  }
30
+ export function _markSessionSwitchAbortGraceWindow(durationMs = DEFAULT_SESSION_SWITCH_ABORT_GRACE_MS) {
31
+ _sessionSwitchAbortGraceUntil = Math.max(_sessionSwitchAbortGraceUntil, Date.now() + durationMs);
32
+ }
33
+ export function _clearSessionSwitchAbortGraceWindow() {
34
+ _sessionSwitchAbortGraceUntil = 0;
35
+ }
36
+ export function isSessionSwitchAbortGraceActive(now = Date.now()) {
37
+ return now < _sessionSwitchAbortGraceUntil;
38
+ }
28
39
  export function _clearCurrentResolve() {
29
40
  _currentResolve = null;
30
41
  }
@@ -118,6 +129,7 @@ export function _resetPendingResolve() {
118
129
  _currentResolve = null;
119
130
  _sessionSwitchInFlight = false;
120
131
  _pendingSwitchCancellation = null;
132
+ _sessionSwitchAbortGraceUntil = 0;
121
133
  }
122
134
  export function _hasPendingResolveForTest() {
123
135
  return _currentResolve !== null;
@@ -1,6 +1,6 @@
1
1
  // GSD-2 + src/resources/extensions/gsd/auto/run-unit.ts - Runs one GSD auto-mode unit from session creation through agent completion.
2
2
  import { NEW_SESSION_TIMEOUT_MS } from "./session.js";
3
- import { _clearCurrentResolve, _consumePendingSwitchCancellation, _setCurrentResolve, _setSessionSwitchInFlight, } from "./resolve.js";
3
+ import { _clearCurrentResolve, _consumePendingSwitchCancellation, _markSessionSwitchAbortGraceWindow, _setCurrentResolve, _setSessionSwitchInFlight, } from "./resolve.js";
4
4
  import { getCurrentTurnGeneration, runWithTurnGeneration, } from "./turn-epoch.js";
5
5
  import { debugLog } from "../debug-logger.js";
6
6
  import { logWarning } from "../workflow-logger.js";
@@ -35,6 +35,7 @@ export async function runUnit(ctx, pi, s, unitType, unitId, prompt) {
35
35
  workspaceRoot: s.basePath,
36
36
  }).finally(() => {
37
37
  if (sessionSwitchGeneration === mySessionSwitchGeneration) {
38
+ _markSessionSwitchAbortGraceWindow();
38
39
  _setSessionSwitchInFlight(false);
39
40
  }
40
41
  });
@@ -89,6 +90,7 @@ export async function runUnit(ctx, pi, s, unitType, unitId, prompt) {
89
90
  // ── Create the agent_end promise (per-unit one-shot) ──
90
91
  // This happens after newSession completes so session-switch agent_end events
91
92
  // from the previous session cannot resolve the new unit.
93
+ _markSessionSwitchAbortGraceWindow();
92
94
  _setSessionSwitchInFlight(false);
93
95
  const unitPromise = new Promise((resolve) => {
94
96
  _setCurrentResolve(resolve);
@@ -1,7 +1,39 @@
1
1
  // Project/App: GSD-2
2
2
  // File Purpose: Best-effort unit dispatch claim adapter for auto-mode loop.
3
+ export function ensureDispatchLease(s, milestoneId, deps, opts = {}) {
4
+ if (!s.workerId)
5
+ return { kind: "degraded", reason: "missing-worker" };
6
+ if (!milestoneId)
7
+ return { kind: "degraded", reason: "missing-milestone" };
8
+ if (!opts.forceReclaim && typeof s.milestoneLeaseToken === "number") {
9
+ return { kind: "ready", token: s.milestoneLeaseToken, recovered: false };
10
+ }
11
+ s.milestoneLeaseToken = null;
12
+ try {
13
+ const claim = deps.claimMilestoneLease(s.workerId, milestoneId);
14
+ if (!claim.ok) {
15
+ const reason = `Milestone ${milestoneId} is held by worker ${claim.byWorker} until ${claim.expiresAt}.`;
16
+ deps.logLeaseRecoveryFailed({ milestoneId, workerId: s.workerId, reason });
17
+ return { kind: "blocked", reason };
18
+ }
19
+ s.currentMilestoneId = milestoneId;
20
+ s.milestoneLeaseToken = claim.token;
21
+ deps.logLeaseRecovered({
22
+ milestoneId,
23
+ workerId: s.workerId,
24
+ token: claim.token,
25
+ recovered: opts.forceReclaim === true,
26
+ });
27
+ return { kind: "ready", token: claim.token, recovered: opts.forceReclaim === true };
28
+ }
29
+ catch (err) {
30
+ const reason = err instanceof Error ? err.message : String(err);
31
+ deps.logLeaseRecoveryFailed({ milestoneId, workerId: s.workerId, reason });
32
+ return { kind: "failed", reason };
33
+ }
34
+ }
3
35
  export function openDispatchClaim(s, flowId, turnId, iterData, deps) {
4
- if (!s.workerId || s.milestoneLeaseToken === null)
36
+ if (!s.workerId || typeof s.milestoneLeaseToken !== "number")
5
37
  return { kind: "degraded" };
6
38
  const mid = iterData.mid;
7
39
  if (!mid)
@@ -6,7 +6,15 @@ export function maintainWorkerHeartbeat(session, deps) {
6
6
  try {
7
7
  deps.heartbeatAutoWorker(session.workerId);
8
8
  if (session.currentMilestoneId && session.milestoneLeaseToken) {
9
- deps.refreshMilestoneLease(session.workerId, session.currentMilestoneId, session.milestoneLeaseToken);
9
+ const refreshed = deps.refreshMilestoneLease(session.workerId, session.currentMilestoneId, session.milestoneLeaseToken);
10
+ if (!refreshed) {
11
+ deps.logLeaseRefreshMiss?.({
12
+ workerId: session.workerId,
13
+ milestoneId: session.currentMilestoneId,
14
+ fencingToken: session.milestoneLeaseToken,
15
+ });
16
+ session.milestoneLeaseToken = null;
17
+ }
10
18
  }
11
19
  }
12
20
  catch (err) {
@@ -1,3 +1,5 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Auto-mode post-unit git, verification, projection, and hook processing.
1
3
  /**
2
4
  * Post-unit processing for auto-loop — auto-commit, doctor run,
3
5
  * state rebuild, projection checks, DB tool closeout, hooks, triage, and
@@ -70,6 +72,62 @@ function formatPreExecutionCheckDetail(check) {
70
72
  }
71
73
  const COMPLETE_MILESTONE_DB_SETTLE_MS = 1500;
72
74
  const COMPLETE_MILESTONE_DB_SETTLE_POLL_MS = 100;
75
+ function stripKnownIdPrefix(value, id) {
76
+ const raw = String(value ?? "").trim();
77
+ if (!raw)
78
+ return undefined;
79
+ const lower = raw.toLowerCase();
80
+ const idLower = id.toLowerCase();
81
+ if (lower.startsWith(`${idLower}:`))
82
+ return raw.slice(id.length + 1).trim() || undefined;
83
+ return raw;
84
+ }
85
+ async function buildTaskCommitContextForUnit(basePath, unitId) {
86
+ const { milestone: mid, slice: sid, task: tid } = parseUnitId(unitId);
87
+ if (!mid || !sid || !tid)
88
+ return undefined;
89
+ const milestone = isDbAvailable() ? getMilestone(mid) : null;
90
+ const slice = isDbAvailable() ? getSlice(mid, sid) : null;
91
+ const task = isDbAvailable() ? getTask(mid, sid, tid) : null;
92
+ let summary = null;
93
+ const summaryPath = resolveTaskFile(basePath, mid, sid, tid, "SUMMARY");
94
+ if (summaryPath) {
95
+ try {
96
+ const summaryContent = await loadFile(summaryPath);
97
+ if (summaryContent)
98
+ summary = parseSummary(summaryContent);
99
+ }
100
+ catch (e) {
101
+ debugLog("postUnit", { phase: "task-summary-parse", error: String(e) });
102
+ }
103
+ }
104
+ if (!summary && !task)
105
+ return undefined;
106
+ let ghIssueNumber;
107
+ try {
108
+ const { getTaskIssueNumberForCommit } = await import("../github-sync/sync.js");
109
+ ghIssueNumber = getTaskIssueNumberForCommit(basePath, mid, sid, tid) ?? undefined;
110
+ }
111
+ catch (err) {
112
+ logWarning("engine", `GitHub issue lookup failed: ${err instanceof Error ? err.message : String(err)}`);
113
+ }
114
+ return {
115
+ taskId: `${sid}/${tid}`,
116
+ taskDisplayId: tid,
117
+ taskTitle: stripKnownIdPrefix(summary?.title, tid) ??
118
+ stripKnownIdPrefix(task?.title, tid) ??
119
+ tid,
120
+ milestoneId: mid,
121
+ milestoneTitle: stripKnownIdPrefix(milestone?.title, mid),
122
+ sliceId: sid,
123
+ sliceTitle: stripKnownIdPrefix(slice?.title, sid),
124
+ oneLiner: summary?.oneLiner || task?.one_liner || undefined,
125
+ keyFiles: summary?.frontmatter.key_files?.filter(f => !f.includes("{{")) ??
126
+ task?.key_files ??
127
+ undefined,
128
+ issueNumber: ghIssueNumber,
129
+ };
130
+ }
73
131
  async function waitForMilestoneDbClose(mid) {
74
132
  const deadline = Date.now() + COMPLETE_MILESTONE_DB_SETTLE_MS;
75
133
  while (Date.now() < deadline) {
@@ -96,6 +154,19 @@ function enqueueSidecar(s, ctx, entry, debugExtra, notification) {
96
154
  ctx.ui.notify(notification, "info");
97
155
  return "continue";
98
156
  }
157
+ export function _shouldDispatchTriageForTest(state) {
158
+ return !state.stepMode &&
159
+ !!state.currentUnit &&
160
+ !state.currentUnit.type.startsWith("hook/") &&
161
+ state.currentUnit.type !== "triage-captures" &&
162
+ state.currentUnit.type !== "quick-task";
163
+ }
164
+ export function _shouldDispatchQuickTaskForTest(state) {
165
+ return !state.stepMode &&
166
+ state.pendingQuickTasks.length > 0 &&
167
+ !!state.currentUnit &&
168
+ state.currentUnit.type !== "quick-task";
169
+ }
99
170
  /** Unit types that only touch `.gsd/` internal state files (no code changes).
100
171
  * Auto-commit is skipped for these — their state files are picked up by the
101
172
  * next actual task commit via `smartStage()`. */
@@ -216,7 +287,7 @@ export function detectRogueFileWrites(unitType, unitId, basePath) {
216
287
  * in auto-verification.ts. Exceeding this limit pauses auto-mode instead of
217
288
  * looping indefinitely (#2007).
218
289
  */
219
- const MAX_ARTIFACT_VERIFICATION_RETRIES = 3;
290
+ export const MAX_ARTIFACT_VERIFICATION_RETRIES = 3;
220
291
  export const STEP_COMPLETE_FALLBACK_MESSAGE = "Step complete. Run /clear, then /gsd to continue (or /gsd auto to run continuously).";
221
292
  export function buildStepCompleteMessage(nextState) {
222
293
  if (nextState.phase === "complete") {
@@ -267,36 +338,7 @@ export async function autoCommitUnit(basePath, unitType, unitId, ctx) {
267
338
  try {
268
339
  let taskContext;
269
340
  if (unitType === "execute-task") {
270
- const { milestone: mid, slice: sid, task: tid } = parseUnitId(unitId);
271
- if (mid && sid && tid) {
272
- const summaryPath = resolveTaskFile(basePath, mid, sid, tid, "SUMMARY");
273
- if (summaryPath) {
274
- try {
275
- const summaryContent = await loadFile(summaryPath);
276
- if (summaryContent) {
277
- const summary = parseSummary(summaryContent);
278
- let ghIssueNumber;
279
- try {
280
- const { getTaskIssueNumberForCommit } = await import("../github-sync/sync.js");
281
- ghIssueNumber = getTaskIssueNumberForCommit(basePath, mid, sid, tid) ?? undefined;
282
- }
283
- catch (err) {
284
- logWarning("engine", `GitHub issue lookup failed: ${err instanceof Error ? err.message : String(err)}`);
285
- }
286
- taskContext = {
287
- taskId: `${sid}/${tid}`,
288
- taskTitle: summary.title?.replace(/^T\d+:\s*/, "") || tid,
289
- oneLiner: summary.oneLiner || undefined,
290
- keyFiles: summary.frontmatter.key_files?.filter(f => !f.includes("{{")) || undefined,
291
- issueNumber: ghIssueNumber,
292
- };
293
- }
294
- }
295
- catch (e) {
296
- debugLog("postUnit", { phase: "task-summary-parse", error: String(e) });
297
- }
298
- }
299
- }
341
+ taskContext = await buildTaskCommitContextForUnit(basePath, unitId);
300
342
  }
301
343
  _resetHasChangesCache();
302
344
  if (LIFECYCLE_ONLY_UNITS.has(unitType)) {
@@ -359,38 +401,7 @@ export async function postUnitPreVerification(pctx, opts) {
359
401
  try {
360
402
  let taskContext;
361
403
  if (turnAction === "commit" && s.currentUnit.type === "execute-task") {
362
- const { milestone: mid, slice: sid, task: tid } = parseUnitId(s.currentUnit.id);
363
- if (mid && sid && tid) {
364
- const summaryPath = resolveTaskFile(s.basePath, mid, sid, tid, "SUMMARY");
365
- if (summaryPath) {
366
- try {
367
- const summaryContent = await loadFile(summaryPath);
368
- if (summaryContent) {
369
- const summary = parseSummary(summaryContent);
370
- // Look up GitHub issue number for commit linking
371
- let ghIssueNumber;
372
- try {
373
- const { getTaskIssueNumberForCommit } = await import("../github-sync/sync.js");
374
- ghIssueNumber = getTaskIssueNumberForCommit(s.basePath, mid, sid, tid) ?? undefined;
375
- }
376
- catch (err) {
377
- // GitHub sync not available — skip
378
- logWarning("engine", `GitHub issue lookup failed: ${err instanceof Error ? err.message : String(err)}`);
379
- }
380
- taskContext = {
381
- taskId: `${sid}/${tid}`,
382
- taskTitle: summary.title?.replace(/^T\d+:\s*/, "") || tid,
383
- oneLiner: summary.oneLiner || undefined,
384
- keyFiles: summary.frontmatter.key_files?.filter(f => !f.includes("{{")) || undefined,
385
- issueNumber: ghIssueNumber,
386
- };
387
- }
388
- }
389
- catch (e) {
390
- debugLog("postUnit", { phase: "task-summary-parse", error: String(e) });
391
- }
392
- }
393
- }
404
+ taskContext = await buildTaskCommitContextForUnit(s.basePath, s.currentUnit.id);
394
405
  }
395
406
  // Invalidate the nativeHasChanges cache before auto-commit (#1853).
396
407
  // The cache has a 10-second TTL and is keyed by basePath. A stale
@@ -1123,10 +1134,11 @@ export async function postUnitPostVerification(pctx) {
1123
1134
  return;
1124
1135
  }
1125
1136
  const strictMode = prefs?.enhanced_verification_strict === true;
1126
- // Run pre-execution checks against the canonical project root. In
1127
- // worktree isolation, s.basePath can point at a metadata-only worktree,
1128
- // while source files remain under the project root.
1129
- const preExecutionBasePath = s.canonicalProjectRoot;
1137
+ // Run pre-execution checks against s.basePath the actual checkout
1138
+ // where prior-slice files were created. In worktree isolation,
1139
+ // s.canonicalProjectRoot is the project root and lacks files that a
1140
+ // prior slice wrote to the worktree but hasn't merged to main yet.
1141
+ const preExecutionBasePath = s.basePath;
1130
1142
  const result = await runPreExecutionChecks(tasks, preExecutionBasePath);
1131
1143
  // Log summary to stderr in existing verification output format
1132
1144
  const emoji = result.status === "pass" ? "✅" : result.status === "warn" ? "⚠️" : "❌";
@@ -1266,11 +1278,7 @@ export async function postUnitPostVerification(pctx) {
1266
1278
  }
1267
1279
  }
1268
1280
  // ── Triage check ──
1269
- if (!s.stepMode &&
1270
- s.currentUnit &&
1271
- !s.currentUnit.type.startsWith("hook/") &&
1272
- s.currentUnit.type !== "triage-captures" &&
1273
- s.currentUnit.type !== "quick-task") {
1281
+ if (_shouldDispatchTriageForTest(s)) {
1274
1282
  try {
1275
1283
  if (hasPendingCaptures(s.basePath)) {
1276
1284
  const pending = loadPendingCaptures(s.basePath);
@@ -1308,10 +1316,7 @@ export async function postUnitPostVerification(pctx) {
1308
1316
  }
1309
1317
  }
1310
1318
  // ── Quick-task dispatch ──
1311
- if (!s.stepMode &&
1312
- s.pendingQuickTasks.length > 0 &&
1313
- s.currentUnit &&
1314
- s.currentUnit.type !== "quick-task") {
1319
+ if (_shouldDispatchQuickTaskForTest(s)) {
1315
1320
  try {
1316
1321
  const capture = s.pendingQuickTasks.shift();
1317
1322
  const { buildQuickTaskPrompt } = await import("./triage-resolution.js");
@@ -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
  *
@@ -44,6 +46,11 @@ import { resolveProjectRootDbPath } from "./bootstrap/dynamic-tools.js";
44
46
  import { validateDirectory } from "./validate-directory.js";
45
47
  import { isCustomProvider, resolveDefaultSessionModel, resolveDynamicRoutingConfig, } from "./preferences-models.js";
46
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
+ }
47
54
  /**
48
55
  * Bootstrap a fresh auto-mode session. Handles everything from git init
49
56
  * through secrets collection, returning when ready for the first
@@ -55,6 +62,12 @@ import { getSessionModelOverride } from "./session-model-override.js";
55
62
  // Guard constant for consecutive bootstrap attempts that found phase === "complete".
56
63
  // Counter moved to AutoSession.consecutiveCompleteBootstraps so s.reset() clears it.
57
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
+ }
58
71
  export async function openProjectDbIfPresent(basePath) {
59
72
  const gsdDbPath = resolveProjectRootDbPath(basePath);
60
73
  if (!existsSync(gsdDbPath) || isDbAvailable())
@@ -670,7 +683,26 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
670
683
  {
671
684
  const orphan = findUnmergedCompletedMilestone(base, getIsolationMode(base));
672
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;
673
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
+ }
674
706
  if (result.merged) {
675
707
  invalidateAllCaches();
676
708
  state = await deriveState(base);
@@ -797,13 +829,16 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
797
829
  // Guard against stale milestone branch when isolation:none (#3613).
798
830
  // A prior session with isolation:branch/worktree may have left HEAD on
799
831
  // milestone/<MID>. Auto-checkout back to the integration branch.
800
- if (getIsolationMode(base) === "none" && nativeIsRepo(base)) {
832
+ const isolationMode = getIsolationMode(base);
833
+ const isRepo = nativeIsRepo(base);
834
+ if (isolationMode === "none" && isRepo) {
801
835
  try {
802
836
  const currentBranch = nativeGetCurrentBranch(base);
803
- if (currentBranch.startsWith("milestone/")) {
804
- const integrationBranch = nativeDetectMainBranch(base);
805
- nativeCheckoutBranch(base, integrationBranch);
806
- 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).`);
807
842
  }
808
843
  }
809
844
  catch (err) {
@@ -848,7 +883,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
848
883
  logError("engine", `failed to initialize project database: ${err.message}`);
849
884
  }
850
885
  }
851
- if (existsSync(gsdDbPath) && !isDbAvailable()) {
886
+ if (_shouldAbortBootstrapForUnavailableDbForTest(gsdDbPath, isDbAvailable())) {
852
887
  try {
853
888
  const { openDatabase: openDb } = await import("./gsd-db.js");
854
889
  openDb(gsdDbPath);