@opengsd/gsd-pi 1.5.0 → 1.6.0-dev.aa7f94e8

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 (633) hide show
  1. package/README.md +10 -10
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/ask-user-questions.js +1 -1
  4. package/dist/resources/extensions/browser-tools/engine/managed-gsd-browser.js +114 -36
  5. package/dist/resources/extensions/gsd/activity-log.js +1 -1
  6. package/dist/resources/extensions/gsd/auto/closeout.js +97 -5
  7. package/dist/resources/extensions/gsd/auto/orchestrator.js +20 -13
  8. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +6 -3
  9. package/dist/resources/extensions/gsd/auto/unit-phase.js +5 -9
  10. package/dist/resources/extensions/gsd/auto-artifact-paths.js +14 -5
  11. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -7
  12. package/dist/resources/extensions/gsd/auto-dispatch.js +69 -17
  13. package/dist/resources/extensions/gsd/auto-model-selection.js +28 -1
  14. package/dist/resources/extensions/gsd/auto-post-unit.js +23 -6
  15. package/dist/resources/extensions/gsd/auto-prompts.js +49 -117
  16. package/dist/resources/extensions/gsd/auto-recovery.js +50 -6
  17. package/dist/resources/extensions/gsd/auto-start.js +57 -33
  18. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +12 -2
  19. package/dist/resources/extensions/gsd/auto-timers.js +9 -2
  20. package/dist/resources/extensions/gsd/auto-worktree-branch-lifecycle.js +189 -0
  21. package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +133 -0
  22. package/dist/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.js +35 -0
  23. package/dist/resources/extensions/gsd/auto-worktree-creation.js +130 -0
  24. package/dist/resources/extensions/gsd/auto-worktree-entry.js +118 -0
  25. package/dist/resources/extensions/gsd/auto-worktree-merge-already-merged.js +98 -0
  26. package/dist/resources/extensions/gsd/auto-worktree-merge-branch-head.js +52 -0
  27. package/dist/resources/extensions/gsd/auto-worktree-merge-cleanup.js +87 -0
  28. package/dist/resources/extensions/gsd/auto-worktree-merge-code-changes.js +46 -0
  29. package/dist/resources/extensions/gsd/auto-worktree-merge-db-ready.js +68 -0
  30. package/dist/resources/extensions/gsd/auto-worktree-merge-integration-branch.js +51 -0
  31. package/dist/resources/extensions/gsd/auto-worktree-merge-message.js +106 -0
  32. package/dist/resources/extensions/gsd/auto-worktree-merge-pre-teardown.js +64 -0
  33. package/dist/resources/extensions/gsd/auto-worktree-merge-stash.js +168 -0
  34. package/dist/resources/extensions/gsd/auto-worktree-merge.js +302 -0
  35. package/dist/resources/extensions/gsd/auto-worktree-milestone-shelter.js +119 -0
  36. package/dist/resources/extensions/gsd/auto-worktree-path-resolution.js +5 -0
  37. package/dist/resources/extensions/gsd/auto-worktree-path-utils.js +5 -0
  38. package/dist/resources/extensions/gsd/auto-worktree-resource-version.js +41 -0
  39. package/dist/resources/extensions/gsd/auto-worktree-runtime-cleanup.js +99 -0
  40. package/dist/resources/extensions/gsd/auto-worktree-session-registry.js +57 -0
  41. package/dist/resources/extensions/gsd/auto-worktree-sync.js +249 -0
  42. package/dist/resources/extensions/gsd/auto-worktree-teardown.js +120 -0
  43. package/dist/resources/extensions/gsd/auto-worktree.js +20 -2073
  44. package/dist/resources/extensions/gsd/auto.js +118 -34
  45. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -1
  46. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +20 -2
  47. package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
  48. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +185 -27
  49. package/dist/resources/extensions/gsd/browser-daemon-auto-prep.js +68 -2
  50. package/dist/resources/extensions/gsd/codebase-generator.js +7 -1
  51. package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
  52. package/dist/resources/extensions/gsd/commands-workflow-templates.js +3 -3
  53. package/dist/resources/extensions/gsd/compat/compat-marker.js +44 -0
  54. package/dist/resources/extensions/gsd/config-overlay.js +7 -2
  55. package/dist/resources/extensions/gsd/db/engine.js +33 -0
  56. package/dist/resources/extensions/gsd/db/queries.js +9 -9
  57. package/dist/resources/extensions/gsd/db/writers/cascades.js +20 -2
  58. package/dist/resources/extensions/gsd/db-adapter.js +30 -3
  59. package/dist/resources/extensions/gsd/docs/preferences-reference.md +3 -3
  60. package/dist/resources/extensions/gsd/doctor-engine-checks.js +93 -11
  61. package/dist/resources/extensions/gsd/flat-phase-migration.js +32 -3
  62. package/dist/resources/extensions/gsd/forensics.js +1 -1
  63. package/dist/resources/extensions/gsd/git-conflict-resolve.js +2 -2
  64. package/dist/resources/extensions/gsd/git-service.js +45 -0
  65. package/dist/resources/extensions/gsd/gsd-db.js +23 -11
  66. package/dist/resources/extensions/gsd/guided-flow.js +22 -17
  67. package/dist/resources/extensions/gsd/journal.js +1 -1
  68. package/dist/resources/extensions/gsd/markdown-renderer.js +34 -79
  69. package/dist/resources/extensions/gsd/md-importer.js +89 -23
  70. package/dist/resources/extensions/gsd/metrics.js +2 -2
  71. package/dist/resources/extensions/gsd/migration-auto-check.js +30 -3
  72. package/dist/resources/extensions/gsd/milestone-merge-transaction.js +11 -0
  73. package/dist/resources/extensions/gsd/milestone-settlement.js +1 -1
  74. package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
  75. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -1
  76. package/dist/resources/extensions/gsd/paths.js +87 -52
  77. package/dist/resources/extensions/gsd/post-unit-hooks.js +27 -0
  78. package/dist/resources/extensions/gsd/preferences-models.js +66 -15
  79. package/dist/resources/extensions/gsd/preferences-skills.js +10 -16
  80. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  81. package/dist/resources/extensions/gsd/preferences-validation.js +148 -10
  82. package/dist/resources/extensions/gsd/preferences.js +20 -0
  83. package/dist/resources/extensions/gsd/prompts/system.md +6 -6
  84. package/dist/resources/extensions/gsd/quick.js +12 -3
  85. package/dist/resources/extensions/gsd/reopen-reason.js +98 -0
  86. package/dist/resources/extensions/gsd/rule-registry.js +106 -10
  87. package/dist/resources/extensions/gsd/session-status-io.js +31 -0
  88. package/dist/resources/extensions/gsd/skill-discovery.js +36 -23
  89. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +2 -1
  90. package/dist/resources/extensions/gsd/state/derive/from-db.js +88 -153
  91. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +1 -10
  92. package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +3 -24
  93. package/dist/resources/extensions/gsd/state-reconciliation/index.js +10 -0
  94. package/dist/resources/extensions/gsd/tool-contract.js +14 -0
  95. package/dist/resources/extensions/gsd/tools/complete-milestone.js +3 -5
  96. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +16 -10
  97. package/dist/resources/extensions/gsd/tools/reopen-slice.js +5 -0
  98. package/dist/resources/extensions/gsd/tools/reopen-task.js +28 -5
  99. package/dist/resources/extensions/gsd/tools/validate-milestone.js +3 -8
  100. package/dist/resources/extensions/gsd/uat-dispatch.js +94 -0
  101. package/dist/resources/extensions/gsd/unit-registry.js +12 -2
  102. package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +1 -1
  103. package/dist/resources/extensions/gsd/uok/audit-toggle.js +31 -2
  104. package/dist/resources/extensions/gsd/uok/audit.js +3 -0
  105. package/dist/resources/extensions/gsd/uok/gate-runner.js +22 -30
  106. package/dist/resources/extensions/gsd/uok/gitops.js +18 -15
  107. package/dist/resources/extensions/gsd/uok/kernel.js +120 -46
  108. package/dist/resources/extensions/gsd/uok/model-policy.js +17 -14
  109. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -1
  110. package/dist/resources/extensions/gsd/workflow-event-ledger.js +1 -1
  111. package/dist/resources/extensions/gsd/workflow-logger.js +1 -1
  112. package/dist/resources/extensions/gsd/workflow-projections.js +9 -26
  113. package/dist/resources/extensions/gsd/workspace-git-preflight.js +2 -2
  114. package/dist/resources/extensions/gsd/workspace.js +5 -14
  115. package/dist/resources/extensions/gsd/worktree-command.js +1 -1
  116. package/dist/resources/extensions/gsd/worktree-lifecycle.js +14 -9
  117. package/dist/resources/extensions/gsd/worktree-reentry.js +2 -1
  118. package/dist/resources/extensions/shared/gsd-browser-cli.js +51 -5
  119. package/dist/resources/extensions/shared/interview-ui.js +62 -9
  120. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  121. package/dist/web/standalone/.next/BUILD_ID +1 -1
  122. package/dist/web/standalone/.next/app-path-routes-manifest.json +6 -6
  123. package/dist/web/standalone/.next/build-manifest.json +3 -3
  124. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  125. package/dist/web/standalone/.next/required-server-files.json +3 -3
  126. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  127. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  137. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  143. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  145. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  148. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  151. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  154. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  156. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  162. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  170. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  172. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  175. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  178. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  184. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  187. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  190. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  193. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  196. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  199. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
  202. package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  204. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  205. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  208. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  213. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  216. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  218. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  221. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  224. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  226. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  227. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  230. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  231. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  232. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  233. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  234. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  235. package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
  236. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  237. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  238. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  239. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  240. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  241. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  242. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  243. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  244. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  245. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  246. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  247. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  248. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  249. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  250. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  251. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  252. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  253. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  254. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  255. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  256. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  257. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  258. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  259. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  260. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  261. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  262. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  263. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  264. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  265. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  266. package/dist/web/standalone/.next/server/app/index.html +1 -1
  267. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  268. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  269. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  270. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  271. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  272. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  273. package/dist/web/standalone/.next/server/app/page.js +2 -2
  274. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  275. package/dist/web/standalone/.next/server/app-paths-manifest.json +6 -6
  276. package/dist/web/standalone/.next/server/chunks/{1128.js → 1991.js} +1 -1
  277. package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
  278. package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
  279. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  280. package/dist/web/standalone/.next/server/middleware.js +3 -3
  281. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  282. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  283. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  284. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +1 -0
  285. package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
  286. package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
  287. package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
  288. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
  289. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  290. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  291. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  292. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  293. package/dist/web/standalone/server.js +1 -1
  294. package/dist/worktree-cli-create.d.ts +10 -0
  295. package/dist/worktree-cli-create.js +11 -0
  296. package/dist/worktree-cli-format.d.ts +12 -0
  297. package/dist/worktree-cli-format.js +38 -0
  298. package/dist/worktree-cli-plan.d.ts +16 -0
  299. package/dist/worktree-cli-plan.js +19 -0
  300. package/dist/worktree-cli-session.d.ts +13 -0
  301. package/dist/worktree-cli-session.js +18 -0
  302. package/dist/worktree-cli-status.d.ts +35 -0
  303. package/dist/worktree-cli-status.js +54 -0
  304. package/dist/worktree-cli.d.ts +1 -16
  305. package/dist/worktree-cli.js +28 -122
  306. package/integrations/hermes/open_gsd_hermes/gsd_client.py +25 -36
  307. package/integrations/hermes/pyproject.toml +1 -1
  308. package/integrations/hermes/tests/test_gsd_client_timeout.py +4 -4
  309. package/package.json +6 -6
  310. package/packages/cloud-mcp-gateway/package.json +2 -2
  311. package/packages/contracts/package.json +1 -1
  312. package/packages/daemon/dist/cloud-cli.d.ts +1 -1
  313. package/packages/daemon/dist/cloud-cli.d.ts.map +1 -1
  314. package/packages/daemon/dist/cloud-cli.js +42 -2
  315. package/packages/daemon/dist/cloud-cli.js.map +1 -1
  316. package/packages/daemon/dist/cloud-config.d.ts +1 -0
  317. package/packages/daemon/dist/cloud-config.d.ts.map +1 -1
  318. package/packages/daemon/dist/cloud-config.js +1 -1
  319. package/packages/daemon/dist/cloud-config.js.map +1 -1
  320. package/packages/daemon/dist/device-flow.d.ts +24 -0
  321. package/packages/daemon/dist/device-flow.d.ts.map +1 -0
  322. package/packages/daemon/dist/device-flow.js +128 -0
  323. package/packages/daemon/dist/device-flow.js.map +1 -0
  324. package/packages/daemon/dist/device-flow.test.d.ts +2 -0
  325. package/packages/daemon/dist/device-flow.test.d.ts.map +1 -0
  326. package/packages/daemon/dist/device-flow.test.js +172 -0
  327. package/packages/daemon/dist/device-flow.test.js.map +1 -0
  328. package/packages/daemon/dist/orchestrator-agent.d.ts +21 -0
  329. package/packages/daemon/dist/orchestrator-agent.d.ts.map +1 -0
  330. package/packages/daemon/dist/orchestrator-agent.js +113 -0
  331. package/packages/daemon/dist/orchestrator-agent.js.map +1 -0
  332. package/packages/daemon/dist/orchestrator-tools.d.ts +12 -0
  333. package/packages/daemon/dist/orchestrator-tools.d.ts.map +1 -0
  334. package/packages/daemon/dist/orchestrator-tools.js +137 -0
  335. package/packages/daemon/dist/orchestrator-tools.js.map +1 -0
  336. package/packages/daemon/dist/orchestrator.d.ts +4 -56
  337. package/packages/daemon/dist/orchestrator.d.ts.map +1 -1
  338. package/packages/daemon/dist/orchestrator.js +13 -303
  339. package/packages/daemon/dist/orchestrator.js.map +1 -1
  340. package/packages/daemon/dist/orchestrator.test.js +11 -1
  341. package/packages/daemon/dist/orchestrator.test.js.map +1 -1
  342. package/packages/daemon/package.json +5 -5
  343. package/packages/gsd-agent-core/dist/export-html/template.js +53 -4
  344. package/packages/gsd-agent-core/package.json +5 -5
  345. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  346. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +3 -2
  347. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  348. package/packages/gsd-agent-modes/package.json +7 -7
  349. package/packages/gsd-cloud/README.md +34 -0
  350. package/packages/gsd-cloud/bin/gsd-cloud.js +27 -0
  351. package/packages/gsd-cloud/package.json +38 -0
  352. package/packages/mcp-server/package.json +4 -4
  353. package/packages/native/package.json +1 -1
  354. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  355. package/packages/pi-agent-core/dist/agent-loop.js +14 -9
  356. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  357. package/packages/pi-agent-core/package.json +1 -1
  358. package/packages/pi-ai/dist/index.d.ts +1 -0
  359. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  360. package/packages/pi-ai/dist/index.js +1 -0
  361. package/packages/pi-ai/dist/index.js.map +1 -1
  362. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  363. package/packages/pi-ai/dist/providers/transform-messages.js +7 -3
  364. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  365. package/packages/pi-ai/dist/tool-result-content.d.ts +3 -0
  366. package/packages/pi-ai/dist/tool-result-content.d.ts.map +1 -0
  367. package/packages/pi-ai/dist/tool-result-content.js +62 -0
  368. package/packages/pi-ai/dist/tool-result-content.js.map +1 -0
  369. package/packages/pi-ai/dist/types.d.ts +8 -20
  370. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  371. package/packages/pi-ai/dist/types.js.map +1 -1
  372. package/packages/pi-ai/package.json +1 -1
  373. package/packages/pi-coding-agent/dist/core/package-manager.d.ts +9 -0
  374. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  375. package/packages/pi-coding-agent/dist/core/package-manager.js +74 -53
  376. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  377. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +6 -0
  378. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  379. package/packages/pi-coding-agent/dist/core/resource-loader.js +30 -2
  380. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  381. package/packages/pi-coding-agent/dist/core/skill-directories.d.ts +66 -0
  382. package/packages/pi-coding-agent/dist/core/skill-directories.d.ts.map +1 -0
  383. package/packages/pi-coding-agent/dist/core/skill-directories.js +138 -0
  384. package/packages/pi-coding-agent/dist/core/skill-directories.js.map +1 -0
  385. package/packages/pi-coding-agent/dist/core/skills.d.ts +4 -1
  386. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  387. package/packages/pi-coding-agent/dist/core/skills.js +4 -1
  388. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  389. package/packages/pi-coding-agent/dist/index.d.ts +1 -0
  390. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  391. package/packages/pi-coding-agent/dist/index.js +1 -0
  392. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  393. package/packages/pi-coding-agent/package.json +7 -7
  394. package/packages/pi-tui/package.json +2 -2
  395. package/packages/rpc-client/package.json +2 -2
  396. package/pkg/dist/core/export-html/template.js +53 -4
  397. package/pkg/package.json +1 -1
  398. package/src/resources/extensions/ask-user-questions.ts +1 -1
  399. package/src/resources/extensions/browser-tools/engine/managed-gsd-browser.ts +146 -33
  400. package/src/resources/extensions/browser-tools/tests/gsd-browser-launch-config.test.mjs +44 -0
  401. package/src/resources/extensions/browser-tools/tests/managed-gsd-browser-tools.test.mjs +93 -0
  402. package/src/resources/extensions/gsd/activity-log.ts +1 -1
  403. package/src/resources/extensions/gsd/auto/closeout.ts +114 -7
  404. package/src/resources/extensions/gsd/auto/orchestrator.ts +21 -14
  405. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +6 -3
  406. package/src/resources/extensions/gsd/auto/unit-phase.ts +5 -9
  407. package/src/resources/extensions/gsd/auto-artifact-paths.ts +14 -4
  408. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +13 -7
  409. package/src/resources/extensions/gsd/auto-dispatch.ts +77 -16
  410. package/src/resources/extensions/gsd/auto-model-selection.ts +33 -1
  411. package/src/resources/extensions/gsd/auto-post-unit.ts +26 -5
  412. package/src/resources/extensions/gsd/auto-prompts.ts +73 -113
  413. package/src/resources/extensions/gsd/auto-recovery.ts +50 -6
  414. package/src/resources/extensions/gsd/auto-start.ts +62 -31
  415. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -2
  416. package/src/resources/extensions/gsd/auto-timers.ts +9 -2
  417. package/src/resources/extensions/gsd/auto-worktree-branch-lifecycle.ts +237 -0
  418. package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +166 -0
  419. package/src/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.ts +37 -0
  420. package/src/resources/extensions/gsd/auto-worktree-creation.ts +171 -0
  421. package/src/resources/extensions/gsd/auto-worktree-entry.ts +154 -0
  422. package/src/resources/extensions/gsd/auto-worktree-merge-already-merged.ts +161 -0
  423. package/src/resources/extensions/gsd/auto-worktree-merge-branch-head.ts +83 -0
  424. package/src/resources/extensions/gsd/auto-worktree-merge-cleanup.ts +132 -0
  425. package/src/resources/extensions/gsd/auto-worktree-merge-code-changes.ts +71 -0
  426. package/src/resources/extensions/gsd/auto-worktree-merge-db-ready.ts +112 -0
  427. package/src/resources/extensions/gsd/auto-worktree-merge-integration-branch.ts +99 -0
  428. package/src/resources/extensions/gsd/auto-worktree-merge-message.ts +166 -0
  429. package/src/resources/extensions/gsd/auto-worktree-merge-pre-teardown.ts +93 -0
  430. package/src/resources/extensions/gsd/auto-worktree-merge-stash.ts +213 -0
  431. package/src/resources/extensions/gsd/auto-worktree-merge.ts +391 -0
  432. package/src/resources/extensions/gsd/auto-worktree-milestone-shelter.ts +159 -0
  433. package/src/resources/extensions/gsd/auto-worktree-path-resolution.ts +6 -0
  434. package/src/resources/extensions/gsd/auto-worktree-path-utils.ts +10 -0
  435. package/src/resources/extensions/gsd/auto-worktree-resource-version.ts +44 -0
  436. package/src/resources/extensions/gsd/auto-worktree-runtime-cleanup.ts +119 -0
  437. package/src/resources/extensions/gsd/auto-worktree-session-registry.ts +71 -0
  438. package/src/resources/extensions/gsd/auto-worktree-sync.ts +370 -0
  439. package/src/resources/extensions/gsd/auto-worktree-teardown.ts +161 -0
  440. package/src/resources/extensions/gsd/auto-worktree.ts +69 -2429
  441. package/src/resources/extensions/gsd/auto.ts +126 -47
  442. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -1
  443. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +20 -2
  444. package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
  445. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +218 -27
  446. package/src/resources/extensions/gsd/browser-daemon-auto-prep.ts +77 -1
  447. package/src/resources/extensions/gsd/codebase-generator.ts +7 -1
  448. package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
  449. package/src/resources/extensions/gsd/commands-workflow-templates.ts +3 -3
  450. package/src/resources/extensions/gsd/compat/compat-marker.ts +47 -0
  451. package/src/resources/extensions/gsd/config-overlay.ts +7 -1
  452. package/src/resources/extensions/gsd/db/engine.ts +36 -0
  453. package/src/resources/extensions/gsd/db/queries.ts +9 -9
  454. package/src/resources/extensions/gsd/db/writers/cascades.ts +23 -1
  455. package/src/resources/extensions/gsd/db-adapter.ts +29 -3
  456. package/src/resources/extensions/gsd/docs/preferences-reference.md +3 -3
  457. package/src/resources/extensions/gsd/doctor-engine-checks.ts +109 -10
  458. package/src/resources/extensions/gsd/flat-phase-migration.ts +34 -3
  459. package/src/resources/extensions/gsd/forensics.ts +1 -1
  460. package/src/resources/extensions/gsd/git-conflict-resolve.ts +2 -2
  461. package/src/resources/extensions/gsd/git-service.ts +53 -0
  462. package/src/resources/extensions/gsd/gsd-db.ts +33 -11
  463. package/src/resources/extensions/gsd/guided-flow.ts +26 -18
  464. package/src/resources/extensions/gsd/journal.ts +1 -1
  465. package/src/resources/extensions/gsd/markdown-renderer.ts +52 -91
  466. package/src/resources/extensions/gsd/md-importer.ts +93 -22
  467. package/src/resources/extensions/gsd/metrics.ts +2 -2
  468. package/src/resources/extensions/gsd/migration-auto-check.ts +32 -3
  469. package/src/resources/extensions/gsd/milestone-merge-transaction.ts +15 -0
  470. package/src/resources/extensions/gsd/milestone-settlement.ts +1 -1
  471. package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
  472. package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -1
  473. package/src/resources/extensions/gsd/paths.ts +108 -51
  474. package/src/resources/extensions/gsd/post-unit-hooks.ts +32 -0
  475. package/src/resources/extensions/gsd/preferences-models.ts +74 -20
  476. package/src/resources/extensions/gsd/preferences-skills.ts +10 -16
  477. package/src/resources/extensions/gsd/preferences-types.ts +54 -1
  478. package/src/resources/extensions/gsd/preferences-validation.ts +146 -9
  479. package/src/resources/extensions/gsd/preferences.ts +20 -0
  480. package/src/resources/extensions/gsd/prompts/system.md +6 -6
  481. package/src/resources/extensions/gsd/quick.ts +11 -3
  482. package/src/resources/extensions/gsd/reopen-reason.ts +109 -0
  483. package/src/resources/extensions/gsd/rule-registry.ts +111 -9
  484. package/src/resources/extensions/gsd/session-status-io.ts +34 -0
  485. package/src/resources/extensions/gsd/skill-discovery.ts +47 -23
  486. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -1
  487. package/src/resources/extensions/gsd/state/derive/from-db.ts +201 -157
  488. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +1 -9
  489. package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +2 -22
  490. package/src/resources/extensions/gsd/state-reconciliation/index.ts +14 -0
  491. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +169 -1
  492. package/src/resources/extensions/gsd/tests/auto-loop-no-copy-artifacts.test.ts +2 -1
  493. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +41 -2
  494. package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +48 -1
  495. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +57 -0
  496. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +1 -1
  497. package/src/resources/extensions/gsd/tests/auto-start-project-milestone-reconcile.test.ts +29 -1
  498. package/src/resources/extensions/gsd/tests/auto-timeout-recovery-supervisor-inflight-guard.test.ts +159 -0
  499. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +2 -1
  500. package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +1 -1
  501. package/src/resources/extensions/gsd/tests/auto-worktree-merge-already-merged.test.ts +177 -0
  502. package/src/resources/extensions/gsd/tests/auto-worktree-merge-branch-head.test.ts +118 -0
  503. package/src/resources/extensions/gsd/tests/auto-worktree-merge-cleanup.test.ts +115 -0
  504. package/src/resources/extensions/gsd/tests/auto-worktree-merge-code-changes.test.ts +76 -0
  505. package/src/resources/extensions/gsd/tests/auto-worktree-merge-db-ready.test.ts +140 -0
  506. package/src/resources/extensions/gsd/tests/auto-worktree-merge-integration-branch.test.ts +123 -0
  507. package/src/resources/extensions/gsd/tests/auto-worktree-merge-message.test.ts +114 -0
  508. package/src/resources/extensions/gsd/tests/auto-worktree-merge-pre-teardown.test.ts +84 -0
  509. package/src/resources/extensions/gsd/tests/auto-worktree-merge-stash.test.ts +70 -0
  510. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-shelter.test.ts +52 -0
  511. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +6 -6
  512. package/src/resources/extensions/gsd/tests/auto-worktree-resource-version.test.ts +59 -0
  513. package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +3 -1
  514. package/src/resources/extensions/gsd/tests/browser-daemon-auto-prep.test.ts +26 -0
  515. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
  516. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +3 -1
  517. package/src/resources/extensions/gsd/tests/compat-marker.test.ts +85 -0
  518. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +45 -0
  519. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +1 -1
  520. package/src/resources/extensions/gsd/tests/db-adapter.test.ts +39 -0
  521. package/src/resources/extensions/gsd/tests/db-writable-probe.test.ts +66 -0
  522. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -0
  523. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +174 -0
  524. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +1 -1
  525. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +71 -1
  526. package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +46 -1
  527. package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +72 -32
  528. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +40 -0
  529. package/src/resources/extensions/gsd/tests/import-completion-lost-update.test.ts +196 -0
  530. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +4 -6
  531. package/src/resources/extensions/gsd/tests/integration/auto-stash-merge.test.ts +2 -1
  532. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +3 -3
  533. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +7 -8
  534. package/src/resources/extensions/gsd/tests/integration/feature-branch-lifecycle-integration.test.ts +2 -5
  535. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +76 -0
  536. package/src/resources/extensions/gsd/tests/integration/merge-cwd-restore.test.ts +1 -1
  537. package/src/resources/extensions/gsd/tests/integration/merge-preserve-worktree-on-preteardown-error.test.ts +1 -1
  538. package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +2 -1
  539. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +5 -7
  540. package/src/resources/extensions/gsd/tests/integration/paths.test.ts +88 -1
  541. package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +2 -4
  542. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -15
  543. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +1 -1
  544. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +1 -1
  545. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +1 -1
  546. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +91 -0
  547. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +2 -1
  548. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +439 -0
  549. package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +24 -0
  550. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +1 -1
  551. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -3
  552. package/src/resources/extensions/gsd/tests/parallel-worker-lock-contention.test.ts +1 -1
  553. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +0 -1
  554. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +269 -0
  555. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +8 -1
  556. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +1 -4
  557. package/src/resources/extensions/gsd/tests/preferences.test.ts +19 -0
  558. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +5 -0
  559. package/src/resources/extensions/gsd/tests/read-uat-gate-verdict.test.ts +54 -0
  560. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +49 -1
  561. package/src/resources/extensions/gsd/tests/reopen-reason.test.ts +117 -0
  562. package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +52 -0
  563. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +95 -1
  564. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -0
  565. package/src/resources/extensions/gsd/tests/sibling-model-fallbacks.test.ts +189 -0
  566. package/src/resources/extensions/gsd/tests/single-field-model-thinking.test.ts +156 -0
  567. package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +46 -0
  568. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +6 -1
  569. package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +3 -5
  570. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +32 -0
  571. package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +2 -1
  572. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +2 -1
  573. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +1 -1
  574. package/src/resources/extensions/gsd/tests/supervisor-model-swap-inflight-guard.test.ts +181 -0
  575. package/src/resources/extensions/gsd/tests/supervisor-model-swap-thinking-clamp.test.ts +122 -0
  576. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +1 -1
  577. package/src/resources/extensions/gsd/tests/system-flat-phase-layout.test.ts +33 -0
  578. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +4 -4
  579. package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +2 -1
  580. package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +4 -4
  581. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +196 -0
  582. package/src/resources/extensions/gsd/tests/uat-dispatch.test.ts +211 -0
  583. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +1 -1
  584. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +26 -1
  585. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +39 -0
  586. package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +226 -2
  587. package/src/resources/extensions/gsd/tests/uok-model-policy.test.ts +6 -0
  588. package/src/resources/extensions/gsd/tests/worker-resume-wait.test.ts +73 -0
  589. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +213 -2
  590. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -1
  591. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +1 -1
  592. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +1 -3
  593. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +1 -1
  594. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +1 -1
  595. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +1 -1
  596. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +1 -1
  597. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +2 -1
  598. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +5 -2
  599. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +1 -1
  600. package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +1 -1
  601. package/src/resources/extensions/gsd/tool-contract.ts +29 -0
  602. package/src/resources/extensions/gsd/tools/complete-milestone.ts +9 -5
  603. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +19 -8
  604. package/src/resources/extensions/gsd/tools/reopen-slice.ts +5 -0
  605. package/src/resources/extensions/gsd/tools/reopen-task.ts +28 -5
  606. package/src/resources/extensions/gsd/tools/validate-milestone.ts +13 -9
  607. package/src/resources/extensions/gsd/types.ts +23 -4
  608. package/src/resources/extensions/gsd/uat-dispatch.ts +176 -0
  609. package/src/resources/extensions/gsd/unit-registry.ts +16 -2
  610. package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +1 -1
  611. package/src/resources/extensions/gsd/uok/audit-toggle.ts +32 -2
  612. package/src/resources/extensions/gsd/uok/audit.ts +2 -0
  613. package/src/resources/extensions/gsd/uok/gate-runner.ts +26 -36
  614. package/src/resources/extensions/gsd/uok/gitops.ts +21 -18
  615. package/src/resources/extensions/gsd/uok/kernel.ts +169 -48
  616. package/src/resources/extensions/gsd/uok/model-policy.ts +20 -17
  617. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -1
  618. package/src/resources/extensions/gsd/workflow-event-ledger.ts +1 -1
  619. package/src/resources/extensions/gsd/workflow-logger.ts +1 -1
  620. package/src/resources/extensions/gsd/workflow-projections.ts +9 -24
  621. package/src/resources/extensions/gsd/workspace-git-preflight.ts +2 -2
  622. package/src/resources/extensions/gsd/workspace.ts +5 -21
  623. package/src/resources/extensions/gsd/worktree-command.ts +1 -1
  624. package/src/resources/extensions/gsd/worktree-lifecycle.ts +19 -15
  625. package/src/resources/extensions/gsd/worktree-reentry.ts +2 -1
  626. package/src/resources/extensions/shared/gsd-browser-cli.ts +64 -7
  627. package/src/resources/extensions/shared/interview-ui.ts +58 -11
  628. package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +32 -0
  629. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
  630. package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
  631. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
  632. /package/dist/web/standalone/.next/static/{bCg3aYrFN1DKZr2dqgE7L → XFuMvz26Zb_lrrR-8dvkd}/_buildManifest.js +0 -0
  633. /package/dist/web/standalone/.next/static/{bCg3aYrFN1DKZr2dqgE7L → XFuMvz26Zb_lrrR-8dvkd}/_ssgManifest.js +0 -0
@@ -23,7 +23,7 @@ import type {
23
23
  GSDModelPhaseKey,
24
24
  GSDThinkingConfig,
25
25
  ResolvedModelConfig,
26
- AutoSupervisorConfig,
26
+ ResolvedAutoSupervisorConfig,
27
27
  } from "./preferences-types.js";
28
28
  import { clearGSDPreferencesCache, loadEffectiveGSDPreferences, getGlobalGSDPreferencesPath } from "./preferences.js";
29
29
  import { getUnitPhaseChain } from "./unit-registry.js";
@@ -86,6 +86,40 @@ function resolveWinningPhase(
86
86
  return undefined;
87
87
  }
88
88
 
89
+ /**
90
+ * Normalize a single model field into a {@link ResolvedModelConfig}.
91
+ *
92
+ * Accepts either the legacy bare-string form or the extended object form
93
+ * (`{ model, provider?, fallbacks? }`). This is the shared normalization used
94
+ * for phase buckets so sibling single-model fields — `post_unit_hooks[].model`,
95
+ * `auto_supervisor.model`, and `reactive_execution.subagent_model` — honor
96
+ * `fallbacks[]` identically rather than accepting a bare string only (#1229).
97
+ *
98
+ * Returns undefined for an unset, blank, or model-less field.
99
+ */
100
+ export function normalizeModelFieldConfig(
101
+ field: string | GSDPhaseModelConfig | undefined,
102
+ ): ResolvedModelConfig | undefined {
103
+ if (!field) return undefined;
104
+ if (typeof field === "string") {
105
+ return field.trim() ? { primary: field, fallbacks: [] } : undefined;
106
+ }
107
+ if (!field.model) return undefined;
108
+ // When provider is explicitly set, prepend it to the model ID so the
109
+ // resolution code in auto.ts can do an explicit provider match.
110
+ const primary = field.provider && !field.model.includes("/")
111
+ ? `${field.provider}/${field.model}`
112
+ : field.model;
113
+ // Carry the per-field `thinking` sub-field through so the dispatch site can
114
+ // prefer it over the session/floor level, mirroring phase-inline thinking
115
+ // (#1269). `undefined` is preserved as absent so behavior is unchanged.
116
+ return {
117
+ primary,
118
+ fallbacks: field.fallbacks ?? [],
119
+ ...(field.thinking ? { thinking: field.thinking } : {}),
120
+ };
121
+ }
122
+
89
123
  /**
90
124
  * Resolve model and fallbacks for a given auto-mode unit type.
91
125
  * Returns the primary model and ordered fallbacks, or undefined if not configured.
@@ -93,6 +127,15 @@ function resolveWinningPhase(
93
127
  * Supports both legacy string format and extended object format:
94
128
  * - Legacy: `planning: claude-opus-4-6`
95
129
  * - Extended: `planning: { model: claude-opus-4-6, fallbacks: [glm-5, minimax-m2.5] }`
130
+ *
131
+ * Hook unit types (`hook/<name>`) resolve against the matching
132
+ * `post_unit_hooks[]` entry's `model` field so hook sessions honor the same
133
+ * `fallbacks[]` chain as phase buckets — the recovery path can then switch to
134
+ * a fallback provider instead of hard-failing (and potentially pausing) the
135
+ * run on a transient provider trip (#1229).
136
+ *
137
+ * The synthetic `supervisor` unit type resolves against `auto_supervisor.model`
138
+ * for supervisor interventions (wrap-up warnings, timeout recovery).
96
139
  */
97
140
  export function resolveModelWithFallbacksForUnit(
98
141
  unitType: string,
@@ -107,27 +150,26 @@ export function resolveModelWithFallbacksForUnit(
107
150
  ...(skipProfileDefaults ? { skipProfileDefaults: true } : {}),
108
151
  };
109
152
  const prefs = loadEffectiveGSDPreferences(basePath, loadOpts);
110
- const chain = phaseChainForUnit(unitType);
111
- if (!chain) return undefined;
112
- const winner = resolveWinningPhase(prefs?.preferences?.models as GSDModelConfigV2 | undefined, chain);
113
- if (!winner) return undefined;
114
- const phaseConfig = winner.config;
115
153
 
116
- // Normalize: string -> { model, fallbacks: [] }
117
- if (typeof phaseConfig === "string") {
118
- return { primary: phaseConfig, fallbacks: [] };
154
+ // Supervisor interventions resolve against `auto_supervisor.model` (#1229).
155
+ if (unitType === "supervisor") {
156
+ return normalizeModelFieldConfig(prefs?.preferences?.auto_supervisor?.model);
119
157
  }
120
158
 
121
- // When provider is explicitly set, prepend it to the model ID so the
122
- // resolution code in auto.ts can do an explicit provider match.
123
- const primary = phaseConfig.provider && !phaseConfig.model.includes("/")
124
- ? `${phaseConfig.provider}/${phaseConfig.model}`
125
- : phaseConfig.model;
159
+ // Hook sessions resolve against their own `post_unit_hooks[].model` field,
160
+ // which now shares the phase-bucket object form (#1229).
161
+ if (unitType.startsWith("hook/")) {
162
+ const hookName = unitType.slice("hook/".length);
163
+ const hooks = prefs?.preferences?.post_unit_hooks;
164
+ const hook = Array.isArray(hooks) ? hooks.find((h) => h.name === hookName) : undefined;
165
+ return normalizeModelFieldConfig(hook?.model);
166
+ }
126
167
 
127
- return {
128
- primary,
129
- fallbacks: phaseConfig.fallbacks ?? [],
130
- };
168
+ const chain = phaseChainForUnit(unitType);
169
+ if (!chain) return undefined;
170
+ const winner = resolveWinningPhase(prefs?.preferences?.models as GSDModelConfigV2 | undefined, chain);
171
+ if (!winner) return undefined;
172
+ return normalizeModelFieldConfig(winner.config);
131
173
  }
132
174
 
133
175
  /**
@@ -157,6 +199,14 @@ export function resolveThinkingLevelForUnit(
157
199
  basePath?: string,
158
200
  availableModelIds?: string[],
159
201
  ): GSDThinkingLevel | undefined {
202
+ // Single-field configs — `auto_supervisor.model` and `post_unit_hooks[].model`
203
+ // — carry their own inline `thinking` on the object model form and have no
204
+ // phase-bucket chain, so the walk below never covers them. Resolve their
205
+ // per-field level directly (#1269).
206
+ if (unitType === "supervisor" || unitType.startsWith("hook/")) {
207
+ return resolveModelWithFallbacksForUnit(unitType, basePath, availableModelIds)?.thinking;
208
+ }
209
+
160
210
  const loadOpts = availableModelIds !== undefined ? { availableModelIds } : undefined;
161
211
  const prefs = loadEffectiveGSDPreferences(basePath, loadOpts)?.preferences;
162
212
  if (!prefs) return undefined;
@@ -425,16 +475,20 @@ export function resolveDynamicRoutingConfig(): DynamicRoutingConfig {
425
475
  };
426
476
  }
427
477
 
428
- export function resolveAutoSupervisorConfig(): AutoSupervisorConfig {
478
+ export function resolveAutoSupervisorConfig(): ResolvedAutoSupervisorConfig {
429
479
  const prefs = loadEffectiveGSDPreferences();
430
480
  const configured = prefs?.preferences.auto_supervisor ?? {};
431
481
 
482
+ const modelConfig = normalizeModelFieldConfig(configured.model);
483
+
432
484
  return {
433
485
  soft_timeout_minutes: configured.soft_timeout_minutes ?? 20,
434
486
  idle_timeout_minutes: configured.idle_timeout_minutes ?? 10,
435
487
  hard_timeout_minutes: configured.hard_timeout_minutes ?? 30,
436
488
  stalled_tool_timeout_minutes: configured.stalled_tool_timeout_minutes ?? 5,
437
- ...(configured.model ? { model: configured.model } : {}),
489
+ ...(modelConfig
490
+ ? { model: modelConfig.primary, modelFallbacks: modelConfig.fallbacks }
491
+ : {}),
438
492
  };
439
493
  }
440
494
 
@@ -5,11 +5,11 @@
5
5
  * to absolute filesystem paths, plus skill discovery and staleness config.
6
6
  */
7
7
 
8
- import { existsSync, readdirSync } from "node:fs";
8
+ import { existsSync, readdirSync, statSync } from "node:fs";
9
9
  import { homedir } from "node:os";
10
10
  import { isAbsolute, join } from "node:path";
11
+ import { getSkillDirectories } from "@gsd/pi-coding-agent";
11
12
  import { gsdHome } from "./gsd-home.js";
12
- import { statSync } from "node:fs";
13
13
 
14
14
  import type {
15
15
  GSDPreferences,
@@ -25,26 +25,20 @@ export type { GSDSkillRule, SkillDiscoveryMode, SkillResolution, SkillResolution
25
25
  /**
26
26
  * Known skill directories for **preference reference resolution** (bare skill names).
27
27
  *
28
- * Search order (first match wins):
29
- * 1. ~/.gsd/agent/skills/ (GSD bundled)
30
- * 2. ~/.agents/skills/ (ecosystem global)
31
- * 3. .agents/skills/ (project ecosystem)
32
- * 4. ~/.claude/skills/ and .claude/skills/ (Claude Code compatibility)
28
+ * Sourced from the shared taxonomy (`@gsd/pi-coding-agent` `getSkillDirectories`)
29
+ * so preference resolution, mid-session discovery, and the PackageManager
30
+ * catalog all agree on which directories exist. The `method` is derived from
31
+ * each entry's scope.
33
32
  *
34
33
  * Note: the ResourceLoader catalog uses PackageManager precedence instead —
35
34
  * project `.gsd/skills` and `.agents/skills` can override bundled GSD skills
36
35
  * on name collision. See docs/dev/what-is-pi/09-the-customization-stack.md.
37
36
  */
38
37
  export function getSkillSearchDirs(cwd: string): Array<{ dir: string; method: SkillResolution["method"] }> {
39
- const dirs: Array<{ dir: string; method: SkillResolution["method"] }> = [
40
- { dir: join(gsdHome(), "agent", "skills"), method: "user-skill" },
41
- { dir: join(homedir(), ".agents", "skills"), method: "user-skill" },
42
- { dir: join(cwd, ".agents", "skills"), method: "project-skill" },
43
- // Claude Code official skill directories
44
- { dir: join(homedir(), ".claude", "skills"), method: "user-skill" },
45
- { dir: join(cwd, ".claude", "skills"), method: "project-skill" },
46
- ];
47
- return dirs;
38
+ return getSkillDirectories({ cwd, gsdHome: gsdHome() }).map((entry) => ({
39
+ dir: entry.path,
40
+ method: entry.scope === "project" ? "project-skill" : "user-skill",
41
+ }));
48
42
  }
49
43
 
50
44
  /**
@@ -29,6 +29,33 @@ export interface ContextManagementConfig {
29
29
  tool_result_max_chars?: number; // default: 800, range: 200-10000
30
30
  }
31
31
 
32
+ /**
33
+ * User-tunable thresholds for the tool-call loop guard (#1198). Keeps the two
34
+ * guards separately configurable: the identical-args guard (catches real
35
+ * infinite loops) and the repeated-tool-name cap (catches improvisation loops,
36
+ * more likely to false-positive on legitimate automation). All fields are
37
+ * optional; omitted fields fall back to the built-in defaults so existing
38
+ * installs keep their current behavior. Also overridable via GSD_TOOL_LOOP_*
39
+ * environment variables.
40
+ */
41
+ export interface ToolCallLoopGuardConfig {
42
+ /** Master switch for both guards. Default: true. */
43
+ enabled?: boolean;
44
+ /** Identical-args sliding-window guard. */
45
+ identical_args?: {
46
+ enabled?: boolean; // default: true
47
+ max_consecutive_calls?: number; // default: 4, min: 1
48
+ };
49
+ /** Per-tool-name cap, independent of args. */
50
+ repeated_tool?: {
51
+ enabled?: boolean; // default: true
52
+ default_cap?: number; // default: 6, min: 1
53
+ repeatable_cap?: number; // default: 15, min: 1
54
+ /** Additional tool names exempt from the per-tool cap (merged with built-in defaults). */
55
+ exempt_tools?: string[];
56
+ };
57
+ }
58
+
32
59
  /**
33
60
  * Opt-in tool-output sandboxing for sub-sessions. When enabled, the gsd_exec
34
61
  * MCP tool runs scripts in an isolated subprocess and returns only a short
@@ -139,6 +166,7 @@ export const KNOWN_PREFERENCE_KEYS = new Set<string>([
139
166
  "min_request_interval_ms",
140
167
  "stale_commit_threshold_minutes",
141
168
  "context_management",
169
+ "tool_call_loop_guard",
142
170
  "experimental",
143
171
  "codebase",
144
172
  "slice_parallel",
@@ -284,12 +312,24 @@ export interface GSDModelConfigV2 {
284
312
  export interface ResolvedModelConfig {
285
313
  primary: string;
286
314
  fallbacks: string[];
315
+ /**
316
+ * Per-field reasoning level carried from the object model form's `thinking`
317
+ * sub-field (e.g. `{ model, thinking: high }` on `post_unit_hooks[].model`,
318
+ * `auto_supervisor.model`, or `reactive_execution.subagent_model`). Applied at
319
+ * the dispatch site in preference to the session/floor level (#1269).
320
+ */
321
+ thinking?: GSDThinkingLevel;
287
322
  }
288
323
 
289
324
  export type SkillDiscoveryMode = "auto" | "suggest" | "off";
290
325
 
291
326
  export interface AutoSupervisorConfig {
292
- model?: string;
327
+ /**
328
+ * Model ID for the supervisor process. Accepts a bare model ID or the
329
+ * extended `{ model, provider?, fallbacks? }` object form for parity with
330
+ * phase buckets (#1229). Resolution normalizes it to the primary model ID.
331
+ */
332
+ model?: string | GSDPhaseModelConfig;
293
333
  soft_timeout_minutes?: number;
294
334
  idle_timeout_minutes?: number;
295
335
  hard_timeout_minutes?: number;
@@ -303,6 +343,17 @@ export interface AutoSupervisorConfig {
303
343
  stalled_tool_timeout_minutes?: number;
304
344
  }
305
345
 
346
+ /**
347
+ * The supervisor config after resolution by `resolveAutoSupervisorConfig`.
348
+ * Identical to {@link AutoSupervisorConfig} except `model` is always the
349
+ * normalized primary model ID string and `modelFallbacks` carries the ordered
350
+ * fallback chain from the object form accepted in preferences (#1229).
351
+ */
352
+ export type ResolvedAutoSupervisorConfig = Omit<AutoSupervisorConfig, "model"> & {
353
+ model?: string;
354
+ modelFallbacks?: string[];
355
+ };
356
+
306
357
  export interface RemoteQuestionsConfig {
307
358
  channel: "slack" | "discord" | "telegram";
308
359
  channel_id: string | number;
@@ -440,6 +491,8 @@ export interface GSDPreferences {
440
491
  */
441
492
  context_window_override?: number;
442
493
  context_management?: ContextManagementConfig;
494
+ /** User-tunable tool-call loop guard thresholds (#1198). */
495
+ tool_call_loop_guard?: ToolCallLoopGuardConfig;
443
496
  /**
444
497
  * Tool-output sandboxing via gsd_exec. Keeps sub-session context windows
445
498
  * clean by running scripts in a subprocess and only surfacing a short
@@ -22,6 +22,7 @@ import {
22
22
  SKILL_ACTIONS,
23
23
  type WorkflowMode,
24
24
  type GSDPreferences,
25
+ type GSDPhaseModelConfig,
25
26
  type GSDSkillRule,
26
27
  type GSDThinkingLevel,
27
28
  } from "./preferences-types.js";
@@ -41,6 +42,62 @@ const VALID_UOK_TURN_ACTIONS = new Set<"commit" | "snapshot" | "status-only">([
41
42
  "snapshot",
42
43
  "status-only",
43
44
  ]);
45
+ /**
46
+ * Sanitize a single model field that accepts either a bare model ID or the
47
+ * extended `{ model, provider?, fallbacks? }` object form used by phase buckets
48
+ * (#1229). Returns the sanitized value, or undefined when unset/invalid (in
49
+ * which case an error describing `label` is pushed onto `errors`).
50
+ */
51
+ function sanitizeModelField(
52
+ raw: unknown,
53
+ label: string,
54
+ errors: string[],
55
+ warnings?: string[],
56
+ ): string | GSDPhaseModelConfig | undefined {
57
+ if (raw === undefined) return undefined;
58
+ if (typeof raw === "string") {
59
+ const trimmed = raw.trim();
60
+ if (!trimmed) {
61
+ errors.push(`${label} must not be an empty string`);
62
+ return undefined;
63
+ }
64
+ return trimmed;
65
+ }
66
+ if (raw && typeof raw === "object") {
67
+ const obj = raw as Record<string, unknown>;
68
+ const model = typeof obj.model === "string" ? obj.model.trim() : "";
69
+ if (!model) {
70
+ errors.push(`${label} object form requires a non-empty "model"`);
71
+ return undefined;
72
+ }
73
+ const sanitized: GSDPhaseModelConfig = { model };
74
+ if (typeof obj.provider === "string" && obj.provider.trim()) {
75
+ sanitized.provider = obj.provider.trim();
76
+ }
77
+ if (obj.fallbacks !== undefined) {
78
+ const fallbacks = normalizeStringArray(obj.fallbacks);
79
+ if (fallbacks.length > 0) sanitized.fallbacks = fallbacks;
80
+ }
81
+ // Preserve the object form's `thinking` sub-field so the dispatch site can
82
+ // pin the hook/supervisor/subagent reasoning level (#1269). An illegal level
83
+ // is warned-and-stripped, mirroring inline per-phase thinking, so a typo can't
84
+ // reach the resolver and be treated as explicit configuration.
85
+ if (obj.thinking !== undefined) {
86
+ if (VALID_THINKING_LEVELS.has(obj.thinking as GSDThinkingLevel)) {
87
+ sanitized.thinking = obj.thinking as GSDThinkingLevel;
88
+ } else {
89
+ warnings?.push(
90
+ `${label} thinking "${String(obj.thinking)}" is not a valid thinking level ` +
91
+ `(off, minimal, low, medium, high, xhigh) — ignored`,
92
+ );
93
+ }
94
+ }
95
+ return sanitized;
96
+ }
97
+ errors.push(`${label} must be a string or an object with a "model" field`);
98
+ return undefined;
99
+ }
100
+
44
101
  const VALID_POST_UNIT_HOOK_CRITICALITIES = new Set(["advisory", "blocking"]);
45
102
  const VALID_POST_UNIT_HOOK_ON_BLOCK_ACTIONS = new Set([
46
103
  "retry-unit",
@@ -476,7 +533,15 @@ export function validatePreferences(preferences: GSDPreferences): {
476
533
  // ─── Auto Supervisor ────────────────────────────────────────────────
477
534
  if (preferences.auto_supervisor !== undefined) {
478
535
  if (preferences.auto_supervisor && typeof preferences.auto_supervisor === "object") {
479
- validated.auto_supervisor = preferences.auto_supervisor;
536
+ // Validate `model` through the shared sanitizer so the
537
+ // `{ model, provider?, fallbacks? }` object form is rejected on the same
538
+ // terms as its post_unit_hooks / reactive_execution siblings (#1229).
539
+ // Other supervisor fields pass through unchanged.
540
+ const supervisor = { ...preferences.auto_supervisor };
541
+ if (supervisor.model !== undefined) {
542
+ supervisor.model = sanitizeModelField(supervisor.model, "auto_supervisor.model", errors, warnings);
543
+ }
544
+ validated.auto_supervisor = supervisor;
480
545
  } else {
481
546
  errors.push("auto_supervisor must be an object");
482
547
  }
@@ -568,8 +633,9 @@ export function validatePreferences(preferences: GSDPreferences): {
568
633
  const mc = typeof hook.max_cycles === "number" ? hook.max_cycles : Number(hook.max_cycles);
569
634
  validHook.max_cycles = Number.isFinite(mc) ? Math.max(1, Math.min(10, Math.round(mc))) : 1;
570
635
  }
571
- if (typeof hook.model === "string" && hook.model.trim()) {
572
- validHook.model = hook.model.trim();
636
+ const hookModel = sanitizeModelField(hook.model, `post_unit_hooks "${name}" model`, errors, warnings);
637
+ if (hookModel !== undefined) {
638
+ validHook.model = hookModel;
573
639
  }
574
640
  if (typeof hook.artifact === "string" && hook.artifact.trim()) {
575
641
  validHook.artifact = hook.artifact.trim();
@@ -794,6 +860,75 @@ export function validatePreferences(preferences: GSDPreferences): {
794
860
  }
795
861
  }
796
862
 
863
+ // ─── Tool-call loop guard (#1198) ────────────────────────────────────────
864
+ if (preferences.tool_call_loop_guard !== undefined) {
865
+ if (typeof preferences.tool_call_loop_guard === "object" && preferences.tool_call_loop_guard !== null) {
866
+ const g = preferences.tool_call_loop_guard as unknown as Record<string, unknown>;
867
+ const validGuard: Record<string, unknown> = {};
868
+
869
+ if (g.enabled !== undefined) {
870
+ if (typeof g.enabled === "boolean") validGuard.enabled = g.enabled;
871
+ else errors.push("tool_call_loop_guard.enabled must be a boolean");
872
+ }
873
+
874
+ if (g.identical_args !== undefined) {
875
+ if (typeof g.identical_args === "object" && g.identical_args !== null) {
876
+ const ia = g.identical_args as Record<string, unknown>;
877
+ const validIa: Record<string, unknown> = {};
878
+ if (ia.enabled !== undefined) {
879
+ if (typeof ia.enabled === "boolean") validIa.enabled = ia.enabled;
880
+ else errors.push("tool_call_loop_guard.identical_args.enabled must be a boolean");
881
+ }
882
+ if (ia.max_consecutive_calls !== undefined) {
883
+ const n = ia.max_consecutive_calls;
884
+ if (typeof n === "number" && Number.isInteger(n) && n >= 1) validIa.max_consecutive_calls = n;
885
+ else errors.push("tool_call_loop_guard.identical_args.max_consecutive_calls must be an integer >= 1");
886
+ }
887
+ if (Object.keys(validIa).length > 0) validGuard.identical_args = validIa;
888
+ } else {
889
+ errors.push("tool_call_loop_guard.identical_args must be an object");
890
+ }
891
+ }
892
+
893
+ if (g.repeated_tool !== undefined) {
894
+ if (typeof g.repeated_tool === "object" && g.repeated_tool !== null) {
895
+ const rt = g.repeated_tool as Record<string, unknown>;
896
+ const validRt: Record<string, unknown> = {};
897
+ if (rt.enabled !== undefined) {
898
+ if (typeof rt.enabled === "boolean") validRt.enabled = rt.enabled;
899
+ else errors.push("tool_call_loop_guard.repeated_tool.enabled must be a boolean");
900
+ }
901
+ if (rt.default_cap !== undefined) {
902
+ const n = rt.default_cap;
903
+ if (typeof n === "number" && Number.isInteger(n) && n >= 1) validRt.default_cap = n;
904
+ else errors.push("tool_call_loop_guard.repeated_tool.default_cap must be an integer >= 1");
905
+ }
906
+ if (rt.repeatable_cap !== undefined) {
907
+ const n = rt.repeatable_cap;
908
+ if (typeof n === "number" && Number.isInteger(n) && n >= 1) validRt.repeatable_cap = n;
909
+ else errors.push("tool_call_loop_guard.repeated_tool.repeatable_cap must be an integer >= 1");
910
+ }
911
+ if (rt.exempt_tools !== undefined) {
912
+ if (Array.isArray(rt.exempt_tools) && rt.exempt_tools.every((t) => typeof t === "string")) {
913
+ validRt.exempt_tools = rt.exempt_tools;
914
+ } else {
915
+ errors.push("tool_call_loop_guard.repeated_tool.exempt_tools must be an array of strings");
916
+ }
917
+ }
918
+ if (Object.keys(validRt).length > 0) validGuard.repeated_tool = validRt;
919
+ } else {
920
+ errors.push("tool_call_loop_guard.repeated_tool must be an object");
921
+ }
922
+ }
923
+
924
+ if (Object.keys(validGuard).length > 0) {
925
+ validated.tool_call_loop_guard = validGuard as any;
926
+ }
927
+ } else {
928
+ errors.push("tool_call_loop_guard must be an object");
929
+ }
930
+ }
931
+
797
932
  // ─── Context Mode (gsd_exec sandbox) ────────────────────────────────────
798
933
  if (preferences.context_mode !== undefined) {
799
934
  if (typeof preferences.context_mode === "object" && preferences.context_mode !== null) {
@@ -952,12 +1087,14 @@ export function validatePreferences(preferences: GSDPreferences): {
952
1087
  }
953
1088
  }
954
1089
 
955
- if (re.subagent_model !== undefined) {
956
- if (typeof re.subagent_model === "string" && re.subagent_model.length > 0) {
957
- validRe.subagent_model = re.subagent_model;
958
- } else {
959
- errors.push("reactive_execution.subagent_model must be a non-empty string");
960
- }
1090
+ const subagentModel = sanitizeModelField(
1091
+ re.subagent_model,
1092
+ "reactive_execution.subagent_model",
1093
+ errors,
1094
+ warnings,
1095
+ );
1096
+ if (subagentModel !== undefined) {
1097
+ validRe.subagent_model = subagentModel;
961
1098
  }
962
1099
 
963
1100
  const knownReKeys = new Set(["enabled", "max_parallel", "isolation_mode", "subagent_model"]);
@@ -1033,6 +1033,26 @@ export function renderPreferencesForSystemPrompt(
1033
1033
  return lines.join("\n");
1034
1034
  }
1035
1035
 
1036
+ /**
1037
+ * Render a compact response-language directive for injection into dispatched
1038
+ * prompt *content* (discuss/QA and auto-execution unit prompts).
1039
+ *
1040
+ * The main session's system prompt already carries the full GSD Skill
1041
+ * Preferences block (including language) via `before_agent_start`, but
1042
+ * discuss/QA turns and auto-execution units are dispatched as separate
1043
+ * turns/sessions whose prompts are assembled here — without that block — so the
1044
+ * configured language never reaches them (#1210). Injecting this directive into
1045
+ * the dispatched prompt content makes the `language` preference effective across
1046
+ * both guided and auto workflows.
1047
+ *
1048
+ * Returns "" when no language is configured.
1049
+ */
1050
+ export function renderLanguageDirectiveForPrompt(preferences: GSDPreferences | undefined): string {
1051
+ if (!preferences?.language) return "";
1052
+ const safeLang = preferences.language.replace(/[\r\n]/g, " ").slice(0, 50);
1053
+ return `## Response Language\n\nAlways respond in ${safeLang} — questions, explanations, and summaries.`;
1054
+ }
1055
+
1036
1056
  // ─── Hook Resolution ──────────────────────────────────────────────────────────
1037
1057
 
1038
1058
  /**
@@ -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
@@ -15,7 +15,7 @@ import { isAbsolute, join, relative, resolve } from "node:path";
15
15
  import { QUICK_BRANCH_RE } from "./branch-patterns.js";
16
16
  import { loadPrompt } from "./prompt-loader.js";
17
17
  import { gsdRoot } from "./paths.js";
18
- import { GitServiceImpl, runGit } from "./git-service.js";
18
+ import { GitServiceImpl, runGit, taskBranchArgs } from "./git-service.js";
19
19
  import { loadEffectiveGSDPreferences } from "./preferences.js";
20
20
  import { nativeBranchExists, nativeDetectMainBranch, nativeDiffNumstat } from "./native-git-bridge.js";
21
21
  import { nativeHasStagedChanges } from "./native-git-bridge.js";
@@ -365,6 +365,7 @@ export async function handleQuick(
365
365
  const git = new GitServiceImpl(basePath, gitPrefs);
366
366
  const branchName = `gsd/quick/${taskNum}-${slug}`;
367
367
  let originalBranch = git.getCurrentBranch();
368
+ let returnBranch = originalBranch;
368
369
 
369
370
  const { getIsolationMode } = await import("./preferences.js");
370
371
  const usesBranch = getIsolationMode() !== "none" && isGitOpsEnabled();
@@ -381,7 +382,14 @@ export async function handleQuick(
381
382
  }
382
383
  } catch { /* nothing to commit — fine */ }
383
384
 
384
- runGit(basePath, ["checkout", "-b", branchName]);
385
+ const branchArgs = taskBranchArgs(basePath, branchName, current, git.getMainBranch());
386
+ const startPoint = branchArgs[3];
387
+ // When the quick branch is redirected off a stale task branch, the
388
+ // squash-merge on closeout must return to the same base — merging a
389
+ // base-branch-rooted quick branch back into the stale task branch
390
+ // would drag the base's newer history into it.
391
+ if (startPoint) returnBranch = startPoint;
392
+ runGit(basePath, branchArgs);
385
393
  branchCreated = true;
386
394
  }
387
395
  } catch (err) {
@@ -395,7 +403,7 @@ export async function handleQuick(
395
403
  if (actualBranch === branchName && originalBranch !== branchName) {
396
404
  persistPendingReturn({
397
405
  basePath,
398
- originalBranch,
406
+ originalBranch: returnBranch,
399
407
  quickBranch: branchName,
400
408
  taskNum,
401
409
  slug,