@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
@@ -4,7 +4,9 @@ import type { GSDState } from "../../types.js";
4
4
  import { createRequire } from "node:module";
5
5
 
6
6
  import { computeProgressScore, formatProgressLine } from "../../progress-score.js";
7
+ import { isRepositoryDirty } from "../../git-service.js";
7
8
  import { loadEffectiveGSDPreferences, getGlobalGSDPreferencesPath, getProjectGSDPreferencesPath, availableModelIdsFromRegistry, modelIdsForProfileResolution, resolveProfileAnchorProvider, resolveDisabledModelProvidersFromPreferences } from "../../preferences.js";
9
+ import { createRepositoryRegistryFromPreferences } from "../../repository-registry.js";
8
10
  import { ensurePreferencesFile, handlePrefs, handlePrefsMode, handlePrefsWizard, handleLanguage } from "../../commands-prefs-wizard.js";
9
11
  import { runEnvironmentChecks } from "../../doctor-environment.js";
10
12
  import { deriveState } from "../../state.js";
@@ -220,7 +222,7 @@ export async function handleStatus(ctx: ExtensionCommandContext): Promise<void>
220
222
  );
221
223
 
222
224
  if (result === undefined) {
223
- ctx.ui.notify(formatTextStatus(state), "info");
225
+ ctx.ui.notify(formatTextStatus(state, basePath), "info");
224
226
  }
225
227
  }
226
228
 
@@ -610,7 +612,8 @@ export async function handleCoreCommand(
610
612
  return false;
611
613
  }
612
614
 
613
- export function formatTextStatus(state: GSDState): string {
615
+ export function formatTextStatus(state: GSDState, basePath?: string): string {
616
+ const root = basePath ?? projectRoot();
614
617
  const lines: string[] = ["GSD Status\n"];
615
618
  lines.push(formatProgressLine(computeProgressScore()));
616
619
  lines.push("");
@@ -653,7 +656,7 @@ export function formatTextStatus(state: GSDState): string {
653
656
  }
654
657
  }
655
658
 
656
- const envResults = runEnvironmentChecks(projectRoot());
659
+ const envResults = runEnvironmentChecks(root);
657
660
  const envIssues = envResults.filter((result) => result.status !== "ok");
658
661
  if (envIssues.length > 0) {
659
662
  lines.push("");
@@ -663,5 +666,38 @@ export function formatTextStatus(state: GSDState): string {
663
666
  }
664
667
  }
665
668
 
669
+ // Parent-workspace per-repository git health (#818). No-op for single-repo
670
+ // projects; surfaces which declared child repos have uncommitted changes.
671
+ const repoBlock = buildWorkspaceRepoStatusBlock(root);
672
+ if (repoBlock) {
673
+ lines.push("");
674
+ lines.push("Repositories:");
675
+ lines.push(repoBlock);
676
+ }
677
+
666
678
  return lines.join("\n");
667
679
  }
680
+
681
+ /**
682
+ * Build a per-repository dirty/clean summary for parent-workspace status.
683
+ * Returns "" for single-repo (project-mode) projects so the status output is
684
+ * unchanged; otherwise one line per declared child repository.
685
+ */
686
+ function buildWorkspaceRepoStatusBlock(basePath: string): string {
687
+ let registry;
688
+ try {
689
+ registry = createRepositoryRegistryFromPreferences(basePath, loadEffectiveGSDPreferences(basePath)?.preferences);
690
+ } catch {
691
+ return "";
692
+ }
693
+ if (registry.mode !== "parent") return "";
694
+ const childRepos = registry.repositories.filter((repo) => repo.id !== "project");
695
+ if (childRepos.length === 0) return "";
696
+
697
+ return childRepos
698
+ .map((repo) => {
699
+ const dirty = isRepositoryDirty(repo.root);
700
+ return ` ${dirty ? "✗" : "✓"} ${repo.id}${repo.role ? ` — ${repo.role}` : ""}${dirty ? " (uncommitted changes)" : " (clean)"}`;
701
+ })
702
+ .join("\n");
703
+ }
@@ -25,7 +25,7 @@ import {
25
25
  filterDoctorIssues,
26
26
  } from "./doctor.js";
27
27
  import { isAutoActive, checkRemoteAutoSession } from "./auto.js";
28
- import { getAutoWorktreePath } from "./auto-worktree.js";
28
+ import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
29
29
  import { currentDirectoryRoot, projectRoot } from "./commands/context.js";
30
30
  import { loadPrompt } from "./prompt-loader.js";
31
31
  import { buildClaudeRuntimeFloorAdvisory } from "../../shared/claude-runtime-floor.js";
@@ -551,6 +551,17 @@ export function buildCategorySummaries(prefs: Record<string, unknown>): Record<s
551
551
  if (parts.length > 0) integrationsSummary = parts.join(", ");
552
552
  }
553
553
 
554
+ // Workspace (parent-workspace multi-repo)
555
+ const workspace = prefs.workspace as Record<string, unknown> | undefined;
556
+ const workspaceRepos = workspace?.repositories as Record<string, unknown> | undefined;
557
+ let workspaceSummary = "(single-repo)";
558
+ {
559
+ const parts: string[] = [];
560
+ if (workspace?.mode) parts.push(`mode: ${workspace.mode}`);
561
+ if (workspaceRepos && Object.keys(workspaceRepos).length > 0) parts.push(`${Object.keys(workspaceRepos).length} repo(s)`);
562
+ if (parts.length > 0) workspaceSummary = parts.join(", ");
563
+ }
564
+
554
565
  return {
555
566
  mode: modeSummary,
556
567
  models: modelsSummary,
@@ -568,6 +579,7 @@ export function buildCategorySummaries(prefs: Record<string, unknown>): Record<s
568
579
  hooks: hooksSummary,
569
580
  uok: uokSummary,
570
581
  integrations: integrationsSummary,
582
+ workspace: workspaceSummary,
571
583
  };
572
584
  }
573
585
 
@@ -758,7 +770,10 @@ async function configureDynamicRouting(ctx: ExtensionCommandContext, prefs: Reco
758
770
  const hooks = await promptBoolean(ctx, "Route hook sessions dynamically", dr.hooks, true);
759
771
  if (hooks !== undefined) dr.hooks = hooks;
760
772
 
761
- const flatRate = await promptBoolean(ctx, "Allow dynamic routing for flat-rate providers", dr.allow_flat_rate_providers, false);
773
+ // Opt-out flag (#1115): routing is allowed for flat-rate providers by
774
+ // default; only an explicit `false` suppresses it. The default hint reflects
775
+ // that allow-by-default behavior.
776
+ const flatRate = await promptBoolean(ctx, "Allow dynamic routing for flat-rate providers", dr.allow_flat_rate_providers, true);
762
777
  if (flatRate !== undefined) dr.allow_flat_rate_providers = flatRate;
763
778
 
764
779
  // tier_models.light / standard / heavy — optional model IDs
@@ -968,6 +983,114 @@ async function configureSkills(ctx: ExtensionCommandContext, prefs: Record<strin
968
983
  applyNumber(prefs, "skill_staleness_days", staleness);
969
984
  }
970
985
 
986
+ async function configureWorkspace(ctx: ExtensionCommandContext, prefs: Record<string, unknown>): Promise<void> {
987
+ type RepoConfig = { path: string; role?: string; verification?: string[]; commit_policy?: "auto" | "skip" };
988
+ let workspace = (prefs.workspace ?? {}) as { mode?: "project" | "parent"; repositories?: Record<string, RepoConfig> };
989
+
990
+ // Mode
991
+ const mode = await promptEnum(ctx, "Workspace mode", workspace.mode, ["project", "parent"]);
992
+ if (mode !== undefined) workspace = { ...workspace, mode: mode as "project" | "parent" };
993
+
994
+ if (workspace.mode !== "parent") {
995
+ // Single-repo mode: drop any declared repositories and persist.
996
+ if (workspace.repositories && Object.keys(workspace.repositories).length > 0) {
997
+ const clear = await promptBoolean(ctx, "Clear declared repositories (switch to single-repo)?", false, false);
998
+ if (clear) workspace = { mode: workspace.mode };
999
+ }
1000
+ persistWorkspace(prefs, workspace);
1001
+ return;
1002
+ }
1003
+
1004
+ // Parent mode — edit child repositories via a sub-menu.
1005
+ let repositories = { ...(workspace.repositories ?? {}) };
1006
+ while (true) {
1007
+ const ids = Object.keys(repositories).sort();
1008
+ const summary = ids.length === 0 ? "(no repositories — parent mode requires at least one)" : `${ids.length} repo(s)`;
1009
+ const listLabels = ids.map((id) => {
1010
+ const r = repositories[id];
1011
+ const roleStr = r.role ? ` — ${r.role}` : "";
1012
+ const policyStr = r.commit_policy === "skip" ? " [skip]" : "";
1013
+ return `${id} (${r.path})${roleStr}${policyStr}`;
1014
+ });
1015
+ const choice = await ctx.ui.select(`Declared repositories — ${summary}`, [...listLabels, "Add repository", "Done"]);
1016
+ const pick = typeof choice === "string" ? choice : "";
1017
+ if (!pick || pick === "Done") break;
1018
+ if (pick === "Add repository") {
1019
+ const idInput = await ctx.ui.input("Repository id (letters, digits, . _ -; 'project' is reserved):", "");
1020
+ const id = typeof idInput === "string" ? idInput.trim() : "";
1021
+ if (!id || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(id)) {
1022
+ ctx.ui.notify("Invalid repository id — must match ^[A-Za-z0-9][A-Za-z0-9._-]*$ and cannot be 'project'.", "warning");
1023
+ continue;
1024
+ }
1025
+ if (id === "project" || repositories[id]) {
1026
+ ctx.ui.notify(`Repository id "${id}" is reserved or already declared.`, "warning");
1027
+ continue;
1028
+ }
1029
+ const pathInput = await ctx.ui.input("Repository path (relative to project root, e.g. frontend):", "");
1030
+ const path = typeof pathInput === "string" ? pathInput.trim() : "";
1031
+ if (!path) { ctx.ui.notify("Repository path is required.", "warning"); continue; }
1032
+ const repo: RepoConfig = { path };
1033
+ const roleInput = await ctx.ui.input("Role/label (optional):", "");
1034
+ if (typeof roleInput === "string" && roleInput.trim()) repo.role = roleInput.trim();
1035
+ const verifyInput = await ctx.ui.input("Verification commands (comma- or newline-separated, optional):", "");
1036
+ if (typeof verifyInput === "string" && verifyInput.trim()) {
1037
+ const cmds = parseStringList(verifyInput);
1038
+ if (cmds.length > 0) repo.verification = cmds;
1039
+ }
1040
+ const policy = await promptEnum(ctx, "Commit policy", undefined, ["auto", "skip"]);
1041
+ if (policy === "skip") repo.commit_policy = "skip";
1042
+ repositories[id] = repo;
1043
+ } else {
1044
+ // Edit/delete an existing repo (the first token is the id).
1045
+ const id = pick.split(" ")[0];
1046
+ if (!repositories[id]) continue;
1047
+ const editChoice = await ctx.ui.select(
1048
+ `Repository ${id}`,
1049
+ ["Edit path", "Edit role", "Edit verification", "Edit commit policy", "Delete repository", "Cancel"],
1050
+ );
1051
+ const ec = typeof editChoice === "string" ? editChoice : "";
1052
+ if (!ec || ec === "Cancel") continue;
1053
+ if (ec === "Delete repository") {
1054
+ delete repositories[id];
1055
+ } else if (ec === "Edit path") {
1056
+ const v = await ctx.ui.input("Repository path:", repositories[id].path);
1057
+ if (typeof v === "string" && v.trim()) repositories[id] = { ...repositories[id], path: v.trim() };
1058
+ } else if (ec === "Edit role") {
1059
+ const v = await ctx.ui.input("Role/label (blank to clear):", repositories[id].role ?? "");
1060
+ if (typeof v === "string" && v.trim()) repositories[id] = { ...repositories[id], role: v.trim() };
1061
+ else if (typeof v === "string") { const { role, ...rest } = repositories[id]; void role; repositories[id] = rest; }
1062
+ } else if (ec === "Edit verification") {
1063
+ const v = await ctx.ui.input("Verification commands (blank to clear):", (repositories[id].verification ?? []).join(", "));
1064
+ if (typeof v === "string" && v.trim()) {
1065
+ const cmds = parseStringList(v);
1066
+ if (cmds.length > 0) repositories[id] = { ...repositories[id], verification: cmds };
1067
+ } else if (typeof v === "string") {
1068
+ const { verification, ...rest } = repositories[id]; void verification; repositories[id] = rest;
1069
+ }
1070
+ } else if (ec === "Edit commit policy") {
1071
+ const policy = await promptEnum(ctx, "Commit policy", repositories[id].commit_policy, ["auto", "skip"]);
1072
+ if (policy === "skip") repositories[id] = { ...repositories[id], commit_policy: "skip" };
1073
+ else { const { commit_policy, ...rest } = repositories[id]; void commit_policy; repositories[id] = rest; }
1074
+ }
1075
+ }
1076
+ }
1077
+
1078
+ if (Object.keys(repositories).length === 0) {
1079
+ ctx.ui.notify("Parent mode requires at least one repository — mode not saved.", "warning");
1080
+ return;
1081
+ }
1082
+ persistWorkspace(prefs, { mode: "parent", repositories });
1083
+ }
1084
+
1085
+ /** Persist the workspace config onto prefs, dropping it entirely when empty. */
1086
+ function persistWorkspace(prefs: Record<string, unknown>, workspace: { mode?: string; repositories?: Record<string, unknown> }): void {
1087
+ if (!workspace.mode && (!workspace.repositories || Object.keys(workspace.repositories).length === 0)) {
1088
+ delete prefs.workspace;
1089
+ return;
1090
+ }
1091
+ prefs.workspace = workspace;
1092
+ }
1093
+
971
1094
  async function configureSkillRules(ctx: ExtensionCommandContext, prefs: Record<string, unknown>): Promise<void> {
972
1095
  type Rule = { when: string; use?: string[]; prefer?: string[]; avoid?: string[] };
973
1096
  let rules: Rule[] = Array.isArray(prefs.skill_rules) ? [...prefs.skill_rules as Rule[]] : [];
@@ -1176,6 +1299,14 @@ async function configureVerification(ctx: ExtensionCommandContext, prefs: Record
1176
1299
  const maxRetries = await promptInteger(ctx, "Verification max retries", prefs.verification_max_retries, "2");
1177
1300
  applyNumber(prefs, "verification_max_retries", maxRetries);
1178
1301
 
1302
+ const perUnitCap = await promptNumber(
1303
+ ctx,
1304
+ "Per-unit cost cap (USD; retry cost ceiling, blank = clear to default)",
1305
+ prefs.per_unit_cost_cap_usd,
1306
+ "5.0",
1307
+ );
1308
+ applyNumber(prefs, "per_unit_cost_cap_usd", perUnitCap);
1309
+
1179
1310
  const ev = await promptBoolean(ctx, "Enhanced verification (master toggle)", prefs.enhanced_verification, true);
1180
1311
  if (ev !== undefined) prefs.enhanced_verification = ev;
1181
1312
  const evPre = await promptBoolean(ctx, "Enhanced verification — pre-execution checks", prefs.enhanced_verification_pre, true);
@@ -1621,6 +1752,7 @@ export async function handlePrefsWizard(
1621
1752
  `Hooks ${summaries.hooks}`,
1622
1753
  `UoK ${summaries.uok}`,
1623
1754
  `Integrations ${summaries.integrations}`,
1755
+ `Workspace ${summaries.workspace}`,
1624
1756
  `Advanced ${summaries.advanced}`,
1625
1757
  `── Save & Exit ──`,
1626
1758
  ];
@@ -1644,6 +1776,7 @@ export async function handlePrefsWizard(
1644
1776
  else if (choice.startsWith("Hooks")) await configureHooks(ctx, prefs);
1645
1777
  else if (choice.startsWith("UoK")) await configureUoK(ctx, prefs);
1646
1778
  else if (choice.startsWith("Integrations")) await configureIntegrations(ctx, prefs);
1779
+ else if (choice.startsWith("Workspace")) await configureWorkspace(ctx, prefs);
1647
1780
  else if (choice.startsWith("Advanced")) await configureAdvanced(ctx, prefs);
1648
1781
  }
1649
1782
 
@@ -1780,6 +1913,7 @@ export function serializePreferencesToFrontmatter(prefs: Record<string, unknown>
1780
1913
  "reactive_execution", "gate_evaluation",
1781
1914
  "auto_visualize", "auto_report",
1782
1915
  "verification_commands", "verification_auto_fix", "verification_max_retries",
1916
+ "per_unit_cost_cap_usd",
1783
1917
  "enhanced_verification", "enhanced_verification_pre",
1784
1918
  "enhanced_verification_post", "enhanced_verification_strict",
1785
1919
  "safety_harness",
@@ -23,7 +23,7 @@ import {
23
23
  } from "./workflow-templates.js";
24
24
  import { loadPrompt } from "./prompt-loader.js";
25
25
  import { gsdRoot } from "./paths.js";
26
- import { createGitService, runGit } from "./git-service.js";
26
+ import { createGitService, runGit, taskBranchArgs } from "./git-service.js";
27
27
  import { isAutoActive, isAutoPaused } from "./auto.js";
28
28
  import { getErrorMessage } from "./error-utils.js";
29
29
  import { resolvePlugin, type WorkflowPlugin } from "./workflow-plugins.js";
@@ -464,7 +464,7 @@ export async function handleStart(
464
464
  try {
465
465
  git.autoCommit("workflow-template", templateId, []);
466
466
  } catch { /* nothing to commit */ }
467
- runGit(basePath, ["checkout", "-b", branchName]);
467
+ runGit(basePath, taskBranchArgs(basePath, branchName, current, git.getMainBranch()));
468
468
  branchCreated = true;
469
469
  }
470
470
  } catch (err) {
@@ -636,7 +636,7 @@ export function dispatchMarkdownPhasePlugin(
636
636
  const current = git.getCurrentBranch();
637
637
  if (current !== branchName) {
638
638
  try { git.autoCommit("workflow-template", templateId, []); } catch { /* nothing to commit */ }
639
- runGit(basePath, ["checkout", "-b", branchName]);
639
+ runGit(basePath, taskBranchArgs(basePath, branchName, current, git.getMainBranch()));
640
640
  branchCreated = true;
641
641
  }
642
642
  } catch (err) {
@@ -315,8 +315,19 @@ async function handleRemove(args: string, ctx: ExtensionCommandContext): Promise
315
315
  }
316
316
 
317
317
  try {
318
- removeWorktree(basePath, name, { deleteBranch: true });
319
- ctx.ui.notify(`Removed worktree ${name}.`, "info");
318
+ const removed = removeWorktree(basePath, name, { deleteBranch: true });
319
+ if (removed) {
320
+ ctx.ui.notify(`Removed worktree ${name}.`, "info");
321
+ } else {
322
+ ctx.ui.notify(
323
+ [
324
+ `Worktree removal aborted for "${name}" to preserve uncommitted changes.`,
325
+ "",
326
+ "Manual quarantine recovery may be needed before retrying removal.",
327
+ ].join("\n"),
328
+ "warning",
329
+ );
330
+ }
320
331
  } catch (err) {
321
332
  const msg = err instanceof Error ? err.message : String(err);
322
333
  ctx.ui.notify(
@@ -281,7 +281,7 @@ export function getMilestone(id: string): MilestoneRow | null {
281
281
  export function getActiveMilestoneFromDb(): MilestoneRow | null {
282
282
  if (!getDbOrNull()!) return null;
283
283
  const row = getDbOrNull()!.prepare(
284
- "SELECT * FROM milestones WHERE status NOT IN ('complete', 'done', 'skipped', 'closed', 'parked') ORDER BY id LIMIT 1",
284
+ `SELECT * FROM milestones WHERE status NOT IN (${TERMINAL_STATUS_SQL}, 'parked') ORDER BY id LIMIT 1`,
285
285
  ).get();
286
286
  if (!row) return null;
287
287
  return rowToMilestone(row);
@@ -295,11 +295,11 @@ export function getActiveSliceFromDb(milestoneId: string): SliceRow | null {
295
295
  const row = getDbOrNull()!.prepare(
296
296
  `SELECT s.* FROM slices s
297
297
  WHERE s.milestone_id = :mid
298
- AND s.status NOT IN ('complete', 'done', 'skipped')
298
+ AND s.status NOT IN (${TERMINAL_STATUS_SQL})
299
299
  AND NOT EXISTS (
300
300
  SELECT 1 FROM json_each(s.depends) AS dep
301
301
  WHERE dep.value NOT IN (
302
- SELECT id FROM slices WHERE milestone_id = :mid AND status IN ('complete', 'done', 'skipped')
302
+ SELECT id FROM slices WHERE milestone_id = :mid AND status IN (${TERMINAL_STATUS_SQL})
303
303
  )
304
304
  )
305
305
  ORDER BY s.sequence, s.id
@@ -312,7 +312,7 @@ export function getActiveSliceFromDb(milestoneId: string): SliceRow | null {
312
312
  export function getActiveTaskFromDb(milestoneId: string, sliceId: string): TaskRow | null {
313
313
  if (!getDbOrNull()!) return null;
314
314
  const row = getDbOrNull()!.prepare(
315
- "SELECT * FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND status NOT IN ('complete', 'done') ORDER BY sequence, id LIMIT 1",
315
+ `SELECT * FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND status NOT IN (${TERMINAL_STATUS_SQL}) ORDER BY sequence, id LIMIT 1`,
316
316
  ).get({ ":mid": milestoneId, ":sid": sliceId });
317
317
  if (!row) return null;
318
318
  return rowToTask(row);
@@ -339,7 +339,7 @@ export function getParallelMonitorSliceProgress(milestoneId: string): ParallelMo
339
339
  s.id AS id,
340
340
  s.status AS status,
341
341
  COUNT(t.id) AS total,
342
- COALESCE(SUM(CASE WHEN t.status='complete' THEN 1 ELSE 0 END), 0) AS done
342
+ COALESCE(SUM(CASE WHEN t.status IN (${TERMINAL_STATUS_SQL}) THEN 1 ELSE 0 END), 0) AS done
343
343
  FROM slices s
344
344
  LEFT JOIN tasks t ON s.milestone_id=t.milestone_id AND s.id=t.slice_id
345
345
  WHERE s.milestone_id=:mid
@@ -413,6 +413,46 @@ export function getSlicesByMilestoneIds(milestoneIds: readonly string[]): Map<st
413
413
  return byMilestone;
414
414
  }
415
415
 
416
+ /**
417
+ * Load tasks for many (milestone, slice) pairs in batched queries. Returns a Map
418
+ * keyed by `${milestone_id}\0${slice_id}`, preserving `ORDER BY sequence, id`
419
+ * within each bucket. Mirrors getSlicesByMilestoneIds to avoid an N+1 over tasks
420
+ * during full projection rebuilds.
421
+ */
422
+ export function getTasksBySliceIds(
423
+ slices: ReadonlyArray<{ milestoneId: string; sliceId: string }>,
424
+ ): Map<string, TaskRow[]> {
425
+ const bySlice = new Map<string, TaskRow[]>();
426
+ const db = getDbOrNull();
427
+ if (!db || slices.length === 0) return bySlice;
428
+ // SQLite caps bound params (~999); 2 per pair, so chunk well under the limit.
429
+ const CHUNK = 400;
430
+ for (let start = 0; start < slices.length; start += CHUNK) {
431
+ const chunk = slices.slice(start, start + CHUNK);
432
+ const clauses: string[] = [];
433
+ const params: Record<string, unknown> = {};
434
+ chunk.forEach((s, i) => {
435
+ clauses.push(`(milestone_id = :m${i} AND slice_id = :s${i})`);
436
+ params[`:m${i}`] = s.milestoneId;
437
+ params[`:s${i}`] = s.sliceId;
438
+ });
439
+ const rows = db
440
+ .prepare(`SELECT * FROM tasks WHERE ${clauses.join(" OR ")} ORDER BY milestone_id, slice_id, sequence, id`)
441
+ .all(params) as Record<string, unknown>[];
442
+ for (const row of rows) {
443
+ const task = rowToTask(row);
444
+ const key = `${task.milestone_id}\0${task.slice_id}`;
445
+ const bucket = bySlice.get(key);
446
+ if (bucket) {
447
+ bucket.push(task);
448
+ } else {
449
+ bySlice.set(key, [task]);
450
+ }
451
+ }
452
+ }
453
+ return bySlice;
454
+ }
455
+
416
456
  /** Dispatch-eligibility shape consumed by decision-path callers (ADR-017). */
417
457
  export interface MilestoneSliceSummary {
418
458
  id: string;
@@ -478,7 +518,7 @@ export function getSliceScopedArtifacts(milestoneId: string, sliceId: string): A
478
518
  export function getActiveMilestoneIdFromDb(): IdStatusSummary | null {
479
519
  if (!getDbOrNull()!) return null;
480
520
  const row = getDbOrNull()!.prepare(
481
- "SELECT id, status FROM milestones WHERE status NOT IN ('complete', 'done', 'skipped', 'closed', 'parked') ORDER BY id LIMIT 1",
521
+ `SELECT id, status FROM milestones WHERE status NOT IN (${TERMINAL_STATUS_SQL}, 'parked') ORDER BY id LIMIT 1`,
482
522
  ).get();
483
523
  if (!row) return null;
484
524
  return rowToIdStatusSummary(row);
@@ -496,7 +536,7 @@ export function getSliceStatusSummary(milestoneId: string): IdStatusSummary[] {
496
536
  export function getActiveTaskIdFromDb(milestoneId: string, sliceId: string): ActiveTaskSummary | null {
497
537
  if (!getDbOrNull()!) return null;
498
538
  const row = getDbOrNull()!.prepare(
499
- "SELECT id, status, title FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND status NOT IN ('complete', 'done') ORDER BY sequence, id LIMIT 1",
539
+ `SELECT id, status, title FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND status NOT IN (${TERMINAL_STATUS_SQL}) ORDER BY sequence, id LIMIT 1`,
500
540
  ).get({ ":mid": milestoneId, ":sid": sliceId });
501
541
  if (!row) return null;
502
542
  return rowToActiveTaskSummary(row);
@@ -508,8 +548,8 @@ export function getSliceTaskCounts(milestoneId: string, sliceId: string): TaskSt
508
548
  const row = getDbOrNull()!.prepare(
509
549
  `SELECT
510
550
  COUNT(*) as total,
511
- SUM(CASE WHEN status IN ('complete', 'done') THEN 1 ELSE 0 END) as done,
512
- SUM(CASE WHEN status NOT IN ('complete', 'done') THEN 1 ELSE 0 END) as pending
551
+ SUM(CASE WHEN status IN (${TERMINAL_STATUS_SQL}) THEN 1 ELSE 0 END) as done,
552
+ SUM(CASE WHEN status NOT IN (${TERMINAL_STATUS_SQL}) THEN 1 ELSE 0 END) as pending
513
553
  FROM tasks WHERE milestone_id = :mid AND slice_id = :sid`,
514
554
  ).get({ ":mid": milestoneId, ":sid": sliceId });
515
555
  return rowToTaskStatusCounts(row);
@@ -82,7 +82,13 @@ function ensureMilestoneRowForAcceptedHandoff(
82
82
  entry: PendingAutoStartEntry,
83
83
  contextFile: string | null,
84
84
  ): boolean {
85
- if (!isDbAvailable()) return true;
85
+ if (!isDbAvailable()) {
86
+ logWarning(
87
+ "guided",
88
+ `R3b: milestone ${entry.milestoneId} DB-row recovery skipped because DB is unavailable`,
89
+ );
90
+ return false;
91
+ }
86
92
 
87
93
  const { basePath, milestoneId } = entry;
88
94
  const milestoneRow = getMilestone(milestoneId);
@@ -122,12 +128,14 @@ function ensureMilestoneRowForAcceptedHandoff(
122
128
  `(attempt ${entry.r3bRecoveryCount + 1}/${MAX_DB_ROW_RECOVERIES})`,
123
129
  );
124
130
 
131
+ let inserted = false;
125
132
  try {
126
- insertMilestone({ id: milestoneId, title: milestoneId, status: "queued" });
133
+ inserted = insertMilestone({ id: milestoneId, title: milestoneId, status: "queued" });
127
134
  } catch (e) {
128
135
  logWarning("guided", `R3b: insertMilestone failed: ${(e as Error).message}`);
129
136
  }
130
137
 
138
+ if (inserted) return true;
131
139
  if (getMilestone(milestoneId)) return true;
132
140
 
133
141
  noteDbRowRecoveryMiss(entry);
@@ -163,7 +163,7 @@ Diagnostics record the file path, scope (global/project), severity (error/warnin
163
163
  - **Deprecated:** `merge_to_main` — no longer valid; milestone-level merge is always used. Remove this setting.
164
164
 
165
165
  - `workspace`: configures multi-repository parent workspaces. Keys:
166
- - `mode`: `"project"` (default single-repo behavior) or `"parent"` (one `.gsd` controlling child repos).
166
+ - `mode`: `"project"` (default single-repo behavior) or `"parent"` (one `.gsd` controlling child repos). In `"parent"` mode at least one child repository must be declared under `repositories`, otherwise the setting is rejected at validation time.
167
167
  - `repositories`: object map of repository IDs to config.
168
168
  - Repository ID format: `^[A-Za-z0-9][A-Za-z0-9._-]*$`.
169
169
  - Reserved ID: `project` is implicit and always maps to the project root; user-defined `workspace.repositories.project` is rejected.
@@ -171,6 +171,8 @@ Diagnostics record the file path, scope (global/project), severity (error/warnin
171
171
  - `role`: optional short description of what the repo owns.
172
172
  - `verification`: optional array of verification commands for that repo.
173
173
  - `commit_policy`: optional `"auto"` or `"skip"` to include or skip commit actions per repo.
174
+ - Planning tools consume repository IDs through `targetRepositories`: `gsd_plan_slice.targetRepositories` sets a slice-wide default, and `gsd_plan_task.targetRepositories` records the repositories an individual task touches. Values must be declared IDs or the implicit `project`; omit these fields in single-repo projects.
175
+ - In parent mode with declared child repositories, `/gsd codebase generate` and automatic `.gsd/CODEBASE.md` refreshes enumerate `project` plus each child repository, render repo-labeled sections, and store repository IDs in map metadata.
174
176
 
175
177
  ## Workspace Example
176
178
 
@@ -198,6 +200,8 @@ workspace:
198
200
 
199
201
  This config sets a parent workspace with two child repositories. The implicit `project` repository is always created for the project root and cannot be user-defined.
200
202
 
203
+ In `"parent"` mode, slice/task `targetRepositories` default to the declared child repositories (here `frontend` and `backend`) rather than the root `project` repo. In `"project"` mode (the default), `targetRepositories` defaults to `["project"]`.
204
+
201
205
  - `unique_milestone_ids`: boolean — when `true`, generates milestone IDs in `M{seq}-{rand6}` format (e.g. `M001-eh88as`) instead of plain sequential `M001`. Prevents ID collisions in team workflows where multiple contributors create milestones concurrently. Both formats coexist — existing `M001`-style milestones remain valid. Default: `false`.
202
206
 
203
207
  - `budget_ceiling`: number — maximum dollar amount to spend on auto-mode. When reached, behavior is controlled by `budget_enforcement`. Default: no limit.
@@ -303,7 +307,9 @@ This config sets a parent workspace with two child repositories. The implicit `p
303
307
  - `verification`: string[] (optional) — repository-specific verification commands used when global `verification_commands` is not set.
304
308
  - `commit_policy`: `"auto"` | `"skip"` (optional) — per-repository closeout commit behavior.
305
309
  - `project` is always an implicit repository target mapped to the project root for backward compatibility.
306
- - Plan/task `targetRepositories` defaults to `["project"]` when omitted.
310
+ - `targetRepositories` on `gsd_plan_slice` sets the slice-wide default. `targetRepositories` on `gsd_plan_task` records or overrides the repository IDs for an individual task.
311
+ - Values must match declared repository IDs or the implicit `project`; omitted plan/task `targetRepositories` defaults to `["project"]`.
312
+ - `/gsd codebase` is workspace-aware in parent mode with declared child repositories: generated `.gsd/CODEBASE.md` uses workspace-relative paths, groups files under `## [repo-id]` headings, and refreshes when repository registry metadata changes.
307
313
 
308
314
  - `verification_commands`: string[] — shell commands to run as verification after task execution (e.g., `["npm test", "npm run lint"]`). Commands run in order; if any fails, the task is marked as needing fixes.
309
315