@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
@@ -9,10 +9,19 @@ import {
9
9
  import {
10
10
  resolveGsdBrowserCliAvailability,
11
11
  resolveGsdBrowserDaemonStartInvocation,
12
+ resolveGsdBrowserDaemonStopInvocation,
12
13
  } from "../shared/gsd-browser-cli.js";
13
14
  import { uatTypeIncludesBrowser, type UatType } from "./uat-policy.js";
14
15
 
15
16
  const DEFAULT_DAEMON_START_TIMEOUT_MS = 30_000;
17
+ const DEFAULT_DAEMON_STOP_TIMEOUT_MS = 15_000;
18
+
19
+ /**
20
+ * Project roots whose gsd-browser daemon this process warmed via
21
+ * {@link prepareBrowserDaemonForUat}. Teardown only stops daemons we actually
22
+ * started, so non-browser auto-mode sessions never spawn a stray `daemon stop`.
23
+ */
24
+ const warmedDaemonProjectRoots = new Set<string>();
16
25
 
17
26
  function isEnvDisabled(value: string | undefined): boolean {
18
27
  if (!value) return false;
@@ -102,7 +111,74 @@ export function prepareBrowserDaemonForUat(ctx: BrowserDaemonWarmContext): strin
102
111
  if (!shouldWarmBrowserDaemonForUat(ctx)) return null;
103
112
 
104
113
  const result = ensureBrowserDaemonStarted(ctx.projectRoot, { env: ctx.env });
105
- if (result.ok) return null;
114
+ if (result.ok) {
115
+ warmedDaemonProjectRoots.add(resolve(ctx.projectRoot));
116
+ return null;
117
+ }
106
118
 
107
119
  return `Cannot dispatch browser-backed run-uat: gsd-browser daemon failed to start (${result.error}). Ensure Chrome/Chromium is installed, run \`gsd-browser daemon health\` with the project session flags from .mcp.json, or set GSD_BROWSER_PATH to a Chromium binary.`;
108
120
  }
121
+
122
+ /**
123
+ * Best-effort stop of a gsd-browser session daemon warmed for browser UAT.
124
+ * Mirrors {@link ensureBrowserDaemonStarted}; returns the failure detail rather
125
+ * than throwing so teardown can stay non-fatal.
126
+ */
127
+ export function stopBrowserDaemon(
128
+ projectRoot: string,
129
+ options: { env?: NodeJS.ProcessEnv; timeoutMs?: number } = {},
130
+ ): { ok: true } | { ok: false; error: string } {
131
+ const env = options.env ?? process.env;
132
+ const availability = resolveGsdBrowserCliAvailability(env);
133
+ if (!availability.available) {
134
+ return { ok: false, error: availability.detail };
135
+ }
136
+
137
+ let invocation: ReturnType<typeof resolveGsdBrowserDaemonStopInvocation>;
138
+ try {
139
+ invocation = resolveGsdBrowserDaemonStopInvocation(projectRoot, env);
140
+ } catch (error) {
141
+ return {
142
+ ok: false,
143
+ error: error instanceof Error ? error.message : String(error),
144
+ };
145
+ }
146
+
147
+ try {
148
+ execFileSync(invocation.command, invocation.args, {
149
+ cwd: invocation.cwd,
150
+ env: { ...process.env, ...env, ...(invocation.env ?? {}) },
151
+ stdio: ["ignore", "pipe", "pipe"],
152
+ timeout: options.timeoutMs ?? DEFAULT_DAEMON_STOP_TIMEOUT_MS,
153
+ encoding: "utf-8",
154
+ });
155
+ return { ok: true };
156
+ } catch (error) {
157
+ return {
158
+ ok: false,
159
+ error: error instanceof Error ? error.message : String(error),
160
+ };
161
+ }
162
+ }
163
+
164
+ /**
165
+ * Tear down every gsd-browser daemon this process warmed for browser UAT,
166
+ * clearing the tracked set. Called on auto-mode loop exit so the Chrome process
167
+ * does not survive session/task completion (mirrors the warm-up preflight).
168
+ * Best-effort: returns the project roots whose stop failed for logging.
169
+ */
170
+ export function teardownWarmedBrowserDaemons(
171
+ options: { env?: NodeJS.ProcessEnv } = {},
172
+ ): { projectRoot: string; error: string }[] {
173
+ if (warmedDaemonProjectRoots.size === 0) return [];
174
+
175
+ const failures: { projectRoot: string; error: string }[] = [];
176
+ for (const projectRoot of warmedDaemonProjectRoots) {
177
+ const result = stopBrowserDaemon(projectRoot, { env: options.env });
178
+ if (!result.ok) {
179
+ failures.push({ projectRoot, error: result.error });
180
+ }
181
+ }
182
+ warmedDaemonProjectRoots.clear();
183
+ return failures;
184
+ }
@@ -675,10 +675,16 @@ export function ensureCodebaseMapFresh(
675
675
 
676
676
  const metadata = parseCodebaseMapMetadata(existing);
677
677
  const existingDescriptions = parseCodebaseMap(existing);
678
+ // Compare against the truncated count: when the repository has more tracked
679
+ // files than maxFiles, the map only lists the first maxFiles entries, so a
680
+ // stored fileCount above the cap (e.g. from an older map that recorded the
681
+ // full count) still matches the current truncated listing. Comparing raw
682
+ // values would flag "file-count-changed" on every turn, rewriting the
683
+ // timestamp and invalidating the provider KV cache prefix.
678
684
  const staleReason =
679
685
  !metadata ? "missing-metadata"
680
686
  : metadata.fingerprint !== fingerprint ? "files-changed"
681
- : metadata.fileCount !== listed.files.length ? "file-count-changed"
687
+ : Math.min(metadata.fileCount, resolved.maxFiles) !== listed.files.length ? "file-count-changed"
682
688
  : metadata.truncated !== listed.truncated ? "truncation-changed"
683
689
  : undefined;
684
690
 
@@ -25,7 +25,7 @@ import {
25
25
  filterDoctorIssues,
26
26
  } from "./doctor.js";
27
27
  import { isAutoActive, checkRemoteAutoSession } from "./auto.js";
28
- import { getAutoWorktreePath } from "./auto-worktree.js";
28
+ import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
29
29
  import { currentDirectoryRoot, projectRoot } from "./commands/context.js";
30
30
  import { loadPrompt } from "./prompt-loader.js";
31
31
  import { buildClaudeRuntimeFloorAdvisory } from "../../shared/claude-runtime-floor.js";
@@ -23,7 +23,7 @@ import {
23
23
  } from "./workflow-templates.js";
24
24
  import { loadPrompt } from "./prompt-loader.js";
25
25
  import { gsdRoot } from "./paths.js";
26
- import { createGitService, runGit } from "./git-service.js";
26
+ import { createGitService, runGit, taskBranchArgs } from "./git-service.js";
27
27
  import { isAutoActive, isAutoPaused } from "./auto.js";
28
28
  import { getErrorMessage } from "./error-utils.js";
29
29
  import { resolvePlugin, type WorkflowPlugin } from "./workflow-plugins.js";
@@ -464,7 +464,7 @@ export async function handleStart(
464
464
  try {
465
465
  git.autoCommit("workflow-template", templateId, []);
466
466
  } catch { /* nothing to commit */ }
467
- runGit(basePath, ["checkout", "-b", branchName]);
467
+ runGit(basePath, taskBranchArgs(basePath, branchName, current, git.getMainBranch()));
468
468
  branchCreated = true;
469
469
  }
470
470
  } catch (err) {
@@ -636,7 +636,7 @@ export function dispatchMarkdownPhasePlugin(
636
636
  const current = git.getCurrentBranch();
637
637
  if (current !== branchName) {
638
638
  try { git.autoCommit("workflow-template", templateId, []); } catch { /* nothing to commit */ }
639
- runGit(basePath, ["checkout", "-b", branchName]);
639
+ runGit(basePath, taskBranchArgs(basePath, branchName, current, git.getMainBranch()));
640
640
  branchCreated = true;
641
641
  }
642
642
  } catch (err) {
@@ -148,6 +148,53 @@ export function writeCompatMarker(basePath: string, marker: CompatMarker): void
148
148
  renameSync(tmp, path);
149
149
  }
150
150
 
151
+ /**
152
+ * Remove projection entries whose backing file no longer exists on disk.
153
+ *
154
+ * gsd-pi never deletes marker entries on its own: both drift detectors skip
155
+ * files missing from disk (`if (!existsSync(abs)) continue;`) and the write-time
156
+ * flush only ever adds or refreshes entries. So when a phase directory is
157
+ * renamed or removed (e.g. `phases/29-new-milestone-m029/` →
158
+ * `phases/29-frontend-code-debt-cleanup/`), the old projection paths linger in
159
+ * `.compat.json` forever as phantom entries pointing at directories that no
160
+ * longer exist (#1257). They never reconcile, and `.compat.json` keeps drifting
161
+ * from disk reality so `git status` stops being a reliable proxy for "did the
162
+ * engine touch my plans?".
163
+ *
164
+ * This prunes those orphaned entries across the `.gsd/` projections and the
165
+ * `.planning/` projections/passthrough maps. It is safe: a missing-file entry is
166
+ * inert (every detector already ignores it), and if the file is later
167
+ * re-projected the write-time flush / unseeded-file detection re-seeds an
168
+ * accurate baseline.
169
+ *
170
+ * Returns the number of entries removed; when nothing is orphaned the marker is
171
+ * left untouched (no needless write, no `lastProjectedAt` churn).
172
+ */
173
+ export function pruneOrphanedProjectionEntries(basePath: string): number {
174
+ if (!existsSync(compatMarkerPath(basePath))) return 0;
175
+
176
+ const marker = readCompatMarker(basePath);
177
+ let removed = 0;
178
+
179
+ const pruneMap = (map: Record<string, ProjectionEntry>, root: string): void => {
180
+ for (const relPath of Object.keys(map)) {
181
+ if (!existsSync(join(basePath, root, relPath))) {
182
+ delete map[relPath];
183
+ removed++;
184
+ }
185
+ }
186
+ };
187
+
188
+ pruneMap(marker.projections, ".gsd");
189
+ if (marker.planning) {
190
+ pruneMap(marker.planning.projections, ".planning");
191
+ pruneMap(marker.planning.passthrough, ".planning");
192
+ }
193
+
194
+ if (removed > 0) writeCompatMarker(basePath, marker);
195
+ return removed;
196
+ }
197
+
151
198
  function quarantine(basePath: string, raw: string): void {
152
199
  const path = compatMarkerPath(basePath);
153
200
  const badPath = `${path}.bad-${Date.now()}`;
@@ -150,7 +150,13 @@ function collectConfigSections(options?: CollectConfigOptions): ConfigSection[]
150
150
  if (prefs?.auto_supervisor) {
151
151
  const sup = resolveAutoSupervisorConfig();
152
152
  const supRows: ConfigSection["rows"] = [];
153
- if (sup.model) supRows.push({ label: "Model", value: sup.model });
153
+ if (sup.model) {
154
+ let modelVal = sup.model;
155
+ if (sup.modelFallbacks && sup.modelFallbacks.length > 0) {
156
+ modelVal += ` \u2192 ${sup.modelFallbacks.join(" \u2192 ")}`;
157
+ }
158
+ supRows.push({ label: "Model", value: modelVal });
159
+ }
154
160
  supRows.push({ label: "Soft timeout", value: `${sup.soft_timeout_minutes}m` });
155
161
  supRows.push({ label: "Idle timeout", value: `${sup.idle_timeout_minutes}m` });
156
162
  supRows.push({ label: "Stalled tool timeout", value: `${sup.stalled_tool_timeout_minutes}m` });
@@ -860,3 +860,39 @@ export function getDb(): DbAdapter {
860
860
  export function getDbOrNull(): DbAdapter | null {
861
861
  return currentDb;
862
862
  }
863
+
864
+ export interface DbWritableProbeResult {
865
+ ok: boolean;
866
+ detail?: string;
867
+ }
868
+
869
+ /**
870
+ * Confirm the open handle can actually write, not just that it opened.
871
+ *
872
+ * A schema-current database performs zero writes during open, so a handle that
873
+ * opened successfully but is not writable (read-only file, WAL/SHM permission
874
+ * mismatch, or a stale/moved handle → SQLITE_READONLY_DBMOVED) otherwise passes
875
+ * the open-only availability check and only fails much later at the first real
876
+ * write. The probe forces a genuine page write by re-writing the current
877
+ * `PRAGMA user_version` value back inside an IMMEDIATE transaction: a bare
878
+ * `BEGIN IMMEDIATE; ROLLBACK` is not sufficient because a moved handle does not
879
+ * fail until a page is actually dirtied. The value is unchanged, so the probe
880
+ * is idempotent, and the transaction is rolled back so nothing persists.
881
+ */
882
+ export function probeDbWritable(): DbWritableProbeResult {
883
+ const db = currentDb;
884
+ if (!db) return { ok: false, detail: "No database is open." };
885
+ try {
886
+ const row = db.prepare("PRAGMA user_version").get() as { user_version?: number } | undefined;
887
+ const current = typeof row?.user_version === "number" ? row.user_version : 0;
888
+ db.exec("BEGIN IMMEDIATE");
889
+ try {
890
+ db.exec(`PRAGMA user_version = ${current}`);
891
+ } finally {
892
+ db.exec("ROLLBACK");
893
+ }
894
+ return { ok: true };
895
+ } catch (err) {
896
+ return { ok: false, detail: (err as Error).message };
897
+ }
898
+ }
@@ -281,7 +281,7 @@ export function getMilestone(id: string): MilestoneRow | null {
281
281
  export function getActiveMilestoneFromDb(): MilestoneRow | null {
282
282
  if (!getDbOrNull()!) return null;
283
283
  const row = getDbOrNull()!.prepare(
284
- "SELECT * FROM milestones WHERE status NOT IN ('complete', 'done', 'skipped', 'closed', 'parked') ORDER BY id LIMIT 1",
284
+ `SELECT * FROM milestones WHERE status NOT IN (${TERMINAL_STATUS_SQL}, 'parked') ORDER BY id LIMIT 1`,
285
285
  ).get();
286
286
  if (!row) return null;
287
287
  return rowToMilestone(row);
@@ -295,11 +295,11 @@ export function getActiveSliceFromDb(milestoneId: string): SliceRow | null {
295
295
  const row = getDbOrNull()!.prepare(
296
296
  `SELECT s.* FROM slices s
297
297
  WHERE s.milestone_id = :mid
298
- AND s.status NOT IN ('complete', 'done', 'skipped')
298
+ AND s.status NOT IN (${TERMINAL_STATUS_SQL})
299
299
  AND NOT EXISTS (
300
300
  SELECT 1 FROM json_each(s.depends) AS dep
301
301
  WHERE dep.value NOT IN (
302
- SELECT id FROM slices WHERE milestone_id = :mid AND status IN ('complete', 'done', 'skipped')
302
+ SELECT id FROM slices WHERE milestone_id = :mid AND status IN (${TERMINAL_STATUS_SQL})
303
303
  )
304
304
  )
305
305
  ORDER BY s.sequence, s.id
@@ -312,7 +312,7 @@ export function getActiveSliceFromDb(milestoneId: string): SliceRow | null {
312
312
  export function getActiveTaskFromDb(milestoneId: string, sliceId: string): TaskRow | null {
313
313
  if (!getDbOrNull()!) return null;
314
314
  const row = getDbOrNull()!.prepare(
315
- "SELECT * FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND status NOT IN ('complete', 'done') ORDER BY sequence, id LIMIT 1",
315
+ `SELECT * FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND status NOT IN (${TERMINAL_STATUS_SQL}) ORDER BY sequence, id LIMIT 1`,
316
316
  ).get({ ":mid": milestoneId, ":sid": sliceId });
317
317
  if (!row) return null;
318
318
  return rowToTask(row);
@@ -339,7 +339,7 @@ export function getParallelMonitorSliceProgress(milestoneId: string): ParallelMo
339
339
  s.id AS id,
340
340
  s.status AS status,
341
341
  COUNT(t.id) AS total,
342
- COALESCE(SUM(CASE WHEN t.status='complete' THEN 1 ELSE 0 END), 0) AS done
342
+ COALESCE(SUM(CASE WHEN t.status IN (${TERMINAL_STATUS_SQL}) THEN 1 ELSE 0 END), 0) AS done
343
343
  FROM slices s
344
344
  LEFT JOIN tasks t ON s.milestone_id=t.milestone_id AND s.id=t.slice_id
345
345
  WHERE s.milestone_id=:mid
@@ -518,7 +518,7 @@ export function getSliceScopedArtifacts(milestoneId: string, sliceId: string): A
518
518
  export function getActiveMilestoneIdFromDb(): IdStatusSummary | null {
519
519
  if (!getDbOrNull()!) return null;
520
520
  const row = getDbOrNull()!.prepare(
521
- "SELECT id, status FROM milestones WHERE status NOT IN ('complete', 'done', 'skipped', 'closed', 'parked') ORDER BY id LIMIT 1",
521
+ `SELECT id, status FROM milestones WHERE status NOT IN (${TERMINAL_STATUS_SQL}, 'parked') ORDER BY id LIMIT 1`,
522
522
  ).get();
523
523
  if (!row) return null;
524
524
  return rowToIdStatusSummary(row);
@@ -536,7 +536,7 @@ export function getSliceStatusSummary(milestoneId: string): IdStatusSummary[] {
536
536
  export function getActiveTaskIdFromDb(milestoneId: string, sliceId: string): ActiveTaskSummary | null {
537
537
  if (!getDbOrNull()!) return null;
538
538
  const row = getDbOrNull()!.prepare(
539
- "SELECT id, status, title FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND status NOT IN ('complete', 'done') ORDER BY sequence, id LIMIT 1",
539
+ `SELECT id, status, title FROM tasks WHERE milestone_id = :mid AND slice_id = :sid AND status NOT IN (${TERMINAL_STATUS_SQL}) ORDER BY sequence, id LIMIT 1`,
540
540
  ).get({ ":mid": milestoneId, ":sid": sliceId });
541
541
  if (!row) return null;
542
542
  return rowToActiveTaskSummary(row);
@@ -548,8 +548,8 @@ export function getSliceTaskCounts(milestoneId: string, sliceId: string): TaskSt
548
548
  const row = getDbOrNull()!.prepare(
549
549
  `SELECT
550
550
  COUNT(*) as total,
551
- SUM(CASE WHEN status IN ('complete', 'done') THEN 1 ELSE 0 END) as done,
552
- SUM(CASE WHEN status NOT IN ('complete', 'done') THEN 1 ELSE 0 END) as pending
551
+ SUM(CASE WHEN status IN (${TERMINAL_STATUS_SQL}) THEN 1 ELSE 0 END) as done,
552
+ SUM(CASE WHEN status NOT IN (${TERMINAL_STATUS_SQL}) THEN 1 ELSE 0 END) as pending
553
553
  FROM tasks WHERE milestone_id = :mid AND slice_id = :sid`,
554
554
  ).get({ ":mid": milestoneId, ":sid": sliceId });
555
555
  return rowToTaskStatusCounts(row);
@@ -38,6 +38,17 @@ export type ReopenSliceOutcome =
38
38
  * completion timestamps cleared, in one commit. Folds the hand-rolled
39
39
  * transaction-plus-cascade previously in tools/reopen-slice.ts. Guards run
40
40
  * inside the transaction (TOCTOU-safe).
41
+ *
42
+ * A closed slice is always reopenable. An open slice is only reopenable when it
43
+ * carries a completed-task state desync (#1205): a UAT→planning fallback can
44
+ * leave the slice "pending" while *all* its tasks stay "complete", which
45
+ * deadlocks every recovery path (plan-slice/replan-slice/complete-task all
46
+ * reject the still-closed tasks, and slice_reopen historically rejected the
47
+ * still-open slice). Resetting those tasks to pending gives the planner the
48
+ * clean slate it needs. An open slice that still has any unfinished
49
+ * (pending/in-progress) task is a normal in-flight slice, not the desync, and
50
+ * stays rejected as "slice-not-complete" so a full reset can't wipe its
51
+ * legitimate progress.
41
52
  */
42
53
  export function reopenSliceCascade(milestoneId: string, sliceId: string): ReopenSliceOutcome {
43
54
  requireDb();
@@ -48,9 +59,20 @@ export function reopenSliceCascade(milestoneId: string, sliceId: string): Reopen
48
59
  if (isClosedStatus(milestone.status)) { outcome = { ok: false, reason: "milestone-closed", status: milestone.status }; return; }
49
60
  const slice = getSlice(milestoneId, sliceId);
50
61
  if (!slice) { outcome = { ok: false, reason: "slice-not-found" }; return; }
51
- if (!isClosedStatus(slice.status)) { outcome = { ok: false, reason: "slice-not-complete", status: slice.status }; return; }
52
62
 
53
63
  const tasks = getSliceTasks(milestoneId, sliceId);
64
+ // A closed slice is always reopenable. An open slice is only the #1205
65
+ // desync when EVERY task is already closed (a UAT→planning fallback left the
66
+ // slice open with all tasks still "complete"). Requiring *all* tasks closed
67
+ // (not merely one) means a normal in-flight slice — which keeps at least one
68
+ // pending/in-progress task — is rejected, so a full reset can't wipe its
69
+ // legitimate progress.
70
+ const allTasksClosed = tasks.length > 0 && tasks.every((t) => isClosedStatus(t.status));
71
+ if (!isClosedStatus(slice.status) && !allTasksClosed) {
72
+ outcome = { ok: false, reason: "slice-not-complete", status: slice.status };
73
+ return;
74
+ }
75
+
54
76
  getDbOrNull()!.prepare(
55
77
  `UPDATE slices SET status = 'in_progress', completed_at = NULL WHERE milestone_id = :mid AND id = :sid`,
56
78
  ).run({ ":mid": milestoneId, ":sid": sliceId });
@@ -25,6 +25,32 @@ export function normalizeDbRows(rows: unknown[]): Record<string, unknown>[] {
25
25
  return rows.map((row) => normalizeDbRow(row)!);
26
26
  }
27
27
 
28
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
29
+ if (value === null || typeof value !== "object") return false;
30
+ const proto = Object.getPrototypeOf(value);
31
+ return proto === Object.prototype || proto === null;
32
+ }
33
+
34
+ // node:sqlite accepts binding-object keys with or without the ':'/'@'/'$'
35
+ // prefix, but better-sqlite3 accepts only bare keys — strip the prefix so
36
+ // call sites written against node:sqlite also work on the fallback provider.
37
+ function normalizeBindParams(params: unknown[]): unknown[] {
38
+ return params.map((param) => {
39
+ if (!isPlainObject(param)) return param;
40
+ let changed = false;
41
+ const normalized: Record<string, unknown> = {};
42
+ for (const [key, value] of Object.entries(param)) {
43
+ if (key.length > 1 && (key[0] === ":" || key[0] === "@" || key[0] === "$")) {
44
+ normalized[key.slice(1)] = value;
45
+ changed = true;
46
+ } else {
47
+ normalized[key] = value;
48
+ }
49
+ }
50
+ return changed ? normalized : param;
51
+ });
52
+ }
53
+
28
54
  export function createDbAdapter(rawDb: unknown): DbAdapter {
29
55
  const db = rawDb as {
30
56
  exec(sql: string): void;
@@ -45,13 +71,13 @@ export function createDbAdapter(rawDb: unknown): DbAdapter {
45
71
  }): DbStatement {
46
72
  return {
47
73
  run(...params: unknown[]): unknown {
48
- return raw.run(...params);
74
+ return raw.run(...normalizeBindParams(params));
49
75
  },
50
76
  get(...params: unknown[]): Record<string, unknown> | undefined {
51
- return normalizeDbRow(raw.get(...params));
77
+ return normalizeDbRow(raw.get(...normalizeBindParams(params)));
52
78
  },
53
79
  all(...params: unknown[]): Record<string, unknown>[] {
54
- return normalizeDbRows(raw.all(...params));
80
+ return normalizeDbRows(raw.all(...normalizeBindParams(params)));
55
81
  },
56
82
  };
57
83
  }
@@ -138,7 +138,7 @@ Diagnostics record the file path, scope (global/project), severity (error/warnin
138
138
  - `off` — skill discovery is disabled entirely.
139
139
 
140
140
  - `auto_supervisor`: configures the auto-mode supervisor that monitors agent progress and enforces timeouts. Keys:
141
- - `model`: model ID to use for the supervisor process (defaults to the currently active model).
141
+ - `model`: model to use for the supervisor process (defaults to the currently active model). Accepts a bare model ID **or** the same `{ model, provider?, fallbacks? }` object form as `models.<phase>`, so it honors `fallbacks[]` on a transient provider trip.
142
142
  - `soft_timeout_minutes`: minutes before the supervisor issues a soft warning (default: 20).
143
143
  - `idle_timeout_minutes`: minutes of inactivity before the supervisor intervenes (default: 10).
144
144
  - `hard_timeout_minutes`: minutes before the supervisor forces termination (default: 30).
@@ -228,7 +228,7 @@ In `"parent"` mode, slice/task `targetRepositories` default to the declared chil
228
228
  - `enabled`: boolean — set `false` to force sequential task execution. Default: `true`.
229
229
  - `max_parallel`: number — maximum tasks to dispatch in one batch, range `1`-`8`. Default: `2`.
230
230
  - `isolation_mode`: `"same-tree"` — currently the only supported value.
231
- - `subagent_model`: string — optional model override for reactive task subagents. Falls back to the `models.subagent` routing when omitted.
231
+ - `subagent_model`: optional model override for reactive task subagents. Accepts a bare model ID **or** the `{ model, provider?, fallbacks? }` object form (parity with `models.<phase>`). Falls back to the `models.subagent` routing when omitted.
232
232
 
233
233
  - `remote_questions`: route interactive questions to Slack/Discord for headless auto-mode. Keys:
234
234
  - `channel`: `"slack"` or `"discord"` — channel type.
@@ -326,7 +326,7 @@ In `"parent"` mode, slice/task `targetRepositories` default to the declared chil
326
326
  - `after`: string[] — unit types that trigger this hook (e.g., `["execute-task"]`).
327
327
  - `prompt`: string — prompt sent to the LLM. Supports `{milestoneId}`, `{sliceId}`, `{taskId}` substitutions.
328
328
  - `max_cycles`: number — max times this hook fires per trigger (default: 1, max: 10).
329
- - `model`: string — optional model override.
329
+ - `model`: optional model override. Accepts a bare model ID **or** the same `{ model, provider?, fallbacks? }` object form as `models.<phase>`. With `fallbacks[]`, a transient trip of the primary provider falls back to the next entry instead of hard-failing the hook — which, for a `blocking` hook with `on_block: { action: pause }`, would otherwise pause the whole run.
330
330
  - `artifact`: string — expected output file name (relative to task/slice dir). Hook is skipped if file already exists (idempotent).
331
331
  - `criticality`: `"advisory"` or `"blocking"` — advisory preserves current best-effort behavior; blocking requires clean hook completion plus a valid outcome verdict before auto-mode advances. Default: `"advisory"`.
332
332
  - `retry_on`: string — if this file is produced instead of the artifact, re-run the trigger unit then re-run hooks.
@@ -14,7 +14,15 @@ import {
14
14
  } from "./gsd-db.js";
15
15
  import { MEMORIES_FTS_REBUILT_KEY } from "./db-memory-fts-schema.js";
16
16
  import { isAfter, latestExplicitReopenAt } from "./milestone-reopen-events.js";
17
- import { gsdProjectionRoot, gsdRoot, resolveGsdPathContract, resolveMilestoneFile, resolveSliceFile } from "./paths.js";
17
+ import {
18
+ buildTaskFileName,
19
+ gsdProjectionRoot,
20
+ gsdRoot,
21
+ resolveGsdPathContract,
22
+ resolveMilestoneFile,
23
+ resolveMilestonePath,
24
+ resolveSliceFile,
25
+ } from "./paths.js";
18
26
  import { deriveState } from "./state.js";
19
27
  import { isClosedStatus } from "./status-guards.js";
20
28
  import { workflowEventLogPath } from "./workflow-event-ledger.js";
@@ -23,6 +31,7 @@ import { flushWorkflowProjections } from "./projection-flush.js";
23
31
  import { parseRoadmapSlices } from "./roadmap-slices.js";
24
32
  import { parsePlan } from "./parsers-legacy.js";
25
33
  import { parseSummary } from "./files.js";
34
+ import { LAYOUT_SEGMENTS } from "./layout-policy.js";
26
35
 
27
36
  const USER_AUTHORED_ARTIFACT_TYPES = new Set(["CONTEXT", "RESEARCH"]);
28
37
 
@@ -160,11 +169,11 @@ function isClearedByMilestoneShellProjectionFlush(
160
169
  return issue.file === relativeFile(basePath, roadmapPath);
161
170
  }
162
171
 
163
- function artifactExistsOnDisk(basePath: string, artifactPath: string): boolean {
164
- return resolveArtifactDiskPath(basePath, artifactPath) !== null;
172
+ function artifactExistsOnDisk(basePath: string, artifactPath: string, row?: ArtifactRow): boolean {
173
+ return resolveArtifactDiskPath(basePath, artifactPath, row) !== null;
165
174
  }
166
175
 
167
- function resolveArtifactDiskPath(basePath: string, artifactPath: string): string | null {
176
+ function resolveLiteralArtifactDiskPath(basePath: string, artifactPath: string): string | null {
168
177
  const relativeArtifactPath = artifactPathRelativeToGsd(artifactPath);
169
178
  if (isAbsolute(relativeArtifactPath)) {
170
179
  return existsSync(relativeArtifactPath) ? relativeArtifactPath : null;
@@ -176,6 +185,50 @@ function resolveArtifactDiskPath(basePath: string, artifactPath: string): string
176
185
  return null;
177
186
  }
178
187
 
188
+ function relativeToGsdRoot(basePath: string, diskPath: string): string | null {
189
+ for (const root of [gsdProjectionRoot(basePath), gsdRoot(basePath)]) {
190
+ if (!isPathInside(root, diskPath)) continue;
191
+ return relative(root, diskPath).split("\\").join("/");
192
+ }
193
+ return null;
194
+ }
195
+
196
+ function isFlatPhaseDiskPath(basePath: string, diskPath: string): boolean {
197
+ return relativeToGsdRoot(basePath, diskPath)?.startsWith(`${LAYOUT_SEGMENTS.level1}/`) ?? false;
198
+ }
199
+
200
+ function hasFlatPhaseLayout(basePath: string): boolean {
201
+ return existsSync(join(gsdProjectionRoot(basePath), LAYOUT_SEGMENTS.level1));
202
+ }
203
+
204
+ function resolveFlatPhaseArtifactDiskPath(basePath: string, row: ArtifactRow): string | null {
205
+ if (!hasFlatPhaseLayout(basePath)) return null;
206
+ if (!row.milestone_id) return null;
207
+ const artifactType = normalizedArtifactType(row.artifact_type);
208
+ if (!artifactType) return null;
209
+
210
+ if (row.slice_id && row.task_id) {
211
+ const phaseDir = resolveMilestonePath(basePath, row.milestone_id);
212
+ if (!phaseDir || !isFlatPhaseDiskPath(basePath, phaseDir)) return null;
213
+ const candidate = join(phaseDir, buildTaskFileName(row.task_id, artifactType));
214
+ return existsSync(candidate) ? candidate : null;
215
+ }
216
+
217
+ const candidate = row.slice_id
218
+ ? resolveSliceFile(basePath, row.milestone_id, row.slice_id, artifactType)
219
+ : resolveMilestoneFile(basePath, row.milestone_id, artifactType);
220
+
221
+ return candidate && isFlatPhaseDiskPath(basePath, candidate) ? candidate : null;
222
+ }
223
+
224
+ function resolveArtifactDiskPath(basePath: string, artifactPath: string, row?: ArtifactRow): string | null {
225
+ if (row && isMilestonesArtifactPath(row.path)) {
226
+ const flatPath = resolveFlatPhaseArtifactDiskPath(basePath, row);
227
+ if (flatPath) return flatPath;
228
+ }
229
+ return resolveLiteralArtifactDiskPath(basePath, artifactPath);
230
+ }
231
+
179
232
  function taskExistsInPlan(basePath: string, milestoneId: string, sliceId: string, taskId: string): boolean {
180
233
  const planPath = resolveSliceFile(basePath, milestoneId, sliceId, "PLAN");
181
234
  if (!planPath || !existsSync(planPath)) return false;
@@ -228,7 +281,7 @@ function readTaskCompletionEvidenceFromSummary(
228
281
  if (!row.task_status && Number(row.task_count) > 0 && !taskExistsInPlan(basePath, row.milestone_id, row.slice_id, row.task_id)) {
229
282
  return null;
230
283
  }
231
- const diskPath = resolveArtifactDiskPath(basePath, row.path);
284
+ const diskPath = resolveArtifactDiskPath(basePath, row.path, { ...row, artifact_type: "SUMMARY" });
232
285
  if (!diskPath) return null;
233
286
  try {
234
287
  const fullSummaryMd = readFileSync(diskPath, "utf-8");
@@ -262,6 +315,7 @@ function repairTaskArtifactDbStatusDivergence(
262
315
  basePath: string,
263
316
  row: {
264
317
  path: string;
318
+ artifact_type?: string;
265
319
  milestone_id: string;
266
320
  slice_id: string | null;
267
321
  task_id: string | null;
@@ -353,6 +407,49 @@ function hasPresentMilestonesReplacement(basePath: string, row: ArtifactRow, art
353
407
  );
354
408
  }
355
409
 
410
+ function hasPresentFlatPhaseReplacement(basePath: string, row: ArtifactRow, artifactRows: ArtifactRow[]): boolean {
411
+ if (resolveFlatPhaseArtifactDiskPath(basePath, row)) return true;
412
+
413
+ return artifactRows.some(
414
+ (other) =>
415
+ other.path !== row.path &&
416
+ !isMilestonesArtifactPath(other.path) &&
417
+ sameArtifactIdentity(row, other) &&
418
+ artifactExistsOnDisk(basePath, other.path, other),
419
+ );
420
+ }
421
+
422
+ function hasNoFlatPhaseFileEquivalent(row: ArtifactRow): boolean {
423
+ const artifactType = normalizedArtifactType(row.artifact_type);
424
+ if (row.slice_id && row.task_id) {
425
+ return artifactType === "PLAN" || artifactType === "SUMMARY";
426
+ }
427
+ return Boolean(row.slice_id && !row.task_id && artifactType === "SUMMARY");
428
+ }
429
+
430
+ function staleMilestonesArtifactRowFixable(basePath: string, row: ArtifactRow, artifactRows: ArtifactRow[]): boolean {
431
+ if (!isMilestonesArtifactPath(row.path)) return false;
432
+ if (!hasFlatPhaseLayout(basePath)) return false;
433
+ if (hasPresentFlatPhaseReplacement(basePath, row, artifactRows)) return true;
434
+ return hasNoFlatPhaseFileEquivalent(row) && !resolveLiteralArtifactDiskPath(basePath, row.path);
435
+ }
436
+
437
+ function stalePhasesArtifactRowFixable(basePath: string, row: ArtifactRow, artifactRows: ArtifactRow[]): boolean {
438
+ const issuePath = artifactPathRelativeToGsd(row.path);
439
+ return issuePath.startsWith(`${LAYOUT_SEGMENTS.level1}/`) && hasPresentMilestonesReplacement(basePath, row, artifactRows);
440
+ }
441
+
442
+ function staleArtifactRowFixable(basePath: string, row: ArtifactRow, artifactRows: ArtifactRow[]): boolean {
443
+ return staleMilestonesArtifactRowFixable(basePath, row, artifactRows) ||
444
+ stalePhasesArtifactRowFixable(basePath, row, artifactRows);
445
+ }
446
+
447
+ function staleArtifactPruneMessage(row: ArtifactRow): string {
448
+ return isMilestonesArtifactPath(row.path)
449
+ ? `pruned stale legacy artifact row ${row.path}`
450
+ : `pruned stale flat-phase artifact row ${row.path}`;
451
+ }
452
+
356
453
  export async function checkEngineHealth(
357
454
  basePath: string,
358
455
  issues: DoctorIssue[],
@@ -579,17 +676,18 @@ export async function checkEngineHealth(
579
676
  .all() as ArtifactRow[];
580
677
 
581
678
  for (const row of artifactRows) {
582
- if (artifactExistsOnDisk(basePath, row.path)) continue;
583
679
  const unitId = artifactUnitId(row);
584
680
  const issuePath = artifactPathRelativeToGsd(row.path);
585
- if (options?.repair && issuePath.startsWith("phases/") && hasPresentMilestonesReplacement(basePath, row, artifactRows)) {
681
+ if (artifactExistsOnDisk(basePath, row.path)) continue;
682
+ if (options?.repair && staleArtifactRowFixable(basePath, row, artifactRows)) {
586
683
  // Route the write through the Single Writer owner (gsd-db.ts) instead
587
684
  // of issuing raw DELETE SQL here — doctor is a read-only consumer and
588
685
  // the single-writer invariant forbids write SQL outside the allowlist.
589
686
  deleteArtifactByPath(row.path);
590
- fixesApplied.push(`pruned stale flat-phase artifact row ${row.path}`);
687
+ fixesApplied.push(staleArtifactPruneMessage(row));
591
688
  continue;
592
689
  }
690
+ if (artifactExistsOnDisk(basePath, row.path, row)) continue;
593
691
  if (isUserAuthoredArtifactType(row.artifact_type)) {
594
692
  const artifactType = normalizedArtifactType(row.artifact_type);
595
693
  missingUserContentArtifacts.push({ path: issuePath, artifactType });
@@ -611,7 +709,7 @@ export async function checkEngineHealth(
611
709
  unitId,
612
710
  message: `Artifact ${issuePath} is recorded in the database as ${row.artifact_type || "UNKNOWN"} but no matching file exists on disk`,
613
711
  file: issuePath,
614
- fixable: issuePath.startsWith("phases/") && hasPresentMilestonesReplacement(basePath, row, artifactRows),
712
+ fixable: staleArtifactRowFixable(basePath, row, artifactRows),
615
713
  });
616
714
  }
617
715
  } catch {
@@ -643,6 +741,7 @@ export async function checkEngineHealth(
643
741
  )
644
742
  .all() as Array<{
645
743
  path: string;
744
+ artifact_type: string;
646
745
  milestone_id: string;
647
746
  slice_id: string | null;
648
747
  task_id: string | null;
@@ -654,7 +753,7 @@ export async function checkEngineHealth(
654
753
 
655
754
  const seen = new Set<string>();
656
755
  for (const row of rows) {
657
- if (!artifactExistsOnDisk(basePath, row.path)) continue;
756
+ if (!artifactExistsOnDisk(basePath, row.path, row)) continue;
658
757
  const reopenAt = latestExplicitReopenAt(basePath, row.milestone_id);
659
758
  if (!isAfter(row.imported_at, reopenAt)) continue;
660
759
  const isSliceSummary = row.slice_id && !row.task_id && row.slice_status && !["complete", "done", "skipped", "closed"].includes(row.slice_status);