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,37 +1,27 @@
1
- import { readFileSync } from "node:fs";
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtempSync, mkdirSync, realpathSync, rmSync } from "node:fs";
2
4
  import { join } from "node:path";
5
+ import { tmpdir } from "node:os";
3
6
 
4
- import {createTestContext, extractSourceRegion } from "./test-helpers.ts";
7
+ import { openProjectDbIfPresent } from "../auto-start.ts";
8
+ import { closeDatabase, isDbAvailable, openDatabase } from "../gsd-db.ts";
5
9
 
6
- const { assertTrue, report } = createTestContext();
10
+ test.afterEach(() => {
11
+ if (isDbAvailable()) closeDatabase();
12
+ });
7
13
 
8
- const srcPath = join(import.meta.dirname, "..", "auto-start.ts");
9
- const src = readFileSync(srcPath, "utf-8");
14
+ test("#2841: cold DB bootstrap opens an existing project database before state derivation", async (t) => {
15
+ const base = realpathSync(mkdtempSync(join(tmpdir(), "gsd-cold-db-")));
16
+ t.after(() => rmSync(base, { recursive: true, force: true }));
17
+ mkdirSync(join(base, ".gsd"), { recursive: true });
18
+ const dbPath = join(base, ".gsd", "gsd.db");
10
19
 
11
- console.log("\n=== #2841: cold DB opened before initial deriveState ===");
20
+ assert.equal(openDatabase(dbPath), true);
21
+ closeDatabase();
22
+ assert.equal(isDbAvailable(), false);
12
23
 
13
- const helperIdx = src.indexOf("async function openProjectDbIfPresent");
14
- assertTrue(helperIdx >= 0, "auto-start.ts defines a helper for pre-derive DB open (#2841)");
24
+ await openProjectDbIfPresent(base);
15
25
 
16
- const helperRegion = helperIdx >= 0 ? extractSourceRegion(src, "async function openProjectDbIfPresent") : "";
17
- assertTrue(
18
- helperRegion.includes("resolveProjectRootDbPath(basePath)"),
19
- "pre-derive DB helper resolves the project-root DB path (#2841)",
20
- );
21
- assertTrue(
22
- helperRegion.includes("openDatabase(gsdDbPath)"),
23
- "pre-derive DB helper opens the resolved DB path (#2841)",
24
- );
25
-
26
- const firstDeriveIdx = src.indexOf("let state = await deriveState(base);");
27
- assertTrue(firstDeriveIdx > 0, "auto-start.ts has the initial deriveState(base) call");
28
-
29
- const preDeriveRegion = firstDeriveIdx > 0 ? src.slice(0, firstDeriveIdx) : "";
30
- const preDeriveOpenIdx = preDeriveRegion.lastIndexOf("await openProjectDbIfPresent(base);");
31
-
32
- assertTrue(
33
- preDeriveOpenIdx > 0,
34
- "bootstrapAutoSession opens the DB before the first deriveState(base) call (#2841)",
35
- );
36
-
37
- report();
26
+ assert.equal(isDbAvailable(), true);
27
+ });
@@ -1,38 +1,26 @@
1
1
  import test from "node:test";
2
2
  import assert from "node:assert/strict";
3
- import { readFileSync } from "node:fs";
3
+ import { existsSync, mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
+ import { tmpdir } from "node:os";
5
6
 
6
- const sourcePath = join(import.meta.dirname, "..", "auto-start.ts");
7
- const source = readFileSync(sourcePath, "utf-8");
7
+ import { hasGitIndexLockForTest } from "../auto-start.ts";
8
8
 
9
- test("bootstrapAutoSession blocks on .git/index.lock before git mutations", () => {
10
- const preflightIdx = source.indexOf('join(base, ".git", "index.lock")');
11
- const initIdx = source.indexOf("nativeInit(base, mainBranch)");
12
- const addIdx = source.indexOf("nativeAddAll(base)");
13
- const commitIdx = source.indexOf('nativeCommit(base, "chore: init gsd")');
9
+ test("bootstrapAutoSession detects .git/index.lock without deleting it", (t) => {
10
+ const base = mkdtempSync(join(tmpdir(), "gsd-index-lock-"));
11
+ t.after(() => rmSync(base, { recursive: true, force: true }));
12
+ const lockPath = join(base, ".git", "index.lock");
13
+ mkdirSync(join(base, ".git"), { recursive: true });
14
+ writeFileSync(lockPath, "locked\n", "utf-8");
14
15
 
15
- assert.ok(preflightIdx > -1, "bootstrap must check for .git/index.lock");
16
- assert.ok(initIdx > -1, "bootstrap still initializes git when safe");
17
- assert.ok(addIdx > -1, "bootstrap still stages bootstrap files when safe");
18
- assert.ok(commitIdx > -1, "bootstrap still commits bootstrap files when safe");
19
-
20
- assert.ok(preflightIdx < initIdx, "index.lock preflight must run before git init");
21
- assert.ok(preflightIdx < addIdx, "index.lock preflight must run before git add");
22
- assert.ok(preflightIdx < commitIdx, "index.lock preflight must run before git commit");
16
+ assert.equal(hasGitIndexLockForTest(base), true);
17
+ assert.equal(existsSync(lockPath), true);
23
18
  });
24
19
 
25
- test("bootstrapAutoSession never deletes .git/index.lock", () => {
26
- assert.ok(
27
- !source.includes("unlinkSync(gitLockFile)") && !source.includes("rmSync(gitLockFile"),
28
- "bootstrap must not remove .git/index.lock because git lock staleness is not safe to infer",
29
- );
30
- assert.ok(
31
- !source.includes("STALE_GIT_LOCK_THRESHOLD_MS"),
32
- "bootstrap must not use lock age as a deletion heuristic",
33
- );
34
- assert.ok(
35
- source.includes("return releaseLockAndReturn();"),
36
- "bootstrap must abort and release the session lock when the git index is locked",
37
- );
20
+ test("bootstrapAutoSession reports no index lock when the lock file is absent", (t) => {
21
+ const base = mkdtempSync(join(tmpdir(), "gsd-index-lock-missing-"));
22
+ t.after(() => rmSync(base, { recursive: true, force: true }));
23
+ mkdirSync(join(base, ".git"), { recursive: true });
24
+
25
+ assert.equal(hasGitIndexLockForTest(base), false);
38
26
  });
@@ -0,0 +1,138 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Bootstrap behavior tests for completed milestone orphan merges.
3
+ import test from "node:test";
4
+ import assert from "node:assert/strict";
5
+ import { execFileSync } from "node:child_process";
6
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
7
+ import { tmpdir } from "node:os";
8
+ import { join } from "node:path";
9
+
10
+ import { bootstrapAutoSession } from "../auto-start.ts";
11
+ import { AutoSession } from "../auto/session.ts";
12
+ import {
13
+ closeDatabase,
14
+ insertMilestone,
15
+ openDatabase,
16
+ } from "../gsd-db.ts";
17
+
18
+ function runGit(base: string, args: string[]): string {
19
+ return execFileSync("git", args, {
20
+ cwd: base,
21
+ encoding: "utf-8",
22
+ stdio: ["ignore", "pipe", "pipe"],
23
+ }).trim();
24
+ }
25
+
26
+ function makeRepoWithUnmergedCompletedMilestone(): string {
27
+ const base = mkdtempSync(join(tmpdir(), "gsd-orphan-bootstrap-"));
28
+ mkdirSync(join(base, ".gsd", "milestones"), { recursive: true });
29
+ writeFileSync(
30
+ join(base, ".gsd", "PREFERENCES.md"),
31
+ "---\ngit:\n isolation: \"branch\"\n---\n",
32
+ );
33
+ runGit(base, ["init"]);
34
+ runGit(base, ["config", "user.email", "test@test.com"]);
35
+ runGit(base, ["config", "user.name", "Test"]);
36
+ writeFileSync(join(base, "README.md"), "# test\n");
37
+ runGit(base, ["add", "-A"]);
38
+ runGit(base, ["commit", "-m", "init"]);
39
+ runGit(base, ["branch", "-M", "main"]);
40
+
41
+ runGit(base, ["checkout", "-b", "milestone/M002"]);
42
+ writeFileSync(join(base, "m002.txt"), "complete but unmerged\n");
43
+ runGit(base, ["add", "-A"]);
44
+ runGit(base, ["commit", "-m", "feat: M002 work"]);
45
+ runGit(base, ["checkout", "main"]);
46
+
47
+ openDatabase(join(base, ".gsd", "gsd.db"));
48
+ insertMilestone({ id: "M002", title: "Completed milestone", status: "complete" });
49
+ insertMilestone({ id: "M003", title: "Next milestone", status: "active" });
50
+ closeDatabase();
51
+
52
+ return base;
53
+ }
54
+
55
+ function makeCtx(notifications: Array<{ message: string; level?: string }>) {
56
+ const model = { provider: "claude-code", id: "claude-sonnet-4-6", contextWindow: 128000 };
57
+ return {
58
+ ui: {
59
+ notify: (message: string, level?: string) => {
60
+ notifications.push({ message, level });
61
+ },
62
+ setStatus: () => {},
63
+ setWidget: () => {},
64
+ },
65
+ model,
66
+ modelRegistry: {
67
+ getAvailable: () => [model],
68
+ isProviderRequestReady: () => true,
69
+ getProviderAuthMode: () => "oauth",
70
+ },
71
+ sessionManager: {
72
+ getSessionId: () => "orphan-bootstrap-test",
73
+ getSessionFile: () => null,
74
+ getEntries: () => [],
75
+ },
76
+ };
77
+ }
78
+
79
+ test("bootstrap aborts before starting next milestone when completed orphan merge fails", async () => {
80
+ const base = makeRepoWithUnmergedCompletedMilestone();
81
+ const previousCwd = process.cwd();
82
+ const s = new AutoSession();
83
+ const mergeCalls: string[] = [];
84
+ const notifications: Array<{ message: string; level?: string }> = [];
85
+
86
+ try {
87
+ const ready = await bootstrapAutoSession(
88
+ s,
89
+ makeCtx(notifications) as any,
90
+ {
91
+ getThinkingLevel: () => "medium",
92
+ getActiveTools: () => [],
93
+ events: { emit: () => {} },
94
+ } as any,
95
+ base,
96
+ false,
97
+ false,
98
+ {
99
+ shouldUseWorktreeIsolation: () => true,
100
+ registerSigtermHandler: () => {},
101
+ lockBase: () => base,
102
+ buildResolver: () => ({
103
+ mergeAndExit: (milestoneId: string) => {
104
+ mergeCalls.push(milestoneId);
105
+ throw new Error("synthetic merge failure");
106
+ },
107
+ }) as any,
108
+ },
109
+ {
110
+ classification: "none",
111
+ lock: null,
112
+ pausedSession: null,
113
+ state: null,
114
+ recovery: null,
115
+ recoveryPrompt: null,
116
+ recoveryToolCallCount: 0,
117
+ artifactSatisfied: false,
118
+ hasResumableDiskState: false,
119
+ isBootstrapCrash: false,
120
+ },
121
+ );
122
+
123
+ assert.equal(ready, false);
124
+ assert.deepEqual(mergeCalls, ["M002"]);
125
+ assert.equal(s.active, false);
126
+ assert.match(
127
+ notifications.map((entry) => entry.message).join("\n"),
128
+ /Could not merge orphan milestone M002: synthetic merge failure/,
129
+ );
130
+ } finally {
131
+ try {
132
+ closeDatabase();
133
+ } catch {}
134
+ process.chdir(previousCwd);
135
+ rmSync(base, { recursive: true, force: true });
136
+ }
137
+ });
138
+
@@ -1,50 +1,32 @@
1
- // GSD2 — Verify autoStartTime is persisted in paused-session.json and restored on resume
2
- // Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
3
-
4
- /**
5
- * auto-start-time-persistence.test.ts — Ensures autoStartTime survives
6
- * cross-session resume via paused-session.json (#3585).
7
- *
8
- * Source-code regression guards: verify auto.ts saves and restores
9
- * autoStartTime so the elapsed timer doesn't vanish after /exit + resume.
10
- */
1
+ // GSD2 — Verify autoStartTime is carried through dashboard state
11
2
 
12
3
  import test from "node:test";
13
4
  import assert from "node:assert/strict";
14
- import { readFileSync } from "node:fs";
15
- import { join, dirname } from "node:path";
16
- import { fileURLToPath } from "node:url";
17
-
18
- const __dirname = dirname(fileURLToPath(import.meta.url));
19
- const AUTO_TS_PATH = join(__dirname, "..", "auto.ts");
20
5
 
21
- const source = readFileSync(AUTO_TS_PATH, "utf-8");
6
+ import { getAutoDashboardData } from "../auto.ts";
7
+ import { autoSession } from "../auto-runtime-state.ts";
22
8
 
23
- test("pauseAuto persists autoStartTime in paused-session.json (#3585)", () => {
24
- assert.ok(
25
- source.includes("autoStartTime: s.autoStartTime"),
26
- "pausedMeta must include autoStartTime so the timer survives /exit",
27
- );
9
+ test.afterEach(() => {
10
+ autoSession.reset();
28
11
  });
29
12
 
30
- test("cross-session resume restores autoStartTime from paused-session.json (#3585)", () => {
31
- const matches = source.match(/s\.autoStartTime\s*=\s*meta\.autoStartTime/g);
32
- assert.ok(
33
- matches && matches.length >= 2,
34
- "both resume paths (custom workflow + milestone) must restore autoStartTime from meta",
35
- );
36
- });
13
+ test("getAutoDashboardData exposes the active autoStartTime (#3585)", () => {
14
+ const start = Date.now() - 5_000;
15
+ autoSession.active = true;
16
+ autoSession.autoStartTime = start;
37
17
 
38
- test("resume path falls back to Date.now() when autoStartTime is missing (#3585)", () => {
39
- assert.ok(
40
- source.includes("meta.autoStartTime || Date.now()"),
41
- "restore should fall back to Date.now() for old paused-session files without autoStartTime",
42
- );
18
+ const data = getAutoDashboardData();
19
+
20
+ assert.equal(data.startTime, start);
21
+ assert.ok(data.elapsed >= 0);
43
22
  });
44
23
 
45
- test("resume path guards against zero autoStartTime (#3585)", () => {
46
- assert.ok(
47
- source.includes("if (!s.autoStartTime || s.autoStartTime <= 0) s.autoStartTime = Date.now()"),
48
- "resume path must set autoStartTime to Date.now() if still zero after restore",
49
- );
24
+ test("getAutoDashboardData suppresses elapsed time when autoStartTime is zero (#3585)", () => {
25
+ autoSession.active = true;
26
+ autoSession.autoStartTime = 0;
27
+
28
+ const data = getAutoDashboardData();
29
+
30
+ assert.equal(data.startTime, 0);
31
+ assert.equal(data.elapsed, 0);
50
32
  });
@@ -1,28 +1,19 @@
1
- import { readFileSync } from "node:fs";
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtempSync, mkdirSync, realpathSync, rmSync } from "node:fs";
2
4
  import { join } from "node:path";
5
+ import { tmpdir } from "node:os";
3
6
 
4
- import {createTestContext, extractSourceRegion } from "./test-helpers.ts";
7
+ import { resolveProjectRootDbPath } from "../bootstrap/dynamic-tools.ts";
5
8
 
6
- const { assertTrue, report } = createTestContext();
9
+ test("#3822: worktree bootstrap resolves the project-root DB path", (t) => {
10
+ const project = realpathSync(mkdtempSync(join(tmpdir(), "gsd-project-db-")));
11
+ t.after(() => rmSync(project, { recursive: true, force: true }));
12
+ const worktree = join(project, ".gsd", "worktrees", "M001");
13
+ mkdirSync(worktree, { recursive: true });
7
14
 
8
- const srcPath = join(import.meta.dirname, "..", "auto-start.ts");
9
- const src = readFileSync(srcPath, "utf-8");
10
-
11
- console.log("\n=== #3822: worktree bootstrap uses project DB path ===");
12
-
13
- const dbLifecycleIdx = src.indexOf("// ── DB lifecycle ──");
14
- assertTrue(dbLifecycleIdx > 0, "auto-start.ts has a DB lifecycle section");
15
-
16
- const dbLifecycleRegion = dbLifecycleIdx > 0 ? extractSourceRegion(src, "// ── DB lifecycle ──") : "";
17
-
18
- assertTrue(
19
- dbLifecycleRegion.includes("const gsdDbPath = resolveProjectRootDbPath(s.basePath);"),
20
- "DB lifecycle resolves the project-root DB path after worktree entry (#3822)",
21
- );
22
-
23
- assertTrue(
24
- !dbLifecycleRegion.includes('join(s.basePath, ".gsd", "gsd.db")'),
25
- "DB lifecycle no longer derives gsd.db directly from the worktree path (#3822)",
26
- );
27
-
28
- report();
15
+ assert.equal(
16
+ resolveProjectRootDbPath(worktree),
17
+ join(project, ".gsd", "gsd.db"),
18
+ );
19
+ });
@@ -1,39 +1,54 @@
1
1
  import test from "node:test";
2
2
  import assert from "node:assert/strict";
3
- import { readFileSync } from "node:fs";
3
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
- import { extractSourceRegion } from "./test-helpers.ts";
5
+ import { tmpdir } from "node:os";
6
6
 
7
- const autoSrc = readFileSync(join(import.meta.dirname, "..", "auto.ts"), "utf-8");
8
- const phasesSrc = readFileSync(join(import.meta.dirname, "..", "auto", "phases.ts"), "utf-8");
7
+ import { selectAndApplyModel } from "../auto-model-selection.ts";
9
8
 
10
- test("stopAuto restores original thinking level", () => {
11
- assert.ok(
12
- autoSrc.includes("if (pi && s.originalThinkingLevel)"),
13
- "auto.ts should conditionally restore original thinking level in stopAuto",
9
+ test("selectAndApplyModel restores captured thinking level after model selection", async (t) => {
10
+ const originalCwd = process.cwd();
11
+ const base = mkdtempSync(join(tmpdir(), "gsd-thinking-restore-"));
12
+ const thinkingLevels: unknown[] = [];
13
+ t.after(() => {
14
+ process.chdir(originalCwd);
15
+ rmSync(base, { recursive: true, force: true });
16
+ });
17
+ mkdirSync(join(base, ".gsd"), { recursive: true });
18
+ writeFileSync(
19
+ join(base, ".gsd", "PREFERENCES.md"),
20
+ ["---", "models:", " planning: anthropic/claude-sonnet-4-6", "---"].join("\n"),
21
+ "utf-8",
14
22
  );
15
- assert.ok(
16
- autoSrc.includes("pi.setThinkingLevel(s.originalThinkingLevel)"),
17
- "auto.ts should call pi.setThinkingLevel with originalThinkingLevel",
18
- );
19
- });
23
+ process.chdir(base);
20
24
 
21
- test("runUnitPhase threads captured thinking level into selectAndApplyModel", () => {
22
- const callIdx = phasesSrc.indexOf("deps.selectAndApplyModel(");
23
- assert.ok(callIdx > -1, "phases.ts should call selectAndApplyModel");
24
- const callBlock = extractSourceRegion(phasesSrc, "deps.selectAndApplyModel(");
25
- assert.ok(
26
- callBlock.includes("s.autoModeStartThinkingLevel"),
27
- "runUnitPhase should pass autoModeStartThinkingLevel to selectAndApplyModel",
25
+ const result = await selectAndApplyModel(
26
+ {
27
+ modelRegistry: { getAvailable: () => [{ id: "claude-sonnet-4-6", provider: "anthropic", api: "anthropic-messages" }] },
28
+ sessionManager: { getSessionId: () => "thinking-test" },
29
+ ui: { notify: () => {} },
30
+ model: { provider: "anthropic", id: "claude-sonnet-4-6", api: "anthropic-messages" },
31
+ } as any,
32
+ {
33
+ setModel: async () => true,
34
+ setThinkingLevel: (level: unknown) => { thinkingLevels.push(level); },
35
+ emitBeforeModelSelect: async () => undefined,
36
+ getActiveTools: () => [],
37
+ emitAdjustToolSet: async () => undefined,
38
+ setActiveTools: () => {},
39
+ } as any,
40
+ "plan-slice",
41
+ "M001/S01",
42
+ base,
43
+ undefined,
44
+ false,
45
+ { provider: "anthropic", id: "claude-sonnet-4-6" },
46
+ undefined,
47
+ true,
48
+ undefined,
49
+ { effort: "medium" } as any,
28
50
  );
29
- });
30
51
 
31
- test("hook model override preserves captured thinking level", () => {
32
- const hookIdx = phasesSrc.indexOf("const hookModelOverride = sidecarItem?.model ?? iterData.hookModelOverride;");
33
- assert.ok(hookIdx > -1, "phases.ts should include hook model override handling");
34
- const hookBlock = extractSourceRegion(phasesSrc, "const hookModelOverride = sidecarItem?.model ?? iterData.hookModelOverride;");
35
- assert.ok(
36
- hookBlock.includes("pi.setThinkingLevel(s.autoModeStartThinkingLevel)"),
37
- "hook model override should re-apply captured thinking level after setModel",
38
- );
52
+ assert.equal(result.appliedModel?.provider, "anthropic");
53
+ assert.deepEqual(thinkingLevels, [{ effort: "medium" }]);
39
54
  });
@@ -23,11 +23,17 @@
23
23
 
24
24
  import test from "node:test";
25
25
  import assert from "node:assert/strict";
26
- import { readFileSync } from "node:fs";
26
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
27
27
  import { join } from "node:path";
28
+ import { tmpdir } from "node:os";
28
29
 
29
30
  import { buildFlatRateContext } from "../auto-model-selection.ts";
30
- import { extractSourceRegion } from "./test-helpers.ts";
31
+ import { _isSamePathForTest, _resetAutoWorktreeOriginalBaseForTests } from "../auto-worktree.ts";
32
+ import {
33
+ checkAutoStartAfterDiscuss,
34
+ clearPendingAutoStart,
35
+ setPendingAutoStart,
36
+ } from "../guided-flow.ts";
31
37
 
32
38
  // ─── Bug 2: this-binding regression ─────────────────────────────────────
33
39
 
@@ -62,57 +68,39 @@ test("buildFlatRateContext invokes getProviderAuthMode with correct `this`", ()
62
68
 
63
69
  // ─── Bug 1: isSamePath source check ─────────────────────────────────────
64
70
 
65
- test("isSamePath short-circuits ENOENT before logging a warning", () => {
66
- const srcPath = join(import.meta.dirname, "..", "auto-worktree.ts");
67
- const src = readFileSync(srcPath, "utf-8");
68
-
69
- const fnIdx = src.indexOf("function isSamePath");
70
- assert.ok(fnIdx !== -1, "isSamePath function exists");
71
-
72
- // Grab the function body (enough to cover the catch block).
73
- const fnBody = extractSourceRegion(src, "function isSamePath", { fromIdx: fnIdx });
74
-
75
- const catchIdx = fnBody.indexOf("catch");
76
- assert.ok(catchIdx !== -1, "isSamePath has a catch block");
77
-
78
- const enoentIdx = fnBody.indexOf("ENOENT", catchIdx);
79
- const warnIdx = fnBody.indexOf("logWarning", catchIdx);
80
-
81
- assert.ok(enoentIdx !== -1, "catch block must handle ENOENT explicitly");
82
- assert.ok(warnIdx !== -1, "catch block still warns on non-ENOENT errors");
83
- assert.ok(
84
- enoentIdx < warnIdx,
85
- "ENOENT early-return must precede the logWarning call",
86
- );
71
+ test("isSamePath returns false for missing paths without throwing", () => {
72
+ const dir = mkdtempSync(join(tmpdir(), "gsd-same-path-"));
73
+ try {
74
+ assert.equal(_isSamePathForTest(join(dir, "missing-a"), join(dir, "missing-b")), false);
75
+ } finally {
76
+ rmSync(dir, { recursive: true, force: true });
77
+ _resetAutoWorktreeOriginalBaseForTests();
78
+ }
87
79
  });
88
80
 
89
81
  // ─── Bug 3: guided-flow manifest unlink source check ────────────────────
90
82
 
91
- test("checkAutoStartAfterDiscuss guards DISCUSSION-MANIFEST.json unlink with existsSync", () => {
92
- const srcPath = join(import.meta.dirname, "..", "guided-flow.ts");
93
- const src = readFileSync(srcPath, "utf-8");
94
-
95
- const fnIdx = src.indexOf("function checkAutoStartAfterDiscuss");
96
- assert.ok(fnIdx !== -1, "checkAutoStartAfterDiscuss function exists");
97
-
98
- // Locate the manifest cleanup comment and its surrounding block.
99
- const cleanupIdx = src.indexOf(
100
- "remove discussion manifest after auto-start",
101
- fnIdx,
102
- );
103
- assert.ok(cleanupIdx !== -1, "manifest cleanup block still exists");
104
-
105
- // Everything from the comment to a short distance below should contain
106
- // the existsSync guard before the unlinkSync call.
107
- const block = extractSourceRegion(src, "remove discussion manifest after auto-start", { fromIdx: cleanupIdx });
108
-
109
- const existsIdx = block.indexOf("existsSync(manifestPath)");
110
- const unlinkIdx = block.indexOf("unlinkSync(manifestPath)");
111
-
112
- assert.ok(existsIdx !== -1, "manifest unlink must be guarded by existsSync");
113
- assert.ok(unlinkIdx !== -1, "manifest unlink still happens when file exists");
114
- assert.ok(
115
- existsIdx < unlinkIdx,
116
- "existsSync guard must precede the unlinkSync call",
117
- );
83
+ test("checkAutoStartAfterDiscuss completes when discussion manifest is absent", () => {
84
+ const base = mkdtempSync(join(tmpdir(), "gsd-discuss-manifest-"));
85
+ const notifications: Array<{ message: string; level: string }> = [];
86
+ let scheduled = false;
87
+ try {
88
+ const milestoneDir = join(base, ".gsd", "milestones", "M001");
89
+ mkdirSync(milestoneDir, { recursive: true });
90
+ writeFileSync(join(milestoneDir, "M001-CONTEXT.md"), "# Context\n", "utf-8");
91
+ writeFileSync(join(base, ".gsd", "STATE.md"), "# State\n", "utf-8");
92
+ setPendingAutoStart(base, {
93
+ basePath: base,
94
+ milestoneId: "M001",
95
+ ctx: { ui: { notify: (message: string, level: string) => notifications.push({ message, level }) } } as any,
96
+ pi: { sendMessage: () => { scheduled = true; } } as any,
97
+ });
98
+
99
+ assert.equal(checkAutoStartAfterDiscuss(), true);
100
+ assert.equal(scheduled, false);
101
+ assert.deepEqual(notifications, [{ message: "Milestone M001 ready.", level: "success" }]);
102
+ } finally {
103
+ clearPendingAutoStart(base);
104
+ rmSync(base, { recursive: true, force: true });
105
+ }
118
106
  });