@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
@@ -1,6 +1,6 @@
1
1
  import test from "node:test";
2
2
  import assert from "node:assert/strict";
3
- import { mkdtempSync, mkdirSync, rmSync, existsSync } from "node:fs";
3
+ import { mkdtempSync, mkdirSync, rmSync, existsSync, writeFileSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  import { tmpdir } from "node:os";
6
6
 
@@ -9,11 +9,11 @@ import type { PhaseAnchor } from "../phase-anchor.js";
9
9
 
10
10
  function makeTempBase(): string {
11
11
  const tmp = mkdtempSync(join(tmpdir(), "gsd-anchor-test-"));
12
- mkdirSync(join(tmp, ".gsd", "milestones", "M001", "anchors"), { recursive: true });
12
+ mkdirSync(join(tmp, ".gsd"), { recursive: true });
13
13
  return tmp;
14
14
  }
15
15
 
16
- test("writePhaseAnchor creates anchor file in correct location", () => {
16
+ test("writePhaseAnchor creates anchor file under runtime state", () => {
17
17
  const base = makeTempBase();
18
18
  try {
19
19
  const anchor: PhaseAnchor = {
@@ -26,7 +26,35 @@ test("writePhaseAnchor creates anchor file in correct location", () => {
26
26
  nextSteps: ["Plan the implementation slices"],
27
27
  };
28
28
  writePhaseAnchor(base, "M001", anchor);
29
- assert.ok(existsSync(join(base, ".gsd", "milestones", "M001", "anchors", "discuss.json")));
29
+ assert.ok(existsSync(join(base, ".gsd", "runtime", "anchors", "M001", "discuss.json")));
30
+ assert.equal(existsSync(join(base, ".gsd", "milestones", "M001", "anchors", "discuss.json")), false);
31
+ } finally {
32
+ rmSync(base, { recursive: true, force: true });
33
+ }
34
+ });
35
+
36
+ test("readPhaseAnchor falls back to legacy anchor location", () => {
37
+ const base = makeTempBase();
38
+ try {
39
+ const legacyDir = join(base, ".gsd", "milestones", "M001", "anchors");
40
+ mkdirSync(legacyDir, { recursive: true });
41
+ writeFileSync(
42
+ join(legacyDir, "research-slice.json"),
43
+ JSON.stringify({
44
+ phase: "research-slice",
45
+ milestoneId: "M001",
46
+ generatedAt: "2026-07-07T00:00:00.000Z",
47
+ intent: "Keep reading old anchors during upgrade.",
48
+ decisions: [],
49
+ blockers: [],
50
+ nextSteps: [],
51
+ }),
52
+ "utf-8",
53
+ );
54
+
55
+ const read = readPhaseAnchor(base, "M001", "research-slice");
56
+ assert.ok(read);
57
+ assert.equal(read.intent, "Keep reading old anchors during upgrade.");
30
58
  } finally {
31
59
  rmSync(base, { recursive: true, force: true });
32
60
  }
@@ -6,7 +6,7 @@ import { tmpdir } from 'node:os';
6
6
 
7
7
  import { openDatabase, closeDatabase, insertMilestone, insertSlice, insertTask, getSlice, getTask, getSliceTasks, getGateResults } from '../gsd-db.ts';
8
8
  import { handlePlanTask } from '../tools/plan-task.ts';
9
- import { parseTaskPlanFile } from '../files.ts';
9
+ import { parsePlan } from '../parsers-legacy.ts';
10
10
 
11
11
  function makeTmpBase(): string {
12
12
  const base = mkdtempSync(join(tmpdir(), 'gsd-plan-task-'));
@@ -60,7 +60,7 @@ function validParams() {
60
60
  };
61
61
  }
62
62
 
63
- test('handlePlanTask writes planning state and renders task plan', async () => {
63
+ test('handlePlanTask writes planning state and renders the flat-phase slice plan', async () => {
64
64
  const base = makeTmpBase();
65
65
  openDatabase(join(base, '.gsd', 'gsd.db'));
66
66
 
@@ -75,11 +75,13 @@ test('handlePlanTask writes planning state and renders task plan', async () => {
75
75
  assert.equal(task?.description, 'Implement the DB-backed task planning handler.');
76
76
  assert.equal(task?.estimate, '30m');
77
77
 
78
- const taskPlanPath = join(base, '.gsd', 'phases', '01-test', 'T02-PLAN.md');
79
- assert.ok(existsSync(taskPlanPath), 'task plan should be rendered to disk');
80
- const taskPlan = parseTaskPlanFile(readFileSync(taskPlanPath, 'utf-8'));
81
- assert.equal(taskPlan.frontmatter.estimated_files, 1);
82
- assert.deepEqual(taskPlan.frontmatter.skills_used, []);
78
+ const slicePlanPath = join(base, '.gsd', 'phases', '01-test', '01-02-PLAN.md');
79
+ assert.equal(result.taskPlanPath, slicePlanPath);
80
+ assert.ok(existsSync(slicePlanPath), 'slice plan should be rendered to disk');
81
+ assert.equal(existsSync(join(base, '.gsd', 'phases', '01-test', 'T02-PLAN.md')), false);
82
+ const slicePlan = parsePlan(readFileSync(slicePlanPath, 'utf-8'));
83
+ assert.equal(slicePlan.tasks[0]?.id, 'T02');
84
+ assert.equal(slicePlan.tasks[0]?.files?.[0], 'src/resources/extensions/gsd/tools/plan-task.ts');
83
85
  } finally {
84
86
  cleanup(base);
85
87
  }
@@ -215,17 +217,17 @@ test('handlePlanTask rejects missing parent slice', async () => {
215
217
  }
216
218
  });
217
219
 
218
- test('handlePlanTask surfaces render failures without changing parse-visible task plan state', async () => {
220
+ test('handlePlanTask surfaces render failures without changing parse-visible slice plan state', async () => {
219
221
  const base = makeTmpBase();
220
222
  openDatabase(join(base, '.gsd', 'gsd.db'));
221
223
 
222
224
  try {
223
225
  seedParent();
224
226
  insertTask({ id: 'T02', sliceId: 'S02', milestoneId: 'M001', title: 'Cached task', status: 'pending' });
225
- const taskPlanPath = join(base, '.gsd', 'phases', '01-test', 'T02-PLAN.md');
226
- writeFileSync(taskPlanPath, '---\nestimated_steps: 1\nestimated_files: 1\nskills_used: []\n---\n\n# T02: Cached task\n', 'utf-8');
227
- rmSync(taskPlanPath, { force: true });
228
- mkdirSync(taskPlanPath, { recursive: true });
227
+ const slicePlanPath = join(base, '.gsd', 'phases', '01-test', '01-02-PLAN.md');
228
+ writeFileSync(slicePlanPath, '# S02: Cached slice\n\n<tasks>\n- [ ] **T02**: Cached task\n</tasks>\n', 'utf-8');
229
+ rmSync(slicePlanPath, { force: true });
230
+ mkdirSync(slicePlanPath, { recursive: true });
229
231
 
230
232
  const result = await handlePlanTask(validParams(), base);
231
233
  assert.ok('error' in result);
@@ -243,15 +245,16 @@ test('handlePlanTask keeps the sketch flag set when the flat-phase slice plan sy
243
245
  insertMilestone({ id: 'M001', title: 'Milestone', status: 'active' });
244
246
  insertSlice({ id: 'S02', milestoneId: 'M001', title: 'Planning slice', status: 'pending', demo: 'Rendered plans exist.', isSketch: true });
245
247
 
246
- // The per-task render writes T02-PLAN.md and succeeds, but the flat-phase
247
- // slice re-render (the canonical PLAN.md that embeds task checkboxes) targets
248
- // phases/01-test/01-02-PLAN.md. Pre-creating that path as a directory forces
249
- // EISDIR on the slice sync, so the canonical slice plan never reflects the
250
- // task. The sketch flag must therefore stay set — the slice keeps refining —
251
- // instead of leaving the slice out of refining over a stale plan.
248
+ // The flat-phase slice render targets phases/01-test/01-02-PLAN.md.
249
+ // Pre-creating that path as a directory forces EISDIR, so the canonical
250
+ // slice plan never reflects the task. The sketch flag must therefore stay
251
+ // set the slice keeps refining instead of leaving the slice out of
252
+ // refining over a stale plan.
252
253
  mkdirSync(join(base, '.gsd', 'phases', '01-test', '01-02-PLAN.md'), { recursive: true });
253
254
 
254
255
  const result = await handlePlanTask(validParams(), base);
256
+ assert.ok('error' in result);
257
+ assert.match(result.error, /render failed:/);
255
258
  assert.equal(getSlice('M001', 'S02')?.is_sketch, 1, 'sketch flag must stay set when the canonical slice plan could not sync');
256
259
  assert.ok(getTask('M001', 'S02', 'T02'), 'the task itself is still persisted so the slice can re-sync on retry');
257
260
  } finally {
@@ -265,8 +268,8 @@ test('handlePlanTask reruns idempotently and refreshes parse-visible state', asy
265
268
 
266
269
  try {
267
270
  seedParent();
268
- const taskPlanPath = join(base, '.gsd', 'phases', '01-test', 'T02-PLAN.md');
269
- writeFileSync(taskPlanPath, '---\nestimated_steps: 1\nestimated_files: 1\nskills_used: []\n---\n\n# T02: Cached task\n', 'utf-8');
271
+ const slicePlanPath = join(base, '.gsd', 'phases', '01-test', '01-02-PLAN.md');
272
+ writeFileSync(slicePlanPath, '# S02: Cached slice\n\n<tasks>\n- [ ] **T02**: Cached task\n</tasks>\n', 'utf-8');
270
273
 
271
274
  const first = await handlePlanTask(validParams(), base);
272
275
  assert.ok(!('error' in first));
@@ -282,9 +285,9 @@ test('handlePlanTask reruns idempotently and refreshes parse-visible state', asy
282
285
  assert.equal(task?.description, 'Updated task handler description.');
283
286
  assert.equal(task?.estimate, '1h');
284
287
 
285
- const parsed = parseTaskPlanFile(readFileSync(taskPlanPath, 'utf-8'));
286
- assert.equal(parsed.frontmatter.estimated_steps, 1);
287
- assert.match(readFileSync(taskPlanPath, 'utf-8'), /Updated task handler description\./);
288
+ const parsed = parsePlan(readFileSync(slicePlanPath, 'utf-8'));
289
+ assert.equal(parsed.tasks[0]?.id, 'T02');
290
+ assert.match(readFileSync(slicePlanPath, 'utf-8'), /Updated task handler description\./);
288
291
  } finally {
289
292
  cleanup(base);
290
293
  }
@@ -92,6 +92,35 @@ test("writePlanningDirectory is idempotent: writing twice produces stable conten
92
92
  assert.equal(roadmap2, roadmap1);
93
93
  });
94
94
 
95
+ test("writePlanningDirectory does not emit an ingestible PLAN.md for a task-less (sketch) slice", async () => {
96
+ // Regression for #1285: a milestone-level sketch slice has zero DB tasks.
97
+ // The projection must not write a placeholder NN-01-PLAN.md — the reverse
98
+ // transform maps one task per plan file, so a placeholder would materialize
99
+ // a phantom "Plan NN" task and make auto-mode skip planning.
100
+ const base = makeTmp();
101
+ insertSlice({
102
+ milestoneId: "M001", id: "S02", title: "Sketch slice", status: "pending",
103
+ risk: "medium", depends: ["S01"], demo: "designed", sequence: 2,
104
+ });
105
+ // S02 intentionally has no tasks.
106
+
107
+ await writePlanningDirectory(base, "flat-phases");
108
+
109
+ const phaseDirs = readdirSync(join(base, ".planning", "phases"), { withFileTypes: true })
110
+ .filter((d) => d.isDirectory())
111
+ .map((d) => d.name);
112
+ const sketchDir = phaseDirs.find((d) => /^02-/.test(d));
113
+ assert.ok(sketchDir, `expected a 02- phase dir for the sketch slice, got ${JSON.stringify(phaseDirs)}`);
114
+
115
+ const planFiles = readdirSync(join(base, ".planning", "phases", sketchDir!))
116
+ .filter((f) => f.endsWith("PLAN.md"));
117
+ assert.equal(planFiles.length, 0, `sketch slice should have no PLAN.md, got ${JSON.stringify(planFiles)}`);
118
+
119
+ // The slice remains discoverable via ROADMAP.md.
120
+ const roadmap = readFileSync(join(base, ".planning", "ROADMAP.md"), "utf-8");
121
+ assert.match(roadmap, /Sketch slice/);
122
+ });
123
+
95
124
  test("writePlanningDirectory throws for unsupported layouts", async () => {
96
125
  const base = makeTmp();
97
126
  await assert.rejects(() => writePlanningDirectory(base, "multi-milestone"), /not yet supported/);
@@ -496,6 +496,28 @@ describe("checkImportResolution", () => {
496
496
  }
497
497
  });
498
498
 
499
+ test("ignores generated Convex _generated imports", () => {
500
+ tempDir = join(tmpdir(), `post-exec-test-${Date.now()}`);
501
+ mkdirSync(tempDir, { recursive: true });
502
+ mkdirSync(join(tempDir, "convex"), { recursive: true });
503
+ writeFileSync(
504
+ join(tempDir, "convex", "stagedLibraryEdits.ts"),
505
+ "import type { DataModel } from './_generated/dataModel';\nexport const model = {} as DataModel;"
506
+ );
507
+
508
+ try {
509
+ const task = createTask({
510
+ id: "T01",
511
+ key_files: ["convex/stagedLibraryEdits.ts"],
512
+ });
513
+
514
+ const results = checkImportResolution(task, [], tempDir);
515
+ assert.deepEqual(results, []);
516
+ } finally {
517
+ rmSync(tempDir, { recursive: true, force: true });
518
+ }
519
+ });
520
+
499
521
  test("fails when import doesn't resolve", () => {
500
522
  tempDir = join(tmpdir(), `post-exec-test-${Date.now()}`);
501
523
  mkdirSync(tempDir, { recursive: true });
@@ -823,6 +823,90 @@ test("pre-dispatch hook action validation via validatePreferences", () => {
823
823
  assert.ok(e3.some(e => e.includes("invalid action")));
824
824
  });
825
825
 
826
+ test("planning_subagents validation accepts configured read-only planning specialists", () => {
827
+ const { preferences, errors } = validatePreferences({
828
+ planning_subagents: {
829
+ "plan-milestone": { allowed: ["security", "reviewer"] },
830
+ "plan-slice": { allowed: ["scout", "security", "security"] },
831
+ },
832
+ } as any);
833
+
834
+ assert.equal(errors.length, 0);
835
+ assert.deepEqual(preferences.planning_subagents?.["plan-milestone"]?.allowed, ["security", "reviewer"]);
836
+ assert.deepEqual(preferences.planning_subagents?.["plan-slice"]?.allowed, ["scout", "security"]);
837
+ });
838
+
839
+ test("planning_subagents validation rejects unsupported units and unsafe agents", () => {
840
+ const { preferences, errors } = validatePreferences({
841
+ planning_subagents: {
842
+ "execute-task": { allowed: ["security"] },
843
+ "plan-slice": { allowed: ["worker"] },
844
+ },
845
+ } as any);
846
+
847
+ assert.equal(preferences.planning_subagents, undefined);
848
+ assert.ok(errors.some(e => e.includes("unsupported unit \"execute-task\"")));
849
+ assert.ok(errors.some(e => e.includes("\"worker\"") && e.includes("read-only planning specialist")));
850
+ });
851
+
852
+ test("loadEffectiveGSDPreferences merges planning_subagents allowlists", (t) => {
853
+ const originalCwd = process.cwd();
854
+ const originalGsdHome = process.env.GSD_HOME;
855
+ const tempProject = mkdtempSync(join(tmpdir(), "gsd-planning-subagents-project-"));
856
+ const tempGsdHome = mkdtempSync(join(tmpdir(), "gsd-planning-subagents-home-"));
857
+
858
+ t.after(() => {
859
+ clearGSDPreferencesCache();
860
+ process.chdir(originalCwd);
861
+ if (originalGsdHome === undefined) delete process.env.GSD_HOME;
862
+ else process.env.GSD_HOME = originalGsdHome;
863
+ rmSync(tempProject, { recursive: true, force: true });
864
+ rmSync(tempGsdHome, { recursive: true, force: true });
865
+ });
866
+
867
+ mkdirSync(join(tempProject, ".gsd"), { recursive: true });
868
+ process.env.GSD_HOME = tempGsdHome;
869
+ process.chdir(tempProject);
870
+ clearGSDPreferencesCache();
871
+
872
+ writeFileSync(
873
+ getGlobalGSDPreferencesPath(),
874
+ [
875
+ "---",
876
+ "version: 1",
877
+ "planning_subagents:",
878
+ " plan-slice:",
879
+ " allowed: [scout, reviewer]",
880
+ "---",
881
+ "",
882
+ ].join("\n"),
883
+ "utf-8",
884
+ );
885
+ writeFileSync(
886
+ getProjectGSDPreferencesPath(tempProject),
887
+ [
888
+ "---",
889
+ "version: 1",
890
+ "planning_subagents:",
891
+ " plan-slice:",
892
+ " allowed: [security]",
893
+ " plan-milestone:",
894
+ " allowed: [planner]",
895
+ "---",
896
+ "",
897
+ ].join("\n"),
898
+ "utf-8",
899
+ );
900
+
901
+ const loaded = loadEffectiveGSDPreferences(tempProject);
902
+ assert.deepEqual(loaded?.preferences.planning_subagents?.["plan-slice"]?.allowed, [
903
+ "scout",
904
+ "reviewer",
905
+ "security",
906
+ ]);
907
+ assert.deepEqual(loaded?.preferences.planning_subagents?.["plan-milestone"]?.allowed, ["planner"]);
908
+ });
909
+
826
910
  // ── Model config parsing ─────────────────────────────────────────────────────
827
911
 
828
912
  test("parses OpenRouter model config with org/model IDs and fallbacks", () => {
@@ -54,6 +54,10 @@ const PREF_SAMPLE_VALUES: Record<string, unknown> = {
54
54
  },
55
55
  post_unit_hooks: [{ command: "npm test" }],
56
56
  pre_dispatch_hooks: [{ command: "npm run lint" }],
57
+ planning_subagents: {
58
+ "plan-milestone": { allowed: ["scout", "planner"] },
59
+ "plan-slice": { allowed: ["scout"] },
60
+ },
57
61
  dynamic_routing: { enabled: true },
58
62
  disabled_model_providers: ["slow-provider"],
59
63
  uok: { enabled: true },
@@ -13,6 +13,7 @@ import { tmpdir } from "node:os";
13
13
  import { fileURLToPath } from "node:url";
14
14
 
15
15
  import { buildExecuteTaskPrompt, buildPlanSlicePrompt, buildReactiveExecutePrompt, buildResearchSlicePrompt, inlineDependencySummaries } from "../auto-prompts.js";
16
+ import { buildDiscussSlicePrompt } from "../guided-flow.js";
16
17
  import { computeBudgets, truncateAtSectionBoundary } from "../context-budget.js";
17
18
 
18
19
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -735,3 +736,89 @@ describe("prompt-budget: modelRegistry + sessionContextWindow behavior", () => {
735
736
  }
736
737
  });
737
738
  });
739
+
740
+ // ─── execute-task + discuss-slice inline caps (plan 039) ──────────────────────
741
+
742
+ describe("prompt-budget: execute-task inline cap (039)", () => {
743
+ it("keeps the authoritative task plan whole but drops trailing templates when the plan alone exceeds the inline budget", async () => {
744
+ const base = createFixtureBase();
745
+ try {
746
+ const sliceDir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
747
+ const taskDir = join(sliceDir, "tasks");
748
+ mkdirSync(taskDir, { recursive: true });
749
+ writeFileSync(join(base, ".gsd", "milestones", "M001", "M001-ROADMAP.md"), "# Roadmap\n");
750
+ writeFileSync(join(sliceDir, "S01-PLAN.md"), "# Slice Plan\n");
751
+ // Oversized task plan (~60K) — well past the 20K inline ceiling.
752
+ const bigPlan = "# Task Plan\n\nMARKER_TASKPLAN_HEAD\n\n" + Array.from({ length: 30 }, (_, i) =>
753
+ `### Step ${i}\n\n${"Implementation detail. ".repeat(90)}`
754
+ ).join("\n\n");
755
+ writeFileSync(join(taskDir, "T01-PLAN.md"), bigPlan);
756
+
757
+ const prompt = await buildExecuteTaskPrompt("M001", "S01", "Slice", "T01", "Task", base, {
758
+ level: "standard",
759
+ sessionContextWindow: 32_000,
760
+ });
761
+
762
+ // The task plan is the authoritative execution contract — never truncated;
763
+ // its content survives whole even when it alone exceeds the inline budget.
764
+ assert.match(prompt, /MARKER_TASKPLAN_HEAD/);
765
+ assert.match(prompt, /### Step 29/);
766
+ // Trailing lower-priority templates are dropped — the on-demand decisions
767
+ // template that "standard" normally inlines is gone because the task plan
768
+ // consumed the entire inline budget. (Baseline: the tiny-plan test above
769
+ // asserts this block IS present.)
770
+ assert.doesNotMatch(prompt, /### On-demand Decisions Template/);
771
+ } finally {
772
+ cleanup(base);
773
+ }
774
+ });
775
+ });
776
+
777
+ describe("prompt-budget: discuss-slice inline cap (039)", () => {
778
+ it("prepends the configured response language", async () => {
779
+ const base = createFixtureBase();
780
+ const gsdHome = mkdtempSync(join(tmpdir(), "gsd-discuss-slice-language-home-"));
781
+ const previousGsdHome = process.env.GSD_HOME;
782
+ process.env.GSD_HOME = gsdHome;
783
+
784
+ try {
785
+ writeFileSync(join(gsdHome, "PREFERENCES.md"), "---\nversion: 1\nlanguage: 中文\n---\n", "utf-8");
786
+ mkdirSync(join(base, ".gsd", "milestones", "M001", "slices", "S01"), { recursive: true });
787
+
788
+ const prompt = await buildDiscussSlicePrompt("M001", "S01", "Current", base);
789
+
790
+ assert.match(prompt, /^## Response Language\n\nAlways respond in 中文/);
791
+ } finally {
792
+ if (previousGsdHome === undefined) delete process.env.GSD_HOME;
793
+ else process.env.GSD_HOME = previousGsdHome;
794
+ cleanup(base);
795
+ cleanup(gsdHome);
796
+ }
797
+ });
798
+
799
+ it("caps the inlined block — roadmap survives first, the trailing decisions register truncates", async () => {
800
+ const base = createFixtureBase();
801
+ try {
802
+ const msDir = join(base, ".gsd", "milestones", "M001");
803
+ mkdirSync(join(msDir, "slices", "S01"), { recursive: true });
804
+ writeFileSync(join(msDir, "M001-ROADMAP.md"), "# Roadmap\n\nMARKER_ROADMAP\n\n- [ ] **S01: Current** `risk:low`\n");
805
+ writeFileSync(join(msDir, "M001-CONTEXT.md"), "# Context\n\nMARKER_CONTEXT\n");
806
+ // Huge decisions register (~60K) — the unbounded-growth surface the cap bounds.
807
+ const bigDecisions = "# Decisions\n\n" + Array.from({ length: 40 }, (_, i) =>
808
+ `### D${String(i).padStart(3, "0")}\n\n${"Decision rationale detail. ".repeat(60)}`
809
+ ).join("\n\n");
810
+ writeFileSync(join(base, ".gsd", "DECISIONS.md"), bigDecisions);
811
+
812
+ const prompt = await buildDiscussSlicePrompt("M001", "S01", "Current", base);
813
+
814
+ // Roadmap is first in the inlined block → survives the cap.
815
+ assert.match(prompt, /MARKER_ROADMAP/);
816
+ // The cap fired (capPreamble ceiling is 20K; the block is ~60K).
817
+ assert.match(prompt, /\[\.\.\.truncated/);
818
+ // The last decision (trailing content) is dropped.
819
+ assert.doesNotMatch(prompt, /### D039/);
820
+ } finally {
821
+ cleanup(base);
822
+ }
823
+ });
824
+ });
@@ -23,7 +23,10 @@ import {
23
23
  } from "../bootstrap/agent-end-recovery.ts";
24
24
  import { blockModelUntil, clearTemporaryModelBlocksForTest } from "../blocked-models.ts";
25
25
  import { _buildCancelledUnitStopReason } from "../auto/phase-helpers.ts";
26
- import { _classifyZeroToolProviderMessageForTest } from "../auto/unit-phase.ts";
26
+ import {
27
+ _classifyZeroToolProviderMessageForTest,
28
+ _zeroToolPseudoToolCallSnippetForTest,
29
+ } from "../auto/unit-phase.ts";
27
30
  import { autoSession } from "../auto-runtime-state.ts";
28
31
  import { getNextFallbackModel } from "../preferences.ts";
29
32
  import { clearGuidedUnitContext, getGuidedUnitContext, setGuidedUnitContext } from "../guided-unit-context.ts";
@@ -77,6 +80,21 @@ test("zero-tool provider classifier treats weekly limit wording as transient rat
77
80
  assert.equal(result.kind, "rate-limit");
78
81
  });
79
82
 
83
+ test("zero-tool pseudo tool-call detector identifies serialization drift", () => {
84
+ const snippet = _zeroToolPseudoToolCallSnippetForTest(
85
+ 'bash<arg_key>command</arg_key><arg_value>ls -la /tmp && echo "---SRC---"</arg_value></tool_call>',
86
+ );
87
+ assert.ok(snippet, "pseudo tool-call text should be recognized");
88
+ assert.match(snippet, /bash<arg_key>command<\/arg_key>/);
89
+ });
90
+
91
+ test("zero-tool provider classifier does not treat pseudo tool-call text as an error class", () => {
92
+ const result = _classifyZeroToolProviderMessageForTest(
93
+ 'bash<arg_key>command</arg_key><arg_value>ls -la /tmp && echo "---SRC---"</arg_value></tool_call>',
94
+ );
95
+ assert.equal(result, null, "pseudo tool-call text is drift, not a provider error");
96
+ });
97
+
80
98
  test("classifyError treats extra-usage phrasing as transient rate-limit (#4397)", () => {
81
99
  const result = classifyError("You are out of extra usage. Please wait before retrying.");
82
100
  assert.ok(isTransient(result));
@@ -651,6 +669,108 @@ test("rate-limit agent_end walks past unavailable fallback models before pausing
651
669
  }
652
670
  });
653
671
 
672
+ test("retry-exhausted abort/unknown provider stop reasons trigger model fallback (#1364)", async () => {
673
+ const originalCwd = process.cwd();
674
+ const originalSetTimeout = globalThis.setTimeout;
675
+
676
+ globalThis.setTimeout = ((fn: (...args: unknown[]) => void, delay?: number) => {
677
+ if ((delay ?? 0) === 0) {
678
+ fn();
679
+ }
680
+ return 0 as unknown as ReturnType<typeof setTimeout>;
681
+ }) as typeof setTimeout;
682
+
683
+ try {
684
+ for (const reason of ["abort", "unknown"]) {
685
+ const base = mkdtempSync(join(tmpdir(), `gsd-stop-reason-${reason}-`));
686
+ const notifications: Array<{ message: string; level?: string }> = [];
687
+ const setModelCalls: string[] = [];
688
+ const sendMessageCalls: unknown[][] = [];
689
+
690
+ try {
691
+ resetTransientRetryState();
692
+ clearTemporaryModelBlocksForTest();
693
+ autoSession.reset();
694
+ mkdirSync(join(base, ".gsd"), { recursive: true });
695
+ writeFileSync(
696
+ join(base, ".gsd", "PREFERENCES.md"),
697
+ [
698
+ "---",
699
+ "models:",
700
+ " execution:",
701
+ " model: gpt-5.5",
702
+ " provider: openai-codex",
703
+ " fallbacks:",
704
+ " - anthropic/claude-sonnet-4-6",
705
+ "---",
706
+ ].join("\n"),
707
+ "utf-8",
708
+ );
709
+ process.chdir(base);
710
+
711
+ autoSession.active = true;
712
+ autoSession.basePath = base;
713
+ autoSession.currentUnit = { type: "execute-task", id: "M001/S01/T01", startedAt: Date.now() };
714
+ autoSession.autoModeStartModel = { provider: "openai-codex", id: "gpt-5.5" };
715
+
716
+ const availableModels = [
717
+ { id: "gpt-5.5", provider: "openai-codex", api: "responses" },
718
+ { id: "claude-sonnet-4-6", provider: "anthropic", api: "anthropic-messages" },
719
+ ];
720
+ const ctx = {
721
+ model: availableModels[0],
722
+ modelRegistry: { getAvailable: () => availableModels },
723
+ ui: {
724
+ notify(message: string, level?: "info" | "warning" | "error" | "success") {
725
+ notifications.push({ message, level });
726
+ },
727
+ setStatus: () => {},
728
+ setWidget: () => {},
729
+ setWorkingMessage: () => {},
730
+ },
731
+ } as any;
732
+ const pi = {
733
+ setModel: async (model: { provider: string; id: string }) => {
734
+ setModelCalls.push(`${model.provider}/${model.id}`);
735
+ return true;
736
+ },
737
+ sendMessage: (...args: unknown[]) => {
738
+ sendMessageCalls.push(args);
739
+ },
740
+ } as any;
741
+
742
+ await handleAgentEnd(pi, {
743
+ messages: [{
744
+ role: "assistant",
745
+ stopReason: "error",
746
+ errorMessage: `Retry failed after 3 attempts: Unhandled stop reason: ${reason}`,
747
+ }],
748
+ } as any, ctx);
749
+
750
+ assert.deepEqual(setModelCalls, ["anthropic/claude-sonnet-4-6"], `${reason} should switch to configured fallback`);
751
+ assert.equal(sendMessageCalls.length, 1, `${reason} fallback recovery must trigger a continuation turn`);
752
+ assert.deepEqual(sendMessageCalls[0][1], { triggerTurn: true });
753
+ assert.ok(
754
+ notifications.some((n) => n.message.includes("anthropic/claude-sonnet-4-6")),
755
+ `${reason} notification should name the selected fallback`,
756
+ );
757
+ } finally {
758
+ process.chdir(originalCwd);
759
+ clearTemporaryModelBlocksForTest();
760
+ resetTransientRetryState();
761
+ autoSession.reset();
762
+ rmSync(base, { recursive: true, force: true });
763
+ }
764
+ }
765
+ } finally {
766
+ globalThis.setTimeout = originalSetTimeout;
767
+ process.chdir(originalCwd);
768
+ clearTemporaryModelBlocksForTest();
769
+ resetTransientRetryState();
770
+ autoSession.reset();
771
+ }
772
+ });
773
+
654
774
  test("isTerminalDeletedWorktreeProviderError matches removed auto-worktree paths only", () => {
655
775
  assert.equal(
656
776
  isTerminalDeletedWorktreeProviderError('Path "/Users/dev/.gsd/projects/abc123/worktrees/M005" does not exist'),
@@ -608,3 +608,42 @@ test("getDependencyTaskSummaryPaths handles missing dependency summaries gracefu
608
608
  rmSync(repo, { recursive: true, force: true });
609
609
  }
610
610
  });
611
+
612
+ test("#1343: getPriorTaskSummaryPaths excludes sibling-slice summaries in flat-phase", async () => {
613
+ const { getPriorTaskSummaryPaths } = await import("../auto-prompts.ts");
614
+ const repo = mkdtempSync(join(tmpdir(), "gsd-reactive-flat-prior-"));
615
+ try {
616
+ // Flat-phase: slices S01 and S02 share the phase dir and overlap task ids.
617
+ const phaseDir = join(repo, ".gsd", "phases", "01-test");
618
+ mkdirSync(phaseDir, { recursive: true });
619
+ writeFileSync(join(phaseDir, "S01-T01-SUMMARY.md"), "---\nid: T01\n---\n# S01 T01\n");
620
+ writeFileSync(join(phaseDir, "S02-T01-SUMMARY.md"), "---\nid: T01\n---\n# S02 T01\n");
621
+
622
+ // S02/T02 prior summaries must not pull the sibling S01-T01 summary.
623
+ const paths = await getPriorTaskSummaryPaths("M001", "S02", "T02", repo);
624
+ assert.equal(paths.length, 1, "Should only return the current slice's prior summary");
625
+ assert.ok(paths[0].includes("S02-T01-SUMMARY"), "Should include S02's T01");
626
+ assert.ok(!paths.some((p) => p.includes("S01-T01-SUMMARY")), "Should NOT include sibling S01's T01");
627
+ } finally {
628
+ rmSync(repo, { recursive: true, force: true });
629
+ }
630
+ });
631
+
632
+ test("#1343: getDependencyTaskSummaryPaths excludes sibling-slice summaries in flat-phase", async () => {
633
+ const { getDependencyTaskSummaryPaths } = await import("../auto-prompts.ts");
634
+ const repo = mkdtempSync(join(tmpdir(), "gsd-reactive-flat-dep-"));
635
+ try {
636
+ const phaseDir = join(repo, ".gsd", "phases", "01-test");
637
+ mkdirSync(phaseDir, { recursive: true });
638
+ writeFileSync(join(phaseDir, "S01-T01-SUMMARY.md"), "---\nid: T01\n---\n# S01 T01\n");
639
+ writeFileSync(join(phaseDir, "S02-T01-SUMMARY.md"), "---\nid: T01\n---\n# S02 T01\n");
640
+
641
+ // S02/T02 depends on T01 — must resolve S02's T01, not the sibling S01's.
642
+ const paths = await getDependencyTaskSummaryPaths("M001", "S02", "T02", ["T01"], repo);
643
+ assert.equal(paths.length, 1, "Should only return the current slice's dependency summary");
644
+ assert.ok(paths[0].includes("S02-T01-SUMMARY"), "Should include S02's T01");
645
+ assert.ok(!paths.some((p) => p.includes("S01-T01-SUMMARY")), "Should NOT include sibling S01's T01");
646
+ } finally {
647
+ rmSync(repo, { recursive: true, force: true });
648
+ }
649
+ });