gsd-pi 2.78.0 → 2.78.1-dev.82bcf6b71

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 (577) hide show
  1. package/README.md +60 -23
  2. package/dist/bundled-resource-path.d.ts +7 -0
  3. package/dist/bundled-resource-path.js +34 -2
  4. package/dist/claude-cli-check.js +104 -33
  5. package/dist/cli-policy.d.ts +13 -0
  6. package/dist/cli-policy.js +17 -0
  7. package/dist/cli.js +95 -55
  8. package/dist/headless-query.d.ts +22 -0
  9. package/dist/headless-query.js +43 -8
  10. package/dist/headless.d.ts +10 -0
  11. package/dist/headless.js +16 -1
  12. package/dist/loader.js +9 -13
  13. package/dist/onboarding.d.ts +10 -0
  14. package/dist/onboarding.js +2 -2
  15. package/dist/provider-migrations.d.ts +2 -2
  16. package/dist/provider-migrations.js +5 -2
  17. package/dist/resource-loader.d.ts +5 -2
  18. package/dist/resource-loader.js +30 -13
  19. package/dist/resources/.managed-resources-content-hash +1 -0
  20. package/dist/resources/extensions/claude-code-cli/readiness.js +128 -32
  21. package/dist/resources/extensions/google-search/index.js +2 -6
  22. package/dist/resources/extensions/gsd/auto/loop.js +23 -0
  23. package/dist/resources/extensions/gsd/auto/phases.js +5 -13
  24. package/dist/resources/extensions/gsd/auto/run-unit.js +26 -12
  25. package/dist/resources/extensions/gsd/auto/session.js +5 -6
  26. package/dist/resources/extensions/gsd/auto-dashboard.js +3 -2
  27. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +55 -21
  28. package/dist/resources/extensions/gsd/auto-dispatch.js +18 -6
  29. package/dist/resources/extensions/gsd/auto-prompts.js +69 -2
  30. package/dist/resources/extensions/gsd/auto-recovery.js +43 -4
  31. package/dist/resources/extensions/gsd/auto-runtime-state.js +31 -0
  32. package/dist/resources/extensions/gsd/auto-start.js +1 -1
  33. package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -2
  34. package/dist/resources/extensions/gsd/auto-worktree.js +75 -13
  35. package/dist/resources/extensions/gsd/auto.js +39 -14
  36. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +14 -2
  37. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -5
  38. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
  39. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +5 -4
  40. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +112 -31
  41. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +11 -6
  42. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +22 -0
  43. package/dist/resources/extensions/gsd/bootstrap/system-context.js +45 -8
  44. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +121 -3
  45. package/dist/resources/extensions/gsd/commands/catalog.js +76 -5
  46. package/dist/resources/extensions/gsd/commands/handlers/core.js +23 -1
  47. package/dist/resources/extensions/gsd/commands/handlers/ops.js +8 -0
  48. package/dist/resources/extensions/gsd/commands-config.js +3 -2
  49. package/dist/resources/extensions/gsd/commands-extensions.js +46 -3
  50. package/dist/resources/extensions/gsd/commands-handlers.js +3 -2
  51. package/dist/resources/extensions/gsd/commands-mcp-status.js +3 -1
  52. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +10 -1
  53. package/dist/resources/extensions/gsd/commands-worktree.js +309 -0
  54. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  55. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  56. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  57. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +39 -1
  58. package/dist/resources/extensions/gsd/error-classifier.js +1 -1
  59. package/dist/resources/extensions/gsd/forensics.js +10 -8
  60. package/dist/resources/extensions/gsd/git-service.js +12 -5
  61. package/dist/resources/extensions/gsd/gsd-db.js +11 -2
  62. package/dist/resources/extensions/gsd/guided-flow.js +25 -24
  63. package/dist/resources/extensions/gsd/home-dir.js +16 -0
  64. package/dist/resources/extensions/gsd/key-manager.js +2 -1
  65. package/dist/resources/extensions/gsd/memory-store.js +66 -31
  66. package/dist/resources/extensions/gsd/migrate/command.js +3 -2
  67. package/dist/resources/extensions/gsd/milestone-id-reservation.js +36 -0
  68. package/dist/resources/extensions/gsd/model-router.js +114 -9
  69. package/dist/resources/extensions/gsd/native-git-bridge.js +7 -1
  70. package/dist/resources/extensions/gsd/preferences-models.js +91 -15
  71. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  72. package/dist/resources/extensions/gsd/preferences-validation.js +32 -0
  73. package/dist/resources/extensions/gsd/preferences.js +5 -3
  74. package/dist/resources/extensions/gsd/prompt-loader.js +23 -12
  75. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  76. package/dist/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  77. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  78. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +2 -0
  79. package/dist/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  80. package/dist/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  81. package/dist/resources/extensions/gsd/prompts/rewrite-docs.md +2 -0
  82. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +9 -3
  83. package/dist/resources/extensions/gsd/state.js +42 -0
  84. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  85. package/dist/resources/extensions/gsd/tools/memory-tools.js +18 -1
  86. package/dist/resources/extensions/gsd/unit-context-manifest.js +29 -4
  87. package/dist/resources/extensions/gsd/visualizer-overlay.js +1 -1
  88. package/dist/resources/extensions/gsd/watch/header-renderer.js +3 -1
  89. package/dist/resources/extensions/gsd/worktree-command.js +26 -46
  90. package/dist/resources/extensions/gsd/worktree-manager.js +20 -1
  91. package/dist/resources/extensions/gsd/worktree-resolver.js +28 -13
  92. package/dist/resources/extensions/gsd/worktree-root.js +124 -0
  93. package/dist/resources/extensions/gsd/worktree-session-state.js +33 -0
  94. package/dist/resources/extensions/gsd/worktree.js +4 -115
  95. package/dist/resources/extensions/mcp-client/index.js +6 -9
  96. package/dist/resources/extensions/ollama/index.js +15 -2
  97. package/dist/resources/extensions/ollama/model-capabilities.js +31 -0
  98. package/dist/resources/extensions/ollama/ollama-client.js +40 -4
  99. package/dist/resources/extensions/slash-commands/create-extension.js +36 -22
  100. package/dist/resources/extensions/subagent/index.js +324 -178
  101. package/dist/resources/skills/create-gsd-extension/SKILL.md +9 -5
  102. package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  103. package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  104. package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  105. package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  106. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  107. package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  108. package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  109. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  110. package/dist/resources/skills/lint/SKILL.md +4 -0
  111. package/dist/resources/skills/review/SKILL.md +4 -0
  112. package/dist/resources/skills/test/SKILL.md +3 -0
  113. package/dist/rtk-shared.d.ts +3 -0
  114. package/dist/rtk-shared.js +17 -0
  115. package/dist/rtk.d.ts +2 -5
  116. package/dist/rtk.js +3 -20
  117. package/dist/runtime-checks.d.ts +27 -0
  118. package/dist/runtime-checks.js +38 -0
  119. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  120. package/dist/web/standalone/.next/BUILD_ID +1 -1
  121. package/dist/web/standalone/.next/app-path-routes-manifest.json +19 -19
  122. package/dist/web/standalone/.next/build-manifest.json +4 -4
  123. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  124. package/dist/web/standalone/.next/react-loadable-manifest.json +44 -4
  125. package/dist/web/standalone/.next/required-server-files.json +3 -3
  126. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  127. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  137. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  143. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  145. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  153. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  165. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  185. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  195. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/session/events/route.js +4 -2
  201. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  203. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  205. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  211. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  213. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  215. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  217. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  219. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  221. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  223. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  224. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  225. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  226. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  227. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  229. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  230. package/dist/web/standalone/.next/server/app/index.html +1 -1
  231. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  232. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  233. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  234. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  235. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  236. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  237. package/dist/web/standalone/.next/server/app/page.js +2 -2
  238. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  239. package/dist/web/standalone/.next/server/app-paths-manifest.json +19 -19
  240. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  241. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  242. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  243. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  244. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  245. package/dist/web/standalone/.next/server/middleware.js +2 -2
  246. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  247. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  248. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  249. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  250. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  251. package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
  252. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +1 -0
  253. package/dist/web/standalone/.next/static/chunks/2824.08296bc2f9654698.js +1 -0
  254. package/dist/web/standalone/.next/static/chunks/3026.3af53b279375f082.js +1 -0
  255. package/dist/web/standalone/.next/static/chunks/315.6f68ae79b67d25cf.js +1 -0
  256. package/dist/web/standalone/.next/static/chunks/3497.4bfc60a3b3dea717.js +1 -0
  257. package/dist/web/standalone/.next/static/chunks/5516.4a07c872b5c3a663.js +1 -0
  258. package/dist/web/standalone/.next/static/chunks/8336.31b019697882acfb.js +10 -0
  259. package/dist/web/standalone/.next/static/chunks/8845.c9702695e8c5a9c5.js +2 -0
  260. package/dist/web/standalone/.next/static/chunks/9058.01ef3a463bda88f1.js +20 -0
  261. package/dist/web/standalone/.next/static/chunks/9441.1081da1125d1764f.js +1 -0
  262. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  263. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  264. package/dist/web/standalone/.next/static/chunks/app/page-9bf2e0c50fb2ca05.js +1 -0
  265. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  266. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  267. package/dist/web/standalone/.next/static/chunks/webpack-f9f0dc45e4f3ac10.js +1 -0
  268. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  269. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  270. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  271. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  272. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  273. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  274. package/dist/web/standalone/package.json +2 -1
  275. package/dist/web/standalone/server.js +1 -1
  276. package/dist/welcome-screen.js +27 -1
  277. package/dist/worktree-cli.d.ts +1 -0
  278. package/dist/worktree-cli.js +9 -3
  279. package/dist/worktree-status-banner.d.ts +1 -0
  280. package/dist/worktree-status-banner.js +132 -0
  281. package/package.json +1 -3
  282. package/packages/daemon/package.json +2 -2
  283. package/packages/mcp-server/dist/alias-telemetry.d.ts +8 -0
  284. package/packages/mcp-server/dist/alias-telemetry.d.ts.map +1 -0
  285. package/packages/mcp-server/dist/alias-telemetry.js +30 -0
  286. package/packages/mcp-server/dist/alias-telemetry.js.map +1 -0
  287. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  288. package/packages/mcp-server/dist/workflow-tools.js +74 -46
  289. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  290. package/packages/mcp-server/package.json +2 -2
  291. package/packages/mcp-server/src/alias-telemetry.test.ts +78 -0
  292. package/packages/mcp-server/src/alias-telemetry.ts +30 -0
  293. package/packages/mcp-server/src/workflow-tools.test.ts +78 -0
  294. package/packages/mcp-server/src/workflow-tools.ts +93 -58
  295. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  296. package/packages/native/package.json +1 -1
  297. package/packages/native/tsconfig.tsbuildinfo +1 -1
  298. package/packages/pi-agent-core/package.json +1 -1
  299. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  300. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts +2 -0
  301. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.d.ts.map +1 -0
  302. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js +231 -0
  303. package/packages/pi-ai/dist/providers/anthropic-shared.cache-breakpoint.test.js.map +1 -0
  304. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  305. package/packages/pi-ai/dist/providers/anthropic-shared.js +48 -19
  306. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  307. package/packages/pi-ai/dist/types.d.ts +13 -0
  308. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  309. package/packages/pi-ai/dist/types.js.map +1 -1
  310. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -1
  311. package/packages/pi-ai/dist/utils/repair-tool-json.js +24 -3
  312. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -1
  313. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +26 -0
  314. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -1
  315. package/packages/pi-ai/package.json +1 -1
  316. package/packages/pi-ai/src/providers/anthropic-shared.cache-breakpoint.test.ts +289 -0
  317. package/packages/pi-ai/src/providers/anthropic-shared.ts +52 -20
  318. package/packages/pi-ai/src/types.ts +13 -0
  319. package/packages/pi-ai/src/utils/repair-tool-json.ts +24 -3
  320. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +32 -0
  321. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  322. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  323. package/packages/pi-coding-agent/dist/core/agent-session.js +6 -0
  324. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  325. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  326. package/packages/pi-coding-agent/dist/core/messages.js +4 -0
  327. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  328. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +19 -2
  329. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  330. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +10 -0
  331. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  332. package/packages/pi-coding-agent/dist/core/model-registry.js +18 -0
  333. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  334. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +13 -0
  335. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  336. package/packages/pi-coding-agent/dist/core/system-prompt.js +20 -16
  337. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  338. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts +37 -0
  339. package/packages/pi-coding-agent/dist/core/token-telemetry.d.ts.map +1 -0
  340. package/packages/pi-coding-agent/dist/core/token-telemetry.js +49 -0
  341. package/packages/pi-coding-agent/dist/core/token-telemetry.js.map +1 -0
  342. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts +2 -0
  343. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.d.ts.map +1 -0
  344. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +133 -0
  345. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -0
  346. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +1 -1
  347. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  348. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -1
  349. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  350. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts +2 -0
  351. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.d.ts.map +1 -0
  352. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js +78 -0
  353. package/packages/pi-coding-agent/dist/tests/system-prompt-cache-stability.test.js.map +1 -0
  354. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts +2 -0
  355. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.d.ts.map +1 -0
  356. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js +181 -0
  357. package/packages/pi-coding-agent/dist/tests/token-telemetry.test.js.map +1 -0
  358. package/packages/pi-coding-agent/package.json +1 -1
  359. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -0
  360. package/packages/pi-coding-agent/src/core/messages.ts +4 -0
  361. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +32 -2
  362. package/packages/pi-coding-agent/src/core/model-registry.ts +21 -0
  363. package/packages/pi-coding-agent/src/core/system-prompt.ts +33 -15
  364. package/packages/pi-coding-agent/src/core/token-telemetry.ts +77 -0
  365. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +212 -0
  366. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +17 -1
  367. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +1 -1
  368. package/packages/pi-coding-agent/src/tests/system-prompt-cache-stability.test.ts +102 -0
  369. package/packages/pi-coding-agent/src/tests/token-telemetry.test.ts +200 -0
  370. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  371. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +17 -3
  372. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  373. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts +2 -0
  374. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.d.ts.map +1 -0
  375. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js +161 -0
  376. package/packages/pi-tui/dist/components/__tests__/leak-fixes-runtime.test.js.map +1 -0
  377. package/packages/pi-tui/package.json +1 -1
  378. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -3
  379. package/packages/pi-tui/src/components/__tests__/leak-fixes-runtime.test.ts +219 -0
  380. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  381. package/packages/rpc-client/package.json +1 -1
  382. package/pkg/package.json +1 -1
  383. package/src/resources/extensions/claude-code-cli/readiness.ts +130 -30
  384. package/src/resources/extensions/google-search/index.ts +2 -9
  385. package/src/resources/extensions/gsd/auto/loop.ts +24 -2
  386. package/src/resources/extensions/gsd/auto/phases.ts +6 -14
  387. package/src/resources/extensions/gsd/auto/run-unit.ts +26 -12
  388. package/src/resources/extensions/gsd/auto/session.ts +5 -6
  389. package/src/resources/extensions/gsd/auto/types.ts +1 -0
  390. package/src/resources/extensions/gsd/auto-dashboard.ts +3 -2
  391. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +60 -24
  392. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -6
  393. package/src/resources/extensions/gsd/auto-prompts.ts +66 -2
  394. package/src/resources/extensions/gsd/auto-recovery.ts +46 -8
  395. package/src/resources/extensions/gsd/auto-runtime-state.ts +51 -0
  396. package/src/resources/extensions/gsd/auto-start.ts +1 -1
  397. package/src/resources/extensions/gsd/auto-tool-tracking.ts +2 -4
  398. package/src/resources/extensions/gsd/auto-worktree.ts +97 -12
  399. package/src/resources/extensions/gsd/auto.ts +37 -10
  400. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +15 -13
  401. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +8 -7
  402. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
  403. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +10 -9
  404. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +121 -31
  405. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +12 -6
  406. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +20 -0
  407. package/src/resources/extensions/gsd/bootstrap/system-context.ts +50 -8
  408. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +141 -11
  409. package/src/resources/extensions/gsd/commands/catalog.ts +82 -5
  410. package/src/resources/extensions/gsd/commands/handlers/core.ts +23 -1
  411. package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
  412. package/src/resources/extensions/gsd/commands-config.ts +3 -2
  413. package/src/resources/extensions/gsd/commands-extensions.ts +43 -3
  414. package/src/resources/extensions/gsd/commands-handlers.ts +3 -2
  415. package/src/resources/extensions/gsd/commands-mcp-status.ts +3 -1
  416. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +15 -1
  417. package/src/resources/extensions/gsd/commands-worktree.ts +383 -0
  418. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  419. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  420. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  421. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +39 -1
  422. package/src/resources/extensions/gsd/doctor-types.ts +3 -1
  423. package/src/resources/extensions/gsd/error-classifier.ts +1 -1
  424. package/src/resources/extensions/gsd/forensics.ts +12 -7
  425. package/src/resources/extensions/gsd/git-service.ts +13 -5
  426. package/src/resources/extensions/gsd/gsd-db.ts +12 -2
  427. package/src/resources/extensions/gsd/guided-flow.ts +27 -26
  428. package/src/resources/extensions/gsd/home-dir.ts +19 -0
  429. package/src/resources/extensions/gsd/journal.ts +4 -1
  430. package/src/resources/extensions/gsd/key-manager.ts +2 -1
  431. package/src/resources/extensions/gsd/memory-store.ts +81 -28
  432. package/src/resources/extensions/gsd/migrate/command.ts +3 -2
  433. package/src/resources/extensions/gsd/milestone-id-reservation.ts +47 -0
  434. package/src/resources/extensions/gsd/model-router.ts +172 -9
  435. package/src/resources/extensions/gsd/native-git-bridge.ts +7 -1
  436. package/src/resources/extensions/gsd/preferences-models.ts +101 -15
  437. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  438. package/src/resources/extensions/gsd/preferences-validation.ts +35 -0
  439. package/src/resources/extensions/gsd/preferences.ts +16 -2
  440. package/src/resources/extensions/gsd/prompt-loader.ts +26 -12
  441. package/src/resources/extensions/gsd/prompts/complete-milestone.md +10 -0
  442. package/src/resources/extensions/gsd/prompts/complete-slice.md +10 -0
  443. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  444. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +2 -0
  445. package/src/resources/extensions/gsd/prompts/plan-slice.md +10 -0
  446. package/src/resources/extensions/gsd/prompts/refine-slice.md +10 -0
  447. package/src/resources/extensions/gsd/prompts/rewrite-docs.md +2 -0
  448. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +9 -3
  449. package/src/resources/extensions/gsd/state.ts +42 -0
  450. package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -0
  451. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +179 -1
  452. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +58 -0
  453. package/src/resources/extensions/gsd/tests/auto-session-encapsulation.test.ts +24 -5
  454. package/src/resources/extensions/gsd/tests/auto-supervisor.test.mjs +21 -4
  455. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +1 -1
  456. package/src/resources/extensions/gsd/tests/budget-prediction.test.ts +138 -211
  457. package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +50 -27
  458. package/src/resources/extensions/gsd/tests/commands-extensions-version-compare.test.ts +58 -0
  459. package/src/resources/extensions/gsd/tests/commands-worktree-clean.test.ts +48 -0
  460. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +142 -59
  461. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +7 -4
  462. package/src/resources/extensions/gsd/tests/completed-at-reconcile.test.ts +89 -32
  463. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +41 -23
  464. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +3 -43
  465. package/src/resources/extensions/gsd/tests/debug-logger.test.ts +5 -3
  466. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +116 -0
  467. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +22 -87
  468. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +7 -118
  469. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +18 -60
  470. package/src/resources/extensions/gsd/tests/doctor-orphan-milestone-4996.test.ts +100 -0
  471. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +14 -76
  472. package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +93 -0
  473. package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +22 -83
  474. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +1 -63
  475. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed-runtime.test.ts +47 -0
  476. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +26 -1
  477. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +63 -0
  478. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +25 -65
  479. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +30 -0
  480. package/src/resources/extensions/gsd/tests/gsd-no-project-error-runtime.test.ts +81 -0
  481. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +14 -4
  482. package/src/resources/extensions/gsd/tests/health-widget.test.ts +22 -12
  483. package/src/resources/extensions/gsd/tests/help-menu-coverage.test.ts +57 -0
  484. package/src/resources/extensions/gsd/tests/home-dir.test.ts +52 -0
  485. package/src/resources/extensions/gsd/tests/import-done-milestones-runtime.test.ts +145 -0
  486. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +64 -1
  487. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +72 -1
  488. package/src/resources/extensions/gsd/tests/integration/token-savings.test.ts +0 -23
  489. package/src/resources/extensions/gsd/tests/memory-store.test.ts +128 -0
  490. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +33 -1
  491. package/src/resources/extensions/gsd/tests/merge-self-branch-guard.test.ts +124 -0
  492. package/src/resources/extensions/gsd/tests/milestone-id-gap-reuse-4996.test.ts +152 -0
  493. package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +18 -1
  494. package/src/resources/extensions/gsd/tests/model-router.test.ts +169 -8
  495. package/src/resources/extensions/gsd/tests/native-git-infra-errors.test.ts +50 -0
  496. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +8 -0
  497. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +32 -43
  498. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +4 -10
  499. package/src/resources/extensions/gsd/tests/preferences.test.ts +127 -0
  500. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +16 -0
  501. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +7 -0
  502. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +6 -6
  503. package/src/resources/extensions/gsd/tests/register-hooks-compaction-checkpoint.test.ts +93 -0
  504. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +34 -0
  505. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +168 -19
  506. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +7 -1
  507. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +23 -1
  508. package/src/resources/extensions/gsd/tests/stash-pop-gsd-conflict.test.ts +8 -2
  509. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +12 -6
  510. package/src/resources/extensions/gsd/tests/steer-worktree-path.test.ts +17 -1
  511. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +101 -0
  512. package/src/resources/extensions/gsd/tests/token-profile.test.ts +51 -4
  513. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +7 -16
  514. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +38 -3
  515. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -7
  516. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +15 -1
  517. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -6
  518. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +235 -0
  519. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +85 -0
  520. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +34 -33
  521. package/src/resources/extensions/gsd/tests/worktree.test.ts +8 -0
  522. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +131 -1
  523. package/src/resources/extensions/gsd/tools/memory-tools.ts +17 -1
  524. package/src/resources/extensions/gsd/unit-context-manifest.ts +44 -12
  525. package/src/resources/extensions/gsd/visualizer-overlay.ts +1 -1
  526. package/src/resources/extensions/gsd/watch/header-renderer.ts +3 -1
  527. package/src/resources/extensions/gsd/workflow-logger.ts +1 -0
  528. package/src/resources/extensions/gsd/worktree-command.ts +31 -44
  529. package/src/resources/extensions/gsd/worktree-manager.ts +40 -1
  530. package/src/resources/extensions/gsd/worktree-resolver.ts +28 -14
  531. package/src/resources/extensions/gsd/worktree-root.ts +144 -0
  532. package/src/resources/extensions/gsd/worktree-session-state.ts +35 -0
  533. package/src/resources/extensions/gsd/worktree.ts +8 -119
  534. package/src/resources/extensions/mcp-client/index.ts +6 -10
  535. package/src/resources/extensions/mcp-client/tests/global-config.test.ts +91 -0
  536. package/src/resources/extensions/ollama/index.ts +16 -2
  537. package/src/resources/extensions/ollama/model-capabilities.ts +34 -0
  538. package/src/resources/extensions/ollama/ollama-client.ts +41 -4
  539. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +96 -0
  540. package/src/resources/extensions/ollama/tests/ollama-client-timeout-env.test.ts +147 -0
  541. package/src/resources/extensions/slash-commands/create-extension.ts +38 -24
  542. package/src/resources/extensions/subagent/index.ts +165 -7
  543. package/src/resources/skills/create-gsd-extension/SKILL.md +9 -5
  544. package/src/resources/skills/create-gsd-extension/references/custom-commands.md +1 -1
  545. package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +5 -5
  546. package/src/resources/skills/create-gsd-extension/references/custom-tools.md +4 -4
  547. package/src/resources/skills/create-gsd-extension/references/custom-ui.md +6 -6
  548. package/src/resources/skills/create-gsd-extension/references/events-reference.md +3 -3
  549. package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +1 -1
  550. package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +3 -3
  551. package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +2 -2
  552. package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +3 -3
  553. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +58 -0
  554. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +32 -12
  555. package/src/resources/skills/lint/SKILL.md +4 -0
  556. package/src/resources/skills/review/SKILL.md +4 -0
  557. package/src/resources/skills/test/SKILL.md +3 -0
  558. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +0 -601
  559. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +0 -651
  560. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +0 -91
  561. package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +0 -53
  562. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +0 -112
  563. package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +0 -23
  564. package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +0 -5
  565. package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
  566. package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +0 -608
  567. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +0 -11
  568. package/dist/web/standalone/.next/static/chunks/3621.fc7480022c972438.js +0 -20
  569. package/dist/web/standalone/.next/static/chunks/app/page-151349214571e2b6.js +0 -1
  570. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  571. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  572. package/dist/web/standalone/.next/static/chunks/webpack-2e68521d7c82f7c2.js +0 -1
  573. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +0 -22
  574. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +0 -47
  575. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +0 -75
  576. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → hcvW7f3yv1JHzlWe7tIc6}/_buildManifest.js +0 -0
  577. /package/dist/web/standalone/.next/static/{C1zT2kEfoLhDdbWPWKrXd → hcvW7f3yv1JHzlWe7tIc6}/_ssgManifest.js +0 -0
@@ -18,6 +18,7 @@ import { clearLock } from "./crash-recovery.js";
18
18
  import { assessInterruptedSession, formatInterruptedSessionRunningMessage, formatInterruptedSessionSummary, } from "./interrupted-session.js";
19
19
  import { listUnitRuntimeRecords, clearUnitRuntimeRecord } from "./unit-runtime.js";
20
20
  import { resolveExpectedArtifactPath } from "./auto.js";
21
+ import { getHomeDir } from "./home-dir.js";
21
22
  import { gsdRoot, milestonesDir, resolveMilestoneFile, resolveSliceFile, resolveSlicePath, resolveGsdRootFile, relGsdRootFile, relMilestoneFile, relSliceFile, } from "./paths.js";
22
23
  import { join } from "node:path";
23
24
  import { readFileSync, existsSync, mkdirSync, readdirSync, unlinkSync } from "node:fs";
@@ -33,7 +34,9 @@ import { showProjectInit, offerMigration } from "./init-wizard.js";
33
34
  import { validateDirectory } from "./validate-directory.js";
34
35
  import { showConfirm } from "../shared/tui.js";
35
36
  import { debugLog } from "./debug-logger.js";
36
- import { findMilestoneIds, nextMilestoneId, reserveMilestoneId, getReservedMilestoneIds, clearReservedMilestoneIds } from "./milestone-ids.js";
37
+ import { findMilestoneIds, clearReservedMilestoneIds } from "./milestone-ids.js";
38
+ import { nextMilestoneIdReserved } from "./milestone-id-reservation.js";
39
+ export { nextMilestoneIdReserved } from "./milestone-id-reservation.js";
37
40
  import { parkMilestone, discardMilestone } from "./milestone-actions.js";
38
41
  import { selectAndApplyModel } from "./auto-model-selection.js";
39
42
  import { DISCUSS_TOOLS_ALLOWLIST } from "./constants.js";
@@ -43,18 +46,6 @@ import { runPreparation, formatCodebaseBrief, formatPriorContextBrief, } from ".
43
46
  export { MILESTONE_ID_RE, generateMilestoneSuffix, nextMilestoneId, extractMilestoneSeq, parseMilestoneId, milestoneIdSort, maxMilestoneNum, findMilestoneIds, reserveMilestoneId, claimReservedId, getReservedMilestoneIds, clearReservedMilestoneIds, } from "./milestone-ids.js";
44
47
  export { showQueue, handleQueueReorder, showQueueAdd, buildExistingMilestonesContext, } from "./guided-flow-queue.js";
45
48
  import { logWarning } from "./workflow-logger.js";
46
- // ─── ID Generation with Reservation ─────────────────────────────────────────
47
- /**
48
- * Generate the next milestone ID, accounting for reserved IDs, and reserve it.
49
- * Ensures any preview ID shown in the UI matches what `gsd_milestone_generate_id`
50
- * will later return.
51
- */
52
- function nextMilestoneIdReserved(existingIds, uniqueEnabled) {
53
- const allIds = [...new Set([...existingIds, ...getReservedMilestoneIds()])];
54
- const id = nextMilestoneId(allIds, uniqueEnabled);
55
- reserveMilestoneId(id);
56
- return id;
57
- }
58
49
  function needsPlanV2Gate(state) {
59
50
  return state.phase === "executing"
60
51
  || state.phase === "summarizing"
@@ -505,7 +496,7 @@ async function dispatchWorkflow(pi, note, customType = "gsd-run", ctx, unitType)
505
496
  removed: currentTools.length - scopedTools.length,
506
497
  });
507
498
  }
508
- const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(process.env.HOME ?? "~", ".gsd", "agent", "GSD-WORKFLOW.md");
499
+ const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(getHomeDir(), ".gsd", "agent", "GSD-WORKFLOW.md");
509
500
  const workflow = readFileSync(workflowPath, "utf-8");
510
501
  pi.sendMessage({
511
502
  customType,
@@ -675,13 +666,17 @@ export async function showHeadlessMilestoneCreation(ctx, pi, basePath, seedConte
675
666
  clearReservedMilestoneIds();
676
667
  // Ensure .gsd/ is bootstrapped
677
668
  bootstrapGsdProject(basePath);
669
+ const { ensureDbOpen } = await import("./bootstrap/dynamic-tools.js");
670
+ await ensureDbOpen(basePath);
678
671
  // Generate next milestone ID
679
672
  const existingIds = findMilestoneIds(basePath);
680
673
  const prefs = loadEffectiveGSDPreferences();
681
- const nextId = nextMilestoneIdReserved(existingIds, prefs?.preferences?.unique_milestone_ids ?? false);
682
- // Create milestone directory
683
- const milestoneDir = join(gsdRoot(basePath), "milestones", nextId, "slices");
684
- mkdirSync(milestoneDir, { recursive: true });
674
+ const nextId = nextMilestoneIdReserved(existingIds, prefs?.preferences?.unique_milestone_ids ?? false, basePath);
675
+ // Fix #4996: Do NOT pre-create the milestone directory here.
676
+ // atomicWriteAsync (used by all artifact writers) calls mkdir lazily before
677
+ // each write, so every path through saveArtifactToDb / saveFile is already
678
+ // lazy-mkdir-safe. Pre-creating the dir before the discuss flow runs leaves
679
+ // an orphan stub if discuss is abandoned — that stub later skews nextMilestoneId.
685
680
  // Build and dispatch the headless discuss prompt
686
681
  const prompt = buildHeadlessDiscussPrompt(nextId, seedContext, basePath);
687
682
  // Set pending auto start (auto-mode triggers on "Milestone X ready." via checkAutoStartAfterDiscuss)
@@ -865,9 +860,11 @@ export async function showDiscuss(ctx, pi, basePath) {
865
860
  }), "gsd-discuss", ctx, "discuss-milestone");
866
861
  }
867
862
  else if (choice === "skip_milestone") {
863
+ const { ensureDbOpen } = await import("./bootstrap/dynamic-tools.js");
864
+ await ensureDbOpen(basePath);
868
865
  const milestoneIds = findMilestoneIds(basePath);
869
866
  const uniqueMilestoneIds = !!loadEffectiveGSDPreferences()?.preferences?.unique_milestone_ids;
870
- const nextId = nextMilestoneIdReserved(milestoneIds, uniqueMilestoneIds);
867
+ const nextId = nextMilestoneIdReserved(milestoneIds, uniqueMilestoneIds, basePath);
871
868
  pendingAutoStartMap.set(basePath, { ctx, pi, basePath, milestoneId: nextId, step: false, createdAt: Date.now() });
872
869
  await dispatchWorkflow(pi, await prepareAndBuildDiscussPrompt(ctx, pi, nextId, `New milestone ${nextId}.`, basePath), "gsd-run", ctx, "discuss-milestone");
873
870
  }
@@ -1223,7 +1220,7 @@ async function handleMilestoneActions(ctx, pi, basePath, milestoneId, milestoneT
1223
1220
  if (choice === "skip") {
1224
1221
  const milestoneIds = findMilestoneIds(basePath);
1225
1222
  const uniqueMilestoneIds = !!loadEffectiveGSDPreferences()?.preferences?.unique_milestone_ids;
1226
- const nextId = nextMilestoneIdReserved(milestoneIds, uniqueMilestoneIds);
1223
+ const nextId = nextMilestoneIdReserved(milestoneIds, uniqueMilestoneIds, basePath);
1227
1224
  pendingAutoStartMap.set(basePath, { ctx, pi, basePath, milestoneId: nextId, step: stepMode, createdAt: Date.now() });
1228
1225
  await dispatchWorkflow(pi, await prepareAndBuildDiscussPrompt(ctx, pi, nextId, `New milestone ${nextId}.`, basePath), "gsd-run", ctx, "discuss-milestone");
1229
1226
  return true;
@@ -1291,6 +1288,10 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
1291
1288
  // ── Ensure .gitignore has baseline patterns ──────────────────────────
1292
1289
  ensureGitignore(basePath);
1293
1290
  untrackRuntimeFiles(basePath);
1291
+ {
1292
+ const { ensureDbOpen } = await import("./bootstrap/dynamic-tools.js");
1293
+ await ensureDbOpen(basePath);
1294
+ }
1294
1295
  // ── Self-heal stale runtime records from crashed auto-mode sessions ──
1295
1296
  selfHealRuntimeRecords(basePath, ctx);
1296
1297
  const interrupted = await assessInterruptedSession(basePath);
@@ -1388,7 +1389,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
1388
1389
  }
1389
1390
  }
1390
1391
  const uniqueMilestoneIds = !!loadEffectiveGSDPreferences()?.preferences?.unique_milestone_ids;
1391
- const nextId = nextMilestoneIdReserved(milestoneIds, uniqueMilestoneIds);
1392
+ const nextId = nextMilestoneIdReserved(milestoneIds, uniqueMilestoneIds, basePath);
1392
1393
  const isFirst = milestoneIds.length === 0;
1393
1394
  if (isFirst) {
1394
1395
  // First ever — skip wizard, just ask directly
@@ -1446,7 +1447,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
1446
1447
  if (choice === "new_milestone") {
1447
1448
  const milestoneIds = findMilestoneIds(basePath);
1448
1449
  const uniqueMilestoneIds = !!loadEffectiveGSDPreferences()?.preferences?.unique_milestone_ids;
1449
- const nextId = nextMilestoneIdReserved(milestoneIds, uniqueMilestoneIds);
1450
+ const nextId = nextMilestoneIdReserved(milestoneIds, uniqueMilestoneIds, basePath);
1450
1451
  pendingAutoStartMap.set(basePath, { ctx, pi, basePath, milestoneId: nextId, step: stepMode, createdAt: Date.now() });
1451
1452
  await dispatchWorkflow(pi, await prepareAndBuildDiscussPrompt(ctx, pi, nextId, `New milestone ${nextId}.`, basePath), "gsd-run", ctx, "discuss-milestone");
1452
1453
  }
@@ -1510,7 +1511,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
1510
1511
  else if (choice === "skip_milestone") {
1511
1512
  const milestoneIds = findMilestoneIds(basePath);
1512
1513
  const uniqueMilestoneIds = !!loadEffectiveGSDPreferences()?.preferences?.unique_milestone_ids;
1513
- const nextId = nextMilestoneIdReserved(milestoneIds, uniqueMilestoneIds);
1514
+ const nextId = nextMilestoneIdReserved(milestoneIds, uniqueMilestoneIds, basePath);
1514
1515
  pendingAutoStartMap.set(basePath, { ctx, pi, basePath, milestoneId: nextId, step: stepMode, createdAt: Date.now() });
1515
1516
  await dispatchWorkflow(pi, await prepareAndBuildDiscussPrompt(ctx, pi, nextId, `New milestone ${nextId}.`, basePath), "gsd-run", ctx, "discuss-milestone");
1516
1517
  }
@@ -1600,7 +1601,7 @@ export async function showSmartEntry(ctx, pi, basePath, options) {
1600
1601
  else if (choice === "skip_milestone") {
1601
1602
  const milestoneIds = findMilestoneIds(basePath);
1602
1603
  const uniqueMilestoneIds = !!loadEffectiveGSDPreferences()?.preferences?.unique_milestone_ids;
1603
- const nextId = nextMilestoneIdReserved(milestoneIds, uniqueMilestoneIds);
1604
+ const nextId = nextMilestoneIdReserved(milestoneIds, uniqueMilestoneIds, basePath);
1604
1605
  pendingAutoStartMap.set(basePath, { ctx, pi, basePath, milestoneId: nextId, step: stepMode, createdAt: Date.now() });
1605
1606
  await dispatchWorkflow(pi, await prepareAndBuildDiscussPrompt(ctx, pi, nextId, `New milestone ${nextId}.`, basePath), "gsd-run", ctx, "discuss-milestone");
1606
1607
  }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Cross-platform home directory resolution.
3
+ *
4
+ * `process.env.HOME` is not set on Windows (CMD/PowerShell).
5
+ * Falls back to USERPROFILE, then os.homedir(), then throws.
6
+ *
7
+ * @see https://github.com/gsd-build/gsd-2/issues/5015
8
+ */
9
+ import { homedir } from "node:os";
10
+ export function getHomeDir() {
11
+ const home = process.env.HOME || process.env.USERPROFILE || homedir();
12
+ if (!home) {
13
+ throw new Error("Cannot resolve home directory. Set HOME or USERPROFILE environment variable.");
14
+ }
15
+ return home;
16
+ }
@@ -9,6 +9,7 @@ import { existsSync, statSync, chmodSync } from "node:fs";
9
9
  import { join, dirname } from "node:path";
10
10
  import { mkdirSync } from "node:fs";
11
11
  import { getErrorMessage } from "./error-utils.js";
12
+ import { getHomeDir } from "./home-dir.js";
12
13
  export const PROVIDER_REGISTRY = [
13
14
  // LLM Providers
14
15
  { id: "anthropic", label: "Anthropic (Claude)", category: "llm", envVar: "ANTHROPIC_API_KEY", prefixes: ["sk-ant-"], hasOAuth: true, dashboardUrl: "console.anthropic.com" },
@@ -98,7 +99,7 @@ export function describeCredential(cred) {
98
99
  * Get the auth.json path.
99
100
  */
100
101
  export function getAuthPath() {
101
- return join(process.env.HOME ?? "~", ".gsd", "agent", "auth.json");
102
+ return join(getHomeDir(), ".gsd", "agent", "auth.json");
102
103
  }
103
104
  /**
104
105
  * Create an AuthStorage instance for key management.
@@ -2,8 +2,9 @@
2
2
  //
3
3
  // Storage layer for auto-learned project memories. Follows context-store.ts patterns.
4
4
  // All functions degrade gracefully: return empty results when DB unavailable, never throw.
5
- import { isDbAvailable, _getAdapter, transaction, insertMemoryRow, rewriteMemoryId, updateMemoryContentRow, incrementMemoryHitCount, supersedeMemoryRow, markMemoryUnitProcessed, decayMemoriesBefore, supersedeLowestRankedMemories, deleteMemoryEmbedding, deleteMemoryRelationsFor, } from './gsd-db.js';
5
+ import { isDbAvailable, _getAdapter, transaction, isInTransaction, insertMemoryRow, rewriteMemoryId, updateMemoryContentRow, incrementMemoryHitCount, supersedeMemoryRow, markMemoryUnitProcessed, decayMemoriesBefore, supersedeLowestRankedMemories, deleteMemoryEmbedding, deleteMemoryRelationsFor, } from './gsd-db.js';
6
6
  import { createMemoryRelation, isValidRelation } from './memory-relations.js';
7
+ import { logWarning } from './workflow-logger.js';
7
8
  // ─── Category Display Order ─────────────────────────────────────────────────
8
9
  const CATEGORY_PRIORITY = {
9
10
  gotcha: 0,
@@ -367,7 +368,13 @@ export function nextMemoryId() {
367
368
  * Insert a new memory with a race-safe auto-assigned ID.
368
369
  * Uses AUTOINCREMENT seq to derive the ID after insert, avoiding
369
370
  * the read-then-write race in concurrent scenarios (e.g. worktrees).
370
- * Returns the assigned ID, or null on failure.
371
+ * Returns the assigned ID, or null when the DB is unavailable.
372
+ *
373
+ * Throws on genuine SQL errors (corruption, missing tables, constraint
374
+ * violations) so callers can surface the underlying message instead of
375
+ * collapsing the failure to a generic "create_failed". See issue #4967 —
376
+ * the previous bare-catch swallowed "database disk image is malformed"
377
+ * errors, leaving the memory subsystem broken without any signal.
371
378
  */
372
379
  export function createMemory(fields) {
373
380
  if (!isDbAvailable())
@@ -376,35 +383,57 @@ export function createMemory(fields) {
376
383
  if (!adapter)
377
384
  return null;
378
385
  try {
379
- const now = new Date().toISOString();
380
- // Insert with a temporary placeholder ID — seq is auto-assigned
381
- const placeholder = `_TMP_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
382
- insertMemoryRow({
383
- id: placeholder,
384
- category: fields.category,
385
- content: fields.content,
386
- confidence: fields.confidence ?? 0.8,
387
- sourceUnitType: fields.source_unit_type ?? null,
388
- sourceUnitId: fields.source_unit_id ?? null,
389
- createdAt: now,
390
- updatedAt: now,
391
- scope: fields.scope ?? 'project',
392
- tags: fields.tags ?? [],
393
- structuredFields: fields.structuredFields ?? null,
394
- });
395
- // Derive the real ID from the assigned seq (SELECT is still fine via adapter)
396
- const row = adapter.prepare('SELECT seq FROM memories WHERE id = :id').get({ ':id': placeholder });
397
- if (!row)
398
- return placeholder; // fallback — should not happen
399
- const seq = row['seq'];
400
- const realId = `MEM${String(seq).padStart(3, '0')}`;
401
- rewriteMemoryId(placeholder, realId);
402
- return realId;
403
- }
404
- catch {
405
- return null;
386
+ return transaction(() => doCreateMemory(adapter, fields));
387
+ }
388
+ catch (err) {
389
+ const message = err instanceof Error ? err.message : String(err);
390
+ // Targeted recovery: a malformed memory store can sometimes be rebuilt
391
+ // by VACUUM. Skip when inside a transaction — SQLite refuses VACUUM
392
+ // there and a secondary throw would mask the real fault.
393
+ if (message.toLowerCase().includes('malformed') && !isInTransaction()) {
394
+ try {
395
+ adapter.prepare('VACUUM').run();
396
+ const recoveryMessage = 'recovered malformed memory store via VACUUM';
397
+ process.stderr.write(`memory-store: ${recoveryMessage}\n`);
398
+ logWarning('memory-store', recoveryMessage);
399
+ return transaction(() => doCreateMemory(adapter, fields));
400
+ }
401
+ catch (retryErr) {
402
+ const retryMsg = retryErr instanceof Error ? retryErr.message : String(retryErr);
403
+ logWarning('memory-store', `VACUUM recovery for memory store failed: ${retryMsg}`);
404
+ // Surface the *original* malformed error — it's the actionable signal.
405
+ throw err;
406
+ }
407
+ }
408
+ throw err;
406
409
  }
407
410
  }
411
+ function doCreateMemory(adapter, fields) {
412
+ const now = new Date().toISOString();
413
+ // Insert with a temporary placeholder ID — seq is auto-assigned
414
+ const placeholder = `_TMP_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
415
+ insertMemoryRow({
416
+ id: placeholder,
417
+ category: fields.category,
418
+ content: fields.content,
419
+ confidence: fields.confidence ?? 0.8,
420
+ sourceUnitType: fields.source_unit_type ?? null,
421
+ sourceUnitId: fields.source_unit_id ?? null,
422
+ createdAt: now,
423
+ updatedAt: now,
424
+ scope: fields.scope ?? 'project',
425
+ tags: fields.tags ?? [],
426
+ structuredFields: fields.structuredFields ?? null,
427
+ });
428
+ // Derive the real ID from the assigned seq (SELECT is still fine via adapter)
429
+ const row = adapter.prepare('SELECT seq FROM memories WHERE id = :id').get({ ':id': placeholder });
430
+ if (!row)
431
+ return placeholder; // fallback — should not happen
432
+ const seq = row['seq'];
433
+ const realId = `MEM${String(seq).padStart(3, '0')}`;
434
+ rewriteMemoryId(placeholder, realId);
435
+ return realId;
436
+ }
408
437
  /**
409
438
  * Update a memory's content and optionally its confidence.
410
439
  */
@@ -591,8 +620,14 @@ export function applyMemoryActions(actions, unitType, unitId) {
591
620
  enforceMemoryCap();
592
621
  });
593
622
  }
594
- catch {
595
- // non-fatal — transaction will have rolled back
623
+ catch (err) {
624
+ // Non-fatal — the transaction has rolled back. We log a warning so a
625
+ // degraded memory subsystem (e.g. malformed store, missing tables) is
626
+ // visible to forensics instead of silently dropping every CREATE — see
627
+ // issue #4967, where this swallow combined with createMemory's bare
628
+ // catch hid SQLite corruption from the auto-mode flow entirely.
629
+ const message = err instanceof Error ? err.message : String(err);
630
+ logWarning('memory-store', `applyMemoryActions failed (memory subsystem degraded): ${message}`);
596
631
  }
597
632
  }
598
633
  // ─── LINK action ────────────────────────────────────────────────────────────
@@ -13,6 +13,7 @@ import { resolve, join, dirname } from "node:path";
13
13
  import { gsdRoot } from "../paths.js";
14
14
  import { fileURLToPath } from "node:url";
15
15
  import { showNextAction } from "../../shared/tui.js";
16
+ import { getHomeDir } from "../home-dir.js";
16
17
  import { validatePlanningDirectory, parsePlanningDirectory, transformToGSD, generatePreview, writeGSDDirectory, } from "./index.js";
17
18
  /** Format preview stats for embedding in the review prompt. */
18
19
  function formatPreviewStats(preview) {
@@ -50,10 +51,10 @@ export async function handleMigrate(args, ctx, pi) {
50
51
  // Default to cwd when no args given; expand ~ to HOME
51
52
  let rawPath = args.trim() || ".";
52
53
  if (rawPath.startsWith("~/")) {
53
- rawPath = join(process.env.HOME ?? "~", rawPath.slice(2));
54
+ rawPath = join(getHomeDir(), rawPath.slice(2));
54
55
  }
55
56
  else if (rawPath === "~") {
56
- rawPath = process.env.HOME ?? "~";
57
+ rawPath = getHomeDir();
57
58
  }
58
59
  let sourcePath = resolve(process.cwd(), rawPath);
59
60
  if (!sourcePath.endsWith(".planning")) {
@@ -0,0 +1,36 @@
1
+ import { isDbAvailable, getAllMilestones } from "./gsd-db.js";
2
+ import { getReservedMilestoneIds, milestoneIdSort, nextMilestoneId, reserveMilestoneId, } from "./milestone-ids.js";
3
+ import { isReusableGhostMilestone } from "./state.js";
4
+ function getDatabaseMilestoneIds() {
5
+ if (!isDbAvailable())
6
+ return [];
7
+ return getAllMilestones().map((milestone) => milestone.id);
8
+ }
9
+ /**
10
+ * Generate the next milestone ID, accounting for DB rows and in-process
11
+ * reservations, and reserve it.
12
+ */
13
+ export function nextMilestoneIdReserved(existingIds, uniqueEnabled, basePath) {
14
+ const reservedIds = getReservedMilestoneIds();
15
+ const allIds = [
16
+ ...new Set([
17
+ ...existingIds,
18
+ ...reservedIds,
19
+ ...getDatabaseMilestoneIds(),
20
+ ]),
21
+ ];
22
+ if (basePath) {
23
+ const sorted = [...allIds].sort(milestoneIdSort);
24
+ for (const candidate of sorted) {
25
+ if (reservedIds.has(candidate))
26
+ continue;
27
+ if (isReusableGhostMilestone(basePath, candidate)) {
28
+ reserveMilestoneId(candidate);
29
+ return candidate;
30
+ }
31
+ }
32
+ }
33
+ const id = nextMilestoneId(allIds, uniqueEnabled);
34
+ reserveMilestoneId(id);
35
+ return id;
36
+ }
@@ -228,11 +228,8 @@ export function getEligibleModels(tier, availableModelIds, routingConfig) {
228
228
  if (availableModelIds.includes(explicitModel))
229
229
  return [explicitModel];
230
230
  // Provider-prefix-stripped match
231
- const match = availableModelIds.find(id => {
232
- const bareAvail = id.includes("/") ? id.split("/").pop() : id;
233
- const bareExplicit = explicitModel.includes("/") ? explicitModel.split("/").pop() : explicitModel;
234
- return bareAvail === bareExplicit;
235
- });
231
+ const bareExplicit = bareModelId(explicitModel);
232
+ const match = availableModelIds.find(id => bareModelId(id) === bareExplicit);
236
233
  if (match)
237
234
  return [match];
238
235
  }
@@ -323,12 +320,31 @@ export function resolveModelForComplexity(classification, phaseConfig, routingCo
323
320
  }
324
321
  // Downgrade-only: if requested tier >= configured tier, no change
325
322
  if (tierOrdinal(requestedTier) >= tierOrdinal(configuredTier)) {
323
+ // If the configured primary is directly available, use it
324
+ if (isModelAvailable(configuredPrimary, availableModelIds)) {
325
+ return {
326
+ modelId: configuredPrimary,
327
+ fallbacks: phaseConfig.fallbacks,
328
+ tier: requestedTier,
329
+ wasDowngraded: false,
330
+ reason: `tier ${requestedTier} >= configured ${configuredTier}`,
331
+ selectionMethod: "tier-only",
332
+ };
333
+ }
334
+ // Configured primary is unavailable (e.g. Anthropic model configured but
335
+ // running on a non-Anthropic provider). Find the best available model at
336
+ // the same capability tier so routing still works cross-provider.
337
+ const crossProviderEquivalent = findModelForTier(configuredTier, routingConfig, availableModelIds, routingConfig.cross_provider !== false);
326
338
  return {
327
- modelId: configuredPrimary,
328
- fallbacks: phaseConfig.fallbacks,
339
+ modelId: crossProviderEquivalent ?? configuredPrimary,
340
+ fallbacks: crossProviderEquivalent
341
+ ? [...phaseConfig.fallbacks.filter(f => f !== crossProviderEquivalent), configuredPrimary]
342
+ : phaseConfig.fallbacks,
329
343
  tier: requestedTier,
330
344
  wasDowngraded: false,
331
- reason: `tier ${requestedTier} >= configured ${configuredTier}`,
345
+ reason: crossProviderEquivalent
346
+ ? `cross-provider ${configuredTier}-tier equivalent`
347
+ : `tier ${requestedTier} >= configured ${configuredTier}`,
332
348
  selectionMethod: "tier-only",
333
349
  };
334
350
  }
@@ -404,7 +420,84 @@ export function defaultRoutingConfig() {
404
420
  hooks: true,
405
421
  };
406
422
  }
423
+ // ─── Tier-Based Model Resolution (for profile defaults) ─────────────────────
424
+ /**
425
+ * Fallback-only canonical model IDs per tier. Returned when the
426
+ * available-model list is empty (e.g., preferences are loaded before the
427
+ * model registry is populated at bootstrap), or when a non-empty registry has
428
+ * no model at the requested tier.
429
+ *
430
+ * Precedence (resolveModelForTier):
431
+ * 1. configured `tier_models[tier]` (via getEligibleModels) — exact/bare match
432
+ * 2. cheapest available model whose tier matches `tier`
433
+ * 3. CANONICAL_TIER_MODELS[tier] as last-resort fallback
434
+ */
435
+ const CANONICAL_TIER_MODELS = {
436
+ light: "claude-haiku-4-5",
437
+ standard: "claude-sonnet-4-6",
438
+ heavy: "claude-opus-4-6",
439
+ };
440
+ export function canonicalModelForTier(tier) {
441
+ return CANONICAL_TIER_MODELS[tier];
442
+ }
443
+ /**
444
+ * Single source of truth for tier-based model selection.
445
+ * Returns the cheapest available model whose capability tier matches `tier`,
446
+ * honoring `routingConfig.tier_models[tier]` when set. Returns undefined when
447
+ * no available model matches the tier.
448
+ *
449
+ * `crossProvider`: when false, restricts the search to models that share the
450
+ * canonical (Anthropic) provider for the tier. When true, any provider is
451
+ * eligible.
452
+ */
453
+ function findModelForTier(tier, routingConfig, availableModelIds, crossProvider) {
454
+ const eligible = getEligibleModels(tier, availableModelIds, routingConfig);
455
+ if (eligible.length === 0)
456
+ return undefined;
457
+ if (crossProvider) {
458
+ return eligible[0];
459
+ }
460
+ // Same-provider only: keep models whose bare ID matches a canonical
461
+ // Anthropic ID at this tier (i.e., a claude-* model in the tier map).
462
+ const sameProvider = eligible.filter(id => {
463
+ const bare = bareModelId(id);
464
+ return MODEL_CAPABILITY_TIER[bare] === tier && bare.startsWith("claude-");
465
+ });
466
+ return sameProvider[0];
467
+ }
468
+ export function resolveModelForTier(tier, availableModelIds, routingConfigOrCrossProvider = defaultRoutingConfig(), crossProvider) {
469
+ const routingConfig = typeof routingConfigOrCrossProvider === "boolean"
470
+ ? defaultRoutingConfig()
471
+ : { ...defaultRoutingConfig(), ...routingConfigOrCrossProvider };
472
+ const allowCrossProvider = typeof routingConfigOrCrossProvider === "boolean"
473
+ ? routingConfigOrCrossProvider
474
+ : crossProvider ?? routingConfig.cross_provider !== false;
475
+ // No available models known — return canonical fallback
476
+ if (availableModelIds.length === 0) {
477
+ return canonicalModelForTier(tier);
478
+ }
479
+ // Cross-provider tier search
480
+ const resolved = findModelForTier(tier, routingConfig, availableModelIds, allowCrossProvider);
481
+ return resolved
482
+ ? normalizeResolvedTierModelId(resolved, tier, routingConfig)
483
+ : canonicalModelForTier(tier);
484
+ }
407
485
  // ─── Internal ────────────────────────────────────────────────────────────────
486
+ /**
487
+ * Check whether a model ID is present in the available models list.
488
+ * Handles bare IDs ("claude-opus-4-6") and provider-prefixed IDs ("anthropic/claude-opus-4-6").
489
+ */
490
+ function isModelAvailable(modelId, availableModelIds) {
491
+ if (availableModelIds.includes(modelId))
492
+ return true;
493
+ // Strip provider prefix for comparison. Treat trailing-slash IDs ("provider/")
494
+ // as no-bare-ID rather than empty-string match (which would erroneously match
495
+ // any other "provider/" ID).
496
+ const bare = bareModelId(modelId);
497
+ if (!bare)
498
+ return false;
499
+ return availableModelIds.some(id => bareModelId(id) === bare);
500
+ }
408
501
  function getModelTier(modelId) {
409
502
  // Strip provider prefix if present
410
503
  const bareId = bareModelId(modelId);
@@ -443,8 +536,20 @@ function getModelCost(modelId) {
443
536
  // Unknown cost — assume expensive to avoid routing to unknown cheap models
444
537
  return 999;
445
538
  }
539
+ function normalizeResolvedTierModelId(modelId, tier, routingConfig) {
540
+ const explicitModel = routingConfig.tier_models?.[tier];
541
+ if (explicitModel?.includes("/")) {
542
+ return modelId;
543
+ }
544
+ const bareId = bareModelId(modelId);
545
+ return MODEL_CAPABILITY_TIER[bareId] ? bareId : modelId;
546
+ }
446
547
  function bareModelId(modelId) {
447
- return modelId.includes("/") ? modelId.split("/").pop() : modelId;
548
+ if (!modelId.includes("/"))
549
+ return modelId;
550
+ // .pop() never returns undefined on a non-empty string but ?? guards future
551
+ // refactors and avoids the misleading non-null assertion.
552
+ return modelId.split("/").pop() ?? modelId;
448
553
  }
449
554
  // ─── Provider-specific Tool Limits ─────────────────────────────────────────
450
555
  /**
@@ -10,6 +10,7 @@ import { join } from "node:path";
10
10
  import { GSDError, GSD_GIT_ERROR } from "./errors.js";
11
11
  import { GIT_NO_PROMPT_ENV } from "./git-constants.js";
12
12
  import { getErrorMessage } from "./error-utils.js";
13
+ import { isInfrastructureError } from "./auto/infra-errors.js";
13
14
  // Issue #453: keep auto-mode bookkeeping on the stable git CLI path unless a
14
15
  // caller explicitly opts into the native helper.
15
16
  const NATIVE_GSD_GIT_ENABLED = process.env.GSD_ENABLE_NATIVE_GSD_GIT === "1";
@@ -695,6 +696,10 @@ export function nativeAddAllWithExclusions(basePath, exclusions) {
695
696
  }
696
697
  catch (err) {
697
698
  const stderr = err?.stderr ?? "";
699
+ const infraCode = isInfrastructureError(err) ?? isInfrastructureError(stderr);
700
+ if (infraCode) {
701
+ throw err;
702
+ }
698
703
  // git exits 1 when pathspec exclusions reference paths already covered
699
704
  // by .gitignore. The staging itself succeeds — only suppress that case.
700
705
  if (stderr.includes("ignored by one of your .gitignore files")) {
@@ -709,7 +714,8 @@ export function nativeAddAllWithExclusions(basePath, exclusions) {
709
714
  fallbackStageWithSymlinkedDotGsd(basePath);
710
715
  return;
711
716
  }
712
- throw new GSDError(GSD_GIT_ERROR, `git add -A with exclusions failed in ${basePath}: ${getErrorMessage(err)}`);
717
+ const stderrDetail = stderr.trim() ? `; stderr: ${stderr.trim()}` : "";
718
+ throw new GSDError(GSD_GIT_ERROR, `git add -A with exclusions failed in ${basePath}: ${getErrorMessage(err)}${stderrDetail}`);
713
719
  }
714
720
  }
715
721
  /**