@opengsd/gsd-pi 1.8.1 → 1.9.0-dev.97ef11e3

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 (613) hide show
  1. package/README.md +10 -8
  2. package/dist/cli.js +5 -1
  3. package/dist/headless-events.d.ts +2 -1
  4. package/dist/headless-events.js +11 -3
  5. package/dist/headless-milestone-readiness.d.ts +29 -0
  6. package/dist/headless-milestone-readiness.js +161 -0
  7. package/dist/headless.js +27 -3
  8. package/dist/print-mode-exit.d.ts +12 -0
  9. package/dist/print-mode-exit.js +14 -0
  10. package/dist/resources/.managed-resources-content-hash +1 -1
  11. package/dist/resources/GSD-WORKFLOW.md +18 -49
  12. package/dist/resources/extensions/browser-tools/capture.js +2 -77
  13. package/dist/resources/extensions/browser-tools/screenshot-constraints.js +83 -0
  14. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +17 -2
  15. package/dist/resources/extensions/claude-code-cli/turn-assembler.js +30 -2
  16. package/dist/resources/extensions/gsd/artifact-verification.js +3 -4
  17. package/dist/resources/extensions/gsd/auto/loop.js +24 -4
  18. package/dist/resources/extensions/gsd/auto/run-unit.js +19 -1
  19. package/dist/resources/extensions/gsd/auto/unit-phase.js +37 -5
  20. package/dist/resources/extensions/gsd/auto-artifact-paths.js +16 -10
  21. package/dist/resources/extensions/gsd/auto-dispatch.js +76 -19
  22. package/dist/resources/extensions/gsd/auto-post-unit.js +4 -0
  23. package/dist/resources/extensions/gsd/auto-prompts.js +137 -22
  24. package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
  25. package/dist/resources/extensions/gsd/auto-runtime-state.js +5 -5
  26. package/dist/resources/extensions/gsd/auto-start.js +29 -9
  27. package/dist/resources/extensions/gsd/auto-tool-tracking.js +40 -0
  28. package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +4 -0
  29. package/dist/resources/extensions/gsd/auto-worktree-sync.js +7 -3
  30. package/dist/resources/extensions/gsd/auto-worktree-teardown.js +1 -1
  31. package/dist/resources/extensions/gsd/auto.js +20 -6
  32. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -4
  33. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -7
  34. package/dist/resources/extensions/gsd/bootstrap/system-context.js +10 -3
  35. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +88 -50
  36. package/dist/resources/extensions/gsd/command-feedback.js +16 -12
  37. package/dist/resources/extensions/gsd/commands-verdict.js +10 -9
  38. package/dist/resources/extensions/gsd/compat/compat-marker.js +98 -6
  39. package/dist/resources/extensions/gsd/constants.js +12 -13
  40. package/dist/resources/extensions/gsd/context-masker.js +97 -21
  41. package/dist/resources/extensions/gsd/db/command-queue.js +7 -2
  42. package/dist/resources/extensions/gsd/db/engine.js +56 -18
  43. package/dist/resources/extensions/gsd/db/writers/cascades.js +5 -1
  44. package/dist/resources/extensions/gsd/db/writers/status.js +13 -3
  45. package/dist/resources/extensions/gsd/db-base-schema.js +28 -0
  46. package/dist/resources/extensions/gsd/db-migration-steps.js +30 -0
  47. package/dist/resources/extensions/gsd/db-schema-metadata.js +4 -1
  48. package/dist/resources/extensions/gsd/docs/preferences-reference.md +26 -4
  49. package/dist/resources/extensions/gsd/doctor-engine-checks.js +24 -8
  50. package/dist/resources/extensions/gsd/error-classifier.js +12 -2
  51. package/dist/resources/extensions/gsd/exec-sandbox.js +1 -0
  52. package/dist/resources/extensions/gsd/flat-phase-migration.js +168 -21
  53. package/dist/resources/extensions/gsd/git-service.js +19 -7
  54. package/dist/resources/extensions/gsd/gsd-db.js +262 -76
  55. package/dist/resources/extensions/gsd/guided-flow.js +40 -15
  56. package/dist/resources/extensions/gsd/markdown-renderer.js +20 -22
  57. package/dist/resources/extensions/gsd/md-importer.js +107 -20
  58. package/dist/resources/extensions/gsd/migrate/command.js +19 -162
  59. package/dist/resources/extensions/gsd/migrate/execution.js +98 -0
  60. package/dist/resources/extensions/gsd/migrate/plan.js +49 -0
  61. package/dist/resources/extensions/gsd/migrate/planning-writer.js +12 -17
  62. package/dist/resources/extensions/gsd/migrate/presentation.js +64 -0
  63. package/dist/resources/extensions/gsd/model-cost-table.js +2 -0
  64. package/dist/resources/extensions/gsd/model-router.js +11 -0
  65. package/dist/resources/extensions/gsd/parallel-eligibility.js +5 -4
  66. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +28 -43
  67. package/dist/resources/extensions/gsd/paths.js +70 -16
  68. package/dist/resources/extensions/gsd/phase-anchor.js +7 -2
  69. package/dist/resources/extensions/gsd/planning-subagent-policy.js +37 -0
  70. package/dist/resources/extensions/gsd/planning-subagent-registry.js +25 -0
  71. package/dist/resources/extensions/gsd/post-execution-checks.js +4 -4
  72. package/dist/resources/extensions/gsd/preferences-types.js +5 -0
  73. package/dist/resources/extensions/gsd/preferences-validation.js +48 -1
  74. package/dist/resources/extensions/gsd/preferences.js +17 -0
  75. package/dist/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  76. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +5 -5
  77. package/dist/resources/extensions/gsd/provider-payload-policy.js +16 -5
  78. package/dist/resources/extensions/gsd/safety/destructive-guard.js +1 -1
  79. package/dist/resources/extensions/gsd/safety/evidence-collector.js +26 -1
  80. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +30 -5
  81. package/dist/resources/extensions/gsd/skill-activation.js +17 -3
  82. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.js +125 -15
  83. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +17 -4
  84. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +5 -2
  85. package/dist/resources/extensions/gsd/stop-notice.js +24 -1
  86. package/dist/resources/extensions/gsd/sync-lock.js +13 -7
  87. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
  88. package/dist/resources/extensions/gsd/tools/complete-task.js +94 -6
  89. package/dist/resources/extensions/gsd/tools/plan-task.js +13 -15
  90. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +18 -15
  91. package/dist/resources/extensions/gsd/tools/reopen-milestone.js +14 -5
  92. package/dist/resources/extensions/gsd/tools/reopen-slice.js +15 -5
  93. package/dist/resources/extensions/gsd/tools/reopen-task.js +16 -10
  94. package/dist/resources/extensions/gsd/tools/replan-task.js +128 -0
  95. package/dist/resources/extensions/gsd/tools/rework-brief.js +74 -0
  96. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +81 -0
  97. package/dist/resources/extensions/gsd/unit-context-composer.js +28 -5
  98. package/dist/resources/extensions/gsd/unit-registry.js +4 -0
  99. package/dist/resources/extensions/gsd/uok/plan-v2.js +19 -3
  100. package/dist/resources/extensions/gsd/workflow-projections.js +2 -3
  101. package/dist/resources/extensions/gsd/workspace.js +2 -1
  102. package/dist/resources/extensions/gsd/worktree-state-projection.js +26 -18
  103. package/dist/resources/extensions/mac-tools/index.js +31 -9
  104. package/dist/resources/extensions/shared/interview-ui.js +43 -6
  105. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  106. package/dist/web/standalone/.next/BUILD_ID +1 -1
  107. package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
  108. package/dist/web/standalone/.next/build-manifest.json +3 -3
  109. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  110. package/dist/web/standalone/.next/required-server-files.json +3 -3
  111. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  112. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  122. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  125. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  126. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  128. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  131. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  138. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  150. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  172. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  182. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  188. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  204. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  208. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/app/index.html +1 -1
  218. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  219. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  220. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  221. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  222. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  223. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  224. package/dist/web/standalone/.next/server/app/page.js +2 -2
  225. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
  227. package/dist/web/standalone/.next/server/chunks/1991.js +2 -2
  228. package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
  229. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  230. package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
  231. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  232. package/dist/web/standalone/.next/server/middleware.js +3 -3
  233. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  234. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  235. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  236. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +1 -0
  237. package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
  238. package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
  239. package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
  240. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
  241. package/dist/web/standalone/.next/static/css/3b1ceb7abfb9a230.css +1 -0
  242. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  243. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  244. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  245. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  246. package/dist/web/standalone/package.json +0 -1
  247. package/dist/web/standalone/server.js +1 -1
  248. package/dist/web-mode.js +31 -3
  249. package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
  250. package/integrations/hermes/pyproject.toml +1 -1
  251. package/package.json +13 -10
  252. package/packages/cloud-mcp-gateway/package.json +2 -2
  253. package/packages/contracts/dist/workflow.d.ts +14 -0
  254. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  255. package/packages/contracts/dist/workflow.js +16 -0
  256. package/packages/contracts/dist/workflow.js.map +1 -1
  257. package/packages/contracts/package.json +1 -1
  258. package/packages/daemon/dist/cloud-config.d.ts +1 -1
  259. package/packages/daemon/dist/cloud-config.d.ts.map +1 -1
  260. package/packages/daemon/dist/cloud-config.js +5 -1
  261. package/packages/daemon/dist/cloud-config.js.map +1 -1
  262. package/packages/daemon/dist/cloud-config.test.js +51 -1
  263. package/packages/daemon/dist/cloud-config.test.js.map +1 -1
  264. package/packages/daemon/dist/local-tool-executor.d.ts.map +1 -1
  265. package/packages/daemon/dist/local-tool-executor.js +2 -0
  266. package/packages/daemon/dist/local-tool-executor.js.map +1 -1
  267. package/packages/daemon/package.json +6 -6
  268. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
  269. package/packages/gsd-agent-core/dist/compaction/compaction.js +36 -4
  270. package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
  271. package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
  272. package/packages/gsd-agent-core/dist/sdk.js +1 -0
  273. package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
  274. package/packages/gsd-agent-core/package.json +5 -5
  275. package/packages/gsd-agent-modes/package.json +7 -7
  276. package/packages/gsd-cloud/README.md +9 -3
  277. package/packages/gsd-cloud/dist/background-cli.test.d.ts +2 -0
  278. package/packages/gsd-cloud/dist/background-cli.test.d.ts.map +1 -0
  279. package/packages/gsd-cloud/dist/background-cli.test.js +248 -0
  280. package/packages/gsd-cloud/dist/background-cli.test.js.map +1 -0
  281. package/packages/gsd-cloud/dist/cli.d.ts +5 -0
  282. package/packages/gsd-cloud/dist/cli.d.ts.map +1 -0
  283. package/packages/gsd-cloud/dist/cli.js +266 -0
  284. package/packages/gsd-cloud/dist/cli.js.map +1 -0
  285. package/packages/gsd-cloud/dist/cloud-config.d.ts +19 -0
  286. package/packages/gsd-cloud/dist/cloud-config.d.ts.map +1 -0
  287. package/packages/gsd-cloud/dist/cloud-config.js +237 -0
  288. package/packages/gsd-cloud/dist/cloud-config.js.map +1 -0
  289. package/packages/gsd-cloud/dist/cloud-config.test.d.ts +2 -0
  290. package/packages/gsd-cloud/dist/cloud-config.test.d.ts.map +1 -0
  291. package/packages/gsd-cloud/dist/cloud-config.test.js +118 -0
  292. package/packages/gsd-cloud/dist/cloud-config.test.js.map +1 -0
  293. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts +2 -0
  294. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.d.ts.map +1 -0
  295. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js +37 -0
  296. package/packages/gsd-cloud/dist/cloud-gateway-lookup.test.js.map +1 -0
  297. package/packages/gsd-cloud/dist/cloud-runtime.d.ts +33 -0
  298. package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -0
  299. package/packages/gsd-cloud/dist/cloud-runtime.js +260 -0
  300. package/packages/gsd-cloud/dist/cloud-runtime.js.map +1 -0
  301. package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts +2 -0
  302. package/packages/gsd-cloud/dist/cloud-runtime.test.d.ts.map +1 -0
  303. package/packages/gsd-cloud/dist/cloud-runtime.test.js +88 -0
  304. package/packages/gsd-cloud/dist/cloud-runtime.test.js.map +1 -0
  305. package/packages/gsd-cloud/dist/cloud-token.d.ts +3 -0
  306. package/packages/gsd-cloud/dist/cloud-token.d.ts.map +1 -0
  307. package/packages/gsd-cloud/dist/cloud-token.js +37 -0
  308. package/packages/gsd-cloud/dist/cloud-token.js.map +1 -0
  309. package/packages/gsd-cloud/dist/config.d.ts +17 -0
  310. package/packages/gsd-cloud/dist/config.d.ts.map +1 -0
  311. package/packages/gsd-cloud/dist/config.js +146 -0
  312. package/packages/gsd-cloud/dist/config.js.map +1 -0
  313. package/packages/gsd-cloud/dist/device-flow.d.ts +24 -0
  314. package/packages/gsd-cloud/dist/device-flow.d.ts.map +1 -0
  315. package/packages/gsd-cloud/dist/device-flow.js +128 -0
  316. package/packages/gsd-cloud/dist/device-flow.js.map +1 -0
  317. package/packages/gsd-cloud/dist/device-flow.test.d.ts +2 -0
  318. package/packages/gsd-cloud/dist/device-flow.test.d.ts.map +1 -0
  319. package/packages/gsd-cloud/dist/device-flow.test.js +155 -0
  320. package/packages/gsd-cloud/dist/device-flow.test.js.map +1 -0
  321. package/packages/gsd-cloud/dist/executors/claude-executor.d.ts +6 -0
  322. package/packages/gsd-cloud/dist/executors/claude-executor.d.ts.map +1 -0
  323. package/packages/gsd-cloud/dist/executors/claude-executor.js +15 -0
  324. package/packages/gsd-cloud/dist/executors/claude-executor.js.map +1 -0
  325. package/packages/gsd-cloud/dist/executors/codex-executor.d.ts +6 -0
  326. package/packages/gsd-cloud/dist/executors/codex-executor.d.ts.map +1 -0
  327. package/packages/gsd-cloud/dist/executors/codex-executor.js +15 -0
  328. package/packages/gsd-cloud/dist/executors/codex-executor.js.map +1 -0
  329. package/packages/gsd-cloud/dist/executors/executor.d.ts +28 -0
  330. package/packages/gsd-cloud/dist/executors/executor.d.ts.map +1 -0
  331. package/packages/gsd-cloud/dist/executors/executor.js +11 -0
  332. package/packages/gsd-cloud/dist/executors/executor.js.map +1 -0
  333. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts +34 -0
  334. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.d.ts.map +1 -0
  335. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js +179 -0
  336. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.js.map +1 -0
  337. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts +2 -0
  338. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.d.ts.map +1 -0
  339. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js +44 -0
  340. package/packages/gsd-cloud/dist/executors/gsd-pi-executor.test.js.map +1 -0
  341. package/packages/gsd-cloud/dist/executors/index.d.ts +17 -0
  342. package/packages/gsd-cloud/dist/executors/index.d.ts.map +1 -0
  343. package/packages/gsd-cloud/dist/executors/index.js +29 -0
  344. package/packages/gsd-cloud/dist/executors/index.js.map +1 -0
  345. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts +36 -0
  346. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.d.ts.map +1 -0
  347. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js +176 -0
  348. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.js.map +1 -0
  349. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts +2 -0
  350. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.d.ts.map +1 -0
  351. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js +34 -0
  352. package/packages/gsd-cloud/dist/executors/mcp-stdio-client.test.js.map +1 -0
  353. package/packages/gsd-cloud/dist/index.d.ts +7 -0
  354. package/packages/gsd-cloud/dist/index.d.ts.map +1 -0
  355. package/packages/gsd-cloud/dist/index.js +8 -0
  356. package/packages/gsd-cloud/dist/index.js.map +1 -0
  357. package/packages/gsd-cloud/dist/inject-gateway.d.ts +16 -0
  358. package/packages/gsd-cloud/dist/inject-gateway.d.ts.map +1 -0
  359. package/packages/gsd-cloud/dist/inject-gateway.js +29 -0
  360. package/packages/gsd-cloud/dist/inject-gateway.js.map +1 -0
  361. package/packages/gsd-cloud/dist/inject-gateway.test.d.ts +2 -0
  362. package/packages/gsd-cloud/dist/inject-gateway.test.d.ts.map +1 -0
  363. package/packages/gsd-cloud/dist/inject-gateway.test.js +41 -0
  364. package/packages/gsd-cloud/dist/inject-gateway.test.js.map +1 -0
  365. package/packages/gsd-cloud/dist/logger.d.ts +25 -0
  366. package/packages/gsd-cloud/dist/logger.d.ts.map +1 -0
  367. package/packages/gsd-cloud/dist/logger.js +72 -0
  368. package/packages/gsd-cloud/dist/logger.js.map +1 -0
  369. package/packages/gsd-cloud/dist/runtime-process.d.ts +27 -0
  370. package/packages/gsd-cloud/dist/runtime-process.d.ts.map +1 -0
  371. package/packages/gsd-cloud/dist/runtime-process.js +272 -0
  372. package/packages/gsd-cloud/dist/runtime-process.js.map +1 -0
  373. package/packages/gsd-cloud/dist/runtime-process.test.d.ts +2 -0
  374. package/packages/gsd-cloud/dist/runtime-process.test.d.ts.map +1 -0
  375. package/packages/gsd-cloud/dist/runtime-process.test.js +97 -0
  376. package/packages/gsd-cloud/dist/runtime-process.test.js.map +1 -0
  377. package/packages/gsd-cloud/dist/types.d.ts +51 -0
  378. package/packages/gsd-cloud/dist/types.d.ts.map +1 -0
  379. package/packages/gsd-cloud/dist/types.js +9 -0
  380. package/packages/gsd-cloud/dist/types.js.map +1 -0
  381. package/packages/gsd-cloud/package.json +3 -3
  382. package/packages/mcp-server/README.md +15 -2
  383. package/packages/mcp-server/dist/cli-runner.d.ts +3 -0
  384. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -1
  385. package/packages/mcp-server/dist/cli-runner.js +119 -33
  386. package/packages/mcp-server/dist/cli-runner.js.map +1 -1
  387. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  388. package/packages/mcp-server/dist/server.js +5 -5
  389. package/packages/mcp-server/dist/server.js.map +1 -1
  390. package/packages/mcp-server/dist/workflow-tools.d.ts +4 -3
  391. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  392. package/packages/mcp-server/dist/workflow-tools.js +64 -2
  393. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  394. package/packages/mcp-server/package.json +4 -4
  395. package/packages/native/package.json +1 -1
  396. package/packages/pi-agent-core/dist/agent.d.ts +5 -1
  397. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  398. package/packages/pi-agent-core/dist/agent.js +2 -0
  399. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  400. package/packages/pi-agent-core/package.json +1 -1
  401. package/packages/pi-ai/dist/models.generated.d.ts +136 -0
  402. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  403. package/packages/pi-ai/dist/models.generated.js +124 -0
  404. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  405. package/packages/pi-ai/dist/providers/amazon-bedrock.js +1 -0
  406. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  407. package/packages/pi-ai/dist/providers/anthropic.js +25 -1
  408. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  409. package/packages/pi-ai/dist/providers/openai-codex-responses.js +1 -1
  410. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  411. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  412. package/packages/pi-ai/dist/providers/openai-completions.js +103 -0
  413. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  414. package/packages/pi-ai/dist/providers/openai-responses.js +1 -1
  415. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  416. package/packages/pi-ai/package.json +1 -1
  417. package/packages/pi-coding-agent/dist/core/capability-patches.js +1 -1
  418. package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
  419. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -1
  420. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  421. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +11 -1
  422. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  423. package/packages/pi-coding-agent/dist/core/settings-manager.js +8 -0
  424. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  425. package/packages/pi-coding-agent/package.json +7 -7
  426. package/packages/pi-tui/package.json +2 -2
  427. package/packages/rpc-client/package.json +2 -2
  428. package/pkg/package.json +1 -1
  429. package/src/resources/GSD-WORKFLOW.md +18 -49
  430. package/src/resources/extensions/browser-tools/capture.ts +2 -86
  431. package/src/resources/extensions/browser-tools/screenshot-constraints.ts +94 -0
  432. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +18 -1
  433. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -0
  434. package/src/resources/extensions/claude-code-cli/turn-assembler.ts +30 -2
  435. package/src/resources/extensions/gsd/artifact-verification.ts +3 -8
  436. package/src/resources/extensions/gsd/auto/loop.ts +48 -4
  437. package/src/resources/extensions/gsd/auto/run-unit.ts +20 -1
  438. package/src/resources/extensions/gsd/auto/unit-phase.ts +41 -5
  439. package/src/resources/extensions/gsd/auto-artifact-paths.ts +16 -9
  440. package/src/resources/extensions/gsd/auto-dispatch.ts +87 -19
  441. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -0
  442. package/src/resources/extensions/gsd/auto-prompts.ts +156 -20
  443. package/src/resources/extensions/gsd/auto-recovery.ts +10 -8
  444. package/src/resources/extensions/gsd/auto-runtime-state.ts +12 -7
  445. package/src/resources/extensions/gsd/auto-start.ts +31 -8
  446. package/src/resources/extensions/gsd/auto-tool-tracking.ts +56 -0
  447. package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +4 -0
  448. package/src/resources/extensions/gsd/auto-worktree-sync.ts +10 -3
  449. package/src/resources/extensions/gsd/auto-worktree-teardown.ts +1 -1
  450. package/src/resources/extensions/gsd/auto.ts +25 -8
  451. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +92 -4
  452. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +41 -12
  453. package/src/resources/extensions/gsd/bootstrap/system-context.ts +11 -3
  454. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +87 -53
  455. package/src/resources/extensions/gsd/command-feedback.ts +19 -12
  456. package/src/resources/extensions/gsd/commands-verdict.ts +16 -9
  457. package/src/resources/extensions/gsd/compat/compat-marker.ts +119 -8
  458. package/src/resources/extensions/gsd/constants.ts +14 -13
  459. package/src/resources/extensions/gsd/context-masker.ts +98 -2
  460. package/src/resources/extensions/gsd/db/command-queue.ts +7 -1
  461. package/src/resources/extensions/gsd/db/engine.ts +58 -19
  462. package/src/resources/extensions/gsd/db/writers/cascades.ts +5 -1
  463. package/src/resources/extensions/gsd/db/writers/status.ts +25 -8
  464. package/src/resources/extensions/gsd/db-base-schema.ts +30 -0
  465. package/src/resources/extensions/gsd/db-migration-steps.ts +32 -0
  466. package/src/resources/extensions/gsd/db-schema-metadata.ts +4 -1
  467. package/src/resources/extensions/gsd/docs/preferences-reference.md +26 -4
  468. package/src/resources/extensions/gsd/doctor-engine-checks.ts +30 -7
  469. package/src/resources/extensions/gsd/error-classifier.ts +13 -2
  470. package/src/resources/extensions/gsd/exec-sandbox.ts +1 -0
  471. package/src/resources/extensions/gsd/flat-phase-migration.ts +174 -19
  472. package/src/resources/extensions/gsd/git-service.ts +19 -6
  473. package/src/resources/extensions/gsd/gsd-db.ts +340 -85
  474. package/src/resources/extensions/gsd/guided-flow.ts +50 -14
  475. package/src/resources/extensions/gsd/markdown-renderer.ts +28 -30
  476. package/src/resources/extensions/gsd/md-importer.ts +114 -16
  477. package/src/resources/extensions/gsd/migrate/command.ts +21 -227
  478. package/src/resources/extensions/gsd/migrate/execution.ts +136 -0
  479. package/src/resources/extensions/gsd/migrate/plan.ts +101 -0
  480. package/src/resources/extensions/gsd/migrate/planning-writer.ts +12 -20
  481. package/src/resources/extensions/gsd/migrate/presentation.ts +83 -0
  482. package/src/resources/extensions/gsd/model-cost-table.ts +2 -0
  483. package/src/resources/extensions/gsd/model-router.ts +12 -0
  484. package/src/resources/extensions/gsd/parallel-eligibility.ts +5 -4
  485. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +37 -40
  486. package/src/resources/extensions/gsd/paths.ts +77 -16
  487. package/src/resources/extensions/gsd/phase-anchor.ts +8 -2
  488. package/src/resources/extensions/gsd/planning-subagent-policy.ts +58 -0
  489. package/src/resources/extensions/gsd/planning-subagent-registry.ts +31 -0
  490. package/src/resources/extensions/gsd/post-execution-checks.ts +4 -4
  491. package/src/resources/extensions/gsd/preferences-types.ts +16 -0
  492. package/src/resources/extensions/gsd/preferences-validation.ts +62 -0
  493. package/src/resources/extensions/gsd/preferences.ts +25 -0
  494. package/src/resources/extensions/gsd/prompts/refine-slice.md +2 -2
  495. package/src/resources/extensions/gsd/prompts/validate-milestone.md +5 -5
  496. package/src/resources/extensions/gsd/provider-payload-policy.ts +18 -4
  497. package/src/resources/extensions/gsd/safety/destructive-guard.ts +1 -1
  498. package/src/resources/extensions/gsd/safety/evidence-collector.ts +28 -1
  499. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +31 -5
  500. package/src/resources/extensions/gsd/skill-activation.ts +17 -3
  501. package/src/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.ts +162 -15
  502. package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +20 -4
  503. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +4 -2
  504. package/src/resources/extensions/gsd/state-reconciliation/types.ts +2 -2
  505. package/src/resources/extensions/gsd/stop-notice.ts +29 -1
  506. package/src/resources/extensions/gsd/sync-lock.ts +14 -6
  507. package/src/resources/extensions/gsd/templates/PREFERENCES.md +5 -0
  508. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +7 -7
  509. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +264 -0
  510. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +39 -0
  511. package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +21 -1
  512. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +74 -1
  513. package/src/resources/extensions/gsd/tests/before-provider-context-management.test.ts +55 -0
  514. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +96 -1
  515. package/src/resources/extensions/gsd/tests/command-feedback.test.ts +12 -0
  516. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +10 -0
  517. package/src/resources/extensions/gsd/tests/compat-marker.test.ts +129 -0
  518. package/src/resources/extensions/gsd/tests/complete-task.test.ts +362 -1
  519. package/src/resources/extensions/gsd/tests/context-masker.test.ts +204 -8
  520. package/src/resources/extensions/gsd/tests/db-engine-cjs-compat.test.ts +12 -0
  521. package/src/resources/extensions/gsd/tests/db-engine-migrate-guards.test.ts +186 -0
  522. package/src/resources/extensions/gsd/tests/db-tools-alias-suppression.test.ts +62 -0
  523. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +29 -0
  524. package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +33 -0
  525. package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +14 -0
  526. package/src/resources/extensions/gsd/tests/discuss-routing-fixes.test.ts +123 -0
  527. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +50 -0
  528. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +49 -0
  529. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +83 -0
  530. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +81 -0
  531. package/src/resources/extensions/gsd/tests/evidence-xref-gsd-exec.test.ts +22 -0
  532. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +33 -1
  533. package/src/resources/extensions/gsd/tests/external-edit-scoped-import.test.ts +262 -0
  534. package/src/resources/extensions/gsd/tests/external-markdown-edit.test.ts +38 -1
  535. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +201 -0
  536. package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +20 -1
  537. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +29 -0
  538. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +57 -0
  539. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +22 -0
  540. package/src/resources/extensions/gsd/tests/import-slice-milestone-completion-preserve.test.ts +116 -0
  541. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +13 -0
  542. package/src/resources/extensions/gsd/tests/integration/paths.test.ts +22 -4
  543. package/src/resources/extensions/gsd/tests/integration-branch-meta-location.test.ts +62 -0
  544. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +5 -5
  545. package/src/resources/extensions/gsd/tests/migrate-plan.test.ts +68 -0
  546. package/src/resources/extensions/gsd/tests/migrate-presentation.test.ts +98 -0
  547. package/src/resources/extensions/gsd/tests/migrate-safety-audit.test.ts +1 -1
  548. package/src/resources/extensions/gsd/tests/milestone-leases.test.ts +55 -0
  549. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
  550. package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
  551. package/src/resources/extensions/gsd/tests/parallel-eligibility-file-overlap.test.ts +146 -0
  552. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +59 -0
  553. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +7 -5
  554. package/src/resources/extensions/gsd/tests/phase-anchor.test.ts +32 -4
  555. package/src/resources/extensions/gsd/tests/plan-task.test.ts +26 -23
  556. package/src/resources/extensions/gsd/tests/planning-writer.test.ts +29 -0
  557. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +22 -0
  558. package/src/resources/extensions/gsd/tests/preferences.test.ts +84 -0
  559. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +4 -0
  560. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +87 -0
  561. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +121 -1
  562. package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +39 -0
  563. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +50 -0
  564. package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +105 -0
  565. package/src/resources/extensions/gsd/tests/replan-task-handler.test.ts +103 -0
  566. package/src/resources/extensions/gsd/tests/rework-brief.test.ts +197 -0
  567. package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
  568. package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +33 -7
  569. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -16
  570. package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +21 -0
  571. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +52 -0
  572. package/src/resources/extensions/gsd/tests/stop-notice.test.ts +38 -1
  573. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +19 -0
  574. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +13 -7
  575. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +14 -0
  576. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
  577. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -0
  578. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +73 -0
  579. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +93 -1
  580. package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +7 -0
  581. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -0
  582. package/src/resources/extensions/gsd/tests/workflow-migration-gates.test.ts +139 -0
  583. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -4
  584. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +36 -0
  585. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +60 -0
  586. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +34 -0
  587. package/src/resources/extensions/gsd/tests/write-gate-seam.test.ts +52 -0
  588. package/src/resources/extensions/gsd/tools/complete-task.ts +140 -5
  589. package/src/resources/extensions/gsd/tools/plan-task.ts +14 -16
  590. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +18 -17
  591. package/src/resources/extensions/gsd/tools/reopen-milestone.ts +24 -5
  592. package/src/resources/extensions/gsd/tools/reopen-slice.ts +25 -5
  593. package/src/resources/extensions/gsd/tools/reopen-task.ts +23 -9
  594. package/src/resources/extensions/gsd/tools/replan-task.ts +160 -0
  595. package/src/resources/extensions/gsd/tools/rework-brief.ts +91 -0
  596. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +92 -0
  597. package/src/resources/extensions/gsd/types.ts +11 -0
  598. package/src/resources/extensions/gsd/unit-context-composer.ts +34 -8
  599. package/src/resources/extensions/gsd/unit-registry.ts +4 -0
  600. package/src/resources/extensions/gsd/uok/plan-v2.ts +20 -3
  601. package/src/resources/extensions/gsd/workflow-projections.ts +2 -3
  602. package/src/resources/extensions/gsd/workspace.ts +2 -1
  603. package/src/resources/extensions/gsd/worktree-state-projection.ts +33 -24
  604. package/src/resources/extensions/mac-tools/index.ts +52 -9
  605. package/src/resources/extensions/mac-tools/tests/mac-screenshot-payload.test.cjs +70 -0
  606. package/src/resources/extensions/shared/interview-ui.ts +47 -8
  607. package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +29 -0
  608. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
  609. package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
  610. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
  611. package/dist/web/standalone/.next/static/css/18c2fdf261bfc1b7.css +0 -1
  612. /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → DXD9fZPnqtjZSlT5xdC3v}/_buildManifest.js +0 -0
  613. /package/dist/web/standalone/.next/static/{UaXRrOYxBpG9QBINKhZkg → DXD9fZPnqtjZSlT5xdC3v}/_ssgManifest.js +0 -0
@@ -0,0 +1,62 @@
1
+ // gsd-pi — Integration-branch META lives OUTSIDE milestones/<MID>/ (ADR-045).
2
+ // Verifies the relocation from milestones/<MID>/<MID>-META.json to the flat
3
+ // .gsd/<MID>-META.json so it can never poison isLegacyMilestonesLayout.
4
+
5
+ import assert from "node:assert/strict";
6
+ import { afterEach, beforeEach, test } from "node:test";
7
+ import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
8
+ import { join } from "node:path";
9
+ import { tmpdir } from "node:os";
10
+
11
+ import { readIntegrationBranch, writeIntegrationBranch } from "../git-service.js";
12
+ import { gsdRoot, isLegacyMilestonesLayout } from "../paths.js";
13
+
14
+ let repo: string;
15
+
16
+ beforeEach(() => {
17
+ repo = mkdtempSync(join(tmpdir(), "gsd-meta-loc-"));
18
+ });
19
+
20
+ afterEach(() => {
21
+ rmSync(repo, { recursive: true, force: true });
22
+ });
23
+
24
+ test("write goes to the new flat .gsd/<MID>-META.json, not milestones/<MID>/", () => {
25
+ writeIntegrationBranch(repo, "M001", "main");
26
+
27
+ assert.ok(
28
+ existsSync(join(gsdRoot(repo), "M001-META.json")),
29
+ "META written to flat .gsd/<MID>-META.json",
30
+ );
31
+ assert.ok(
32
+ !existsSync(join(gsdRoot(repo), "milestones", "M001", "M001-META.json")),
33
+ "no META in legacy milestones/<MID>/ location",
34
+ );
35
+ });
36
+
37
+ test("round-trip: read returns what write recorded", () => {
38
+ writeIntegrationBranch(repo, "M001", "main");
39
+ assert.equal(readIntegrationBranch(repo, "M001"), "main");
40
+ });
41
+
42
+ test("read falls back to the legacy milestones/<MID>/ location", () => {
43
+ const legacyDir = join(gsdRoot(repo), "milestones", "M001");
44
+ mkdirSync(legacyDir, { recursive: true });
45
+ writeFileSync(
46
+ join(legacyDir, "M001-META.json"),
47
+ JSON.stringify({ integrationBranch: "develop" }) + "\n",
48
+ "utf-8",
49
+ );
50
+
51
+ assert.equal(readIntegrationBranch(repo, "M001"), "develop");
52
+ });
53
+
54
+ test("writing META does not create milestones/<MID>/ or flip layout detection", () => {
55
+ assert.equal(isLegacyMilestonesLayout(repo), false, "clean tree is not legacy layout");
56
+ writeIntegrationBranch(repo, "M001", "main");
57
+ assert.equal(
58
+ isLegacyMilestonesLayout(repo),
59
+ false,
60
+ "writing integration-branch META must not poison layout detection",
61
+ );
62
+ });
@@ -824,9 +824,9 @@ test('── markdown-renderer: renderTaskSummary round-trip ──', async () =
824
824
 
825
825
  // Verify file exists on disk
826
826
  const summaryPath = path.join(
827
- tmpDir, '.gsd', 'phases', '01-test', 'T01-SUMMARY.md',
827
+ tmpDir, '.gsd', 'phases', '01-test', 'S01-T01-SUMMARY.md',
828
828
  );
829
- assert.ok(fs.existsSync(summaryPath), 'T01-SUMMARY.md written to disk');
829
+ assert.ok(fs.existsSync(summaryPath), 'S01-T01-SUMMARY.md written to disk');
830
830
 
831
831
  // Parse and verify
832
832
  const rendered = fs.readFileSync(summaryPath, 'utf-8');
@@ -1020,7 +1020,7 @@ test('── markdown-renderer: renderAllFromDb produces all files ──', asyn
1020
1020
 
1021
1021
  // Verify task summary written
1022
1022
  const taskSummaryPath = path.join(
1023
- tmpDir, '.gsd', 'phases', '01-test', 'T01-SUMMARY.md',
1023
+ tmpDir, '.gsd', 'phases', '01-test', 'S01-T01-SUMMARY.md',
1024
1024
  );
1025
1025
  assert.ok(fs.existsSync(taskSummaryPath), 'T01 summary written by renderAll');
1026
1026
  } finally {
@@ -1546,9 +1546,9 @@ test('── markdown-renderer: repairStaleRenders writes missing task summary
1546
1546
 
1547
1547
  // Verify file written
1548
1548
  const summaryPath = path.join(
1549
- tmpDir, '.gsd', 'phases', '01-test', 'T01-SUMMARY.md',
1549
+ tmpDir, '.gsd', 'phases', '01-test', 'S01-T01-SUMMARY.md',
1550
1550
  );
1551
- assert.ok(fs.existsSync(summaryPath), 'T01-SUMMARY.md should exist after repair');
1551
+ assert.ok(fs.existsSync(summaryPath), 'S01-T01-SUMMARY.md should exist after repair');
1552
1552
 
1553
1553
  // Second detect should be empty
1554
1554
  clearAllCaches();
@@ -0,0 +1,68 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import test from "node:test";
6
+
7
+ import { createMigrationPlan, splitValidationIssues } from "../migrate/plan.ts";
8
+ import type { ValidationResult } from "../migrate/types.ts";
9
+
10
+ function makeBase(prefix: string): string {
11
+ return mkdtempSync(join(tmpdir(), prefix));
12
+ }
13
+
14
+ function write(path: string, content: string): void {
15
+ mkdirSync(join(path, ".."), { recursive: true });
16
+ writeFileSync(path, content);
17
+ }
18
+
19
+ test("splitValidationIssues separates warnings from fatals without dropping issue order", () => {
20
+ const validation: ValidationResult = {
21
+ valid: false,
22
+ issues: [
23
+ { file: "ROADMAP.md", severity: "warning", message: "missing roadmap" },
24
+ { file: ".planning", severity: "fatal", message: "missing directory" },
25
+ { file: "PROJECT.md", severity: "warning", message: "missing project" },
26
+ ],
27
+ };
28
+
29
+ assert.deepEqual(splitValidationIssues(validation), {
30
+ warnings: [
31
+ { file: "ROADMAP.md", severity: "warning", message: "missing roadmap" },
32
+ { file: "PROJECT.md", severity: "warning", message: "missing project" },
33
+ ],
34
+ fatals: [
35
+ { file: ".planning", severity: "fatal", message: "missing directory" },
36
+ ],
37
+ });
38
+ });
39
+
40
+ test("createMigrationPlan reports a missing .planning source without parsing", async () => {
41
+ const base = makeBase("gsd-migrate-plan-missing-");
42
+ try {
43
+ const result = await createMigrationPlan(base);
44
+
45
+ assert.equal(result.status, "missing-source");
46
+ assert.equal(result.sourcePath, join(base, ".planning"));
47
+ assert.equal(result.targetRoot, base);
48
+ } finally {
49
+ rmSync(base, { recursive: true, force: true });
50
+ }
51
+ });
52
+
53
+ test("createMigrationPlan reports zero-slice migrations as blocked after validation", async () => {
54
+ const base = makeBase("gsd-migrate-plan-blocked-");
55
+ try {
56
+ mkdirSync(join(base, ".planning"), { recursive: true });
57
+ write(join(base, ".planning", "PROJECT.md"), "# Legacy Project\n");
58
+
59
+ const result = await createMigrationPlan(base);
60
+
61
+ assert.equal(result.status, "blocked");
62
+ assert.match(result.message, /zero slices/);
63
+ assert.equal(result.validation.valid, true);
64
+ assert.ok(result.warnings.some((issue) => issue.file === "ROADMAP.md"));
65
+ } finally {
66
+ rmSync(base, { recursive: true, force: true });
67
+ }
68
+ });
@@ -0,0 +1,98 @@
1
+ import assert from "node:assert/strict";
2
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import test from "node:test";
6
+
7
+ import {
8
+ buildMigrationPreviewSummary,
9
+ buildReviewPrompt,
10
+ formatMigrationPreviewStats,
11
+ } from "../migrate/presentation.ts";
12
+ import { gsdRoot } from "../paths.ts";
13
+ import type { MigrationPreview } from "../migrate/writer.ts";
14
+
15
+ function previewFixture(overrides: Partial<MigrationPreview> = {}): MigrationPreview {
16
+ return {
17
+ decisions: { total: 2 },
18
+ migrationInputs: {
19
+ milestonePhaseDirs: 3,
20
+ decisions: 2,
21
+ seeds: 1,
22
+ },
23
+ milestoneCount: 1,
24
+ totalSlices: 2,
25
+ totalTasks: 5,
26
+ doneSlices: 1,
27
+ doneTasks: 3,
28
+ sliceCompletionPct: 50,
29
+ taskCompletionPct: 60,
30
+ requirements: {
31
+ active: 1,
32
+ validated: 2,
33
+ deferred: 1,
34
+ outOfScope: 1,
35
+ total: 5,
36
+ },
37
+ ...overrides,
38
+ };
39
+ }
40
+
41
+ test("buildMigrationPreviewSummary includes counts, legacy inputs, and existing-target warning", () => {
42
+ const base = mkdtempSync(join(tmpdir(), "gsd-migrate-presentation-"));
43
+ try {
44
+ mkdirSync(join(base, ".gsd"), { recursive: true });
45
+
46
+ assert.deepEqual(buildMigrationPreviewSummary(previewFixture(), base), [
47
+ "Decisions: 2",
48
+ "Milestones: 1",
49
+ "Slices: 2 (1 done — 50%)",
50
+ "Tasks: 5 (3 done — 60%)",
51
+ "Requirements: 5 (2 validated, 1 active, 1 deferred, 1 out of scope)",
52
+ "Legacy inputs: 3 milestone phase dir(s), 2 decision file(s), 1 seed file(s)",
53
+ "",
54
+ `⚠ A .gsd directory already exists at ${gsdRoot(base)}.`,
55
+ "It will be backed up, deleted, and rewritten fresh before DB import.",
56
+ ]);
57
+ } finally {
58
+ rmSync(base, { recursive: true, force: true });
59
+ }
60
+ });
61
+
62
+ test("formatMigrationPreviewStats uses bullet formatting for review prompts", () => {
63
+ assert.equal(
64
+ formatMigrationPreviewStats(previewFixture({ requirements: { active: 0, validated: 0, deferred: 0, outOfScope: 0, total: 0 } })),
65
+ [
66
+ "- Decisions: 2",
67
+ "- Milestones: 1",
68
+ "- Slices: 2 (1 done — 50%)",
69
+ "- Tasks: 5 (3 done — 60%)",
70
+ "- Legacy inputs: 3 milestone phase dir(s), 2 decision file(s), 1 seed file(s)",
71
+ ].join("\n"),
72
+ );
73
+ });
74
+
75
+ test("buildReviewPrompt interpolates source, target, and preview stats", () => {
76
+ const base = mkdtempSync(join(tmpdir(), "gsd-migrate-prompt-"));
77
+ try {
78
+ const promptsDir = join(base, "prompts");
79
+ mkdirSync(promptsDir, { recursive: true });
80
+ writeFileSync(
81
+ join(promptsDir, "review-migration.md"),
82
+ "Source={{sourcePath}}\nTarget={{gsdPath}}\nStats:\n{{previewStats}}\n",
83
+ );
84
+
85
+ const prompt = buildReviewPrompt({
86
+ sourcePath: "/legacy/.planning",
87
+ gsdPath: "/project/.gsd",
88
+ preview: previewFixture(),
89
+ templatePath: join(promptsDir, "review-migration.md"),
90
+ });
91
+
92
+ assert.match(prompt, /Source=\/legacy\/\.planning/);
93
+ assert.match(prompt, /Target=\/project\/\.gsd/);
94
+ assert.match(prompt, /- Requirements: 5 \(2 validated, 1 active, 1 deferred, 1 out of scope\)/);
95
+ } finally {
96
+ rmSync(base, { recursive: true, force: true });
97
+ }
98
+ });
@@ -19,7 +19,7 @@ import {
19
19
  archiveLegacyPlanningDirectory,
20
20
  verifyMigrationProjection,
21
21
  } from "../migrate/audit.ts";
22
- import { assertMigrationDbReadiness, executeMigrationWrite, importWrittenMigrationToDb } from "../migrate/command.ts";
22
+ import { assertMigrationDbReadiness, executeMigrationWrite, importWrittenMigrationToDb } from "../migrate/execution.ts";
23
23
  import { writeGSDDirectory } from "../migrate/writer.ts";
24
24
  import { closeDatabase, getArtifact } from "../gsd-db.ts";
25
25
  import type { GSDProject } from "../migrate/types.ts";
@@ -18,6 +18,7 @@ import {
18
18
  releaseMilestoneLease,
19
19
  refreshMilestoneLease,
20
20
  getMilestoneLease,
21
+ forceReleaseLeasesForWorker,
21
22
  } from "../db/milestone-leases.ts";
22
23
 
23
24
  function makeBase(): string {
@@ -163,6 +164,60 @@ test("refreshMilestoneLease only succeeds with the matching fencing token", (t)
163
164
  assert.equal(refreshMilestoneLease(w1, "M001", claim.token - 1), false);
164
165
  });
165
166
 
167
+ test("forceReleaseLeasesForWorker frees only the dead worker's leases, not a live peer's", (t) => {
168
+ const base = makeBase();
169
+ t.after(() => cleanup(base));
170
+ openDatabase(join(base, ".gsd", "gsd.db"));
171
+ insertMilestone({ id: "M001", title: "One", status: "active" });
172
+ insertMilestone({ id: "M002", title: "Two", status: "active" });
173
+
174
+ // Distinct project roots → distinct processes (not re-entrant peers).
175
+ const wA = registerAutoWorker({ projectRootRealpath: base });
176
+ const wB = registerAutoWorker({ projectRootRealpath: join(base, "peer") });
177
+ assert.equal(claimMilestoneLease(wA, "M001").ok, true);
178
+ assert.equal(claimMilestoneLease(wB, "M002").ok, true);
179
+
180
+ const freed = forceReleaseLeasesForWorker(wA);
181
+ assert.equal(freed, 1, "exactly A's one held lease is released");
182
+
183
+ assert.equal(getMilestoneLease("M001")!.status, "released", "A's M001 lease is released");
184
+ const m2 = getMilestoneLease("M002")!;
185
+ assert.equal(m2.status, "held", "B's M002 lease must stay held (no over-release)");
186
+ assert.equal(m2.worker_id, wB);
187
+ });
188
+
189
+ test("after force release a fresh claim on the freed milestone gets a larger fencing token", (t) => {
190
+ const base = makeBase();
191
+ t.after(() => cleanup(base));
192
+ openDatabase(join(base, ".gsd", "gsd.db"));
193
+ insertMilestone({ id: "M001", title: "One", status: "active" });
194
+
195
+ const wA = registerAutoWorker({ projectRootRealpath: base });
196
+ const wB = registerAutoWorker({ projectRootRealpath: join(base, "peer") });
197
+ const first = claimMilestoneLease(wA, "M001");
198
+ assert.equal(first.ok, true);
199
+ const releasedToken = first.ok ? first.token : 0;
200
+
201
+ assert.equal(forceReleaseLeasesForWorker(wA), 1);
202
+
203
+ const takeover = claimMilestoneLease(wB, "M001");
204
+ assert.equal(takeover.ok, true);
205
+ if (takeover.ok) {
206
+ assert.ok(takeover.token > releasedToken, "takeover token must exceed the released lease's token");
207
+ }
208
+ assert.equal(getMilestoneLease("M001")!.worker_id, wB);
209
+ });
210
+
211
+ test("forceReleaseLeasesForWorker returns 0 for a worker holding no leases", (t) => {
212
+ const base = makeBase();
213
+ t.after(() => cleanup(base));
214
+ openDatabase(join(base, ".gsd", "gsd.db"));
215
+ insertMilestone({ id: "M001", title: "One", status: "active" });
216
+
217
+ const wA = registerAutoWorker({ projectRootRealpath: base });
218
+ assert.equal(forceReleaseLeasesForWorker(wA), 0);
219
+ });
220
+
166
221
  test("claimMilestoneLease rethrows foreign-key failures instead of treating them as lease contention", (t) => {
167
222
  const base = makeBase();
168
223
  t.after(() => cleanup(base));
@@ -74,7 +74,7 @@ test("#2885: cost table includes openai-codex provider models", () => {
74
74
  const ids = BUNDLED_COST_TABLE.map(e => e.id);
75
75
  const codexModels = [
76
76
  "gpt-5.1", "gpt-5.1-codex-max", "gpt-5.1-codex-mini",
77
- "gpt-5.2", "gpt-5.2-codex", "gpt-5.3-codex", "gpt-5.3-codex-spark", "gpt-5.4", "gpt-5.4-mini", "gpt-5.5",
77
+ "gpt-5.2", "gpt-5.2-codex", "gpt-5.3-codex", "gpt-5.3-codex-spark", "gpt-5.4", "gpt-5.4-mini", "gpt-5.5", "gpt-5.6",
78
78
  ];
79
79
  for (const model of codexModels) {
80
80
  assert.ok(ids.includes(model), `cost table should include openai-codex model "${model}"`);
@@ -109,3 +109,11 @@ test("gpt-5.5 uses official OpenAI list pricing", () => {
109
109
  assert.equal(entry.outputPer1k, 0.03);
110
110
  assert.equal(entry.updatedAt, "2026-04-23");
111
111
  });
112
+
113
+ test("gpt-5.6 mirrors gpt-5.5 pricing until official pricing is published", () => {
114
+ const entry = lookupModelCost("gpt-5.6");
115
+ assert.ok(entry, "lookupModelCost should find gpt-5.6");
116
+ assert.equal(entry.inputPer1k, 0.005);
117
+ assert.equal(entry.outputPer1k, 0.03);
118
+ assert.equal(entry.updatedAt, "2026-07-08");
119
+ });
@@ -900,7 +900,7 @@ test("#2885: openai-codex standard-tier models are recognized", () => {
900
900
 
901
901
  test("#2885: openai-codex heavy-tier models are recognized", () => {
902
902
  const config = { ...defaultRoutingConfig(), enabled: true };
903
- const heavyModels = ["gpt-5", "gpt-5-pro", "gpt-5.1", "gpt-5.2", "gpt-5.2-codex", "gpt-5.3-codex", "gpt-5.4", "gpt-5.5", "o4-mini", "o4-mini-deep-research"];
903
+ const heavyModels = ["gpt-5", "gpt-5-pro", "gpt-5.1", "gpt-5.2", "gpt-5.2-codex", "gpt-5.3-codex", "gpt-5.4", "gpt-5.5", "gpt-5.6", "o4-mini", "o4-mini-deep-research"];
904
904
  for (const model of heavyModels) {
905
905
  const result = resolveModelForComplexity(
906
906
  makeClassification("heavy"),
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Regression tests for batched touched-file collection in parallel eligibility.
3
+ *
4
+ * `collectTouchedFiles` used to run one `getSliceTasks` query per slice (N+1);
5
+ * it now issues a single `getTasksBySliceIds` batch and dedups paths into a
6
+ * Set. These tests pin the observable contract of that path through the public
7
+ * `analyzeParallelEligibility` API:
8
+ * 1. files are collected from EVERY slice of a milestone, not just the first
9
+ * (a file present only in a non-first slice must still drive overlap), and
10
+ * 2. a path repeated across a milestone's slices is deduped (Set semantics),
11
+ * so it appears once in the cross-milestone overlap.
12
+ */
13
+
14
+ import { describe, test, beforeEach, afterEach } from "node:test";
15
+ import assert from "node:assert/strict";
16
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
17
+ import { join } from "node:path";
18
+ import { tmpdir } from "node:os";
19
+
20
+ import { analyzeParallelEligibility } from "../parallel-eligibility.ts";
21
+ import { invalidateStateCache } from "../state.ts";
22
+ import {
23
+ openDatabase,
24
+ closeDatabase,
25
+ insertMilestone,
26
+ insertSlice,
27
+ insertTask,
28
+ } from "../gsd-db.ts";
29
+
30
+ // ─── Fixture Helpers ───────────────────────────────────────────────────────
31
+
32
+ function createFixtureBase(): string {
33
+ const base = mkdtempSync(join(tmpdir(), "gsd-parallel-elig-overlap-"));
34
+ mkdirSync(join(base, ".gsd", "milestones"), { recursive: true });
35
+ return base;
36
+ }
37
+
38
+ function writeMilestoneFile(base: string, milestoneId: string, filename: string, content: string): void {
39
+ const filePath = join(base, ".gsd", "milestones", milestoneId, filename);
40
+ mkdirSync(join(filePath, ".."), { recursive: true });
41
+ writeFileSync(filePath, content);
42
+ }
43
+
44
+ /**
45
+ * Write the on-disk planning artifacts that make a milestone eligible
46
+ * (CONTEXT + ROADMAP listing its slices + a PLAN per slice). Mirrors the
47
+ * proven-eligible setup used by parallel-eligibility-ghost.test.ts.
48
+ */
49
+ function writeEligibleMilestoneFiles(base: string, milestoneId: string, sliceIds: string[]): void {
50
+ writeMilestoneFile(base, milestoneId, `${milestoneId}-CONTEXT.md`, `# ${milestoneId}: Fixture\n\nBatch fixture.`);
51
+ const roadmapSlices = sliceIds
52
+ .map((sid) => `- [ ] **${sid}: Slice ${sid}** \`risk:low\` \`depends:[]\`\n > Slice ${sid}.`)
53
+ .join("\n");
54
+ writeMilestoneFile(
55
+ base,
56
+ milestoneId,
57
+ `${milestoneId}-ROADMAP.md`,
58
+ `# ${milestoneId}: Fixture\n\n## Slices\n\n${roadmapSlices}\n`,
59
+ );
60
+ for (const sid of sliceIds) {
61
+ writeMilestoneFile(
62
+ base,
63
+ milestoneId,
64
+ `slices/${sid}/${sid}-PLAN.md`,
65
+ `# ${sid}: Slice ${sid}\n\n**Goal:** Do ${sid}.\n**Demo:** Done.\n\n## Tasks\n\n- [ ] **T01: Task** \`est:10m\`\n Do it.\n`,
66
+ );
67
+ }
68
+ }
69
+
70
+ function cleanup(base: string): void {
71
+ rmSync(base, { recursive: true, force: true });
72
+ }
73
+
74
+ // ─── Tests ─────────────────────────────────────────────────────────────────
75
+
76
+ describe("parallel-eligibility: batched touched-file collection", () => {
77
+ let base: string;
78
+
79
+ beforeEach(() => {
80
+ base = createFixtureBase();
81
+ openDatabase(":memory:");
82
+ });
83
+
84
+ afterEach(() => {
85
+ closeDatabase();
86
+ cleanup(base);
87
+ invalidateStateCache();
88
+ });
89
+
90
+ test("collects files from every slice (batch) and dedups repeated paths", async () => {
91
+ // M001 spans two slices. `src/shared.ts` appears in BOTH slices (dedup
92
+ // target); `src/beta.ts` appears ONLY in the second slice S02 (proves the
93
+ // batch covers non-first slices). `src/alpha.ts` is unique to M001.
94
+ writeEligibleMilestoneFiles(base, "M001", ["S01", "S02"]);
95
+ insertMilestone({ id: "M001", title: "M001: Fixture", status: "active" });
96
+ insertSlice({ id: "S01", milestoneId: "M001", title: "Slice S01", status: "active", risk: "low", depends: [], sequence: 1 });
97
+ insertSlice({ id: "S02", milestoneId: "M001", title: "Slice S02", status: "active", risk: "low", depends: [], sequence: 2 });
98
+ insertTask({
99
+ id: "T01", sliceId: "S01", milestoneId: "M001", title: "S01 task", status: "pending",
100
+ planning: { files: ["src/alpha.ts", "src/shared.ts"] },
101
+ });
102
+ insertTask({
103
+ id: "T01", sliceId: "S02", milestoneId: "M001", title: "S02 task", status: "pending",
104
+ planning: { files: ["src/shared.ts", "src/beta.ts"] },
105
+ });
106
+
107
+ // M002 overlaps M001 on both `src/shared.ts` and `src/beta.ts`.
108
+ writeEligibleMilestoneFiles(base, "M002", ["S01"]);
109
+ insertMilestone({ id: "M002", title: "M002: Fixture", status: "active" });
110
+ insertSlice({ id: "S01", milestoneId: "M002", title: "Slice S01", status: "active", risk: "low", depends: [], sequence: 1 });
111
+ insertTask({
112
+ id: "T01", sliceId: "S01", milestoneId: "M002", title: "S01 task", status: "pending",
113
+ planning: { files: ["src/shared.ts", "src/beta.ts"] },
114
+ });
115
+
116
+ invalidateStateCache();
117
+ const result = await analyzeParallelEligibility(base);
118
+
119
+ // Both milestones must be eligible so Rule 3 (file overlap) runs on them.
120
+ assert.ok(result.eligible.find((e) => e.milestoneId === "M001"), "M001 should be eligible");
121
+ assert.ok(result.eligible.find((e) => e.milestoneId === "M002"), "M002 should be eligible");
122
+
123
+ const overlap = result.fileOverlaps.find(
124
+ (o) =>
125
+ (o.mid1 === "M001" && o.mid2 === "M002") ||
126
+ (o.mid1 === "M002" && o.mid2 === "M001"),
127
+ );
128
+ assert.ok(overlap, "M001 and M002 must be reported as overlapping");
129
+
130
+ // `src/beta.ts` lives only in M001's SECOND slice — its presence proves the
131
+ // batched query collected tasks from every slice, not just the first.
132
+ assert.ok(
133
+ overlap!.files.includes("src/beta.ts"),
134
+ "overlap must include src/beta.ts (only present in M001's non-first slice S02)",
135
+ );
136
+ assert.ok(overlap!.files.includes("src/shared.ts"), "overlap must include src/shared.ts");
137
+
138
+ // `src/shared.ts` appears in both of M001's slices but must be deduped to a
139
+ // single entry (Set collection), so the sorted overlap is exactly these two.
140
+ assert.deepEqual(
141
+ [...overlap!.files].sort(),
142
+ ["src/beta.ts", "src/shared.ts"],
143
+ "overlap files must be deduped and limited to the shared paths",
144
+ );
145
+ });
146
+ });
@@ -108,6 +108,65 @@ describe("parallel-monitor-overlay", () => {
108
108
  }
109
109
  });
110
110
 
111
+ it("merged worker query renders slice progress and completions across multiple slices", async () => {
112
+ // Regression guard for the single-open merge: queryWorkerProgress now
113
+ // returns { slices, completions } from ONE connection per worker per tick.
114
+ // A worker spanning two slices, each with a completed task, must still
115
+ // surface every slice's progress AND both completions (previously two
116
+ // separate DB opens produced these).
117
+ const base = mkdtempSync(join(tmpdir(), "gsd-parallel-overlay-multi-"));
118
+
119
+ try {
120
+ mkdirSync(join(base, ".gsd", "parallel"), { recursive: true });
121
+ assert.equal(openDatabase(join(base, ".gsd", "gsd.db")), true);
122
+ insertMilestone({ id: "M001", title: "Multi-slice Fixture" });
123
+ insertSlice({ milestoneId: "M001", id: "S01", title: "First", status: "pending", sequence: 1 });
124
+ insertSlice({ milestoneId: "M001", id: "S02", title: "Second", status: "pending", sequence: 2 });
125
+ insertTask({ milestoneId: "M001", sliceId: "S01", id: "T01", status: "complete", oneLiner: "alpha done", sequence: 1 });
126
+ insertTask({ milestoneId: "M001", sliceId: "S01", id: "T02", status: "pending", sequence: 2 });
127
+ insertTask({ milestoneId: "M001", sliceId: "S02", id: "T01", status: "complete", oneLiner: "beta done", sequence: 1 });
128
+ insertTask({ milestoneId: "M001", sliceId: "S02", id: "T02", status: "pending", sequence: 2 });
129
+ closeDatabase();
130
+
131
+ writeFileSync(
132
+ join(base, ".gsd", "parallel", "M001.status.json"),
133
+ JSON.stringify({
134
+ milestoneId: "M001",
135
+ pid: process.pid,
136
+ state: "running",
137
+ cost: 0,
138
+ lastHeartbeat: Date.now(),
139
+ startedAt: Date.now() - 30_000,
140
+ worktreePath: join(base, ".gsd-worktrees", "M001"),
141
+ }),
142
+ "utf-8",
143
+ );
144
+
145
+ const mod = await import("../parallel-monitor-overlay.js");
146
+ const mockTui = { requestRender: () => {} };
147
+ const mockTheme = {
148
+ fg: (_color: string, text: string) => text,
149
+ bold: (text: string) => text,
150
+ };
151
+ const overlay = new mod.ParallelMonitorOverlay(mockTui, mockTheme as any, () => {}, base);
152
+
153
+ try {
154
+ const joined = overlay.render(120).join("\n");
155
+ // Both slices' progress must come from the single merged query.
156
+ assert.match(joined, /S01:1\/2/, "S01 progress should render from the merged query");
157
+ assert.match(joined, /S02:1\/2/, "S02 progress should render from the merged query");
158
+ // Completions for tasks in both slices ride along on the same DB open.
159
+ assert.match(joined, /S01\/T01: alpha done/, "S01 completion should render");
160
+ assert.match(joined, /S02\/T01: beta done/, "S02 completion should render");
161
+ } finally {
162
+ overlay.dispose();
163
+ }
164
+ } finally {
165
+ try { closeDatabase(); } catch { /* already closed */ }
166
+ rmSync(base, { recursive: true, force: true });
167
+ }
168
+ });
169
+
111
170
  it("progressBar generates correct width", async () => {
112
171
  // Dynamic import to test the module loads cleanly
113
172
  const mod = await import("../parallel-monitor-overlay.js");
@@ -29,12 +29,14 @@ import {
29
29
 
30
30
  const SKILL_NAME = "testskill";
31
31
  const COMPLETE_SLICE_SKILL_NAME = "complete-slice-policies";
32
- const SKILL_ACTIVATION_SUBSTRING = `Read the installed '${SKILL_NAME}' skill file from <available_skills>`;
33
- const COMPLETE_SLICE_SKILL_ACTIVATION_SUBSTRING = `Read the installed '${COMPLETE_SLICE_SKILL_NAME}' skill file from <available_skills>`;
34
32
 
35
33
  const tmpDirs: string[] = [];
36
34
  let savedCwd: string | undefined;
37
35
 
36
+ function expectedSkillRead(base: string, name: string): string {
37
+ return `Read the skill file at \`${join(base, ".agents", "skills", name, "SKILL.md")}\``;
38
+ }
39
+
38
40
  function setupProjectWithSkill(options: {
39
41
  skillName?: string;
40
42
  preferencesLines?: string[];
@@ -139,7 +141,7 @@ test("worker prompt (buildResearchSlicePrompt) includes <skill_activation> from
139
141
  "research-slice prompt should contain a <skill_activation> block",
140
142
  );
141
143
  assert.ok(
142
- prompt.includes(SKILL_ACTIVATION_SUBSTRING),
144
+ prompt.includes(expectedSkillRead(base, SKILL_NAME)),
143
145
  `research-slice prompt should reference the always-used skill '${SKILL_NAME}'`,
144
146
  );
145
147
  });
@@ -164,7 +166,7 @@ test("complete-slice prompt includes <skill_activation> from unit-specific skill
164
166
  "complete-slice prompt should contain a <skill_activation> block",
165
167
  );
166
168
  assert.ok(
167
- prompt.includes(COMPLETE_SLICE_SKILL_ACTIVATION_SUBSTRING),
169
+ prompt.includes(expectedSkillRead(base, COMPLETE_SLICE_SKILL_NAME)),
168
170
  `complete-slice prompt should reference the skill-rule skill '${COMPLETE_SLICE_SKILL_NAME}'`,
169
171
  );
170
172
  });
@@ -192,7 +194,7 @@ test("subagent dispatch prompt (buildParallelResearchSlicesPrompt) carries <skil
192
194
  `expected at least 2 <skill_activation> blocks (one per slice), got ${blockCount}`,
193
195
  );
194
196
  assert.ok(
195
- prompt.includes(SKILL_ACTIVATION_SUBSTRING),
197
+ prompt.includes(expectedSkillRead(base, SKILL_NAME)),
196
198
  `parallel-research-slices prompt should reference the always-used skill '${SKILL_NAME}'`,
197
199
  );
198
200
  assert.ok(