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
@@ -6,32 +6,50 @@
6
6
  * planning/import APIs.
7
7
  */
8
8
 
9
- import { describe, test } from "node:test";
9
+ import { afterEach, beforeEach, describe, test } from "node:test";
10
10
  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";
11
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
12
+ import { tmpdir } from "node:os";
13
+ import { join } from "node:path";
14
14
 
15
- const __dirname = dirname(fileURLToPath(import.meta.url));
16
- const sourceFile = join(__dirname, "..", "state.ts");
15
+ import { closeDatabase, insertMilestone, insertSlice, openDatabase } from "../gsd-db.ts";
16
+ import { deriveStateFromDb, invalidateStateCache } from "../state.ts";
17
17
 
18
18
  describe("dispatcher DB-authoritative planning boundary", () => {
19
- const source = readFileSync(sourceFile, "utf-8");
19
+ let base: string;
20
20
 
21
- test("does not import insertTask into state derivation", () => {
22
- assert.doesNotMatch(source, /import\s*\{[^}]*insertTask[^}]*\}\s*from/);
21
+ beforeEach(() => {
22
+ base = mkdtempSync(join(tmpdir(), "gsd-dispatcher-planning-"));
23
+ mkdirSync(join(base, ".gsd", "milestones", "M001", "S01"), { recursive: true });
24
+ writeFileSync(join(base, ".gsd", "milestones", "M001", "CONTEXT.md"), "# M001\n");
25
+ writeFileSync(join(base, ".gsd", "milestones", "M001", "ROADMAP.md"), [
26
+ "## Slices",
27
+ "- [ ] **S01: Build** `risk:low` `depends:[]`",
28
+ ].join("\n"));
29
+ writeFileSync(join(base, ".gsd", "milestones", "M001", "S01", "PLAN.md"), [
30
+ "## Tasks",
31
+ "- [ ] **T01: Projection-only task**",
32
+ ].join("\n"));
33
+ openDatabase(join(base, ".gsd", "gsd.db"));
23
34
  });
24
35
 
25
- test("does not contain plan-file task reconciliation block", () => {
26
- assert.doesNotMatch(source, /dbTaskIds\.has\(t\.id\)/);
27
- assert.match(source, /Slice \$\{activeSlice\.id\} has no DB tasks/);
36
+ afterEach(() => {
37
+ closeDatabase();
38
+ invalidateStateCache();
39
+ rmSync(base, { recursive: true, force: true });
28
40
  });
29
41
 
30
- test("does not call insertTask from state derivation", () => {
31
- assert.doesNotMatch(source, /insertTask\(\{/);
32
- });
42
+ test("PLAN.md projection tasks are not imported into runtime DB state", async () => {
43
+ insertMilestone({ id: "M001", title: "Milestone 1", status: "active", depends_on: [] });
44
+ insertSlice({ id: "S01", milestoneId: "M001", title: "Build", status: "active", depends: [] });
45
+
46
+ const state = await deriveStateFromDb(base);
33
47
 
34
- test("documents markdown projections as non-authoritative", () => {
35
- assert.match(source, /Markdown files are projections only/);
48
+ assert.equal(state.phase, "planning");
49
+ assert.equal(state.activeTask, null);
50
+ assert.match(
51
+ state.nextAction ?? "",
52
+ /Slice S01 has no DB tasks\. Plan slice tasks before execution\./,
53
+ );
36
54
  });
37
55
  });
@@ -8,30 +8,25 @@
8
8
 
9
9
  import { describe, test } from "node:test";
10
10
  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";
14
-
15
- const __dirname = dirname(fileURLToPath(import.meta.url));
16
- const sourceFile = join(__dirname, "..", "bootstrap", "agent-end-recovery.ts");
11
+ import { resolveAgentEndErrorDisplay } from "../bootstrap/agent-end-recovery.ts";
17
12
 
18
13
  describe("error-success mask detection (#3664)", () => {
19
- const source = readFileSync(sourceFile, "utf-8");
20
-
21
- test("detects useless errorMessage values with regex", () => {
22
- assert.match(source, /success\|ok\|true\|error\|unknown/i);
23
- });
24
-
25
- test("extracts display message from content text block", () => {
26
- assert.match(source, /textBlock/);
27
- assert.match(source, /\.text\.slice\(0,\s*300\)/);
28
- });
29
-
30
- test("classifies using rawErrorMsg, not displayMsg", () => {
31
- assert.match(source, /classifyError\(rawErrorMsg/);
14
+ test("falls back to assistant text when errorMessage is uninformative", () => {
15
+ assert.equal(
16
+ resolveAgentEndErrorDisplay("success", [
17
+ { type: "tool_use", name: "noop" },
18
+ { type: "text", text: "provider failed with a useful message" },
19
+ ]),
20
+ "provider failed with a useful message",
21
+ );
32
22
  });
33
23
 
34
- test("references issue #3588 in comments", () => {
35
- assert.match(source, /#3588/);
24
+ test("keeps informative raw error messages", () => {
25
+ assert.equal(
26
+ resolveAgentEndErrorDisplay("rate limit exceeded", [
27
+ { type: "text", text: "prose should not replace useful raw error" },
28
+ ]),
29
+ "rate limit exceeded",
30
+ );
36
31
  });
37
32
  });
@@ -8,46 +8,7 @@
8
8
 
9
9
  import test from "node:test";
10
10
  import assert from "node:assert/strict";
11
- import { readFileSync } from "node:fs";
12
- import { join } from "node:path";
13
-
14
- const timersSrcPath = join(import.meta.dirname, "..", "auto-timers.ts");
15
- const timersSrc = readFileSync(timersSrcPath, "utf-8");
16
-
17
- // ─── Source analysis: parseEstimateMinutes exists and is exported ────────────
18
-
19
- test("#2243: auto-timers.ts should export parseEstimateMinutes", () => {
20
- assert.ok(
21
- timersSrc.includes("export function parseEstimateMinutes"),
22
- "parseEstimateMinutes should be exported from auto-timers.ts",
23
- );
24
- });
25
-
26
- // ─── Inline unit test of parseEstimateMinutes logic ─────────────────────────
27
- // Since importing the module pulls in heavy deps, test the parsing logic inline.
28
-
29
- function parseEstimateMinutes(estimate: string): number | null {
30
- if (!estimate || typeof estimate !== "string") return null;
31
- const trimmed = estimate.trim();
32
- if (!trimmed) return null;
33
-
34
- let totalMinutes = 0;
35
- let matched = false;
36
-
37
- const hoursMatch = trimmed.match(/(\d+)\s*h/i);
38
- if (hoursMatch) {
39
- totalMinutes += Number(hoursMatch[1]) * 60;
40
- matched = true;
41
- }
42
-
43
- const minutesMatch = trimmed.match(/(\d+)\s*m/i);
44
- if (minutesMatch) {
45
- totalMinutes += Number(minutesMatch[1]);
46
- matched = true;
47
- }
48
-
49
- return matched ? totalMinutes : null;
50
- }
11
+ import { parseEstimateMinutes, resolveUnitSupervisionTimeouts } from "../auto-timers.ts";
51
12
 
52
13
  test("#2243: parseEstimateMinutes parses '30m' correctly", () => {
53
14
  assert.equal(parseEstimateMinutes("30m"), 30);
@@ -73,48 +34,20 @@ test("#2243: parseEstimateMinutes returns null for invalid string", () => {
73
34
  assert.equal(parseEstimateMinutes("not a time"), null);
74
35
  });
75
36
 
76
- // ─── Source analysis: startUnitSupervision uses task estimates ───────────────
77
-
78
- test("#2243: startUnitSupervision should reference task estimates for timeout scaling", () => {
79
- const usesEstimate =
80
- timersSrc.includes("parseEstimateMinutes") &&
81
- timersSrc.includes("estimateMinutes") &&
82
- timersSrc.includes("taskEstimate");
83
-
84
- assert.ok(
85
- usesEstimate,
86
- "startUnitSupervision should use task estimate annotations for timeout scaling",
37
+ test("#2243: estimate scale affects soft and hard timeouts but not idle timeout", () => {
38
+ const result = resolveUnitSupervisionTimeouts(
39
+ "execute-task",
40
+ {
41
+ soft_timeout_minutes: 10,
42
+ idle_timeout_minutes: 5,
43
+ hard_timeout_minutes: 20,
44
+ },
45
+ 3,
87
46
  );
88
- });
89
-
90
- test("#2243: SupervisionContext should accept an optional taskEstimate field", () => {
91
- const ctxIdx = timersSrc.indexOf("SupervisionContext");
92
- assert.ok(ctxIdx !== -1, "SupervisionContext interface exists");
93
47
 
94
- const ctxEnd = timersSrc.indexOf("}", ctxIdx);
95
- const ctxBlock = timersSrc.slice(ctxIdx, ctxEnd);
96
-
97
- assert.ok(
98
- ctxBlock.includes("taskEstimate"),
99
- "SupervisionContext should include a taskEstimate field",
100
- );
101
- });
102
-
103
- test("#2243: timeouts should be scaled by estimate (timeoutScale in source)", () => {
104
- assert.ok(
105
- timersSrc.includes("timeoutScale"),
106
- "auto-timers.ts should use a timeoutScale factor derived from est: annotations",
107
- );
108
- });
109
-
110
- test("#2243: idle timeout should NOT be scaled (idle is idle regardless of estimate)", () => {
111
- // Find the idleTimeoutMs line
112
- const idleIdx = timersSrc.indexOf("const idleTimeoutMs");
113
- assert.ok(idleIdx !== -1, "idleTimeoutMs variable exists");
114
-
115
- const idleLine = timersSrc.slice(idleIdx, timersSrc.indexOf("\n", idleIdx));
116
- assert.ok(
117
- !idleLine.includes("timeoutScale"),
118
- "idleTimeoutMs should NOT be scaled — idle is idle",
119
- );
48
+ assert.deepEqual(result, {
49
+ softTimeoutMs: 30 * 60 * 1000,
50
+ idleTimeoutMs: 5 * 60 * 1000,
51
+ hardTimeoutMs: 60 * 60 * 1000,
52
+ });
120
53
  });
@@ -6,14 +6,11 @@
6
6
 
7
7
  import { describe, test } from "node:test";
8
8
  import assert from "node:assert/strict";
9
- import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, rmSync } from "node:fs";
9
+ import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
10
10
  import { tmpdir } from "node:os";
11
- import { dirname, join } from "node:path";
12
- import { fileURLToPath } from "node:url";
11
+ import { join } from "node:path";
13
12
  import { buildFlatRateContext, isFlatRateProvider, resolvePreferredModelConfig } from "../auto-model-selection.ts";
14
13
 
15
- const __dirname_4386 = dirname(fileURLToPath(import.meta.url));
16
-
17
14
  describe("flat-rate provider routing guard (#3453)", () => {
18
15
 
19
16
  test("isFlatRateProvider returns true for github-copilot", () => {
@@ -306,18 +303,3 @@ describe("flat-rate routing opt-in (#4386)", () => {
306
303
  );
307
304
  });
308
305
  });
309
-
310
- // ─── Banner transparency: auto-start respects the opt-in (#4386) ────────────
311
-
312
- describe("auto-start banner respects allow_flat_rate_providers (#4386)", () => {
313
- test("banner expression gates flat-rate disable on allow_flat_rate_providers", () => {
314
- const src = readFileSync(
315
- join(__dirname_4386, "..", "auto-start.ts"),
316
- "utf-8",
317
- );
318
- assert.ok(
319
- src.includes("routingConfig.allow_flat_rate_providers"),
320
- "auto-start banner must read allow_flat_rate_providers so the banner reflects the opt-in",
321
- );
322
- });
323
- });
@@ -7,36 +7,28 @@
7
7
 
8
8
  import { describe, test } from 'node:test';
9
9
  import assert from 'node:assert/strict';
10
- import { readFileSync } from 'node:fs';
11
- import { fileURLToPath } from 'node:url';
12
- import { dirname, join } from 'node:path';
13
-
14
- const __filename = fileURLToPath(import.meta.url);
15
- const __dirname = dirname(__filename);
16
-
17
- const prefsSrc = readFileSync(
18
- join(__dirname, '..', 'preferences.ts'),
19
- 'utf-8',
20
- );
10
+ import { _resetParseWarningFlag, parsePreferencesMarkdown } from "../preferences.ts";
11
+ import { drainLogs } from "../workflow-logger.ts";
21
12
 
22
13
  describe('frontmatter parse noise suppression (#3693)', () => {
23
- test('_warnedFrontmatterParse flag is defined', () => {
24
- assert.match(prefsSrc, /_warnedFrontmatterParse/,
25
- '_warnedFrontmatterParse flag should exist in preferences.ts');
26
- });
14
+ test('invalid frontmatter emits one warning per reset', () => {
15
+ _resetParseWarningFlag();
16
+ drainLogs();
27
17
 
28
- test('parseFrontmatterBlock function exists', () => {
29
- assert.match(prefsSrc, /function parseFrontmatterBlock\(/,
30
- 'parseFrontmatterBlock function should be defined');
31
- });
18
+ const invalidPrefs = [
19
+ "---",
20
+ "models: [unterminated",
21
+ "---",
22
+ ].join("\n");
32
23
 
33
- test('flag is checked before warning', () => {
34
- assert.match(prefsSrc, /if\s*\(\s*!_warnedFrontmatterParse\s*\)/,
35
- 'should check !_warnedFrontmatterParse before logging');
36
- });
24
+ assert.deepEqual(parsePreferencesMarkdown(invalidPrefs), {});
25
+ assert.deepEqual(parsePreferencesMarkdown(invalidPrefs), {});
37
26
 
38
- test('flag is set to true after first warning', () => {
39
- assert.match(prefsSrc, /_warnedFrontmatterParse\s*=\s*true/,
40
- 'should set _warnedFrontmatterParse = true after warning');
27
+ const warnings = drainLogs().filter((entry) =>
28
+ entry.severity === "warn" &&
29
+ entry.component === "guided" &&
30
+ entry.message.includes("YAML parse error in preferences frontmatter")
31
+ );
32
+ assert.equal(warnings.length, 1);
41
33
  });
42
34
  });
@@ -1,19 +1,16 @@
1
1
  import test from "node:test";
2
2
  import assert from "node:assert/strict";
3
- import { readFileSync } from "node:fs";
4
- import { join } from "node:path";
5
3
 
6
- const initWizardSource = readFileSync(join(import.meta.dirname, "..", "init-wizard.ts"), "utf8");
7
- const guidedFlowSource = readFileSync(join(import.meta.dirname, "..", "guided-flow.ts"), "utf8");
4
+ import { shouldWriteGitFiles } from "../init-wizard.ts";
5
+ import { shouldSkipGitBootstrapAfterInit } from "../guided-flow.ts";
8
6
 
9
- test("init wizard returns gitEnabled false when git setup is skipped", () => {
10
- assert.match(initWizardSource, /gitEnabled = signals\.isGitRepo/);
11
- assert.match(initWizardSource, /return \{ completed: true, bootstrapped: true, gitEnabled \}/);
12
- assert.match(initWizardSource, /if \(gitEnabled\) \{\s*ensureGitignore\(basePath\);/);
7
+ test("init wizard does not write git files when git setup is skipped", () => {
8
+ assert.equal(shouldWriteGitFiles(false), false);
9
+ assert.equal(shouldWriteGitFiles(true), true);
13
10
  });
14
11
 
15
- test("guided flow does not initialize git after the init wizard skip-git choice", () => {
16
- assert.match(guidedFlowSource, /skipGitBootstrap = result\.gitEnabled === false/);
17
- assert.match(guidedFlowSource, /if \(!skipGitBootstrap && \(!nativeIsRepo\(basePath\) \|\| isInheritedRepo\(basePath\)\)\)/);
18
- assert.match(guidedFlowSource, /if \(!skipGitBootstrap && nativeIsRepo\(basePath\)\) \{\s*ensureGitignore\(basePath\);/);
12
+ test("guided flow skips git bootstrap after the init wizard skip-git choice", () => {
13
+ assert.equal(shouldSkipGitBootstrapAfterInit({ gitEnabled: false }), true);
14
+ assert.equal(shouldSkipGitBootstrapAfterInit({ gitEnabled: true }), false);
15
+ assert.equal(shouldSkipGitBootstrapAfterInit({}), false);
19
16
  });
@@ -1,3 +1,5 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Auto-worktree milestone squash-merge integration tests.
1
3
  /**
2
4
  * auto-worktree-milestone-merge.test.ts — Integration tests for mergeMilestoneToMain.
3
5
  *
@@ -25,6 +27,13 @@ import {
25
27
  import { getSliceBranchName } from "../../worktree.ts";
26
28
  import { nativeMergeSquash } from "../../native-git-bridge.ts";
27
29
  import { drainLogs, setStderrLoggingEnabled } from "../../workflow-logger.ts";
30
+ import {
31
+ closeDatabase,
32
+ insertMilestone,
33
+ insertSlice,
34
+ insertTask,
35
+ openDatabase,
36
+ } from "../../gsd-db.ts";
28
37
 
29
38
  function run(cmd: string, cwd: string): string {
30
39
  // Safe: all inputs are hardcoded test strings, not user input
@@ -117,6 +126,7 @@ describe("auto-worktree-milestone-merge", { timeout: 300_000 }, () => {
117
126
 
118
127
  afterEach(() => {
119
128
  process.chdir(savedCwd);
129
+ closeDatabase();
120
130
  for (const d of tempDirs) {
121
131
  if (existsSync(d)) rmSync(d, { recursive: true, force: true });
122
132
  }
@@ -179,6 +189,24 @@ describe("auto-worktree-milestone-merge", { timeout: 300_000 }, () => {
179
189
  addSliceToMilestone(repo, wtPath, "M020", "S03", "Logging infra", [
180
190
  { file: "logger.ts", content: "export const log = () => {};\n", message: "add logger" },
181
191
  ]);
192
+ openDatabase(":memory:");
193
+ insertMilestone({ id: "M020", title: "M020: Backend foundation", status: "complete" });
194
+ for (const slice of [
195
+ { id: "S01", title: "Core API", tasks: [{ id: "T01", title: "Create API router" }] },
196
+ { id: "S02", title: "Error handling", tasks: [{ id: "T02", title: "Handle API errors" }] },
197
+ { id: "S03", title: "Logging infra", tasks: [{ id: "T03", title: "Wire request logging" }] },
198
+ ]) {
199
+ insertSlice({ id: slice.id, milestoneId: "M020", title: slice.title, status: "complete" });
200
+ for (const task of slice.tasks) {
201
+ insertTask({
202
+ id: task.id,
203
+ sliceId: slice.id,
204
+ milestoneId: "M020",
205
+ title: task.title,
206
+ status: "complete",
207
+ });
208
+ }
209
+ }
182
210
 
183
211
  const roadmap = makeRoadmap("M020", "Backend foundation", [
184
212
  { id: "S01", title: "Core API" },
@@ -193,13 +221,20 @@ describe("auto-worktree-milestone-merge", { timeout: 300_000 }, () => {
193
221
  assert.ok(result.commitMessage.includes("- S01: Core API"), "body lists S01");
194
222
  assert.ok(result.commitMessage.includes("- S02: Error handling"), "body lists S02");
195
223
  assert.ok(result.commitMessage.includes("- S03: Logging infra"), "body lists S03");
224
+ assert.ok(result.commitMessage.includes("Completed tasks:"), "body lists completed tasks");
225
+ assert.ok(result.commitMessage.includes("- S01/T01: Create API router"), "body lists S01 task");
226
+ assert.ok(result.commitMessage.includes("- S02/T02: Handle API errors"), "body lists S02 task");
227
+ assert.ok(result.commitMessage.includes("Milestone: M020 - Backend foundation"), "body has human milestone context");
196
228
  assert.ok(result.commitMessage.includes("GSD-Milestone: M020"), "body has GSD-Milestone trailer");
197
229
  assert.ok(result.commitMessage.includes("Branch: milestone/M020"), "body has branch metadata");
230
+ assert.ok(!result.commitMessage.includes("auto-commit after complete-milestone"), "body avoids generic complete-milestone fallback");
231
+ assert.ok(!result.commitMessage.includes("GSD-Unit:"), "body avoids generic unit trailer");
198
232
 
199
233
  const gitMsg = run("git log -1 --format=%B main", repo).trim();
200
234
  assert.match(gitMsg, /^feat:/, "git commit message starts with feat:");
201
235
  assert.ok(gitMsg.includes("GSD-Milestone: M020"), "git commit has GSD-Milestone trailer");
202
236
  assert.ok(gitMsg.includes("- S01: Core API"), "git commit body has S01");
237
+ assert.ok(gitMsg.includes("- S03/T03: Wire request logging"), "git commit body has task names");
203
238
  });
204
239
 
205
240
  test("nothing to commit — safe when no code changes (#1738, #1792)", () => {
@@ -780,6 +815,11 @@ describe("auto-worktree-milestone-merge", { timeout: 300_000 }, () => {
780
815
  !existsSync(mergeHeadPath),
781
816
  "#2912: MERGE_HEAD must be cleaned up after merge conflict error",
782
817
  );
818
+ assert.equal(
819
+ run("git diff --name-only --diff-filter=U", repo),
820
+ "",
821
+ "squash conflict cleanup must clear unmerged index entries",
822
+ );
783
823
  });
784
824
 
785
825
  test("#2912: stale MERGE_HEAD from native merge is cleaned after successful commit", () => {
@@ -1,3 +1,5 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Integration tests for the /gsd eval-review helper chain.
1
3
  /**
2
4
  * Integration test for `/gsd eval-review` .
3
5
  *
@@ -10,7 +12,7 @@
10
12
 
11
13
  import { describe, it, beforeEach, afterEach } from "node:test";
12
14
  import assert from "node:assert/strict";
13
- import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
15
+ import { mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "node:fs";
14
16
  import { join } from "node:path";
15
17
  import { tmpdir } from "node:os";
16
18
 
@@ -119,7 +121,7 @@ describe("integration: /gsd eval-review helper chain on a real on-disk slice", (
119
121
  );
120
122
  assert.equal(ctx.truncated, false);
121
123
  assert.equal(ctx.sliceId, "S07");
122
- assert.equal(ctx.outputPath, evalReviewWritePath(layout.sliceDir, "S07"));
124
+ assert.equal(ctx.outputPath, evalReviewWritePath(realpathSync(layout.sliceDir), "S07"));
123
125
 
124
126
  const prompt = buildEvalReviewPrompt(ctx);
125
127
 
@@ -7,13 +7,13 @@ import assert from 'node:assert/strict';
7
7
  * English output, and that nativeMergeSquash passes the env to execFileSync.
8
8
  */
9
9
 
10
- import { mkdtempSync, mkdirSync, writeFileSync, rmSync, readFileSync } from "node:fs";
10
+ import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
11
11
  import { join } from "node:path";
12
12
  import { tmpdir } from "node:os";
13
13
  import { execFileSync } from "node:child_process";
14
14
 
15
15
  import { GIT_NO_PROMPT_ENV } from "../../git-constants.ts";
16
- import { nativeAddAllWithExclusions } from "../../native-git-bridge.ts";
16
+ import { nativeAddAllWithExclusions, nativeMergeSquash } from "../../native-git-bridge.ts";
17
17
  import { RUNTIME_EXCLUSION_PATHS } from "../../git-service.ts";
18
18
  function git(cwd: string, ...args: string[]): string {
19
19
  return execFileSync("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
@@ -97,23 +97,34 @@ describe('git-locale', async () => {
97
97
 
98
98
  // ─── nativeMergeSquash: env is passed (merge-squash stderr is English) ─
99
99
 
100
- test('nativeMergeSquash fallback uses GIT_NO_PROMPT_ENV', () => {
101
- // We verify indirectly: the source code must pass env: GIT_NO_PROMPT_ENV.
102
- // Read the source and check for the pattern. This is a static check.
103
- const src = readFileSync(
104
- join(import.meta.dirname, "../..", "native-git-bridge.ts"),
105
- "utf-8"
106
- );
107
-
108
- // Find the nativeMergeSquash function and check it uses GIT_NO_PROMPT_ENV
109
- const fnStart = src.indexOf("export function nativeMergeSquash");
110
- assert.ok(fnStart !== -1, "nativeMergeSquash function exists in source");
111
-
112
- const fnBody = src.slice(fnStart, src.indexOf("\nexport function", fnStart + 1));
113
- const hasEnv = fnBody.includes("env: GIT_NO_PROMPT_ENV");
114
- assert.ok(
115
- hasEnv,
116
- "nativeMergeSquash fallback must pass env: GIT_NO_PROMPT_ENV to execFileSync (#1997)"
117
- );
100
+ test('nativeMergeSquash succeeds under non-English locale env', () => {
101
+ const repo = initTempRepo();
102
+ try {
103
+ const mainBranch = git(repo, "branch", "--show-current");
104
+ git(repo, "checkout", "-b", "feature");
105
+ createFile(repo, "src/feature.ts", "export const feature = true;");
106
+ git(repo, "add", "-A");
107
+ git(repo, "commit", "-m", "feat: add feature");
108
+ git(repo, "checkout", mainBranch);
109
+
110
+ const origLcAll = process.env.LC_ALL;
111
+ const origLang = process.env.LANG;
112
+ process.env.LANG = "de_DE.UTF-8";
113
+ delete process.env.LC_ALL;
114
+ try {
115
+ const result = nativeMergeSquash(repo, "feature");
116
+ assert.equal(result.success, true);
117
+ } finally {
118
+ if (origLcAll !== undefined) process.env.LC_ALL = origLcAll;
119
+ else delete process.env.LC_ALL;
120
+ if (origLang !== undefined) process.env.LANG = origLang;
121
+ else delete process.env.LANG;
122
+ }
123
+
124
+ const staged = git(repo, "diff", "--cached", "--name-only");
125
+ assert.ok(staged.includes("src/feature.ts"));
126
+ } finally {
127
+ rmSync(repo, { recursive: true, force: true });
128
+ }
118
129
  });
119
130
  });
@@ -1,3 +1,5 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Git service integration and commit-message tests.
1
3
  import { describe, test } from 'node:test';
2
4
  import assert from 'node:assert/strict';
3
5
  import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, symlinkSync, readFileSync } from "node:fs";
@@ -211,7 +213,12 @@ describe('git-service', async () => {
211
213
  test('buildTaskCommitMessage', () => {
212
214
  const msg = buildTaskCommitMessage({
213
215
  taskId: "S01/T02",
216
+ taskDisplayId: "T02",
214
217
  taskTitle: "implement user authentication",
218
+ milestoneId: "M001",
219
+ milestoneTitle: "User management",
220
+ sliceId: "S01",
221
+ sliceTitle: "Authentication",
215
222
  oneLiner: "Added JWT-based auth with refresh token rotation",
216
223
  keyFiles: ["src/auth.ts", "src/middleware/jwt.ts"],
217
224
  });
@@ -220,7 +227,12 @@ describe('git-service', async () => {
220
227
  assert.ok(msg.includes("JWT-based auth"), "message includes one-liner content");
221
228
  assert.ok(msg.includes("- src/auth.ts"), "message body includes key files");
222
229
  assert.ok(msg.includes("- src/middleware/jwt.ts"), "message body includes second key file");
230
+ assert.ok(msg.includes("GSD context:"), "message includes human GSD context block");
231
+ assert.ok(msg.includes("- Milestone: M001 - User management"), "message includes milestone name");
232
+ assert.ok(msg.includes("- Slice: S01 - Authentication"), "message includes slice name");
233
+ assert.ok(msg.includes("- Task: T02 - implement user authentication"), "message includes task name");
223
234
  assert.ok(msg.includes("GSD-Task: S01/T02"), "GSD-Task trailer in body");
235
+ assert.ok(!msg.includes("chore: auto-commit after execute-task"), "message does not use generic fallback");
224
236
  });
225
237
 
226
238
  test('buildTaskCommitMessage sanitizes subject text', () => {
@@ -4,8 +4,6 @@
4
4
  * Verifies that when auto-mode transitions between milestones, the
5
5
  * worktree lifecycle is handled: old worktree merged, new worktree created.
6
6
  *
7
- * Uses source-level checks since the full auto-mode dispatch loop
8
- * requires the @gsd/pi-coding-agent runtime.
9
7
  */
10
8
 
11
9
  import test from "node:test";
@@ -119,48 +117,3 @@ test("worktree swap on milestone transition: merge old, create new", () => {
119
117
  }
120
118
  }
121
119
  });
122
-
123
- // ─── Verify the transition code path exists in auto.ts ──────────────────────
124
-
125
- test("auto/phases.ts milestone transition block contains worktree lifecycle", () => {
126
- const phasesSrc = readFileSync(
127
- join(__dirname, "../..", "auto", "phases.ts"),
128
- "utf-8",
129
- );
130
-
131
- // The resolver handles worktree merge + enter inside the milestone transition block
132
- assert.ok(
133
- phasesSrc.includes("Worktree lifecycle on milestone transition"),
134
- "auto/phases.ts should contain the worktree lifecycle comment marker",
135
- );
136
- assert.ok(
137
- phasesSrc.includes("resolver.mergeAndExit") && phasesSrc.includes("mid !== s.currentMilestoneId"),
138
- "auto/phases.ts should call resolver.mergeAndExit during milestone transition",
139
- );
140
- assert.ok(
141
- phasesSrc.includes("resolver.enterMilestone"),
142
- "auto/phases.ts should call resolver.enterMilestone for incoming milestone",
143
- );
144
- });
145
-
146
- // ─── Verify worktree-resolver mergeAndExit preserves branch on missing roadmap (#1573) ──
147
-
148
- test("worktree-resolver mergeAndExit preserves branch when roadmap is missing (#1573)", () => {
149
- const resolverSrc = readFileSync(
150
- join(__dirname, "../..", "worktree-resolver.ts"),
151
- "utf-8",
152
- );
153
-
154
- // The fallback teardown must pass preserveBranch: true to prevent orphaning commits
155
- assert.ok(
156
- resolverSrc.includes("preserveBranch: true"),
157
- "worktree-resolver.ts should pass preserveBranch: true in the no-roadmap fallback",
158
- );
159
-
160
- // The worktree path should be tried as a fallback for roadmap resolution
161
- assert.ok(
162
- resolverSrc.includes("this.s.basePath !== originalBase") ||
163
- resolverSrc.includes("roadmap-fallback"),
164
- "worktree-resolver.ts should try resolving roadmap from worktree path as fallback",
165
- );
166
- });