@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
@@ -12,7 +12,7 @@ import { readFileSync, existsSync, mkdirSync, statSync, unlinkSync } from "node:
12
12
  import { logWarning } from "./workflow-logger.js";
13
13
  import { isClosedStatus } from "./status-guards.js";
14
14
  import { dirname, join, relative } from "node:path";
15
- import { getAllMilestones, getMilestone, getMilestoneScopedArtifacts, getSliceScopedArtifacts, getMilestoneSlices, getSliceTasks, getTask, getSlice, insertArtifact, deleteArtifactByPath, getGateResults, isDbAvailable, } from "./gsd-db.js";
15
+ import { getAllMilestones, getMilestone, getMilestoneScopedArtifacts, getSliceScopedArtifacts, getMilestoneSlices, getSliceTasks, getTasksBySliceIds, getTask, getSlice, insertArtifact, deleteArtifactByPath, getGateResults, isDbAvailable, } from "./gsd-db.js";
16
16
  import { resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTasksDir, gsdProjectionRoot, gsdRoot, buildMilestoneFileName, buildTaskFileName, } from "./paths.js";
17
17
  import { saveFile, clearParseCache, registerCacheClearCallback } from "./files.js";
18
18
  import { parseRoadmap, parsePlan } from "./parsers-legacy.js";
@@ -99,6 +99,12 @@ function meaningfulSection(value) {
99
99
  return "";
100
100
  return trimmed;
101
101
  }
102
+ function renderGateFindings(gate) {
103
+ const findings = gate.findings.trim() || `- **Verdict:** ${gate.verdict}\n- **Rationale:** ${gate.rationale}`;
104
+ if (gate.verdict !== "flag")
105
+ return findings;
106
+ return `> **Warning:** Verdict: flag - concerns recorded below\n\n${findings}`;
107
+ }
102
108
  function pushIndented(lines, value, indent = " ") {
103
109
  for (const line of value.split("\n")) {
104
110
  lines.push(`${indent}${line}`);
@@ -289,7 +295,7 @@ function renderTaskPlanMarkdown(task, taskGates = []) {
289
295
  if (gate && gate.verdict !== "omitted") {
290
296
  lines.push(`## ${label}`);
291
297
  lines.push("");
292
- lines.push(gate.findings.trim() || `- **Verdict:** ${gate.verdict}\n- **Rationale:** ${gate.rationale}`);
298
+ lines.push(renderGateFindings(gate));
293
299
  lines.push("");
294
300
  }
295
301
  }
@@ -319,14 +325,14 @@ function renderSlicePlanMarkdown(slice, tasks, gates = []) {
319
325
  if (q3 && q3.verdict !== "omitted") {
320
326
  lines.push("## Threat Surface");
321
327
  lines.push("");
322
- lines.push(q3.findings.trim() || `- **Verdict:** ${q3.verdict}\n- **Rationale:** ${q3.rationale}`);
328
+ lines.push(renderGateFindings(q3));
323
329
  lines.push("");
324
330
  }
325
331
  const q4 = gates.find(g => g.gate_id === "Q4" && g.status === "complete");
326
332
  if (q4 && q4.verdict !== "omitted") {
327
333
  lines.push("## Requirement Impact");
328
334
  lines.push("");
329
- lines.push(q4.findings.trim() || `- **Verdict:** ${q4.verdict}\n- **Rationale:** ${q4.rationale}`);
335
+ lines.push(renderGateFindings(q4));
330
336
  lines.push("");
331
337
  }
332
338
  const proofLevel = meaningfulSection(slice.proof_level);
@@ -701,6 +707,17 @@ export async function renderSliceSummary(basePath, milestoneId, sliceId) {
701
707
  export async function renderAllFromDb(basePath) {
702
708
  const result = { rendered: 0, skipped: 0, errors: [] };
703
709
  const milestones = getAllMilestones();
710
+ // Pre-fetch slices once per milestone and batch-load all tasks in one query
711
+ // family, avoiding an N+1 (previously one task query per slice).
712
+ const slicesByMilestone = new Map();
713
+ const slicePairs = [];
714
+ for (const milestone of milestones) {
715
+ const slices = getMilestoneSlices(milestone.id);
716
+ slicesByMilestone.set(milestone.id, slices);
717
+ for (const slice of slices)
718
+ slicePairs.push({ milestoneId: milestone.id, sliceId: slice.id });
719
+ }
720
+ const tasksBySlice = getTasksBySliceIds(slicePairs);
704
721
  for (const milestone of milestones) {
705
722
  // Render roadmap checkboxes
706
723
  try {
@@ -723,8 +740,8 @@ export async function renderAllFromDb(basePath) {
723
740
  catch (err) {
724
741
  result.errors.push(`milestone artifacts ${milestone.id}: ${err.message}`);
725
742
  }
726
- // Iterate slices
727
- const slices = getMilestoneSlices(milestone.id);
743
+ // Iterate slices (pre-fetched above)
744
+ const slices = slicesByMilestone.get(milestone.id) ?? [];
728
745
  for (const slice of slices) {
729
746
  // Preserve slice-scoped artifacts imported from disk, including real PLAN
730
747
  // fallback content when task rows cannot regenerate it.
@@ -760,8 +777,8 @@ export async function renderAllFromDb(basePath) {
760
777
  catch (err) {
761
778
  result.errors.push(`slice summary ${milestone.id}/${slice.id}: ${err.message}`);
762
779
  }
763
- // Iterate tasks
764
- const tasks = getSliceTasks(milestone.id, slice.id);
780
+ // Iterate tasks (batched above)
781
+ const tasks = tasksBySlice.get(`${milestone.id}\0${slice.id}`) ?? [];
765
782
  for (const task of tasks) {
766
783
  try {
767
784
  const ok = await renderTaskSummary(basePath, milestone.id, slice.id, task.id);
@@ -1028,9 +1045,21 @@ export async function renderReplanFromDb(basePath, milestoneId, sliceId, replanD
1028
1045
  return { replanPath: absPath, content };
1029
1046
  }
1030
1047
  export async function renderAssessmentFromDb(basePath, milestoneId, sliceId, assessmentData) {
1031
- // Flat-phase: assessment file lives in the phase dir
1032
- const slicePath = resolveSlicePath(basePath, milestoneId, sliceId)
1033
- ?? join(milestonesDir(basePath), canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title));
1048
+ // Flat-phase: the assessment file lives in the phase dir, NOT in a slices/SID/
1049
+ // subdir. resolveSlicePath() detects a slices/SID/ dir unconditionally, so a
1050
+ // stray slices/SID/ created by an earlier planning step would send this write
1051
+ // to a hybrid path (wrong dir, flat filename) that verification cannot find.
1052
+ // Guard with the same legacy-base check relSlicePath() uses so flat-phase
1053
+ // milestones always target the phase dir.
1054
+ const mDir = resolveMilestonePath(basePath, milestoneId);
1055
+ const legacyBase = legacyMilestonesDir(basePath);
1056
+ const isLegacyLayout = mDir
1057
+ ? mDir.startsWith(legacyBase + "/") || mDir.startsWith(legacyBase + "\\")
1058
+ : false;
1059
+ const fallbackDir = join(milestonesDir(basePath), canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title));
1060
+ const slicePath = isLegacyLayout
1061
+ ? (resolveSlicePath(basePath, milestoneId, sliceId) ?? fallbackDir)
1062
+ : (mDir ?? fallbackDir);
1034
1063
  const phaseNum = milestoneIdToPhaseNum(milestoneId);
1035
1064
  const planNum = sliceIdToPlanNum(sliceId);
1036
1065
  const absPath = join(slicePath, planFileName(phaseNum, planNum, "ASSESSMENT"));
@@ -8,7 +8,7 @@
8
8
  import { execFileSync } from "node:child_process";
9
9
  import { existsSync, lstatSync, mkdirSync, readdirSync, realpathSync, renameSync, cpSync, rmSync, statSync, symlinkSync } from "node:fs";
10
10
  import { join } from "node:path";
11
- import { externalGsdRoot, isInsideWorktree } from "./repo-identity.js";
11
+ import { externalGsdRoot, externalStateAlreadyExistsForProject, isInsideWorktree } from "./repo-identity.js";
12
12
  import { getErrorMessage } from "./error-utils.js";
13
13
  import { hasGitTrackedGsdFiles } from "./gitignore.js";
14
14
  import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
@@ -74,6 +74,15 @@ export function migrateToExternalState(basePath) {
74
74
  return { migrated: false };
75
75
  }
76
76
  }
77
+ // If external state already contains project data, this is not a legacy
78
+ // migration source. It is likely an already-migrated project whose symlink
79
+ // was replaced by a real directory, so copying would risk data loss.
80
+ if (externalStateAlreadyExistsForProject(basePath)) {
81
+ return {
82
+ migrated: false,
83
+ error: "External state already exists for this project; leaving local .gsd directory untouched to avoid overwriting authoritative state",
84
+ };
85
+ }
77
86
  const externalPath = externalGsdRoot(basePath);
78
87
  const migratingPath = join(basePath, ".gsd.migrating");
79
88
  try {
@@ -81,13 +90,13 @@ export function migrateToExternalState(basePath) {
81
90
  mkdirSync(externalPath, { recursive: true });
82
91
  // Rename .gsd -> .gsd.migrating (atomic lock).
83
92
  // On Windows, NTFS may reject rename with EPERM if file descriptors are
84
- // open (VS Code watchers, antivirus on-access scan). Fall back to
85
- // copy+delete (#1292).
93
+ // open (VS Code watchers, antivirus on-access scan). WSL/DrvFs can report
94
+ // the same transient lock as EACCES. Fall back to copy+delete (#1292).
86
95
  try {
87
96
  renameSync(localGsd, migratingPath);
88
97
  }
89
98
  catch (renameErr) {
90
- if (renameErr?.code === "EPERM" || renameErr?.code === "EBUSY") {
99
+ if (renameErr?.code === "EPERM" || renameErr?.code === "EBUSY" || renameErr?.code === "EACCES") {
91
100
  try {
92
101
  cpSync(localGsd, migratingPath, { recursive: true, force: true });
93
102
  rmSync(localGsd, { recursive: true, force: true });
@@ -239,7 +248,7 @@ function isLocalGsdExternalStateJunction(basePath, localGsd) {
239
248
  * Recover from a failed migration (`.gsd.migrating` exists).
240
249
  * Moves `.gsd.migrating` back to `.gsd` if `.gsd` doesn't exist, or removes an
241
250
  * orphaned staging directory when `.gsd` is already a verified external state
242
- * junction with intact current state.
251
+ * junction, or an intact real directory, with intact current state.
243
252
  */
244
253
  export function recoverFailedMigration(basePath) {
245
254
  const localGsd = join(basePath, ".gsd");
@@ -247,10 +256,18 @@ export function recoverFailedMigration(basePath) {
247
256
  if (!existsSync(migratingPath))
248
257
  return false;
249
258
  if (existsSync(localGsd)) {
250
- if (!isLocalGsdExternalStateJunction(basePath, localGsd))
251
- return false;
252
259
  if (!isCurrentGsdStateIntactForMigratingCleanup(basePath))
253
260
  return false;
261
+ if (!isLocalGsdExternalStateJunction(basePath, localGsd)) {
262
+ try {
263
+ const stat = lstatSync(localGsd);
264
+ if (!stat.isDirectory())
265
+ return false;
266
+ }
267
+ catch {
268
+ return false;
269
+ }
270
+ }
254
271
  try {
255
272
  rmSync(migratingPath, { recursive: true, force: true });
256
273
  return true;
@@ -1,10 +1,21 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: Process-level transaction wrapper for milestone merge closeout.
3
+ import { mergeMilestoneToMain } from "./auto-worktree-merge.js";
3
4
  export function runMilestoneMergeTransaction(deps, input) {
4
- return deps.mergeMilestoneToMain(input.basePath, input.milestoneId, input.roadmapContent);
5
+ return deps.mergeMilestone(input.basePath, input.milestoneId, input.roadmapContent);
5
6
  }
6
- export function createMilestoneMergeTransaction(mergeMilestoneToMain) {
7
+ export function createMilestoneMergeTransaction(mergeMilestone) {
7
8
  return function mergeMilestoneTransaction(basePath, milestoneId, roadmapContent) {
8
- return runMilestoneMergeTransaction({ mergeMilestoneToMain }, { basePath, milestoneId, roadmapContent });
9
+ return runMilestoneMergeTransaction({ mergeMilestone }, { basePath, milestoneId, roadmapContent });
9
10
  };
10
11
  }
12
+ /**
13
+ * Production merge transaction adapter.
14
+ *
15
+ * This is the only production construction point that knows the legacy
16
+ * `auto-worktree.ts` merge primitive. Lifecycle callers depend on the
17
+ * transaction runner interface, not the legacy implementation module.
18
+ */
19
+ export function createDefaultMilestoneMergeTransaction(mergeMilestone = mergeMilestoneToMain) {
20
+ return createMilestoneMergeTransaction(mergeMilestone);
21
+ }
@@ -1,6 +1,6 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: Milestone closeout settlement state across DB proof, artifacts, merge, and cleanup.
3
- import { isInAutoWorktree } from "./auto-worktree.js";
3
+ import { isInAutoWorktree } from "./auto-worktree-entry.js";
4
4
  import { formatCloseoutProofBlock, proveMilestoneCloseout, } from "./milestone-closeout-proof.js";
5
5
  import { resolveCloseoutArtifactProjection } from "./artifact-projection.js";
6
6
  function isActiveUnmergedWorktree(input) {
@@ -8,7 +8,7 @@ import { existsSync, readdirSync } from "node:fs";
8
8
  import { spawnSync } from "node:child_process";
9
9
  import { resolveGsdPathContract } from "./paths.js";
10
10
  import { worktreePathFor, worktreesDirs } from "./worktree-placement.js";
11
- import { getAutoWorktreePath } from "./auto-worktree.js";
11
+ import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
12
12
  import { buildWorktreeLifecycleDeps } from "./auto.js";
13
13
  import { mergeMilestoneStandalone, } from "./worktree-lifecycle.js";
14
14
  import { MergeConflictError } from "./git-service.js";
@@ -12,7 +12,9 @@ import { join, dirname } from "node:path";
12
12
  import { fileURLToPath } from "node:url";
13
13
  import { gsdRoot } from "./paths.js";
14
14
  import { createWorktree, worktreePath } from "./worktree-manager.js";
15
- import { autoWorktreeBranch, fastForwardReusedMilestoneBranchIfSafe, runWorktreePostCreateHook, syncGsdStateToWorktreeByScope } from "./auto-worktree.js";
15
+ import { autoWorktreeBranch, fastForwardReusedMilestoneBranchIfSafe } from "./auto-worktree-branch-lifecycle.js";
16
+ import { syncGsdStateToWorktreeByScope } from "./auto-worktree-sync.js";
17
+ import { runWorktreePostCreateHook } from "./worktree-post-create-hook.js";
16
18
  import { nativeBranchExists } from "./native-git-bridge.js";
17
19
  import { readIntegrationBranch } from "./git-service.js";
18
20
  import { createWorkspace, scopeMilestone } from "./workspace.js";
@@ -1,4 +1,5 @@
1
- import { loadGlobalGSDPreferences, loadProjectGSDPreferences, } from "./preferences.js";
1
+ import { loadEffectiveGSDPreferences, loadGlobalGSDPreferences, loadProjectGSDPreferences, } from "./preferences.js";
2
+ import { crossAxisPreferenceWarnings } from "./preferences-validation.js";
2
3
  const notifiedPreferenceDiagnostics = new Set();
3
4
  export function collectPreferenceDiagnostics(basePath) {
4
5
  const diagnostics = [
@@ -14,6 +15,28 @@ export function collectPreferenceDiagnostics(basePath) {
14
15
  seen.add(signature);
15
16
  unique.push(diagnostic);
16
17
  }
18
+ const effective = loadEffectiveGSDPreferences(basePath);
19
+ if (effective) {
20
+ const existingMessages = new Set(unique.map((diagnostic) => diagnostic.message));
21
+ for (const message of crossAxisPreferenceWarnings(effective.preferences)) {
22
+ if (existingMessages.has(message))
23
+ continue;
24
+ const diagnostic = {
25
+ path: effective.path,
26
+ scope: effective.scope,
27
+ severity: "warning",
28
+ kind: "validation",
29
+ message,
30
+ sanitized: true,
31
+ };
32
+ const signature = preferenceDiagnosticSignature(diagnostic);
33
+ if (seen.has(signature))
34
+ continue;
35
+ seen.add(signature);
36
+ existingMessages.add(message);
37
+ unique.push(diagnostic);
38
+ }
39
+ }
17
40
  return unique;
18
41
  }
19
42
  export function formatPreferenceDiagnostic(diagnostic) {
@@ -74,10 +74,12 @@ function resolveWinningPhase(models, chain) {
74
74
  * - Legacy: `planning: claude-opus-4-6`
75
75
  * - Extended: `planning: { model: claude-opus-4-6, fallbacks: [glm-5, minimax-m2.5] }`
76
76
  */
77
- export function resolveModelWithFallbacksForUnit(unitType, basePath, availableModelIds, preferredModelId) {
78
- const loadOpts = availableModelIds !== undefined || preferredModelId !== undefined
79
- ? { availableModelIds, preferredModelId }
80
- : undefined;
77
+ export function resolveModelWithFallbacksForUnit(unitType, basePath, availableModelIds, preferredModelId, skipProfileDefaults = false) {
78
+ const loadOpts = {
79
+ ...(availableModelIds !== undefined ? { availableModelIds } : {}),
80
+ ...(preferredModelId !== undefined ? { preferredModelId } : {}),
81
+ ...(skipProfileDefaults ? { skipProfileDefaults: true } : {}),
82
+ };
81
83
  const prefs = loadEffectiveGSDPreferences(basePath, loadOpts);
82
84
  const chain = phaseChainForUnit(unitType);
83
85
  if (!chain)
@@ -86,6 +86,7 @@ export const KNOWN_PREFERENCE_KEYS = new Set([
86
86
  "min_request_interval_ms",
87
87
  "stale_commit_threshold_minutes",
88
88
  "context_management",
89
+ "tool_call_loop_guard",
89
90
  "experimental",
90
91
  "codebase",
91
92
  "slice_parallel",
@@ -34,6 +34,15 @@ const VALID_POST_UNIT_HOOK_ON_BLOCK_ACTIONS = new Set([
34
34
  "pause",
35
35
  ]);
36
36
  const VALID_GATE_EVALUATE_SLICE_GATES = new Set(getGateIdsForTurn("gate-evaluate"));
37
+ /** Cross-axis warnings that only apply to the effective (merged) preference shape. */
38
+ export function crossAxisPreferenceWarnings(preferences) {
39
+ if (preferences.mode === "team" && preferences.workspace?.mode === "parent") {
40
+ return [
41
+ "mode:team + workspace.mode:parent: team branch-push/PR resolves at the project root and will not push child repositories — see docs/dev/ADR-044",
42
+ ];
43
+ }
44
+ return [];
45
+ }
37
46
  export function validatePreferences(preferences) {
38
47
  const errors = [];
39
48
  const warnings = [];
@@ -489,8 +498,12 @@ export function validatePreferences(preferences) {
489
498
  }
490
499
  // ─── Remote Questions ───────────────────────────────────────────────
491
500
  if (preferences.remote_questions !== undefined) {
492
- if (preferences.remote_questions && typeof preferences.remote_questions === "object") {
493
- validated.remote_questions = preferences.remote_questions;
501
+ const remoteQuestions = preferences.remote_questions;
502
+ if (typeof remoteQuestions === "object" && remoteQuestions !== null) {
503
+ validated.remote_questions = remoteQuestions;
504
+ }
505
+ else if (remoteQuestions === false) {
506
+ // Explicit disable for a globally-configured remote questions channel.
494
507
  }
495
508
  else {
496
509
  errors.push("remote_questions must be an object");
@@ -788,6 +801,88 @@ export function validatePreferences(preferences) {
788
801
  errors.push("context_management must be an object");
789
802
  }
790
803
  }
804
+ // ─── Tool-call loop guard (#1198) ────────────────────────────────────────
805
+ if (preferences.tool_call_loop_guard !== undefined) {
806
+ if (typeof preferences.tool_call_loop_guard === "object" && preferences.tool_call_loop_guard !== null) {
807
+ const g = preferences.tool_call_loop_guard;
808
+ const validGuard = {};
809
+ if (g.enabled !== undefined) {
810
+ if (typeof g.enabled === "boolean")
811
+ validGuard.enabled = g.enabled;
812
+ else
813
+ errors.push("tool_call_loop_guard.enabled must be a boolean");
814
+ }
815
+ if (g.identical_args !== undefined) {
816
+ if (typeof g.identical_args === "object" && g.identical_args !== null) {
817
+ const ia = g.identical_args;
818
+ const validIa = {};
819
+ if (ia.enabled !== undefined) {
820
+ if (typeof ia.enabled === "boolean")
821
+ validIa.enabled = ia.enabled;
822
+ else
823
+ errors.push("tool_call_loop_guard.identical_args.enabled must be a boolean");
824
+ }
825
+ if (ia.max_consecutive_calls !== undefined) {
826
+ const n = ia.max_consecutive_calls;
827
+ if (typeof n === "number" && Number.isInteger(n) && n >= 1)
828
+ validIa.max_consecutive_calls = n;
829
+ else
830
+ errors.push("tool_call_loop_guard.identical_args.max_consecutive_calls must be an integer >= 1");
831
+ }
832
+ if (Object.keys(validIa).length > 0)
833
+ validGuard.identical_args = validIa;
834
+ }
835
+ else {
836
+ errors.push("tool_call_loop_guard.identical_args must be an object");
837
+ }
838
+ }
839
+ if (g.repeated_tool !== undefined) {
840
+ if (typeof g.repeated_tool === "object" && g.repeated_tool !== null) {
841
+ const rt = g.repeated_tool;
842
+ const validRt = {};
843
+ if (rt.enabled !== undefined) {
844
+ if (typeof rt.enabled === "boolean")
845
+ validRt.enabled = rt.enabled;
846
+ else
847
+ errors.push("tool_call_loop_guard.repeated_tool.enabled must be a boolean");
848
+ }
849
+ if (rt.default_cap !== undefined) {
850
+ const n = rt.default_cap;
851
+ if (typeof n === "number" && Number.isInteger(n) && n >= 1)
852
+ validRt.default_cap = n;
853
+ else
854
+ errors.push("tool_call_loop_guard.repeated_tool.default_cap must be an integer >= 1");
855
+ }
856
+ if (rt.repeatable_cap !== undefined) {
857
+ const n = rt.repeatable_cap;
858
+ if (typeof n === "number" && Number.isInteger(n) && n >= 1)
859
+ validRt.repeatable_cap = n;
860
+ else
861
+ errors.push("tool_call_loop_guard.repeated_tool.repeatable_cap must be an integer >= 1");
862
+ }
863
+ if (rt.exempt_tools !== undefined) {
864
+ if (Array.isArray(rt.exempt_tools) && rt.exempt_tools.every((t) => typeof t === "string")) {
865
+ validRt.exempt_tools = rt.exempt_tools;
866
+ }
867
+ else {
868
+ errors.push("tool_call_loop_guard.repeated_tool.exempt_tools must be an array of strings");
869
+ }
870
+ }
871
+ if (Object.keys(validRt).length > 0)
872
+ validGuard.repeated_tool = validRt;
873
+ }
874
+ else {
875
+ errors.push("tool_call_loop_guard.repeated_tool must be an object");
876
+ }
877
+ }
878
+ if (Object.keys(validGuard).length > 0) {
879
+ validated.tool_call_loop_guard = validGuard;
880
+ }
881
+ }
882
+ else {
883
+ errors.push("tool_call_loop_guard must be an object");
884
+ }
885
+ }
791
886
  // ─── Context Mode (gsd_exec sandbox) ────────────────────────────────────
792
887
  if (preferences.context_mode !== undefined) {
793
888
  if (typeof preferences.context_mode === "object" && preferences.context_mode !== null) {
@@ -1524,6 +1619,15 @@ export function validatePreferences(preferences) {
1524
1619
  else {
1525
1620
  errors.push("workspace must be an object");
1526
1621
  }
1622
+ // parent mode is behavioral: it must coordinate at least one declared
1623
+ // child repository. Without one it is indistinguishable from project
1624
+ // mode, so reject it explicitly rather than silently degrading.
1625
+ if (validated.workspace?.mode === "parent") {
1626
+ const childRepoCount = validated.workspace.repositories ? Object.keys(validated.workspace.repositories).length : 0;
1627
+ if (childRepoCount === 0) {
1628
+ errors.push('workspace.mode "parent" requires at least one repository under workspace.repositories');
1629
+ }
1630
+ }
1527
1631
  }
1528
1632
  // ─── Enhanced Verification ──────────────────────────────────────────────────
1529
1633
  if (preferences.enhanced_verification !== undefined) {
@@ -1596,5 +1700,6 @@ export function validatePreferences(preferences) {
1596
1700
  errors.push(`language must be a non-empty string up to 50 characters with no newlines (e.g. "Chinese", "de", "日本語")`);
1597
1701
  }
1598
1702
  }
1703
+ warnings.push(...crossAxisPreferenceWarnings(validated));
1599
1704
  return { preferences: validated, errors, warnings };
1600
1705
  }
@@ -19,7 +19,7 @@ import { logWarning } from "./workflow-logger.js";
19
19
  import { DEFAULT_TOKEN_PROFILE, resolveProfileDefaults as _resolveProfileDefaults, VALID_TOKEN_PROFILES, resolveDisabledModelProvidersFromPreferences, } from "./preferences-models.js";
20
20
  import { nativeHasCommittedHead, nativeIsRepo } from "./native-git-bridge.js";
21
21
  import { KNOWN_PREFERENCE_KEYS, MODE_DEFAULTS, formatSkillRef, } from "./preferences-types.js";
22
- import { validatePreferences } from "./preferences-validation.js";
22
+ import { crossAxisPreferenceWarnings, validatePreferences } from "./preferences-validation.js";
23
23
  import { gsdHome } from "./gsd-home.js";
24
24
  // ─── Re-exports: validation ─────────────────────────────────────────────────
25
25
  export { validatePreferences } from "./preferences-validation.js";
@@ -203,6 +203,7 @@ function effectivePreferencesCacheKey(basePath, opts) {
203
203
  project: projectPreferencesCandidatePaths(basePath).map(preferencesFileSignature),
204
204
  availableModelIds: opts?.availableModelIds ?? null,
205
205
  preferredModelId: opts?.preferredModelId ?? null,
206
+ skipProfileDefaults: opts?.skipProfileDefaults === true,
206
207
  });
207
208
  }
208
209
  function cloneLoadedPreferences(loaded) {
@@ -264,7 +265,7 @@ export function loadEffectiveGSDPreferences(basePath, opts) {
264
265
  else {
265
266
  profileForDefaults = DEFAULT_TOKEN_PROFILE;
266
267
  }
267
- if (profileForDefaults) {
268
+ if (profileForDefaults && !opts?.skipProfileDefaults) {
268
269
  const profileDefaults = _resolveProfileDefaults(profileForDefaults, opts?.availableModelIds, result.preferences.dynamic_routing, opts?.preferredModelId);
269
270
  const defaultsToApply = explicitProfile
270
271
  ? profileDefaults
@@ -282,9 +283,35 @@ export function loadEffectiveGSDPreferences(basePath, opts) {
282
283
  };
283
284
  }
284
285
  result = stripInheritedPlanningDepth(result, projectHasPlanningDepth);
286
+ result = appendCrossAxisPreferenceWarnings(result);
285
287
  cacheEffectivePreferences(cacheKey, result);
286
288
  return result;
287
289
  }
290
+ function appendCrossAxisPreferenceWarnings(loaded) {
291
+ const crossWarnings = crossAxisPreferenceWarnings(loaded.preferences);
292
+ const existingMessages = new Set([
293
+ ...(loaded.warnings ?? []),
294
+ ...(loaded.diagnostics ?? []).map((diagnostic) => diagnostic.message),
295
+ ]);
296
+ const newWarnings = crossWarnings.filter((message) => !existingMessages.has(message));
297
+ if (newWarnings.length === 0)
298
+ return loaded;
299
+ return {
300
+ ...loaded,
301
+ warnings: [...(loaded.warnings ?? []), ...newWarnings],
302
+ diagnostics: [
303
+ ...(loaded.diagnostics ?? []),
304
+ ...newWarnings.map((message) => ({
305
+ path: loaded.path,
306
+ scope: loaded.scope,
307
+ severity: "warning",
308
+ kind: "validation",
309
+ message,
310
+ sanitized: true,
311
+ })),
312
+ ],
313
+ };
314
+ }
288
315
  function withoutProfilePhaseDefaults(defaults) {
289
316
  if (defaults.phases === undefined)
290
317
  return defaults;
@@ -32,6 +32,8 @@ Before planning, validate roadmap assumptions against code and dependency summar
32
32
 
33
33
  If slice research is inlined, trust its architectural findings, but verify every concrete file path you place in task `inputs` or `expectedOutput` against the current tree or prior/same-task outputs. Explore enough code to confirm paths, boundaries, and verification. Executors later get only task plans, slice excerpt, and prior summaries, so put required paths, steps, inputs, and outputs in task plans.
34
34
 
35
+ {{repoRegistry}}
36
+
35
37
  {{executorContextConstraints}}
36
38
 
37
39
  ## Planning Rules
@@ -45,8 +47,8 @@ If slice research is inlined, trust its architectural findings, but verify every
45
47
  6. Include Threat Surface (Q3), Requirement Impact (Q4), proof level, observability, integration closure, Failure Modes (Q5), Load Profile (Q6), and Negative Tests (Q7) only where applicable.
46
48
  7. Right-size tasks. Simple slices can be one task; split only when context, ownership, or verification boundaries justify it.
47
49
  8. Task `verify` commands must be safe, simple commands. Do not use shell pipes, redirects, semicolons, backticks, command substitution, output trimming, or grep regex alternation with `|`. If multiple checks are needed, create a small test file and run it with `node --test` or a package test script, or use separate simple commands joined only with `&&`. For absence checks, verify a pattern does not exist with `! grep -q 'pattern' file` or `! rg -q 'pattern' file`; do not use `grep -c` or `rg -c` to assert zero matches because count commands exit 1 when they find zero matches, and the verification gate treats that as failure.
48
- 9. Each task persisted with `gsd_plan_task` needs the exact shape: `milestoneId`, `sliceId`, `taskId`, `title`, `description`, `estimate`, `files`, `verify`, `inputs`, `expectedOutput`, and optional `observabilityImpact`. `description` should contain the Why / Do / Done-when narrative. Any npm package name in a task description's install/add instructions (`npm install`, `yarn add`, `pnpm add`) or in `require('...')` or `import ... from '...'` code examples is subject to pre-execution registry validation; reference only packages that exist on the public npm registry, and remove or correct any package name that is not real. `files`, `inputs`, and `expectedOutput` must be JSON arrays of strings, even when there is only one path (for example, `"inputs": ["src/index.ts"]`, never `"inputs": "src/index.ts"`). Use paths relative to `{{workingDirectory}}`; do not put absolute paths to the original checkout or any directory outside `{{workingDirectory}}` in `files`, `inputs`, `expectedOutput`, or verification commands. **`expectedOutput` must only list files the task actually creates or overwrites on disk.** Do NOT include files the task merely reads, verifies, tests, or describes — those belong in `inputs`, `verify`, `description`, or slice success criteria. If a task is a pure verification or test task that produces no new files, `expectedOutput` must be `[]`; if it writes a test-result log or assertion output file, list only that concrete file path. A file that does not yet exist on disk and is needed as an `input` must be produced by an earlier task's `expectedOutput` — if no prior task creates it, add a task before this one that does. Never list GSD planning artifacts — anything under `.gsd/`, `.planning/`, or `.audits/`, or artifact names like `M001-CONTEXT.md` / `S01-PLAN.md` — in `inputs`, `files`, or `expectedOutput`: their content is preloaded as context, and they are written by workflow tools, not by tasks.
49
- 10. Persist incrementally through DB-backed tools. First call `gsd_plan_slice` with `milestoneId`, `sliceId`, `goal`, and optional `successCriteria`/`proofLevel`/`integrationClosure`/`observabilityImpact`; omit `tasks` for this metadata call. Then call `gsd_plan_task` once per task, using the task shape above. Each successful tool call saves progress and re-renders `{{outputPath}}` from DB. The DB-backed tools are the canonical write path. Do **not** rely on direct `PLAN.md` writes as the source of truth.
50
+ 9. Each task persisted with `gsd_plan_task` needs the exact shape: `milestoneId`, `sliceId`, `taskId`, `title`, `description`, `estimate`, `files`, `verify`, `inputs`, `expectedOutput`, and optional `observabilityImpact`. In a parent workspace (when a Declared Repositories block is present above), also set `targetRepositories` to the repository id(s) the task touches. `description` should contain the Why / Do / Done-when narrative. Any npm package name in a task description's install/add instructions (`npm install`, `yarn add`, `pnpm add`) or in `require('...')` or `import ... from '...'` code examples is subject to pre-execution registry validation; reference only packages that exist on the public npm registry, and remove or correct any package name that is not real. `files`, `inputs`, and `expectedOutput` must be JSON arrays of strings, even when there is only one path (for example, `"inputs": ["src/index.ts"]`, never `"inputs": "src/index.ts"`). Use paths relative to `{{workingDirectory}}`; do not put absolute paths to the original checkout or any directory outside `{{workingDirectory}}` in `files`, `inputs`, `expectedOutput`, or verification commands. **`expectedOutput` must only list files the task actually creates or overwrites on disk.** Do NOT include files the task merely reads, verifies, tests, or describes — those belong in `inputs`, `verify`, `description`, or slice success criteria. If a task is a pure verification or test task that produces no new files, `expectedOutput` must be `[]`; if it writes a test-result log or assertion output file, list only that concrete file path. A file that does not yet exist on disk and is needed as an `input` must be produced by an earlier task's `expectedOutput` — if no prior task creates it, add a task before this one that does. Never list GSD planning artifacts — anything under `.gsd/`, `.planning/`, or `.audits/`, or artifact names like `M001-CONTEXT.md` / `S01-PLAN.md` — in `inputs`, `files`, or `expectedOutput`: their content is preloaded as context, and they are written by workflow tools, not by tasks.
51
+ 10. Persist incrementally through DB-backed tools. First call `gsd_plan_slice` with `milestoneId`, `sliceId`, `goal`, and optional `successCriteria`/`proofLevel`/`integrationClosure`/`observabilityImpact` (and `targetRepositories` in a parent workspace, to set the slice-wide default); omit `tasks` for this metadata call. Then call `gsd_plan_task` once per task, using the task shape above. Each successful tool call saves progress and re-renders `{{outputPath}}` from DB. The DB-backed tools are the canonical write path. Do **not** rely on direct `PLAN.md` writes as the source of truth.
50
52
  11. Self-audit before finishing: goal/demo closure, requirement coverage, deliverable coverage audit (cross-check every file listed in CONTEXT.md `## Scope` / `### In Scope` against task `files` or `expectedOutput`), locked decisions, concrete paths, dependency order, wiring, scope size, proof truthfulness, feature completeness, and quality gates. Quality gates: non-trivial slices/tasks include specific Q3-Q7 coverage where applicable.
51
53
  12. If planning creates structural decisions, call `gsd_decision_save` for each; the tool persists the decision and regenerates `.gsd/DECISIONS.md`.
52
54
  13. {{commitInstruction}}
@@ -38,7 +38,7 @@ If a `GSD Skill Preferences` block appears below, treat it as durable guidance f
38
38
 
39
39
  ### Naming Convention
40
40
 
41
- Directories use bare IDs. Files use ID-SUFFIX format. Milestones: `M001/` or `M{seq}-{rand6}/` when `unique_milestone_ids: true`; files like `M001-CONTEXT.md`, `M001-ROADMAP.md`, `M001-RESEARCH.md`. Slices: `S01/` with `S01-PLAN.md`, `S01-RESEARCH.md`, `S01-SUMMARY.md`, `S01-UAT.md`. Tasks: `T01-PLAN.md`, `T01-SUMMARY.md`. Titles live inside content, not names.
41
+ GSD projects use a flat-phase layout. Phase directories are `{MM}-{slug}` where `{MM}` is the zero-padded phase number and `{slug}` is derived from the phase title (e.g. `47-real-time-runtime-hardening`). Phase-level files are `{MM}-SUFFIX.md` (e.g. `47-CONTEXT.md`, `47-RESEARCH.md`, `47-ROADMAP.md`, `47-VALIDATION.md`, `47-SUMMARY.md`). Slice/plan files live directly in the phase directory as `{MM}-{SS}-SUFFIX.md` (e.g. `47-01-PLAN.md`, `47-01-SUMMARY.md`, `47-01-UAT.md`). Task plan content lives inside the slice plan file (`{MM}-{SS}-PLAN.md`) as checkboxes; there is no `tasks/` subdirectory and no `tasks/T##-PLAN.md`. Titles live inside content, not names. Prefer GSD-provided layout-aware paths/resolvers over hardcoding artifact paths, since phase slugs are title-derived.
42
42
 
43
43
  ### Directory Structure
44
44
 
@@ -46,13 +46,13 @@ Directories use bare IDs. Files use ID-SUFFIX format. Milestones: `M001/` or `M{
46
46
  .gsd/
47
47
  PROJECT.md, REQUIREMENTS.md, DECISIONS.md, KNOWLEDGE.md, CODEBASE.md, OVERRIDES.md, QUEUE.md, STATE.md
48
48
  runtime/, activity/, worktrees/
49
- milestones/M001/
50
- M001-CONTEXT.md, M001-RESEARCH.md, M001-ROADMAP.md, M001-SUMMARY.md
51
- slices/S01/
52
- S01-CONTEXT.md, S01-RESEARCH.md, S01-PLAN.md, S01-SUMMARY.md, S01-UAT.md
53
- tasks/T01-PLAN.md, tasks/T01-SUMMARY.md
49
+ phases/{MM}-{slug}/
50
+ {MM}-CONTEXT.md, {MM}-RESEARCH.md, {MM}-ROADMAP.md, {MM}-VALIDATION.md, {MM}-SUMMARY.md
51
+ {MM}-{SS}-PLAN.md, {MM}-{SS}-SUMMARY.md, {MM}-{SS}-UAT.md
54
52
  ```
55
53
 
54
+ Task plan content is embedded in `{MM}-{SS}-PLAN.md`; do not expect `tasks/T##-PLAN.md`.
55
+
56
56
  `runtime/`, `activity/`, `worktrees/`, and `STATE.md` are system-managed. `PROJECT.md` is current state; `REQUIREMENTS.md` is the active capability contract; `DECISIONS.md` and `KNOWLEDGE.md` are append-only; `CODEBASE.md` is an auto-refreshed codebase map.
57
57
 
58
58
  ### Isolation Model
@@ -13,7 +13,7 @@ import { isAbsolute, join, relative, resolve } from "node:path";
13
13
  import { QUICK_BRANCH_RE } from "./branch-patterns.js";
14
14
  import { loadPrompt } from "./prompt-loader.js";
15
15
  import { gsdRoot } from "./paths.js";
16
- import { GitServiceImpl, runGit } from "./git-service.js";
16
+ import { GitServiceImpl, runGit, taskBranchArgs } from "./git-service.js";
17
17
  import { loadEffectiveGSDPreferences } from "./preferences.js";
18
18
  import { nativeBranchExists, nativeDetectMainBranch, nativeDiffNumstat } from "./native-git-bridge.js";
19
19
  import { nativeHasStagedChanges } from "./native-git-bridge.js";
@@ -317,6 +317,7 @@ export async function handleQuick(args, ctx, pi) {
317
317
  const git = new GitServiceImpl(basePath, gitPrefs);
318
318
  const branchName = `gsd/quick/${taskNum}-${slug}`;
319
319
  let originalBranch = git.getCurrentBranch();
320
+ let returnBranch = originalBranch;
320
321
  const { getIsolationMode } = await import("./preferences.js");
321
322
  const usesBranch = getIsolationMode() !== "none" && isGitOpsEnabled();
322
323
  let branchCreated = false;
@@ -331,7 +332,15 @@ export async function handleQuick(args, ctx, pi) {
331
332
  }
332
333
  }
333
334
  catch { /* nothing to commit — fine */ }
334
- runGit(basePath, ["checkout", "-b", branchName]);
335
+ const branchArgs = taskBranchArgs(basePath, branchName, current, git.getMainBranch());
336
+ const startPoint = branchArgs[3];
337
+ // When the quick branch is redirected off a stale task branch, the
338
+ // squash-merge on closeout must return to the same base — merging a
339
+ // base-branch-rooted quick branch back into the stale task branch
340
+ // would drag the base's newer history into it.
341
+ if (startPoint)
342
+ returnBranch = startPoint;
343
+ runGit(basePath, branchArgs);
335
344
  branchCreated = true;
336
345
  }
337
346
  }
@@ -345,7 +354,7 @@ export async function handleQuick(args, ctx, pi) {
345
354
  if (actualBranch === branchName && originalBranch !== branchName) {
346
355
  persistPendingReturn({
347
356
  basePath,
348
- originalBranch,
357
+ originalBranch: returnBranch,
349
358
  quickBranch: branchName,
350
359
  taskNum,
351
360
  slug,