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
@@ -1,65 +1,29 @@
1
- /**
2
- * sqlite-unavailable-gate.test.ts — #2419
3
- *
4
- * When the SQLite provider fails to open, bootstrapAutoSession must
5
- * refuse to start auto-mode. Otherwise gsd_task_complete returns
6
- * "db_unavailable", artifact retry re-dispatches the same task, and
7
- * the session loops forever.
8
- *
9
- * This test verifies the gate by reading auto-start.ts source and
10
- * confirming the pattern: after the DB lifecycle block, if the DB
11
- * file exists on disk but isDbAvailable() still returns false after
12
- * the open attempt, bootstrap must abort with an error notification.
13
- */
1
+ // GSD-2 — SQLite unavailable bootstrap gate regression tests.
14
2
 
15
- import { readFileSync } from "node:fs";
16
- import { join } from "node:path";
17
- import { createTestContext } from "./test-helpers.ts";
3
+ import test from "node:test";
4
+ import assert from "node:assert/strict";
18
5
 
19
- const { assertTrue, report } = createTestContext();
6
+ import { _shouldAbortBootstrapForUnavailableDbForTest } from "../auto-start.ts";
20
7
 
21
- const srcPath = join(import.meta.dirname, "..", "auto-start.ts");
22
- const src = readFileSync(srcPath, "utf-8");
8
+ test("bootstrap abort gate trips when DB exists but SQLite remains unavailable", () => {
9
+ const dbPath = "/repo/.gsd/gsd.db";
10
+ const exists = (path: string) => path === dbPath;
23
11
 
24
- console.log("\n=== #2419: SQLite unavailable gate in auto-start.ts ===");
25
-
26
- // The DB lifecycle section tries to open the DB. After those try/catch
27
- // blocks, there must be a HARD GATE: if the DB file exists on disk but
28
- // isDbAvailable() is still false (open failed), bootstrap must abort
29
- // by calling releaseLockAndReturn() with an error notification.
30
-
31
- const dbLifecycleIdx = src.indexOf("DB lifecycle");
32
- assertTrue(dbLifecycleIdx > 0, "auto-start.ts has a DB lifecycle section");
33
-
34
- const afterDbLifecycle = src.slice(dbLifecycleIdx);
35
-
36
- // The DB lifecycle section may contain multiple isDbAvailable() checks now that
37
- // cold-start bootstrap can pre-open the DB earlier in the file. What matters
38
- // for #2419 is the explicit abort gate after the DB open attempts.
39
- assertTrue(
40
- afterDbLifecycle.includes("!isDbAvailable()"),
41
- "DB lifecycle section still checks for unavailable DB state (#2419)",
42
- );
43
-
44
- const gateMatch = afterDbLifecycle.match(
45
- /if\s*\(existsSync\(gsdDbPath\)\s*&&\s*!isDbAvailable\(\)\)\s*\{[\s\S]*?releaseLockAndReturn\(\);[\s\S]*?\}/,
46
- );
12
+ assert.equal(
13
+ _shouldAbortBootstrapForUnavailableDbForTest(dbPath, false, exists),
14
+ true,
15
+ );
16
+ });
47
17
 
48
- assertTrue(
49
- !!gateMatch,
50
- "auto-start.ts has a hard abort gate when gsd.db exists but SQLite is still unavailable (#2419)",
51
- );
18
+ test("bootstrap abort gate stays open when DB is available or absent", () => {
19
+ const dbPath = "/repo/.gsd/gsd.db";
52
20
 
53
- if (gateMatch) {
54
- const gateRegion = gateMatch[0];
55
- assertTrue(
56
- gateRegion.includes("releaseLockAndReturn"),
57
- "The DB availability gate calls releaseLockAndReturn() to abort bootstrap (#2419)",
21
+ assert.equal(
22
+ _shouldAbortBootstrapForUnavailableDbForTest(dbPath, true, () => true),
23
+ false,
58
24
  );
59
- assertTrue(
60
- /database|sqlite|db.*unavailable/i.test(gateRegion),
61
- "The DB availability gate includes a user-facing error message about the database (#2419)",
25
+ assert.equal(
26
+ _shouldAbortBootstrapForUnavailableDbForTest(dbPath, false, () => false),
27
+ false,
62
28
  );
63
- }
64
-
65
- report();
29
+ });
@@ -1,38 +1,15 @@
1
1
  /**
2
- * GSD-2 / agent-end-recovery — regression tests for #4648
3
- *
4
- * Covers the stale `dirListCache` bug where `maybeHandleReadyPhraseWithoutFiles`
5
- * (and `checkAutoStartAfterDiscuss`) falsely reported milestone artifacts as
6
- * missing, because the directory-listing cache in `paths.ts` was populated
7
- * before the LLM wrote the files during the same turn.
8
- *
9
- * The fix invalidates the cache at the top of `handleAgentEnd`, before any
10
- * artifact-existence check runs.
2
+ * GSD-2 / agent-end-recovery — regression tests for #4648.
11
3
  */
12
4
 
13
5
  import { describe, test } from "node:test";
14
6
  import assert from "node:assert/strict";
15
- import {
16
- mkdtempSync,
17
- mkdirSync,
18
- rmSync,
19
- writeFileSync,
20
- readFileSync,
21
- } from "node:fs";
22
- import { join, dirname } from "node:path";
7
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
8
+ import { join } from "node:path";
23
9
  import { tmpdir } from "node:os";
24
- import { fileURLToPath } from "node:url";
25
10
 
26
- import { resolveMilestoneFile } from "../paths.ts";
27
- import { clearPathCache } from "../paths.ts";
28
-
29
- const __dirname = dirname(fileURLToPath(import.meta.url));
30
- const AGENT_END_RECOVERY_PATH = join(
31
- __dirname,
32
- "..",
33
- "bootstrap",
34
- "agent-end-recovery.ts",
35
- );
11
+ import { handleAgentEnd } from "../bootstrap/agent-end-recovery.ts";
12
+ import { resolveMilestoneFile, clearPathCache } from "../paths.ts";
36
13
 
37
14
  function mkBase(): string {
38
15
  const base = mkdtempSync(join(tmpdir(), "gsd-4648-"));
@@ -40,73 +17,49 @@ function mkBase(): string {
40
17
  return base;
41
18
  }
42
19
 
43
- describe("#4648 stale dirListCache — behavioral", () => {
20
+ describe("#4648 stale dirListCache", () => {
44
21
  test("resolveMilestoneFile returns stale null until clearPathCache runs", () => {
45
22
  const base = mkBase();
46
23
  try {
47
24
  clearPathCache();
25
+ assert.equal(resolveMilestoneFile(base, "M001", "CONTEXT"), null);
48
26
 
49
- // Prime the cache: directory exists but is empty at this point.
50
- assert.equal(
51
- resolveMilestoneFile(base, "M001", "CONTEXT"),
52
- null,
53
- "empty dir → null",
54
- );
55
-
56
- // Simulate the LLM writing CONTEXT.md during the turn.
57
27
  writeFileSync(
58
28
  join(base, ".gsd", "milestones", "M001", "M001-CONTEXT.md"),
59
29
  "# M001 Context\n",
60
30
  );
61
31
 
62
- // Without a cache flush the resolver still reports null — this is the bug.
63
- assert.equal(
64
- resolveMilestoneFile(base, "M001", "CONTEXT"),
65
- null,
66
- "stale cache returns null even though the file exists on disk",
67
- );
68
-
69
- // The fix: clearPathCache() — after which the resolver finds the file.
32
+ assert.equal(resolveMilestoneFile(base, "M001", "CONTEXT"), null);
70
33
  clearPathCache();
71
- const resolved = resolveMilestoneFile(base, "M001", "CONTEXT");
72
- assert.ok(
73
- resolved && /M001-CONTEXT\.md$/.test(resolved),
74
- `after clearPathCache, resolver finds the file (got: ${resolved})`,
75
- );
34
+ assert.match(resolveMilestoneFile(base, "M001", "CONTEXT") ?? "", /M001-CONTEXT\.md$/);
76
35
  } finally {
77
36
  clearPathCache();
78
37
  rmSync(base, { recursive: true, force: true });
79
38
  }
80
39
  });
81
- });
82
-
83
- describe("#4648 agent-end-recovery wiring", () => {
84
- test("handleAgentEnd invalidates the path cache before the discuss guards", () => {
85
- const source = readFileSync(AGENT_END_RECOVERY_PATH, "utf-8");
86
40
 
87
- assert.ok(
88
- /import\s*\{\s*clearPathCache\s*\}\s*from\s*"\.\.\/paths\.js"/.test(source),
89
- "agent-end-recovery.ts must import clearPathCache from ../paths.js",
90
- );
41
+ test("handleAgentEnd invalidates the path cache before recovery guards read artifacts", async () => {
42
+ const base = mkBase();
43
+ const previousCwd = process.cwd();
44
+ try {
45
+ process.chdir(base);
46
+ clearPathCache();
47
+ assert.equal(resolveMilestoneFile(base, "M001", "CONTEXT"), null);
91
48
 
92
- const fnStart = source.indexOf("export async function handleAgentEnd");
93
- assert.ok(fnStart > -1, "handleAgentEnd must exist");
49
+ writeFileSync(
50
+ join(base, ".gsd", "milestones", "M001", "M001-CONTEXT.md"),
51
+ "# M001 Context\n",
52
+ );
94
53
 
95
- const checkIdx = source.indexOf("checkAutoStartAfterDiscuss(", fnStart);
96
- const clearIdx = source.indexOf("clearPathCache(", fnStart);
97
- const readyIdx = source.indexOf(
98
- "maybeHandleReadyPhraseWithoutFiles(",
99
- fnStart,
100
- );
54
+ await handleAgentEnd({} as any, { messages: [] }, {
55
+ ui: { notify: () => {} },
56
+ } as any);
101
57
 
102
- assert.ok(clearIdx > -1, "handleAgentEnd must call clearPathCache");
103
- assert.ok(
104
- clearIdx < checkIdx,
105
- "clearPathCache must run before checkAutoStartAfterDiscuss so the guard sees fresh disk state",
106
- );
107
- assert.ok(
108
- clearIdx < readyIdx,
109
- "clearPathCache must run before maybeHandleReadyPhraseWithoutFiles",
110
- );
58
+ assert.match(resolveMilestoneFile(base, "M001", "CONTEXT") ?? "", /M001-CONTEXT\.md$/);
59
+ } finally {
60
+ process.chdir(previousCwd);
61
+ clearPathCache();
62
+ rmSync(base, { recursive: true, force: true });
63
+ }
111
64
  });
112
65
  });
@@ -1,36 +1,45 @@
1
1
  /**
2
- * stale-lockfile-recovery.test.ts — #3668
3
- *
4
- * Verify that session-lock.ts contains pre-flight stale lock cleanup logic
5
- * that removes orphaned lock directories when the owning PID is dead,
6
- * preventing the 30-min stale window from blocking /gsd after crashes.
2
+ * stale-lockfile-recovery.test.ts — #3668.
7
3
  */
8
4
 
9
- import { describe, test } from "node:test";
5
+ import { describe, test, afterEach } from "node:test";
10
6
  import assert from "node:assert/strict";
11
- import { readFileSync } from "node:fs";
12
- import { join, dirname } from "node:path";
13
- import { fileURLToPath } from "node:url";
7
+ import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
8
+ import { join } from "node:path";
9
+ import { tmpdir } from "node:os";
14
10
 
15
- const __dirname = dirname(fileURLToPath(import.meta.url));
16
- const sourceFile = join(__dirname, "..", "session-lock.ts");
11
+ import { acquireSessionLock, releaseSessionLock } from "../session-lock.ts";
17
12
 
18
- describe("stale lockfile auto-recovery (#3668)", () => {
19
- const source = readFileSync(sourceFile, "utf-8");
13
+ let tempBase: string | null = null;
20
14
 
21
- test("checks for orphan lock with isPidAlive", () => {
22
- assert.match(source, /isPidAlive\(existingData\.pid\)/);
23
- });
15
+ afterEach(() => {
16
+ if (tempBase) {
17
+ releaseSessionLock(tempBase);
18
+ rmSync(tempBase, { recursive: true, force: true });
19
+ }
20
+ tempBase = null;
21
+ });
24
22
 
25
- test("removes stale lock directory with rmSync", () => {
26
- assert.match(source, /rmSync\(lockDir,\s*\{\s*recursive:\s*true/);
27
- });
23
+ describe("stale lockfile auto-recovery (#3668)", () => {
24
+ test("acquireSessionLock removes an orphan proper-lockfile directory before acquiring", () => {
25
+ tempBase = mkdtempSync(join(tmpdir(), "gsd-stale-lock-"));
26
+ const gsdDir = join(tempBase, ".gsd");
27
+ mkdirSync(join(gsdDir, "auto.lock.lock"), { recursive: true });
28
+ writeFileSync(
29
+ join(gsdDir, "auto.lock"),
30
+ JSON.stringify({
31
+ pid: 999_999_999,
32
+ startedAt: new Date().toISOString(),
33
+ unitType: "execute-task",
34
+ unitId: "M001/S01/T01",
35
+ unitStartedAt: new Date().toISOString(),
36
+ }),
37
+ "utf-8",
38
+ );
28
39
 
29
- test("references issue #3218 in pre-flight cleanup comment", () => {
30
- assert.match(source, /#3218.*Pre-flight stale lock cleanup/);
31
- });
40
+ const result = acquireSessionLock(tempBase);
32
41
 
33
- test("provides actionable rm -rf workaround in error message", () => {
34
- assert.match(source, /rm\s+-rf/);
42
+ assert.equal(result.acquired, true);
43
+ assert.equal(existsSync(join(gsdDir, "auto.lock.lock")), true, "new active lock directory is present");
35
44
  });
36
45
  });
@@ -1,40 +1,49 @@
1
1
  /**
2
- * stale-slice-rows.test.ts
3
- *
4
- * Verify that state.ts no longer treats slice SUMMARY.md projections as
5
- * authority for DB slice status. Slice rows must be updated through DB-backed
6
- * completion/import APIs.
2
+ * Verify that state derivation treats DB slice rows as authoritative over
3
+ * stale markdown projections.
7
4
  */
8
5
 
9
- import { describe, test } from "node:test";
6
+ import { describe, test, afterEach } from "node:test";
10
7
  import assert from "node:assert/strict";
11
- import { readFileSync } from "node:fs";
12
- import { join, dirname } from "node:path";
13
- import { fileURLToPath } from "node:url";
8
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
9
+ import { join } from "node:path";
10
+ import { tmpdir } from "node:os";
14
11
 
15
- const __dirname = dirname(fileURLToPath(import.meta.url));
16
- const sourceFile = join(__dirname, "..", "state.ts");
12
+ import { deriveState, invalidateStateCache } from "../state.ts";
13
+ import { closeDatabase, insertMilestone, insertSlice, openDatabase } from "../gsd-db.ts";
17
14
 
18
- describe("stale slice row DB-authoritative boundary", () => {
19
- const source = readFileSync(sourceFile, "utf-8");
20
-
21
- test("does not import updateSliceStatus into state derivation", () => {
22
- assert.doesNotMatch(source, /import\s*\{[^}]*updateSliceStatus[^}]*\}\s*from/);
23
- });
24
-
25
- test("does not scan DB slice rows for disk SUMMARY reconciliation", () => {
26
- assert.doesNotMatch(source, /dbSlice/);
27
- });
15
+ let tempBase: string | null = null;
28
16
 
29
- test("does not resolve slice SUMMARY to mutate DB state", () => {
30
- assert.doesNotMatch(source, /resolveSliceFile\(basePath,\s*mid,\s*dbSlice\.id,\s*["']SUMMARY["']\)/);
31
- });
32
-
33
- test("does not call updateSliceStatus from state derivation", () => {
34
- assert.doesNotMatch(source, /updateSliceStatus\(/);
35
- });
17
+ afterEach(() => {
18
+ closeDatabase();
19
+ invalidateStateCache();
20
+ if (tempBase) rmSync(tempBase, { recursive: true, force: true });
21
+ tempBase = null;
22
+ });
36
23
 
37
- test("documents markdown projections as non-authoritative", () => {
38
- assert.match(source, /Markdown files are projections only/);
24
+ describe("stale slice row DB-authoritative boundary", () => {
25
+ test("a stale SUMMARY.md projection does not make a DB-pending slice complete", async () => {
26
+ tempBase = mkdtempSync(join(tmpdir(), "gsd-stale-slice-"));
27
+ const sliceDir = join(tempBase, ".gsd", "milestones", "M001", "slices", "S01");
28
+ mkdirSync(sliceDir, { recursive: true });
29
+ writeFileSync(join(sliceDir, "S01-SUMMARY.md"), "# S01 Summary\n", "utf-8");
30
+
31
+ openDatabase(join(tempBase, ".gsd", "gsd.db"));
32
+ insertMilestone({ id: "M001", title: "DB authority", status: "active", depends_on: [] });
33
+ insertSlice({
34
+ id: "S01",
35
+ milestoneId: "M001",
36
+ title: "Still pending",
37
+ status: "pending",
38
+ risk: "low",
39
+ depends: [],
40
+ demo: "",
41
+ sequence: 1,
42
+ });
43
+
44
+ const state = await deriveState(tempBase);
45
+
46
+ assert.equal(state.activeSlice?.id, "S01");
47
+ assert.equal(state.phase, "planning");
39
48
  });
40
49
  });
@@ -1,56 +1,42 @@
1
1
  /**
2
- * Regression test for #3691 — /gsd status opens DB before deriveState
3
- *
4
- * In cold sessions the DB was not opened before deriveState, causing
5
- * status to fall back to filesystem-only state. The fix adds an
6
- * ensureDbOpen() call before deriveState in handleStatus.
7
- *
8
- * Also verifies that quick.ts checks getIsolationMode before branching.
2
+ * Regression tests for status/quick behavior.
9
3
  */
10
4
 
11
- import { describe, test } from 'node:test';
12
- import assert from 'node:assert/strict';
13
- import { readFileSync } from 'node:fs';
14
- import { fileURLToPath } from 'node:url';
15
- import { dirname, join } from 'node:path';
16
-
17
- const __filename = fileURLToPath(import.meta.url);
18
- const __dirname = dirname(__filename);
19
-
20
- const coreSrc = readFileSync(
21
- join(__dirname, '..', 'commands', 'handlers', 'core.ts'),
22
- 'utf-8',
23
- );
24
- const quickSrc = readFileSync(
25
- join(__dirname, '..', 'quick.ts'),
26
- 'utf-8',
27
- );
28
-
29
- describe('status opens DB before deriveState (#3691)', () => {
30
- test('handleStatus calls ensureDbOpen before deriveState', () => {
31
- const ensureIdx = coreSrc.indexOf('ensureDbOpen');
32
- const deriveIdx = coreSrc.indexOf('deriveState(basePath)');
33
- assert.ok(ensureIdx > -1, 'ensureDbOpen call should exist in core.ts');
34
- assert.ok(deriveIdx > -1, 'deriveState(basePath) call should exist in core.ts');
35
- assert.ok(
36
- ensureIdx < deriveIdx,
37
- 'ensureDbOpen must appear before deriveState so DB is ready',
38
- );
5
+ import { describe, test } from "node:test";
6
+ import assert from "node:assert/strict";
7
+
8
+ import { handleCoreCommand } from "../commands/handlers/core.ts";
9
+ import { buildQuickCommitInstruction } from "../quick.ts";
10
+
11
+ describe("status opens DB before deriveState (#3691)", () => {
12
+ test("core handler routes status command", async () => {
13
+ const notifications: Array<{ message: string; level: string }> = [];
14
+ const ctx = {
15
+ ui: {
16
+ custom: async () => undefined,
17
+ notify: (message: string, level: string) => {
18
+ notifications.push({ message, level });
19
+ },
20
+ },
21
+ };
22
+
23
+ const handled = await handleCoreCommand("status", ctx as any);
24
+
25
+ assert.equal(handled, true);
26
+ assert.ok(notifications.length >= 0);
39
27
  });
40
28
 
41
- test('quick.ts checks getIsolationMode before branching', () => {
42
- assert.match(quickSrc, /getIsolationMode\(\)/,
43
- 'quick.ts should call getIsolationMode()');
44
- assert.match(quickSrc, /getIsolationMode\(\)\s*!==\s*"none"/,
45
- 'quick.ts should compare isolation mode against "none"');
29
+ test("quick task commit instructions handle external .gsd roots without staging quick files", () => {
30
+ const instruction = buildQuickCommitInstruction("/project", "/external/.gsd");
31
+
32
+ assert.match(instruction, /do not stage or commit `\.gsd\/quick\/\.\.\.`/);
33
+ assert.match(instruction, /nothing in the project repo to commit/);
46
34
  });
47
35
 
48
- test('quick task prompt handles external .gsd without staging quick files', () => {
49
- assert.match(quickSrc, /isExternalGsdRoot/,
50
- 'quick.ts should detect whether .gsd resolves outside the project repo');
51
- assert.match(quickSrc, /do not stage or commit `\.gsd\/quick\/\.\.\.`/,
52
- 'external-state quick tasks must tell the agent not to stage .gsd/quick files');
53
- assert.match(quickSrc, /nothing in the project repo to commit/,
54
- 'external-state quick tasks should allow summary-only work without a git commit');
36
+ test("quick task commit instructions include normal commit guidance for in-project .gsd roots", () => {
37
+ const instruction = buildQuickCommitInstruction("/project", "/project/.gsd");
38
+
39
+ assert.doesNotMatch(instruction, /nothing in the project repo to commit/);
40
+ assert.match(instruction, /Commit your changes atomically/);
55
41
  });
56
42
  });
@@ -1,5 +1,7 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Stop-auto worktree exit strategy regression tests.
1
3
  /**
2
- * stop-auto-merge-back.test.ts — Regression test for #2317.
4
+ * stop-auto-merge-back.test.ts — Regression test for #5576.
3
5
  *
4
6
  * When auto-mode stops after a milestone is complete, stopAuto should trigger
5
7
  * merge-back (mergeAndExit) instead of just exiting the worktree with
@@ -9,59 +11,59 @@
9
11
 
10
12
  import test from "node:test";
11
13
  import assert from "node:assert/strict";
12
- import { readFileSync } from "node:fs";
13
- import { join } from "node:path";
14
+ import { _selectStopAutoWorktreeExit } from "../auto.ts";
14
15
 
15
- // ─── Source analysis: stopAuto calls mergeAndExit for complete milestones ────
16
-
17
- const autoSrcPath = join(import.meta.dirname, "..", "auto.ts");
18
- const autoSrc = readFileSync(autoSrcPath, "utf-8");
19
-
20
- test("#2317: stopAuto should check milestone completion status before choosing exit strategy", () => {
21
- // stopAuto Step 4 should NOT unconditionally call exitMilestone(preserveBranch: true).
22
- // It should check if the milestone is complete and call mergeAndExit instead.
23
-
24
- // Find the Step 4 section
25
- const step4Idx = autoSrc.indexOf("Step 4: Auto-worktree exit");
26
- assert.ok(step4Idx !== -1, "Step 4 comment exists in stopAuto");
27
-
28
- // Extract a reasonable window around Step 4 (up to Step 5)
29
- const step5Idx = autoSrc.indexOf("Step 5:", step4Idx);
30
- const step4Block = autoSrc.slice(step4Idx, step5Idx);
31
-
32
- // The fix: Step 4 should call mergeAndExit when milestone is complete
33
- assert.ok(
34
- step4Block.includes("mergeAndExit"),
35
- "Step 4 should call mergeAndExit for completed milestones",
16
+ test("#5576: stopAuto should check milestone completion status before choosing exit strategy", () => {
17
+ assert.equal(
18
+ _selectStopAutoWorktreeExit({
19
+ currentMilestoneId: "M001",
20
+ milestoneComplete: true,
21
+ milestoneMergedInPhases: false,
22
+ }),
23
+ "merge",
36
24
  );
37
25
  });
38
26
 
39
- test("#2317: stopAuto should detect milestone completion via SUMMARY file or DB", () => {
40
- const step4Idx = autoSrc.indexOf("Step 4: Auto-worktree exit");
41
- const step5Idx = autoSrc.indexOf("Step 5:", step4Idx);
42
- const step4Block = autoSrc.slice(step4Idx, step5Idx);
43
-
44
- // Should check completion status — either via SUMMARY file, DB getMilestone, or phase
45
- const checksCompletion =
46
- step4Block.includes("SUMMARY") ||
47
- step4Block.includes("getMilestone") ||
48
- step4Block.includes("complete") ||
49
- step4Block.includes("isMilestoneComplete");
27
+ test("#5576: stopAuto still preserves branch for incomplete milestones", () => {
28
+ assert.equal(
29
+ _selectStopAutoWorktreeExit({
30
+ currentMilestoneId: "M001",
31
+ milestoneComplete: false,
32
+ milestoneMergedInPhases: false,
33
+ }),
34
+ "preserve",
35
+ );
36
+ });
50
37
 
51
- assert.ok(
52
- checksCompletion,
53
- "Step 4 should check if milestone is complete before deciding exit strategy",
38
+ test("#5576: stopAuto does not merge a milestone already merged in phases", () => {
39
+ assert.equal(
40
+ _selectStopAutoWorktreeExit({
41
+ currentMilestoneId: "M001",
42
+ milestoneComplete: true,
43
+ milestoneMergedInPhases: true,
44
+ }),
45
+ "none",
54
46
  );
55
47
  });
56
48
 
57
- test("#2317: stopAuto still preserves branch for incomplete milestones", () => {
58
- const step4Idx = autoSrc.indexOf("Step 4: Auto-worktree exit");
59
- const step5Idx = autoSrc.indexOf("Step 5:", step4Idx);
60
- const step4Block = autoSrc.slice(step4Idx, step5Idx);
49
+ test("#5576: stopAuto skips worktree teardown when no milestone is active", () => {
50
+ assert.equal(
51
+ _selectStopAutoWorktreeExit({
52
+ currentMilestoneId: null,
53
+ milestoneComplete: true,
54
+ milestoneMergedInPhases: false,
55
+ }),
56
+ "none",
57
+ );
58
+ });
61
59
 
62
- // preserveBranch should still be used as fallback for non-complete milestones
63
- assert.ok(
64
- step4Block.includes("preserveBranch"),
65
- "Step 4 should still preserve branch for incomplete milestones (fallback path)",
60
+ test("#5576: stopAuto returns none when phases are already merged even if milestone is not flagged complete", () => {
61
+ assert.equal(
62
+ _selectStopAutoWorktreeExit({
63
+ currentMilestoneId: "M001",
64
+ milestoneComplete: false,
65
+ milestoneMergedInPhases: true,
66
+ }),
67
+ "none",
66
68
  );
67
69
  });