@opengsd/gsd-pi 1.4.0 → 1.5.0-dev.553dc518

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 (606) hide show
  1. package/README.md +11 -11
  2. package/dist/onboarding.js +11 -0
  3. package/dist/resources/.managed-resources-content-hash +1 -1
  4. package/dist/resources/GSD-WORKFLOW.md +20 -25
  5. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +118 -53
  6. package/dist/resources/extensions/cursor-cli/index.js +16 -0
  7. package/dist/resources/extensions/cursor-cli/models.js +63 -0
  8. package/dist/resources/extensions/cursor-cli/package.json +11 -0
  9. package/dist/resources/extensions/cursor-cli/readiness.js +128 -0
  10. package/dist/resources/extensions/cursor-cli/stream-adapter.js +353 -0
  11. package/dist/resources/extensions/gsd/activity-log.js +4 -1
  12. package/dist/resources/extensions/gsd/artifact-verification.js +25 -9
  13. package/dist/resources/extensions/gsd/auto/closeout.js +137 -42
  14. package/dist/resources/extensions/gsd/auto/finalize.js +9 -0
  15. package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -3
  16. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +6 -3
  17. package/dist/resources/extensions/gsd/auto/run-unit.js +5 -2
  18. package/dist/resources/extensions/gsd/auto/schedule-wakeup.js +3 -0
  19. package/dist/resources/extensions/gsd/auto/unit-phase.js +5 -9
  20. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +4 -5
  21. package/dist/resources/extensions/gsd/auto-dispatch.js +15 -5
  22. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -18
  23. package/dist/resources/extensions/gsd/auto-prompts.js +76 -2
  24. package/dist/resources/extensions/gsd/auto-start.js +7 -5
  25. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +4 -0
  26. package/dist/resources/extensions/gsd/auto-worktree-branch-lifecycle.js +189 -0
  27. package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +133 -0
  28. package/dist/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.js +35 -0
  29. package/dist/resources/extensions/gsd/auto-worktree-creation.js +130 -0
  30. package/dist/resources/extensions/gsd/auto-worktree-entry.js +118 -0
  31. package/dist/resources/extensions/gsd/auto-worktree-merge-already-merged.js +98 -0
  32. package/dist/resources/extensions/gsd/auto-worktree-merge-branch-head.js +52 -0
  33. package/dist/resources/extensions/gsd/auto-worktree-merge-cleanup.js +87 -0
  34. package/dist/resources/extensions/gsd/auto-worktree-merge-code-changes.js +46 -0
  35. package/dist/resources/extensions/gsd/auto-worktree-merge-db-ready.js +68 -0
  36. package/dist/resources/extensions/gsd/auto-worktree-merge-integration-branch.js +51 -0
  37. package/dist/resources/extensions/gsd/auto-worktree-merge-message.js +106 -0
  38. package/dist/resources/extensions/gsd/auto-worktree-merge-pre-teardown.js +64 -0
  39. package/dist/resources/extensions/gsd/auto-worktree-merge-stash.js +168 -0
  40. package/dist/resources/extensions/gsd/auto-worktree-merge.js +302 -0
  41. package/dist/resources/extensions/gsd/auto-worktree-milestone-shelter.js +119 -0
  42. package/dist/resources/extensions/gsd/auto-worktree-path-resolution.js +5 -0
  43. package/dist/resources/extensions/gsd/auto-worktree-path-utils.js +5 -0
  44. package/dist/resources/extensions/gsd/auto-worktree-resource-version.js +41 -0
  45. package/dist/resources/extensions/gsd/auto-worktree-runtime-cleanup.js +99 -0
  46. package/dist/resources/extensions/gsd/auto-worktree-session-registry.js +57 -0
  47. package/dist/resources/extensions/gsd/auto-worktree-sync.js +249 -0
  48. package/dist/resources/extensions/gsd/auto-worktree-teardown.js +120 -0
  49. package/dist/resources/extensions/gsd/auto-worktree.js +20 -2046
  50. package/dist/resources/extensions/gsd/auto.js +31 -5
  51. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -0
  52. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -1
  53. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +133 -6
  54. package/dist/resources/extensions/gsd/bootstrap/schedule-wakeup-tool.js +58 -9
  55. package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
  56. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +127 -22
  57. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +14 -1
  58. package/dist/resources/extensions/gsd/codebase-generator.js +157 -19
  59. package/dist/resources/extensions/gsd/commands/handlers/core.js +40 -4
  60. package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
  61. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +153 -1
  62. package/dist/resources/extensions/gsd/commands-workflow-templates.js +3 -3
  63. package/dist/resources/extensions/gsd/commands-worktree.js +11 -2
  64. package/dist/resources/extensions/gsd/db/queries.js +48 -9
  65. package/dist/resources/extensions/gsd/discussion-handoff.js +8 -3
  66. package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -2
  67. package/dist/resources/extensions/gsd/doctor-engine-checks.js +292 -18
  68. package/dist/resources/extensions/gsd/doctor-providers.js +38 -10
  69. package/dist/resources/extensions/gsd/doctor.js +93 -3
  70. package/dist/resources/extensions/gsd/exec-sandbox.js +6 -2
  71. package/dist/resources/extensions/gsd/flat-phase-migration.js +88 -26
  72. package/dist/resources/extensions/gsd/forensics.js +1 -1
  73. package/dist/resources/extensions/gsd/git-conflict-resolve.js +2 -2
  74. package/dist/resources/extensions/gsd/git-service.js +59 -18
  75. package/dist/resources/extensions/gsd/gsd-db.js +63 -0
  76. package/dist/resources/extensions/gsd/guidance.js +1 -0
  77. package/dist/resources/extensions/gsd/guided-flow.js +46 -12
  78. package/dist/resources/extensions/gsd/key-manager.js +1 -0
  79. package/dist/resources/extensions/gsd/markdown-renderer.js +40 -11
  80. package/dist/resources/extensions/gsd/migrate-external.js +24 -7
  81. package/dist/resources/extensions/gsd/milestone-merge-transaction.js +14 -3
  82. package/dist/resources/extensions/gsd/milestone-settlement.js +1 -1
  83. package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
  84. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -1
  85. package/dist/resources/extensions/gsd/preferences-diagnostics.js +24 -1
  86. package/dist/resources/extensions/gsd/preferences-models.js +6 -4
  87. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  88. package/dist/resources/extensions/gsd/preferences-validation.js +107 -2
  89. package/dist/resources/extensions/gsd/preferences.js +29 -2
  90. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -2
  91. package/dist/resources/extensions/gsd/prompts/system.md +6 -6
  92. package/dist/resources/extensions/gsd/quick.js +12 -3
  93. package/dist/resources/extensions/gsd/redact-secrets.js +37 -0
  94. package/dist/resources/extensions/gsd/repo-identity.js +16 -0
  95. package/dist/resources/extensions/gsd/repository-registry.js +6 -1
  96. package/dist/resources/extensions/gsd/root-write-leak-guard.js +4 -2
  97. package/dist/resources/extensions/gsd/safe-fs.js +23 -2
  98. package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
  99. package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -0
  100. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +2 -1
  101. package/dist/resources/extensions/gsd/state/derive/from-db.js +88 -153
  102. package/dist/resources/extensions/gsd/tool-contract.js +14 -0
  103. package/dist/resources/extensions/gsd/tools/plan-task.js +76 -8
  104. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +40 -0
  105. package/dist/resources/extensions/gsd/unit-context-manifest.js +5 -4
  106. package/dist/resources/extensions/gsd/unit-registry.js +37 -2
  107. package/dist/resources/extensions/gsd/unit-runtime.js +21 -0
  108. package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +1 -1
  109. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -1
  110. package/dist/resources/extensions/gsd/workspace-git-preflight.js +2 -2
  111. package/dist/resources/extensions/gsd/workspace.js +26 -8
  112. package/dist/resources/extensions/gsd/worktree-command.js +1 -1
  113. package/dist/resources/extensions/gsd/worktree-lifecycle.js +81 -14
  114. package/dist/resources/extensions/gsd/worktree-manager.js +97 -4
  115. package/dist/resources/extensions/gsd/worktree-reentry.js +2 -1
  116. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  117. package/dist/web/standalone/.next/BUILD_ID +1 -1
  118. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  119. package/dist/web/standalone/.next/build-manifest.json +3 -3
  120. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  121. package/dist/web/standalone/.next/required-server-files.json +3 -3
  122. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  123. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  133. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  136. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  139. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  149. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  161. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  183. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  193. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  199. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  215. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  219. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  224. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  228. package/dist/web/standalone/.next/server/app/index.html +1 -1
  229. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  230. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  231. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  232. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  233. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  234. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  235. package/dist/web/standalone/.next/server/app/page.js +2 -2
  236. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  237. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  238. package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
  239. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  240. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  241. package/dist/web/standalone/.next/server/middleware.js +3 -3
  242. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  243. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  244. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  245. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +1 -0
  246. package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
  247. package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
  248. package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
  249. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
  250. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  251. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  252. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  253. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  254. package/dist/web/standalone/server.js +1 -1
  255. package/dist/wizard.d.ts +8 -0
  256. package/dist/wizard.js +8 -1
  257. package/integrations/hermes/CONTEXT.md +47 -0
  258. package/integrations/hermes/README.md +21 -0
  259. package/integrations/hermes/__init__.py +31 -0
  260. package/integrations/hermes/docs/issue-1162-grilling.md +197 -0
  261. package/integrations/hermes/docs/setup.md +4 -0
  262. package/integrations/hermes/open_gsd_hermes/commands.py +141 -0
  263. package/integrations/hermes/open_gsd_hermes/config.py +2 -0
  264. package/integrations/hermes/open_gsd_hermes/gsd_client.py +591 -39
  265. package/integrations/hermes/open_gsd_hermes/notifications.py +10 -1
  266. package/integrations/hermes/plugin.yaml +4 -0
  267. package/integrations/hermes/tests/test_config.py +6 -0
  268. package/integrations/hermes/tests/test_directory_loader.py +37 -0
  269. package/integrations/hermes/tests/test_gsd_client_cache.py +3 -0
  270. package/integrations/hermes/tests/test_gsd_client_execute.py +35 -0
  271. package/integrations/hermes/tests/test_gsd_client_process_cwd.py +22 -0
  272. package/integrations/hermes/tests/test_gsd_client_timeout.py +98 -0
  273. package/integrations/hermes/tests/test_milestone_client.py +447 -0
  274. package/integrations/hermes/tests/test_new_milestone_command.py +313 -0
  275. package/integrations/hermes/tests/test_supervisor_fsm.py +40 -0
  276. package/package.json +8 -8
  277. package/packages/cloud-mcp-gateway/dist/auth-store.d.ts +1 -0
  278. package/packages/cloud-mcp-gateway/dist/auth-store.d.ts.map +1 -1
  279. package/packages/cloud-mcp-gateway/dist/auth-store.js +21 -1
  280. package/packages/cloud-mcp-gateway/dist/auth-store.js.map +1 -1
  281. package/packages/cloud-mcp-gateway/dist/auth-store.test.js +34 -0
  282. package/packages/cloud-mcp-gateway/dist/auth-store.test.js.map +1 -1
  283. package/packages/cloud-mcp-gateway/package.json +2 -2
  284. package/packages/contracts/package.json +1 -1
  285. package/packages/daemon/dist/cloud-runtime.d.ts +2 -0
  286. package/packages/daemon/dist/cloud-runtime.d.ts.map +1 -1
  287. package/packages/daemon/dist/cloud-runtime.js +25 -1
  288. package/packages/daemon/dist/cloud-runtime.js.map +1 -1
  289. package/packages/daemon/dist/cloud-runtime.test.js +51 -0
  290. package/packages/daemon/dist/cloud-runtime.test.js.map +1 -1
  291. package/packages/daemon/dist/message-batcher.d.ts +7 -0
  292. package/packages/daemon/dist/message-batcher.d.ts.map +1 -1
  293. package/packages/daemon/dist/message-batcher.js +13 -0
  294. package/packages/daemon/dist/message-batcher.js.map +1 -1
  295. package/packages/daemon/dist/message-batcher.test.js +48 -0
  296. package/packages/daemon/dist/message-batcher.test.js.map +1 -1
  297. package/packages/daemon/dist/session-manager.js +1 -1
  298. package/packages/daemon/dist/session-manager.js.map +1 -1
  299. package/packages/daemon/package.json +5 -5
  300. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts +13 -1
  301. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
  302. package/packages/gsd-agent-core/dist/compaction/compaction.js +15 -1
  303. package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
  304. package/packages/gsd-agent-core/dist/export-html/template.js +53 -4
  305. package/packages/gsd-agent-core/dist/session/agent-session-navigation.d.ts.map +1 -1
  306. package/packages/gsd-agent-core/dist/session/agent-session-navigation.js +4 -1
  307. package/packages/gsd-agent-core/dist/session/agent-session-navigation.js.map +1 -1
  308. package/packages/gsd-agent-core/package.json +5 -5
  309. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  310. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +3 -2
  311. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  312. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -1
  313. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +1 -0
  314. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -1
  315. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +1 -1
  316. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
  317. package/packages/gsd-agent-modes/package.json +7 -7
  318. package/packages/mcp-server/dist/server.d.ts +18 -5
  319. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  320. package/packages/mcp-server/dist/server.js +46 -5
  321. package/packages/mcp-server/dist/server.js.map +1 -1
  322. package/packages/mcp-server/dist/session-manager.js +1 -1
  323. package/packages/mcp-server/dist/session-manager.js.map +1 -1
  324. package/packages/mcp-server/package.json +4 -4
  325. package/packages/native/package.json +1 -1
  326. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  327. package/packages/pi-agent-core/dist/agent-loop.js +14 -9
  328. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  329. package/packages/pi-agent-core/package.json +1 -1
  330. package/packages/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  331. package/packages/pi-ai/dist/env-api-keys.js +3 -0
  332. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  333. package/packages/pi-ai/dist/index.d.ts +1 -0
  334. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  335. package/packages/pi-ai/dist/index.js +1 -0
  336. package/packages/pi-ai/dist/index.js.map +1 -1
  337. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  338. package/packages/pi-ai/dist/providers/transform-messages.js +7 -3
  339. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  340. package/packages/pi-ai/dist/tool-result-content.d.ts +3 -0
  341. package/packages/pi-ai/dist/tool-result-content.d.ts.map +1 -0
  342. package/packages/pi-ai/dist/tool-result-content.js +62 -0
  343. package/packages/pi-ai/dist/tool-result-content.js.map +1 -0
  344. package/packages/pi-ai/dist/types.d.ts +10 -22
  345. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  346. package/packages/pi-ai/dist/types.js.map +1 -1
  347. package/packages/pi-ai/package.json +1 -1
  348. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  349. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  350. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  351. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +1 -0
  352. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -1
  353. package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -1
  354. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  355. package/packages/pi-coding-agent/dist/core/session-manager.js +3 -0
  356. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  357. package/packages/pi-coding-agent/package.json +7 -7
  358. package/packages/pi-tui/package.json +2 -2
  359. package/packages/rpc-client/dist/rpc-client.js +1 -1
  360. package/packages/rpc-client/dist/rpc-client.js.map +1 -1
  361. package/packages/rpc-client/package.json +2 -2
  362. package/pkg/dist/core/export-html/template.js +53 -4
  363. package/pkg/package.json +1 -1
  364. package/scripts/link-workspace-packages.cjs +14 -4
  365. package/src/resources/GSD-WORKFLOW.md +20 -25
  366. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +130 -51
  367. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +371 -39
  368. package/src/resources/extensions/cursor-cli/index.ts +18 -0
  369. package/src/resources/extensions/cursor-cli/models.ts +65 -0
  370. package/src/resources/extensions/cursor-cli/package.json +11 -0
  371. package/src/resources/extensions/cursor-cli/readiness.ts +143 -0
  372. package/src/resources/extensions/cursor-cli/stream-adapter.ts +440 -0
  373. package/src/resources/extensions/cursor-cli/tests/index.test.ts +54 -0
  374. package/src/resources/extensions/cursor-cli/tests/readiness.test.ts +29 -0
  375. package/src/resources/extensions/cursor-cli/tests/stream-adapter.test.ts +166 -0
  376. package/src/resources/extensions/gsd/activity-log.ts +4 -1
  377. package/src/resources/extensions/gsd/artifact-verification.ts +25 -9
  378. package/src/resources/extensions/gsd/auto/closeout.ts +163 -58
  379. package/src/resources/extensions/gsd/auto/finalize.ts +8 -0
  380. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  381. package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -3
  382. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +6 -3
  383. package/src/resources/extensions/gsd/auto/run-unit.ts +5 -2
  384. package/src/resources/extensions/gsd/auto/schedule-wakeup.ts +8 -0
  385. package/src/resources/extensions/gsd/auto/unit-phase.ts +5 -9
  386. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +4 -5
  387. package/src/resources/extensions/gsd/auto-dispatch.ts +17 -5
  388. package/src/resources/extensions/gsd/auto-model-selection.ts +49 -18
  389. package/src/resources/extensions/gsd/auto-prompts.ts +73 -2
  390. package/src/resources/extensions/gsd/auto-start.ts +8 -5
  391. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +4 -0
  392. package/src/resources/extensions/gsd/auto-worktree-branch-lifecycle.ts +237 -0
  393. package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +166 -0
  394. package/src/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.ts +37 -0
  395. package/src/resources/extensions/gsd/auto-worktree-creation.ts +171 -0
  396. package/src/resources/extensions/gsd/auto-worktree-entry.ts +154 -0
  397. package/src/resources/extensions/gsd/auto-worktree-merge-already-merged.ts +161 -0
  398. package/src/resources/extensions/gsd/auto-worktree-merge-branch-head.ts +83 -0
  399. package/src/resources/extensions/gsd/auto-worktree-merge-cleanup.ts +132 -0
  400. package/src/resources/extensions/gsd/auto-worktree-merge-code-changes.ts +71 -0
  401. package/src/resources/extensions/gsd/auto-worktree-merge-db-ready.ts +112 -0
  402. package/src/resources/extensions/gsd/auto-worktree-merge-integration-branch.ts +99 -0
  403. package/src/resources/extensions/gsd/auto-worktree-merge-message.ts +166 -0
  404. package/src/resources/extensions/gsd/auto-worktree-merge-pre-teardown.ts +93 -0
  405. package/src/resources/extensions/gsd/auto-worktree-merge-stash.ts +213 -0
  406. package/src/resources/extensions/gsd/auto-worktree-merge.ts +391 -0
  407. package/src/resources/extensions/gsd/auto-worktree-milestone-shelter.ts +159 -0
  408. package/src/resources/extensions/gsd/auto-worktree-path-resolution.ts +6 -0
  409. package/src/resources/extensions/gsd/auto-worktree-path-utils.ts +10 -0
  410. package/src/resources/extensions/gsd/auto-worktree-resource-version.ts +44 -0
  411. package/src/resources/extensions/gsd/auto-worktree-runtime-cleanup.ts +119 -0
  412. package/src/resources/extensions/gsd/auto-worktree-session-registry.ts +71 -0
  413. package/src/resources/extensions/gsd/auto-worktree-sync.ts +370 -0
  414. package/src/resources/extensions/gsd/auto-worktree-teardown.ts +161 -0
  415. package/src/resources/extensions/gsd/auto-worktree.ts +69 -2390
  416. package/src/resources/extensions/gsd/auto.ts +32 -19
  417. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -0
  418. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -1
  419. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +147 -6
  420. package/src/resources/extensions/gsd/bootstrap/schedule-wakeup-tool.ts +80 -12
  421. package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
  422. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +163 -22
  423. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +23 -1
  424. package/src/resources/extensions/gsd/codebase-generator.ts +179 -18
  425. package/src/resources/extensions/gsd/commands/handlers/core.ts +39 -3
  426. package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
  427. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +135 -1
  428. package/src/resources/extensions/gsd/commands-workflow-templates.ts +3 -3
  429. package/src/resources/extensions/gsd/commands-worktree.ts +13 -2
  430. package/src/resources/extensions/gsd/db/queries.ts +49 -9
  431. package/src/resources/extensions/gsd/discussion-handoff.ts +10 -2
  432. package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -2
  433. package/src/resources/extensions/gsd/doctor-engine-checks.ts +372 -22
  434. package/src/resources/extensions/gsd/doctor-providers.ts +39 -10
  435. package/src/resources/extensions/gsd/doctor-types.ts +5 -1
  436. package/src/resources/extensions/gsd/doctor.ts +95 -3
  437. package/src/resources/extensions/gsd/exec-sandbox.ts +6 -2
  438. package/src/resources/extensions/gsd/flat-phase-migration.ts +112 -25
  439. package/src/resources/extensions/gsd/forensics.ts +1 -1
  440. package/src/resources/extensions/gsd/git-conflict-resolve.ts +2 -2
  441. package/src/resources/extensions/gsd/git-service.ts +67 -17
  442. package/src/resources/extensions/gsd/gsd-db.ts +85 -0
  443. package/src/resources/extensions/gsd/guidance.ts +2 -0
  444. package/src/resources/extensions/gsd/guided-flow.ts +52 -13
  445. package/src/resources/extensions/gsd/key-manager.ts +1 -0
  446. package/src/resources/extensions/gsd/markdown-renderer.ts +40 -10
  447. package/src/resources/extensions/gsd/migrate-external.ts +23 -6
  448. package/src/resources/extensions/gsd/milestone-merge-transaction.ts +19 -4
  449. package/src/resources/extensions/gsd/milestone-settlement.ts +1 -1
  450. package/src/resources/extensions/gsd/model-router.ts +4 -5
  451. package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
  452. package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -1
  453. package/src/resources/extensions/gsd/preferences-diagnostics.ts +24 -0
  454. package/src/resources/extensions/gsd/preferences-models.ts +6 -3
  455. package/src/resources/extensions/gsd/preferences-types.ts +30 -0
  456. package/src/resources/extensions/gsd/preferences-validation.ts +97 -2
  457. package/src/resources/extensions/gsd/preferences.ts +38 -4
  458. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -2
  459. package/src/resources/extensions/gsd/prompts/system.md +6 -6
  460. package/src/resources/extensions/gsd/quick.ts +11 -3
  461. package/src/resources/extensions/gsd/redact-secrets.ts +40 -0
  462. package/src/resources/extensions/gsd/repo-identity.ts +17 -0
  463. package/src/resources/extensions/gsd/repository-registry.ts +7 -1
  464. package/src/resources/extensions/gsd/root-write-leak-guard.ts +3 -2
  465. package/src/resources/extensions/gsd/safe-fs.ts +22 -2
  466. package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
  467. package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -0
  468. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -1
  469. package/src/resources/extensions/gsd/state/derive/from-db.ts +201 -157
  470. package/src/resources/extensions/gsd/tests/auto-loop-no-copy-artifacts.test.ts +2 -1
  471. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +131 -5
  472. package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +18 -0
  473. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +178 -0
  474. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +43 -1
  475. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +54 -0
  476. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +41 -0
  477. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +41 -0
  478. package/src/resources/extensions/gsd/tests/auto-session-scope.test.ts +4 -4
  479. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +3 -0
  480. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +1 -1
  481. package/src/resources/extensions/gsd/tests/auto-timeout-recovery-harness-abort.test.ts +55 -0
  482. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +10 -1
  483. package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +1 -1
  484. package/src/resources/extensions/gsd/tests/auto-worktree-merge-already-merged.test.ts +177 -0
  485. package/src/resources/extensions/gsd/tests/auto-worktree-merge-branch-head.test.ts +118 -0
  486. package/src/resources/extensions/gsd/tests/auto-worktree-merge-cleanup.test.ts +115 -0
  487. package/src/resources/extensions/gsd/tests/auto-worktree-merge-code-changes.test.ts +76 -0
  488. package/src/resources/extensions/gsd/tests/auto-worktree-merge-db-ready.test.ts +140 -0
  489. package/src/resources/extensions/gsd/tests/auto-worktree-merge-integration-branch.test.ts +123 -0
  490. package/src/resources/extensions/gsd/tests/auto-worktree-merge-message.test.ts +114 -0
  491. package/src/resources/extensions/gsd/tests/auto-worktree-merge-pre-teardown.test.ts +84 -0
  492. package/src/resources/extensions/gsd/tests/auto-worktree-merge-stash.test.ts +70 -0
  493. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-shelter.test.ts +52 -0
  494. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +6 -6
  495. package/src/resources/extensions/gsd/tests/auto-worktree-resource-version.test.ts +59 -0
  496. package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +3 -1
  497. package/src/resources/extensions/gsd/tests/batch-task-query.test.ts +85 -0
  498. package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +29 -0
  499. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +365 -0
  500. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +62 -1
  501. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +1 -1
  502. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -0
  503. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +138 -1
  504. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +571 -5
  505. package/src/resources/extensions/gsd/tests/doctor-workspace.test.ts +207 -0
  506. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +1 -1
  507. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +82 -2
  508. package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +25 -1
  509. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +87 -19
  510. package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +89 -0
  511. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +40 -0
  512. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +9 -0
  513. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +4 -6
  514. package/src/resources/extensions/gsd/tests/integration/auto-stash-merge.test.ts +2 -1
  515. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +3 -3
  516. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +7 -8
  517. package/src/resources/extensions/gsd/tests/integration/feature-branch-lifecycle-integration.test.ts +2 -5
  518. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +76 -0
  519. package/src/resources/extensions/gsd/tests/integration/merge-cwd-restore.test.ts +1 -1
  520. package/src/resources/extensions/gsd/tests/integration/merge-preserve-worktree-on-preteardown-error.test.ts +1 -1
  521. package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +2 -1
  522. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +5 -7
  523. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
  524. package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +2 -4
  525. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +122 -0
  526. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +1 -1
  527. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +4 -4
  528. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +1 -1
  529. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +1 -1
  530. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +116 -0
  531. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +592 -23
  532. package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +25 -1
  533. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +1 -1
  534. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -3
  535. package/src/resources/extensions/gsd/tests/parallel-worker-lock-contention.test.ts +1 -1
  536. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +2 -2
  537. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +50 -6
  538. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +17 -0
  539. package/src/resources/extensions/gsd/tests/plan-task.test.ts +264 -1
  540. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +1 -4
  541. package/src/resources/extensions/gsd/tests/preferences.test.ts +150 -0
  542. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +147 -0
  543. package/src/resources/extensions/gsd/tests/recovery-verify-logs.test.ts +4 -4
  544. package/src/resources/extensions/gsd/tests/redact-secrets.test.ts +56 -0
  545. package/src/resources/extensions/gsd/tests/register-hooks-flat-phase-migration.test.ts +73 -0
  546. package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +275 -0
  547. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +41 -2
  548. package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +55 -0
  549. package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +31 -9
  550. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -0
  551. package/src/resources/extensions/gsd/tests/schedule-wakeup-tool.test.ts +167 -0
  552. package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +3 -5
  553. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -0
  554. package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +2 -1
  555. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +2 -1
  556. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -1
  557. package/src/resources/extensions/gsd/tests/status-per-repo.test.ts +94 -0
  558. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +1 -1
  559. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +1 -1
  560. package/src/resources/extensions/gsd/tests/system-flat-phase-layout.test.ts +33 -0
  561. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +4 -4
  562. package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +2 -1
  563. package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +4 -4
  564. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +35 -0
  565. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +166 -0
  566. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +1 -1
  567. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +66 -18
  568. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +81 -0
  569. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +30 -0
  570. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +52 -0
  571. package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +53 -1
  572. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +208 -1
  573. package/src/resources/extensions/gsd/tests/workspace.test.ts +18 -4
  574. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -1
  575. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +1 -1
  576. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +1 -3
  577. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +1 -1
  578. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +1 -1
  579. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +4 -4
  580. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +2 -2
  581. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +1 -1
  582. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +1 -1
  583. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +2 -1
  584. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +36 -3
  585. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +1 -1
  586. package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +1 -1
  587. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +32 -0
  588. package/src/resources/extensions/gsd/tool-contract.ts +29 -0
  589. package/src/resources/extensions/gsd/tools/plan-task.ts +107 -9
  590. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +58 -0
  591. package/src/resources/extensions/gsd/unit-context-manifest.ts +11 -5
  592. package/src/resources/extensions/gsd/unit-registry.ts +48 -2
  593. package/src/resources/extensions/gsd/unit-runtime.ts +42 -0
  594. package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +1 -1
  595. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -1
  596. package/src/resources/extensions/gsd/workspace-git-preflight.ts +2 -2
  597. package/src/resources/extensions/gsd/workspace.ts +42 -8
  598. package/src/resources/extensions/gsd/worktree-command.ts +1 -1
  599. package/src/resources/extensions/gsd/worktree-lifecycle.ts +154 -26
  600. package/src/resources/extensions/gsd/worktree-manager.ts +143 -5
  601. package/src/resources/extensions/gsd/worktree-reentry.ts +2 -1
  602. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
  603. package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
  604. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
  605. /package/dist/web/standalone/.next/static/{zQLcXm0Za8lexoXtgDpMG → ZpFDazP-38PXBPiI_LdZf}/_buildManifest.js +0 -0
  606. /package/dist/web/standalone/.next/static/{zQLcXm0Za8lexoXtgDpMG → ZpFDazP-38PXBPiI_LdZf}/_ssgManifest.js +0 -0
@@ -0,0 +1,37 @@
1
+ // redact-secrets.ts
2
+ // Best-effort redaction of secret-shaped substrings before persisting free text
3
+ // (exec-sandbox output, activity-log session entries) to disk under .gsd/, which
4
+ // the secret scanner skips. Patterns mirror scripts/secret-scan.mjs.
5
+ const PLACEHOLDER = "«redacted»";
6
+ // Each secret shape. Global flag so replace() catches every occurrence in a line.
7
+ // Order is not significant — matches are replaced independently.
8
+ const PATTERNS = [
9
+ /AKIA[0-9A-Z]{16}/g, // AWS access key id
10
+ /(api[_-]?key|apikey|api[_-]?secret)[ \t]*[:=][ \t]*['"][0-9a-zA-Z_./-]{20,}['"]/gi,
11
+ /(secret|token|password|passwd|pwd|credential)[ \t]*[:=][ \t]*['"][^\s'"]{8,}['"]/gi,
12
+ /(authorization|bearer)[ \t]*[:=][ \t]*['"][^\s'"]{8,}['"]/gi,
13
+ /Bearer[ \t]+[0-9a-zA-Z._-]{8,}/g, // Authorization: Bearer <token> (unquoted)
14
+ /-----BEGIN\s+(RSA|DSA|EC|OPENSSH|PGP)\s+PRIVATE\s+KEY-----[\s\S]*?-----END\s+(RSA|DSA|EC|OPENSSH|PGP)\s+PRIVATE\s+KEY-----/g,
15
+ /(mysql|postgres|postgresql|mongodb|redis|amqp|mssql):\/\/[^\s'"]{8,}/gi,
16
+ /gh[pousr]_[0-9a-zA-Z]{36,}/g, // GitHub token
17
+ /glpat-[0-9a-zA-Z-]{20,}/g, // GitLab token
18
+ /xox[baprs]-[0-9a-zA-Z-]{10,}/g, // Slack token
19
+ /hooks\.slack\.com\/services\/T[0-9A-Z]{8,}\/B[0-9A-Z]{8,}\/[0-9a-zA-Z]{20,}/g,
20
+ /AIza[0-9A-Za-z_-]{35}/g, // Google API key
21
+ /[sr]k_(live|test)_[0-9a-zA-Z]{20,}/g, // Stripe key
22
+ /sk-(ant-)?[0-9a-zA-Z_-]{20,}/g, // OpenAI / Anthropic style key
23
+ /npm_[0-9a-zA-Z]{36,}/g, // npm token
24
+ /(secret|key|token|password)[ \t]*[:=][ \t]*['"]?[0-9a-f]{32,}['"]?/gi, // hex secret
25
+ ];
26
+ /**
27
+ * Replace secret-shaped substrings in `text` with a placeholder, preserving the
28
+ * surrounding content. Pure and safe to call per log line. The placeholder
29
+ * contains no quote/brace/backslash, so redacting a JSON string keeps it valid.
30
+ */
31
+ export function redactSecrets(text) {
32
+ let out = text;
33
+ for (const pattern of PATTERNS) {
34
+ out = out.replace(pattern, PLACEHOLDER);
35
+ }
36
+ return out;
37
+ }
@@ -328,6 +328,22 @@ export function externalProjectsRoot() {
328
328
  const base = process.env.GSD_STATE_DIR || gsdHome();
329
329
  return join(base, "projects");
330
330
  }
331
+ /**
332
+ * Check whether this project already has authoritative external state.
333
+ *
334
+ * Used by legacy `.gsd/` migration to avoid re-copying a re-materialized local
335
+ * directory over newer state when an already-migrated symlink was replaced.
336
+ */
337
+ export function externalStateAlreadyExistsForProject(basePath) {
338
+ const base = process.env.GSD_STATE_DIR || gsdHome();
339
+ const computedPath = join(base, "projects", repoIdentity(basePath));
340
+ if (hasProjectState(computedPath))
341
+ return true;
342
+ const markerId = readGsdIdMarker(resolveGitRoot(basePath));
343
+ if (!markerId)
344
+ return false;
345
+ return hasProjectState(join(base, "projects", markerId));
346
+ }
331
347
  // ─── Numbered Variant Cleanup ────────────────────────────────────────────────
332
348
  /**
333
349
  * macOS collision pattern: `.gsd 2`, `.gsd 3`, `.gsd 4`, etc.
@@ -5,6 +5,11 @@ import { isAbsolute, relative, resolve } from "node:path";
5
5
  import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
6
6
  import { resolveGsdPathContract } from "./paths.js";
7
7
  export function defaultRepositoryTargets(registry) {
8
+ // In parent mode, default to the declared child repositories so work is
9
+ // attributed to the repo it touches — not silently to the root "project".
10
+ if (registry.mode === "parent") {
11
+ return registry.repositories.filter((repo) => repo.id !== "project").map((repo) => repo.id);
12
+ }
8
13
  const project = registry.byId.get("project");
9
14
  if (project)
10
15
  return [project.id];
@@ -51,7 +56,7 @@ function resolveGitWorkingTreeRoot(basePath) {
51
56
  export function createRepositoryRegistry(basePath, workspacePrefs) {
52
57
  const contract = resolveGsdPathContract(basePath);
53
58
  const projectRoot = contract.isWorktree
54
- ? resolveGitWorkingTreeRoot(contract.workRoot) ?? contract.projectRoot
59
+ ? resolveGitWorkingTreeRoot(contract.workRoot) ?? contract.workRoot
55
60
  : contract.projectRoot;
56
61
  const mode = workspacePrefs?.mode ?? "project";
57
62
  const repoMap = new Map();
@@ -42,12 +42,14 @@ export function captureRootDirtySnapshot(rootPath) {
42
42
  if (!line.trim())
43
43
  continue;
44
44
  const code = line.slice(0, 2);
45
+ if (code !== "??")
46
+ continue;
45
47
  const path = line.slice(3).replace(/^"|"$/g, "");
46
48
  if (!path || isRootRuntimePath(path))
47
49
  continue;
48
50
  snapshot.set(path, {
49
51
  path,
50
- status: code.trim() || code,
52
+ status: code,
51
53
  fingerprint: fileFingerprint(rootPath, path),
52
54
  });
53
55
  }
@@ -58,7 +60,7 @@ export function detectRootWriteLeak(input) {
58
60
  const leaked = [];
59
61
  for (const entry of after.values()) {
60
62
  const prior = input.before?.get(entry.path);
61
- if (!prior || prior.status !== entry.status || prior.fingerprint !== entry.fingerprint) {
63
+ if (!prior || prior.fingerprint !== entry.fingerprint) {
62
64
  leaked.push(entry);
63
65
  }
64
66
  }
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdirSync, cpSync } from "node:fs";
1
+ import { existsSync, mkdirSync, cpSync, statSync } from "node:fs";
2
2
  import { dirname } from "node:path";
3
3
  import { logWarning } from "./workflow-logger.js";
4
4
  /**
@@ -40,7 +40,28 @@ export function safeCopyRecursive(src, dst, opts) {
40
40
  return false;
41
41
  try {
42
42
  mkdirSync(dirname(dst), { recursive: true });
43
- cpSync(src, dst, { ...opts, recursive: true });
43
+ const userFilter = opts?.filter;
44
+ cpSync(src, dst, {
45
+ ...opts,
46
+ recursive: true,
47
+ filter: (srcPath, dstPath) => {
48
+ if (existsSync(dstPath)) {
49
+ try {
50
+ const srcStat = statSync(srcPath);
51
+ const dstStat = statSync(dstPath);
52
+ if (srcStat.isDirectory() !== dstStat.isDirectory()) {
53
+ logWarning("fs", `recursive copy skipped type collision: ${srcPath} → ${dstPath}`);
54
+ return false;
55
+ }
56
+ }
57
+ catch (err) {
58
+ logWarning("fs", `recursive copy skipped unreadable path: ${srcPath} → ${dstPath}: ${err.message}`);
59
+ return false;
60
+ }
61
+ }
62
+ return userFilter ? userFilter(srcPath, dstPath) : true;
63
+ },
64
+ });
44
65
  return true;
45
66
  }
46
67
  catch (err) {
@@ -211,17 +211,15 @@ All state lives in `.gsd/` as markdown files (version-controllable):
211
211
 
212
212
  ```
213
213
  .gsd/
214
- milestones/M001/
215
- M001-CONTEXT.md # Requirements, scope, decisions
216
- M001-ROADMAP.md # Slices with tasks, dependencies, checkboxes
217
- M001-SUMMARY.md # Completion summary
218
- slices/S01/
219
- S01-PLAN.md # Task list
220
- S01-SUMMARY.md # Slice summary with frontmatter
221
- tasks/T01-PLAN.md # Individual task spec
214
+ phases/01-foundation/
215
+ 01-CONTEXT.md # Requirements, scope, decisions
216
+ 01-ROADMAP.md # Slices with tasks, dependencies, checkboxes
217
+ 01-SUMMARY.md # Completion summary
218
+ 01-01-PLAN.md # First slice task list
219
+ 01-01-SUMMARY.md # First slice summary with frontmatter
222
220
  ```
223
221
 
224
- State is derived from files on disk — checkboxes in ROADMAP.md are the source of truth for completion.
222
+ Runtime state is stored in the project-root database; markdown files are reviewable projections written under `.gsd/phases/`. Legacy projects may still resolve to `.gsd/milestones/<MID>/` until migrated.
225
223
 
226
224
  ## All Headless Commands
227
225
 
@@ -22,6 +22,7 @@ All commands can be run via `gsd headless [command]`.
22
22
  | `status` | Progress dashboard (TUI overlay — useful interactively, not for parsing) |
23
23
  | `visualize` | Workflow visualizer (deps, metrics, timeline) |
24
24
  | `history` | Execution history (supports --cost, --phase, --model, limit) |
25
+ | `codebase` | Manage `.gsd/CODEBASE.md`; parent workspaces include declared child repositories under repo-labeled sections |
25
26
 
26
27
  ## Unit Control
27
28
 
@@ -19,7 +19,8 @@ import { isAbsolute, join, dirname, resolve } from "node:path";
19
19
  import { fileURLToPath } from "node:url";
20
20
  import { gsdRoot } from "./paths.js";
21
21
  import { createWorktree, worktreePath, removeWorktree } from "./worktree-manager.js";
22
- import { runWorktreePostCreateHook, syncGsdStateToWorktreeByScope } from "./auto-worktree.js";
22
+ import { syncGsdStateToWorktreeByScope } from "./auto-worktree-sync.js";
23
+ import { runWorktreePostCreateHook } from "./worktree-post-create-hook.js";
23
24
  import { createWorkspace, scopeMilestone } from "./workspace.js";
24
25
  import { writeSessionStatus, } from "./session-status-io.js";
25
26
  import { hasFileConflict } from "./slice-parallel-conflict.js";
@@ -12,6 +12,31 @@ import { countUnmappedActiveRequirements, formatCompletePhaseNextAction } from '
12
12
  import { logWarning } from '../../workflow-logger.js';
13
13
  import { buildDbUnavailableState, ensureExistingWorkflowDbOpen, getRequestedMilestoneLock, } from './db-open.js';
14
14
  const isStatusDone = isClosedStatus;
15
+ function buildProgress(context) {
16
+ return {
17
+ milestones: context.milestoneProgress,
18
+ ...(context.sliceProgress ? { slices: context.sliceProgress } : {}),
19
+ ...(context.taskProgress ? { tasks: context.taskProgress } : {}),
20
+ };
21
+ }
22
+ function buildDerivedState(context, phase, nextAction, options = {}) {
23
+ return {
24
+ activeMilestone: context.activeMilestone,
25
+ activeSlice: context.activeSlice ?? null,
26
+ activeTask: context.activeTask ?? null,
27
+ phase,
28
+ recentDecisions: [],
29
+ blockers: options.blockers ?? [],
30
+ nextAction,
31
+ ...(options.lastCompletedMilestone !== undefined
32
+ ? { lastCompletedMilestone: options.lastCompletedMilestone }
33
+ : {}),
34
+ ...(options.includeActiveWorkspace ? { activeWorkspace: undefined } : {}),
35
+ registry: context.registry,
36
+ requirements: context.requirements,
37
+ progress: buildProgress(context),
38
+ };
39
+ }
15
40
  function stripMilestonePrefix(title) {
16
41
  return title.replace(/^M\d+(?:-[a-z0-9]{6})?[^:]*:\s*/, '') || title;
17
42
  }
@@ -125,103 +150,60 @@ async function buildRegistryAndFindActive(basePath, milestones, completeMileston
125
150
  function handleNoActiveMilestone(registry, requirements, milestoneProgress) {
126
151
  const pendingEntries = registry.filter(e => e.status === 'pending');
127
152
  const parkedEntries = registry.filter(e => e.status === 'parked');
153
+ const context = {
154
+ activeMilestone: null,
155
+ registry,
156
+ requirements,
157
+ milestoneProgress,
158
+ };
128
159
  if (pendingEntries.length > 0) {
129
160
  const blockerDetails = pendingEntries
130
161
  .filter(e => e.dependsOn && e.dependsOn.length > 0)
131
162
  .map(e => `${e.id} is waiting on unmet deps: ${e.dependsOn.join(', ')}`);
132
- return {
133
- activeMilestone: null, activeSlice: null, activeTask: null,
134
- phase: 'blocked',
135
- recentDecisions: [], blockers: blockerDetails.length > 0
163
+ return buildDerivedState(context, 'blocked', 'Resolve milestone dependencies before proceeding.', {
164
+ blockers: blockerDetails.length > 0
136
165
  ? blockerDetails
137
166
  : ['All remaining milestones are dep-blocked but no deps listed — check CONTEXT.md files'],
138
- nextAction: 'Resolve milestone dependencies before proceeding.',
139
- registry, requirements,
140
- progress: { milestones: milestoneProgress },
141
- };
167
+ });
142
168
  }
143
169
  if (parkedEntries.length > 0) {
144
170
  const parkedIds = parkedEntries.map(e => e.id).join(', ');
145
- return {
146
- activeMilestone: null, activeSlice: null, activeTask: null,
147
- phase: 'pre-planning',
148
- recentDecisions: [], blockers: [],
149
- nextAction: `All remaining milestones are parked (${parkedIds}). Run /gsd unpark <id> or create a new milestone.`,
150
- registry, requirements,
151
- progress: { milestones: milestoneProgress },
152
- };
171
+ return buildDerivedState(context, 'pre-planning', `All remaining milestones are parked (${parkedIds}). Run /gsd unpark <id> or create a new milestone.`);
153
172
  }
154
173
  if (registry.length === 0) {
155
- return {
156
- activeMilestone: null, activeSlice: null, activeTask: null,
157
- phase: 'pre-planning',
158
- recentDecisions: [], blockers: [],
159
- nextAction: 'No milestones found. Run /gsd to create one.',
160
- registry: [], requirements,
161
- progress: { milestones: { done: 0, total: 0 } },
162
- };
174
+ return buildDerivedState({ ...context, registry: [], milestoneProgress: { done: 0, total: 0 } }, 'pre-planning', 'No milestones found. Run /gsd to create one.');
163
175
  }
164
176
  const lastEntry = registry[registry.length - 1];
165
177
  const unmappedActive = countUnmappedActiveRequirements();
166
178
  const completionNote = formatCompletePhaseNextAction(unmappedActive);
167
- return {
168
- activeMilestone: null,
179
+ return buildDerivedState(context, 'complete', completionNote, {
169
180
  lastCompletedMilestone: lastEntry ? { id: lastEntry.id, title: lastEntry.title } : null,
170
- activeSlice: null, activeTask: null,
171
- phase: 'complete',
172
- recentDecisions: [], blockers: [],
173
- nextAction: completionNote,
174
- registry, requirements,
175
- progress: { milestones: milestoneProgress },
176
- };
181
+ });
177
182
  }
178
183
  async function handleAllSlicesDone(basePath, activeMilestone, registry, requirements, milestoneProgress, sliceProgress) {
179
184
  const validation = getLatestAssessmentByScope(activeMilestone.id, "milestone-validation");
180
185
  const verdict = typeof validation?.status === "string" ? validation.status : undefined;
181
186
  const validationTerminal = verdict != null && verdict !== "";
187
+ const context = {
188
+ activeMilestone,
189
+ registry,
190
+ requirements,
191
+ milestoneProgress,
192
+ sliceProgress,
193
+ };
182
194
  if (!validationTerminal) {
183
- return {
184
- activeMilestone, activeSlice: null, activeTask: null,
185
- phase: 'validating-milestone',
186
- recentDecisions: [], blockers: [],
187
- nextAction: `Validate milestone ${activeMilestone.id} before completion.`,
188
- registry, requirements,
189
- progress: { milestones: milestoneProgress, slices: sliceProgress },
190
- };
195
+ return buildDerivedState(context, 'validating-milestone', `Validate milestone ${activeMilestone.id} before completion.`);
191
196
  }
192
197
  // All roadmap slices are done (enforced by caller) and verdict is
193
198
  // needs-remediation — remediation cannot progress without new slices.
194
199
  // Return blocked instead of re-dispatching validate-milestone (#4506).
195
200
  if (verdict === 'needs-attention') {
196
- return {
197
- activeMilestone, activeSlice: null, activeTask: null,
198
- phase: 'blocked',
199
- recentDecisions: [],
200
- blockers: [formatNeedsAttentionBlocker(activeMilestone.id)],
201
- nextAction: `Resolve ${activeMilestone.id} validation attention before proceeding.`,
202
- registry, requirements,
203
- progress: { milestones: milestoneProgress, slices: sliceProgress },
204
- };
201
+ return buildDerivedState(context, 'blocked', `Resolve ${activeMilestone.id} validation attention before proceeding.`, { blockers: [formatNeedsAttentionBlocker(activeMilestone.id)] });
205
202
  }
206
203
  if (verdict === 'needs-remediation') {
207
- return {
208
- activeMilestone, activeSlice: null, activeTask: null,
209
- phase: 'blocked',
210
- recentDecisions: [],
211
- blockers: [formatNeedsRemediationBlocker(activeMilestone.id)],
212
- nextAction: `Resolve ${activeMilestone.id} remediation before proceeding.`,
213
- registry, requirements,
214
- progress: { milestones: milestoneProgress, slices: sliceProgress },
215
- };
204
+ return buildDerivedState(context, 'blocked', `Resolve ${activeMilestone.id} remediation before proceeding.`, { blockers: [formatNeedsRemediationBlocker(activeMilestone.id)] });
216
205
  }
217
- return {
218
- activeMilestone, activeSlice: null, activeTask: null,
219
- phase: 'completing-milestone',
220
- recentDecisions: [], blockers: [],
221
- nextAction: `All slices complete in ${activeMilestone.id}. Write milestone summary.`,
222
- registry, requirements,
223
- progress: { milestones: milestoneProgress, slices: sliceProgress },
224
- };
206
+ return buildDerivedState(context, 'completing-milestone', `All slices complete in ${activeMilestone.id}. Write milestone summary.`);
225
207
  }
226
208
  function resolveSliceDependencies(activeMilestoneSlices) {
227
209
  const doneSliceIds = new Set(activeMilestoneSlices.filter(s => isStatusDone(s.status)).map(s => s.id));
@@ -271,13 +253,12 @@ export async function deriveStateFromDb(basePath, artifactReadRoot = basePath) {
271
253
  ? allMilestones.filter(m => m.id === milestoneLock)
272
254
  : allMilestones;
273
255
  if (milestones.length === 0) {
274
- return {
275
- activeMilestone: null, activeSlice: null, activeTask: null,
276
- phase: 'pre-planning', recentDecisions: [], blockers: [],
277
- nextAction: 'No milestones found. Run /gsd to create one.',
278
- registry: [], requirements,
279
- progress: { milestones: { done: 0, total: 0 } },
280
- };
256
+ return buildDerivedState({
257
+ activeMilestone: null,
258
+ registry: [],
259
+ requirements,
260
+ milestoneProgress: { done: 0, total: 0 },
261
+ }, 'pre-planning', 'No milestones found. Run /gsd to create one.');
281
262
  }
282
263
  const { completeMilestoneIds, parkedMilestoneIds } = buildCompletenessSet(basePath, milestones);
283
264
  const registryContext = await buildRegistryAndFindActive(basePath, milestones, completeMilestoneIds, parkedMilestoneIds);
@@ -294,18 +275,20 @@ export async function deriveStateFromDb(basePath, artifactReadRoot = basePath) {
294
275
  const nextAction = activeMilestoneHasDraft
295
276
  ? `Discuss draft context for milestone ${activeMilestone.id}.`
296
277
  : `Plan milestone ${activeMilestone.id}.`;
297
- return {
298
- activeMilestone, activeSlice: null, activeTask: null,
299
- phase, recentDecisions: [], blockers: [],
300
- nextAction, registry, requirements,
301
- progress: { milestones: milestoneProgress },
302
- };
278
+ return buildDerivedState({ activeMilestone, registry, requirements, milestoneProgress }, phase, nextAction);
303
279
  }
304
280
  const allSlicesDone = activeMilestoneSlices.every(s => isStatusDone(s.status));
305
281
  const sliceProgress = {
306
282
  done: activeMilestoneSlices.filter(s => isStatusDone(s.status)).length,
307
283
  total: activeMilestoneSlices.length,
308
284
  };
285
+ const sliceStateContext = {
286
+ activeMilestone,
287
+ registry,
288
+ requirements,
289
+ milestoneProgress,
290
+ sliceProgress,
291
+ };
309
292
  if (allSlicesDone) {
310
293
  return handleAllSlicesDone(basePath, activeMilestone, registry, requirements, milestoneProgress, sliceProgress);
311
294
  }
@@ -314,21 +297,9 @@ export async function deriveStateFromDb(basePath, artifactReadRoot = basePath) {
314
297
  // If locked slice wasn't found, it returns null but logs warning, we need to return 'blocked'
315
298
  const sliceLock = process.env.GSD_PARALLEL_WORKER ? process.env.GSD_SLICE_LOCK : undefined;
316
299
  if (sliceLock) {
317
- return {
318
- activeMilestone, activeSlice: null, activeTask: null,
319
- phase: 'blocked', recentDecisions: [], blockers: [`GSD_SLICE_LOCK=${sliceLock} not found in active milestone slices`],
320
- nextAction: 'Slice lock references a non-existent slice — check orchestrator dispatch.',
321
- registry, requirements,
322
- progress: { milestones: milestoneProgress, slices: sliceProgress },
323
- };
300
+ return buildDerivedState(sliceStateContext, 'blocked', 'Slice lock references a non-existent slice — check orchestrator dispatch.', { blockers: [`GSD_SLICE_LOCK=${sliceLock} not found in active milestone slices`] });
324
301
  }
325
- return {
326
- activeMilestone, activeSlice: null, activeTask: null,
327
- phase: 'blocked', recentDecisions: [], blockers: ['No slice eligible — check dependency ordering'],
328
- nextAction: 'Resolve dependency blockers or plan next slice.',
329
- registry, requirements,
330
- progress: { milestones: milestoneProgress, slices: sliceProgress },
331
- };
302
+ return buildDerivedState(sliceStateContext, 'blocked', 'Resolve dependency blockers or plan next slice.', { blockers: ['No slice eligible — check dependency ordering'] });
332
303
  }
333
304
  const { activeSlice } = activeSliceContext;
334
305
  const activeSliceRow = activeSliceContext.activeSliceRow;
@@ -338,39 +309,30 @@ export async function deriveStateFromDb(basePath, artifactReadRoot = basePath) {
338
309
  // PLAN.md and preference flags are projections/configuration and are
339
310
  // deliberately not used to infer whether the slice itself is a sketch.
340
311
  if (activeSliceRow?.is_sketch === 1) {
341
- return {
342
- activeMilestone, activeSlice, activeTask: null,
343
- phase: 'refining', recentDecisions: [], blockers: [],
344
- nextAction: `Refine sketch slice ${activeSlice.id} (${activeSlice.title}) using prior slice context.`,
345
- registry, requirements,
346
- progress: { milestones: milestoneProgress, slices: sliceProgress },
347
- };
312
+ return buildDerivedState({ ...sliceStateContext, activeSlice }, 'refining', `Refine sketch slice ${activeSlice.id} (${activeSlice.title}) using prior slice context.`);
348
313
  }
349
314
  const tasks = getSliceTasks(activeMilestone.id, activeSlice.id);
350
315
  const taskProgress = {
351
316
  done: tasks.filter(t => isStatusDone(t.status)).length,
352
317
  total: tasks.length,
353
318
  };
319
+ const taskStateContext = {
320
+ ...sliceStateContext,
321
+ activeSlice,
322
+ taskProgress,
323
+ };
354
324
  const activeTaskRow = tasks.find(t => !isStatusDone(t.status));
355
325
  if (!activeTaskRow && tasks.length > 0) {
356
- return {
357
- activeMilestone, activeSlice, activeTask: null,
358
- phase: 'summarizing', recentDecisions: [], blockers: [],
359
- nextAction: `All tasks done in ${activeSlice.id}. Write slice summary and complete slice.`,
360
- registry, requirements,
361
- progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
362
- };
326
+ return buildDerivedState(taskStateContext, 'summarizing', `All tasks done in ${activeSlice.id}. Write slice summary and complete slice.`);
363
327
  }
364
328
  if (!activeTaskRow) {
365
- return {
366
- activeMilestone, activeSlice, activeTask: null,
367
- phase: 'planning', recentDecisions: [], blockers: [],
368
- nextAction: `Slice ${activeSlice.id} has no DB tasks. Plan slice tasks before execution.`,
369
- registry, requirements,
370
- progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
371
- };
329
+ return buildDerivedState(taskStateContext, 'planning', `Slice ${activeSlice.id} has no DB tasks. Plan slice tasks before execution.`);
372
330
  }
373
331
  const activeTask = { id: activeTaskRow.id, title: activeTaskRow.title };
332
+ const activeTaskStateContext = {
333
+ ...taskStateContext,
334
+ activeTask,
335
+ };
374
336
  // ── Quality gate evaluation check ──────────────────────────────────
375
337
  // Pause before execution only when gates owned by the `gate-evaluate`
376
338
  // turn (Q3/Q4) are still pending. Q8 is also `scope:"slice"` but is
@@ -380,27 +342,16 @@ export async function deriveStateFromDb(basePath, artifactReadRoot = basePath) {
380
342
  // Slices with zero gate rows (pre-feature or simple) skip straight through.
381
343
  const pendingGateCount = getPendingGateCountForTurn(activeMilestone.id, activeSlice.id, "gate-evaluate");
382
344
  if (pendingGateCount > 0) {
383
- return {
384
- activeMilestone, activeSlice, activeTask: null,
385
- phase: 'evaluating-gates', recentDecisions: [], blockers: [],
386
- nextAction: `Evaluate ${pendingGateCount} quality gate(s) for ${activeSlice.id} before execution.`,
387
- registry, requirements,
388
- progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
389
- };
345
+ return buildDerivedState(taskStateContext, 'evaluating-gates', `Evaluate ${pendingGateCount} quality gate(s) for ${activeSlice.id} before execution.`);
390
346
  }
391
347
  const blockerTaskId = await detectBlockers(basePath, activeMilestone.id, activeSlice.id, tasks);
392
348
  if (blockerTaskId) {
393
349
  const replanHistory = getReplanHistory(activeMilestone.id, activeSlice.id);
394
350
  if (replanHistory.length === 0) {
395
- return {
396
- activeMilestone, activeSlice, activeTask,
397
- phase: 'replanning-slice', recentDecisions: [],
351
+ return buildDerivedState(activeTaskStateContext, 'replanning-slice', `Task ${blockerTaskId} reported blocker_discovered. Replan slice ${activeSlice.id} before continuing.`, {
398
352
  blockers: [`Task ${blockerTaskId} discovered a blocker requiring slice replan`],
399
- nextAction: `Task ${blockerTaskId} reported blocker_discovered. Replan slice ${activeSlice.id} before continuing.`,
400
- activeWorkspace: undefined,
401
- registry, requirements,
402
- progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
403
- };
353
+ includeActiveWorkspace: true,
354
+ });
404
355
  }
405
356
  }
406
357
  // ADR-011 Phase 2: pause-on-escalation takes precedence over dispatching the
@@ -415,38 +366,22 @@ export async function deriveStateFromDb(basePath, artifactReadRoot = basePath) {
415
366
  // and the user's prior resolution never lands.
416
367
  const escalatingTaskId = detectPendingEscalation(tasks, basePath);
417
368
  if (escalatingTaskId) {
418
- return {
419
- activeMilestone, activeSlice, activeTask,
420
- phase: 'escalating-task', recentDecisions: [],
369
+ return buildDerivedState(activeTaskStateContext, 'escalating-task', `Run /gsd escalate show ${escalatingTaskId} to review, then /gsd escalate resolve ${escalatingTaskId} <choice> to proceed.`, {
421
370
  blockers: [`Task ${escalatingTaskId} requires a user decision before the loop can proceed`],
422
- nextAction: `Run /gsd escalate show ${escalatingTaskId} to review, then /gsd escalate resolve ${escalatingTaskId} <choice> to proceed.`,
423
- activeWorkspace: undefined,
424
- registry, requirements,
425
- progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
426
- };
371
+ includeActiveWorkspace: true,
372
+ });
427
373
  }
428
374
  if (!blockerTaskId) {
429
375
  const isTriggered = checkReplanTrigger(basePath, activeMilestone.id, activeSlice.id);
430
376
  if (isTriggered) {
431
377
  const replanHistory = getReplanHistory(activeMilestone.id, activeSlice.id);
432
378
  if (replanHistory.length === 0) {
433
- return {
434
- activeMilestone, activeSlice, activeTask,
435
- phase: 'replanning-slice', recentDecisions: [],
379
+ return buildDerivedState(activeTaskStateContext, 'replanning-slice', `Triage replan triggered for slice ${activeSlice.id}. Replan before continuing.`, {
436
380
  blockers: ['Triage replan trigger detected — slice replan required'],
437
- nextAction: `Triage replan triggered for slice ${activeSlice.id}. Replan before continuing.`,
438
- activeWorkspace: undefined,
439
- registry, requirements,
440
- progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
441
- };
381
+ includeActiveWorkspace: true,
382
+ });
442
383
  }
443
384
  }
444
385
  }
445
- return {
446
- activeMilestone, activeSlice, activeTask,
447
- phase: 'executing', recentDecisions: [], blockers: [],
448
- nextAction: `Execute ${activeTask.id}: ${activeTask.title} in slice ${activeSlice.id}.`,
449
- registry, requirements,
450
- progress: { milestones: milestoneProgress, slices: sliceProgress, tasks: taskProgress },
451
- };
386
+ return buildDerivedState(activeTaskStateContext, 'executing', `Execute ${activeTask.id}: ${activeTask.title} in slice ${activeSlice.id}.`);
452
387
  }
@@ -26,6 +26,20 @@ export function getUnitWorkflowDispatchReadinessError(input) {
26
26
  activeTools: input.activeTools,
27
27
  });
28
28
  }
29
+ export function getUnitWorkflowDispatchReadinessErrorForModel(input) {
30
+ const provider = input.model?.provider ?? input.fallbackModel?.provider;
31
+ const baseUrl = input.model?.baseUrl ?? input.fallbackModel?.baseUrl;
32
+ return getUnitWorkflowDispatchReadinessError({
33
+ provider,
34
+ unitType: input.unitType,
35
+ projectRoot: input.projectRoot,
36
+ env: input.env,
37
+ surface: input.surface,
38
+ authMode: provider ? input.getProviderAuthMode?.(provider) : undefined,
39
+ baseUrl,
40
+ activeTools: input.activeTools,
41
+ });
42
+ }
29
43
  export function compileUnitToolContract(unitType) {
30
44
  const manifest = resolveManifest(unitType);
31
45
  const surfaceContract = getUnitToolSurfaceContract(unitType);