@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
@@ -30,9 +30,10 @@ import { playNotificationBell, sendDesktopNotification } from "./notifications.j
30
30
  import { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, HARD_CONTEXT_REROOT_THRESHOLD_PERCENT, resolveCompactionThresholdPercent, shouldRerootStepSessionForContext, shouldWarnStepSessionForContext, } from "./auto-budget.js";
31
31
  import { markToolStart as _markToolStart, markToolEnd as _markToolEnd, getOldestInFlightToolAgeMs as _getOldestInFlightToolAgeMs, clearInFlightTools, isToolInvocationError, isQueuedUserMessageSkip, isDeterministicPolicyError, } from "./auto-tool-tracking.js";
32
32
  import { closeoutUnit } from "./auto-unit-closeout.js";
33
- import { selectAndApplyModel, resolveModelId, clearToolBaseline } from "./auto-model-selection.js";
33
+ import { selectAndApplyModel, resolveModelId, clearToolBaseline, isModelUnavailable, applyThinkingLevelForModel } from "./auto-model-selection.js";
34
+ import { resolveModelWithFallbacksForUnit } from "./preferences-models.js";
34
35
  import { resetRoutingHistory, recordOutcome } from "./routing-history.js";
35
- import { resetHookState, runPreDispatchHooks, restoreHookState, clearPersistedHookState, } from "./post-unit-hooks.js";
36
+ import { resetHookState, runPreDispatchHooks, restoreHookState, reconcileRestoredHookDispatch, clearPersistedHookState, } from "./post-unit-hooks.js";
36
37
  import { runGSDDoctor, rebuildState } from "./doctor.js";
37
38
  import { preDispatchHealthGate, resetProactiveHealing, setLevelChangeCallback, } from "./doctor-proactive.js";
38
39
  import { clearSkillSnapshot } from "./skill-discovery.js";
@@ -51,10 +52,17 @@ import { atomicWriteSync } from "./atomic-write.js";
51
52
  import { captureIntegrationBranch, detectWorktreeName, getCurrentBranch, getMainBranch, setActiveMilestoneId, } from "./worktree.js";
52
53
  import { GitServiceImpl } from "./git-service.js";
53
54
  import { getPriorSliceCompletionBlocker } from "./dispatch-guard.js";
54
- import { createAutoWorktree, teardownAutoWorktree, isInAutoWorktree, getAutoWorktreePath, mergeMilestoneToMain, autoWorktreeBranch, checkResourcesStale, escapeStaleWorktree, } from "./auto-worktree.js";
55
+ import { autoWorktreeBranch } from "./auto-worktree-branch-lifecycle.js";
56
+ import { createAutoWorktree } from "./auto-worktree-creation.js";
57
+ import { isInAutoWorktree } from "./auto-worktree-entry.js";
58
+ import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
59
+ import { checkResourcesStale } from "./auto-worktree-resource-version.js";
60
+ import { escapeStaleWorktree } from "./auto-worktree-runtime-cleanup.js";
61
+ import { teardownWarmedBrowserDaemons } from "./browser-daemon-auto-prep.js";
62
+ import { teardownAutoWorktree } from "./auto-worktree-teardown.js";
55
63
  import { pruneQueueOrder } from "./queue-order.js";
56
64
  import { startCommandPolling as _startCommandPolling, isRemoteConfigured } from "../remote-questions/manager.js";
57
- import { createMilestoneMergeTransaction } from "./milestone-merge-transaction.js";
65
+ import { createDefaultMilestoneMergeTransaction } from "./milestone-merge-transaction.js";
58
66
  import { debugLog, isDebugEnabled, writeDebugSummary } from "./debug-logger.js";
59
67
  import { reconcileMergeState, verifyExpectedArtifact, } from "./auto-recovery.js";
60
68
  import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.js";
@@ -326,11 +334,24 @@ function withDetachedAutoKeepalive(run) {
326
334
  }
327
335
  export const _withDetachedAutoKeepaliveForTest = withDetachedAutoKeepalive;
328
336
  export function startAutoDetached(ctx, pi, base, verboseMode, options) {
329
- void withDetachedAutoKeepalive(startAuto(ctx, pi, base, verboseMode, options)).catch((err) => {
337
+ void withDetachedAutoKeepalive(startAuto(ctx, pi, base, verboseMode, options)).catch(async (err) => {
330
338
  const message = getErrorMessage(err);
331
339
  ctx.ui.notify(`Auto-start failed: ${message}`, "error");
332
340
  logWarning("engine", `auto start error: ${message}`, { file: "auto.ts" });
333
341
  debugLog("auto-start-failed", { error: message });
342
+ // Backstop cleanup (#1235): if startAuto threw after auto-mode was activated
343
+ // (e.g. an exception during bootstrap, before the loop's try/finally could
344
+ // run cleanupAfterLoopExit), s.active and the on-disk auto lock leak, so the
345
+ // re-entry guard silently no-ops every later /gsd auto until restart. Clear
346
+ // the leaked activation here so a failed start is always recoverable.
347
+ if (s.active) {
348
+ try {
349
+ await cleanupAfterLoopExit(ctx);
350
+ }
351
+ catch (cleanupErr) {
352
+ logWarning("engine", `auto start cleanup failed: ${cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr)}`, { file: "auto.ts" });
353
+ }
354
+ }
334
355
  });
335
356
  }
336
357
  /** Returns true if the project is configured for `isolation:worktree` mode. */
@@ -983,6 +1004,17 @@ export async function cleanupAfterLoopExit(ctx) {
983
1004
  /* best-effort — mirror stopAuto cleanup */
984
1005
  logWarning("session", `lock cleanup failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
985
1006
  }
1007
+ // Symmetric teardown for the browser-UAT warm-up preflight (#1259): stop any
1008
+ // gsd-browser daemon this session started so the Chrome process does not
1009
+ // linger after the loop exits. Re-warms on the next browser-backed run-uat.
1010
+ try {
1011
+ for (const { projectRoot, error } of teardownWarmedBrowserDaemons()) {
1012
+ logWarning("session", `gsd-browser daemon stop failed for ${projectRoot}: ${error}`, { file: "auto.ts" });
1013
+ }
1014
+ }
1015
+ catch (err) {
1016
+ logWarning("session", `browser daemon teardown failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
1017
+ }
986
1018
  // A transient provider-error pause intentionally leaves the paused badge
987
1019
  // visible so the user still has a resumable auto-mode signal on screen.
988
1020
  if (!s.paused) {
@@ -1746,7 +1778,7 @@ export function buildWorktreeLifecycleDeps() {
1746
1778
  return new GitServiceImpl(basePath, gitConfig);
1747
1779
  },
1748
1780
  worktreeProjection: new WorktreeStateProjection(),
1749
- mergeMilestone: createMilestoneMergeTransaction(mergeMilestoneToMain),
1781
+ mergeMilestone: createDefaultMilestoneMergeTransaction(),
1750
1782
  };
1751
1783
  }
1752
1784
  function buildLifecycle() {
@@ -2169,6 +2201,10 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
2169
2201
  ctx.ui.setWidget("gsd-health", undefined);
2170
2202
  ctx.ui.notify(s.stepMode ? "Step-mode resumed." : "Auto-mode resumed.", "info");
2171
2203
  restoreHookState(s.basePath);
2204
+ // A restored activeHook has no live dispatch (the sidecar queue is not
2205
+ // persisted); re-enqueue it so the hook runs instead of blocking the next
2206
+ // unrelated unit's close-out (#1246).
2207
+ reconcileRestoredHookDispatch(s.basePath, s.sidecarQueue);
2172
2208
  // Re-sync managed resources on resume so long-lived auto sessions pick up
2173
2209
  // bundled extension updates before resume-time verification/state logic runs.
2174
2210
  // GSD_PKG_ROOT is set by loader.ts and points to the gsd-pi package root.
@@ -2222,15 +2258,19 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
2222
2258
  debugLog("resume-orchestration-resume", { error: err instanceof Error ? err.message : String(err) });
2223
2259
  }
2224
2260
  startAutoCommandPolling(s.basePath);
2225
- await runAutoLoopWithUok({
2226
- ctx,
2227
- pi,
2228
- s,
2229
- deps: loopDeps,
2230
- runKernelLoop: runUokKernelLoop,
2231
- runLegacyLoop: runLegacyAutoLoop,
2232
- });
2233
- await cleanupAfterLoopExit(ctx);
2261
+ try {
2262
+ await runAutoLoopWithUok({
2263
+ ctx,
2264
+ pi,
2265
+ s,
2266
+ deps: loopDeps,
2267
+ runKernelLoop: runUokKernelLoop,
2268
+ runLegacyLoop: runLegacyAutoLoop,
2269
+ });
2270
+ }
2271
+ finally {
2272
+ await cleanupAfterLoopExit(ctx);
2273
+ }
2234
2274
  return;
2235
2275
  }
2236
2276
  // ── Fresh start path — delegated to auto-start.ts ──
@@ -2246,8 +2286,16 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
2246
2286
  // for crash-recovery fidelity (#5405).
2247
2287
  registerAutoWorkerForSession(s, base);
2248
2288
  const ready = await bootstrapAutoSession(s, ctx, pi, base, verboseMode, requestedStepMode, bootstrapDeps, freshStartAssessment);
2249
- if (!ready)
2289
+ if (!ready) {
2290
+ // bootstrapAutoSession sets s.active = true (auto-start.ts) before several
2291
+ // post-activation bail-outs return false without a loop ever running (e.g.
2292
+ // the SQLite-unavailable gate). Without this, s.active and the auto lock
2293
+ // leak and every later /gsd auto silently no-ops via the re-entry guard
2294
+ // (#1235). Run the canonical cleanup so a failed bootstrap stays recoverable.
2295
+ if (s.active)
2296
+ await cleanupAfterLoopExit(ctx);
2250
2297
  return;
2298
+ }
2251
2299
  // Build scope after bootstrap has populated s.basePath / s.originalBasePath /
2252
2300
  // s.currentMilestoneId (including worktree setup inside bootstrapAutoSession).
2253
2301
  rebuildScope(s.basePath, s.currentMilestoneId);
@@ -2271,15 +2319,19 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
2271
2319
  }
2272
2320
  startAutoCommandPolling(s.basePath);
2273
2321
  // Dispatch the first unit
2274
- await runAutoLoopWithUok({
2275
- ctx,
2276
- pi,
2277
- s,
2278
- deps: loopDeps,
2279
- runKernelLoop: runUokKernelLoop,
2280
- runLegacyLoop: runLegacyAutoLoop,
2281
- });
2282
- await cleanupAfterLoopExit(ctx);
2322
+ try {
2323
+ await runAutoLoopWithUok({
2324
+ ctx,
2325
+ pi,
2326
+ s,
2327
+ deps: loopDeps,
2328
+ runKernelLoop: runUokKernelLoop,
2329
+ runLegacyLoop: runLegacyAutoLoop,
2330
+ });
2331
+ }
2332
+ finally {
2333
+ await cleanupAfterLoopExit(ctx);
2334
+ }
2283
2335
  }
2284
2336
  // describeNextUnit is imported from auto-dashboard.ts and re-exported
2285
2337
  export { describeNextUnit } from "./auto-dashboard.js";
@@ -2396,20 +2448,52 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
2396
2448
  startedAt: hookStartedAt,
2397
2449
  workspaceRoot: s.basePath,
2398
2450
  });
2399
- if (hookModel) {
2400
- const availableModels = ctx.modelRegistry.getAvailable();
2401
- const match = resolveModelId(hookModel, availableModels, ctx.model?.provider);
2402
- if (match) {
2451
+ // Resolve the hook's model honoring the configured `fallbacks[]` chain
2452
+ // (#1229). The manual trigger path bypasses selectAndApplyModel, so resolve
2453
+ // the primary→fallbacks order here and apply the first candidate available in
2454
+ // the registry — a blocked or unconfigured primary then transparently drops
2455
+ // to a fallback instead of silently reverting to the session model.
2456
+ const availableModels = ctx.modelRegistry.getAvailable();
2457
+ const availableModelIds = availableModels.map((m) => `${m.provider}/${m.id}`);
2458
+ const hookModelConfig = resolveModelWithFallbacksForUnit(hookUnitType, targetBasePath, availableModelIds);
2459
+ const modelCandidates = hookModelConfig
2460
+ ? [hookModelConfig.primary, ...hookModelConfig.fallbacks]
2461
+ : hookModel
2462
+ ? [hookModel]
2463
+ : [];
2464
+ if (modelCandidates.length > 0) {
2465
+ let applied = false;
2466
+ for (const candidate of modelCandidates) {
2467
+ const match = resolveModelId(candidate, availableModels, ctx.model?.provider);
2468
+ if (!match)
2469
+ continue;
2470
+ // Skip models the runtime has marked blocked or temporarily unavailable
2471
+ // (e.g. a primary that just tripped a provider limit) so the configured
2472
+ // fallbacks[] chain actually engages — parity with auto-mode's
2473
+ // selectAndApplyModel, which consults the same blocked-models store (#1229).
2474
+ if (isModelUnavailable(targetBasePath, match.provider, match.id))
2475
+ continue;
2403
2476
  try {
2404
- await pi.setModel(match);
2477
+ if (await pi.setModel(match)) {
2478
+ // The manual trigger path bypasses selectAndApplyModel, so apply the
2479
+ // hook's per-field `thinking` (from `post_unit_hooks[].model`'s object
2480
+ // form) here against the just-set model rather than leaving the hook at
2481
+ // the session level (#1269). Absent → session level, unchanged.
2482
+ if (hookModelConfig?.thinking) {
2483
+ applyThinkingLevelForModel(pi, hookModelConfig.thinking, match, ctx);
2484
+ }
2485
+ applied = true;
2486
+ break;
2487
+ }
2405
2488
  }
2406
2489
  catch (err) {
2407
- /* non-fatal */
2408
- logWarning("dispatch", `hook model set failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
2490
+ /* non-fatal — try the next fallback */
2491
+ logWarning("dispatch", `hook model set failed for ${candidate}: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
2409
2492
  }
2410
2493
  }
2411
- else {
2412
- ctx.ui.notify(`Hook model "${hookModel}" not found in available models. Falling back to current session model. ` +
2494
+ if (!applied) {
2495
+ ctx.ui.notify(`Hook model${modelCandidates.length > 1 ? "s" : ""} "${modelCandidates.join(", ")}" not available. ` +
2496
+ `Falling back to current session model. ` +
2413
2497
  `Ensure the model is defined in models.json and has auth configured.`, "warning");
2414
2498
  }
2415
2499
  }
@@ -6,7 +6,7 @@ import { join } from "node:path";
6
6
  import { createBashTool, createEditTool, createReadTool, createWriteTool } from "@gsd/pi-coding-agent";
7
7
  import { logWarning } from "../workflow-logger.js";
8
8
  import { getWorkflowDatabaseStatus, openWorkflowDatabase, } from "../db-workspace.js";
9
- import { getAutoWorktreePath } from "../auto-worktree.js";
9
+ import { getAutoWorktreePath } from "../auto-worktree-path-resolution.js";
10
10
  import { resolveWorktreeProjectRoot } from "../worktree-root.js";
11
11
  import { worktreesDirs } from "../worktree-placement.js";
12
12
  export function safeWorkspaceCwd() {
@@ -15,7 +15,7 @@ import { loadFile, saveFile, formatContinue } from "../files.js";
15
15
  import { clearAutoCompletionStopInProgress, clearToolInvocationError, getAutoRuntimeSnapshot, getSourceObservationStore, isAutoActive, isAutoCompletionStopInProgress, isAutoPaused, isInteractiveElicitationInFlight, markToolEnd, markToolStart, recordAutoToolSurfaceSnapshot, recordToolInvocationError, } from "../auto-runtime-state.js";
16
16
  import { isDeterministicPolicyError, isQueuedUserMessageSkip, isToolInvocationError, isToolUnavailableError, } from "../auto-tool-tracking.js";
17
17
  import { applyProviderPayloadPolicy } from "../provider-payload-policy.js";
18
- import { checkToolCallLoop, recordToolCallLoopMutation, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
18
+ import { checkToolCallLoop, configureToolCallLoopGuard, recordToolCallLoopMutation, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
19
19
  import { MINIMAL_AUTO_BASE_TOOL_NAMES } from "./core-session-tools.js";
20
20
  import { maybePauseAutoForApprovalGate, resetPendingGatePauseGuard } from "./pending-gate-pause.js";
21
21
  import { saveActivityLog } from "../activity-log.js";
@@ -432,6 +432,22 @@ async function applyCompactionThresholdOverride(ctx) {
432
432
  ctx.setCompactionThresholdOverride?.(0.6);
433
433
  }
434
434
  }
435
+ /**
436
+ * Apply user-tunable tool-call loop guard thresholds (#1198) from GSD
437
+ * preferences plus GSD_TOOL_LOOP_* env overrides. Runs at session boundaries
438
+ * so both interactive sessions and `/gsd auto` pick up the configuration.
439
+ * Non-fatal: falls back to built-in defaults when preferences cannot be loaded.
440
+ */
441
+ async function applyToolCallLoopGuardConfig(basePath) {
442
+ try {
443
+ const { loadEffectiveGSDPreferences } = await import("../preferences.js");
444
+ const prefs = loadEffectiveGSDPreferences(basePath);
445
+ configureToolCallLoopGuard(prefs?.preferences.tool_call_loop_guard);
446
+ }
447
+ catch {
448
+ configureToolCallLoopGuard(null);
449
+ }
450
+ }
435
451
  function clearDeferredApprovalGate(basePath) {
436
452
  if (!basePath) {
437
453
  deferredApprovalGates.clear();
@@ -779,6 +795,7 @@ export function registerHooks(pi, ecosystemHandlers) {
779
795
  }
780
796
  resetWriteGateState(basePath);
781
797
  resetToolCallLoopGuard();
798
+ await applyToolCallLoopGuardConfig(basePath);
782
799
  approvalQuestionAbortInFlight = false;
783
800
  clearDeferredApprovalGate();
784
801
  await resetAskUserQuestionsTurnCache();
@@ -864,6 +881,7 @@ export function registerHooks(pi, ecosystemHandlers) {
864
881
  initSessionNotifications(ctx);
865
882
  resetWriteGateState(basePath);
866
883
  resetToolCallLoopGuard();
884
+ await applyToolCallLoopGuardConfig(basePath);
867
885
  clearDeferredApprovalGate();
868
886
  await resetAskUserQuestionsTurnCache();
869
887
  clearDiscussionFlowState(basePath);
@@ -1389,7 +1407,7 @@ export function registerHooks(pi, ecosystemHandlers) {
1389
1407
  }
1390
1408
  }
1391
1409
  if (!event.isError) {
1392
- recordToolCallLoopMutation(toolName);
1410
+ recordToolCallLoopMutation(toolName, event.details);
1393
1411
  refreshSourceObservationAfterMutation(toolName, event.input, ctx);
1394
1412
  clearSourceObservationsAfterShell(toolName);
1395
1413
  }
@@ -11,7 +11,7 @@ import { resolveModelWithFallbacksForUnit } from "../preferences-models.js";
11
11
  import { resolveGsdRootFile, resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveTaskFiles, resolveTasksDir, relSliceFile, relSlicePath, relTaskFile } from "../paths.js";
12
12
  import { extractIntroAndRules } from "../knowledge-parser.js";
13
13
  import { ensureCodebaseMapFresh, readCodebaseMap } from "../codebase-generator.js";
14
- import { getActiveAutoWorktreeContext } from "../auto-worktree.js";
14
+ import { getActiveAutoWorktreeContext } from "../auto-worktree-session-registry.js";
15
15
  import { getActiveWorktreeName, getWorktreeOriginalCwd } from "../worktree-session-state.js";
16
16
  import { deriveState } from "../state.js";
17
17
  import { formatOverridesSection, formatShortcut, loadActiveOverrides, loadFile, parseContinue, parseSummary } from "../files.js";
@@ -14,36 +14,173 @@
14
14
  * to stop tooling for the rest of that turn and answer in text.
15
15
  *
16
16
  * The per-tool-name check (#783 Brief C) tracks call counts within a
17
- * turn regardless of args, decaying after successful state-mutating tools.
17
+ * turn regardless of args, decaying after successful state-progressing tools.
18
18
  * This catches improvisation
19
19
  * loops where the model attempts the same missing workflow tool through
20
20
  * varied surfaces (bash → `node -e` → CLI), each with a different
21
21
  * signature, so the identical-args streak never trips, while allowing
22
- * tool-heavy turns that are making file-mutation progress. Whichever guard
23
- * trips first blocks.
22
+ * tool-heavy turns that are making progress. Progress means a successful file
23
+ * mutation (edit/write) or a successful shell/exec call (bg_shell,
24
+ * gsd_uat_exec, …) — so a local model running a legitimate iterative
25
+ * debugging loop (restart server, npm install, curl an endpoint) is not
26
+ * blocked as a false loop (#1206). Whichever guard trips first blocks.
27
+ *
28
+ * Thresholds, exempt tools, and enable flags are user-tunable (#1198) via the
29
+ * `tool_call_loop_guard` key in `.gsd/PREFERENCES.md` and `GSD_TOOL_LOOP_*`
30
+ * environment variables, applied through {@link configureToolCallLoopGuard}.
31
+ * Defaults preserve the original hardcoded behavior.
24
32
  */
25
33
  import { createHash } from "node:crypto";
26
34
  import { INHERENTLY_REPEATABLE_TOOL_SET } from "./core-session-tools.js";
27
35
  import { hasBrowserContractPrefix } from "../../shared/browser-contract.js";
28
36
  import { canonicalToolName } from "../engine-hook-contract.js";
29
- const MAX_CONSECUTIVE_IDENTICAL_CALLS = 4;
37
+ /** Built-in defaults. Preserved when preferences/env do not override them. */
38
+ const DEFAULT_MAX_CONSECUTIVE_IDENTICAL_CALLS = 4;
39
+ const DEFAULT_PER_TOOL_DEFAULT_CAP = 6;
40
+ const DEFAULT_PER_TOOL_REPEATABLE_CAP = 15;
41
+ const DEFAULT_PER_TOOL_CAP_EXEMPT_TOOLS = ["find", "glob", "grep", "ls", "read", "search_and_read"];
30
42
  /** Interactive/user-facing tools where even 1 duplicate is confusing. */
31
43
  const STRICT_LOOP_TOOLS = new Set(["ask_user_questions"]);
32
44
  const MAX_CONSECUTIVE_STRICT = 1;
45
+ const STATE_MUTATING_TOOL_SET = new Set(["edit", "write", "multi_edit", "notebook_edit"]);
33
46
  /**
34
- * Per-turn cap on calls to the SAME tool name, regardless of args (#783).
47
+ * Successful shell/exec calls are state progression too (#1206), not just file
48
+ * mutations. A local model debugging a UAT scenario legitimately restarts
49
+ * servers, runs `npm install`, and curls endpoints via bg_shell / gsd_uat_exec
50
+ * with varied args — productive work that never touches a file, so Guard 2's
51
+ * per-tool cap would otherwise misfire as a false loop. Decaying on these
52
+ * successful calls keeps the guard from aborting a progressing turn.
35
53
  *
36
- * General-purpose execution tools are routinely called many times per turn
37
- * (touching multiple files, running several commands), so they get a higher
38
- * ceiling. Everything else workflow one-shot tools (e.g. gsd_complete_milestone)
39
- * and any non-allowlisted tool gets the default cap. The default is generous
40
- * enough to absorb legitimate retries but catches the reported improvisation
41
- * loop (~51 calls) well before a cost spike.
54
+ * Only successful calls reach {@link recordToolCallLoopMutation}: the
55
+ * tool_result hook skips `isError` results, and the bash tool throws on
56
+ * non-zero exit, so a genuinely stuck improvisation loop of failing commands
57
+ * (#783) never decays and still trips the cap. `async_bash` is excluded
58
+ * because it only registers a background job; command success is reported
59
+ * later via `await_job`. `bg_shell` may return `isError: false` for failed
60
+ * `run`/`start` outcomes, so the hook passes `details` for validation.
42
61
  */
43
- const PER_TOOL_DEFAULT_CAP = 6;
44
- const PER_TOOL_REPEATABLE_CAP = 15;
45
- const PER_TOOL_CAP_EXEMPT_TOOLS = new Set(["find", "glob", "grep", "ls", "read", "search_and_read"]);
46
- const STATE_MUTATING_TOOL_SET = new Set(["edit", "write", "multi_edit", "notebook_edit"]);
62
+ const STATE_PROGRESSING_EXEC_TOOL_SET = new Set([
63
+ "bash",
64
+ "bg_shell",
65
+ "shell",
66
+ "powershell",
67
+ "gsd_exec",
68
+ "gsd_uat_exec",
69
+ ]);
70
+ function isSuccessfulBgShellLoopProgress(details) {
71
+ if (!details || typeof details !== "object")
72
+ return false;
73
+ const record = details;
74
+ switch (record.action) {
75
+ case "run":
76
+ return record.exitCode === 0 && record.timedOut !== true;
77
+ case "start":
78
+ case "restart": {
79
+ const process = record.process;
80
+ if (!process || typeof process !== "object")
81
+ return false;
82
+ return process.alive === true;
83
+ }
84
+ case "wait_for_ready":
85
+ return record.ready === true;
86
+ case "send_and_wait":
87
+ return record.matched === true;
88
+ default:
89
+ return true;
90
+ }
91
+ }
92
+ function defaultGuardConfig() {
93
+ return {
94
+ guardEnabled: true,
95
+ identicalEnabled: true,
96
+ maxConsecutiveIdentical: DEFAULT_MAX_CONSECUTIVE_IDENTICAL_CALLS,
97
+ repeatedEnabled: true,
98
+ perToolDefaultCap: DEFAULT_PER_TOOL_DEFAULT_CAP,
99
+ perToolRepeatableCap: DEFAULT_PER_TOOL_REPEATABLE_CAP,
100
+ perToolExempt: new Set(DEFAULT_PER_TOOL_CAP_EXEMPT_TOOLS),
101
+ };
102
+ }
103
+ let config = defaultGuardConfig();
104
+ /** Parse a positive-integer env var, returning undefined when unset/invalid. */
105
+ function envPositiveInt(name) {
106
+ const raw = process.env[name];
107
+ if (raw === undefined || raw.trim() === "")
108
+ return undefined;
109
+ const n = Number(raw);
110
+ return Number.isFinite(n) && n >= 1 ? Math.floor(n) : undefined;
111
+ }
112
+ /** Parse a boolean env var (`true`/`1` vs `false`/`0`), undefined when unset. */
113
+ function envBool(name) {
114
+ const raw = process.env[name];
115
+ if (raw === undefined || raw.trim() === "")
116
+ return undefined;
117
+ const v = raw.trim().toLowerCase();
118
+ if (v === "true" || v === "1" || v === "yes" || v === "on")
119
+ return true;
120
+ if (v === "false" || v === "0" || v === "no" || v === "off")
121
+ return false;
122
+ return undefined;
123
+ }
124
+ /** Parse a comma-separated tool-name list env var. */
125
+ function envToolList(name) {
126
+ const raw = process.env[name];
127
+ if (!raw)
128
+ return [];
129
+ return raw.split(",").map((s) => s.trim()).filter(Boolean);
130
+ }
131
+ /**
132
+ * Resolve preferences + environment overrides into the active configuration.
133
+ * Environment variables win over preferences; preferences win over built-in
134
+ * defaults. User-supplied exempt tools are additive to the built-in exempt
135
+ * set so defaults are always preserved.
136
+ *
137
+ * Applied to both interactive sessions and `/gsd auto` (called from the
138
+ * session_start / session_switch hooks).
139
+ */
140
+ export function configureToolCallLoopGuard(prefs) {
141
+ const next = defaultGuardConfig();
142
+ if (prefs) {
143
+ if (typeof prefs.enabled === "boolean")
144
+ next.guardEnabled = prefs.enabled;
145
+ if (prefs.identical_args) {
146
+ if (typeof prefs.identical_args.enabled === "boolean")
147
+ next.identicalEnabled = prefs.identical_args.enabled;
148
+ if (typeof prefs.identical_args.max_consecutive_calls === "number" && prefs.identical_args.max_consecutive_calls >= 1) {
149
+ next.maxConsecutiveIdentical = Math.floor(prefs.identical_args.max_consecutive_calls);
150
+ }
151
+ }
152
+ if (prefs.repeated_tool) {
153
+ if (typeof prefs.repeated_tool.enabled === "boolean")
154
+ next.repeatedEnabled = prefs.repeated_tool.enabled;
155
+ if (typeof prefs.repeated_tool.default_cap === "number" && prefs.repeated_tool.default_cap >= 1) {
156
+ next.perToolDefaultCap = Math.floor(prefs.repeated_tool.default_cap);
157
+ }
158
+ if (typeof prefs.repeated_tool.repeatable_cap === "number" && prefs.repeated_tool.repeatable_cap >= 1) {
159
+ next.perToolRepeatableCap = Math.floor(prefs.repeated_tool.repeatable_cap);
160
+ }
161
+ for (const tool of prefs.repeated_tool.exempt_tools ?? []) {
162
+ if (typeof tool === "string" && tool.trim())
163
+ next.perToolExempt.add(tool.trim());
164
+ }
165
+ }
166
+ }
167
+ // Environment overrides (win over preferences).
168
+ const envEnabled = envBool("GSD_TOOL_LOOP_GUARD_ENABLED");
169
+ if (envEnabled !== undefined)
170
+ next.guardEnabled = envEnabled;
171
+ const envIdenticalMax = envPositiveInt("GSD_TOOL_LOOP_IDENTICAL_MAX");
172
+ if (envIdenticalMax !== undefined)
173
+ next.maxConsecutiveIdentical = envIdenticalMax;
174
+ const envDefaultCap = envPositiveInt("GSD_TOOL_LOOP_REPEATED_DEFAULT_CAP");
175
+ if (envDefaultCap !== undefined)
176
+ next.perToolDefaultCap = envDefaultCap;
177
+ const envRepeatableCap = envPositiveInt("GSD_TOOL_LOOP_REPEATED_REPEATABLE_CAP");
178
+ if (envRepeatableCap !== undefined)
179
+ next.perToolRepeatableCap = envRepeatableCap;
180
+ for (const tool of envToolList("GSD_TOOL_LOOP_EXEMPT_TOOLS"))
181
+ next.perToolExempt.add(tool);
182
+ config = next;
183
+ }
47
184
  let consecutiveCount = 0;
48
185
  let lastSignature = "";
49
186
  let lastToolName = "";
@@ -72,14 +209,17 @@ function hashToolCall(toolName, args) {
72
209
  * Returns `{ block: true, reason }` when the loop threshold is exceeded.
73
210
  *
74
211
  * Two independent guards run; whichever trips first blocks:
75
- * 1. Identical-signature streak (MAX_CONSECUTIVE_IDENTICAL_CALLS, strict for
212
+ * 1. Identical-signature streak (config.maxConsecutiveIdentical, strict for
76
213
  * ask_user_questions).
77
- * 2. Per-tool-name cap (PER_TOOL_DEFAULT_CAP / PER_TOOL_REPEATABLE_CAP),
214
+ * 2. Per-tool-name cap (config.perToolDefaultCap / config.perToolRepeatableCap),
78
215
  * independent of args, reset after file-mutation progress — catches
79
216
  * improvisation loops (#783).
217
+ *
218
+ * Both guards, their thresholds, and the per-tool exempt set are user-tunable
219
+ * via {@link configureToolCallLoopGuard} (#1198).
80
220
  */
81
221
  export function checkToolCallLoop(toolName, args) {
82
- if (!enabled)
222
+ if (!enabled || !config.guardEnabled)
83
223
  return { block: false, count: 0 };
84
224
  const sig = hashToolCall(toolName, args);
85
225
  if (sig === lastSignature) {
@@ -93,12 +233,14 @@ export function checkToolCallLoop(toolName, args) {
93
233
  // ── Guard 1: identical-signature streak ──
94
234
  const threshold = STRICT_LOOP_TOOLS.has(toolName)
95
235
  ? MAX_CONSECUTIVE_STRICT
96
- : MAX_CONSECUTIVE_IDENTICAL_CALLS;
97
- if (consecutiveCount > threshold) {
236
+ : config.maxConsecutiveIdentical;
237
+ if (config.identicalEnabled && consecutiveCount > threshold) {
98
238
  return {
99
239
  block: true,
100
240
  reason: `Tool loop detected (identical args): ${toolName} called ${consecutiveCount} times ` +
101
- `with identical arguments. Blocking to prevent infinite loop. ` +
241
+ `with identical arguments (max ${threshold}). Blocking to prevent infinite loop. ` +
242
+ `Raise tool_call_loop_guard.identical_args.max_consecutive_calls in .gsd/PREFERENCES.md ` +
243
+ `(or GSD_TOOL_LOOP_IDENTICAL_MAX) if this is expected. ` +
102
244
  `Do not retry this tool or call other tools this turn — stop and respond to the user in text.`,
103
245
  count: consecutiveCount,
104
246
  };
@@ -119,30 +261,46 @@ export function checkToolCallLoop(toolName, args) {
119
261
  // so the arg-independent per-tool cap misfires on legitimate verification;
120
262
  // Guard 1's identical-signature streak still catches a genuinely stuck
121
263
  // browser loop.
122
- if (PER_TOOL_CAP_EXEMPT_TOOLS.has(toolName) ||
264
+ if (!config.repeatedEnabled ||
265
+ config.perToolExempt.has(toolName) ||
123
266
  hasBrowserContractPrefix(canonicalToolName(toolName))) {
124
267
  return { block: false, count: consecutiveCount };
125
268
  }
126
269
  const perToolCap = INHERENTLY_REPEATABLE_TOOL_SET.has(toolName)
127
- ? PER_TOOL_REPEATABLE_CAP
128
- : PER_TOOL_DEFAULT_CAP;
270
+ ? config.perToolRepeatableCap
271
+ : config.perToolDefaultCap;
129
272
  if (perToolCount > perToolCap) {
130
273
  return {
131
274
  block: true,
132
275
  reason: `Tool loop detected (repeated tool): ${toolName} called ${perToolCount} times ` +
133
276
  `this turn (cap ${perToolCap}). Blocking to prevent infinite loop. ` +
134
277
  `The tool may be unavailable or failing repeatedly. ` +
278
+ `Raise tool_call_loop_guard.repeated_tool.default_cap/repeatable_cap or add "${toolName}" ` +
279
+ `to tool_call_loop_guard.repeated_tool.exempt_tools in .gsd/PREFERENCES.md ` +
280
+ `(or GSD_TOOL_LOOP_REPEATED_* / GSD_TOOL_LOOP_EXEMPT_TOOLS) if this is expected. ` +
135
281
  `Do not retry this tool or pivot to other tools this turn — stop and respond to the user in text.`,
136
282
  count: perToolCount,
137
283
  };
138
284
  }
139
285
  return { block: false, count: consecutiveCount };
140
286
  }
141
- /** Record successful mutation progress so Guard 2 can decay on the next count. */
142
- export function recordToolCallLoopMutation(toolName) {
287
+ /**
288
+ * Record successful state progress so Guard 2 can decay on the next count.
289
+ * File mutations (edit/write/…) and successful shell/exec calls (bash,
290
+ * bg_shell, gsd_uat_exec, …) both count as progress (#1092, #1206). The caller
291
+ * only invokes this for non-error results, so failing improvisation loops
292
+ * (#783) never decay and still trip the per-tool cap.
293
+ */
294
+ export function recordToolCallLoopMutation(toolName, details) {
143
295
  if (!enabled)
144
296
  return;
145
- if (!STATE_MUTATING_TOOL_SET.has(toolName))
297
+ if (STATE_MUTATING_TOOL_SET.has(toolName)) {
298
+ mutationEpoch++;
299
+ return;
300
+ }
301
+ if (!STATE_PROGRESSING_EXEC_TOOL_SET.has(toolName))
302
+ return;
303
+ if (toolName === "bg_shell" && details !== undefined && !isSuccessfulBgShellLoopProgress(details))
146
304
  return;
147
305
  mutationEpoch++;
148
306
  }