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,444 +1,84 @@
1
- // Tests for GSD visualizer data loader.
2
- // Verifies the VisualizerData interface shape and source-file contracts.
3
-
4
- import { readFileSync } from "node:fs";
5
- import { join, dirname } from "node:path";
6
- import { fileURLToPath } from "node:url";
7
- import { test } from 'node:test';
8
- import assert from 'node:assert/strict';
9
-
10
- const __dirname = dirname(fileURLToPath(import.meta.url));
11
-
12
- const dataPath = join(__dirname, "..", "visualizer-data.ts");
13
- const dataSrc = readFileSync(dataPath, "utf-8");
14
-
15
- console.log("\n=== visualizer-data.ts source contracts ===");
16
-
17
- // Interface exports
18
- assert.ok(
19
- dataSrc.includes("export interface VisualizerData"),
20
- "exports VisualizerData interface",
21
- );
22
-
23
- assert.ok(
24
- dataSrc.includes("export interface VisualizerMilestone"),
25
- "exports VisualizerMilestone interface",
26
- );
27
-
28
- assert.ok(
29
- dataSrc.includes("export interface VisualizerSlice"),
30
- "exports VisualizerSlice interface",
31
- );
32
-
33
- assert.ok(
34
- dataSrc.includes("export interface VisualizerTask"),
35
- "exports VisualizerTask interface",
36
- );
37
-
38
- // New interfaces
39
- assert.ok(
40
- dataSrc.includes("export interface CriticalPathInfo"),
41
- "exports CriticalPathInfo interface",
42
- );
43
-
44
- assert.ok(
45
- dataSrc.includes("export interface AgentActivityInfo"),
46
- "exports AgentActivityInfo interface",
47
- );
48
-
49
- assert.ok(
50
- dataSrc.includes("export interface ChangelogEntry"),
51
- "exports ChangelogEntry interface",
52
- );
53
-
54
- assert.ok(
55
- dataSrc.includes("export interface ChangelogInfo"),
56
- "exports ChangelogInfo interface",
57
- );
58
-
59
- assert.ok(
60
- dataSrc.includes("export interface SliceVerification"),
61
- "exports SliceVerification interface",
62
- );
63
-
64
- assert.ok(
65
- dataSrc.includes("export interface KnowledgeInfo"),
66
- "exports KnowledgeInfo interface",
67
- );
68
-
69
- assert.ok(
70
- dataSrc.includes("export interface CapturesInfo"),
71
- "exports CapturesInfo interface",
72
- );
73
-
74
- assert.ok(
75
- dataSrc.includes("export interface HealthInfo"),
76
- "exports HealthInfo interface",
77
- );
78
-
79
- assert.ok(
80
- dataSrc.includes("export interface VisualizerDiscussionState"),
81
- "exports VisualizerDiscussionState interface",
82
- );
83
-
84
- assert.ok(
85
- dataSrc.includes("export type DiscussionState"),
86
- "exports DiscussionState type",
87
- );
88
-
89
- assert.ok(
90
- dataSrc.includes("export interface VisualizerSliceRef"),
91
- "exports VisualizerSliceRef interface",
92
- );
93
-
94
- assert.ok(
95
- dataSrc.includes("export interface VisualizerSliceActivity"),
96
- "exports VisualizerSliceActivity interface",
97
- );
98
-
99
- assert.ok(
100
- dataSrc.includes("export interface VisualizerStats"),
101
- "exports VisualizerStats interface",
102
- );
103
-
104
- // Function export
105
- assert.ok(
106
- dataSrc.includes("export async function loadVisualizerData"),
107
- "exports loadVisualizerData function",
108
- );
109
-
110
- assert.ok(
111
- dataSrc.includes("export function computeCriticalPath"),
112
- "exports computeCriticalPath function",
113
- );
114
-
115
- // Data source usage
116
- assert.ok(
117
- dataSrc.includes("deriveState"),
118
- "uses deriveState for state derivation",
119
- );
120
-
121
- assert.ok(
122
- dataSrc.includes("findMilestoneIds"),
123
- "uses findMilestoneIds to enumerate milestones",
124
- );
125
-
126
- assert.ok(
127
- dataSrc.includes("parseRoadmap"),
128
- "uses parseRoadmap for roadmap parsing",
129
- );
130
-
131
- assert.ok(
132
- dataSrc.includes("parsePlan"),
133
- "uses parsePlan for plan parsing",
134
- );
135
-
136
- assert.ok(
137
- dataSrc.includes("parseSummary"),
138
- "uses parseSummary for changelog parsing",
139
- );
140
-
141
- assert.ok(
142
- dataSrc.includes("getLedger"),
143
- "uses getLedger for in-memory metrics",
144
- );
145
-
146
- assert.ok(
147
- dataSrc.includes("loadLedgerFromDisk"),
148
- "uses loadLedgerFromDisk as fallback",
149
- );
150
-
151
- assert.ok(
152
- dataSrc.includes("getProjectTotals"),
153
- "uses getProjectTotals for aggregation",
154
- );
155
-
156
- assert.ok(
157
- dataSrc.includes("aggregateByPhase"),
158
- "uses aggregateByPhase",
159
- );
160
-
161
- assert.ok(
162
- dataSrc.includes("aggregateBySlice"),
163
- "uses aggregateBySlice",
164
- );
165
-
166
- assert.ok(
167
- dataSrc.includes("aggregateByModel"),
168
- "uses aggregateByModel",
169
- );
170
-
171
- assert.ok(
172
- dataSrc.includes("aggregateByTier"),
173
- "uses aggregateByTier",
174
- );
175
-
176
- assert.ok(
177
- dataSrc.includes("formatTierSavings"),
178
- "uses formatTierSavings",
179
- );
180
-
181
- assert.ok(
182
- dataSrc.includes("loadAllCaptures"),
183
- "uses loadAllCaptures",
184
- );
185
-
186
- assert.ok(
187
- dataSrc.includes("countPendingCaptures"),
188
- "uses countPendingCaptures",
189
- );
190
-
191
- assert.ok(
192
- dataSrc.includes("loadEffectiveGSDPreferences"),
193
- "uses loadEffectiveGSDPreferences",
194
- );
195
-
196
- assert.ok(
197
- dataSrc.includes("resolveGsdRootFile"),
198
- "uses resolveGsdRootFile for KNOWLEDGE path",
199
- );
200
-
201
- // Interface fields
202
- assert.ok(
203
- dataSrc.includes("dependsOn: string[]"),
204
- "VisualizerMilestone has dependsOn field",
205
- );
206
-
207
- assert.ok(
208
- dataSrc.includes("depends: string[]"),
209
- "VisualizerSlice has depends field",
210
- );
211
-
212
- assert.ok(
213
- dataSrc.includes("totals: ProjectTotals | null"),
214
- "VisualizerData has nullable totals",
215
- );
216
-
217
- assert.ok(
218
- dataSrc.includes("units: UnitMetrics[]"),
219
- "VisualizerData has units array",
220
- );
221
-
222
- assert.ok(
223
- dataSrc.includes("estimate?: string"),
224
- "VisualizerTask has optional estimate field",
225
- );
226
-
227
- // New data model fields
228
- assert.ok(
229
- dataSrc.includes("criticalPath: CriticalPathInfo"),
230
- "VisualizerData has criticalPath field",
231
- );
232
-
233
- assert.ok(
234
- dataSrc.includes("remainingSliceCount: number"),
235
- "VisualizerData has remainingSliceCount field",
236
- );
237
-
238
- assert.ok(
239
- dataSrc.includes("agentActivity: AgentActivityInfo | null"),
240
- "VisualizerData has agentActivity field",
241
- );
242
-
243
- assert.ok(
244
- dataSrc.includes("changelog: ChangelogInfo"),
245
- "VisualizerData has changelog field",
246
- );
247
-
248
- assert.ok(
249
- dataSrc.includes("sliceVerifications: SliceVerification[]"),
250
- "VisualizerData has sliceVerifications field",
251
- );
252
-
253
- assert.ok(
254
- dataSrc.includes("knowledge: KnowledgeInfo"),
255
- "VisualizerData has knowledge field",
256
- );
257
-
258
- assert.ok(
259
- dataSrc.includes("captures: CapturesInfo"),
260
- "VisualizerData has captures field",
261
- );
262
-
263
- assert.ok(
264
- dataSrc.includes("health: HealthInfo"),
265
- "VisualizerData has health field",
266
- );
267
-
268
- assert.ok(
269
- dataSrc.includes("stats: VisualizerStats"),
270
- "VisualizerData has stats field",
271
- );
272
-
273
- assert.ok(
274
- dataSrc.includes("discussion: VisualizerDiscussionState[]"),
275
- "VisualizerData has discussion field",
276
- );
277
-
278
- assert.ok(
279
- dataSrc.includes("loadDiscussionState"),
280
- "uses loadDiscussionState helper",
281
- );
282
-
283
- assert.ok(
284
- dataSrc.includes("buildVisualizerStats"),
285
- "uses buildVisualizerStats helper",
286
- );
287
-
288
- assert.ok(
289
- dataSrc.includes("byTier: TierAggregate[]"),
290
- "VisualizerData has byTier field",
291
- );
292
-
293
- assert.ok(
294
- dataSrc.includes("tierSavingsLine: string"),
295
- "VisualizerData has tierSavingsLine field",
296
- );
297
-
298
- // completedAt must be coerced to String() to handle YAML Date objects (issue #644)
299
- assert.ok(
300
- dataSrc.includes("String(summary.frontmatter.completed_at"),
301
- "completedAt assignment coerces to String() for YAML Date safety",
302
- );
303
-
304
- assert.ok(
305
- dataSrc.includes("String(b.completedAt") && dataSrc.includes("String(a.completedAt"),
306
- "changelog sort coerces completedAt to String() for YAML Date safety",
307
- );
308
-
309
- // Verify overlay source exists and imports data module
310
- const overlayPath = join(__dirname, "..", "visualizer-overlay.ts");
311
- const overlaySrc = readFileSync(overlayPath, "utf-8");
312
-
313
- console.log("\n=== visualizer-overlay.ts source contracts ===");
314
-
315
- assert.ok(
316
- overlaySrc.includes("export class GSDVisualizerOverlay"),
317
- "exports GSDVisualizerOverlay class",
318
- );
319
-
320
- assert.ok(
321
- overlaySrc.includes("loadVisualizerData"),
322
- "overlay uses loadVisualizerData",
323
- );
324
-
325
- assert.ok(
326
- overlaySrc.includes("renderProgressView"),
327
- "overlay delegates to renderProgressView",
328
- );
329
-
330
- assert.ok(
331
- overlaySrc.includes("renderDepsView"),
332
- "overlay delegates to renderDepsView",
333
- );
334
-
335
- assert.ok(
336
- overlaySrc.includes("renderMetricsView"),
337
- "overlay delegates to renderMetricsView",
338
- );
339
-
340
- assert.ok(
341
- overlaySrc.includes("renderTimelineView"),
342
- "overlay delegates to renderTimelineView",
343
- );
344
-
345
- assert.ok(
346
- overlaySrc.includes("renderAgentView"),
347
- "overlay delegates to renderAgentView",
348
- );
349
-
350
- assert.ok(
351
- overlaySrc.includes("renderChangelogView"),
352
- "overlay delegates to renderChangelogView",
353
- );
354
-
355
- assert.ok(
356
- overlaySrc.includes("renderExportView"),
357
- "overlay delegates to renderExportView",
358
- );
359
-
360
- assert.ok(
361
- overlaySrc.includes("renderKnowledgeView"),
362
- "overlay delegates to renderKnowledgeView",
363
- );
364
-
365
- assert.ok(
366
- overlaySrc.includes("renderCapturesView"),
367
- "overlay delegates to renderCapturesView",
368
- );
369
-
370
- assert.ok(
371
- overlaySrc.includes("renderHealthView"),
372
- "overlay delegates to renderHealthView",
373
- );
374
-
375
- assert.ok(
376
- overlaySrc.includes("handleInput"),
377
- "overlay has handleInput method",
378
- );
379
-
380
- assert.ok(
381
- overlaySrc.includes("dispose"),
382
- "overlay has dispose method",
383
- );
384
-
385
- assert.ok(
386
- overlaySrc.includes("wrapInBox"),
387
- "overlay has wrapInBox helper",
388
- );
389
-
390
- assert.ok(
391
- overlaySrc.includes("activeTab"),
392
- "overlay tracks active tab",
393
- );
394
-
395
- assert.ok(
396
- overlaySrc.includes("scrollOffsets"),
397
- "overlay tracks per-tab scroll offsets",
398
- );
399
-
400
- assert.ok(
401
- overlaySrc.includes("filterMode"),
402
- "overlay has filterMode state",
403
- );
404
-
405
- assert.ok(
406
- overlaySrc.includes("filterText"),
407
- "overlay has filterText state",
408
- );
409
-
410
- assert.ok(
411
- overlaySrc.includes("filterField"),
412
- "overlay has filterField state",
413
- );
414
-
415
- assert.ok(
416
- overlaySrc.includes("TAB_COUNT"),
417
- "overlay defines TAB_COUNT",
418
- );
419
-
420
- assert.ok(
421
- overlaySrc.includes("0 Export"),
422
- "overlay has 10 tab labels",
423
- );
424
-
425
- // Verify commands/handlers/core.ts integration
426
- const coreHandlerPath = join(__dirname, "..", "commands", "handlers", "core.ts");
427
- const coreHandlerSrc = readFileSync(coreHandlerPath, "utf-8");
428
-
429
- console.log("\n=== commands/handlers/core.ts integration ===");
430
-
431
- assert.ok(
432
- coreHandlerSrc.includes('"visualize"'),
433
- "core.ts has visualize in subcommands array",
434
- );
435
-
436
- assert.ok(
437
- coreHandlerSrc.includes("GSDVisualizerOverlay"),
438
- "core.ts imports GSDVisualizerOverlay",
439
- );
440
-
441
- assert.ok(
442
- coreHandlerSrc.includes("handleVisualize"),
443
- "core.ts has handleVisualize handler",
444
- );
1
+ // GSD-2 Visualizer data behavior tests.
2
+
3
+ import test from "node:test";
4
+ import assert from "node:assert/strict";
5
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
6
+ import { join } from "node:path";
7
+ import { tmpdir } from "node:os";
8
+
9
+ import {
10
+ computeCriticalPath,
11
+ loadVisualizerData,
12
+ type VisualizerMilestone,
13
+ } from "../visualizer-data.ts";
14
+
15
+ test("computeCriticalPath follows milestone dependencies", () => {
16
+ const milestones: VisualizerMilestone[] = [
17
+ {
18
+ id: "M001",
19
+ title: "Foundation",
20
+ status: "active",
21
+ dependsOn: [],
22
+ slices: [{ id: "S01", title: "Foundation", done: false, active: false, risk: "low", depends: [], tasks: [] }],
23
+ },
24
+ {
25
+ id: "M002",
26
+ title: "Feature",
27
+ status: "active",
28
+ dependsOn: ["M001"],
29
+ slices: [{ id: "S01", title: "Build", done: false, active: true, risk: "medium", depends: [], tasks: [] }],
30
+ },
31
+ ];
32
+
33
+ const path = computeCriticalPath(milestones);
34
+ assert.deepEqual(path.milestonePath, ["M001", "M002"]);
35
+ assert.equal(path.milestoneSlack.has("M001"), true);
36
+ assert.equal(path.milestoneSlack.has("M002"), true);
37
+ });
38
+
39
+ test("loadVisualizerData hydrates milestones, captures, stats, and health fields", async () => {
40
+ const base = mkdtempSync(join(tmpdir(), "gsd-visualizer-data-"));
41
+ try {
42
+ const msDir = join(base, ".gsd", "milestones", "M001");
43
+ const sliceDir = join(msDir, "slices", "S01");
44
+ mkdirSync(sliceDir, { recursive: true });
45
+ writeFileSync(
46
+ join(msDir, "M001-ROADMAP.md"),
47
+ [
48
+ "# M001: Visualizer",
49
+ "",
50
+ "## Slices",
51
+ "- [ ] **S01: Build UI** `risk:low` `depends:[]`",
52
+ ].join("\n"),
53
+ );
54
+ writeFileSync(
55
+ join(sliceDir, "S01-PLAN.md"),
56
+ "# S01 Plan\n\n## Tasks\n- [ ] **T01: Render data** `est:10m`\n",
57
+ );
58
+ writeFileSync(
59
+ join(base, ".gsd", "CAPTURES.md"),
60
+ [
61
+ "# Captures",
62
+ "",
63
+ "### CAP-visual",
64
+ "**Text:** Investigate visualizer state",
65
+ "**Captured:** 2026-01-01T00:00:00.000Z",
66
+ "**Status:** pending",
67
+ "",
68
+ ].join("\n"),
69
+ );
70
+
71
+ const data = await loadVisualizerData(base);
72
+
73
+ assert.equal(data.milestones.length, 1);
74
+ assert.equal(data.milestones[0]?.id, "M001");
75
+ assert.equal(data.milestones[0]?.slices[0]?.id, "S01");
76
+ assert.equal(data.remainingSliceCount, 1);
77
+ assert.equal(data.captures.pendingCount, 1);
78
+ assert.equal(data.stats.missingCount, 1);
79
+ assert.ok(data.health);
80
+ assert.ok(data.criticalPath.milestonePath.length >= 1);
81
+ } finally {
82
+ rmSync(base, { recursive: true, force: true });
83
+ }
84
+ });
@@ -7,7 +7,9 @@ import test from "node:test";
7
7
  import type { AutoSession } from "../auto/session.ts";
8
8
  import type { IterationData } from "../auto/types.ts";
9
9
  import {
10
+ ensureDispatchLease,
10
11
  openDispatchClaim,
12
+ type EnsureDispatchLeaseDeps,
11
13
  type OpenDispatchClaimDeps,
12
14
  } from "../auto/workflow-dispatch-claim.ts";
13
15
 
@@ -49,6 +51,25 @@ function makeDeps(overrides?: Partial<OpenDispatchClaimDeps>): OpenDispatchClaim
49
51
  };
50
52
  }
51
53
 
54
+ function makeLeaseDeps(overrides?: Partial<EnsureDispatchLeaseDeps>): {
55
+ deps: EnsureDispatchLeaseDeps;
56
+ calls: unknown[];
57
+ failures: unknown[];
58
+ } {
59
+ const calls: unknown[] = [];
60
+ const failures: unknown[] = [];
61
+ const deps: EnsureDispatchLeaseDeps = {
62
+ claimMilestoneLease: (workerId, milestoneId) => {
63
+ calls.push(["claim", workerId, milestoneId]);
64
+ return { ok: true, token: 8, expiresAt: "2030-01-01T00:00:00.000Z" };
65
+ },
66
+ logLeaseRecovered: details => calls.push(["recovered", details]),
67
+ logLeaseRecoveryFailed: details => failures.push(details),
68
+ ...overrides,
69
+ };
70
+ return { deps, calls, failures };
71
+ }
72
+
52
73
  test("openDispatchClaim degrades when worker identity or lease token is missing", () => {
53
74
  assert.deepEqual(
54
75
  openDispatchClaim(makeSession({ workerId: null }), "flow", "turn", makeIterationData(), makeDeps({
@@ -156,3 +177,124 @@ test("openDispatchClaim degrades on claim write failures", () => {
156
177
  assert.deepEqual(outcome, { kind: "degraded" });
157
178
  assert.deepEqual(logged, [writeError]);
158
179
  });
180
+
181
+ test("ensureDispatchLease degrades without worker identity or milestone id", () => {
182
+ const { deps, calls } = makeLeaseDeps({
183
+ claimMilestoneLease: () => assert.fail("claimMilestoneLease should not be called"),
184
+ });
185
+
186
+ assert.deepEqual(
187
+ ensureDispatchLease(makeSession({ workerId: null }), "M001", deps),
188
+ { kind: "degraded", reason: "missing-worker" },
189
+ );
190
+ assert.deepEqual(
191
+ ensureDispatchLease(makeSession(), undefined, deps),
192
+ { kind: "degraded", reason: "missing-milestone" },
193
+ );
194
+ assert.deepEqual(calls, []);
195
+ });
196
+
197
+ test("ensureDispatchLease reuses an existing numeric token", () => {
198
+ const { deps, calls } = makeLeaseDeps({
199
+ claimMilestoneLease: () => assert.fail("claimMilestoneLease should not be called"),
200
+ });
201
+
202
+ const session = makeSession({ milestoneLeaseToken: 7 });
203
+ const outcome = ensureDispatchLease(session, "M001", deps);
204
+
205
+ assert.deepEqual(outcome, { kind: "ready", token: 7, recovered: false });
206
+ assert.equal(session.milestoneLeaseToken, 7);
207
+ assert.deepEqual(calls, []);
208
+ });
209
+
210
+ test("ensureDispatchLease claims a lease when the session has no token", () => {
211
+ const { deps, calls, failures } = makeLeaseDeps();
212
+ const session = makeSession({
213
+ currentMilestoneId: "M001",
214
+ milestoneLeaseToken: null,
215
+ });
216
+
217
+ const outcome = ensureDispatchLease(session, "M001", deps);
218
+
219
+ assert.deepEqual(outcome, { kind: "ready", token: 8, recovered: false });
220
+ assert.equal(session.currentMilestoneId, "M001");
221
+ assert.equal(session.milestoneLeaseToken, 8);
222
+ assert.deepEqual(calls, [
223
+ ["claim", "worker-1", "M001"],
224
+ ["recovered", {
225
+ milestoneId: "M001",
226
+ workerId: "worker-1",
227
+ token: 8,
228
+ recovered: false,
229
+ }],
230
+ ]);
231
+ assert.deepEqual(failures, []);
232
+ });
233
+
234
+ test("ensureDispatchLease force-reclaims after a stale dispatch claim", () => {
235
+ const { deps, calls } = makeLeaseDeps({
236
+ claimMilestoneLease: (workerId, milestoneId) => {
237
+ calls.push(["claim", workerId, milestoneId]);
238
+ return { ok: true, token: 9, expiresAt: "2030-01-01T00:00:00.000Z" };
239
+ },
240
+ });
241
+ const session = makeSession({ milestoneLeaseToken: 7 });
242
+
243
+ const outcome = ensureDispatchLease(session, "M001", deps, { forceReclaim: true });
244
+
245
+ assert.deepEqual(outcome, { kind: "ready", token: 9, recovered: true });
246
+ assert.equal(session.milestoneLeaseToken, 9);
247
+ assert.deepEqual(calls, [
248
+ ["claim", "worker-1", "M001"],
249
+ ["recovered", {
250
+ milestoneId: "M001",
251
+ workerId: "worker-1",
252
+ token: 9,
253
+ recovered: true,
254
+ }],
255
+ ]);
256
+ });
257
+
258
+ test("ensureDispatchLease blocks when another worker holds the lease", () => {
259
+ const { deps, failures } = makeLeaseDeps({
260
+ claimMilestoneLease: () => ({
261
+ ok: false,
262
+ error: "held_by",
263
+ byWorker: "worker-2",
264
+ expiresAt: "2030-01-01T00:00:00.000Z",
265
+ }),
266
+ });
267
+ const session = makeSession({ milestoneLeaseToken: null });
268
+
269
+ const outcome = ensureDispatchLease(session, "M001", deps);
270
+
271
+ assert.deepEqual(outcome, {
272
+ kind: "blocked",
273
+ reason: "Milestone M001 is held by worker worker-2 until 2030-01-01T00:00:00.000Z.",
274
+ });
275
+ assert.equal(session.milestoneLeaseToken, null);
276
+ assert.deepEqual(failures, [{
277
+ milestoneId: "M001",
278
+ workerId: "worker-1",
279
+ reason: "Milestone M001 is held by worker worker-2 until 2030-01-01T00:00:00.000Z.",
280
+ }]);
281
+ });
282
+
283
+ test("ensureDispatchLease fails closed on claim errors", () => {
284
+ const { deps, failures } = makeLeaseDeps({
285
+ claimMilestoneLease: () => {
286
+ throw new Error("db unavailable");
287
+ },
288
+ });
289
+ const session = makeSession({ milestoneLeaseToken: null });
290
+
291
+ const outcome = ensureDispatchLease(session, "M001", deps);
292
+
293
+ assert.deepEqual(outcome, { kind: "failed", reason: "db unavailable" });
294
+ assert.equal(session.milestoneLeaseToken, null);
295
+ assert.deepEqual(failures, [{
296
+ milestoneId: "M001",
297
+ workerId: "worker-1",
298
+ reason: "db unavailable",
299
+ }]);
300
+ });