@opengsd/gsd-pi 1.4.0-dev.c18009cd → 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 (334) hide show
  1. package/README.md +10 -10
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/ask-user-questions.js +1 -1
  4. package/dist/resources/extensions/gsd/auto/closeout.js +97 -5
  5. package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -3
  6. package/dist/resources/extensions/gsd/auto/pre-dispatch.js +6 -3
  7. package/dist/resources/extensions/gsd/auto/unit-phase.js +5 -9
  8. package/dist/resources/extensions/gsd/auto-artifact-paths.js +12 -3
  9. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +11 -7
  10. package/dist/resources/extensions/gsd/auto-dispatch.js +16 -2
  11. package/dist/resources/extensions/gsd/auto-recovery.js +50 -6
  12. package/dist/resources/extensions/gsd/auto-start.js +4 -3
  13. package/dist/resources/extensions/gsd/auto-worktree-branch-lifecycle.js +189 -0
  14. package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +133 -0
  15. package/dist/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.js +35 -0
  16. package/dist/resources/extensions/gsd/auto-worktree-creation.js +130 -0
  17. package/dist/resources/extensions/gsd/auto-worktree-entry.js +118 -0
  18. package/dist/resources/extensions/gsd/auto-worktree-merge-already-merged.js +98 -0
  19. package/dist/resources/extensions/gsd/auto-worktree-merge-branch-head.js +52 -0
  20. package/dist/resources/extensions/gsd/auto-worktree-merge-cleanup.js +87 -0
  21. package/dist/resources/extensions/gsd/auto-worktree-merge-code-changes.js +46 -0
  22. package/dist/resources/extensions/gsd/auto-worktree-merge-db-ready.js +68 -0
  23. package/dist/resources/extensions/gsd/auto-worktree-merge-integration-branch.js +51 -0
  24. package/dist/resources/extensions/gsd/auto-worktree-merge-message.js +106 -0
  25. package/dist/resources/extensions/gsd/auto-worktree-merge-pre-teardown.js +64 -0
  26. package/dist/resources/extensions/gsd/auto-worktree-merge-stash.js +168 -0
  27. package/dist/resources/extensions/gsd/auto-worktree-merge.js +302 -0
  28. package/dist/resources/extensions/gsd/auto-worktree-milestone-shelter.js +119 -0
  29. package/dist/resources/extensions/gsd/auto-worktree-path-resolution.js +5 -0
  30. package/dist/resources/extensions/gsd/auto-worktree-path-utils.js +5 -0
  31. package/dist/resources/extensions/gsd/auto-worktree-resource-version.js +41 -0
  32. package/dist/resources/extensions/gsd/auto-worktree-runtime-cleanup.js +99 -0
  33. package/dist/resources/extensions/gsd/auto-worktree-session-registry.js +57 -0
  34. package/dist/resources/extensions/gsd/auto-worktree-sync.js +249 -0
  35. package/dist/resources/extensions/gsd/auto-worktree-teardown.js +120 -0
  36. package/dist/resources/extensions/gsd/auto-worktree.js +20 -2073
  37. package/dist/resources/extensions/gsd/auto.js +9 -3
  38. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +1 -1
  39. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +20 -2
  40. package/dist/resources/extensions/gsd/bootstrap/system-context.js +1 -1
  41. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +185 -27
  42. package/dist/resources/extensions/gsd/codebase-generator.js +7 -1
  43. package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
  44. package/dist/resources/extensions/gsd/commands-workflow-templates.js +3 -3
  45. package/dist/resources/extensions/gsd/db/queries.js +9 -9
  46. package/dist/resources/extensions/gsd/db/writers/cascades.js +20 -2
  47. package/dist/resources/extensions/gsd/doctor-engine-checks.js +93 -11
  48. package/dist/resources/extensions/gsd/flat-phase-migration.js +32 -3
  49. package/dist/resources/extensions/gsd/forensics.js +1 -1
  50. package/dist/resources/extensions/gsd/git-conflict-resolve.js +2 -2
  51. package/dist/resources/extensions/gsd/git-service.js +45 -0
  52. package/dist/resources/extensions/gsd/gsd-db.js +23 -11
  53. package/dist/resources/extensions/gsd/guided-flow.js +22 -17
  54. package/dist/resources/extensions/gsd/markdown-renderer.js +15 -3
  55. package/dist/resources/extensions/gsd/md-importer.js +89 -23
  56. package/dist/resources/extensions/gsd/migration-auto-check.js +30 -3
  57. package/dist/resources/extensions/gsd/milestone-merge-transaction.js +11 -0
  58. package/dist/resources/extensions/gsd/milestone-settlement.js +1 -1
  59. package/dist/resources/extensions/gsd/parallel-merge.js +1 -1
  60. package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -1
  61. package/dist/resources/extensions/gsd/paths.js +17 -3
  62. package/dist/resources/extensions/gsd/preferences-skills.js +10 -16
  63. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  64. package/dist/resources/extensions/gsd/preferences-validation.js +82 -0
  65. package/dist/resources/extensions/gsd/preferences.js +20 -0
  66. package/dist/resources/extensions/gsd/prompts/system.md +6 -6
  67. package/dist/resources/extensions/gsd/quick.js +12 -3
  68. package/dist/resources/extensions/gsd/skill-discovery.js +36 -23
  69. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +2 -1
  70. package/dist/resources/extensions/gsd/state/derive/from-db.js +88 -153
  71. package/dist/resources/extensions/gsd/tool-contract.js +14 -0
  72. package/dist/resources/extensions/gsd/tools/reopen-slice.js +5 -0
  73. package/dist/resources/extensions/gsd/tools/reopen-task.js +13 -5
  74. package/dist/resources/extensions/gsd/unit-registry.js +12 -2
  75. package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +1 -1
  76. package/dist/resources/extensions/gsd/validation-block-guard.js +2 -1
  77. package/dist/resources/extensions/gsd/workspace-git-preflight.js +2 -2
  78. package/dist/resources/extensions/gsd/worktree-command.js +1 -1
  79. package/dist/resources/extensions/gsd/worktree-lifecycle.js +14 -9
  80. package/dist/resources/extensions/gsd/worktree-reentry.js +2 -1
  81. package/dist/resources/extensions/shared/interview-ui.js +62 -9
  82. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  83. package/dist/web/standalone/.next/BUILD_ID +1 -1
  84. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  85. package/dist/web/standalone/.next/build-manifest.json +2 -2
  86. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  87. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  88. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  96. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/index.html +1 -1
  104. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  111. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  113. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  114. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  115. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  116. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  117. package/integrations/hermes/open_gsd_hermes/gsd_client.py +24 -35
  118. package/integrations/hermes/tests/test_gsd_client_timeout.py +4 -4
  119. package/package.json +6 -6
  120. package/packages/cloud-mcp-gateway/package.json +2 -2
  121. package/packages/contracts/package.json +1 -1
  122. package/packages/daemon/package.json +4 -4
  123. package/packages/gsd-agent-core/dist/export-html/template.js +53 -4
  124. package/packages/gsd-agent-core/package.json +5 -5
  125. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  126. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +3 -2
  127. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  128. package/packages/gsd-agent-modes/package.json +7 -7
  129. package/packages/mcp-server/package.json +4 -4
  130. package/packages/native/package.json +1 -1
  131. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  132. package/packages/pi-agent-core/dist/agent-loop.js +14 -9
  133. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  134. package/packages/pi-agent-core/package.json +1 -1
  135. package/packages/pi-ai/dist/index.d.ts +1 -0
  136. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  137. package/packages/pi-ai/dist/index.js +1 -0
  138. package/packages/pi-ai/dist/index.js.map +1 -1
  139. package/packages/pi-ai/dist/providers/transform-messages.d.ts.map +1 -1
  140. package/packages/pi-ai/dist/providers/transform-messages.js +7 -3
  141. package/packages/pi-ai/dist/providers/transform-messages.js.map +1 -1
  142. package/packages/pi-ai/dist/tool-result-content.d.ts +3 -0
  143. package/packages/pi-ai/dist/tool-result-content.d.ts.map +1 -0
  144. package/packages/pi-ai/dist/tool-result-content.js +62 -0
  145. package/packages/pi-ai/dist/tool-result-content.js.map +1 -0
  146. package/packages/pi-ai/dist/types.d.ts +8 -20
  147. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  148. package/packages/pi-ai/dist/types.js.map +1 -1
  149. package/packages/pi-ai/package.json +1 -1
  150. package/packages/pi-coding-agent/dist/core/package-manager.d.ts +9 -0
  151. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  152. package/packages/pi-coding-agent/dist/core/package-manager.js +74 -53
  153. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  154. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +6 -0
  155. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  156. package/packages/pi-coding-agent/dist/core/resource-loader.js +30 -2
  157. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  158. package/packages/pi-coding-agent/dist/core/skill-directories.d.ts +66 -0
  159. package/packages/pi-coding-agent/dist/core/skill-directories.d.ts.map +1 -0
  160. package/packages/pi-coding-agent/dist/core/skill-directories.js +138 -0
  161. package/packages/pi-coding-agent/dist/core/skill-directories.js.map +1 -0
  162. package/packages/pi-coding-agent/dist/core/skills.d.ts +4 -1
  163. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  164. package/packages/pi-coding-agent/dist/core/skills.js +4 -1
  165. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  166. package/packages/pi-coding-agent/dist/index.d.ts +1 -0
  167. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  168. package/packages/pi-coding-agent/dist/index.js +1 -0
  169. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  170. package/packages/pi-coding-agent/package.json +7 -7
  171. package/packages/pi-tui/package.json +2 -2
  172. package/packages/rpc-client/package.json +2 -2
  173. package/pkg/dist/core/export-html/template.js +53 -4
  174. package/pkg/package.json +1 -1
  175. package/src/resources/extensions/ask-user-questions.ts +1 -1
  176. package/src/resources/extensions/gsd/auto/closeout.ts +114 -7
  177. package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -3
  178. package/src/resources/extensions/gsd/auto/pre-dispatch.ts +6 -3
  179. package/src/resources/extensions/gsd/auto/unit-phase.ts +5 -9
  180. package/src/resources/extensions/gsd/auto-artifact-paths.ts +12 -3
  181. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +13 -7
  182. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -2
  183. package/src/resources/extensions/gsd/auto-recovery.ts +50 -6
  184. package/src/resources/extensions/gsd/auto-start.ts +5 -3
  185. package/src/resources/extensions/gsd/auto-worktree-branch-lifecycle.ts +237 -0
  186. package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +166 -0
  187. package/src/resources/extensions/gsd/auto-worktree-conflict-auto-resolve.ts +37 -0
  188. package/src/resources/extensions/gsd/auto-worktree-creation.ts +171 -0
  189. package/src/resources/extensions/gsd/auto-worktree-entry.ts +154 -0
  190. package/src/resources/extensions/gsd/auto-worktree-merge-already-merged.ts +161 -0
  191. package/src/resources/extensions/gsd/auto-worktree-merge-branch-head.ts +83 -0
  192. package/src/resources/extensions/gsd/auto-worktree-merge-cleanup.ts +132 -0
  193. package/src/resources/extensions/gsd/auto-worktree-merge-code-changes.ts +71 -0
  194. package/src/resources/extensions/gsd/auto-worktree-merge-db-ready.ts +112 -0
  195. package/src/resources/extensions/gsd/auto-worktree-merge-integration-branch.ts +99 -0
  196. package/src/resources/extensions/gsd/auto-worktree-merge-message.ts +166 -0
  197. package/src/resources/extensions/gsd/auto-worktree-merge-pre-teardown.ts +93 -0
  198. package/src/resources/extensions/gsd/auto-worktree-merge-stash.ts +213 -0
  199. package/src/resources/extensions/gsd/auto-worktree-merge.ts +391 -0
  200. package/src/resources/extensions/gsd/auto-worktree-milestone-shelter.ts +159 -0
  201. package/src/resources/extensions/gsd/auto-worktree-path-resolution.ts +6 -0
  202. package/src/resources/extensions/gsd/auto-worktree-path-utils.ts +10 -0
  203. package/src/resources/extensions/gsd/auto-worktree-resource-version.ts +44 -0
  204. package/src/resources/extensions/gsd/auto-worktree-runtime-cleanup.ts +119 -0
  205. package/src/resources/extensions/gsd/auto-worktree-session-registry.ts +71 -0
  206. package/src/resources/extensions/gsd/auto-worktree-sync.ts +370 -0
  207. package/src/resources/extensions/gsd/auto-worktree-teardown.ts +161 -0
  208. package/src/resources/extensions/gsd/auto-worktree.ts +69 -2429
  209. package/src/resources/extensions/gsd/auto.ts +11 -17
  210. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +1 -1
  211. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +20 -2
  212. package/src/resources/extensions/gsd/bootstrap/system-context.ts +1 -1
  213. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +218 -27
  214. package/src/resources/extensions/gsd/codebase-generator.ts +7 -1
  215. package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
  216. package/src/resources/extensions/gsd/commands-workflow-templates.ts +3 -3
  217. package/src/resources/extensions/gsd/db/queries.ts +9 -9
  218. package/src/resources/extensions/gsd/db/writers/cascades.ts +23 -1
  219. package/src/resources/extensions/gsd/doctor-engine-checks.ts +109 -10
  220. package/src/resources/extensions/gsd/flat-phase-migration.ts +34 -3
  221. package/src/resources/extensions/gsd/forensics.ts +1 -1
  222. package/src/resources/extensions/gsd/git-conflict-resolve.ts +2 -2
  223. package/src/resources/extensions/gsd/git-service.ts +53 -0
  224. package/src/resources/extensions/gsd/gsd-db.ts +33 -11
  225. package/src/resources/extensions/gsd/guided-flow.ts +26 -18
  226. package/src/resources/extensions/gsd/markdown-renderer.ts +15 -3
  227. package/src/resources/extensions/gsd/md-importer.ts +93 -22
  228. package/src/resources/extensions/gsd/migration-auto-check.ts +32 -3
  229. package/src/resources/extensions/gsd/milestone-merge-transaction.ts +15 -0
  230. package/src/resources/extensions/gsd/milestone-settlement.ts +1 -1
  231. package/src/resources/extensions/gsd/parallel-merge.ts +1 -1
  232. package/src/resources/extensions/gsd/parallel-orchestrator.ts +3 -1
  233. package/src/resources/extensions/gsd/paths.ts +21 -3
  234. package/src/resources/extensions/gsd/preferences-skills.ts +10 -16
  235. package/src/resources/extensions/gsd/preferences-types.ts +30 -0
  236. package/src/resources/extensions/gsd/preferences-validation.ts +69 -0
  237. package/src/resources/extensions/gsd/preferences.ts +20 -0
  238. package/src/resources/extensions/gsd/prompts/system.md +6 -6
  239. package/src/resources/extensions/gsd/quick.ts +11 -3
  240. package/src/resources/extensions/gsd/skill-discovery.ts +47 -23
  241. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +3 -1
  242. package/src/resources/extensions/gsd/state/derive/from-db.ts +201 -157
  243. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +169 -1
  244. package/src/resources/extensions/gsd/tests/auto-loop-no-copy-artifacts.test.ts +2 -1
  245. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +57 -0
  246. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +1 -1
  247. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +2 -1
  248. package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +1 -1
  249. package/src/resources/extensions/gsd/tests/auto-worktree-merge-already-merged.test.ts +177 -0
  250. package/src/resources/extensions/gsd/tests/auto-worktree-merge-branch-head.test.ts +118 -0
  251. package/src/resources/extensions/gsd/tests/auto-worktree-merge-cleanup.test.ts +115 -0
  252. package/src/resources/extensions/gsd/tests/auto-worktree-merge-code-changes.test.ts +76 -0
  253. package/src/resources/extensions/gsd/tests/auto-worktree-merge-db-ready.test.ts +140 -0
  254. package/src/resources/extensions/gsd/tests/auto-worktree-merge-integration-branch.test.ts +123 -0
  255. package/src/resources/extensions/gsd/tests/auto-worktree-merge-message.test.ts +114 -0
  256. package/src/resources/extensions/gsd/tests/auto-worktree-merge-pre-teardown.test.ts +84 -0
  257. package/src/resources/extensions/gsd/tests/auto-worktree-merge-stash.test.ts +70 -0
  258. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-shelter.test.ts +52 -0
  259. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +6 -6
  260. package/src/resources/extensions/gsd/tests/auto-worktree-resource-version.test.ts +59 -0
  261. package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +3 -1
  262. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
  263. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +1 -1
  264. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +4 -0
  265. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +174 -0
  266. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +1 -1
  267. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +71 -1
  268. package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +25 -1
  269. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +40 -0
  270. package/src/resources/extensions/gsd/tests/import-completion-lost-update.test.ts +196 -0
  271. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +4 -6
  272. package/src/resources/extensions/gsd/tests/integration/auto-stash-merge.test.ts +2 -1
  273. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +3 -3
  274. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +7 -8
  275. package/src/resources/extensions/gsd/tests/integration/feature-branch-lifecycle-integration.test.ts +2 -5
  276. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +76 -0
  277. package/src/resources/extensions/gsd/tests/integration/merge-cwd-restore.test.ts +1 -1
  278. package/src/resources/extensions/gsd/tests/integration/merge-preserve-worktree-on-preteardown-error.test.ts +1 -1
  279. package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +2 -1
  280. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +5 -7
  281. package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +2 -4
  282. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +16 -15
  283. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +1 -1
  284. package/src/resources/extensions/gsd/tests/merge-db-cycle.test.ts +1 -1
  285. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +1 -1
  286. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +91 -0
  287. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +439 -0
  288. package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +24 -0
  289. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +1 -1
  290. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -3
  291. package/src/resources/extensions/gsd/tests/parallel-worker-lock-contention.test.ts +1 -1
  292. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +1 -4
  293. package/src/resources/extensions/gsd/tests/preferences.test.ts +19 -0
  294. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +5 -0
  295. package/src/resources/extensions/gsd/tests/reopen-slice.test.ts +52 -0
  296. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +20 -0
  297. package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +46 -0
  298. package/src/resources/extensions/gsd/tests/stale-worktree-cwd.test.ts +3 -5
  299. package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +2 -1
  300. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +2 -1
  301. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +1 -1
  302. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +1 -1
  303. package/src/resources/extensions/gsd/tests/system-flat-phase-layout.test.ts +33 -0
  304. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +4 -4
  305. package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +2 -1
  306. package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +4 -4
  307. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +196 -0
  308. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +1 -1
  309. package/src/resources/extensions/gsd/tests/unit-registry.test.ts +26 -1
  310. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -1
  311. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +1 -1
  312. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +1 -3
  313. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +1 -1
  314. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +1 -1
  315. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +1 -1
  316. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +1 -1
  317. package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +2 -1
  318. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +5 -2
  319. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +1 -1
  320. package/src/resources/extensions/gsd/tests/worktree-sync-tasks.test.ts +1 -1
  321. package/src/resources/extensions/gsd/tool-contract.ts +29 -0
  322. package/src/resources/extensions/gsd/tools/reopen-slice.ts +5 -0
  323. package/src/resources/extensions/gsd/tools/reopen-task.ts +13 -5
  324. package/src/resources/extensions/gsd/unit-registry.ts +16 -2
  325. package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +1 -1
  326. package/src/resources/extensions/gsd/validation-block-guard.ts +2 -1
  327. package/src/resources/extensions/gsd/workspace-git-preflight.ts +2 -2
  328. package/src/resources/extensions/gsd/worktree-command.ts +1 -1
  329. package/src/resources/extensions/gsd/worktree-lifecycle.ts +19 -15
  330. package/src/resources/extensions/gsd/worktree-reentry.ts +2 -1
  331. package/src/resources/extensions/shared/interview-ui.ts +58 -11
  332. package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +32 -0
  333. /package/dist/web/standalone/.next/static/{L2UMqXELiDH3oz-7yguXp → gXoWec4UNqcR0tkuHwYCr}/_buildManifest.js +0 -0
  334. /package/dist/web/standalone/.next/static/{L2UMqXELiDH3oz-7yguXp → gXoWec4UNqcR0tkuHwYCr}/_ssgManifest.js +0 -0
package/README.md CHANGED
@@ -28,16 +28,16 @@ See [CHANGELOG.md](./CHANGELOG.md) for release-by-release fixes and [Legacy Rele
28
28
  ## Latest Release Highlights
29
29
 
30
30
  <!-- release-highlights:start -->
31
- Latest release: **v1.4.0**
32
-
33
- - **models:** Add Claude Sonnet 5.
34
- - **Added:** Add Hermes plugin installer.
35
- - **compat:** Report .planning/ drift in /gsd sync and doctor.
36
- - **compat:** Project to .planning/ inside renderAllFromDb.
37
- - **compat:** Add external-planning-edit drift handler.
38
- - **compat:** Add DB .planning/ projection writer.
39
- - **compat:** Extract .planning/ layout detector.
40
- - **compat:** Extend marker schema 1→2 with planning field.
31
+ Latest release: **v1.5.0**
32
+
33
+ - **hermes:** Add /gsd new-milestone command for chat-driven milestone creation (#1162).
34
+ - **gsd:** Make CODEBASE.md workspace-aware in parent mode.
35
+ - **gsd:** Doctor probe + validation for parent-workspace repos.
36
+ - **gsd:** Surface per-repo git health in /gsd status + document limits.
37
+ - **gsd:** Wire repository assignment into slice/task planning.
38
+ - **gsd:** Add parent-workspace discovery UX + document nested-only layout.
39
+ - **provider:** Add Cursor Agent provider.
40
+ - **gsd:** Make workspace.mode parent behavioral (mode contract).
41
41
 
42
42
  <!-- release-highlights:end -->
43
43
 
@@ -1 +1 @@
1
- f30abebf080db301
1
+ dc6f7673892b74e1
@@ -209,7 +209,7 @@ export default function AskUserQuestions(pi) {
209
209
  "For single-select: each question must have 2-3 options. Put the recommended option first with '(Recommended)' suffix. Do not include an 'Other' or 'None of the above' option - the client adds one automatically.",
210
210
  "For multi-select: set allowMultiple: true. The user can pick any number of options. No 'None of the above' is added.",
211
211
  "When options involve code patterns, config choices, or architecture decisions, add a 'preview' field with markdown content (code blocks, lists, headers, etc.). The preview renders in a side-by-side panel when the option is highlighted.",
212
- "Preview content is rendered in a fixed-height panel (max ~20 lines visible). Keep previews concise — show the most relevant snippet, not exhaustive examples. Longer content is truncated with a '+N lines hidden' indicator.",
212
+ "Preview content is rendered in a fixed-height panel (max ~20 lines visible). Keep previews concise — show the most relevant snippet, not exhaustive examples. Longer content stays fully accessible: the user scrolls it with PgUp/PgDn, with '▲/▼ N more' indicators marking hidden rows.",
213
213
  ],
214
214
  parameters: AskUserQuestionsParams,
215
215
  async execute(_toolCallId, params, signal, _onUpdate, ctx) {
@@ -1,12 +1,17 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: Auto-loop closeout, milestone report, and merge helpers.
3
3
  import { importExtensionModule } from "@gsd/pi-coding-agent";
4
+ import { execFileSync } from "node:child_process";
5
+ import { createHash } from "node:crypto";
6
+ import { join, basename } from "node:path";
7
+ import { readFileSync } from "node:fs";
4
8
  import { MergeConflictError } from "../git-service.js";
5
9
  import { findUnmergedCompletedMilestones } from "../unmerged-milestone-guard.js";
6
10
  import { getIsolationMode } from "../preferences.js";
7
11
  import { isDbAvailable, getMilestone } from "../gsd-db.js";
8
12
  import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
9
13
  import { isClosedStatus } from "../status-guards.js";
14
+ import { PLANNING_ARTIFACT_SUFFIXES } from "../paths.js";
10
15
  import { logWarning, logError } from "../workflow-logger.js";
11
16
  import { debugLog } from "../debug-logger.js";
12
17
  import { _resolveReportBasePath } from "./phase-helpers.js";
@@ -51,7 +56,15 @@ export async function restorePreflightStashOrStop(ic, preflight, milestoneId) {
51
56
  */
52
57
  export async function _runMilestoneMergeWithStashRestore(ic, milestoneId, options = {}) {
53
58
  const { ctx, pi, s, deps } = ic;
54
- const projectRoot = s.originalBasePath || s.basePath;
59
+ // Resolve the project root once, before the merge can flip session path
60
+ // pointers (worktree teardown mutates s.basePath / s.scope). The guarded
61
+ // merge's preflight/postflight stash restore, the pre-merge ignored-markdown
62
+ // snapshot, the dirty-projection check, and the rebuild must all target this
63
+ // same tree; otherwise `.gsd` markdown restored on one tree can be silently
64
+ // overwritten by a rebuild on another. canonicalProjectRoot is the
65
+ // authoritative `.gsd`/DB writer path (see AutoSession.canonicalProjectRoot).
66
+ const projectRoot = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
67
+ const ignoredProjectionSnapshot = snapshotIgnoredGsdMarkdownProjections(projectRoot);
55
68
  const mergeResult = deps.lifecycle.exitMilestone(milestoneId, {
56
69
  merge: true,
57
70
  guardedMerge: {
@@ -61,11 +74,11 @@ export async function _runMilestoneMergeWithStashRestore(ic, milestoneId, option
61
74
  },
62
75
  }, ctx.ui);
63
76
  if (mergeResult.ok) {
64
- await markMilestoneMergedAndRebuild(s);
77
+ await markMilestoneMergedAndRebuild(s, projectRoot, ignoredProjectionSnapshot);
65
78
  return null;
66
79
  }
67
80
  if (mergeResult.reason === "postflight-stash-restore-failed") {
68
- await markMilestoneMergedAndRebuild(s);
81
+ await markMilestoneMergedAndRebuild(s, projectRoot, ignoredProjectionSnapshot);
69
82
  }
70
83
  if (mergeResult.reason === "preflight-dirty-overlap" || mergeResult.reason === "preflight-unmerged-conflicts") {
71
84
  const reason = mergeResult.reason === "preflight-unmerged-conflicts"
@@ -122,10 +135,13 @@ export async function _runMilestoneMergeWithStashRestore(ic, milestoneId, option
122
135
  }
123
136
  return null;
124
137
  }
125
- async function markMilestoneMergedAndRebuild(s) {
138
+ async function markMilestoneMergedAndRebuild(s, rebuildBasePath, ignoredProjectionSnapshot) {
126
139
  s.milestoneMergedInPhases = true;
140
+ if (hasDirtyGsdMarkdownProjections(rebuildBasePath, ignoredProjectionSnapshot)) {
141
+ logWarning("engine", "skipping markdown projection rebuild after milestone merge because restored .gsd edits are dirty");
142
+ return;
143
+ }
127
144
  try {
128
- const rebuildBasePath = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
129
145
  const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.js");
130
146
  await rebuildMarkdownProjectionsFromDb(rebuildBasePath);
131
147
  }
@@ -133,6 +149,82 @@ async function markMilestoneMergedAndRebuild(s) {
133
149
  logWarning("engine", `markdown projection rebuild after milestone merge failed: ${err instanceof Error ? err.message : String(err)}`);
134
150
  }
135
151
  }
152
+ function hasDirtyGsdMarkdownProjections(basePath, ignoredProjectionSnapshot) {
153
+ try {
154
+ const output = execFileSync("git", ["status", "--porcelain", "-z", "--untracked-files=all", "--", ".gsd"], { cwd: basePath, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
155
+ const entries = output.split("\0").filter(Boolean);
156
+ for (let i = 0; i < entries.length; i++) {
157
+ const entry = entries[i];
158
+ if (entry.length <= 3)
159
+ continue;
160
+ const status = entry.slice(0, 2);
161
+ const path = entry.slice(3);
162
+ if (isGeneratedGsdMarkdownProjection(path))
163
+ return true;
164
+ if ((status === "R " || status === "C ") && i + 1 < entries.length) {
165
+ const dest = entries[++i];
166
+ if (isGeneratedGsdMarkdownProjection(dest))
167
+ return true;
168
+ }
169
+ }
170
+ }
171
+ catch (err) {
172
+ void err;
173
+ // Fall through to ignored-file snapshot comparison below.
174
+ }
175
+ return ignoredGsdMarkdownProjectionSnapshotChanged(basePath, ignoredProjectionSnapshot);
176
+ }
177
+ function isGeneratedGsdMarkdownProjection(path) {
178
+ const normalized = path.replace(/\\/g, "/");
179
+ if (normalized === ".gsd/DECISIONS.md")
180
+ return true;
181
+ if (!normalized.startsWith(".gsd/milestones/") && !normalized.startsWith(".gsd/phases/")) {
182
+ return false;
183
+ }
184
+ return isGeneratedPlanningArtifactFileName(basename(normalized));
185
+ }
186
+ function isGeneratedPlanningArtifactFileName(fileName) {
187
+ if (!fileName.endsWith(".md"))
188
+ return false;
189
+ const stem = fileName.slice(0, -".md".length).toUpperCase();
190
+ for (const suffix of PLANNING_ARTIFACT_SUFFIXES) {
191
+ if (!stem.endsWith(`-${suffix}`))
192
+ continue;
193
+ const idPrefix = stem.slice(0, -suffix.length - 1);
194
+ return /^(?:[MST]\d+|\d{2,})(?:-[A-Z0-9]+)*$/.test(idPrefix);
195
+ }
196
+ return false;
197
+ }
198
+ function snapshotIgnoredGsdMarkdownProjections(basePath) {
199
+ try {
200
+ const output = execFileSync("git", ["ls-files", "--others", "--ignored", "--exclude-standard", "-z", "--", ".gsd"], { cwd: basePath, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
201
+ const snapshot = new Map();
202
+ for (const path of output.split("\0")) {
203
+ if (!isGeneratedGsdMarkdownProjection(path))
204
+ continue;
205
+ snapshot.set(path, hashFile(join(basePath, path)));
206
+ }
207
+ return snapshot;
208
+ }
209
+ catch {
210
+ return null;
211
+ }
212
+ }
213
+ function hashFile(path) {
214
+ return createHash("sha256").update(readFileSync(path)).digest("hex");
215
+ }
216
+ function ignoredGsdMarkdownProjectionSnapshotChanged(basePath, before) {
217
+ if (!before)
218
+ return true;
219
+ const after = snapshotIgnoredGsdMarkdownProjections(basePath);
220
+ if (!after || after.size !== before.size)
221
+ return true;
222
+ for (const [path, hash] of before) {
223
+ if (after.get(path) !== hash)
224
+ return true;
225
+ }
226
+ return false;
227
+ }
136
228
  export async function _runMilestoneMergeOnceWithStashRestore(ic, milestoneId, options = {}) {
137
229
  if (ic.s.milestoneMergedInPhases) {
138
230
  debugLog("autoLoop", {
@@ -21,7 +21,8 @@ import { createWorktreeSafetyModule } from "../worktree-safety.js";
21
21
  import { repairAutoWorktreeSafetyFailure } from "../auto-worktree-repair.js";
22
22
  import { resolveManifest } from "../unit-context-manifest.js";
23
23
  import { preDispatchHealthGate, recordHealthSnapshot, } from "../doctor-proactive.js";
24
- import { checkResourcesStale, autoWorktreeBranch, mergeMilestoneToMain } from "../auto-worktree.js";
24
+ import { autoWorktreeBranch } from "../auto-worktree-branch-lifecycle.js";
25
+ import { checkResourcesStale } from "../auto-worktree-resource-version.js";
25
26
  import { getSessionLockStatus } from "../session-lock.js";
26
27
  import { resolveUokFlags } from "../uok/flags.js";
27
28
  import { emitJournalEvent as _emitJournalEvent } from "../journal.js";
@@ -31,7 +32,7 @@ import { getPriorSliceCompletionBlocker } from "../dispatch-guard.js";
31
32
  import { GitServiceImpl } from "../git-service.js";
32
33
  import { WorktreeStateProjection } from "../worktree-state-projection.js";
33
34
  import { WorktreeLifecycle } from "../worktree-lifecycle.js";
34
- import { createMilestoneMergeTransaction } from "../milestone-merge-transaction.js";
35
+ import { createDefaultMilestoneMergeTransaction } from "../milestone-merge-transaction.js";
35
36
  import { createWorkspace, scopeMilestone } from "../workspace.js";
36
37
  import { supportsStructuredQuestions } from "../workflow-mcp.js";
37
38
  import { getRegisteredToolSnapshot, getToolBaselineSnapshot } from "../auto-model-selection.js";
@@ -560,7 +561,7 @@ export class AutoOrchestrator {
560
561
  return new GitServiceImpl(basePath, gitConfig);
561
562
  },
562
563
  worktreeProjection: new WorktreeStateProjection(),
563
- mergeMilestone: createMilestoneMergeTransaction(mergeMilestoneToMain),
564
+ mergeMilestone: createDefaultMilestoneMergeTransaction(),
564
565
  });
565
566
  }
566
567
  rebuildScope(rawPath, milestoneId) {
@@ -345,7 +345,8 @@ export async function runPreDispatch(ic, loopState) {
345
345
  if (stop)
346
346
  return stop;
347
347
  }
348
- // PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
348
+ // PR creation (auto_pr) is handled by the publication handoff in
349
+ // the milestone merge transaction (#2302).
349
350
  deps.invalidateAllCaches();
350
351
  state = await deps.deriveState(s.canonicalProjectRoot);
351
352
  mid = state.activeMilestone?.id;
@@ -430,7 +431,8 @@ export async function runPreDispatch(ic, loopState) {
430
431
  const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId);
431
432
  if (stop)
432
433
  return stop;
433
- // PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
434
+ // PR creation (auto_pr) is handled by the publication handoff in
435
+ // the milestone merge transaction (#2302).
434
436
  }
435
437
  const unmappedActive = countUnmappedActiveRequirements();
436
438
  const completionStopReason = formatCompletePhaseNextAction(unmappedActive);
@@ -506,7 +508,8 @@ export async function runPreDispatch(ic, loopState) {
506
508
  const stop = await _runMilestoneMergeOnceWithStashRestore(ic, s.currentMilestoneId);
507
509
  if (stop)
508
510
  return stop;
509
- // PR creation (auto_pr) is handled inside mergeMilestoneToMain (#2302)
511
+ // PR creation (auto_pr) is handled by the publication handoff in
512
+ // the milestone merge transaction (#2302).
510
513
  }
511
514
  deps.sendDesktopNotification("GSD", `Milestone ${mid} complete!`, "success", "milestone", basename(s.originalBasePath || s.basePath));
512
515
  deps.logCmuxEvent(prefs, `Milestone ${mid} complete.`, "success");
@@ -17,7 +17,7 @@ import { isDbAvailable, getTask } from "../gsd-db.js";
17
17
  import { parseUnitId } from "../unit-id.js";
18
18
  import { createCheckpoint, cleanupCheckpoint, rollbackToCheckpoint } from "../safety/git-checkpoint.js";
19
19
  import { resolveSafetyHarnessConfig } from "../safety/safety-harness.js";
20
- import { getUnitWorkflowDispatchReadinessError } from "../tool-contract.js";
20
+ import { getUnitWorkflowDispatchReadinessErrorForModel } from "../tool-contract.js";
21
21
  import { prepareWorkflowMcpForProject } from "../workflow-mcp-auto-prep.js";
22
22
  import { applyThinkingLevelForModel, floorThinkingLevelForUnit, } from "../auto-model-selection.js";
23
23
  import { isSuspiciousGhostCompletion } from "../auto-unit-closeout.js";
@@ -246,17 +246,13 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
246
246
  s.currentDispatchedModelId = s.currentUnitModel
247
247
  ? `${s.currentUnitModel.provider ?? ""}/${s.currentUnitModel.id ?? ""}`
248
248
  : null;
249
- const compatibilityError = getUnitWorkflowDispatchReadinessError({
250
- provider: s.currentUnitModel?.provider ?? ctx.model?.provider,
249
+ const compatibilityError = getUnitWorkflowDispatchReadinessErrorForModel({
250
+ model: s.currentUnitModel,
251
+ fallbackModel: ctx.model,
252
+ getProviderAuthMode: (provider) => ctx.modelRegistry.getProviderAuthMode(provider),
251
253
  projectRoot: s.basePath,
252
254
  surface: "auto-mode",
253
255
  unitType,
254
- authMode: s.currentUnitModel?.provider
255
- ? ctx.modelRegistry.getProviderAuthMode(s.currentUnitModel.provider)
256
- : ctx.model?.provider
257
- ? ctx.modelRegistry.getProviderAuthMode(ctx.model.provider)
258
- : undefined,
259
- baseUrl: s.currentUnitModel?.baseUrl ?? ctx.model?.baseUrl,
260
256
  activeTools: typeof pi.getActiveTools === "function" ? pi.getActiveTools() : [],
261
257
  });
262
258
  const workflowMcpPrepModel = s.currentUnitModel;
@@ -8,7 +8,7 @@
8
8
  import { gsdRoot, resolveDir, resolveFile, resolveMilestonePath, resolveMilestoneFile, resolveSliceFile, relMilestoneFile, relSliceFile, buildTaskFileName, resolveSlicePath, resolveTasksDir, dirIsMetaOnlyLegacyMilestone, } from "./paths.js";
9
9
  import { milestoneIdToPhaseNum } from "./layout-policy.js";
10
10
  import { parseUnitId } from "./unit-id.js";
11
- import { dirname, join, relative } from "node:path";
11
+ import { basename, dirname, join, relative } from "node:path";
12
12
  import { existsSync } from "node:fs";
13
13
  function resolveMilestoneArtifactPath(base, mid, suffix) {
14
14
  const existing = resolveProjectedMilestoneFile(base, mid, suffix) ?? resolveProjectMilestoneFile(base, mid, suffix);
@@ -193,8 +193,17 @@ export function resolveExpectedArtifactPath(unitType, unitId, base) {
193
193
  ?? resolveSlicePath(base, mid, sid);
194
194
  if (!slicePath || !tid)
195
195
  return null;
196
- const tasksDir = resolveTasksDir(base, mid, sid) ?? slicePath;
197
- return join(tasksDir, buildTaskFileName(tid, "SUMMARY"));
196
+ // Legacy layout: slice dirs live under slices/<SID>/ and task summaries
197
+ // live in a tasks/ subdir. Flat-phase layout: slicePath IS the phase dir
198
+ // and task summaries live beside the plan files at the phase root. A
199
+ // tasks/ subdir may still exist in flat-phase for auxiliary task-scoped
200
+ // artifacts (e.g. T01-VERIFY.json gate outputs) — its mere existence must
201
+ // NOT redirect summary resolution into tasks/ (#1208).
202
+ const isLegacySlice = basename(dirname(slicePath)) === "slices";
203
+ const summaryDir = isLegacySlice
204
+ ? (resolveTasksDir(base, mid, sid) ?? slicePath)
205
+ : slicePath;
206
+ return join(summaryDir, buildTaskFileName(tid, "SUMMARY"));
198
207
  }
199
208
  case "complete-slice": {
200
209
  return resolveSliceArtifactPath(base, mid, sid, "SUMMARY");
@@ -7,10 +7,10 @@ import { loadFile } from "./files.js";
7
7
  import { isDbAvailable, getClosedSliceIds } from "./gsd-db.js";
8
8
  import { resolveSliceFile, relSliceFile, } from "./paths.js";
9
9
  import { buildResearchSlicePrompt, buildResearchMilestonePrompt, buildPlanSlicePrompt, buildPlanMilestonePrompt, buildExecuteTaskPrompt, buildCompleteSlicePrompt, buildCompleteMilestonePrompt, buildValidateMilestonePrompt, buildReassessRoadmapPrompt, buildRunUatPrompt, buildReplanSlicePrompt, } from "./auto-prompts.js";
10
- import { loadEffectiveGSDPreferences } from "./preferences.js";
10
+ import { loadEffectiveGSDPreferences, renderLanguageDirectiveForPrompt } from "./preferences.js";
11
11
  import { pauseAuto } from "./auto.js";
12
12
  import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
13
- import { getUnitWorkflowDispatchReadinessError } from "./tool-contract.js";
13
+ import { getUnitWorkflowDispatchReadinessErrorForModel } from "./tool-contract.js";
14
14
  export function parseDirectDispatchPhase(raw) {
15
15
  const tokens = raw.trim().split(/\s+/).filter(Boolean);
16
16
  if (tokens.length === 0)
@@ -213,13 +213,12 @@ export async function dispatchDirectPhase(ctx, pi, phase, base, opts = {}) {
213
213
  ctx.ui.notify(`Unknown phase "${phase}". Valid phases: research, plan, execute, complete, validate, reassess, uat, replan.`, "warning");
214
214
  return;
215
215
  }
216
- const compatibilityError = getUnitWorkflowDispatchReadinessError({
217
- provider: ctx.model?.provider,
216
+ const compatibilityError = getUnitWorkflowDispatchReadinessErrorForModel({
217
+ model: ctx.model,
218
+ getProviderAuthMode: (provider) => ctx.modelRegistry.getProviderAuthMode(provider),
218
219
  projectRoot,
219
220
  surface: "direct phase dispatch",
220
221
  unitType,
221
- authMode: ctx.model?.provider ? ctx.modelRegistry.getProviderAuthMode(ctx.model.provider) : undefined,
222
- baseUrl: ctx.model?.baseUrl,
223
222
  activeTools: typeof pi.getActiveTools === "function" ? pi.getActiveTools() : [],
224
223
  });
225
224
  if (compatibilityError) {
@@ -232,5 +231,10 @@ export async function dispatchDirectPhase(ctx, pi, phase, base, opts = {}) {
232
231
  ctx.ui.notify("Session creation cancelled.", "warning");
233
232
  return;
234
233
  }
235
- pi.sendMessage({ customType: "gsd-dispatch", content: prompt, display: false }, { triggerTurn: true });
234
+ // Inject the configured response language into the dispatched prompt content
235
+ // — the new session's system prompt does not carry the preferences block, so
236
+ // the language setting would otherwise never reach the unit (#1210).
237
+ const languageDirective = renderLanguageDirectiveForPrompt(loadEffectiveGSDPreferences(dispatchBase)?.preferences);
238
+ const dispatchContent = languageDirective ? `${languageDirective}\n\n${prompt}` : prompt;
239
+ pi.sendMessage({ customType: "gsd-dispatch", content: dispatchContent, display: false }, { triggerTurn: true });
236
240
  }
@@ -1,5 +1,6 @@
1
1
  // Project/App: gsd-pi
2
2
  // File Purpose: Declarative auto-mode dispatch rules and dispatch resolver.
3
+ import { renderLanguageDirectiveForPrompt } from "./preferences.js";
3
4
  import { loadFile, extractUatType, loadActiveOverrides } from "./files.js";
4
5
  import { getUatBrowserToolSupportError } from "./uat-policy.js";
5
6
  import { isDbAvailable, getMilestoneSlices, getMilestoneSliceSummaries, getClosedSliceIds, getPendingGatesForTurn, markPendingGatesOmittedForTurn, getMilestone, insertArtifact, insertAssessment, setSliceSketchFlag, transaction, getAssessment, getSliceRunUatAssessment, } from "./gsd-db.js";
@@ -1500,6 +1501,19 @@ export const DISPATCH_RULES = [
1500
1501
  },
1501
1502
  ];
1502
1503
  import { getRegistry } from "./rule-registry.js";
1504
+ /**
1505
+ * Prepend the configured response-language directive to a dispatched unit
1506
+ * prompt so auto-execution units respond in the language set in PREFERENCES.md
1507
+ * (#1210). No-op for non-dispatch actions or when no language is configured.
1508
+ */
1509
+ function applyLanguageDirectiveToDispatch(action, prefs) {
1510
+ if (action.action !== "dispatch" || !action.prompt)
1511
+ return action;
1512
+ const directive = renderLanguageDirectiveForPrompt(prefs);
1513
+ if (!directive)
1514
+ return action;
1515
+ return { ...action, prompt: `${directive}\n\n${action.prompt}` };
1516
+ }
1503
1517
  // ─── Resolver ─────────────────────────────────────────────────────────────
1504
1518
  /**
1505
1519
  * Evaluate dispatch rules in order. Returns the first matching action,
@@ -1551,7 +1565,7 @@ export async function resolveDispatch(ctx) {
1551
1565
  level: "error",
1552
1566
  };
1553
1567
  }
1554
- return action;
1568
+ return applyLanguageDirectiveToDispatch(action, ctx.prefs);
1555
1569
  }
1556
1570
  catch (err) {
1557
1571
  // Registry not initialized — fall back to inline loop
@@ -1572,7 +1586,7 @@ export async function resolveDispatch(ctx) {
1572
1586
  matchedRule: rule.name,
1573
1587
  };
1574
1588
  }
1575
- return action;
1589
+ return applyLanguageDirectiveToDispatch(action, ctx.prefs);
1576
1590
  }
1577
1591
  }
1578
1592
  // No rule matched — unhandled phase.
@@ -149,12 +149,56 @@ export function refreshRecoveryDbForArtifact(unitType, unitId, basePath) {
149
149
  };
150
150
  }
151
151
  if (!isClosedStatus(task.status)) {
152
- return {
153
- ok: false,
154
- fatal: true,
155
- reason: "execute-task-artifact-db-mismatch",
156
- message: `Stuck recovery found execute-task ${unitId} artifacts, but the DB task status is still '${task.status}' after refresh.`,
157
- };
152
+ // The artifact was already confirmed on disk by verifyExpectedArtifact
153
+ // upstream (Gate 1 accepts a checked disk checkbox as proof of completion),
154
+ // but the DB task row is still open. A bare refreshWorkflowDatabaseFromDisk
155
+ // never promotes the disk checkbox into task status (the checkbox is
156
+ // rendered *from* the DB, never *into* it), so this divergence can never
157
+ // self-heal. Promote the task to align the DB with disk instead of failing
158
+ // shut — otherwise the lowest-pending derivation re-picks the same task
159
+ // forever and execute-task hard-stops with "state did not advance" (#1204).
160
+ // Mirrors the promotion pattern used by the context-exhaustion and
161
+ // reactive-execute-blocker recovery paths.
162
+ const ts = new Date().toISOString();
163
+ // Only the DB promotion is load-bearing: if it throws, nothing advanced
164
+ // and failing shut is correct. The plan checkbox rewrite and cache clears
165
+ // are best-effort follow-ups — a throw there must NOT abort recovery, or
166
+ // the DB is left complete without ever emitting the stuck-artifact-recovery
167
+ // event (#1221), stranding worktree reconciliation.
168
+ try {
169
+ updateTaskStatus(mid, sid, tid, "complete", ts);
170
+ }
171
+ catch (e) {
172
+ return {
173
+ ok: false,
174
+ fatal: true,
175
+ reason: "execute-task-artifact-db-promote-failed",
176
+ message: `Stuck recovery found execute-task ${unitId} artifacts, but promoting the DB task status from '${task.status}' failed: ${getErrorMessage(e)}`,
177
+ };
178
+ }
179
+ try {
180
+ const artifactBase = resolveArtifactVerificationBase(unitId, basePath);
181
+ const planPath = resolveExpectedArtifactPath("plan-slice", `${mid}/${sid}`, artifactBase);
182
+ if (planPath && existsSync(planPath)) {
183
+ const planContent = readFileSync(planPath, "utf-8");
184
+ const updatedPlan = planContent.replace(new RegExp(`^(\\s*-\\s+)\\[ \\]\\s+\\*\\*${tid}:`, "m"), `$1[x] **${tid}:`);
185
+ if (updatedPlan !== planContent) {
186
+ atomicWriteSync(planPath, updatedPlan);
187
+ }
188
+ }
189
+ clearPathCache();
190
+ clearParseCache();
191
+ }
192
+ catch (e) {
193
+ logWarning("recovery", `stuck-artifact plan checkbox sync failed after DB promotion of ${unitId}: ${getErrorMessage(e)}`);
194
+ }
195
+ // Append event so worktree reconciliation can replay this recovery completion.
196
+ try {
197
+ appendEvent(basePath, { cmd: "complete-task", params: { milestoneId: mid, sliceId: sid, taskId: tid }, ts, actor: "system", trigger_reason: "stuck-artifact-recovery" });
198
+ }
199
+ catch (e) {
200
+ logWarning("recovery", `appendEvent failed for stuck-artifact task promotion: ${getErrorMessage(e)}`);
201
+ }
158
202
  }
159
203
  return { ok: true };
160
204
  }
@@ -27,9 +27,10 @@ import { ensureGitignore, untrackRuntimeFiles } from "./gitignore.js";
27
27
  import { nativeIsRepo, nativeInit, nativeAddAll, nativeCommit, nativeGetCurrentBranch, nativeDetectMainBranch, nativeBranchList, nativeBranchExists, nativeBranchListMerged, nativeBranchDelete, nativeWorktreeRemove, nativeCommitCountBetween, nativeHasChanges, } from "./native-git-bridge.js";
28
28
  import { GitServiceImpl } from "./git-service.js";
29
29
  import { captureIntegrationBranch, detectWorktreeName, setActiveMilestoneId, } from "./worktree.js";
30
- import { getAutoWorktreePath } from "./auto-worktree.js";
30
+ import { getAutoWorktreePath } from "./auto-worktree-path-resolution.js";
31
31
  import { checkoutBranchWithStashGuard } from "./worktree-git-recovery.js";
32
- import { readResourceVersion, cleanStaleRuntimeUnits } from "./auto-worktree.js";
32
+ import { cleanStaleRuntimeUnits } from "./auto-worktree-runtime-cleanup.js";
33
+ import { readResourceVersion } from "./auto-worktree-resource-version.js";
33
34
  import { worktreePath as getWorktreeDir, isInsideWorktreesDir } from "./worktree-manager.js";
34
35
  import { emitWorktreeOrphaned } from "./worktree-telemetry.js";
35
36
  import { queryJournal } from "./journal.js";
@@ -1409,7 +1410,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
1409
1410
  }
1410
1411
  // Snapshot installed skills
1411
1412
  if (resolveSkillDiscoveryMode(base) !== "off") {
1412
- snapshotSkills();
1413
+ snapshotSkills({ cwd: s.basePath });
1413
1414
  }
1414
1415
  setAutoActiveStatus(ctx, s.stepMode ? "next" : "auto");
1415
1416
  ctx.ui.setWidget("gsd-health", undefined);