@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
@@ -18,6 +18,8 @@ import { handleCompleteSlice } from "./complete-slice.js";
18
18
  import { handlePlanMilestone } from "./plan-milestone.js";
19
19
  import { handlePlanSlice } from "./plan-slice.js";
20
20
  import { handleReplanSlice } from "./replan-slice.js";
21
+ import { handleReplanTask } from "./replan-task.js";
22
+ import { handleReworkBriefSave } from "./rework-brief.js";
21
23
  import { handleReopenMilestone } from "./reopen-milestone.js";
22
24
  import { handleReopenSlice } from "./reopen-slice.js";
23
25
  import { handleReopenTask } from "./reopen-task.js";
@@ -1277,6 +1279,85 @@ export async function executePlanSlice(params, basePath = process.cwd()) {
1277
1279
  };
1278
1280
  }
1279
1281
  }
1282
+ export async function executeReplanTask(params, basePath = process.cwd()) {
1283
+ const dbAvailable = await ensureDbOpen(basePath);
1284
+ if (!dbAvailable) {
1285
+ return {
1286
+ content: [{ type: "text", text: "Error: GSD database is not available. Cannot replan task." }],
1287
+ details: { operation: "replan_task", error: "db_unavailable" },
1288
+ isError: true,
1289
+ };
1290
+ }
1291
+ try {
1292
+ const result = await handleReplanTask(params, basePath);
1293
+ if ("error" in result) {
1294
+ return {
1295
+ content: [{ type: "text", text: `Error replanning task: ${result.error}` }],
1296
+ details: { operation: "replan_task", error: result.error },
1297
+ isError: true,
1298
+ };
1299
+ }
1300
+ return {
1301
+ content: [{ type: "text", text: `Replanned task ${result.taskId} (${result.sliceId}/${result.milestoneId})` }],
1302
+ details: {
1303
+ operation: "replan_task",
1304
+ milestoneId: result.milestoneId,
1305
+ sliceId: result.sliceId,
1306
+ taskId: result.taskId,
1307
+ taskPlanPath: result.taskPlanPath,
1308
+ },
1309
+ };
1310
+ }
1311
+ catch (err) {
1312
+ const msg = err instanceof Error ? err.message : String(err);
1313
+ logError("tool", `replan_task tool failed: ${msg}`, { tool: "gsd_replan_task", error: String(err) });
1314
+ return {
1315
+ content: [{ type: "text", text: `Error replanning task: ${msg}` }],
1316
+ details: { operation: "replan_task", error: msg },
1317
+ isError: true,
1318
+ };
1319
+ }
1320
+ }
1321
+ export async function executeReworkBriefSave(params, basePath = process.cwd()) {
1322
+ const dbAvailable = await ensureDbOpen(basePath);
1323
+ if (!dbAvailable) {
1324
+ return {
1325
+ content: [{ type: "text", text: "Error: GSD database is not available. Cannot save rework brief." }],
1326
+ details: { operation: "rework_brief_save", error: "db_unavailable" },
1327
+ isError: true,
1328
+ };
1329
+ }
1330
+ try {
1331
+ const result = await handleReworkBriefSave(params);
1332
+ if ("error" in result) {
1333
+ return {
1334
+ content: [{ type: "text", text: `Error saving rework brief: ${result.error}` }],
1335
+ details: { operation: "rework_brief_save", error: result.error },
1336
+ isError: true,
1337
+ };
1338
+ }
1339
+ return {
1340
+ content: [{ type: "text", text: `Saved rework brief ${result.briefId} with ${result.findingCount} finding(s)` }],
1341
+ details: {
1342
+ operation: "rework_brief_save",
1343
+ briefId: result.briefId,
1344
+ milestoneId: result.milestoneId,
1345
+ sliceId: result.sliceId,
1346
+ taskId: result.taskId,
1347
+ findingCount: result.findingCount,
1348
+ },
1349
+ };
1350
+ }
1351
+ catch (err) {
1352
+ const msg = err instanceof Error ? err.message : String(err);
1353
+ logError("tool", `rework_brief_save tool failed: ${msg}`, { tool: "gsd_rework_brief_save", error: String(err) });
1354
+ return {
1355
+ content: [{ type: "text", text: `Error saving rework brief: ${msg}` }],
1356
+ details: { operation: "rework_brief_save", error: msg },
1357
+ isError: true,
1358
+ };
1359
+ }
1360
+ }
1280
1361
  export async function executeReplanSlice(params, basePath = process.cwd()) {
1281
1362
  const dbAvailable = await ensureDbOpen(basePath);
1282
1363
  if (!dbAvailable) {
@@ -36,6 +36,7 @@
36
36
  // owned by the unit, not in the composer. Reviews must enforce this — it
37
37
  // is the difference between an orchestrator and a runaway DSL.
38
38
  import { resolveManifest, } from "./unit-context-manifest.js";
39
+ import { resolveEffectivePlanningToolsPolicy } from "./planning-subagent-policy.js";
39
40
  import { getUnitToolSurfaceContract } from "./unit-tool-contracts.js";
40
41
  /**
41
42
  * Produce the inlined-context portion of a unit's system prompt by
@@ -148,11 +149,32 @@ const TOOL_SURFACE_GUIDANCE_BY_UNIT = {
148
149
  "validate-milestone": "Dispatch reviewer subagents in parallel, then persist the verdict via `gsd_validate_milestone`. Do not query `.gsd/gsd.db` directly — use `gsd_milestone_status` and inlined context.",
149
150
  "complete-milestone": "Persist completion only through `gsd_complete_milestone` after verification passes. Do not query `.gsd/gsd.db` directly. Do not write `.gsd/PROJECT.md` or `.gsd/REQUIREMENTS.md` by hand — use `gsd_summary_save` and `gsd_requirement_update`.",
150
151
  "replan-slice": "Persist replans through `gsd_replan_slice` only. Do not edit `PLAN.md` or task plans directly.",
151
- "plan-slice": "Persist planning through `gsd_plan_slice` only. Dispatch subagents only to **scout** or **planner** for reconnaissance — not implementation agents. Do not edit user source files outside `.gsd/**`.",
152
- "refine-slice": "Persist refinements through `gsd_plan_slice` only. Dispatch subagents only to **scout** or **planner**. Do not edit user source files outside `.gsd/**`.",
153
- "plan-milestone": "Persist milestone planning through `gsd_plan_milestone` / `gsd_plan_slice`. Do not edit user source files outside `.gsd/**`.",
154
152
  "research-slice": "Dispatch subagents only to **scout** or **planner** for reconnaissance. Do not edit user source files outside `.gsd/**`.",
155
153
  };
154
+ function formatAllowedAgents(agents) {
155
+ return agents.map((agent) => `**${agent}**`).join(", ");
156
+ }
157
+ function guidanceForUnitToolsPolicy(unitType, policy) {
158
+ if (unitType === "plan-slice") {
159
+ const dispatch = policy.mode === "planning-dispatch"
160
+ ? ` Dispatch subagents only to ${formatAllowedAgents(policy.allowedSubagents)} for reconnaissance — not implementation agents.`
161
+ : " Do not dispatch subagents.";
162
+ return `Persist planning through \`gsd_plan_slice\` only.${dispatch} Do not edit user source files outside \`.gsd/**\`.`;
163
+ }
164
+ if (unitType === "refine-slice") {
165
+ const dispatch = policy.mode === "planning-dispatch"
166
+ ? ` Dispatch subagents only to ${formatAllowedAgents(policy.allowedSubagents)}.`
167
+ : " Do not dispatch subagents.";
168
+ return `Persist refinements through \`gsd_plan_slice\` only.${dispatch} Do not edit user source files outside \`.gsd/**\`.`;
169
+ }
170
+ if (unitType === "plan-milestone") {
171
+ const dispatch = policy.mode === "planning-dispatch"
172
+ ? ` Dispatch subagents only to ${formatAllowedAgents(policy.allowedSubagents)}.`
173
+ : "";
174
+ return `Persist milestone planning through \`gsd_plan_milestone\` / \`gsd_plan_slice\`.${dispatch} Do not edit user source files outside \`.gsd/**\`.`;
175
+ }
176
+ return undefined;
177
+ }
156
178
  function guidanceForToolsPolicy(policy) {
157
179
  switch (policy.mode) {
158
180
  case "planning":
@@ -191,8 +213,9 @@ export function composeToolSurfaceInstructions(unitType, opts) {
191
213
  const manifest = resolveManifest(unitType);
192
214
  if (!manifest)
193
215
  return "";
194
- const unitGuidance = TOOL_SURFACE_GUIDANCE_BY_UNIT[unitType];
195
- const policyGuidance = unitGuidance ? null : guidanceForToolsPolicy(manifest.tools);
216
+ const effectiveTools = resolveEffectivePlanningToolsPolicy(unitType, manifest.tools, opts.basePath) ?? manifest.tools;
217
+ const unitGuidance = guidanceForUnitToolsPolicy(unitType, effectiveTools) ?? TOOL_SURFACE_GUIDANCE_BY_UNIT[unitType];
218
+ const policyGuidance = unitGuidance ? null : guidanceForToolsPolicy(effectiveTools);
196
219
  const forbiddenLine = formatForbiddenWorkflowToolsLine(unitType, unitGuidance);
197
220
  const parts = [unitGuidance, policyGuidance, forbiddenLine].filter((part) => typeof part === "string" && part.length > 0);
198
221
  if (parts.length === 0)
@@ -232,6 +232,8 @@ export const UNIT_REGISTRY = {
232
232
  "gsd_slice_complete",
233
233
  "gsd_task_reopen",
234
234
  "gsd_replan_slice",
235
+ "gsd_replan_task",
236
+ "gsd_rework_brief_save",
235
237
  "gsd_decision_save",
236
238
  "gsd_capture_thought",
237
239
  "gsd_requirement_update",
@@ -245,6 +247,8 @@ export const UNIT_REGISTRY = {
245
247
  "gsd_slice_complete",
246
248
  "gsd_task_reopen",
247
249
  "gsd_replan_slice",
250
+ "gsd_replan_task",
251
+ "gsd_rework_brief_save",
248
252
  "gsd_requirement_update",
249
253
  "gsd_summary_save",
250
254
  ],
@@ -3,7 +3,7 @@
3
3
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  import { gsdRoot, resolveMilestoneFile, resolveSliceFile } from "../paths.js";
6
- import { isDbAvailable, getMilestoneSlices, getSliceTasks } from "../gsd-db.js";
6
+ import { isDbAvailable, getMilestoneSlices, getTasksBySliceIds } from "../gsd-db.js";
7
7
  const PLAN_V2_CLARIFY_ROUND_LIMIT = 3;
8
8
  export const EXECUTION_ENTRY_PHASES = new Set([
9
9
  "executing",
@@ -17,6 +17,19 @@ export function isExecutionEntryPhase(phase) {
17
17
  function graphOutputPath(basePath) {
18
18
  return join(gsdRoot(basePath), "runtime", "uok-plan-v2-graph.json");
19
19
  }
20
+ // True when the on-disk graph matches `output` ignoring the volatile `compiledAt`
21
+ // stamp, so redundant recompiles on the dispatch hot path skip the disk write.
22
+ function graphBodyUnchanged(outPath, output) {
23
+ try {
24
+ const existing = JSON.parse(readFileSync(outPath, "utf-8"));
25
+ const { compiledAt: _existingStamp, ...existingBody } = existing;
26
+ const { compiledAt: _outputStamp, ...outputBody } = output;
27
+ return JSON.stringify(existingBody) === JSON.stringify(outputBody);
28
+ }
29
+ catch {
30
+ return false; // Missing, unreadable, or corrupt — write.
31
+ }
32
+ }
20
33
  function hasFileContent(path) {
21
34
  if (!path || !existsSync(path))
22
35
  return false;
@@ -88,9 +101,10 @@ export function compileUnitGraphFromState(basePath, state) {
88
101
  finalizedContextIncluded,
89
102
  };
90
103
  }
104
+ const tasksBySlice = getTasksBySliceIds(slices.map((slice) => ({ milestoneId: mid, sliceId: slice.id })));
91
105
  for (const slice of slices) {
92
106
  const sid = slice.id;
93
- const tasks = getSliceTasks(mid, sid)
107
+ const tasks = (tasksBySlice.get(`${mid}\0${sid}`) ?? [])
94
108
  .sort((a, b) => Number(a.sequence ?? 0) - Number(b.sequence ?? 0));
95
109
  let previousTaskNodeId = null;
96
110
  for (const task of tasks) {
@@ -138,7 +152,9 @@ export function compileUnitGraphFromState(basePath, state) {
138
152
  };
139
153
  const outPath = graphOutputPath(basePath);
140
154
  mkdirSync(join(gsdRoot(basePath), "runtime"), { recursive: true });
141
- writeFileSync(outPath, JSON.stringify(output, null, 2) + "\n", "utf-8");
155
+ if (!graphBodyUnchanged(outPath, output)) {
156
+ writeFileSync(outPath, JSON.stringify(output, null, 2) + "\n", "utf-8");
157
+ }
142
158
  return {
143
159
  ok: true,
144
160
  graphPath: outPath,
@@ -13,7 +13,7 @@ import { isClosedStatus } from "./status-guards.js";
13
13
  import { deriveState } from "./state.js";
14
14
  import { renderPlanFromDb, renderRoadmapFromDb } from "./markdown-renderer.js";
15
15
  import { readManifest } from "./workflow-manifest.js";
16
- import { gsdRoot, resolveMilestoneFile, resolveSliceFile, resolveTaskFile, relTaskFile } from "./paths.js";
16
+ import { gsdRoot, resolveMilestoneFile, resolveSliceFile, resolveTaskFile, targetTaskFile } from "./paths.js";
17
17
  // ─── Helpers ─────────────────────────────────────────────────────────────
18
18
  /**
19
19
  * Strip a leading ID prefix (e.g. "M001: " or "S04: ") from a title
@@ -276,8 +276,7 @@ export function renderSummaryProjection(basePath, milestoneId, sliceId, taskId)
276
276
  return;
277
277
  const evidenceRows = getVerificationEvidence(milestoneId, sliceId, taskId);
278
278
  const content = renderSummaryContent(taskRow, sliceId, milestoneId, evidenceRows);
279
- const summaryPath = resolveTaskFile(basePath, milestoneId, sliceId, taskId, "SUMMARY")
280
- ?? join(basePath, relTaskFile(basePath, milestoneId, sliceId, taskId, "SUMMARY", getMilestone(milestoneId)?.title));
279
+ const summaryPath = targetTaskFile(basePath, milestoneId, sliceId, taskId, "SUMMARY", getMilestone(milestoneId)?.title);
281
280
  mkdirSync(dirname(summaryPath), { recursive: true });
282
281
  atomicWriteSync(summaryPath, content);
283
282
  }
@@ -2,6 +2,7 @@
2
2
  import { dirname, join, resolve } from "node:path";
3
3
  import { resolveGsdPathContract, resolveMilestoneFile, resolveMilestonePath, targetMilestoneFile, normalizeRealPath, } from "./paths.js";
4
4
  import { isGsdWorktreePath, resolveWorktreeProjectRoot } from "./worktree-root.js";
5
+ import { milestoneMetaPath } from "./git-service.js";
5
6
  function tryRealpath(p) {
6
7
  return normalizeRealPath(p);
7
8
  }
@@ -63,7 +64,7 @@ export function scopeMilestone(workspace, milestoneId) {
63
64
  stateFile: () => join(gsd, "STATE.md"),
64
65
  dbPath: () => contract.projectDb,
65
66
  milestoneDir: () => scopeMilestoneDir(basePath, milestoneId),
66
- metaJson: () => join(gsd, `${milestoneId}-META.json`),
67
+ metaJson: () => milestoneMetaPath(basePath, milestoneId),
67
68
  });
68
69
  return scope;
69
70
  }
@@ -21,7 +21,7 @@
21
21
  import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, statSync, unlinkSync, } from "node:fs";
22
22
  import { join } from "node:path";
23
23
  import { reconcileWorktreeDb } from "./gsd-db.js";
24
- import { resolveGsdPathContract } from "./paths.js";
24
+ import { dirIsContentBearingLegacyMilestone, resolveGsdPathContract } from "./paths.js";
25
25
  import { safeCopy, safeCopyRecursive } from "./safe-fs.js";
26
26
  import { logError, logWarning } from "./workflow-logger.js";
27
27
  // ─── Private helpers ──────────────────────────────────────────────────────
@@ -129,6 +129,8 @@ function syncOtherMilestoneArtifacts(srcMilestonesDir, dstMilestonesDir, current
129
129
  if (milestoneEntry.name === currentMilestoneId)
130
130
  continue;
131
131
  const srcMilestoneDir = join(srcMilestonesDir, milestoneEntry.name);
132
+ if (!dirIsContentBearingLegacyMilestone(srcMilestoneDir))
133
+ continue;
132
134
  const dstMilestoneDir = join(dstMilestonesDir, milestoneEntry.name);
133
135
  // Additively project the entire milestone subtree (force:false), not just
134
136
  // top-level files. Prior completed milestones keep their per-slice and
@@ -143,6 +145,9 @@ function syncOtherMilestoneArtifacts(srcMilestonesDir, dstMilestonesDir, current
143
145
  logWarning("worktree", `milestone artifact scan failed: ${err instanceof Error ? err.message : String(err)}`);
144
146
  }
145
147
  }
148
+ function syncFlatPhaseArtifacts(prGsd, wtGsd) {
149
+ safeCopyRecursive(join(prGsd, "phases"), join(wtGsd, "phases"), { force: false });
150
+ }
146
151
  /**
147
152
  * Root-level .gsd/ files copied from worktree back to project root for
148
153
  * post-merge diagnostics. Markdown projections are NOT in this list — DB
@@ -208,30 +213,33 @@ export function _projectRootToWorktreeImpl(projectRoot, worktreePath_, milestone
208
213
  // Root PROJECT/REQUIREMENTS/DECISIONS projections must be readable from a
209
214
  // worktree-bound unit; the project root remains authoritative.
210
215
  syncRootProjectionFilesToWorktree(prGsd, wtGsd);
216
+ // Flat-phase artifacts (phases/NN-slug/NN-CONTEXT.md, NN-DISCUSSION.md,
217
+ // ROADMAP, etc.) must be available before the first worktree dispatch.
218
+ syncFlatPhaseArtifacts(prGsd, wtGsd);
211
219
  // Copy milestone directory from project root to worktree — additive only.
212
220
  // force:false prevents cpSync from overwriting existing worktree files.
213
221
  // Without this, worktree-local files (e.g. VALIDATION.md written
214
222
  // by validate-milestone) get clobbered by stale project root copies,
215
223
  // causing an infinite re-validation loop (#1886).
216
- safeCopyRecursive(join(prGsd, "milestones", milestoneId), join(wtGsd, "milestones", milestoneId), { force: false });
217
- // Additively project the full subtree of every OTHER milestone so
218
- // worktree-bound units can read prior-milestone context artifacts and so
219
- // completed milestones retain their per-slice/per-task SUMMARY.md and
220
- // UAT.md on the worktree filesystem (otherwise the stale-render detector
221
- // flags them as "complete in DB but missing on disk").
222
- syncOtherMilestoneArtifacts(join(prGsd, "milestones"), join(wtGsd, "milestones"), milestoneId);
223
- // Force-sync ASSESSMENT files that have a verdict from project root (#2821).
224
- // The additive-only copy above preserves worktree-local files, but
225
- // ASSESSMENT files are special: after run-uat writes a verdict and post-unit
226
- // syncs it to the project root, the worktree may retain a stale copy (e.g.
227
- // verdict:fail while the project root has verdict:pass from a retry). On
228
- // session resume the DB is rebuilt from disk, and if the stale ASSESSMENT
229
- // persists, checkNeedsRunUat finds no passing verdict → re-dispatches
230
- // run-uat indefinitely (stuck-loop ×9).
231
224
  const prMilestoneDir = join(prGsd, "milestones", milestoneId);
232
225
  const wtMilestoneDir = join(wtGsd, "milestones", milestoneId);
233
- forceOverwriteValidationWithVerdict(prMilestoneDir, wtMilestoneDir, milestoneId);
234
- forceOverwriteAssessmentsWithVerdict(prMilestoneDir, wtMilestoneDir);
226
+ if (dirIsContentBearingLegacyMilestone(prMilestoneDir)) {
227
+ safeCopyRecursive(prMilestoneDir, wtMilestoneDir, { force: false });
228
+ // Force-sync ASSESSMENT files that have a verdict from project root (#2821).
229
+ // The additive-only copy above preserves worktree-local files, but
230
+ // ASSESSMENT files are special: after run-uat writes a verdict and post-unit
231
+ // syncs it to the project root, the worktree may retain a stale copy (e.g.
232
+ // verdict:fail while the project root has verdict:pass from a retry). On
233
+ // session resume the DB is rebuilt from disk, and if the stale ASSESSMENT
234
+ // persists, checkNeedsRunUat finds no passing verdict → re-dispatches
235
+ // run-uat indefinitely (stuck-loop ×9).
236
+ forceOverwriteValidationWithVerdict(prMilestoneDir, wtMilestoneDir, milestoneId);
237
+ forceOverwriteAssessmentsWithVerdict(prMilestoneDir, wtMilestoneDir);
238
+ }
239
+ // Additively project the full subtree of every OTHER content-bearing legacy
240
+ // milestone so worktree-bound units can read prior-milestone context artifacts
241
+ // without recreating empty/meta-only milestones/ scaffolds in flat-phase projects.
242
+ syncOtherMilestoneArtifacts(join(prGsd, "milestones"), join(wtGsd, "milestones"), milestoneId);
235
243
  // Forward-sync completed-units.json from project root to worktree.
236
244
  // Project root is authoritative for completion state after crash recovery;
237
245
  // without this, the worktree re-dispatches already-completed units (#1886).
@@ -15,6 +15,7 @@ import { StringEnum, Type } from "@gsd/pi-ai";
15
15
  import { execFileSync } from "node:child_process";
16
16
  import { statSync, readdirSync } from "node:fs";
17
17
  import path from "node:path";
18
+ import { constrainScreenshot, getScreenshotBufferDimensions, } from "../browser-tools/screenshot-constraints.js";
18
19
  // ---------------------------------------------------------------------------
19
20
  // Paths
20
21
  // ---------------------------------------------------------------------------
@@ -79,6 +80,27 @@ function ensureCompiled() {
79
80
  throw new Error(`Swift compilation failed (${action.toLowerCase()}):\n${stderr || stdout || err.message}`);
80
81
  }
81
82
  }
83
+ function macScreenshotQualityToPercent(quality) {
84
+ if (quality === undefined || !Number.isFinite(quality))
85
+ return 80;
86
+ return Math.min(100, Math.max(1, Math.round(quality * 100)));
87
+ }
88
+ export async function prepareMacScreenshotPayload(data, quality) {
89
+ const format = data.format;
90
+ const mimeType = format === "png" ? "image/png" : "image/jpeg";
91
+ const rawBuffer = Buffer.from(data.imageData, "base64");
92
+ const constrainedBuffer = await constrainScreenshot(null, rawBuffer, mimeType, macScreenshotQualityToPercent(quality));
93
+ const dimensions = constrainedBuffer === rawBuffer
94
+ ? null
95
+ : await getScreenshotBufferDimensions(constrainedBuffer);
96
+ return {
97
+ imageData: constrainedBuffer.toString("base64"),
98
+ width: dimensions?.width ?? data.width,
99
+ height: dimensions?.height ?? data.height,
100
+ format,
101
+ mimeType,
102
+ };
103
+ }
82
104
  /**
83
105
  * Invoke the mac-agent CLI with a command and optional params.
84
106
  * Handles compilation caching, stdin/stdout JSON protocol, and error surfacing.
@@ -646,18 +668,18 @@ export default function (pi) {
646
668
  if (!result.success) {
647
669
  throw new Error("mac_screenshot: " + result.error);
648
670
  }
649
- const data = result.data;
650
- const imageData = data.imageData;
651
- const format = data.format;
652
- const width = data.width;
653
- const height = data.height;
654
- const mimeType = format === "png" ? "image/png" : "image/jpeg";
671
+ const screenshot = await prepareMacScreenshotPayload(result.data, args.quality);
655
672
  return {
656
673
  content: [
657
- { type: "text", text: `Screenshot: ${width}x${height} ${format}` },
658
- { type: "image", data: imageData, mimeType },
674
+ { type: "text", text: `Screenshot: ${screenshot.width}x${screenshot.height} ${screenshot.format}` },
675
+ { type: "image", data: screenshot.imageData, mimeType: screenshot.mimeType },
659
676
  ],
660
- details: { width, height, format, mimeType },
677
+ details: {
678
+ width: screenshot.width,
679
+ height: screenshot.height,
680
+ format: screenshot.format,
681
+ mimeType: screenshot.mimeType,
682
+ },
661
683
  };
662
684
  },
663
685
  });
@@ -144,6 +144,10 @@ export async function showInterviewRound(questions, opts, ctx) {
144
144
  let previewViewport = 0;
145
145
  let previewTotal = 0;
146
146
  function resetPreviewScroll() { previewScroll = 0; }
147
+ let optionsScroll = 0;
148
+ let optionsViewport = 0;
149
+ let optionsTotal = 0;
150
+ function resetOptionsScroll() { optionsScroll = 0; }
147
151
  function finish(result) {
148
152
  if (completed)
149
153
  return;
@@ -203,6 +207,7 @@ export async function showInterviewRound(questions, opts, ctx) {
203
207
  saveEditorToState();
204
208
  currentIdx = newIdx;
205
209
  resetPreviewScroll();
210
+ resetOptionsScroll();
206
211
  loadStateToEditor();
207
212
  focusNotes = states[currentIdx].notesVisible && states[currentIdx].notes.length > 0;
208
213
  refresh();
@@ -376,32 +381,49 @@ export async function showInterviewRound(questions, opts, ctx) {
376
381
  return;
377
382
  }
378
383
  }
379
- // ── Preview scrolling ────────────────────────────────────────
384
+ // ── Side-by-side panel scrolling ─────────────────────────────
380
385
  if (matchesKey(data, Key.pageUp)) {
386
+ let didScroll = false;
387
+ if (optionsScroll > 0) {
388
+ optionsScroll = Math.max(0, optionsScroll - optionsViewport);
389
+ didScroll = true;
390
+ }
381
391
  if (previewScroll > 0) {
382
392
  previewScroll = Math.max(0, previewScroll - previewViewport);
383
- refresh();
393
+ didScroll = true;
384
394
  }
395
+ if (didScroll)
396
+ refresh();
385
397
  return;
386
398
  }
387
399
  if (matchesKey(data, Key.pageDown)) {
400
+ let didScroll = false;
401
+ const maxOptionsScroll = Math.max(0, optionsTotal - optionsViewport);
402
+ if (optionsScroll < maxOptionsScroll) {
403
+ optionsScroll = Math.min(maxOptionsScroll, optionsScroll + optionsViewport);
404
+ didScroll = true;
405
+ }
388
406
  const maxScroll = Math.max(0, previewTotal - previewViewport);
389
407
  if (previewScroll < maxScroll) {
390
408
  previewScroll = Math.min(maxScroll, previewScroll + previewViewport);
391
- refresh();
409
+ didScroll = true;
392
410
  }
411
+ if (didScroll)
412
+ refresh();
393
413
  return;
394
414
  }
395
415
  // ── Cursor navigation ────────────────────────────────────────
396
416
  if (matchesKey(data, Key.up)) {
397
417
  st.cursorIndex = (st.cursorIndex - 1 + optCount) % optCount;
398
418
  resetPreviewScroll();
419
+ resetOptionsScroll();
399
420
  refresh();
400
421
  return;
401
422
  }
402
423
  if (matchesKey(data, Key.down)) {
403
424
  st.cursorIndex = (st.cursorIndex + 1) % optCount;
404
425
  resetPreviewScroll();
426
+ resetOptionsScroll();
405
427
  refresh();
406
428
  return;
407
429
  }
@@ -637,6 +659,8 @@ export async function showInterviewRound(questions, opts, ctx) {
637
659
  // No scrollable preview unless the side-by-side path sets these below.
638
660
  previewTotal = 0;
639
661
  previewViewport = 0;
662
+ optionsTotal = 0;
663
+ optionsViewport = 0;
640
664
  if (useSideBySide) {
641
665
  // ── Preview path ──────────────────────────────────────
642
666
  const ui = makeUI(theme, contentWidth);
@@ -672,10 +696,21 @@ export async function showInterviewRound(questions, opts, ctx) {
672
696
  const previewWidth = Math.max(MIN_PREVIEW_WIDTH, Math.min(contentWidth - MIN_OPTIONS_WIDTH - DIVIDER_WIDTH, Math.floor(contentWidth * PREVIEW_RATIO)));
673
697
  const leftWidth = Math.max(MIN_OPTIONS_WIDTH, contentWidth - previewWidth - DIVIDER_WIDTH);
674
698
  const fullLeft = renderOptionsColumn(leftWidth);
675
- const leftLines = fullLeft.slice(0, maxBody);
699
+ optionsTotal = fullLeft.length;
700
+ optionsViewport = maxBody;
701
+ const maxOptionsScroll = Math.max(0, fullLeft.length - maxBody);
702
+ if (optionsScroll > maxOptionsScroll)
703
+ optionsScroll = maxOptionsScroll;
704
+ const leftLines = fullLeft.slice(optionsScroll, optionsScroll + maxBody);
676
705
  if (fullLeft.length > maxBody) {
677
- const n = fullLeft.length - maxBody + 1;
678
- leftLines[maxBody - 1] = scrollIndicator(`+${n} lines hidden`, leftWidth);
706
+ const hiddenAbove = optionsScroll;
707
+ const hiddenBelow = fullLeft.length - (optionsScroll + maxBody);
708
+ if (hiddenAbove > 0) {
709
+ leftLines[0] = scrollIndicator(`▲ ${hiddenAbove} more`, leftWidth);
710
+ }
711
+ if (hiddenBelow > 0) {
712
+ leftLines[leftLines.length - 1] = scrollIndicator(`▼ ${hiddenBelow} more · PgUp/PgDn`, leftWidth);
713
+ }
679
714
  }
680
715
  const preview = getCurrentPreview();
681
716
  const fullRight = preview ? renderPreviewColumn(preview, previewWidth) : [];
@@ -734,6 +769,8 @@ export async function showInterviewRound(questions, opts, ctx) {
734
769
  }
735
770
  if (previewTotal > previewViewport)
736
771
  hints.push("pgup/pgdn scroll preview");
772
+ if (optionsTotal > optionsViewport)
773
+ hints.push("pgup/pgdn scroll options");
737
774
  hints.push("esc to exit");
738
775
  const footer = ui.hints(hints)[0] ?? "";
739
776
  cachedLines = renderSharedDialogFrame(theme, title, lines, width, { footer });