gsd-pi 2.57.0 → 2.58.0-dev.778d6ac

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 (707) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +49 -35
  3. package/dist/headless-ui.d.ts +17 -0
  4. package/dist/headless-ui.js +97 -3
  5. package/dist/headless.js +67 -6
  6. package/dist/help-text.js +1 -0
  7. package/dist/onboarding.js +44 -0
  8. package/dist/resource-loader.js +16 -1
  9. package/dist/resources/agents/researcher.md +1 -1
  10. package/dist/resources/extensions/ask-user-questions.js +16 -3
  11. package/dist/resources/extensions/async-jobs/extension-manifest.json +1 -1
  12. package/dist/resources/extensions/bg-shell/extension-manifest.json +1 -1
  13. package/dist/resources/extensions/browser-tools/extension-manifest.json +1 -1
  14. package/dist/resources/extensions/claude-code-cli/partial-builder.js +14 -6
  15. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +59 -36
  16. package/dist/resources/extensions/context7/extension-manifest.json +1 -1
  17. package/dist/resources/extensions/get-secrets-from-user.js +8 -5
  18. package/dist/resources/extensions/google-search/extension-manifest.json +1 -1
  19. package/dist/resources/extensions/google-search/index.js +2 -1
  20. package/dist/resources/extensions/gsd/auto/infra-errors.js +4 -0
  21. package/dist/resources/extensions/gsd/auto/phases.js +25 -21
  22. package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
  23. package/dist/resources/extensions/gsd/auto-dashboard.js +37 -20
  24. package/dist/resources/extensions/gsd/auto-dispatch.js +20 -5
  25. package/dist/resources/extensions/gsd/auto-model-selection.js +26 -3
  26. package/dist/resources/extensions/gsd/auto-post-unit.js +16 -4
  27. package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
  28. package/dist/resources/extensions/gsd/auto-recovery.js +13 -5
  29. package/dist/resources/extensions/gsd/auto-start.js +35 -22
  30. package/dist/resources/extensions/gsd/auto-worktree.js +203 -14
  31. package/dist/resources/extensions/gsd/auto.js +4 -0
  32. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
  33. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +82 -9
  34. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
  35. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -18
  36. package/dist/resources/extensions/gsd/bootstrap/system-context.js +44 -11
  37. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -0
  38. package/dist/resources/extensions/gsd/captures.js +56 -4
  39. package/dist/resources/extensions/gsd/db-writer.js +116 -8
  40. package/dist/resources/extensions/gsd/dispatch-guard.js +11 -1
  41. package/dist/resources/extensions/gsd/doctor-git-checks.js +28 -0
  42. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  43. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +5 -4
  44. package/dist/resources/extensions/gsd/doctor.js +3 -1
  45. package/dist/resources/extensions/gsd/error-classifier.js +13 -10
  46. package/dist/resources/extensions/gsd/extension-manifest.json +16 -1
  47. package/dist/resources/extensions/gsd/forensics.js +123 -20
  48. package/dist/resources/extensions/gsd/git-service.js +23 -1
  49. package/dist/resources/extensions/gsd/gitignore.js +33 -0
  50. package/dist/resources/extensions/gsd/gsd-db.js +44 -10
  51. package/dist/resources/extensions/gsd/guided-flow.js +106 -44
  52. package/dist/resources/extensions/gsd/health-widget-core.js +31 -0
  53. package/dist/resources/extensions/gsd/health-widget.js +17 -0
  54. package/dist/resources/extensions/gsd/index.js +1 -1
  55. package/dist/resources/extensions/gsd/memory-extractor.js +7 -0
  56. package/dist/resources/extensions/gsd/migrate-external.js +8 -1
  57. package/dist/resources/extensions/gsd/milestone-validation-gates.js +45 -0
  58. package/dist/resources/extensions/gsd/model-cost-table.js +18 -0
  59. package/dist/resources/extensions/gsd/model-router.js +35 -1
  60. package/dist/resources/extensions/gsd/native-git-bridge.js +17 -0
  61. package/dist/resources/extensions/gsd/notifications.js +16 -1
  62. package/dist/resources/extensions/gsd/parallel-eligibility.js +13 -2
  63. package/dist/resources/extensions/gsd/parallel-merge.js +78 -5
  64. package/dist/resources/extensions/gsd/parallel-orchestrator.js +23 -6
  65. package/dist/resources/extensions/gsd/parsers-legacy.js +20 -3
  66. package/dist/resources/extensions/gsd/paths.js +43 -0
  67. package/dist/resources/extensions/gsd/preferences-models.js +14 -1
  68. package/dist/resources/extensions/gsd/preferences-types.js +2 -1
  69. package/dist/resources/extensions/gsd/preferences.js +42 -31
  70. package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
  71. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  72. package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  73. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  74. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  75. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -1
  76. package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
  77. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  78. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  79. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  80. package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
  81. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  82. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  83. package/dist/resources/extensions/gsd/repo-identity.js +205 -11
  84. package/dist/resources/extensions/gsd/rethink.js +5 -0
  85. package/dist/resources/extensions/gsd/roadmap-slices.js +5 -4
  86. package/dist/resources/extensions/gsd/state.js +85 -27
  87. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  88. package/dist/resources/extensions/gsd/tools/complete-task.js +34 -71
  89. package/dist/resources/extensions/gsd/tools/plan-milestone.js +12 -2
  90. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +29 -1
  91. package/dist/resources/extensions/gsd/tools/validate-milestone.js +18 -3
  92. package/dist/resources/extensions/gsd/triage-resolution.js +22 -7
  93. package/dist/resources/extensions/gsd/undo.js +2 -2
  94. package/dist/resources/extensions/gsd/unit-ownership.js +164 -33
  95. package/dist/resources/extensions/gsd/verdict-parser.js +20 -8
  96. package/dist/resources/extensions/gsd/workflow-manifest.js +24 -5
  97. package/dist/resources/extensions/gsd/workflow-projections.js +95 -63
  98. package/dist/resources/extensions/gsd/workflow-reconcile.js +35 -5
  99. package/dist/resources/extensions/gsd/workspace-index.js +24 -0
  100. package/dist/resources/extensions/gsd/worktree-manager.js +105 -1
  101. package/dist/resources/extensions/gsd/worktree-resolver.js +20 -3
  102. package/dist/resources/extensions/mcp-client/index.js +11 -7
  103. package/dist/resources/extensions/ollama/index.js +112 -0
  104. package/dist/resources/extensions/ollama/model-capabilities.js +115 -0
  105. package/dist/resources/extensions/ollama/ollama-client.js +168 -0
  106. package/dist/resources/extensions/ollama/ollama-commands.js +194 -0
  107. package/dist/resources/extensions/ollama/ollama-discovery.js +69 -0
  108. package/dist/resources/extensions/ollama/ollama-tool.js +184 -0
  109. package/dist/resources/extensions/ollama/types.js +2 -0
  110. package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
  111. package/dist/resources/extensions/shared/interview-ui.js +11 -1
  112. package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -3
  113. package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  114. package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  115. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  116. package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  117. package/dist/startup-model-validation.d.ts +39 -0
  118. package/dist/startup-model-validation.js +50 -0
  119. package/dist/web/standalone/.next/BUILD_ID +1 -1
  120. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  121. package/dist/web/standalone/.next/build-manifest.json +4 -4
  122. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  123. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  124. package/dist/web/standalone/.next/required-server-files.json +3 -3
  125. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  126. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  128. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  136. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  139. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  143. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  145. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  152. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  164. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  192. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  198. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  212. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  214. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  216. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  218. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  219. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  221. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  224. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  226. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  227. package/dist/web/standalone/.next/server/app/index.html +1 -1
  228. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  229. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  230. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  231. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  232. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  233. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  234. package/dist/web/standalone/.next/server/app/page.js +2 -2
  235. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  236. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  237. package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
  238. package/dist/web/standalone/.next/server/chunks/7471.js +3 -3
  239. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  240. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  241. package/dist/web/standalone/.next/server/middleware.js +2 -2
  242. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  243. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  244. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  245. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  246. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  247. package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +9 -0
  248. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  249. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  250. package/dist/web/standalone/.next/static/chunks/app/page-0c485498795110d6.js +1 -0
  251. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  252. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  253. package/dist/web/standalone/.next/static/chunks/{webpack-4332cbd5dd1be584.js → webpack-a1c1e452c6b32d04.js} +1 -1
  254. package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +1 -0
  255. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  256. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  257. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  258. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  259. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  260. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  261. package/dist/web/standalone/server.js +1 -1
  262. package/dist/web-mode.js +2 -1
  263. package/package.json +2 -2
  264. package/packages/daemon/src/cli.ts +49 -0
  265. package/packages/daemon/src/daemon.test.ts +104 -1
  266. package/packages/daemon/src/daemon.ts +24 -1
  267. package/packages/daemon/src/discord-bot.ts +73 -3
  268. package/packages/daemon/src/event-bridge.ts +15 -9
  269. package/packages/daemon/src/event-formatter.ts +30 -2
  270. package/packages/daemon/src/index.ts +9 -0
  271. package/packages/daemon/src/launchd.test.ts +356 -0
  272. package/packages/daemon/src/launchd.ts +242 -0
  273. package/packages/daemon/src/message-batcher.test.ts +2 -2
  274. package/packages/daemon/src/message-batcher.ts +9 -3
  275. package/packages/daemon/src/orchestrator.test.ts +1 -0
  276. package/packages/daemon/src/orchestrator.ts +106 -2
  277. package/packages/native/dist/ast/index.js +9 -5
  278. package/packages/native/dist/ast/types.js +2 -1
  279. package/packages/native/dist/clipboard/index.js +12 -7
  280. package/packages/native/dist/clipboard/types.js +2 -1
  281. package/packages/native/dist/diff/index.js +12 -7
  282. package/packages/native/dist/diff/types.js +2 -1
  283. package/packages/native/dist/fd/index.js +6 -3
  284. package/packages/native/dist/fd/types.js +2 -1
  285. package/packages/native/dist/glob/index.js +9 -5
  286. package/packages/native/dist/glob/types.js +2 -1
  287. package/packages/native/dist/grep/index.js +9 -5
  288. package/packages/native/dist/grep/types.js +2 -1
  289. package/packages/native/dist/gsd-parser/index.js +18 -11
  290. package/packages/native/dist/gsd-parser/types.js +2 -1
  291. package/packages/native/dist/highlight/index.js +12 -7
  292. package/packages/native/dist/highlight/types.js +2 -1
  293. package/packages/native/dist/html/index.js +6 -3
  294. package/packages/native/dist/html/types.js +2 -1
  295. package/packages/native/dist/image/index.js +10 -5
  296. package/packages/native/dist/image/types.js +7 -4
  297. package/packages/native/dist/index.js +70 -17
  298. package/packages/native/dist/json-parse/index.js +13 -8
  299. package/packages/native/dist/native.js +47 -10
  300. package/packages/native/dist/ps/index.js +15 -9
  301. package/packages/native/dist/ps/types.js +2 -1
  302. package/packages/native/dist/stream-process/index.js +12 -7
  303. package/packages/native/dist/text/index.js +24 -14
  304. package/packages/native/dist/text/types.js +5 -2
  305. package/packages/native/dist/truncate/index.js +12 -7
  306. package/packages/native/dist/ttsr/index.js +12 -7
  307. package/packages/native/dist/ttsr/types.js +2 -1
  308. package/packages/native/dist/xxhash/index.js +9 -5
  309. package/packages/native/package.json +19 -19
  310. package/packages/native/src/__tests__/module-compat.test.mjs +91 -0
  311. package/packages/native/src/native.ts +9 -8
  312. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  313. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  314. package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
  315. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  316. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  317. package/packages/pi-agent-core/src/agent-loop.test.ts +45 -0
  318. package/packages/pi-agent-core/src/agent-loop.ts +3 -2
  319. package/packages/pi-agent-core/src/proxy.ts +1 -1
  320. package/packages/pi-ai/dist/env-api-keys.js +1 -0
  321. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  322. package/packages/pi-ai/dist/index.d.ts +1 -0
  323. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  324. package/packages/pi-ai/dist/index.js +1 -0
  325. package/packages/pi-ai/dist/index.js.map +1 -1
  326. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  327. package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -2
  328. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  329. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +2 -0
  330. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +1 -0
  331. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +25 -0
  332. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -0
  333. package/packages/pi-ai/dist/types.d.ts +3 -3
  334. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  335. package/packages/pi-ai/dist/types.js.map +1 -1
  336. package/packages/pi-ai/dist/utils/json-parse.d.ts +3 -0
  337. package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
  338. package/packages/pi-ai/dist/utils/json-parse.js +24 -1
  339. package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
  340. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +37 -0
  341. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -0
  342. package/packages/pi-ai/dist/utils/repair-tool-json.js +75 -0
  343. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -0
  344. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +2 -0
  345. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +1 -0
  346. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +73 -0
  347. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -0
  348. package/packages/pi-ai/src/env-api-keys.ts +1 -0
  349. package/packages/pi-ai/src/index.ts +1 -0
  350. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +29 -0
  351. package/packages/pi-ai/src/providers/anthropic-shared.ts +17 -2
  352. package/packages/pi-ai/src/types.ts +3 -2
  353. package/packages/pi-ai/src/utils/json-parse.ts +28 -1
  354. package/packages/pi-ai/src/utils/repair-tool-json.ts +88 -0
  355. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +102 -0
  356. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -0
  357. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  358. package/packages/pi-coding-agent/dist/core/agent-session.js +31 -0
  359. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  360. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +17 -1
  361. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  362. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +62 -2
  363. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  364. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +6 -0
  365. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +1 -0
  366. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +176 -0
  367. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -0
  368. package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/core/exec.js +3 -1
  370. package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +28 -0
  372. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +1 -0
  373. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +37 -0
  374. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +1 -0
  375. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +2 -0
  376. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +1 -0
  377. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +63 -0
  378. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +1 -0
  379. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +19 -0
  380. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +1 -0
  381. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +115 -0
  382. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +1 -0
  383. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +2 -0
  384. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +1 -0
  385. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +109 -0
  386. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +1 -0
  387. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +4 -0
  388. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  389. package/packages/pi-coding-agent/dist/core/extensions/index.js +2 -0
  390. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  391. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  392. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  393. package/packages/pi-coding-agent/dist/core/extensions/loader.js +5 -0
  394. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  395. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts +44 -0
  396. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +1 -0
  397. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +97 -0
  398. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +1 -0
  399. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +2 -0
  400. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +1 -0
  401. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +181 -0
  402. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +1 -0
  403. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
  404. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  405. package/packages/pi-coding-agent/dist/core/index.js +1 -1
  406. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  407. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  408. package/packages/pi-coding-agent/dist/core/lsp/index.js +3 -0
  409. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  410. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  411. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -0
  412. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  413. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  414. package/packages/pi-coding-agent/dist/core/messages.js +31 -2
  415. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  416. package/packages/pi-coding-agent/dist/core/messages.test.d.ts +9 -0
  417. package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +1 -0
  418. package/packages/pi-coding-agent/dist/core/messages.test.js +86 -0
  419. package/packages/pi-coding-agent/dist/core/messages.test.js.map +1 -0
  420. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  421. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  422. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  423. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +10 -0
  424. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  425. package/packages/pi-coding-agent/dist/core/resource-loader.js +12 -1
  426. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  427. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +6 -0
  428. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  429. package/packages/pi-coding-agent/dist/core/retry-handler.js +48 -1
  430. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  431. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +9 -0
  432. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +1 -0
  433. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +193 -0
  434. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -0
  435. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  436. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +10 -3
  437. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  438. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  439. package/packages/pi-coding-agent/dist/core/tools/read.js +13 -4
  440. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  441. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +16 -0
  442. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +1 -0
  443. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +80 -0
  444. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -0
  445. package/packages/pi-coding-agent/dist/index.d.ts +2 -2
  446. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  447. package/packages/pi-coding-agent/dist/index.js +1 -1
  448. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  449. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  450. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +4 -0
  451. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  452. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +1 -0
  453. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
  454. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +5 -0
  455. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
  456. package/packages/pi-coding-agent/package.json +1 -1
  457. package/packages/pi-coding-agent/src/core/agent-session.ts +38 -1
  458. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +236 -0
  459. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +94 -1
  460. package/packages/pi-coding-agent/src/core/exec.ts +3 -1
  461. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +77 -0
  462. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +62 -0
  463. package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +134 -0
  464. package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +137 -0
  465. package/packages/pi-coding-agent/src/core/extensions/index.ts +4 -0
  466. package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
  467. package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +228 -0
  468. package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +118 -0
  469. package/packages/pi-coding-agent/src/core/index.ts +6 -0
  470. package/packages/pi-coding-agent/src/core/lsp/index.ts +3 -0
  471. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -0
  472. package/packages/pi-coding-agent/src/core/messages.test.ts +114 -0
  473. package/packages/pi-coding-agent/src/core/messages.ts +29 -2
  474. package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
  475. package/packages/pi-coding-agent/src/core/resource-loader.ts +20 -1
  476. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +255 -0
  477. package/packages/pi-coding-agent/src/core/retry-handler.ts +52 -1
  478. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +11 -3
  479. package/packages/pi-coding-agent/src/core/tools/read.ts +14 -4
  480. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +92 -0
  481. package/packages/pi-coding-agent/src/index.ts +6 -0
  482. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +7 -0
  483. package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +6 -0
  484. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  485. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  486. package/packages/pi-tui/dist/terminal.js +9 -0
  487. package/packages/pi-tui/dist/terminal.js.map +1 -1
  488. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  489. package/packages/pi-tui/dist/tui.js +9 -0
  490. package/packages/pi-tui/dist/tui.js.map +1 -1
  491. package/packages/pi-tui/src/terminal.ts +14 -0
  492. package/packages/pi-tui/src/tui.ts +8 -0
  493. package/pkg/package.json +1 -1
  494. package/scripts/ensure-workspace-builds.cjs +45 -14
  495. package/src/resources/agents/researcher.md +1 -1
  496. package/src/resources/extensions/ask-user-questions.ts +21 -3
  497. package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
  498. package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
  499. package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
  500. package/src/resources/extensions/claude-code-cli/partial-builder.ts +13 -6
  501. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +63 -35
  502. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +28 -0
  503. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -1
  504. package/src/resources/extensions/context7/extension-manifest.json +1 -1
  505. package/src/resources/extensions/get-secrets-from-user.ts +8 -5
  506. package/src/resources/extensions/google-search/extension-manifest.json +1 -1
  507. package/src/resources/extensions/google-search/index.ts +2 -1
  508. package/src/resources/extensions/gsd/auto/infra-errors.ts +3 -0
  509. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  510. package/src/resources/extensions/gsd/auto/phases.ts +43 -34
  511. package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
  512. package/src/resources/extensions/gsd/auto-dashboard.ts +37 -19
  513. package/src/resources/extensions/gsd/auto-dispatch.ts +21 -5
  514. package/src/resources/extensions/gsd/auto-model-selection.ts +26 -5
  515. package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
  516. package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
  517. package/src/resources/extensions/gsd/auto-recovery.ts +12 -5
  518. package/src/resources/extensions/gsd/auto-start.ts +35 -26
  519. package/src/resources/extensions/gsd/auto-worktree.ts +197 -11
  520. package/src/resources/extensions/gsd/auto.ts +5 -0
  521. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
  522. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +87 -9
  523. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
  524. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +31 -19
  525. package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -11
  526. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +75 -0
  527. package/src/resources/extensions/gsd/captures.ts +63 -3
  528. package/src/resources/extensions/gsd/db-writer.ts +140 -7
  529. package/src/resources/extensions/gsd/dispatch-guard.ts +12 -1
  530. package/src/resources/extensions/gsd/doctor-git-checks.ts +26 -0
  531. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  532. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +5 -4
  533. package/src/resources/extensions/gsd/doctor.ts +3 -1
  534. package/src/resources/extensions/gsd/error-classifier.ts +14 -11
  535. package/src/resources/extensions/gsd/extension-manifest.json +16 -1
  536. package/src/resources/extensions/gsd/forensics.ts +144 -20
  537. package/src/resources/extensions/gsd/git-service.ts +26 -3
  538. package/src/resources/extensions/gsd/gitignore.ts +33 -0
  539. package/src/resources/extensions/gsd/gsd-db.ts +49 -8
  540. package/src/resources/extensions/gsd/guided-flow.ts +114 -45
  541. package/src/resources/extensions/gsd/health-widget-core.ts +34 -0
  542. package/src/resources/extensions/gsd/health-widget.ts +17 -0
  543. package/src/resources/extensions/gsd/index.ts +1 -0
  544. package/src/resources/extensions/gsd/memory-extractor.ts +8 -0
  545. package/src/resources/extensions/gsd/migrate-external.ts +9 -1
  546. package/src/resources/extensions/gsd/milestone-validation-gates.ts +56 -0
  547. package/src/resources/extensions/gsd/model-cost-table.ts +19 -0
  548. package/src/resources/extensions/gsd/model-router.ts +35 -1
  549. package/src/resources/extensions/gsd/native-git-bridge.ts +17 -0
  550. package/src/resources/extensions/gsd/notifications.ts +16 -0
  551. package/src/resources/extensions/gsd/parallel-eligibility.ts +15 -2
  552. package/src/resources/extensions/gsd/parallel-merge.ts +87 -4
  553. package/src/resources/extensions/gsd/parallel-orchestrator.ts +23 -6
  554. package/src/resources/extensions/gsd/parsers-legacy.ts +22 -3
  555. package/src/resources/extensions/gsd/paths.ts +42 -0
  556. package/src/resources/extensions/gsd/preferences-models.ts +14 -1
  557. package/src/resources/extensions/gsd/preferences-types.ts +2 -1
  558. package/src/resources/extensions/gsd/preferences.ts +45 -29
  559. package/src/resources/extensions/gsd/prompt-loader.ts +4 -1
  560. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  561. package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  562. package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  563. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  564. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -1
  565. package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
  566. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  567. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  568. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  569. package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
  570. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  571. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  572. package/src/resources/extensions/gsd/repo-identity.ts +186 -11
  573. package/src/resources/extensions/gsd/rethink.ts +6 -0
  574. package/src/resources/extensions/gsd/roadmap-slices.ts +5 -4
  575. package/src/resources/extensions/gsd/state.ts +84 -32
  576. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +47 -0
  577. package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +71 -0
  578. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +71 -1
  579. package/src/resources/extensions/gsd/tests/captures.test.ts +103 -0
  580. package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +47 -0
  581. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +27 -0
  582. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +21 -0
  583. package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +192 -0
  584. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +131 -0
  585. package/src/resources/extensions/gsd/tests/db-writer.test.ts +7 -12
  586. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +78 -5
  587. package/src/resources/extensions/gsd/tests/derive-state.test.ts +29 -0
  588. package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +47 -0
  589. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +127 -0
  590. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +40 -0
  591. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +47 -0
  592. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  593. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -0
  594. package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +20 -0
  595. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +74 -0
  596. package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +140 -0
  597. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +129 -0
  598. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +96 -0
  599. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +31 -0
  600. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +125 -12
  601. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +164 -0
  602. package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +135 -0
  603. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +97 -0
  604. package/src/resources/extensions/gsd/tests/health-widget.test.ts +67 -0
  605. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +107 -0
  606. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +111 -1
  607. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +101 -0
  608. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +59 -0
  609. package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +243 -0
  610. package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +150 -0
  611. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +110 -0
  612. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
  613. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +959 -0
  614. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +85 -2
  615. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +105 -0
  616. package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +116 -0
  617. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +34 -0
  618. package/src/resources/extensions/gsd/tests/model-router.test.ts +68 -3
  619. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +28 -0
  620. package/src/resources/extensions/gsd/tests/notifications.test.ts +45 -0
  621. package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +159 -0
  622. package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +150 -0
  623. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +9 -8
  624. package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +70 -0
  625. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +33 -1
  626. package/src/resources/extensions/gsd/tests/preferences.test.ts +34 -0
  627. package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +297 -0
  628. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +36 -0
  629. package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +178 -0
  630. package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +69 -0
  631. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +38 -0
  632. package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +157 -0
  633. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +90 -0
  634. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +117 -0
  635. package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +162 -0
  636. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +97 -0
  637. package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +134 -0
  638. package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +233 -0
  639. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +305 -0
  640. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +405 -0
  641. package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +257 -0
  642. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +1628 -0
  643. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +106 -0
  644. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +174 -0
  645. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +221 -0
  646. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +2 -1
  647. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +8 -0
  648. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +289 -0
  649. package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +100 -17
  650. package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +154 -0
  651. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +27 -2
  652. package/src/resources/extensions/gsd/tests/validation-gate-patterns.test.ts +44 -2
  653. package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +156 -0
  654. package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +82 -0
  655. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +48 -0
  656. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +92 -0
  657. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -2
  658. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +140 -0
  659. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +175 -0
  660. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +101 -0
  661. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +48 -1
  662. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +29 -5
  663. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +95 -0
  664. package/src/resources/extensions/gsd/tools/complete-task.ts +36 -74
  665. package/src/resources/extensions/gsd/tools/plan-milestone.ts +13 -1
  666. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +36 -0
  667. package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -2
  668. package/src/resources/extensions/gsd/triage-resolution.ts +23 -6
  669. package/src/resources/extensions/gsd/types.ts +4 -2
  670. package/src/resources/extensions/gsd/undo.ts +2 -2
  671. package/src/resources/extensions/gsd/unit-ownership.ts +206 -35
  672. package/src/resources/extensions/gsd/verdict-parser.ts +21 -6
  673. package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
  674. package/src/resources/extensions/gsd/workflow-manifest.ts +22 -5
  675. package/src/resources/extensions/gsd/workflow-projections.ts +97 -64
  676. package/src/resources/extensions/gsd/workflow-reconcile.ts +39 -10
  677. package/src/resources/extensions/gsd/workspace-index.ts +30 -0
  678. package/src/resources/extensions/gsd/worktree-manager.ts +120 -1
  679. package/src/resources/extensions/gsd/worktree-resolver.ts +22 -3
  680. package/src/resources/extensions/mcp-client/index.ts +13 -7
  681. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +55 -0
  682. package/src/resources/extensions/ollama/index.ts +130 -0
  683. package/src/resources/extensions/ollama/model-capabilities.ts +145 -0
  684. package/src/resources/extensions/ollama/ollama-client.ts +196 -0
  685. package/src/resources/extensions/ollama/ollama-commands.ts +248 -0
  686. package/src/resources/extensions/ollama/ollama-discovery.ts +106 -0
  687. package/src/resources/extensions/ollama/ollama-tool.ts +218 -0
  688. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +162 -0
  689. package/src/resources/extensions/ollama/tests/ollama-client.test.ts +38 -0
  690. package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +28 -0
  691. package/src/resources/extensions/ollama/types.ts +130 -0
  692. package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
  693. package/src/resources/extensions/shared/interview-ui.ts +12 -1
  694. package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +156 -0
  695. package/src/resources/skills/create-gsd-extension/SKILL.md +5 -3
  696. package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  697. package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  698. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  699. package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  700. package/dist/web/standalone/.next/static/chunks/6502.2305d0afd2385711.js +0 -9
  701. package/dist/web/standalone/.next/static/chunks/app/page-62be3b5fa91e4c8f.js +0 -1
  702. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  703. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  704. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +0 -1
  705. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +0 -79
  706. /package/dist/web/standalone/.next/static/{yowc5qPtuKxjOr22KmOAy → R0D4xaIPl5kg93edN7Oo0}/_buildManifest.js +0 -0
  707. /package/dist/web/standalone/.next/static/{yowc5qPtuKxjOr22KmOAy → R0D4xaIPl5kg93edN7Oo0}/_ssgManifest.js +0 -0
@@ -20,9 +20,27 @@ export const BUNDLED_COST_TABLE = [
20
20
  // OpenAI
21
21
  { id: "gpt-4o", inputPer1k: 0.0025, outputPer1k: 0.01, updatedAt: "2025-03-15" },
22
22
  { id: "gpt-4o-mini", inputPer1k: 0.00015, outputPer1k: 0.0006, updatedAt: "2025-03-15" },
23
+ { id: "gpt-4.1", inputPer1k: 0.002, outputPer1k: 0.008, updatedAt: "2026-03-29" },
24
+ { id: "gpt-4.1-mini", inputPer1k: 0.0004, outputPer1k: 0.0016, updatedAt: "2026-03-29" },
25
+ { id: "gpt-4.1-nano", inputPer1k: 0.0001, outputPer1k: 0.0004, updatedAt: "2026-03-29" },
26
+ { id: "gpt-5", inputPer1k: 0.01, outputPer1k: 0.04, updatedAt: "2026-03-29" },
27
+ { id: "gpt-5-mini", inputPer1k: 0.0003, outputPer1k: 0.0012, updatedAt: "2026-03-29" },
28
+ { id: "gpt-5-nano", inputPer1k: 0.0001, outputPer1k: 0.0004, updatedAt: "2026-03-29" },
29
+ { id: "gpt-5-pro", inputPer1k: 0.015, outputPer1k: 0.06, updatedAt: "2026-03-29" },
23
30
  { id: "o1", inputPer1k: 0.015, outputPer1k: 0.06, updatedAt: "2025-03-15" },
24
31
  { id: "o3", inputPer1k: 0.015, outputPer1k: 0.06, updatedAt: "2025-03-15" },
32
+ { id: "o4-mini", inputPer1k: 0.005, outputPer1k: 0.02, updatedAt: "2026-03-29" },
33
+ { id: "o4-mini-deep-research", inputPer1k: 0.005, outputPer1k: 0.02, updatedAt: "2026-03-29" },
25
34
  { id: "gpt-4-turbo", inputPer1k: 0.01, outputPer1k: 0.03, updatedAt: "2025-03-15" },
35
+ // OpenAI Codex
36
+ { id: "gpt-5.1", inputPer1k: 0.005, outputPer1k: 0.02, updatedAt: "2026-03-29" },
37
+ { id: "gpt-5.1-codex-max", inputPer1k: 0.003, outputPer1k: 0.012, updatedAt: "2026-03-29" },
38
+ { id: "gpt-5.1-codex-mini", inputPer1k: 0.0003, outputPer1k: 0.0012, updatedAt: "2026-03-29" },
39
+ { id: "gpt-5.2", inputPer1k: 0.005, outputPer1k: 0.02, updatedAt: "2026-03-29" },
40
+ { id: "gpt-5.2-codex", inputPer1k: 0.005, outputPer1k: 0.02, updatedAt: "2026-03-29" },
41
+ { id: "gpt-5.3-codex", inputPer1k: 0.005, outputPer1k: 0.02, updatedAt: "2026-03-29" },
42
+ { id: "gpt-5.3-codex-spark", inputPer1k: 0.0003, outputPer1k: 0.0012, updatedAt: "2026-03-29" },
43
+ { id: "gpt-5.4", inputPer1k: 0.005, outputPer1k: 0.02, updatedAt: "2026-03-29" },
26
44
  // Google
27
45
  { id: "gemini-2.0-flash", inputPer1k: 0.0001, outputPer1k: 0.0004, updatedAt: "2025-03-15" },
28
46
  { id: "gemini-flash-2.0", inputPer1k: 0.0001, outputPer1k: 0.0004, updatedAt: "2025-03-15" },
@@ -11,6 +11,12 @@ const MODEL_CAPABILITY_TIER = {
11
11
  "claude-3-5-haiku-latest": "light",
12
12
  "claude-3-haiku-20240307": "light",
13
13
  "gpt-4o-mini": "light",
14
+ "gpt-4.1-mini": "light",
15
+ "gpt-4.1-nano": "light",
16
+ "gpt-5-mini": "light",
17
+ "gpt-5-nano": "light",
18
+ "gpt-5.1-codex-mini": "light",
19
+ "gpt-5.3-codex-spark": "light",
14
20
  "gemini-2.0-flash": "light",
15
21
  "gemini-flash-2.0": "light",
16
22
  // Standard-tier models
@@ -18,14 +24,25 @@ const MODEL_CAPABILITY_TIER = {
18
24
  "claude-sonnet-4-5-20250514": "standard",
19
25
  "claude-3-5-sonnet-latest": "standard",
20
26
  "gpt-4o": "standard",
27
+ "gpt-4.1": "standard",
28
+ "gpt-5.1-codex-max": "standard",
21
29
  "gemini-2.5-pro": "standard",
22
30
  "deepseek-chat": "standard",
23
31
  // Heavy-tier models (most capable)
24
32
  "claude-opus-4-6": "heavy",
25
33
  "claude-3-opus-latest": "heavy",
26
34
  "gpt-4-turbo": "heavy",
35
+ "gpt-5": "heavy",
36
+ "gpt-5-pro": "heavy",
37
+ "gpt-5.1": "heavy",
38
+ "gpt-5.2": "heavy",
39
+ "gpt-5.2-codex": "heavy",
40
+ "gpt-5.3-codex": "heavy",
41
+ "gpt-5.4": "heavy",
27
42
  "o1": "heavy",
28
43
  "o3": "heavy",
44
+ "o4-mini": "heavy",
45
+ "o4-mini-deep-research": "heavy",
29
46
  };
30
47
  // ─── Cost Table (per 1K input tokens, approximate USD) ───────────────────────
31
48
  // Used for cross-provider cost comparison when multiple providers offer
@@ -38,6 +55,23 @@ const MODEL_COST_PER_1K_INPUT = {
38
55
  "claude-opus-4-6": 0.015,
39
56
  "gpt-4o-mini": 0.00015,
40
57
  "gpt-4o": 0.0025,
58
+ "gpt-4.1": 0.002,
59
+ "gpt-4.1-mini": 0.0004,
60
+ "gpt-4.1-nano": 0.0001,
61
+ "gpt-5": 0.01,
62
+ "gpt-5-mini": 0.0003,
63
+ "gpt-5-nano": 0.0001,
64
+ "gpt-5-pro": 0.015,
65
+ "gpt-5.1": 0.005,
66
+ "gpt-5.1-codex-max": 0.003,
67
+ "gpt-5.1-codex-mini": 0.0003,
68
+ "gpt-5.2": 0.005,
69
+ "gpt-5.2-codex": 0.005,
70
+ "gpt-5.3-codex": 0.005,
71
+ "gpt-5.3-codex-spark": 0.0003,
72
+ "gpt-5.4": 0.005,
73
+ "o4-mini": 0.005,
74
+ "o4-mini-deep-research": 0.005,
41
75
  "gemini-2.0-flash": 0.0001,
42
76
  "gemini-2.5-pro": 0.00125,
43
77
  "deepseek-chat": 0.00014,
@@ -133,7 +167,7 @@ export function escalateTier(currentTier) {
133
167
  */
134
168
  export function defaultRoutingConfig() {
135
169
  return {
136
- enabled: false,
170
+ enabled: true,
137
171
  escalate_on_failure: true,
138
172
  budget_pressure: true,
139
173
  cross_provider: true,
@@ -758,6 +758,23 @@ export function nativeResetHard(basePath) {
758
758
  }
759
759
  execSync("git reset --hard HEAD", { cwd: basePath, stdio: "pipe" });
760
760
  }
761
+ /**
762
+ * Get the subject line of a commit (git log -1 --format=%s <ref>).
763
+ * Returns empty string if the ref doesn't exist.
764
+ */
765
+ export function nativeCommitSubject(basePath, ref) {
766
+ try {
767
+ return execFileSync("git", ["log", "-1", "--format=%s", ref], {
768
+ cwd: basePath,
769
+ stdio: ["ignore", "pipe", "pipe"],
770
+ encoding: "utf-8",
771
+ env: GIT_NO_PROMPT_ENV,
772
+ }).trim();
773
+ }
774
+ catch {
775
+ return "";
776
+ }
777
+ }
761
778
  /**
762
779
  * Delete a branch.
763
780
  * Native: libgit2 branch delete.
@@ -7,7 +7,12 @@ import { CmuxClient, emitOsc777Notification, resolveCmuxConfig } from "../cmux/i
7
7
  * Send a native desktop notification. Non-blocking, non-fatal.
8
8
  * macOS: osascript, Linux: notify-send, Windows: skipped.
9
9
  */
10
- export function sendDesktopNotification(title, message, level = "info", kind = "complete") {
10
+ export function sendDesktopNotification(title, message, level = "info", kind = "complete", projectName) {
11
+ // When a projectName is provided and the title is the default "GSD",
12
+ // replace it with a project-qualified title for multi-project clarity.
13
+ if (projectName && title === "GSD") {
14
+ title = formatNotificationTitle(projectName);
15
+ }
11
16
  const loaded = loadEffectiveGSDPreferences()?.preferences;
12
17
  if (!shouldSendDesktopNotification(kind, loaded?.notifications))
13
18
  return;
@@ -45,6 +50,16 @@ export function shouldSendDesktopNotification(kind, preferences = loadEffectiveG
45
50
  return preferences?.on_complete ?? true;
46
51
  }
47
52
  }
53
+ /**
54
+ * Format a notification title that includes the project name for context.
55
+ * Returns "GSD — projectName" when a project name is available, otherwise "GSD".
56
+ */
57
+ export function formatNotificationTitle(projectName) {
58
+ const trimmed = projectName?.trim();
59
+ if (trimmed)
60
+ return `GSD — ${trimmed}`;
61
+ return "GSD";
62
+ }
48
63
  export function buildDesktopNotificationCommand(platform, title, message, level = "info") {
49
64
  const normalizedTitle = normalizeNotificationText(title);
50
65
  const normalizedMessage = normalizeNotificationText(message);
@@ -74,7 +74,18 @@ export async function analyzeParallelEligibility(basePath) {
74
74
  for (const mid of milestoneIds) {
75
75
  const entry = registryMap.get(mid);
76
76
  const title = entry?.title ?? mid;
77
- const status = entry?.status ?? "pending";
77
+ // Rule 0: milestones with no registry entry (ghost directories, unknown
78
+ // state) are ineligible — we cannot determine their status or deps (#2501)
79
+ if (!entry) {
80
+ ineligible.push({
81
+ milestoneId: mid,
82
+ title,
83
+ eligible: false,
84
+ reason: "Milestone has no planning data — cannot determine eligibility.",
85
+ });
86
+ continue;
87
+ }
88
+ const status = entry.status;
78
89
  // Rule 1: skip complete and parked milestones
79
90
  if (status === "complete" || status === "parked") {
80
91
  ineligible.push({
@@ -86,7 +97,7 @@ export async function analyzeParallelEligibility(basePath) {
86
97
  continue;
87
98
  }
88
99
  // Rule 2: check dependency satisfaction
89
- const deps = entry?.dependsOn ?? [];
100
+ const deps = entry.dependsOn ?? [];
90
101
  const unsatisfied = deps.filter(dep => {
91
102
  const depEntry = registryMap.get(dep);
92
103
  return !depEntry || depEntry.status !== "complete";
@@ -4,6 +4,9 @@
4
4
  * Handles merging completed milestone worktrees back to main branch
5
5
  * with safety checks for parallel execution context.
6
6
  */
7
+ import { existsSync, readdirSync } from "node:fs";
8
+ import { join } from "node:path";
9
+ import { spawnSync } from "node:child_process";
7
10
  import { loadFile } from "./files.js";
8
11
  import { resolveMilestoneFile } from "./paths.js";
9
12
  import { mergeMilestoneToMain } from "./auto-worktree.js";
@@ -11,19 +14,89 @@ import { MergeConflictError } from "./git-service.js";
11
14
  import { removeSessionStatus } from "./session-status-io.js";
12
15
  import { getErrorMessage } from "./error-utils.js";
13
16
  // ─── Merge Queue ───────────────────────────────────────────────────────────
17
+ /**
18
+ * Check whether a milestone is complete by querying its worktree SQLite DB.
19
+ * Uses a subprocess to avoid disrupting the global DB singleton.
20
+ * Returns true when milestones.status = 'complete' in the worktree's gsd.db.
21
+ */
22
+ export function isMilestoneCompleteInWorktreeDb(basePath, mid) {
23
+ const dbPath = join(basePath, ".gsd", "worktrees", mid, ".gsd", "gsd.db");
24
+ if (!existsSync(dbPath))
25
+ return false;
26
+ try {
27
+ const result = spawnSync("sqlite3", [dbPath, `SELECT status FROM milestones WHERE id='${mid}' LIMIT 1`], { timeout: 3000, encoding: "utf-8" });
28
+ return (result.stdout || "").trim() === "complete";
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ /**
35
+ * Discover milestone IDs with status='complete' in their worktree DB,
36
+ * scanning .gsd/worktrees/<MID>/.gsd/gsd.db for each worktree directory.
37
+ */
38
+ function discoverDbCompletedMilestones(basePath) {
39
+ const completed = new Set();
40
+ const worktreeDir = join(basePath, ".gsd", "worktrees");
41
+ try {
42
+ for (const entry of readdirSync(worktreeDir)) {
43
+ if (entry.startsWith("M") && isMilestoneCompleteInWorktreeDb(basePath, entry)) {
44
+ completed.add(entry);
45
+ }
46
+ }
47
+ }
48
+ catch {
49
+ // worktrees dir may not exist
50
+ }
51
+ return completed;
52
+ }
14
53
  /**
15
54
  * Determine safe merge order for completed milestones.
16
55
  * Sequential: merge in milestone ID order (M001 before M002).
17
56
  * By-completion: merge in the order milestones finished.
57
+ *
58
+ * When basePath is provided, also checks worktree SQLite DBs as the
59
+ * source of truth — workers with stale orchestrator state (e.g. "error")
60
+ * are included if their worktree DB shows status='complete'.
61
+ * See: https://github.com/gsd-build/gsd-2/issues/2812
18
62
  */
19
- export function determineMergeOrder(workers, order = "sequential") {
20
- const completed = workers.filter(w => w.state === "stopped");
63
+ export function determineMergeOrder(workers, order = "sequential", basePath) {
64
+ // Start with workers the orchestrator already knows are stopped
65
+ const stoppedIds = new Set(workers.filter(w => w.state === "stopped").map(w => w.milestoneId));
66
+ // When basePath is available, also check worktree DBs for milestones
67
+ // whose orchestrator state is stale but are actually complete (#2812)
68
+ const dbCompleted = basePath ? discoverDbCompletedMilestones(basePath) : new Set();
69
+ // Union: milestone is mergeable if stopped OR DB-complete
70
+ const mergeableIds = new Set([...stoppedIds, ...dbCompleted]);
71
+ // Build the list from tracked workers + any DB-discovered milestones
72
+ // not tracked by the orchestrator at all
73
+ const workerMap = new Map(workers.map(w => [w.milestoneId, w]));
74
+ const allMergeable = [];
75
+ for (const mid of mergeableIds) {
76
+ const w = workerMap.get(mid);
77
+ if (w) {
78
+ allMergeable.push(w);
79
+ }
80
+ else {
81
+ // Milestone discovered from worktree DB but not in workers list
82
+ allMergeable.push({
83
+ milestoneId: mid,
84
+ title: mid,
85
+ pid: 0,
86
+ process: null,
87
+ worktreePath: basePath ? join(basePath, ".gsd", "worktrees", mid) : "",
88
+ startedAt: 0,
89
+ state: "stopped",
90
+ cost: 0,
91
+ });
92
+ }
93
+ }
21
94
  if (order === "by-completion") {
22
- return completed
95
+ return allMergeable
23
96
  .sort((a, b) => a.startedAt - b.startedAt) // earliest first
24
97
  .map(w => w.milestoneId);
25
98
  }
26
- return completed
99
+ return allMergeable
27
100
  .sort((a, b) => a.milestoneId.localeCompare(b.milestoneId))
28
101
  .map(w => w.milestoneId);
29
102
  }
@@ -82,7 +155,7 @@ export async function mergeCompletedMilestone(basePath, milestoneId) {
82
155
  * Stops on first conflict and returns results so far.
83
156
  */
84
157
  export async function mergeAllCompleted(basePath, workers, order = "sequential") {
85
- const mergeOrder = determineMergeOrder(workers, order);
158
+ const mergeOrder = determineMergeOrder(workers, order, basePath);
86
159
  const results = [];
87
160
  for (const mid of mergeOrder) {
88
161
  const result = await mergeCompletedMilestone(basePath, mid);
@@ -406,8 +406,19 @@ function createMilestoneWorktree(basePath, milestoneId) {
406
406
  // ─── Worker Spawning ───────────────────────────────────────────────────
407
407
  /**
408
408
  * Spawn a worker process for a milestone.
409
- * The worker runs `gsd --print "/gsd auto"` in the milestone's worktree
409
+ * The worker runs `gsd headless --json auto` in the milestone's worktree
410
410
  * with GSD_MILESTONE_LOCK set to isolate state derivation.
411
+ *
412
+ * IMPORTANT: We use `headless --json auto` instead of `--print "/gsd auto"`.
413
+ * --print mode calls session.prompt() which returns immediately after the
414
+ * extension command handler fires, because auto-mode's ctx.newSession()
415
+ * resets the session and unblocks the outer prompt() await. This causes
416
+ * process.exit(0) to fire before any LLM work happens. See #2792.
417
+ *
418
+ * The headless subcommand uses an RPC client that keeps the process alive
419
+ * until auto-mode emits a terminal notification or the idle timer fires.
420
+ * It outputs NDJSON events to stdout (with --json), which our
421
+ * processWorkerLine() parser already understands.
411
422
  */
412
423
  export function spawnWorker(basePath, milestoneId) {
413
424
  if (!state)
@@ -423,7 +434,7 @@ export function spawnWorker(basePath, milestoneId) {
423
434
  return false;
424
435
  let child;
425
436
  try {
426
- child = spawn(process.execPath, [binPath, "--mode", "json", "--print", "/gsd auto"], {
437
+ child = spawn(process.execPath, [binPath, "headless", "--json", "auto"], {
427
438
  cwd: worker.worktreePath,
428
439
  env: {
429
440
  ...process.env,
@@ -461,9 +472,10 @@ export function spawnWorker(basePath, milestoneId) {
461
472
  return false;
462
473
  }
463
474
  // ── NDJSON stdout monitoring ────────────────────────────────────────
464
- // Workers run with --mode json, emitting one JSON event per line.
465
- // We parse message_end events to extract cost/token usage, keeping
466
- // the coordinator's cost tracking in sync with actual API spend.
475
+ // Workers run via `headless --json`, which forwards all RPC events
476
+ // as NDJSON to stdout. We parse message_end events to extract
477
+ // cost/token usage, keeping the coordinator's cost tracking in sync
478
+ // with actual API spend.
467
479
  if (child.stdout) {
468
480
  let stdoutBuffer = "";
469
481
  child.stdout.on("data", (data) => {
@@ -674,7 +686,12 @@ export async function stopParallel(basePath, milestoneId) {
674
686
  }
675
687
  catch { /* process may already be dead */ }
676
688
  }
677
- const exitedAfterTerm = await waitForWorkerExit(worker, 750);
689
+ // Wait for the headless process to cascade SIGTERM to its RPC child.
690
+ // The headless signal handler calls client.stop() which sends SIGTERM
691
+ // to the RPC child and waits up to 1000ms. The previous 750ms window
692
+ // was insufficient — the parent got SIGKILL before the child died,
693
+ // leaving orphaned RPC processes holding auto.lock. See #2798.
694
+ const exitedAfterTerm = await waitForWorkerExit(worker, 3000);
678
695
  if (!exitedAfterTerm && worker.pid > 0) {
679
696
  try {
680
697
  if (worker.process) {
@@ -165,16 +165,26 @@ function _parsePlanImpl(content) {
165
165
  const demo = extractBoldField(body, 'Demo') || '';
166
166
  const mhSection = extractSection(body, 'Must-Haves');
167
167
  const mustHaves = mhSection ? parseBullets(mhSection) : [];
168
+ // Parse tasks from ## Tasks section first, then scan the full body for any
169
+ // task checkboxes that were missed. Multi-task plans can interleave T01 detail
170
+ // headings (## Steps, ## Must-Haves) before T02's checkbox, which causes
171
+ // extractSection("Tasks") to stop at the first ## heading and miss T02+ (#3105).
168
172
  const tasksSection = extractSection(body, 'Tasks');
169
173
  const tasks = [];
170
- if (tasksSection) {
171
- const taskLines = tasksSection.split('\n');
174
+ // Parse task entries from a set of lines, appending to `tasks`.
175
+ const parseTaskLines = (lines, knownIds) => {
172
176
  let currentTask = null;
173
- for (const line of taskLines) {
177
+ for (const line of lines) {
174
178
  const cbMatch = line.match(/^-\s+\[([ xX])\]\s+\*\*([\w.]+):\s+(.+?)\*\*\s*(.*)/);
175
179
  // Heading-style: ### T01 -- Title, ### T01: Title, ### T01 — Title
176
180
  const hdMatch = !cbMatch ? line.match(/^#{2,4}\s+([\w.]+)\s*(?:--|—|:)\s*(.+)/) : null;
177
181
  if (cbMatch || hdMatch) {
182
+ const taskId = cbMatch ? cbMatch[2] : hdMatch[1];
183
+ // Skip tasks already found in the Tasks section
184
+ if (knownIds.has(taskId)) {
185
+ currentTask = null;
186
+ continue;
187
+ }
178
188
  if (currentTask)
179
189
  tasks.push(currentTask);
180
190
  if (cbMatch) {
@@ -229,7 +239,14 @@ function _parsePlanImpl(content) {
229
239
  }
230
240
  if (currentTask)
231
241
  tasks.push(currentTask);
242
+ };
243
+ if (tasksSection) {
244
+ parseTaskLines(tasksSection.split('\n'), new Set());
232
245
  }
246
+ // Second pass: scan the full body for task checkboxes outside ## Tasks.
247
+ // This handles interleaved plans where T02+ appear after T01's detail headings.
248
+ const foundIds = new Set(tasks.map(t => t.id));
249
+ parseTaskLines(body.split('\n'), foundIds);
233
250
  const filesSection = extractSection(body, 'Files Likely Touched');
234
251
  const filesLikelyTouched = filesSection ? parseBullets(filesSection) : [];
235
252
  const result = { id, title, goal, demo, mustHaves, tasks, filesLikelyTouched };
@@ -289,11 +289,51 @@ export function gsdRoot(basePath) {
289
289
  gsdRootCache.set(basePath, result);
290
290
  return result;
291
291
  }
292
+ /**
293
+ * Detect if a path is inside a .gsd/worktrees/<name>/ structure.
294
+ *
295
+ * GSD auto-worktrees live at <project>/.gsd/worktrees/<milestoneId>/.
296
+ * When gsdRoot() is called with such a path, we must NOT walk up to the
297
+ * project root's .gsd — each worktree manages its own .gsd state (#2594).
298
+ *
299
+ * Matches both forward-slash and platform-native separators to handle
300
+ * Windows paths (path.sep = '\\') and normalized Unix paths.
301
+ */
302
+ function isInsideGsdWorktree(p) {
303
+ // Match /.gsd/worktrees/<name> where <name> is the final segment or
304
+ // followed by a separator. The <name> segment must be non-empty.
305
+ const sepFwd = "/";
306
+ const sepNative = "\\";
307
+ const markers = [
308
+ `${sepFwd}.gsd${sepFwd}worktrees${sepFwd}`,
309
+ `${sepNative}.gsd${sepNative}worktrees${sepNative}`,
310
+ ];
311
+ for (const marker of markers) {
312
+ const idx = p.indexOf(marker);
313
+ if (idx === -1)
314
+ continue;
315
+ // Verify there's a non-empty worktree name after the marker
316
+ const afterMarker = p.slice(idx + marker.length);
317
+ // The name is everything up to the next separator (or end of string)
318
+ const nameEnd = afterMarker.search(/[/\\]/);
319
+ const name = nameEnd === -1 ? afterMarker : afterMarker.slice(0, nameEnd);
320
+ if (name.length > 0)
321
+ return true;
322
+ }
323
+ return false;
324
+ }
292
325
  function probeGsdRoot(rawBasePath) {
293
326
  // 1. Fast path — check the input path directly
294
327
  const local = join(rawBasePath, ".gsd");
295
328
  if (existsSync(local))
296
329
  return local;
330
+ // 1b. Worktree guard (#2594) — if basePath is inside a .gsd/worktrees/<name>/
331
+ // structure, return the worktree-local .gsd path immediately. Without this,
332
+ // the git-root probe (step 2) or walk-up (step 3) escapes to the project
333
+ // root's .gsd, causing ensurePreconditions() and deriveState() to read/write
334
+ // state in the wrong location.
335
+ if (isInsideGsdWorktree(rawBasePath))
336
+ return local;
297
337
  // Resolve symlinks so path comparisons work correctly across platforms
298
338
  // (e.g. macOS /var → /private/var). Use rawBasePath as fallback if not resolvable.
299
339
  let basePath;
@@ -303,6 +343,9 @@ function probeGsdRoot(rawBasePath) {
303
343
  catch {
304
344
  basePath = rawBasePath;
305
345
  }
346
+ // Also check the resolved path for the worktree pattern (macOS /tmp → /private/tmp)
347
+ if (basePath !== rawBasePath && isInsideGsdWorktree(basePath))
348
+ return local;
306
349
  // 2. Git root anchor — used as both probe target and walk-up boundary
307
350
  // Only walk if we're inside a git project — prevents escaping into
308
351
  // unrelated filesystem territory when running outside any repo.
@@ -53,6 +53,7 @@ export function resolveModelWithFallbacksForUnit(unitType) {
53
53
  break;
54
54
  case "complete-slice":
55
55
  case "complete-milestone":
56
+ case "worktree-merge":
56
57
  case "run-uat":
57
58
  phaseConfig = m.completion;
58
59
  break;
@@ -110,6 +111,18 @@ export function getNextFallbackModel(currentModelId, modelConfig) {
110
111
  return modelsToTry[0];
111
112
  }
112
113
  }
114
+ /**
115
+ * Detect whether an error message indicates a transient network error
116
+ * (worth retrying the same model) vs a permanent provider error
117
+ * (auth failure, quota exceeded, etc. -- should fall back immediately).
118
+ */
119
+ export function isTransientNetworkError(errorMsg) {
120
+ if (!errorMsg)
121
+ return false;
122
+ const hasNetworkSignal = /network|ECONNRESET|ETIMEDOUT|ECONNREFUSED|socket hang up|fetch failed|connection.*reset|dns/i.test(errorMsg);
123
+ const hasPermanentSignal = /auth|unauthorized|forbidden|invalid.*key|quota|billing/i.test(errorMsg);
124
+ return hasNetworkSignal && !hasPermanentSignal;
125
+ }
113
126
  /**
114
127
  * Validate a model ID string.
115
128
  * Returns true if the ID looks like a valid model identifier.
@@ -273,7 +286,7 @@ export function resolveContextSelection() {
273
286
  return profile === "budget" ? "smart" : "full";
274
287
  }
275
288
  /**
276
- * Resolve the search provider preference from PREFERENCES.md.
289
+ * Resolve the search provider preference from preferences.md.
277
290
  * Returns undefined if not configured (caller falls back to existing behavior).
278
291
  */
279
292
  export function resolveSearchProviderFromPreferences() {
@@ -76,6 +76,7 @@ export const KNOWN_PREFERENCE_KEYS = new Set([
76
76
  export const KNOWN_UNIT_TYPES = [
77
77
  "research-milestone", "plan-milestone", "research-slice", "plan-slice",
78
78
  "execute-task", "reactive-execute", "gate-evaluate", "complete-slice", "replan-slice", "reassess-roadmap",
79
- "run-uat", "complete-milestone",
79
+ "run-uat", "complete-milestone", "validate-milestone", "rewrite-docs",
80
+ "discuss-milestone", "discuss-slice", "worktree-merge",
80
81
  ];
81
82
  export const SKILL_ACTIONS = new Set(["use", "prefer", "avoid"]);
@@ -16,7 +16,7 @@ import { gsdRoot } from "./paths.js";
16
16
  import { parse as parseYaml } from "yaml";
17
17
  import { normalizeStringArray } from "../shared/format-utils.js";
18
18
  import { resolveProfileDefaults as _resolveProfileDefaults } from "./preferences-models.js";
19
- import { MODE_DEFAULTS, } from "./preferences-types.js";
19
+ import { KNOWN_PREFERENCE_KEYS, MODE_DEFAULTS, } from "./preferences-types.js";
20
20
  import { validatePreferences } from "./preferences-validation.js";
21
21
  import { formatSkillRef } from "./preferences-skills.js";
22
22
  // ─── Re-exports: validation ─────────────────────────────────────────────────
@@ -24,27 +24,27 @@ export { validatePreferences } from "./preferences-validation.js";
24
24
  // ─── Re-exports: skills ─────────────────────────────────────────────────────
25
25
  export { resolveAllSkillReferences, resolveSkillDiscoveryMode, resolveSkillStalenessDays, } from "./preferences-skills.js";
26
26
  // ─── Re-exports: models ─────────────────────────────────────────────────────
27
- export { resolveModelForUnit, resolveModelWithFallbacksForUnit, getNextFallbackModel, validateModelId, updatePreferencesModels, resolveDynamicRoutingConfig, resolveAutoSupervisorConfig, resolveProfileDefaults, resolveEffectiveProfile, resolveInlineLevel, resolveContextSelection, resolveSearchProviderFromPreferences, } from "./preferences-models.js";
27
+ export { resolveModelForUnit, resolveModelWithFallbacksForUnit, getNextFallbackModel, isTransientNetworkError, validateModelId, updatePreferencesModels, resolveDynamicRoutingConfig, resolveAutoSupervisorConfig, resolveProfileDefaults, resolveEffectiveProfile, resolveInlineLevel, resolveContextSelection, resolveSearchProviderFromPreferences, } from "./preferences-models.js";
28
28
  // ─── Path Constants & Getters ───────────────────────────────────────────────
29
29
  function gsdHome() {
30
30
  return process.env.GSD_HOME || join(homedir(), ".gsd");
31
31
  }
32
32
  function globalPreferencesPath() {
33
- return join(gsdHome(), "PREFERENCES.md");
33
+ return join(gsdHome(), "preferences.md");
34
34
  }
35
35
  function legacyGlobalPreferencesPath() {
36
36
  return join(homedir(), ".pi", "agent", "gsd-preferences.md");
37
37
  }
38
38
  function projectPreferencesPath() {
39
- return join(gsdRoot(process.cwd()), "PREFERENCES.md");
39
+ return join(gsdRoot(process.cwd()), "preferences.md");
40
40
  }
41
- // Legacy: older versions used lowercase preferences.md.
42
- // Check lowercase as a fallback so those files aren't silently ignored.
43
- function globalPreferencesPathLegacy() {
44
- return join(gsdHome(), "preferences.md");
41
+ // Bootstrap in gitignore.ts historically created PREFERENCES.md (uppercase) by mistake.
42
+ // Check uppercase as a fallback so those files aren't silently ignored.
43
+ function globalPreferencesPathUppercase() {
44
+ return join(gsdHome(), "PREFERENCES.md");
45
45
  }
46
- function projectPreferencesPathLegacy() {
47
- return join(gsdRoot(process.cwd()), "preferences.md");
46
+ function projectPreferencesPathUppercase() {
47
+ return join(gsdRoot(process.cwd()), "PREFERENCES.md");
48
48
  }
49
49
  export function getGlobalGSDPreferencesPath() {
50
50
  return globalPreferencesPath();
@@ -58,12 +58,12 @@ export function getProjectGSDPreferencesPath() {
58
58
  // ─── Loading ────────────────────────────────────────────────────────────────
59
59
  export function loadGlobalGSDPreferences() {
60
60
  return loadPreferencesFile(globalPreferencesPath(), "global")
61
- ?? loadPreferencesFile(globalPreferencesPathLegacy(), "global")
61
+ ?? loadPreferencesFile(globalPreferencesPathUppercase(), "global")
62
62
  ?? loadPreferencesFile(legacyGlobalPreferencesPath(), "global");
63
63
  }
64
64
  export function loadProjectGSDPreferences() {
65
65
  return loadPreferencesFile(projectPreferencesPath(), "project")
66
- ?? loadPreferencesFile(projectPreferencesPathLegacy(), "project");
66
+ ?? loadPreferencesFile(projectPreferencesPathUppercase(), "project");
67
67
  }
68
68
  export function loadEffectiveGSDPreferences() {
69
69
  const globalPreferences = loadGlobalGSDPreferences();
@@ -149,7 +149,7 @@ export function parsePreferencesMarkdown(content) {
149
149
  }
150
150
  if (!_warnedUnrecognizedFormat) {
151
151
  _warnedUnrecognizedFormat = true;
152
- console.warn("[parsePreferencesMarkdown] PREFERENCES.md exists but uses an unrecognized format — skipping.");
152
+ console.warn("[parsePreferencesMarkdown] preferences.md exists but uses an unrecognized format — skipping.");
153
153
  }
154
154
  return null;
155
155
  }
@@ -183,28 +183,42 @@ function parseHeadingListFormat(content) {
183
183
  const headingMatch = line.match(/^##\s+(.+)$/);
184
184
  if (headingMatch) {
185
185
  currentSection = headingMatch[1].trim().toLowerCase().replace(/\s+/g, '_');
186
+ if (!result[currentSection])
187
+ result[currentSection] = [];
186
188
  continue;
187
189
  }
188
- if (currentSection) {
189
- const itemMatch = line.match(/^-\s+([^:]+):\s*(.*)$/);
190
- if (itemMatch) {
191
- if (!result[currentSection])
192
- result[currentSection] = {};
193
- const value = itemMatch[2].trim();
194
- // Coerce "true"/"false" strings and numbers
195
- result[currentSection][itemMatch[1].trim()] = value;
196
- }
190
+ if (currentSection && line.trim() && !line.trimStart().startsWith('#')) {
191
+ result[currentSection].push(line);
197
192
  }
198
193
  }
199
- // Convert string values to appropriate types via YAML parser for each section
200
194
  const typed = {};
201
- for (const [section, entries] of Object.entries(result)) {
202
- const yamlLines = Object.entries(entries).map(([k, v]) => `${k}: ${v}`).join('\n');
195
+ for (const [section, lines] of Object.entries(result)) {
196
+ if (lines.length === 0)
197
+ continue;
198
+ const usesLegacyListItems = lines.every((line) => /^\s*-\s+[^:]+:\s*.*$/.test(line));
199
+ const yamlBlock = usesLegacyListItems
200
+ ? lines.map((line) => line.replace(/^\s*-\s+/, '')).join('\n')
201
+ : lines.join('\n');
203
202
  try {
204
- typed[section] = parseYaml(yamlLines);
203
+ const parsed = parseYaml(yamlBlock);
204
+ if (typeof parsed !== 'object' || parsed === null)
205
+ continue;
206
+ let targetSection = section;
207
+ let value = parsed;
208
+ if (!Array.isArray(parsed)) {
209
+ const keys = Object.keys(parsed);
210
+ if (keys.length === 1) {
211
+ const [onlyKey] = keys;
212
+ if (onlyKey === section || (!KNOWN_PREFERENCE_KEYS.has(section) && KNOWN_PREFERENCE_KEYS.has(onlyKey))) {
213
+ targetSection = onlyKey;
214
+ value = parsed[onlyKey];
215
+ }
216
+ }
217
+ }
218
+ typed[targetSection] = value;
205
219
  }
206
220
  catch {
207
- typed[section] = entries;
221
+ /* malformed section skip */
208
222
  }
209
223
  }
210
224
  return typed;
@@ -275,9 +289,6 @@ function mergePreferences(base, override) {
275
289
  service_tier: override.service_tier ?? base.service_tier,
276
290
  forensics_dedup: override.forensics_dedup ?? base.forensics_dedup,
277
291
  show_token_cost: override.show_token_cost ?? base.show_token_cost,
278
- experimental: (base.experimental || override.experimental)
279
- ? { ...(base.experimental ?? {}), ...(override.experimental ?? {}) }
280
- : undefined,
281
292
  };
282
293
  }
283
294
  function mergeStringLists(base, override) {
@@ -398,7 +409,7 @@ export function resolvePreDispatchHooks() {
398
409
  * Resolve the effective git isolation mode from preferences.
399
410
  * Returns "none" (default), "worktree", or "branch".
400
411
  *
401
- * Default is "none" so GSD works out of the box without PREFERENCES.md.
412
+ * Default is "none" so GSD works out of the box without preferences.md.
402
413
  * Worktree isolation requires explicit opt-in because it depends on git
403
414
  * branch infrastructure that must be set up before use.
404
415
  */