@opengsd/gsd-pi 1.4.0 → 1.5.0-dev.4fb2d460

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 (657) hide show
  1. package/README.md +11 -11
  2. package/dist/onboarding.js +11 -0
  3. package/dist/resources/.managed-resources-content-hash +1 -1
  4. package/dist/resources/GSD-WORKFLOW.md +20 -25
  5. package/dist/resources/extensions/ask-user-questions.js +1 -1
  6. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +118 -53
  7. package/dist/resources/extensions/cursor-cli/index.js +16 -0
  8. package/dist/resources/extensions/cursor-cli/models.js +63 -0
  9. package/dist/resources/extensions/cursor-cli/package.json +11 -0
  10. package/dist/resources/extensions/cursor-cli/readiness.js +128 -0
  11. package/dist/resources/extensions/cursor-cli/stream-adapter.js +353 -0
  12. package/dist/resources/extensions/gsd/activity-log.js +4 -1
  13. package/dist/resources/extensions/gsd/artifact-verification.js +25 -9
  14. package/dist/resources/extensions/gsd/auto/closeout.js +137 -42
  15. package/dist/resources/extensions/gsd/auto/finalize.js +9 -0
  16. package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -3
  17. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +6 -3
  18. package/dist/resources/extensions/gsd/auto/run-unit.js +5 -2
  19. package/dist/resources/extensions/gsd/auto/schedule-wakeup.js +3 -0
  20. package/dist/resources/extensions/gsd/auto/unit-phase.js +5 -9
  21. package/dist/resources/extensions/gsd/auto-artifact-paths.js +12 -3
  22. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -7
  23. package/dist/resources/extensions/gsd/auto-dispatch.js +31 -7
  24. package/dist/resources/extensions/gsd/auto-model-selection.js +36 -18
  25. package/dist/resources/extensions/gsd/auto-prompts.js +76 -2
  26. package/dist/resources/extensions/gsd/auto-recovery.js +50 -6
  27. package/dist/resources/extensions/gsd/auto-start.js +8 -6
  28. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +4 -0
  29. package/dist/resources/extensions/gsd/auto-worktree-branch-lifecycle.js +189 -0
  30. package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +133 -0
  31. package/dist/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.js +35 -0
  32. package/dist/resources/extensions/gsd/auto-worktree-creation.js +130 -0
  33. package/dist/resources/extensions/gsd/auto-worktree-entry.js +118 -0
  34. package/dist/resources/extensions/gsd/auto-worktree-merge-already-merged.js +98 -0
  35. package/dist/resources/extensions/gsd/auto-worktree-merge-branch-head.js +52 -0
  36. package/dist/resources/extensions/gsd/auto-worktree-merge-cleanup.js +87 -0
  37. package/dist/resources/extensions/gsd/auto-worktree-merge-code-changes.js +46 -0
  38. package/dist/resources/extensions/gsd/auto-worktree-merge-db-ready.js +68 -0
  39. package/dist/resources/extensions/gsd/auto-worktree-merge-integration-branch.js +51 -0
  40. package/dist/resources/extensions/gsd/auto-worktree-merge-message.js +106 -0
  41. package/dist/resources/extensions/gsd/auto-worktree-merge-pre-teardown.js +64 -0
  42. package/dist/resources/extensions/gsd/auto-worktree-merge-stash.js +168 -0
  43. package/dist/resources/extensions/gsd/auto-worktree-merge.js +302 -0
  44. package/dist/resources/extensions/gsd/auto-worktree-milestone-shelter.js +119 -0
  45. package/dist/resources/extensions/gsd/auto-worktree-path-resolution.js +5 -0
  46. package/dist/resources/extensions/gsd/auto-worktree-path-utils.js +5 -0
  47. package/dist/resources/extensions/gsd/auto-worktree-resource-version.js +41 -0
  48. package/dist/resources/extensions/gsd/auto-worktree-runtime-cleanup.js +99 -0
  49. package/dist/resources/extensions/gsd/auto-worktree-session-registry.js +57 -0
  50. package/dist/resources/extensions/gsd/auto-worktree-sync.js +249 -0
  51. package/dist/resources/extensions/gsd/auto-worktree-teardown.js +120 -0
  52. package/dist/resources/extensions/gsd/auto-worktree.js +20 -2046
  53. package/dist/resources/extensions/gsd/auto.js +31 -5
  54. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -0
  55. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -1
  56. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +134 -7
  57. package/dist/resources/extensions/gsd/bootstrap/schedule-wakeup-tool.js +58 -9
  58. package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
  59. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +194 -28
  60. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +14 -1
  61. package/dist/resources/extensions/gsd/codebase-generator.js +164 -20
  62. package/dist/resources/extensions/gsd/commands/handlers/core.js +40 -4
  63. package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
  64. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +153 -1
  65. package/dist/resources/extensions/gsd/commands-workflow-templates.js +3 -3
  66. package/dist/resources/extensions/gsd/commands-worktree.js +11 -2
  67. package/dist/resources/extensions/gsd/db/queries.js +48 -9
  68. package/dist/resources/extensions/gsd/db/writers/cascades.js +20 -2
  69. package/dist/resources/extensions/gsd/discussion-handoff.js +8 -3
  70. package/dist/resources/extensions/gsd/docs/preferences-reference.md +8 -2
  71. package/dist/resources/extensions/gsd/doctor-engine-checks.js +292 -18
  72. package/dist/resources/extensions/gsd/doctor-providers.js +38 -10
  73. package/dist/resources/extensions/gsd/doctor.js +93 -3
  74. package/dist/resources/extensions/gsd/exec-sandbox.js +6 -2
  75. package/dist/resources/extensions/gsd/flat-phase-migration.js +106 -26
  76. package/dist/resources/extensions/gsd/forensics.js +1 -1
  77. package/dist/resources/extensions/gsd/git-conflict-resolve.js +2 -2
  78. package/dist/resources/extensions/gsd/git-service.js +59 -18
  79. package/dist/resources/extensions/gsd/gsd-db.js +75 -11
  80. package/dist/resources/extensions/gsd/guidance.js +1 -0
  81. package/dist/resources/extensions/gsd/guided-flow.js +62 -19
  82. package/dist/resources/extensions/gsd/key-manager.js +1 -0
  83. package/dist/resources/extensions/gsd/markdown-renderer.js +40 -11
  84. package/dist/resources/extensions/gsd/md-importer.js +89 -23
  85. package/dist/resources/extensions/gsd/migrate-external.js +24 -7
  86. package/dist/resources/extensions/gsd/migration-auto-check.js +30 -3
  87. package/dist/resources/extensions/gsd/milestone-merge-transaction.js +14 -3
  88. package/dist/resources/extensions/gsd/milestone-settlement.js +1 -1
  89. package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
  90. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -1
  91. package/dist/resources/extensions/gsd/paths.js +17 -3
  92. package/dist/resources/extensions/gsd/preferences-diagnostics.js +24 -1
  93. package/dist/resources/extensions/gsd/preferences-models.js +6 -4
  94. package/dist/resources/extensions/gsd/preferences-skills.js +10 -16
  95. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  96. package/dist/resources/extensions/gsd/preferences-validation.js +107 -2
  97. package/dist/resources/extensions/gsd/preferences.js +49 -2
  98. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -2
  99. package/dist/resources/extensions/gsd/prompts/system.md +6 -6
  100. package/dist/resources/extensions/gsd/quick.js +12 -3
  101. package/dist/resources/extensions/gsd/redact-secrets.js +37 -0
  102. package/dist/resources/extensions/gsd/repo-identity.js +16 -0
  103. package/dist/resources/extensions/gsd/repository-registry.js +6 -1
  104. package/dist/resources/extensions/gsd/root-write-leak-guard.js +4 -2
  105. package/dist/resources/extensions/gsd/safe-fs.js +23 -2
  106. package/dist/resources/extensions/gsd/skill-discovery.js +36 -23
  107. package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
  108. package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -0
  109. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +2 -1
  110. package/dist/resources/extensions/gsd/state/derive/from-db.js +88 -153
  111. package/dist/resources/extensions/gsd/tool-contract.js +14 -0
  112. package/dist/resources/extensions/gsd/tools/plan-task.js +76 -8
  113. package/dist/resources/extensions/gsd/tools/reopen-slice.js +5 -0
  114. package/dist/resources/extensions/gsd/tools/reopen-task.js +13 -5
  115. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +40 -0
  116. package/dist/resources/extensions/gsd/unit-context-manifest.js +5 -4
  117. package/dist/resources/extensions/gsd/unit-registry.js +37 -2
  118. package/dist/resources/extensions/gsd/unit-runtime.js +21 -0
  119. package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +1 -1
  120. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -1
  121. package/dist/resources/extensions/gsd/workspace-git-preflight.js +2 -2
  122. package/dist/resources/extensions/gsd/workspace.js +26 -8
  123. package/dist/resources/extensions/gsd/worktree-command.js +1 -1
  124. package/dist/resources/extensions/gsd/worktree-lifecycle.js +81 -14
  125. package/dist/resources/extensions/gsd/worktree-manager.js +97 -4
  126. package/dist/resources/extensions/gsd/worktree-reentry.js +2 -1
  127. package/dist/resources/extensions/shared/interview-ui.js +62 -9
  128. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  129. package/dist/web/standalone/.next/BUILD_ID +1 -1
  130. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  131. package/dist/web/standalone/.next/build-manifest.json +3 -3
  132. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  133. package/dist/web/standalone/.next/required-server-files.json +3 -3
  134. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  135. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  136. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  137. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  143. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  145. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  146. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  147. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  148. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  149. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  151. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  152. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  153. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  154. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  161. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  173. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/export-data/route.js +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_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  195. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  205. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  211. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  224. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  227. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  230. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  231. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  232. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  233. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  234. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  235. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  236. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  237. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  238. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  239. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  240. package/dist/web/standalone/.next/server/app/index.html +1 -1
  241. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  242. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  243. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  244. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  245. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  246. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  247. package/dist/web/standalone/.next/server/app/page.js +2 -2
  248. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  249. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  250. package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
  251. package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
  252. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  253. package/dist/web/standalone/.next/server/middleware.js +3 -3
  254. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  255. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  256. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  257. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +1 -0
  258. package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
  259. package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
  260. package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
  261. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
  262. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  263. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  264. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  265. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  266. package/dist/web/standalone/server.js +1 -1
  267. package/dist/wizard.d.ts +8 -0
  268. package/dist/wizard.js +8 -1
  269. package/integrations/hermes/CONTEXT.md +47 -0
  270. package/integrations/hermes/README.md +21 -0
  271. package/integrations/hermes/__init__.py +31 -0
  272. package/integrations/hermes/docs/issue-1162-grilling.md +197 -0
  273. package/integrations/hermes/docs/setup.md +4 -0
  274. package/integrations/hermes/open_gsd_hermes/commands.py +141 -0
  275. package/integrations/hermes/open_gsd_hermes/config.py +2 -0
  276. package/integrations/hermes/open_gsd_hermes/gsd_client.py +591 -39
  277. package/integrations/hermes/open_gsd_hermes/notifications.py +10 -1
  278. package/integrations/hermes/plugin.yaml +4 -0
  279. package/integrations/hermes/tests/test_config.py +6 -0
  280. package/integrations/hermes/tests/test_directory_loader.py +37 -0
  281. package/integrations/hermes/tests/test_gsd_client_cache.py +3 -0
  282. package/integrations/hermes/tests/test_gsd_client_execute.py +35 -0
  283. package/integrations/hermes/tests/test_gsd_client_process_cwd.py +22 -0
  284. package/integrations/hermes/tests/test_gsd_client_timeout.py +98 -0
  285. package/integrations/hermes/tests/test_milestone_client.py +447 -0
  286. package/integrations/hermes/tests/test_new_milestone_command.py +313 -0
  287. package/integrations/hermes/tests/test_supervisor_fsm.py +40 -0
  288. package/package.json +8 -8
  289. package/packages/cloud-mcp-gateway/dist/auth-store.d.ts +1 -0
  290. package/packages/cloud-mcp-gateway/dist/auth-store.d.ts.map +1 -1
  291. package/packages/cloud-mcp-gateway/dist/auth-store.js +21 -1
  292. package/packages/cloud-mcp-gateway/dist/auth-store.js.map +1 -1
  293. package/packages/cloud-mcp-gateway/dist/auth-store.test.js +34 -0
  294. package/packages/cloud-mcp-gateway/dist/auth-store.test.js.map +1 -1
  295. package/packages/cloud-mcp-gateway/package.json +2 -2
  296. package/packages/contracts/package.json +1 -1
  297. package/packages/daemon/dist/cloud-runtime.d.ts +2 -0
  298. package/packages/daemon/dist/cloud-runtime.d.ts.map +1 -1
  299. package/packages/daemon/dist/cloud-runtime.js +25 -1
  300. package/packages/daemon/dist/cloud-runtime.js.map +1 -1
  301. package/packages/daemon/dist/cloud-runtime.test.js +51 -0
  302. package/packages/daemon/dist/cloud-runtime.test.js.map +1 -1
  303. package/packages/daemon/dist/message-batcher.d.ts +7 -0
  304. package/packages/daemon/dist/message-batcher.d.ts.map +1 -1
  305. package/packages/daemon/dist/message-batcher.js +13 -0
  306. package/packages/daemon/dist/message-batcher.js.map +1 -1
  307. package/packages/daemon/dist/message-batcher.test.js +48 -0
  308. package/packages/daemon/dist/message-batcher.test.js.map +1 -1
  309. package/packages/daemon/dist/session-manager.js +1 -1
  310. package/packages/daemon/dist/session-manager.js.map +1 -1
  311. package/packages/daemon/package.json +5 -5
  312. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts +13 -1
  313. package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
  314. package/packages/gsd-agent-core/dist/compaction/compaction.js +15 -1
  315. package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
  316. package/packages/gsd-agent-core/dist/export-html/template.js +53 -4
  317. package/packages/gsd-agent-core/dist/session/agent-session-navigation.d.ts.map +1 -1
  318. package/packages/gsd-agent-core/dist/session/agent-session-navigation.js +4 -1
  319. package/packages/gsd-agent-core/dist/session/agent-session-navigation.js.map +1 -1
  320. package/packages/gsd-agent-core/package.json +5 -5
  321. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  322. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +3 -2
  323. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  324. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -1
  325. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +1 -0
  326. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -1
  327. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +1 -1
  328. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
  329. package/packages/gsd-agent-modes/package.json +7 -7
  330. package/packages/mcp-server/dist/server.d.ts +18 -5
  331. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  332. package/packages/mcp-server/dist/server.js +46 -5
  333. package/packages/mcp-server/dist/server.js.map +1 -1
  334. package/packages/mcp-server/dist/session-manager.js +1 -1
  335. package/packages/mcp-server/dist/session-manager.js.map +1 -1
  336. package/packages/mcp-server/package.json +4 -4
  337. package/packages/native/package.json +1 -1
  338. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  339. package/packages/pi-agent-core/dist/agent-loop.js +14 -9
  340. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  341. package/packages/pi-agent-core/package.json +1 -1
  342. package/packages/pi-ai/dist/env-api-keys.d.ts.map +1 -1
  343. package/packages/pi-ai/dist/env-api-keys.js +3 -0
  344. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  345. package/packages/pi-ai/dist/index.d.ts +1 -0
  346. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  347. package/packages/pi-ai/dist/index.js +1 -0
  348. package/packages/pi-ai/dist/index.js.map +1 -1
  349. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  350. package/packages/pi-ai/dist/providers/transform-messages.js +7 -3
  351. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  352. package/packages/pi-ai/dist/tool-result-content.d.ts +3 -0
  353. package/packages/pi-ai/dist/tool-result-content.d.ts.map +1 -0
  354. package/packages/pi-ai/dist/tool-result-content.js +62 -0
  355. package/packages/pi-ai/dist/tool-result-content.js.map +1 -0
  356. package/packages/pi-ai/dist/types.d.ts +10 -22
  357. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  358. package/packages/pi-ai/dist/types.js.map +1 -1
  359. package/packages/pi-ai/package.json +1 -1
  360. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  361. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  362. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  363. package/packages/pi-coding-agent/dist/core/package-manager.d.ts +9 -0
  364. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  365. package/packages/pi-coding-agent/dist/core/package-manager.js +74 -53
  366. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  367. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +6 -0
  368. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/core/resource-loader.js +30 -2
  370. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +1 -0
  372. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -1
  373. package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -1
  374. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  375. package/packages/pi-coding-agent/dist/core/session-manager.js +3 -0
  376. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  377. package/packages/pi-coding-agent/dist/core/skill-directories.d.ts +66 -0
  378. package/packages/pi-coding-agent/dist/core/skill-directories.d.ts.map +1 -0
  379. package/packages/pi-coding-agent/dist/core/skill-directories.js +138 -0
  380. package/packages/pi-coding-agent/dist/core/skill-directories.js.map +1 -0
  381. package/packages/pi-coding-agent/dist/core/skills.d.ts +4 -1
  382. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  383. package/packages/pi-coding-agent/dist/core/skills.js +4 -1
  384. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  385. package/packages/pi-coding-agent/dist/index.d.ts +1 -0
  386. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  387. package/packages/pi-coding-agent/dist/index.js +1 -0
  388. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  389. package/packages/pi-coding-agent/package.json +7 -7
  390. package/packages/pi-tui/package.json +2 -2
  391. package/packages/rpc-client/dist/rpc-client.js +1 -1
  392. package/packages/rpc-client/dist/rpc-client.js.map +1 -1
  393. package/packages/rpc-client/package.json +2 -2
  394. package/pkg/dist/core/export-html/template.js +53 -4
  395. package/pkg/package.json +1 -1
  396. package/scripts/link-workspace-packages.cjs +14 -4
  397. package/src/resources/GSD-WORKFLOW.md +20 -25
  398. package/src/resources/extensions/ask-user-questions.ts +1 -1
  399. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +130 -51
  400. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +371 -39
  401. package/src/resources/extensions/cursor-cli/index.ts +18 -0
  402. package/src/resources/extensions/cursor-cli/models.ts +65 -0
  403. package/src/resources/extensions/cursor-cli/package.json +11 -0
  404. package/src/resources/extensions/cursor-cli/readiness.ts +143 -0
  405. package/src/resources/extensions/cursor-cli/stream-adapter.ts +440 -0
  406. package/src/resources/extensions/cursor-cli/tests/index.test.ts +54 -0
  407. package/src/resources/extensions/cursor-cli/tests/readiness.test.ts +29 -0
  408. package/src/resources/extensions/cursor-cli/tests/stream-adapter.test.ts +166 -0
  409. package/src/resources/extensions/gsd/activity-log.ts +4 -1
  410. package/src/resources/extensions/gsd/artifact-verification.ts +25 -9
  411. package/src/resources/extensions/gsd/auto/closeout.ts +163 -58
  412. package/src/resources/extensions/gsd/auto/finalize.ts +8 -0
  413. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  414. package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -3
  415. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +6 -3
  416. package/src/resources/extensions/gsd/auto/run-unit.ts +5 -2
  417. package/src/resources/extensions/gsd/auto/schedule-wakeup.ts +8 -0
  418. package/src/resources/extensions/gsd/auto/unit-phase.ts +5 -9
  419. package/src/resources/extensions/gsd/auto-artifact-paths.ts +12 -3
  420. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +13 -7
  421. package/src/resources/extensions/gsd/auto-dispatch.ts +35 -7
  422. package/src/resources/extensions/gsd/auto-model-selection.ts +49 -18
  423. package/src/resources/extensions/gsd/auto-prompts.ts +73 -2
  424. package/src/resources/extensions/gsd/auto-recovery.ts +50 -6
  425. package/src/resources/extensions/gsd/auto-start.ts +9 -6
  426. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +4 -0
  427. package/src/resources/extensions/gsd/auto-worktree-branch-lifecycle.ts +237 -0
  428. package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +166 -0
  429. package/src/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.ts +37 -0
  430. package/src/resources/extensions/gsd/auto-worktree-creation.ts +171 -0
  431. package/src/resources/extensions/gsd/auto-worktree-entry.ts +154 -0
  432. package/src/resources/extensions/gsd/auto-worktree-merge-already-merged.ts +161 -0
  433. package/src/resources/extensions/gsd/auto-worktree-merge-branch-head.ts +83 -0
  434. package/src/resources/extensions/gsd/auto-worktree-merge-cleanup.ts +132 -0
  435. package/src/resources/extensions/gsd/auto-worktree-merge-code-changes.ts +71 -0
  436. package/src/resources/extensions/gsd/auto-worktree-merge-db-ready.ts +112 -0
  437. package/src/resources/extensions/gsd/auto-worktree-merge-integration-branch.ts +99 -0
  438. package/src/resources/extensions/gsd/auto-worktree-merge-message.ts +166 -0
  439. package/src/resources/extensions/gsd/auto-worktree-merge-pre-teardown.ts +93 -0
  440. package/src/resources/extensions/gsd/auto-worktree-merge-stash.ts +213 -0
  441. package/src/resources/extensions/gsd/auto-worktree-merge.ts +391 -0
  442. package/src/resources/extensions/gsd/auto-worktree-milestone-shelter.ts +159 -0
  443. package/src/resources/extensions/gsd/auto-worktree-path-resolution.ts +6 -0
  444. package/src/resources/extensions/gsd/auto-worktree-path-utils.ts +10 -0
  445. package/src/resources/extensions/gsd/auto-worktree-resource-version.ts +44 -0
  446. package/src/resources/extensions/gsd/auto-worktree-runtime-cleanup.ts +119 -0
  447. package/src/resources/extensions/gsd/auto-worktree-session-registry.ts +71 -0
  448. package/src/resources/extensions/gsd/auto-worktree-sync.ts +370 -0
  449. package/src/resources/extensions/gsd/auto-worktree-teardown.ts +161 -0
  450. package/src/resources/extensions/gsd/auto-worktree.ts +69 -2390
  451. package/src/resources/extensions/gsd/auto.ts +32 -19
  452. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -0
  453. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -1
  454. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +148 -7
  455. package/src/resources/extensions/gsd/bootstrap/schedule-wakeup-tool.ts +80 -12
  456. package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
  457. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +229 -28
  458. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +23 -1
  459. package/src/resources/extensions/gsd/codebase-generator.ts +186 -19
  460. package/src/resources/extensions/gsd/commands/handlers/core.ts +39 -3
  461. package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
  462. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +135 -1
  463. package/src/resources/extensions/gsd/commands-workflow-templates.ts +3 -3
  464. package/src/resources/extensions/gsd/commands-worktree.ts +13 -2
  465. package/src/resources/extensions/gsd/db/queries.ts +49 -9
  466. package/src/resources/extensions/gsd/db/writers/cascades.ts +23 -1
  467. package/src/resources/extensions/gsd/discussion-handoff.ts +10 -2
  468. package/src/resources/extensions/gsd/docs/preferences-reference.md +8 -2
  469. package/src/resources/extensions/gsd/doctor-engine-checks.ts +372 -22
  470. package/src/resources/extensions/gsd/doctor-providers.ts +39 -10
  471. package/src/resources/extensions/gsd/doctor-types.ts +5 -1
  472. package/src/resources/extensions/gsd/doctor.ts +95 -3
  473. package/src/resources/extensions/gsd/exec-sandbox.ts +6 -2
  474. package/src/resources/extensions/gsd/flat-phase-migration.ts +132 -25
  475. package/src/resources/extensions/gsd/forensics.ts +1 -1
  476. package/src/resources/extensions/gsd/git-conflict-resolve.ts +2 -2
  477. package/src/resources/extensions/gsd/git-service.ts +67 -17
  478. package/src/resources/extensions/gsd/gsd-db.ts +105 -11
  479. package/src/resources/extensions/gsd/guidance.ts +2 -0
  480. package/src/resources/extensions/gsd/guided-flow.ts +71 -20
  481. package/src/resources/extensions/gsd/key-manager.ts +1 -0
  482. package/src/resources/extensions/gsd/markdown-renderer.ts +40 -10
  483. package/src/resources/extensions/gsd/md-importer.ts +93 -22
  484. package/src/resources/extensions/gsd/migrate-external.ts +23 -6
  485. package/src/resources/extensions/gsd/migration-auto-check.ts +32 -3
  486. package/src/resources/extensions/gsd/milestone-merge-transaction.ts +19 -4
  487. package/src/resources/extensions/gsd/milestone-settlement.ts +1 -1
  488. package/src/resources/extensions/gsd/model-router.ts +4 -5
  489. package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
  490. package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -1
  491. package/src/resources/extensions/gsd/paths.ts +21 -3
  492. package/src/resources/extensions/gsd/preferences-diagnostics.ts +24 -0
  493. package/src/resources/extensions/gsd/preferences-models.ts +6 -3
  494. package/src/resources/extensions/gsd/preferences-skills.ts +10 -16
  495. package/src/resources/extensions/gsd/preferences-types.ts +30 -0
  496. package/src/resources/extensions/gsd/preferences-validation.ts +97 -2
  497. package/src/resources/extensions/gsd/preferences.ts +58 -4
  498. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -2
  499. package/src/resources/extensions/gsd/prompts/system.md +6 -6
  500. package/src/resources/extensions/gsd/quick.ts +11 -3
  501. package/src/resources/extensions/gsd/redact-secrets.ts +40 -0
  502. package/src/resources/extensions/gsd/repo-identity.ts +17 -0
  503. package/src/resources/extensions/gsd/repository-registry.ts +7 -1
  504. package/src/resources/extensions/gsd/root-write-leak-guard.ts +3 -2
  505. package/src/resources/extensions/gsd/safe-fs.ts +22 -2
  506. package/src/resources/extensions/gsd/skill-discovery.ts +47 -23
  507. package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +7 -9
  508. package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -0
  509. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -1
  510. package/src/resources/extensions/gsd/state/derive/from-db.ts +201 -157
  511. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +169 -1
  512. package/src/resources/extensions/gsd/tests/auto-loop-no-copy-artifacts.test.ts +2 -1
  513. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +131 -5
  514. package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +18 -0
  515. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +178 -0
  516. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +43 -1
  517. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +111 -0
  518. package/src/resources/extensions/gsd/tests/auto-remote-session-lock-cleanup.test.ts +41 -0
  519. package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +41 -0
  520. package/src/resources/extensions/gsd/tests/auto-session-scope.test.ts +4 -4
  521. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +3 -0
  522. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +1 -1
  523. package/src/resources/extensions/gsd/tests/auto-timeout-recovery-harness-abort.test.ts +55 -0
  524. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +10 -1
  525. package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +1 -1
  526. package/src/resources/extensions/gsd/tests/auto-worktree-merge-already-merged.test.ts +177 -0
  527. package/src/resources/extensions/gsd/tests/auto-worktree-merge-branch-head.test.ts +118 -0
  528. package/src/resources/extensions/gsd/tests/auto-worktree-merge-cleanup.test.ts +115 -0
  529. package/src/resources/extensions/gsd/tests/auto-worktree-merge-code-changes.test.ts +76 -0
  530. package/src/resources/extensions/gsd/tests/auto-worktree-merge-db-ready.test.ts +140 -0
  531. package/src/resources/extensions/gsd/tests/auto-worktree-merge-integration-branch.test.ts +123 -0
  532. package/src/resources/extensions/gsd/tests/auto-worktree-merge-message.test.ts +114 -0
  533. package/src/resources/extensions/gsd/tests/auto-worktree-merge-pre-teardown.test.ts +84 -0
  534. package/src/resources/extensions/gsd/tests/auto-worktree-merge-stash.test.ts +70 -0
  535. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-shelter.test.ts +52 -0
  536. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +6 -6
  537. package/src/resources/extensions/gsd/tests/auto-worktree-resource-version.test.ts +59 -0
  538. package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +3 -1
  539. package/src/resources/extensions/gsd/tests/batch-task-query.test.ts +85 -0
  540. package/src/resources/extensions/gsd/tests/check-auto-start-ready-guard.test.ts +29 -0
  541. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +387 -0
  542. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +62 -1
  543. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +1 -1
  544. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -0
  545. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +138 -1
  546. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +571 -5
  547. package/src/resources/extensions/gsd/tests/doctor-workspace.test.ts +207 -0
  548. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +1 -1
  549. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +109 -2
  550. package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +25 -1
  551. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +87 -19
  552. package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +89 -0
  553. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +40 -0
  554. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +9 -0
  555. package/src/resources/extensions/gsd/tests/import-completion-lost-update.test.ts +196 -0
  556. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +4 -6
  557. package/src/resources/extensions/gsd/tests/integration/auto-stash-merge.test.ts +2 -1
  558. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +3 -3
  559. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +7 -8
  560. package/src/resources/extensions/gsd/tests/integration/feature-branch-lifecycle-integration.test.ts +2 -5
  561. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +76 -0
  562. package/src/resources/extensions/gsd/tests/integration/merge-cwd-restore.test.ts +1 -1
  563. package/src/resources/extensions/gsd/tests/integration/merge-preserve-worktree-on-preteardown-error.test.ts +1 -1
  564. package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +2 -1
  565. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +5 -7
  566. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +4 -2
  567. package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +2 -4
  568. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -15
  569. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +122 -0
  570. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +1 -1
  571. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +4 -4
  572. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +1 -1
  573. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +1 -1
  574. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +116 -0
  575. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +91 -0
  576. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +592 -23
  577. package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +25 -1
  578. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +1 -1
  579. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -3
  580. package/src/resources/extensions/gsd/tests/parallel-worker-lock-contention.test.ts +1 -1
  581. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +2 -2
  582. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +50 -6
  583. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +17 -0
  584. package/src/resources/extensions/gsd/tests/plan-task.test.ts +264 -1
  585. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +1 -4
  586. package/src/resources/extensions/gsd/tests/preferences.test.ts +169 -0
  587. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +147 -0
  588. package/src/resources/extensions/gsd/tests/recovery-verify-logs.test.ts +4 -4
  589. package/src/resources/extensions/gsd/tests/redact-secrets.test.ts +56 -0
  590. package/src/resources/extensions/gsd/tests/register-hooks-flat-phase-migration.test.ts +73 -0
  591. package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +275 -0
  592. package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +52 -0
  593. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +41 -2
  594. package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +55 -0
  595. package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +31 -9
  596. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -0
  597. package/src/resources/extensions/gsd/tests/schedule-wakeup-tool.test.ts +167 -0
  598. package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +46 -0
  599. package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +3 -5
  600. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -0
  601. package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +2 -1
  602. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +2 -1
  603. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -1
  604. package/src/resources/extensions/gsd/tests/status-per-repo.test.ts +94 -0
  605. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +1 -1
  606. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +1 -1
  607. package/src/resources/extensions/gsd/tests/system-flat-phase-layout.test.ts +33 -0
  608. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +4 -4
  609. package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +2 -1
  610. package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +4 -4
  611. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +35 -0
  612. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +259 -0
  613. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +1 -1
  614. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +66 -18
  615. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +81 -0
  616. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +30 -0
  617. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +52 -0
  618. package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +53 -1
  619. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +208 -1
  620. package/src/resources/extensions/gsd/tests/workspace.test.ts +18 -4
  621. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -1
  622. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +1 -1
  623. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +1 -3
  624. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +1 -1
  625. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +1 -1
  626. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +4 -4
  627. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +2 -2
  628. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +1 -1
  629. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +1 -1
  630. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +2 -1
  631. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +36 -3
  632. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +1 -1
  633. package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +1 -1
  634. package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +32 -0
  635. package/src/resources/extensions/gsd/tool-contract.ts +29 -0
  636. package/src/resources/extensions/gsd/tools/plan-task.ts +107 -9
  637. package/src/resources/extensions/gsd/tools/reopen-slice.ts +5 -0
  638. package/src/resources/extensions/gsd/tools/reopen-task.ts +13 -5
  639. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +58 -0
  640. package/src/resources/extensions/gsd/unit-context-manifest.ts +11 -5
  641. package/src/resources/extensions/gsd/unit-registry.ts +48 -2
  642. package/src/resources/extensions/gsd/unit-runtime.ts +42 -0
  643. package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +1 -1
  644. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -1
  645. package/src/resources/extensions/gsd/workspace-git-preflight.ts +2 -2
  646. package/src/resources/extensions/gsd/workspace.ts +42 -8
  647. package/src/resources/extensions/gsd/worktree-command.ts +1 -1
  648. package/src/resources/extensions/gsd/worktree-lifecycle.ts +154 -26
  649. package/src/resources/extensions/gsd/worktree-manager.ts +143 -5
  650. package/src/resources/extensions/gsd/worktree-reentry.ts +2 -1
  651. package/src/resources/extensions/shared/interview-ui.ts +58 -11
  652. package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +32 -0
  653. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
  654. package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
  655. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
  656. /package/dist/web/standalone/.next/static/{zQLcXm0Za8lexoXtgDpMG → gXoWec4UNqcR0tkuHwYCr}/_buildManifest.js +0 -0
  657. /package/dist/web/standalone/.next/static/{zQLcXm0Za8lexoXtgDpMG → gXoWec4UNqcR0tkuHwYCr}/_ssgManifest.js +0 -0
@@ -1,7 +1,17 @@
1
1
  // gsd-pi + Workspace handle: single source of truth for path resolution per milestone
2
2
 
3
- import { join, resolve } from "node:path";
4
- import { type GsdPathContract, resolveGsdPathContract, normalizeRealPath } from "./paths.js";
3
+ import { dirname, join, resolve } from "node:path";
4
+ import {
5
+ buildMilestoneFileName,
6
+ canonicalPhaseDirName,
7
+ isLegacyMilestonesLayout,
8
+ milestonesDir,
9
+ type GsdPathContract,
10
+ resolveGsdPathContract,
11
+ resolveMilestoneFile,
12
+ resolveMilestonePath,
13
+ normalizeRealPath,
14
+ } from "./paths.js";
5
15
  import { isGsdWorktreePath, resolveWorktreeProjectRoot } from "./worktree-root.js";
6
16
 
7
17
  export type GsdWorkspaceMode = "project" | "worktree";
@@ -31,6 +41,29 @@ function tryRealpath(p: string): string {
31
41
  return normalizeRealPath(p);
32
42
  }
33
43
 
44
+ function isLegacyMilestoneDirectory(dir: string): boolean {
45
+ const parent = dirname(dir);
46
+ return parent.endsWith("/milestones") || parent.endsWith("\\milestones");
47
+ }
48
+
49
+ function scopeMilestoneDir(basePath: string, milestoneId: string): string {
50
+ return resolveMilestonePath(basePath, milestoneId) ?? join(
51
+ milestonesDir(basePath),
52
+ isLegacyMilestonesLayout(basePath) ? milestoneId : canonicalPhaseDirName(milestoneId),
53
+ );
54
+ }
55
+
56
+ function scopeMilestoneFile(basePath: string, milestoneId: string, suffix: string): string {
57
+ const existing = resolveMilestoneFile(basePath, milestoneId, suffix);
58
+ if (existing) return existing;
59
+
60
+ const dir = scopeMilestoneDir(basePath, milestoneId);
61
+ const filename = isLegacyMilestoneDirectory(dir)
62
+ ? `${milestoneId}-${suffix}.md`
63
+ : buildMilestoneFileName(milestoneId, suffix);
64
+ return join(dir, filename);
65
+ }
66
+
34
67
  /**
35
68
  * Create an immutable GsdWorkspace handle from a raw base path.
36
69
  * Resolves both the project root and (when applicable) the worktree root,
@@ -73,22 +106,23 @@ export function createWorkspace(rawBasePath: string): GsdWorkspace {
73
106
  * Bind a milestoneId to a workspace, producing an immutable MilestoneScope
74
107
  * with path-returning closures for DB-authoritative project state.
75
108
  *
76
- * These scope paths intentionally route to contract.projectGsd. In-flight
77
- * markdown artifact readers outside this scope use the projection-aware
78
- * resolvers in paths.ts so worktree units can see worktree-local projections.
109
+ * DB paths route to contract.projectGsd. Milestone artifact paths resolve from
110
+ * the pinned project root with the layout-aware resolvers, so flat-phase and
111
+ * legacy projects use the same scope surface.
79
112
  */
80
113
  export function scopeMilestone(workspace: GsdWorkspace, milestoneId: string): MilestoneScope {
81
114
  const { contract } = workspace;
82
115
  const gsd = contract.projectGsd;
116
+ const basePath = workspace.projectRoot;
83
117
 
84
118
  const scope: MilestoneScope = Object.freeze({
85
119
  workspace,
86
120
  milestoneId,
87
- contextFile: () => join(gsd, "milestones", milestoneId, `${milestoneId}-CONTEXT.md`),
88
- roadmapFile: () => join(gsd, "milestones", milestoneId, `${milestoneId}-ROADMAP.md`),
121
+ contextFile: () => scopeMilestoneFile(basePath, milestoneId, "CONTEXT"),
122
+ roadmapFile: () => scopeMilestoneFile(basePath, milestoneId, "ROADMAP"),
89
123
  stateFile: () => join(gsd, "STATE.md"),
90
124
  dbPath: () => contract.projectDb,
91
- milestoneDir: () => join(gsd, "milestones", milestoneId),
125
+ milestoneDir: () => scopeMilestoneDir(basePath, milestoneId),
92
126
  metaJson: () => join(gsd, `${milestoneId}-META.json`),
93
127
  });
94
128
 
@@ -13,7 +13,7 @@
13
13
  import type { ExtensionAPI, ExtensionCommandContext } from "@gsd/pi-coding-agent";
14
14
  import { loadPrompt } from "./prompt-loader.js";
15
15
  import { autoCommitCurrentBranch, getMainBranch, resolveGitHeadPath, nudgeGitBranchCache } from "./worktree.js";
16
- import { runWorktreePostCreateHook } from "./auto-worktree.js";
16
+ import { runWorktreePostCreateHook } from "./worktree-post-create-hook.js";
17
17
  import { showConfirm } from "../shared/tui.js";
18
18
  import { gsdRoot, milestonesDir, resolveGsdPathContract } from "./paths.js";
19
19
  import {
@@ -21,6 +21,8 @@ import { existsSync, readFileSync, unlinkSync } from "node:fs";
21
21
  import { randomUUID } from "node:crypto";
22
22
  import { join } from "node:path";
23
23
 
24
+ import type { PreflightResult, PostflightResult } from "./clean-root-preflight.js";
25
+
24
26
  import type { AutoSession } from "./auto/session.js";
25
27
  import { debugLog } from "./debug-logger.js";
26
28
  import { logWarning } from "./workflow-logger.js";
@@ -66,19 +68,21 @@ import {
66
68
  getCurrentBranch,
67
69
  } from "./worktree.js";
68
70
  import { nativeCheckoutBranch } from "./native-git-bridge.js";
69
- // ADR-016 phase 2 / C2 (#5625): worktree-manager helpers inlined from
70
- // `./auto-worktree.js`. These seven functions are not real seams — Lifecycle
71
- // is the only Module that calls them, and they live alongside the Module's
72
- // other primitives in `auto-worktree.ts`.
71
+ // ADR-016 phase 2 / C2 (#5625): lifecycle uses focused auto-worktree
72
+ // modules instead of the legacy compatibility barrel. Branch, entry/path,
73
+ // creation, and teardown primitives are still implementation-level seams for
74
+ // Lifecycle; tests vary them through `WorktreeLifecycleTestOverrides` below.
73
75
  import {
74
76
  autoWorktreeBranch,
75
- createAutoWorktree,
76
- enterAutoWorktree,
77
77
  enterBranchModeForMilestone,
78
- getAutoWorktreePath,
78
+ } from "./auto-worktree-branch-lifecycle.js";
79
+ import { createAutoWorktree } from "./auto-worktree-creation.js";
80
+ import {
81
+ enterAutoWorktree,
79
82
  isInAutoWorktree,
80
- teardownAutoWorktree,
81
- } from "./auto-worktree.js";
83
+ } from "./auto-worktree-entry.js";
84
+ import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
85
+ import { teardownAutoWorktree } from "./auto-worktree-teardown.js";
82
86
  import { resolveRoadmapForMilestoneMerge } from "./milestone-merge-roadmap.js";
83
87
  import type { MilestoneMergeTransactionRunner } from "./milestone-merge-transaction.js";
84
88
 
@@ -153,11 +157,11 @@ export interface WorktreeLifecycleDeps {
153
157
  /**
154
158
  * Milestone Merge Transaction Module runner.
155
159
  *
156
- * The field name is preserved for existing test fixtures, but production
157
- * wiring now supplies the named transaction wrapper rather than the raw
158
- * squash-merge primitive directly.
160
+ * The field name describes the lifecycle seam; production wiring supplies
161
+ * the named transaction wrapper rather than the raw legacy
162
+ * auto-worktree primitive directly.
159
163
  */
160
- mergeMilestoneToMain: MilestoneMergeTransactionRunner;
164
+ mergeMilestone: MilestoneMergeTransactionRunner;
161
165
 
162
166
  // ADR-016 phase 2 / C1 + C2 + C3 + C4 inlined the following fields as
163
167
  // direct imports — leaf primitives that did not vary across callers:
@@ -238,7 +242,106 @@ export interface StrandedMilestoneAdoptionOptions {
238
242
 
239
243
  export type ExitResult =
240
244
  | { ok: true; merged: boolean; codeFilesChanged: boolean }
241
- | { ok: false; reason: "merge-conflict" | "teardown-failed"; cause?: unknown };
245
+ | {
246
+ ok: false;
247
+ reason:
248
+ | "merge-conflict"
249
+ | "teardown-failed"
250
+ | "preflight-dirty-overlap"
251
+ | "preflight-unmerged-conflicts"
252
+ | "merge-failed"
253
+ | "postflight-stash-restore-failed";
254
+ cause?: unknown;
255
+ postflight?: PostflightResult;
256
+ };
257
+
258
+ export interface GuardedMilestoneMergeDeps {
259
+ preflightCleanRoot: (
260
+ basePath: string,
261
+ milestoneId: string,
262
+ notify: NotifyCtx["notify"],
263
+ ) => PreflightResult;
264
+ postflightPopStash: (
265
+ basePath: string,
266
+ milestoneId: string,
267
+ stashMarker: string | undefined,
268
+ notify: NotifyCtx["notify"],
269
+ ) => PostflightResult;
270
+ }
271
+
272
+ /**
273
+ * Optional `exitMilestone(..., { merge: true, guardedMerge })` contract for callers
274
+ * that need root-clean preflight and postflight stash restoration around the
275
+ * lifecycle-owned merge attempt. `projectRoot` is the workspace root whose
276
+ * user changes are protected by the supplied guard functions.
277
+ */
278
+ export interface GuardedMilestoneMergeOptions extends GuardedMilestoneMergeDeps {
279
+ projectRoot: string;
280
+ }
281
+
282
+ type GuardedMilestoneMergeResult = ExitResult;
283
+
284
+ function preflightBlockedMergeReason(
285
+ blockedReason: PreflightResult["blockedReason"],
286
+ ): Extract<ExitResult, { ok: false }>["reason"] {
287
+ if (blockedReason?.startsWith("unmerged-conflicts")) {
288
+ return "preflight-unmerged-conflicts";
289
+ }
290
+ return "preflight-dirty-overlap";
291
+ }
292
+
293
+ /**
294
+ * Run a milestone merge behind the Worktree Lifecycle seam with the root-clean
295
+ * stash guard that protects user changes around merge.
296
+ *
297
+ * The helper owns the invariant ordering (preflight -> merge callback ->
298
+ * postflight on every attempted merge path) and returns the same typed result
299
+ * shape as `exitMilestone`. Auto closeout remains responsible for translating
300
+ * that result into loop policy (pause vs. stop, visible transcript
301
+ * preservation, projection rebuild).
302
+ */
303
+ function runGuardedMilestoneMerge(request: {
304
+ merge: () => ExitResult;
305
+ guard: GuardedMilestoneMergeOptions;
306
+ milestoneId: string;
307
+ notify: NotifyCtx["notify"];
308
+ }): GuardedMilestoneMergeResult {
309
+ const { merge, guard, milestoneId, notify } = request;
310
+ const preflight = guard.preflightCleanRoot(guard.projectRoot, milestoneId, notify);
311
+ if (preflight.blocked) {
312
+ return {
313
+ ok: false,
314
+ reason: preflightBlockedMergeReason(preflight.blockedReason),
315
+ };
316
+ }
317
+
318
+ let mergeError: unknown = null;
319
+ const exitResult = merge();
320
+ if (!exitResult.ok) {
321
+ mergeError = exitResult.cause ?? new Error(`exit ${exitResult.reason}`);
322
+ }
323
+
324
+ let postflight: PostflightResult | undefined;
325
+ if (preflight.stashPushed) {
326
+ postflight = guard.postflightPopStash(
327
+ guard.projectRoot,
328
+ milestoneId,
329
+ preflight.stashMarker,
330
+ notify,
331
+ );
332
+ }
333
+
334
+ if (mergeError instanceof MergeConflictError) {
335
+ return { ok: false, reason: "merge-conflict", cause: mergeError, postflight };
336
+ }
337
+ if (mergeError) {
338
+ return { ok: false, reason: "merge-failed", cause: mergeError, postflight };
339
+ }
340
+ if (postflight?.needsManualRecovery) {
341
+ return { ok: false, reason: "postflight-stash-restore-failed", postflight };
342
+ }
343
+ return exitResult;
344
+ }
242
345
 
243
346
  /**
244
347
  * Session-less merge entry context. Per ADR-016 phase 2 / A1 (#5616), the
@@ -252,7 +355,7 @@ export interface MergeContext {
252
355
  originalBasePath: string;
253
356
  /**
254
357
  * Current worktree path or project root when in branch mode. Used as the
255
- * cwd anchor for `mergeMilestoneToMain` and the source for
358
+ * cwd anchor for the milestone merge transaction and the source for
256
359
  * `Projection.finalizeProjectionForMerge`.
257
360
  */
258
361
  worktreeBasePath: string;
@@ -280,7 +383,8 @@ export interface MergeStandaloneResult {
280
383
  pushed: boolean;
281
384
  /**
282
385
  * Commit message produced by the squash merge, if available. Forwarded
283
- * from `mergeMilestoneToMain`. Only populated when `merged === true`.
386
+ * from the milestone merge transaction. Only populated when
387
+ * `merged === true`.
284
388
  */
285
389
  commitMessage?: string;
286
390
  }
@@ -1046,7 +1150,7 @@ function _mergeWorktreeModeImpl(
1046
1150
  };
1047
1151
  }
1048
1152
 
1049
- const mergeResult = deps.mergeMilestoneToMain(
1153
+ const mergeResult = deps.mergeMilestone(
1050
1154
  originalBasePath,
1051
1155
  milestoneId,
1052
1156
  roadmapResolution.content,
@@ -1213,7 +1317,7 @@ function _mergeBranchModeImpl(
1213
1317
  };
1214
1318
  }
1215
1319
 
1216
- const mergeResult = deps.mergeMilestoneToMain(
1320
+ const mergeResult = deps.mergeMilestone(
1217
1321
  worktreeBasePath,
1218
1322
  milestoneId,
1219
1323
  roadmapResolution.content,
@@ -1272,8 +1376,9 @@ function _mergeBranchModeImpl(
1272
1376
  * **CWD anchor**: anchors `process.cwd()` at `originalBasePath` before
1273
1377
  * non-worktree merge paths to mirror the single-loop guard against ENOENT
1274
1378
  * after teardown (de73fb43d). Worktree-mode merge paths keep the real
1275
- * worktree as cwd because `mergeMilestoneToMain()` infers source worktree
1276
- * state from `process.cwd()`. Best-effort; silent on failure.
1379
+ * worktree as cwd because the default milestone merge transaction delegates
1380
+ * to the legacy merge primitive, which infers source worktree state from
1381
+ * `process.cwd()`. Best-effort; silent on failure.
1277
1382
  *
1278
1383
  * **Failure handling**: `MergeConflictError` and other unrecoverable errors
1279
1384
  * propagate to the caller. The caller is responsible for any state restore
@@ -1374,8 +1479,8 @@ export function mergeMilestoneStandalone(
1374
1479
 
1375
1480
  // Set cwd to the correct anchor before dispatching to mode implementations.
1376
1481
  // Worktree mode / in-worktree override must run from the live worktree so
1377
- // mergeMilestoneToMain can find worktree-local state; branch mode runs from
1378
- // the original project root. Best-effort for synthetic test paths.
1482
+ // The default merge transaction can find worktree-local state; branch mode
1483
+ // runs from the original project root. Best-effort for synthetic test paths.
1379
1484
  const targetCwd = mode === "worktree" || inWorktree
1380
1485
  ? worktreeBasePath
1381
1486
  : originalBasePath;
@@ -1444,18 +1549,41 @@ export class WorktreeLifecycle {
1444
1549
  * With `opts.merge === false`, runs auto-commit and teardown without
1445
1550
  * merging to main.
1446
1551
  *
1552
+ * When `opts.guardedMerge` is present with `opts.merge === true`, the
1553
+ * lifecycle verb also owns the root-clean guard around the merge: preflight
1554
+ * runs before the inner merge, postflight stash restore runs after every
1555
+ * attempted merge path, and guard failures are returned as typed
1556
+ * `ExitResult` reasons.
1557
+ *
1447
1558
  * Returns a typed `ExitResult`. `MergeConflictError` is surfaced as
1448
1559
  * `{ ok: false, reason: "merge-conflict", cause }` instead of thrown,
1449
- * giving callers a typed branch for the expected failure path.
1450
- * Unexpected failures (filesystem, git permissions, etc.) are wrapped
1451
- * as `{ ok: false, reason: "teardown-failed", cause }` so callers always
1560
+ * giving callers a typed branch for the expected failure path. Guarded merge
1561
+ * failures surface as `preflight-dirty-overlap`,
1562
+ * `preflight-unmerged-conflicts`, `merge-failed`, or
1563
+ * `postflight-stash-restore-failed`. Unexpected failures (filesystem, git
1564
+ * permissions, etc.) are wrapped as
1565
+ * `{ ok: false, reason: "teardown-failed", cause }` so callers always
1452
1566
  * receive a discriminated union — no exceptions for any expected outcome.
1453
1567
  */
1454
1568
  exitMilestone(
1455
1569
  milestoneId: string,
1456
- opts: { merge: boolean; preserveBranch?: boolean; preserveWorktree?: boolean },
1570
+ opts: {
1571
+ merge: boolean;
1572
+ preserveBranch?: boolean;
1573
+ preserveWorktree?: boolean;
1574
+ guardedMerge?: GuardedMilestoneMergeOptions;
1575
+ },
1457
1576
  ctx: NotifyCtx,
1458
1577
  ): ExitResult {
1578
+ if (opts.merge && opts.guardedMerge) {
1579
+ return runGuardedMilestoneMerge({
1580
+ merge: () => this.exitMilestone(milestoneId, { merge: true }, ctx),
1581
+ guard: opts.guardedMerge,
1582
+ milestoneId,
1583
+ notify: ctx.notify,
1584
+ });
1585
+ }
1586
+
1459
1587
  if (opts.merge) {
1460
1588
  try {
1461
1589
  const merged = this._mergeAndExit(milestoneId, ctx);
@@ -19,7 +19,7 @@
19
19
  * 4. remove() — git worktree remove + branch cleanup
20
20
  */
21
21
 
22
- import { existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, rmSync, statSync, unlinkSync } from "node:fs";
22
+ import { cpSync, existsSync, lstatSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from "node:fs";
23
23
  import { execFileSync } from "node:child_process";
24
24
  import { join, resolve, sep } from "node:path";
25
25
  import { GSDError, GSD_PARSE_ERROR, GSD_STALE_STATE, GSD_LOCK_HELD, GSD_GIT_ERROR, GSD_MERGE_CONFLICT } from "./errors.js";
@@ -227,6 +227,113 @@ function isRegisteredGitWorktreeAtPath(basePath: string, wtPath: string): boolea
227
227
  }
228
228
  }
229
229
 
230
+ function inspectUncommittedWorktreeState(wtPath: string): { dirty: boolean; status: string } {
231
+ try {
232
+ const status = execFileSync(
233
+ "git",
234
+ ["status", "--porcelain=v1", "--untracked-files=all"],
235
+ { cwd: wtPath, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" },
236
+ ).trimEnd();
237
+ return { dirty: status.length > 0, status };
238
+ } catch (err) {
239
+ const message = err instanceof Error ? err.message : String(err);
240
+ logWarning(
241
+ "worktree",
242
+ `dirty worktree inspection failed for ${wtPath}: ${message}`,
243
+ );
244
+ // Fail closed: unknown state must quarantine rather than force-remove.
245
+ return { dirty: true, status: `git status failed: ${message}` };
246
+ }
247
+ }
248
+
249
+ function timestampForPath(): string {
250
+ return new Date().toISOString().replace(/[:.]/g, "-");
251
+ }
252
+
253
+ function uniqueQuarantinePath(basePath: string, name: string): string {
254
+ const root = join(basePath, ".gsd", "quarantine", "worktrees");
255
+ const baseName = `${name}-${timestampForPath()}`;
256
+ let candidate = join(root, baseName);
257
+ let suffix = 2;
258
+ while (existsSync(candidate)) {
259
+ candidate = join(root, `${baseName}-${suffix}`);
260
+ suffix++;
261
+ }
262
+ return candidate;
263
+ }
264
+
265
+ function quarantineDirtyWorktree(
266
+ basePath: string,
267
+ name: string,
268
+ branch: string,
269
+ wtPath: string,
270
+ status: string,
271
+ ): string | null {
272
+ const quarantinePath = uniqueQuarantinePath(basePath, name);
273
+ mkdirSync(join(basePath, ".gsd", "quarantine", "worktrees"), { recursive: true });
274
+
275
+ let moved = false;
276
+ try {
277
+ renameSync(wtPath, quarantinePath);
278
+ moved = true;
279
+ } catch (renameErr) {
280
+ logWarning(
281
+ "worktree",
282
+ `dirty worktree rename quarantine failed for ${name}: ${renameErr instanceof Error ? renameErr.message : String(renameErr)}; trying copy snapshot`,
283
+ );
284
+ try {
285
+ cpSync(wtPath, quarantinePath, { recursive: true, force: false, errorOnExist: true });
286
+ } catch (copyErr) {
287
+ logWarning(
288
+ "reconcile",
289
+ `Dirty worktree quarantine failed; preserving original worktree ${wtPath}: ${copyErr instanceof Error ? copyErr.message : String(copyErr)}`,
290
+ { worktree: name, path: wtPath },
291
+ );
292
+ return null;
293
+ }
294
+ }
295
+
296
+ try {
297
+ const gitFile = join(quarantinePath, ".git");
298
+ if (existsSync(gitFile) && lstatSync(gitFile).isFile()) {
299
+ unlinkSync(gitFile);
300
+ }
301
+ } catch (err) {
302
+ logWarning(
303
+ "worktree",
304
+ `failed to remove quarantined worktree git pointer: ${err instanceof Error ? err.message : String(err)}`,
305
+ );
306
+ }
307
+
308
+ try {
309
+ writeFileSync(
310
+ join(quarantinePath, ".gsd-quarantine.json"),
311
+ JSON.stringify({
312
+ kind: "dirty-worktree",
313
+ worktree: name,
314
+ branch,
315
+ originalPath: wtPath,
316
+ moved,
317
+ quarantinedAt: new Date().toISOString(),
318
+ status,
319
+ }, null, 2) + "\n",
320
+ "utf-8",
321
+ );
322
+ } catch (err) {
323
+ logWarning(
324
+ "worktree",
325
+ `failed to write worktree quarantine metadata: ${err instanceof Error ? err.message : String(err)}`,
326
+ );
327
+ }
328
+
329
+ logWarning(
330
+ "reconcile",
331
+ `Quarantined dirty worktree ${name} at ${quarantinePath} before removal. Branch ${branch} was preserved.`,
332
+ { worktree: name, path: quarantinePath, branch },
333
+ );
334
+ return quarantinePath;
335
+ }
336
+
230
337
  /** True when `wtPath` has a git worktree checkout marker (`.git` file with gitdir pointer). */
231
338
  export function isLiveGitWorktreeCheckout(wtPath: string): boolean {
232
339
  const gitPath = join(wtPath, ".git");
@@ -730,12 +837,13 @@ export function removeWorktree(
730
837
  basePath: string,
731
838
  name: string,
732
839
  opts: { deleteBranch?: boolean; force?: boolean; branch?: string } = {},
733
- ): void {
840
+ ): boolean {
734
841
  basePath = normalizeBasePathForWorktreeOps(basePath);
735
842
 
736
843
  let wtPath = worktreePath(basePath, name);
737
844
  const branch = opts.branch ?? worktreeBranchName(name);
738
845
  const { deleteBranch = true, force = true } = opts;
846
+ let deleteBranchAfterRemoval = deleteBranch;
739
847
 
740
848
  // Resolve the ACTUAL worktree path from git's worktree list.
741
849
  // The computed path may differ when .gsd/ is (or was) a symlink to an
@@ -788,10 +896,10 @@ export function removeWorktree(
788
896
 
789
897
  if (!existsSync(wtPath)) {
790
898
  nativeWorktreePrune(basePath);
791
- if (deleteBranch) {
899
+ if (deleteBranchAfterRemoval) {
792
900
  deleteBranchIfPresent(basePath, branch, "nativeBranchDelete failed");
793
901
  }
794
- return;
902
+ return true;
795
903
  }
796
904
 
797
905
  // Submodule safety (#2337): detect submodules with uncommitted changes
@@ -873,6 +981,35 @@ export function removeWorktree(
873
981
  }
874
982
  }
875
983
 
984
+ // Dirty-worktree quarantine (#2365): once submodule (#2337) and nested-.git
985
+ // (#2616) rescue have run — they commit/clean the tree first — quarantine any
986
+ // uncommitted state that remains instead of force-deleting it. Gate on a live
987
+ // git checkout so a stale local directory left behind by state-sync (which
988
+ // has no `.git` file and is not a registered worktree) is removed normally
989
+ // rather than quarantined; otherwise its branch would never be deleted and
990
+ // the worktree would never be unregistered (#1852).
991
+ if (force && resolvedPathSafe && isLiveGitWorktreeCheckout(resolvedWtPath)) {
992
+ const dirtyState = inspectUncommittedWorktreeState(resolvedWtPath);
993
+ if (dirtyState.dirty) {
994
+ const quarantinePath = quarantineDirtyWorktree(
995
+ basePath,
996
+ name,
997
+ branch,
998
+ resolvedWtPath,
999
+ dirtyState.status,
1000
+ );
1001
+ if (!quarantinePath) {
1002
+ return false;
1003
+ }
1004
+
1005
+ deleteBranchAfterRemoval = false;
1006
+ if (!existsSync(resolvedWtPath)) {
1007
+ nativeWorktreePrune(basePath);
1008
+ return true;
1009
+ }
1010
+ }
1011
+ }
1012
+
876
1013
  // Remove worktree — only use force/rmSync when the path is safely contained
877
1014
  if (resolvedPathSafe) {
878
1015
  // Remove worktree: try non-force first when submodules have changes,
@@ -923,9 +1060,10 @@ export function removeWorktree(
923
1060
  // Prune stale entries so git knows the worktree is gone
924
1061
  nativeWorktreePrune(basePath);
925
1062
 
926
- if (deleteBranch) {
1063
+ if (deleteBranchAfterRemoval) {
927
1064
  deleteBranchIfPresent(basePath, branch, "final branch delete failed");
928
1065
  }
1066
+ return true;
929
1067
  }
930
1068
 
931
1069
  /**
@@ -8,7 +8,8 @@
8
8
 
9
9
  import { readdirSync } from "node:fs";
10
10
 
11
- import { enterAutoWorktree, getAutoWorktreePath } from "./auto-worktree.js";
11
+ import { enterAutoWorktree } from "./auto-worktree-entry.js";
12
+ import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
12
13
  import { getIsolationMode } from "./preferences.js";
13
14
  import { allWorktreesDirs } from "./worktree-manager.js";
14
15
  import { isGsdWorktreePath, resolveWorktreeProjectRoot } from "./worktree-root.js";