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,345 +1,138 @@
1
- /**
2
- * Triage dispatch ordering contract tests.
3
- *
4
- * These tests verify structural invariants of the triage integration
5
- * by inspecting the actual source code of auto-post-unit.ts, auto.ts,
6
- * and post-unit-hooks.ts. Full behavioral testing requires the
7
- * @gsd/pi-coding-agent runtime.
8
- */
1
+ // GSD-2 — Triage and quick-task dispatch behavior tests.
9
2
 
10
3
  import test from "node:test";
11
4
  import assert from "node:assert/strict";
12
- import { readFileSync } from "node:fs";
13
- import { join, dirname } from "node:path";
14
- import { fileURLToPath } from "node:url";
15
-
16
- const __dirname = dirname(fileURLToPath(import.meta.url));
17
- const hooksPath = join(__dirname, "..", "post-unit-hooks.ts");
18
- const registryPath = join(__dirname, "..", "rule-registry.ts");
19
- const autoPromptsPath = join(__dirname, "..", "auto-prompts.ts");
20
-
21
- // After decomposition, triage/dispatch logic lives in auto-post-unit.ts
22
- const postUnitSrc = readFileSync(join(__dirname, "..", "auto-post-unit.ts"), "utf-8");
23
- // auto.ts retains top-level orchestration and imports
24
- const autoSrc = [
25
- readFileSync(join(__dirname, "..", "auto.ts"), "utf-8"),
26
- postUnitSrc,
27
- readFileSync(join(__dirname, "..", "auto-start.ts"), "utf-8"),
28
- ].join("\n");
29
- // Hook exclusion logic lives in the rule-registry (facade delegates there)
30
- const hooksSrc = [
31
- readFileSync(hooksPath, "utf-8"),
32
- readFileSync(registryPath, "utf-8"),
33
- ].join("\n");
34
- const autoPromptsSrc = (() => { try { return readFileSync(autoPromptsPath, "utf-8"); } catch { return autoSrc; } })();
35
-
36
- // ─── Hook exclusion ──────────────────────────────────────────────────────────
37
-
38
- test("dispatch: triage-captures excluded from post-unit hook triggering", () => {
39
- assert.ok(
40
- hooksSrc.includes('"triage-captures"'),
41
- "post-unit-hooks.ts should reference triage-captures",
42
- );
43
- assert.ok(
44
- hooksSrc.includes('completedUnitType === "triage-captures"'),
45
- "should check for triage-captures in the hook exclusion guard",
46
- );
47
- });
48
-
49
- // ─── Triage check placement ──────────────────────────────────────────────────
50
-
51
- test("dispatch: triage check appears after hook section and before stepMode check", () => {
52
- const triageCheckIndex = postUnitSrc.indexOf("// ── Triage check");
53
- const quickTaskIndex = postUnitSrc.indexOf("// ── Quick-task dispatch");
54
- const stepModeIndex = postUnitSrc.indexOf("if (s.stepMode)");
55
-
56
- assert.ok(triageCheckIndex > 0, "triage check block should exist");
57
- assert.ok(quickTaskIndex > 0, "quick-task dispatch block should exist");
58
- assert.ok(stepModeIndex > 0, "step mode check should exist");
59
-
60
- assert.ok(
61
- triageCheckIndex < quickTaskIndex,
62
- "triage check should come before quick-task dispatch",
63
- );
64
- assert.ok(
65
- quickTaskIndex < stepModeIndex,
66
- "quick-task dispatch should come before stepMode check",
67
- );
68
- });
69
-
70
- // ─── Guard conditions ────────────────────────────────────────────────────────
71
-
72
- test("dispatch: triage check guards against step mode", () => {
73
- const triageBlock = postUnitSrc.slice(
74
- postUnitSrc.indexOf("// ── Triage check"),
75
- postUnitSrc.indexOf("// ── Quick-task dispatch"),
76
- );
77
- assert.ok(
78
- triageBlock.includes("!s.stepMode"),
79
- "triage block should guard against step mode",
80
- );
81
- });
82
-
83
- test("dispatch: triage check guards against hook unit types", () => {
84
- const triageBlock = postUnitSrc.slice(
85
- postUnitSrc.indexOf("// ── Triage check"),
86
- postUnitSrc.indexOf("// ── Quick-task dispatch"),
87
- );
88
- assert.ok(
89
- triageBlock.includes('!s.currentUnit.type.startsWith("hook/")'),
90
- "triage block should not fire for hook units",
91
- );
92
- });
93
-
94
- test("dispatch: triage check guards against triage-on-triage", () => {
95
- const triageBlock = postUnitSrc.slice(
96
- postUnitSrc.indexOf("// ── Triage check"),
97
- postUnitSrc.indexOf("// ── Quick-task dispatch"),
98
- );
99
- assert.ok(
100
- triageBlock.includes('s.currentUnit.type !== "triage-captures"'),
101
- "triage block should not fire for triage units",
102
- );
103
- });
104
-
105
- test("dispatch: triage check guards against quick-task triggering triage", () => {
106
- const triageBlock = postUnitSrc.slice(
107
- postUnitSrc.indexOf("// ── Triage check"),
108
- postUnitSrc.indexOf("// ── Quick-task dispatch"),
109
- );
110
- assert.ok(
111
- triageBlock.includes('s.currentUnit.type !== "quick-task"'),
112
- "triage block should not fire for quick-task units",
113
- );
114
- });
115
-
116
- test("dispatch: triage dispatch keeps the loop in continue mode", () => {
117
- const triageBlock = postUnitSrc.slice(
118
- postUnitSrc.indexOf("// ── Triage check"),
119
- postUnitSrc.indexOf("// ── Quick-task dispatch"),
120
- );
121
- assert.ok(
122
- triageBlock.includes('return "continue"') || triageBlock.includes("return enqueueSidecar("),
123
- "triage dispatch should return 'continue' after enqueuing sidecar work",
124
- );
125
- });
126
-
127
- test("dispatch: triage imports hasPendingCaptures and loadPendingCaptures", () => {
128
- assert.ok(
129
- autoSrc.includes("hasPendingCaptures") && autoSrc.includes("loadPendingCaptures"),
130
- "should import capture functions",
131
- );
132
- assert.ok(
133
- autoSrc.includes('from "./captures.js"'),
134
- "should import from captures module",
135
- );
136
- });
137
-
138
- // ─── Prompt integration ──────────────────────────────────────────────────────
139
-
140
- test("dispatch: replan prompt builder loads capture context", () => {
141
- const src = autoPromptsSrc;
142
- assert.ok(
143
- src.includes("loadReplanCaptures"),
144
- "buildReplanSlicePrompt should load replan captures",
145
- );
146
- assert.ok(
147
- src.includes("captureContext"),
148
- "buildReplanSlicePrompt should pass captureContext to template",
149
- );
150
- });
151
-
152
- test("dispatch: reassess prompt builder loads deferred captures", () => {
153
- const src = autoPromptsSrc;
154
- assert.ok(
155
- src.includes("loadDeferredCaptures"),
156
- "buildReassessRoadmapPrompt should load deferred captures",
157
- );
158
- assert.ok(
159
- src.includes("deferredCaptures"),
160
- "buildReassessRoadmapPrompt should pass deferredCaptures to template",
161
- );
162
- });
163
-
164
- // ─── Prompt templates ────────────────────────────────────────────────────────
165
-
166
- test("dispatch: replan prompt template includes captureContext variable", () => {
167
- const promptPath = join(__dirname, "..", "prompts", "replan-slice.md");
168
- const prompt = readFileSync(promptPath, "utf-8");
169
- assert.ok(
170
- prompt.includes("{{captureContext}}"),
171
- "replan-slice.md should include {{captureContext}}",
172
- );
173
- });
174
-
175
- test("dispatch: reassess prompt template includes deferredCaptures variable", () => {
176
- const promptPath = join(__dirname, "..", "prompts", "reassess-roadmap.md");
177
- const prompt = readFileSync(promptPath, "utf-8");
178
- assert.ok(
179
- prompt.includes("{{deferredCaptures}}"),
180
- "reassess-roadmap.md should include {{deferredCaptures}}",
181
- );
182
- });
183
-
184
- test("dispatch: triage prompt template exists and has classification criteria", () => {
185
- const promptPath = join(__dirname, "..", "prompts", "triage-captures.md");
186
- const prompt = readFileSync(promptPath, "utf-8");
187
- assert.ok(prompt.includes("quick-task"), "should have quick-task classification");
188
- assert.ok(prompt.includes("inject"), "should have inject classification");
189
- assert.ok(prompt.includes("defer"), "should have defer classification");
190
- assert.ok(prompt.includes("replan"), "should have replan classification");
191
- assert.ok(prompt.includes("note"), "should have note classification");
192
- assert.ok(prompt.includes("{{pendingCaptures}}"), "should have pending captures variable");
193
- });
194
-
195
- // ─── Dashboard integration ───────────────────────────────────────────────────
196
-
197
- test("dashboard: AutoDashboardData includes pendingCaptureCount field", () => {
198
- assert.ok(
199
- autoSrc.includes("pendingCaptureCount"),
200
- "auto.ts should have pendingCaptureCount in AutoDashboardData",
201
- );
202
- });
203
-
204
- test("dashboard: getAutoDashboardData computes pendingCaptureCount", () => {
205
- assert.ok(
206
- autoSrc.includes("pendingCaptureCount = countPendingCaptures") ||
207
- autoSrc.includes("pendingCaptureCount = countPendingCaptures(basePath)"),
208
- "getAutoDashboardData should compute pendingCaptureCount from countPendingCaptures (single-read)",
209
- );
210
- });
211
-
212
- test("dashboard: overlay renders pending captures badge", () => {
213
- const overlayPath = join(__dirname, "..", "dashboard-overlay.ts");
214
- const overlaySrc = readFileSync(overlayPath, "utf-8");
215
- assert.ok(
216
- overlaySrc.includes("pendingCaptureCount"),
217
- "dashboard-overlay.ts should reference pendingCaptureCount",
218
- );
219
- assert.ok(
220
- overlaySrc.includes("pending capture"),
221
- "dashboard-overlay.ts should show pending captures text",
222
- );
223
- });
224
-
225
- test("dashboard: overlay labels triage-captures and quick-task unit types", () => {
226
- const overlayPath = join(__dirname, "..", "dashboard-overlay.ts");
227
- const overlaySrc = readFileSync(overlayPath, "utf-8");
228
- assert.ok(
229
- overlaySrc.includes('"triage-captures"'),
230
- "unitLabel should handle triage-captures",
231
- );
232
- assert.ok(
233
- overlaySrc.includes('"quick-task"'),
234
- "unitLabel should handle quick-task",
235
- );
236
- });
237
-
238
- // ─── Post-triage resolution execution ─────────────────────────────────────────
239
-
240
- test("dispatch: post-triage resolution executor fires after triage-captures unit", () => {
241
- const postTriageBlock = postUnitSrc.slice(
242
- postUnitSrc.indexOf("Post-triage: execute actionable resolutions"),
243
- );
244
- assert.ok(
245
- postTriageBlock.includes('s.currentUnit.type === "triage-captures"'),
246
- "should check for triage-captures unit completion",
247
- );
248
- assert.ok(
249
- postTriageBlock.includes("executeTriageResolutions"),
250
- "should call executeTriageResolutions",
251
- );
252
- });
253
-
254
- test("dispatch: post-triage executor handles inject results", () => {
255
- const postTriageBlock = postUnitSrc.slice(
256
- postUnitSrc.indexOf("Post-triage: execute actionable resolutions"),
257
- );
258
- assert.ok(
259
- postTriageBlock.includes("triageResult.injected"),
260
- "should check injected count",
261
- );
262
- });
263
-
264
- test("dispatch: post-triage executor handles replan results", () => {
265
- const postTriageBlock = postUnitSrc.slice(
266
- postUnitSrc.indexOf("Post-triage: execute actionable resolutions"),
267
- );
268
- assert.ok(
269
- postTriageBlock.includes("triageResult.replanned"),
270
- "should check replanned count",
271
- );
272
- });
273
-
274
- test("dispatch: post-triage executor queues quick-tasks", () => {
275
- const postTriageBlock = postUnitSrc.slice(
276
- postUnitSrc.indexOf("Post-triage: execute actionable resolutions"),
277
- );
278
- assert.ok(
279
- postTriageBlock.includes("s.pendingQuickTasks"),
280
- "should push quick-tasks to s.pendingQuickTasks queue",
281
- );
282
- });
283
-
284
- // ─── Quick-task dispatch ──────────────────────────────────────────────────────
285
-
286
- test("dispatch: quick-task dispatch block exists after triage check", () => {
287
- const quickTaskBlock = postUnitSrc.indexOf("// ── Quick-task dispatch");
288
- const triageBlock = postUnitSrc.indexOf("// ── Triage check");
289
-
290
- assert.ok(quickTaskBlock > 0, "quick-task dispatch block should exist");
291
- assert.ok(
292
- quickTaskBlock > triageBlock,
293
- "quick-task dispatch should come after triage check",
294
- );
295
- });
296
-
297
- test("dispatch: quick-task dispatch uses buildQuickTaskPrompt", () => {
298
- const quickTaskSection = postUnitSrc.slice(
299
- postUnitSrc.indexOf("// ── Quick-task dispatch"),
300
- );
301
- assert.ok(
302
- quickTaskSection.includes("buildQuickTaskPrompt"),
303
- "should call buildQuickTaskPrompt for quick-task dispatch",
304
- );
305
- });
306
-
307
- test("dispatch: quick-task dispatch marks capture as executed", () => {
308
- const quickTaskSection = postUnitSrc.slice(
309
- postUnitSrc.indexOf("// ── Quick-task dispatch"),
310
- );
311
- assert.ok(
312
- quickTaskSection.includes("markCaptureExecuted"),
313
- "should mark capture as executed after dispatch",
314
- );
315
- });
316
-
317
- test("dispatch: quick-task dispatch keeps the loop in continue mode", () => {
318
- const quickTaskSection = postUnitSrc.slice(
319
- postUnitSrc.indexOf("// ── Quick-task dispatch"),
320
- postUnitSrc.indexOf("if (s.stepMode)"),
321
- );
322
- assert.ok(
323
- quickTaskSection.includes('return "continue"') || quickTaskSection.includes("return enqueueSidecar("),
324
- "quick-task dispatch should return 'continue' after enqueuing sidecar work",
325
- );
326
- });
327
-
328
- // ─── Post-unit hook exclusion for quick-task ──────────────────────────────────
329
-
330
- test("dispatch: quick-task excluded from post-unit hook triggering", () => {
331
- assert.ok(
332
- hooksSrc.includes('"quick-task"'),
333
- "post-unit-hooks.ts should reference quick-task",
334
- );
335
- });
336
-
337
- // ─── pendingQuickTasks queue lifecycle ────────────────────────────────────────
338
-
339
- test("dispatch: pendingQuickTasks queue is reset on auto-mode start/stop", () => {
340
- const resetMatches = autoSrc.match(/s\.pendingQuickTasks = \[\]/g);
341
- assert.ok(
342
- resetMatches && resetMatches.length >= 2,
343
- "s.pendingQuickTasks should be reset in start and stop paths",
344
- );
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
+ appendCapture,
11
+ countPendingCaptures,
12
+ hasPendingCaptures,
13
+ loadPendingCaptures,
14
+ markCaptureExecuted,
15
+ markCaptureResolved,
16
+ } from "../captures.ts";
17
+ import { checkPostUnitHooks } from "../post-unit-hooks.ts";
18
+ import {
19
+ _shouldDispatchQuickTaskForTest,
20
+ _shouldDispatchTriageForTest,
21
+ } from "../auto-post-unit.ts";
22
+ import {
23
+ buildQuickTaskPrompt,
24
+ loadDeferredCaptures,
25
+ loadReplanCaptures,
26
+ } from "../triage-resolution.ts";
27
+
28
+ function makeProject(): string {
29
+ const base = mkdtempSync(join(tmpdir(), "gsd-triage-dispatch-"));
30
+ mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01"), { recursive: true });
31
+ writeFileSync(
32
+ join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md"),
33
+ [
34
+ "# M001",
35
+ "",
36
+ "## Slices",
37
+ "- [ ] **S01: Slice** `risk:low` `depends:[]`",
38
+ ].join("\n"),
39
+ );
40
+ writeFileSync(
41
+ join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-PLAN.md"),
42
+ "# S01 Plan\n\n## Tasks\n- [ ] **T01: Task** `est:10m`\n",
43
+ );
44
+ return base;
45
+ }
46
+
47
+ test("post-unit hooks exclude triage and quick-task units", () => {
48
+ assert.equal(checkPostUnitHooks("triage-captures", "M001/S01/triage", "/tmp/project"), null);
49
+ assert.equal(checkPostUnitHooks("quick-task", "M001/CAP-1", "/tmp/project"), null);
50
+ });
51
+
52
+ test("triage dispatch guard excludes step mode, hook units, triage units, and quick tasks", () => {
53
+ const normal = { stepMode: false, currentUnit: { type: "execute-task", id: "M001/S01/T01", startedAt: 1 } };
54
+ assert.equal(_shouldDispatchTriageForTest(normal as any), true);
55
+ assert.equal(_shouldDispatchTriageForTest({ ...normal, stepMode: true } as any), false);
56
+ assert.equal(
57
+ _shouldDispatchTriageForTest({ stepMode: false, currentUnit: { type: "hook/review", id: "M001/S01/T01", startedAt: 1 } } as any),
58
+ false,
59
+ );
60
+ assert.equal(
61
+ _shouldDispatchTriageForTest({ stepMode: false, currentUnit: { type: "triage-captures", id: "M001/S01/triage", startedAt: 1 } } as any),
62
+ false,
63
+ );
64
+ assert.equal(
65
+ _shouldDispatchTriageForTest({ stepMode: false, currentUnit: { type: "quick-task", id: "M001/CAP-1", startedAt: 1 } } as any),
66
+ false,
67
+ );
68
+ });
69
+
70
+ test("quick-task dispatch guard requires queued captures and avoids quick-task recursion", () => {
71
+ const capture = {
72
+ id: "CAP-test",
73
+ text: "Fix typo",
74
+ timestamp: new Date().toISOString(),
75
+ status: "resolved" as const,
76
+ classification: "quick-task" as const,
77
+ };
78
+ assert.equal(
79
+ _shouldDispatchQuickTaskForTest({
80
+ stepMode: false,
81
+ currentUnit: { type: "execute-task", id: "M001/S01/T01", startedAt: 1 },
82
+ pendingQuickTasks: [capture],
83
+ } as any),
84
+ true,
85
+ );
86
+ assert.equal(
87
+ _shouldDispatchQuickTaskForTest({
88
+ stepMode: false,
89
+ currentUnit: { type: "quick-task", id: "M001/CAP-test", startedAt: 1 },
90
+ pendingQuickTasks: [capture],
91
+ } as any),
92
+ false,
93
+ );
94
+ assert.equal(
95
+ _shouldDispatchQuickTaskForTest({
96
+ stepMode: false,
97
+ currentUnit: { type: "execute-task", id: "M001/S01/T01", startedAt: 1 },
98
+ pendingQuickTasks: [],
99
+ } as any),
100
+ false,
101
+ );
102
+ });
103
+
104
+ test("capture lifecycle exposes pending, replan, deferred, and executed states", () => {
105
+ const base = makeProject();
106
+ try {
107
+ const pendingId = appendCapture(base, "Need a quick follow-up.");
108
+ const replanId = appendCapture(base, "Plan needs a new task.");
109
+ const deferId = appendCapture(base, "Create a future milestone.");
110
+
111
+ assert.equal(hasPendingCaptures(base), true);
112
+ assert.equal(countPendingCaptures(base), 3);
113
+ assert.deepEqual(loadPendingCaptures(base).map((entry) => entry.id).sort(), [deferId, pendingId, replanId].sort());
114
+
115
+ markCaptureResolved(base, replanId, "replan", "replan slice", "Need plan update", "M001");
116
+ markCaptureResolved(base, deferId, "defer", "defer milestone", "Out of current scope", "M001");
117
+ markCaptureExecuted(base, replanId);
118
+
119
+ assert.equal(loadReplanCaptures(base).some((entry) => entry.id === replanId), true);
120
+ assert.equal(loadDeferredCaptures(base).some((entry) => entry.id === deferId), true);
121
+ } finally {
122
+ rmSync(base, { recursive: true, force: true });
123
+ }
124
+ });
125
+
126
+ test("quick-task prompt carries capture identity and completion instruction", () => {
127
+ const prompt = buildQuickTaskPrompt({
128
+ id: "CAP-quick",
129
+ text: "Fix the CLI typo",
130
+ timestamp: new Date().toISOString(),
131
+ status: "resolved",
132
+ classification: "quick-task",
133
+ });
134
+
135
+ assert.match(prompt, /CAP-quick/);
136
+ assert.match(prompt, /Fix the CLI typo/);
137
+ assert.match(prompt, /Quick task complete/);
345
138
  });
@@ -2,9 +2,6 @@
2
2
 
3
3
  import test from "node:test";
4
4
  import assert from "node:assert/strict";
5
- import { readFileSync } from "node:fs";
6
- import { dirname, join } from "node:path";
7
- import { fileURLToPath } from "node:url";
8
5
 
9
6
  import {
10
7
  ARTIFACT_KEYS,
@@ -17,6 +14,10 @@ import {
17
14
  type UnitContextManifest,
18
15
  } from "../unit-context-manifest.ts";
19
16
  import { ALLOWED_PLANNING_DISPATCH_AGENTS } from "../bootstrap/write-gate.ts";
17
+ import {
18
+ getRequiredWorkflowToolsForAutoUnit,
19
+ getRequiredWorkflowToolsForGuidedUnit,
20
+ } from "../workflow-mcp.ts";
20
21
 
21
22
  // ─── Coverage: every known unit type has a manifest ──────────────────────
22
23
 
@@ -41,29 +42,11 @@ test("#4782 phase 1: every UNIT_MANIFESTS entry corresponds to a known unit type
41
42
 
42
43
  // ─── Coverage: every unitType stringly-typed in auto-dispatch.ts is known ─
43
44
 
44
- test("#4782 phase 1: every unitType string in auto-dispatch.ts has a manifest", () => {
45
- // Source-only coverage check read the dispatcher and enumerate its
46
- // unitType literals. This is a CI guard against manifest drift: if a
47
- // new dispatch rule is added without a corresponding manifest entry,
48
- // this test fails loudly. Read-only check of source text; the cheapest
49
- // way to enumerate declared unit types without running the dispatcher.
50
- // allow-source-grep: enumerate unitType literals for CI coverage guard
51
- const __dirname = dirname(fileURLToPath(import.meta.url));
52
- const dispatchSrc = readFileSync(join(__dirname, "..", "auto-dispatch.ts"), "utf-8");
53
- const matches = Array.from(dispatchSrc.matchAll(/unitType:\s*"([^"]+)"/g));
54
- const seen = new Set<string>();
55
- for (const m of matches) {
56
- const t = m[1];
57
- if (!t) continue;
58
- seen.add(t);
59
- }
60
- const missing: string[] = [];
61
- for (const t of seen) {
62
- if (!UNIT_MANIFESTS[t as keyof typeof UNIT_MANIFESTS]) {
63
- missing.push(t);
64
- }
45
+ test("#4782 phase 1: workflow tool policy maps are defined for every known unit type", () => {
46
+ for (const unitType of KNOWN_UNIT_TYPES) {
47
+ assert.ok(Array.isArray(getRequiredWorkflowToolsForAutoUnit(unitType)));
48
+ assert.ok(Array.isArray(getRequiredWorkflowToolsForGuidedUnit(unitType)));
65
49
  }
66
- assert.deepEqual(missing, [], `unit types dispatched in auto-dispatch.ts but missing from UNIT_MANIFESTS: ${missing.join(", ")}`);
67
50
  });
68
51
 
69
52
  // ─── Shape: every manifest conforms to the schema invariants ──────────────
@@ -13,7 +13,7 @@ import {
13
13
  insertSlice,
14
14
  } from "../gsd-db.ts";
15
15
  import { registerAutoWorker } from "../db/auto-workers.ts";
16
- import { claimMilestoneLease } from "../db/milestone-leases.ts";
16
+ import { claimMilestoneLease, releaseMilestoneLease } from "../db/milestone-leases.ts";
17
17
  import {
18
18
  recordDispatchClaim,
19
19
  markRunning,
@@ -105,6 +105,55 @@ test("partial unique index rejects double-claim of the same active unit", (t) =>
105
105
  }
106
106
  });
107
107
 
108
+ test("recordDispatchClaim cancels stale active dispatch after lease takeover", (t) => {
109
+ const base = makeBase();
110
+ t.after(() => cleanup(base));
111
+ const { workerId: firstWorkerId, leaseToken: firstLeaseToken } = setup(base);
112
+
113
+ const first = recordDispatchClaim({
114
+ traceId: "t-first",
115
+ workerId: firstWorkerId,
116
+ milestoneLeaseToken: firstLeaseToken,
117
+ milestoneId: "M001",
118
+ sliceId: "S01",
119
+ unitType: "plan-slice",
120
+ unitId: "M001/S01",
121
+ });
122
+ assert.equal(first.ok, true);
123
+ if (!first.ok) return;
124
+ markRunning(first.dispatchId);
125
+
126
+ assert.equal(releaseMilestoneLease(firstWorkerId, "M001", firstLeaseToken), true);
127
+ const takeoverWorkerId = registerAutoWorker({ projectRootRealpath: base });
128
+ const takeoverLease = claimMilestoneLease(takeoverWorkerId, "M001");
129
+ assert.equal(takeoverLease.ok, true);
130
+ if (!takeoverLease.ok) return;
131
+
132
+ const second = recordDispatchClaim({
133
+ traceId: "t-takeover",
134
+ workerId: takeoverWorkerId,
135
+ milestoneLeaseToken: takeoverLease.token,
136
+ milestoneId: "M001",
137
+ sliceId: "S01",
138
+ unitType: "plan-slice",
139
+ unitId: "M001/S01",
140
+ attemptN: 2,
141
+ });
142
+
143
+ assert.equal(second.ok, true);
144
+ if (!second.ok) return;
145
+
146
+ const recent = getRecentForUnit("M001/S01", 5);
147
+ assert.equal(recent.length, 2);
148
+ assert.equal(recent[0].id, second.dispatchId);
149
+ assert.equal(recent[0].status, "claimed");
150
+ assert.equal(recent[0].worker_id, takeoverWorkerId);
151
+ assert.equal(recent[0].attempt_n, 2);
152
+ assert.equal(recent[1].id, first.dispatchId);
153
+ assert.equal(recent[1].status, "canceled");
154
+ assert.equal(recent[1].exit_reason, "stale-dispatch-lease-takeover");
155
+ });
156
+
108
157
  test("after markCompleted, a fresh claim for the same unit succeeds", (t) => {
109
158
  const base = makeBase();
110
159
  t.after(() => cleanup(base));