@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
@@ -14,7 +14,8 @@ import { join } from "node:path";
14
14
  import { tmpdir } from "node:os";
15
15
  import { execFileSync } from "node:child_process";
16
16
 
17
- import { createAutoWorktree, teardownAutoWorktree } from "../auto-worktree.ts";
17
+ import { createAutoWorktree } from "../auto-worktree-creation.ts";
18
+ import { teardownAutoWorktree } from "../auto-worktree-teardown.ts";
18
19
 
19
20
  function git(args: string[], cwd: string): void {
20
21
  execFileSync("git", args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
@@ -22,7 +22,7 @@ import {
22
22
  isSessionSwitchAbortGraceActive,
23
23
  } from "../auto/resolve.js";
24
24
  import { runUnit, shouldDeferUnitFailsafeTimeout } from "../auto/run-unit.js";
25
- import { scheduleAutoWakeup, _resetAutoWakeupsForTest } from "../auto/schedule-wakeup.js";
25
+ import { consumeAutoWakeup, scheduleAutoWakeup, _resetAutoWakeupsForTest } from "../auto/schedule-wakeup.js";
26
26
  import { writeUnitRuntimeRecord, readUnitRuntimeRecord } from "../unit-runtime.js";
27
27
  import { autoLoop as rawAutoLoop } from "../auto/loop.js";
28
28
  import { runPreDispatch } from "../auto/pre-dispatch.js";
@@ -67,6 +67,76 @@ async function drainMicrotasks(turns = 20): Promise<void> {
67
67
  }
68
68
  }
69
69
 
70
+ function guardedExitMilestoneForTest(
71
+ merge: (milestoneId: string, opts: { merge: boolean }) => {
72
+ ok: boolean;
73
+ merged?: boolean;
74
+ codeFilesChanged?: boolean;
75
+ reason?: string;
76
+ cause?: unknown;
77
+ },
78
+ ) {
79
+ return (
80
+ milestoneId: string,
81
+ opts: {
82
+ merge: boolean;
83
+ guardedMerge?: {
84
+ projectRoot: string;
85
+ preflightCleanRoot: (
86
+ basePath: string,
87
+ milestoneId: string,
88
+ notify: (message: string, level: "info" | "warning" | "error") => void,
89
+ ) => { blocked?: boolean; blockedReason?: string; stashPushed: boolean; stashMarker?: string };
90
+ postflightPopStash: (
91
+ basePath: string,
92
+ milestoneId: string,
93
+ stashMarker: string | undefined,
94
+ notify: (message: string, level: "info" | "warning" | "error") => void,
95
+ ) => { needsManualRecovery?: boolean };
96
+ };
97
+ },
98
+ ctx?: { notify: (message: string, level: "info" | "warning" | "error") => void },
99
+ ) => {
100
+ const notify = ctx?.notify ?? (() => {});
101
+ const guard = opts.guardedMerge;
102
+ if (opts.merge && guard) {
103
+ const preflight = guard.preflightCleanRoot(guard.projectRoot, milestoneId, notify);
104
+ if (preflight.blocked) {
105
+ return {
106
+ ok: false,
107
+ reason: preflight.blockedReason?.startsWith("unmerged-conflicts")
108
+ ? "preflight-unmerged-conflicts"
109
+ : "preflight-dirty-overlap",
110
+ };
111
+ }
112
+
113
+ const mergeResult = merge(milestoneId, { merge: true });
114
+ const postflight = preflight.stashPushed
115
+ ? guard.postflightPopStash(
116
+ guard.projectRoot,
117
+ milestoneId,
118
+ preflight.stashMarker,
119
+ notify,
120
+ )
121
+ : undefined;
122
+
123
+ if (!mergeResult.ok) {
124
+ return {
125
+ ok: false,
126
+ reason: mergeResult.reason === "merge-conflict" ? "merge-conflict" : "merge-failed",
127
+ cause: mergeResult.cause,
128
+ postflight,
129
+ };
130
+ }
131
+ if (postflight?.needsManualRecovery) {
132
+ return { ok: false, reason: "postflight-stash-restore-failed", postflight };
133
+ }
134
+ return mergeResult;
135
+ }
136
+ return merge(milestoneId, opts);
137
+ };
138
+ }
139
+
70
140
  async function waitForMicrotasks(
71
141
  condition: () => boolean,
72
142
  label: string,
@@ -482,6 +552,62 @@ test("runUnit honors ScheduleWakeup by continuing the same unit session", async
482
552
  assert.equal(pi.calls.length, 2);
483
553
  });
484
554
 
555
+ test("runUnit clears scheduled wakeups when the unit is cancelled", async () => {
556
+ _resetPendingResolve();
557
+ _resetAutoWakeupsForTest();
558
+
559
+ const ctx = {
560
+ ...makeMockCtx(),
561
+ ui: {
562
+ notify: () => {},
563
+ setStatus: () => {},
564
+ setWorkingMessage: () => {},
565
+ },
566
+ sessionManager: {
567
+ getEntries: () => [],
568
+ },
569
+ modelRegistry: {
570
+ getProviderAuthMode: () => undefined,
571
+ isProviderRequestReady: () => true,
572
+ },
573
+ } as any;
574
+ const pi = makeMockPi();
575
+ const s = makeMockSession();
576
+
577
+ const resultPromise = runUnit(
578
+ ctx,
579
+ pi,
580
+ s,
581
+ "execute-task",
582
+ "M001/S01/T02",
583
+ "submit external job",
584
+ );
585
+
586
+ await waitForMicrotasks(() => pi.calls.length === 1, "initial unit dispatch");
587
+ scheduleAutoWakeup({
588
+ basePath: s.basePath,
589
+ unitType: "execute-task",
590
+ unitId: "M001/S01/T02",
591
+ delayMs: 0,
592
+ prompt: "stale prompt from cancelled unit",
593
+ reason: "poll external job",
594
+ createdAt: Date.now(),
595
+ });
596
+ resolveAgentEndCancelled({
597
+ message: "Auto-mode paused",
598
+ category: "aborted",
599
+ isTransient: true,
600
+ });
601
+
602
+ const result = await resultPromise;
603
+ assert.equal(result.status, "cancelled");
604
+ assert.equal(
605
+ consumeAutoWakeup(s.basePath, "execute-task", "M001/S01/T02"),
606
+ null,
607
+ "cancelled units must not leave stale ScheduleWakeup prompts for later retries",
608
+ );
609
+ });
610
+
485
611
  test("runUnit suppresses the global working-message loader for auto dashboard runs", async () => {
486
612
  _resetPendingResolve();
487
613
  const workingMessages: unknown[] = [];
@@ -1335,11 +1461,11 @@ function makeMockDeps(
1335
1461
  GitServiceImpl: class {} as any,
1336
1462
  lifecycle: {
1337
1463
  enterMilestone: () => ({ ok: true, mode: "worktree", path: "/tmp/project" }),
1338
- exitMilestone: (_mid: string, opts: { merge: boolean }) => ({
1464
+ exitMilestone: guardedExitMilestoneForTest((_mid, opts) => ({
1339
1465
  ok: true,
1340
1466
  merged: opts.merge,
1341
1467
  codeFilesChanged: false,
1342
- }),
1468
+ })),
1343
1469
  } as any,
1344
1470
  worktreeProjection: new WorktreeStateProjection(),
1345
1471
  postUnitPreVerification: async () => {
@@ -1762,10 +1888,10 @@ test("autoLoop marks transition merge complete before postflight recovery stop",
1762
1888
  enterMilestone: () => {
1763
1889
  assert.fail("must not enter the next milestone after postflight recovery fails");
1764
1890
  },
1765
- exitMilestone: (_mid: string, opts: { merge: boolean }) => {
1891
+ exitMilestone: guardedExitMilestoneForTest((_mid, opts) => {
1766
1892
  if (opts.merge) mergeCalls += 1;
1767
1893
  return { ok: true, merged: opts.merge, codeFilesChanged: false };
1768
- },
1894
+ }),
1769
1895
  } as any,
1770
1896
  stopAuto: async (_ctx, _pi, reason) => {
1771
1897
  deps.callLog.push("stopAuto");
@@ -49,6 +49,24 @@ test("recoverFailedMigration returns false when both .gsd and .gsd.migrating exi
49
49
  assert.ok(existsSync(join(base, ".gsd.migrating")), ".gsd.migrating must still exist");
50
50
  });
51
51
 
52
+ test("recoverFailedMigration removes orphan when .gsd is a real intact directory", (t) => {
53
+ const base = mkdtempSync(join(tmpdir(), "gsd-migrating-real-orphan-"));
54
+ t.after(() => rmSync(base, { recursive: true, force: true }));
55
+
56
+ const localGsd = join(base, ".gsd");
57
+ mkdirSync(join(localGsd, "phases"), { recursive: true });
58
+ mkdirSync(join(localGsd, "activity"), { recursive: true });
59
+ writeFileSync(join(localGsd, "STATE.md"), "# State\n", "utf-8");
60
+ writeFileSync(join(localGsd, "gsd.db"), "not empty\n", "utf-8");
61
+ mkdirSync(join(base, ".gsd.migrating"), { recursive: true });
62
+
63
+ const recovered = recoverFailedMigration(base);
64
+
65
+ assert.equal(recovered, true, "expected orphan cleanup to succeed");
66
+ assert.ok(existsSync(localGsd), ".gsd real directory must remain");
67
+ assert.ok(!existsSync(join(base, ".gsd.migrating")), ".gsd.migrating orphan must be removed");
68
+ });
69
+
52
70
  test("recoverFailedMigration removes orphan when .gsd is an intact external-state junction", (t) => {
53
71
  const base = mkdtempSync(join(tmpdir(), "gsd-migrating-orphan-"));
54
72
  const stateDir = mkdtempSync(join(tmpdir(), "gsd-migrating-state-"));
@@ -63,6 +63,62 @@ test("resolvePreferredModelConfig synthesizes heavy routing ceiling when models
63
63
  }
64
64
  });
65
65
 
66
+ test("resolvePreferredModelConfig treats token-profile model defaults as synthesized routing", () => {
67
+ const originalCwd = process.cwd();
68
+ const originalGsdHome = process.env.GSD_HOME;
69
+ const tempProject = makeTempDir("gsd-routing-profile-project-");
70
+ const tempGsdHome = makeTempDir("gsd-routing-profile-home-");
71
+
72
+ try {
73
+ mkdirSync(join(tempProject, ".gsd"), { recursive: true });
74
+ writeFileSync(
75
+ join(tempProject, ".gsd", "PREFERENCES.md"),
76
+ [
77
+ "---",
78
+ "token_profile: quality",
79
+ "dynamic_routing:",
80
+ " enabled: true",
81
+ " tier_models:",
82
+ " light: claude-haiku-4-5",
83
+ " standard: claude-sonnet-4-6",
84
+ " heavy: claude-opus-4-6",
85
+ "---",
86
+ ].join("\n"),
87
+ "utf-8",
88
+ );
89
+ process.env.GSD_HOME = tempGsdHome;
90
+ process.chdir(tempProject);
91
+
92
+ const config = resolvePreferredModelConfig(
93
+ "plan-slice",
94
+ {
95
+ provider: "anthropic",
96
+ id: "claude-sonnet-4-6",
97
+ },
98
+ true,
99
+ tempProject,
100
+ [
101
+ "anthropic/claude-haiku-4-5",
102
+ "anthropic/claude-sonnet-4-6",
103
+ "anthropic/claude-opus-4-6",
104
+ ],
105
+ "anthropic/claude-sonnet-4-6",
106
+ );
107
+
108
+ assert.deepEqual(config, {
109
+ primary: "claude-opus-4-6",
110
+ fallbacks: [],
111
+ source: "synthesized",
112
+ });
113
+ } finally {
114
+ process.chdir(originalCwd);
115
+ if (originalGsdHome === undefined) delete process.env.GSD_HOME;
116
+ else process.env.GSD_HOME = originalGsdHome;
117
+ rmSync(tempProject, { recursive: true, force: true });
118
+ rmSync(tempGsdHome, { recursive: true, force: true });
119
+ }
120
+ });
121
+
66
122
  test("resolvePreferredModelConfig falls back to auto start model when heavy tier is absent", () => {
67
123
  const originalCwd = process.cwd();
68
124
  const originalGsdHome = process.env.GSD_HOME;
@@ -152,6 +208,128 @@ test("resolvePreferredModelConfig keeps explicit phase models as the ceiling", (
152
208
  }
153
209
  });
154
210
 
211
+ // #1115 regression: a token_profile with dynamic_routing enabled but NO
212
+ // tier_models pins must still resolve the profile's per-phase model as a
213
+ // synthesized routing ceiling. Before the fix, resolvePreferredModelConfig
214
+ // bailed to undefined here (explicit detection skips profile defaults, and the
215
+ // synthesis path required tier_models), so auto dispatch fell back to the
216
+ // start model for every unit and silently discarded the profile.
217
+ test("resolvePreferredModelConfig resolves profile per-phase models as synthesized when tier_models are absent", () => {
218
+ const originalCwd = process.cwd();
219
+ const originalGsdHome = process.env.GSD_HOME;
220
+ const tempProject = makeTempDir("gsd-routing-profile-notier-");
221
+ const tempGsdHome = makeTempDir("gsd-routing-profile-notier-home-");
222
+
223
+ try {
224
+ mkdirSync(join(tempProject, ".gsd"), { recursive: true });
225
+ writeFileSync(
226
+ join(tempProject, ".gsd", "PREFERENCES.md"),
227
+ [
228
+ "---",
229
+ "token_profile: budget",
230
+ "dynamic_routing:",
231
+ " enabled: true",
232
+ "---",
233
+ ].join("\n"),
234
+ "utf-8",
235
+ );
236
+ process.env.GSD_HOME = tempGsdHome;
237
+ process.chdir(tempProject);
238
+
239
+ const availableModelIds = [
240
+ "anthropic/claude-haiku-4-5",
241
+ "anthropic/claude-sonnet-4-6",
242
+ "anthropic/claude-opus-4-6",
243
+ ];
244
+ const start = { provider: "anthropic", id: "claude-sonnet-4-6" };
245
+ // preferredModelId is intentionally left undefined so profile tier
246
+ // resolution is exercised rather than pinning every tier to the session
247
+ // model (a heavy session model can satisfy every tier).
248
+ const resolve = (unitType: string) =>
249
+ resolvePreferredModelConfig(unitType, start, true, tempProject, availableModelIds);
250
+
251
+ // budget profile: research=light, planning=standard, execution=standard,
252
+ // execution_simple=light, completion=light (PROFILE_TIER_MAP).
253
+ assert.deepEqual(resolve("research-milestone"), {
254
+ primary: "claude-haiku-4-5",
255
+ fallbacks: [],
256
+ source: "synthesized",
257
+ });
258
+ assert.deepEqual(resolve("plan-milestone"), {
259
+ primary: "claude-sonnet-4-6",
260
+ fallbacks: [],
261
+ source: "synthesized",
262
+ });
263
+ assert.deepEqual(resolve("execute-task"), {
264
+ primary: "claude-sonnet-4-6",
265
+ fallbacks: [],
266
+ source: "synthesized",
267
+ });
268
+ assert.deepEqual(resolve("execute-task-simple"), {
269
+ primary: "claude-haiku-4-5",
270
+ fallbacks: [],
271
+ source: "synthesized",
272
+ });
273
+ assert.deepEqual(resolve("complete-slice"), {
274
+ primary: "claude-haiku-4-5",
275
+ fallbacks: [],
276
+ source: "synthesized",
277
+ });
278
+ } finally {
279
+ process.chdir(originalCwd);
280
+ if (originalGsdHome === undefined) delete process.env.GSD_HOME;
281
+ else process.env.GSD_HOME = originalGsdHome;
282
+ rmSync(tempProject, { recursive: true, force: true });
283
+ rmSync(tempGsdHome, { recursive: true, force: true });
284
+ }
285
+ });
286
+
287
+ // #1115 guard: the explicit flat-rate opt-out must suppress synthesized routing
288
+ // even on the profile-derived (no tier_models) path — the opt-out moved ahead
289
+ // of both synthesis branches, so a flat-rate start model with
290
+ // allow_flat_rate_providers:false yields no config (start model is used as-is).
291
+ test("resolvePreferredModelConfig honors flat-rate opt-out on the profile path (no tier_models)", () => {
292
+ const originalCwd = process.cwd();
293
+ const originalGsdHome = process.env.GSD_HOME;
294
+ const tempProject = makeTempDir("gsd-routing-flatrate-notier-");
295
+ const tempGsdHome = makeTempDir("gsd-routing-flatrate-notier-home-");
296
+
297
+ try {
298
+ mkdirSync(join(tempProject, ".gsd"), { recursive: true });
299
+ writeFileSync(
300
+ join(tempProject, ".gsd", "PREFERENCES.md"),
301
+ [
302
+ "---",
303
+ "token_profile: budget",
304
+ "dynamic_routing:",
305
+ " enabled: true",
306
+ " allow_flat_rate_providers: false",
307
+ "---",
308
+ ].join("\n"),
309
+ "utf-8",
310
+ );
311
+ process.env.GSD_HOME = tempGsdHome;
312
+ process.chdir(tempProject);
313
+
314
+ const config = resolvePreferredModelConfig(
315
+ "execute-task",
316
+ // claude-code is a built-in flat-rate provider.
317
+ { provider: "claude-code", id: "claude-opus-4-6" },
318
+ true,
319
+ tempProject,
320
+ ["anthropic/claude-haiku-4-5", "anthropic/claude-sonnet-4-6", "anthropic/claude-opus-4-6"],
321
+ );
322
+
323
+ assert.equal(config, undefined);
324
+ } finally {
325
+ process.chdir(originalCwd);
326
+ if (originalGsdHome === undefined) delete process.env.GSD_HOME;
327
+ else process.env.GSD_HOME = originalGsdHome;
328
+ rmSync(tempProject, { recursive: true, force: true });
329
+ rmSync(tempGsdHome, { recursive: true, force: true });
330
+ }
331
+ });
332
+
155
333
  test("selectAndApplyModel honors explicit phase models without downgrading (#3617)", async () => {
156
334
  const originalCwd = process.cwd();
157
335
  const originalGsdHome = process.env.GSD_HOME;
@@ -61,6 +61,7 @@ async function runSuccessfulFinalize(s: AutoSession) {
61
61
  },
62
62
  stopAuto: async () => {},
63
63
  pauseAuto: async () => {},
64
+ checkpointWorkflowDatabase() {},
64
65
  updateProgressWidget() {},
65
66
  postUnitPreVerification: async () => "continue",
66
67
  runPostUnitVerification: async () => "continue",
@@ -410,9 +411,13 @@ test("runFinalize stops before merge when an isolated unit leaks app files into
410
411
  const notifications: Array<{ message: string; level?: string }> = [];
411
412
  const stopCalls: Array<{ reason?: string; preserve?: boolean }> = [];
412
413
  const mergeCalls: string[] = [];
414
+ const checkpointCalls: string[] = [];
413
415
  const result = await runFinalizeWithDeps(
414
416
  s,
415
417
  {
418
+ checkpointWorkflowDatabase() {
419
+ checkpointCalls.push("checkpoint");
420
+ },
416
421
  stopAuto: async (_ctx: unknown, _pi: unknown, reason?: string, options?: { preserveCompletedMilestoneBranch?: boolean }) => {
417
422
  stopCalls.push({ reason, preserve: options?.preserveCompletedMilestoneBranch });
418
423
  },
@@ -438,16 +443,53 @@ test("runFinalize stops before merge when an isolated unit leaks app files into
438
443
 
439
444
  assert.equal(result.action, "break");
440
445
  assert.equal(result.reason, "root-write-leak");
446
+ assert.deepEqual(checkpointCalls, ["checkpoint"], "root-write leak should flush DB before stopAuto");
441
447
  assert.deepEqual(stopCalls, [{ reason: "Root-write leak during isolated auto-mode", preserve: true }]);
442
448
  assert.deepEqual(mergeCalls, [], "root-write leak must stop before merge preflight");
443
449
  const message = notifications.find((n) => n.level === "error")?.message ?? "";
444
450
  assert.match(message, /execute-task M001\/S01\/T01/);
445
451
  assert.match(message, /Project root:/);
446
452
  assert.match(message, /Expected worktree:/);
447
- assert.match(message, /index\.html/);
453
+ assert.doesNotMatch(message, /index\.html/);
448
454
  assert.match(message, /tests\/verify-s09\.sh/);
449
455
  });
450
456
 
457
+ test("runFinalize ignores tracked root artifact changes during isolated units", async (t) => {
458
+ const root = mkdtempSync(join(tmpdir(), "gsd-root-leak-tracked-"));
459
+ const worktree = join(root, ".gsd", "worktrees", "M001");
460
+ t.after(() => {
461
+ rmSync(root, { recursive: true, force: true });
462
+ });
463
+ initRepo(root);
464
+ writeFileSync(join(root, "openapi.json"), "{}\n");
465
+ runGit(root, ["add", "openapi.json"]);
466
+ runGit(root, ["commit", "-m", "chore: add generated spec"]);
467
+ mkdirSync(worktree, { recursive: true });
468
+
469
+ const s = new AutoSession();
470
+ s.basePath = worktree;
471
+ s.originalBasePath = root;
472
+ s.currentMilestoneId = "M001";
473
+ s.rootWriteBaseline = captureRootDirtySnapshot(root);
474
+ s.currentUnit = {
475
+ type: "execute-task",
476
+ id: "M001/S01/T01",
477
+ startedAt: Date.now(),
478
+ };
479
+
480
+ writeFileSync(join(root, "openapi.json"), "{\"generated\":true}\n");
481
+
482
+ const stopCalls: string[] = [];
483
+ const result = await runFinalizeWithDeps(s, {
484
+ stopAuto: async (_ctx: unknown, _pi: unknown, reason?: string) => {
485
+ stopCalls.push(reason ?? "");
486
+ },
487
+ });
488
+
489
+ assert.equal(result.action, "next");
490
+ assert.deepEqual(stopCalls, []);
491
+ });
492
+
451
493
  test("runFinalize allows root .gsd-only changes during isolated units", async (t) => {
452
494
  const root = mkdtempSync(join(tmpdir(), "gsd-root-leak-gsd-"));
453
495
  const worktree = join(root, ".gsd", "worktrees", "M001");
@@ -299,6 +299,63 @@ test("refreshRecoveryDbForArtifact treats missing execute-task DB rows as fatal
299
299
  });
300
300
  });
301
301
 
302
+ test("refreshRecoveryDbForArtifact promotes an open execute-task DB row when artifacts are verified on disk (#1204)", () => {
303
+ const dir = makeTmpProject();
304
+ insertTask({
305
+ milestoneId: "M001",
306
+ sliceId: "S01",
307
+ id: "T01",
308
+ title: "Stuck Task",
309
+ status: "pending",
310
+ });
311
+ const sliceDir = join(dir, ".gsd", "milestones", "M001", "slices", "S01");
312
+ mkdirSync(sliceDir, { recursive: true });
313
+ writeFileSync(join(sliceDir, "S01-PLAN.md"), [
314
+ "# S01 Plan",
315
+ "",
316
+ "- [ ] **T01: Implement feature** `est:1h`",
317
+ "",
318
+ ].join("\n"));
319
+
320
+ const result = refreshRecoveryDbForArtifact("execute-task", "M001/S01/T01", dir);
321
+
322
+ assert.deepEqual(result, { ok: true });
323
+ assert.equal(getTask("M001", "S01", "T01")?.status, "complete");
324
+ const planContent = readFileSync(join(sliceDir, "S01-PLAN.md"), "utf-8");
325
+ assert.ok(planContent.includes("[x] **T01:"), "plan checkbox should be re-rendered to [x]");
326
+ const events = readEvents(join(dir, ".gsd", "event-log.jsonl"));
327
+ assert.ok(
328
+ events.some((e) => e.cmd === "complete-task" && e.trigger_reason === "stuck-artifact-recovery"),
329
+ "a complete-task recovery event should be appended",
330
+ );
331
+ });
332
+
333
+ test("refreshRecoveryDbForArtifact still appends the recovery event when the plan checkbox sync throws after DB promotion (#1221)", () => {
334
+ const dir = makeTmpProject();
335
+ insertTask({
336
+ milestoneId: "M001",
337
+ sliceId: "S01",
338
+ id: "T01",
339
+ title: "Stuck Task",
340
+ status: "pending",
341
+ });
342
+ const sliceDir = join(dir, ".gsd", "milestones", "M001", "slices", "S01");
343
+ mkdirSync(sliceDir, { recursive: true });
344
+ // Make the expected plan path a directory so the best-effort checkbox
345
+ // rewrite (readFileSync) throws EISDIR after the DB row is already promoted.
346
+ mkdirSync(join(sliceDir, "S01-PLAN.md"), { recursive: true });
347
+
348
+ const result = refreshRecoveryDbForArtifact("execute-task", "M001/S01/T01", dir);
349
+
350
+ assert.deepEqual(result, { ok: true });
351
+ assert.equal(getTask("M001", "S01", "T01")?.status, "complete");
352
+ const events = readEvents(join(dir, ".gsd", "event-log.jsonl"));
353
+ assert.ok(
354
+ events.some((e) => e.cmd === "complete-task" && e.trigger_reason === "stuck-artifact-recovery"),
355
+ "recovery event must still be appended even when the plan checkbox sync fails",
356
+ );
357
+ });
358
+
302
359
  test("refreshRecoveryDbForArtifact closes complete-milestone DB row when artifacts exist but DB is stale (#5568)", async () => {
303
360
  const base = mkdtempSync(join(tmpdir(), "auto-recovery-complete-ms-"));
304
361
  mkdirSync(join(base, ".gsd"), { recursive: true });
@@ -838,6 +895,60 @@ test("verifyExpectedArtifact plan-slice fails when a task plan file is missing (
838
895
  }
839
896
  });
840
897
 
898
+ test("verifyExpectedArtifact accepts flat-phase plan-slice with embedded tasks and no task plan files", () => {
899
+ const base = join(tmpdir(), `gsd-test-${randomUUID()}`);
900
+ try {
901
+ const phaseDir = join(base, ".gsd", "phases", "01-test");
902
+ mkdirSync(join(phaseDir, "tasks"), { recursive: true });
903
+ writeFileSync(join(phaseDir, "01-01-PLAN.md"), [
904
+ "# S01: Test Slice",
905
+ "",
906
+ "<tasks>",
907
+ "- [ ] **T01**: Implement feature _(1h)_",
908
+ " - Files: `src/index.ts`",
909
+ " - Verify: pnpm test",
910
+ "- [ ] **T02**: Write tests _(1h)_",
911
+ "</tasks>",
912
+ ].join("\n"));
913
+
914
+ const result = verifyExpectedArtifact("plan-slice", "M001/S01", base);
915
+ assert.equal(result, true, "flat-phase embedded tasks should not require tasks/T##-PLAN.md files");
916
+ } finally {
917
+ cleanup(base);
918
+ }
919
+ });
920
+
921
+ test("verifyExpectedArtifact plan-slice still verifies per-task files for legacy ## Tasks plan with a stray empty <tasks> block", () => {
922
+ const base = makeTmpBase();
923
+ try {
924
+ const tasksDir = join(base, ".gsd", "milestones", "M001", "slices", "S01", "tasks");
925
+ const planPath = join(base, ".gsd", "milestones", "M001", "slices", "S01", "S01-PLAN.md");
926
+ // Legacy layout: real tasks live in a "## Tasks" section with separate
927
+ // per-task PLAN files, but the plan also carries an empty <tasks></tasks>
928
+ // block. The empty block must NOT flip the plan into flat-phase mode and
929
+ // skip the per-task artifact checks.
930
+ const planContent = [
931
+ "# S01: Test Slice",
932
+ "",
933
+ "<tasks>",
934
+ "</tasks>",
935
+ "",
936
+ "## Tasks",
937
+ "",
938
+ "- [ ] **T01: First task** `est:1h`",
939
+ "- [ ] **T02: Second task** `est:2h`",
940
+ ].join("\n");
941
+ writeFileSync(planPath, planContent);
942
+ // Only T01-PLAN.md exists; T02's artifact is missing.
943
+ writeFileSync(join(tasksDir, "T01-PLAN.md"), "# T01 Plan\n\nDo the thing.");
944
+
945
+ const result = verifyExpectedArtifact("plan-slice", "M001/S01", base);
946
+ assert.equal(result, false, "a stray <tasks> block must not skip per-task file verification for a legacy ## Tasks plan");
947
+ } finally {
948
+ cleanup(base);
949
+ }
950
+ });
951
+
841
952
  test("verifyExpectedArtifact plan-slice fails for plan with no tasks (#699)", () => {
842
953
  const base = makeTmpBase();
843
954
  try {
@@ -124,3 +124,44 @@ test("forceStopAutoRemote escalates a live remote PID and releases worker state"
124
124
  );
125
125
  assert.equal(readCrashLock(base), null, "force stop should remove the visible remote lock");
126
126
  });
127
+
128
+ test("forceStopAutoRemote does not SIGKILL a PID that exits during the grace window", (t) => {
129
+ const base = makeBase();
130
+ t.after(() => cleanup(base));
131
+
132
+ openDatabase(join(base, ".gsd", "gsd.db"));
133
+ const workerId = registerAutoWorker({ projectRootRealpath: normalizeRealPath(base) });
134
+ const pid = 525_252;
135
+ setWorkerPid(workerId, pid);
136
+ writeLegacyLock(base, pid);
137
+
138
+ // The process is alive until it receives SIGTERM, then exits cooperatively
139
+ // (liveness probe throws ESRCH) — so the grace loop should break before SIGKILL.
140
+ const signals: Array<NodeJS.Signals | 0> = [];
141
+ let alive = true;
142
+ const originalKill = process.kill;
143
+ process.kill = ((target: number, signal?: NodeJS.Signals | number) => {
144
+ assert.equal(target, pid);
145
+ if (signal === 0) {
146
+ if (!alive) {
147
+ const err = new Error("no such process") as NodeJS.ErrnoException;
148
+ err.code = "ESRCH";
149
+ throw err;
150
+ }
151
+ return true;
152
+ }
153
+ signals.push((signal ?? 0) as NodeJS.Signals | 0);
154
+ if (signal === "SIGTERM") alive = false; // cooperative exit on SIGTERM
155
+ return true;
156
+ }) as typeof process.kill;
157
+ t.after(() => {
158
+ process.kill = originalKill;
159
+ });
160
+
161
+ const result = forceStopAutoRemote(base);
162
+
163
+ assert.deepEqual(result, { found: true, pid });
164
+ assert.ok(signals.includes("SIGTERM"), "force stop should request graceful termination first");
165
+ assert.ok(!signals.includes("SIGKILL"), "force stop must not escalate when the PID exits during the grace window");
166
+ assert.equal(readCrashLock(base), null, "force stop should remove the visible remote lock");
167
+ });