gsd-pi 2.58.0-dev.d63175c → 2.58.0-dev.e002a57

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 (777) hide show
  1. package/README.md +1 -1
  2. package/dist/cli.js +60 -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/phases.js +25 -21
  21. package/dist/resources/extensions/gsd/auto-artifact-paths.js +2 -2
  22. package/dist/resources/extensions/gsd/auto-dashboard.js +37 -20
  23. package/dist/resources/extensions/gsd/auto-dispatch.js +17 -2
  24. package/dist/resources/extensions/gsd/auto-model-selection.js +26 -3
  25. package/dist/resources/extensions/gsd/auto-post-unit.js +16 -4
  26. package/dist/resources/extensions/gsd/auto-prompts.js +1 -1
  27. package/dist/resources/extensions/gsd/auto-recovery.js +13 -5
  28. package/dist/resources/extensions/gsd/auto-start.js +35 -22
  29. package/dist/resources/extensions/gsd/auto-worktree.js +199 -12
  30. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +32 -0
  31. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +80 -8
  32. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +32 -1
  33. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +42 -34
  34. package/dist/resources/extensions/gsd/bootstrap/system-context.js +66 -12
  35. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -0
  36. package/dist/resources/extensions/gsd/captures.js +56 -4
  37. package/dist/resources/extensions/gsd/codebase-generator.js +279 -0
  38. package/dist/resources/extensions/gsd/commands/catalog.js +10 -1
  39. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  40. package/dist/resources/extensions/gsd/commands-codebase.js +115 -0
  41. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +41 -4
  42. package/dist/resources/extensions/gsd/complexity-classifier.js +8 -6
  43. package/dist/resources/extensions/gsd/db-writer.js +116 -8
  44. package/dist/resources/extensions/gsd/doctor-git-checks.js +76 -1
  45. package/dist/resources/extensions/gsd/doctor-proactive.js +34 -1
  46. package/dist/resources/extensions/gsd/doctor-providers.js +2 -1
  47. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +5 -4
  48. package/dist/resources/extensions/gsd/doctor.js +3 -1
  49. package/dist/resources/extensions/gsd/error-classifier.js +12 -10
  50. package/dist/resources/extensions/gsd/extension-manifest.json +16 -1
  51. package/dist/resources/extensions/gsd/forensics.js +123 -20
  52. package/dist/resources/extensions/gsd/git-service.js +105 -2
  53. package/dist/resources/extensions/gsd/gitignore.js +33 -0
  54. package/dist/resources/extensions/gsd/gsd-db.js +36 -9
  55. package/dist/resources/extensions/gsd/guided-flow.js +106 -44
  56. package/dist/resources/extensions/gsd/health-widget-core.js +31 -0
  57. package/dist/resources/extensions/gsd/health-widget.js +17 -0
  58. package/dist/resources/extensions/gsd/index.js +1 -1
  59. package/dist/resources/extensions/gsd/memory-extractor.js +7 -0
  60. package/dist/resources/extensions/gsd/migrate-external.js +8 -1
  61. package/dist/resources/extensions/gsd/milestone-validation-gates.js +45 -0
  62. package/dist/resources/extensions/gsd/model-cost-table.js +18 -0
  63. package/dist/resources/extensions/gsd/model-router.js +35 -1
  64. package/dist/resources/extensions/gsd/native-git-bridge.js +39 -0
  65. package/dist/resources/extensions/gsd/notifications.js +16 -1
  66. package/dist/resources/extensions/gsd/parallel-eligibility.js +13 -2
  67. package/dist/resources/extensions/gsd/parallel-merge.js +78 -5
  68. package/dist/resources/extensions/gsd/parsers-legacy.js +20 -3
  69. package/dist/resources/extensions/gsd/paths.js +45 -0
  70. package/dist/resources/extensions/gsd/preferences-models.js +14 -1
  71. package/dist/resources/extensions/gsd/preferences-types.js +3 -1
  72. package/dist/resources/extensions/gsd/preferences.js +13 -16
  73. package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
  74. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  75. package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  76. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  77. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  78. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -1
  79. package/dist/resources/extensions/gsd/prompts/forensics.md +2 -2
  80. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  81. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  82. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  83. package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
  84. package/dist/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  85. package/dist/resources/extensions/gsd/repo-identity.js +205 -11
  86. package/dist/resources/extensions/gsd/rethink.js +5 -0
  87. package/dist/resources/extensions/gsd/roadmap-slices.js +5 -4
  88. package/dist/resources/extensions/gsd/state.js +85 -27
  89. package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  90. package/dist/resources/extensions/gsd/tools/complete-task.js +34 -71
  91. package/dist/resources/extensions/gsd/tools/plan-milestone.js +12 -2
  92. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +29 -1
  93. package/dist/resources/extensions/gsd/tools/validate-milestone.js +14 -3
  94. package/dist/resources/extensions/gsd/triage-resolution.js +22 -7
  95. package/dist/resources/extensions/gsd/undo.js +2 -2
  96. package/dist/resources/extensions/gsd/unit-ownership.js +164 -33
  97. package/dist/resources/extensions/gsd/verdict-parser.js +20 -8
  98. package/dist/resources/extensions/gsd/watch/header-renderer.js +241 -0
  99. package/dist/resources/extensions/gsd/workflow-manifest.js +24 -5
  100. package/dist/resources/extensions/gsd/workflow-projections.js +95 -63
  101. package/dist/resources/extensions/gsd/workflow-reconcile.js +35 -5
  102. package/dist/resources/extensions/gsd/workspace-index.js +24 -0
  103. package/dist/resources/extensions/gsd/worktree-manager.js +105 -1
  104. package/dist/resources/extensions/gsd/worktree-resolver.js +20 -3
  105. package/dist/resources/extensions/mcp-client/index.js +11 -7
  106. package/dist/resources/extensions/ollama/index.js +112 -0
  107. package/dist/resources/extensions/ollama/model-capabilities.js +115 -0
  108. package/dist/resources/extensions/ollama/ollama-client.js +168 -0
  109. package/dist/resources/extensions/ollama/ollama-commands.js +194 -0
  110. package/dist/resources/extensions/ollama/ollama-discovery.js +69 -0
  111. package/dist/resources/extensions/ollama/ollama-tool.js +184 -0
  112. package/dist/resources/extensions/ollama/types.js +2 -0
  113. package/dist/resources/extensions/search-the-web/extension-manifest.json +1 -1
  114. package/dist/resources/extensions/search-the-web/url-utils.js +17 -0
  115. package/dist/resources/extensions/shared/interview-ui.js +11 -1
  116. package/dist/resources/skills/create-gsd-extension/SKILL.md +5 -3
  117. package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  118. package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  119. package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  120. package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  121. package/dist/security-overrides.d.ts +11 -0
  122. package/dist/security-overrides.js +41 -0
  123. package/dist/startup-model-validation.d.ts +39 -0
  124. package/dist/startup-model-validation.js +50 -0
  125. package/dist/web/standalone/.next/BUILD_ID +1 -1
  126. package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
  127. package/dist/web/standalone/.next/build-manifest.json +3 -3
  128. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  129. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  130. package/dist/web/standalone/.next/required-server-files.json +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  133. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
  143. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  145. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  146. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  149. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.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_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/index.html +1 -1
  204. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  205. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  206. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  207. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  208. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  209. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  210. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  211. package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
  212. package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
  213. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  214. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  216. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  217. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  218. package/dist/web/standalone/.next/static/chunks/6502.7593d7797a4b3999.js +9 -0
  219. package/dist/web/standalone/.next/static/chunks/{webpack-61d3afac6d0f0ce7.js → webpack-a1c1e452c6b32d04.js} +1 -1
  220. package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +1 -0
  221. package/dist/web/standalone/server.js +1 -1
  222. package/dist/web-mode.js +2 -1
  223. package/dist/welcome-screen.d.ts +1 -0
  224. package/dist/welcome-screen.js +32 -6
  225. package/package.json +2 -2
  226. package/packages/native/dist/ast/index.js +9 -5
  227. package/packages/native/dist/ast/types.js +2 -1
  228. package/packages/native/dist/clipboard/index.js +12 -7
  229. package/packages/native/dist/clipboard/types.js +2 -1
  230. package/packages/native/dist/diff/index.js +12 -7
  231. package/packages/native/dist/diff/types.js +2 -1
  232. package/packages/native/dist/fd/index.js +6 -3
  233. package/packages/native/dist/fd/types.js +2 -1
  234. package/packages/native/dist/glob/index.js +9 -5
  235. package/packages/native/dist/glob/types.js +2 -1
  236. package/packages/native/dist/grep/index.js +9 -5
  237. package/packages/native/dist/grep/types.js +2 -1
  238. package/packages/native/dist/gsd-parser/index.js +18 -11
  239. package/packages/native/dist/gsd-parser/types.js +2 -1
  240. package/packages/native/dist/highlight/index.js +12 -7
  241. package/packages/native/dist/highlight/types.js +2 -1
  242. package/packages/native/dist/html/index.js +6 -3
  243. package/packages/native/dist/html/types.js +2 -1
  244. package/packages/native/dist/image/index.js +10 -5
  245. package/packages/native/dist/image/types.js +7 -4
  246. package/packages/native/dist/index.js +70 -17
  247. package/packages/native/dist/json-parse/index.js +13 -8
  248. package/packages/native/dist/native.js +47 -10
  249. package/packages/native/dist/ps/index.js +15 -9
  250. package/packages/native/dist/ps/types.js +2 -1
  251. package/packages/native/dist/stream-process/index.js +12 -7
  252. package/packages/native/dist/text/index.js +24 -14
  253. package/packages/native/dist/text/types.js +5 -2
  254. package/packages/native/dist/truncate/index.js +12 -7
  255. package/packages/native/dist/ttsr/index.js +12 -7
  256. package/packages/native/dist/ttsr/types.js +2 -1
  257. package/packages/native/dist/xxhash/index.js +9 -5
  258. package/packages/native/package.json +19 -19
  259. package/packages/native/src/__tests__/module-compat.test.mjs +91 -0
  260. package/packages/native/src/native.ts +9 -8
  261. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  262. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  263. package/packages/pi-agent-core/dist/proxy.d.ts +1 -1
  264. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  265. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  266. package/packages/pi-agent-core/src/agent-loop.test.ts +45 -0
  267. package/packages/pi-agent-core/src/agent-loop.ts +3 -2
  268. package/packages/pi-agent-core/src/proxy.ts +1 -1
  269. package/packages/pi-ai/dist/env-api-keys.js +1 -0
  270. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  271. package/packages/pi-ai/dist/index.d.ts +1 -0
  272. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  273. package/packages/pi-ai/dist/index.js +1 -0
  274. package/packages/pi-ai/dist/index.js.map +1 -1
  275. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  276. package/packages/pi-ai/dist/providers/anthropic-shared.js +19 -2
  277. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  278. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts +2 -0
  279. package/packages/pi-ai/dist/providers/anthropic-shared.test.d.ts.map +1 -0
  280. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +25 -0
  281. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -0
  282. package/packages/pi-ai/dist/types.d.ts +3 -3
  283. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  284. package/packages/pi-ai/dist/types.js.map +1 -1
  285. package/packages/pi-ai/dist/utils/json-parse.d.ts +3 -0
  286. package/packages/pi-ai/dist/utils/json-parse.d.ts.map +1 -1
  287. package/packages/pi-ai/dist/utils/json-parse.js +24 -1
  288. package/packages/pi-ai/dist/utils/json-parse.js.map +1 -1
  289. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts +37 -0
  290. package/packages/pi-ai/dist/utils/repair-tool-json.d.ts.map +1 -0
  291. package/packages/pi-ai/dist/utils/repair-tool-json.js +75 -0
  292. package/packages/pi-ai/dist/utils/repair-tool-json.js.map +1 -0
  293. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts +2 -0
  294. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.d.ts.map +1 -0
  295. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js +73 -0
  296. package/packages/pi-ai/dist/utils/tests/repair-tool-json.test.js.map +1 -0
  297. package/packages/pi-ai/src/env-api-keys.ts +1 -0
  298. package/packages/pi-ai/src/index.ts +1 -0
  299. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +29 -0
  300. package/packages/pi-ai/src/providers/anthropic-shared.ts +17 -2
  301. package/packages/pi-ai/src/types.ts +3 -2
  302. package/packages/pi-ai/src/utils/json-parse.ts +28 -1
  303. package/packages/pi-ai/src/utils/repair-tool-json.ts +88 -0
  304. package/packages/pi-ai/src/utils/tests/repair-tool-json.test.ts +102 -0
  305. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +4 -0
  306. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  307. package/packages/pi-coding-agent/dist/core/agent-session.js +31 -0
  308. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  309. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +17 -1
  310. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  311. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +62 -2
  312. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  313. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts +6 -0
  314. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.d.ts.map +1 -0
  315. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +176 -0
  316. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -0
  317. package/packages/pi-coding-agent/dist/core/exec.d.ts.map +1 -1
  318. package/packages/pi-coding-agent/dist/core/exec.js +3 -1
  319. package/packages/pi-coding-agent/dist/core/exec.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts +28 -0
  321. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.d.ts.map +1 -0
  322. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js +37 -0
  323. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.js.map +1 -0
  324. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts +2 -0
  325. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.d.ts.map +1 -0
  326. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js +63 -0
  327. package/packages/pi-coding-agent/dist/core/extensions/extension-manifest.test.js.map +1 -0
  328. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts +19 -0
  329. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.d.ts.map +1 -0
  330. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js +115 -0
  331. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.js.map +1 -0
  332. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts +2 -0
  333. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.d.ts.map +1 -0
  334. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js +109 -0
  335. package/packages/pi-coding-agent/dist/core/extensions/extension-sort.test.js.map +1 -0
  336. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +4 -0
  337. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  338. package/packages/pi-coding-agent/dist/core/extensions/index.js +2 -0
  339. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  340. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  341. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  342. package/packages/pi-coding-agent/dist/core/extensions/loader.js +5 -0
  343. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  344. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts +44 -0
  345. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.d.ts.map +1 -0
  346. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js +97 -0
  347. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.js.map +1 -0
  348. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts +2 -0
  349. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.d.ts.map +1 -0
  350. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js +181 -0
  351. package/packages/pi-coding-agent/dist/core/image-overflow-recovery.test.js.map +1 -0
  352. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -1
  353. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  354. package/packages/pi-coding-agent/dist/core/index.js +1 -1
  355. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  356. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  357. package/packages/pi-coding-agent/dist/core/lsp/index.js +3 -0
  358. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  359. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  360. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -0
  361. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  362. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  363. package/packages/pi-coding-agent/dist/core/messages.js +31 -2
  364. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  365. package/packages/pi-coding-agent/dist/core/messages.test.d.ts +9 -0
  366. package/packages/pi-coding-agent/dist/core/messages.test.d.ts.map +1 -0
  367. package/packages/pi-coding-agent/dist/core/messages.test.js +86 -0
  368. package/packages/pi-coding-agent/dist/core/messages.test.js.map +1 -0
  369. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  370. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  371. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  372. package/packages/pi-coding-agent/dist/core/resolve-config-value.d.ts +8 -0
  373. package/packages/pi-coding-agent/dist/core/resolve-config-value.d.ts.map +1 -1
  374. package/packages/pi-coding-agent/dist/core/resolve-config-value.js +23 -2
  375. package/packages/pi-coding-agent/dist/core/resolve-config-value.js.map +1 -1
  376. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +89 -2
  377. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  378. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +10 -0
  379. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  380. package/packages/pi-coding-agent/dist/core/resource-loader.js +12 -1
  381. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  382. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +6 -0
  383. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  384. package/packages/pi-coding-agent/dist/core/retry-handler.js +48 -1
  385. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  386. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts +9 -0
  387. package/packages/pi-coding-agent/dist/core/retry-handler.test.d.ts.map +1 -0
  388. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +193 -0
  389. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -0
  390. package/packages/pi-coding-agent/dist/core/settings-manager-security.test.d.ts +2 -0
  391. package/packages/pi-coding-agent/dist/core/settings-manager-security.test.d.ts.map +1 -0
  392. package/packages/pi-coding-agent/dist/core/settings-manager-security.test.js +83 -0
  393. package/packages/pi-coding-agent/dist/core/settings-manager-security.test.js.map +1 -0
  394. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +14 -0
  395. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  396. package/packages/pi-coding-agent/dist/core/settings-manager.js +36 -3
  397. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  398. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  399. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +10 -3
  400. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  401. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  402. package/packages/pi-coding-agent/dist/core/tools/read.js +13 -4
  403. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  404. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts +16 -0
  405. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.d.ts.map +1 -0
  406. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +80 -0
  407. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -0
  408. package/packages/pi-coding-agent/dist/index.d.ts +3 -2
  409. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  410. package/packages/pi-coding-agent/dist/index.js +2 -1
  411. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  412. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.d.ts +1 -1
  413. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.d.ts.map +1 -1
  414. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js +9 -8
  415. package/packages/pi-coding-agent/dist/modes/interactive/components/armin.js.map +1 -1
  416. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  417. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +0 -3
  418. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  419. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -0
  420. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  421. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +2 -1
  422. package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
  423. package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js +1 -1
  424. package/packages/pi-coding-agent/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  425. package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js +1 -1
  426. package/packages/pi-coding-agent/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  427. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js +1 -1
  428. package/packages/pi-coding-agent/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  429. package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  430. package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js +5 -2
  431. package/packages/pi-coding-agent/dist/modes/interactive/components/config-selector.js.map +1 -1
  432. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts +1 -0
  433. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  434. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js +4 -0
  435. package/packages/pi-coding-agent/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  436. package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js +1 -1
  437. package/packages/pi-coding-agent/dist/modes/interactive/components/custom-message.js.map +1 -1
  438. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts +1 -1
  439. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  440. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js +4 -2
  441. package/packages/pi-coding-agent/dist/modes/interactive/components/daxnuts.js.map +1 -1
  442. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +2 -2
  443. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
  444. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  445. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +8 -1
  446. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  447. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  448. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js +2 -0
  449. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js.map +1 -1
  450. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  451. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.js +4 -0
  452. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-selector.js.map +1 -1
  453. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  454. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +26 -12
  455. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  456. package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js +4 -4
  457. package/packages/pi-coding-agent/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  458. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts +3 -0
  459. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
  460. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +46 -14
  461. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
  462. package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  463. package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js +2 -8
  464. package/packages/pi-coding-agent/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  465. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +4 -4
  466. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
  467. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +2 -2
  468. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  469. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  470. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +8 -3
  471. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  472. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  473. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.js +3 -2
  474. package/packages/pi-coding-agent/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  475. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  476. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +19 -1
  477. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  478. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  479. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +16 -1
  480. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  481. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +1 -0
  482. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  483. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +27 -4
  484. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  485. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  486. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +6 -0
  487. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  488. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +1 -1
  489. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  490. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts +1 -0
  491. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.d.ts.map +1 -1
  492. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js +5 -0
  493. package/packages/pi-coding-agent/dist/modes/rpc/remote-terminal.js.map +1 -1
  494. package/packages/pi-coding-agent/src/core/agent-session.ts +38 -1
  495. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +236 -0
  496. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +94 -1
  497. package/packages/pi-coding-agent/src/core/exec.ts +3 -1
  498. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.test.ts +77 -0
  499. package/packages/pi-coding-agent/src/core/extensions/extension-manifest.ts +62 -0
  500. package/packages/pi-coding-agent/src/core/extensions/extension-sort.test.ts +134 -0
  501. package/packages/pi-coding-agent/src/core/extensions/extension-sort.ts +137 -0
  502. package/packages/pi-coding-agent/src/core/extensions/index.ts +4 -0
  503. package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
  504. package/packages/pi-coding-agent/src/core/image-overflow-recovery.test.ts +228 -0
  505. package/packages/pi-coding-agent/src/core/image-overflow-recovery.ts +118 -0
  506. package/packages/pi-coding-agent/src/core/index.ts +6 -0
  507. package/packages/pi-coding-agent/src/core/lsp/index.ts +3 -0
  508. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -0
  509. package/packages/pi-coding-agent/src/core/messages.test.ts +114 -0
  510. package/packages/pi-coding-agent/src/core/messages.ts +29 -2
  511. package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
  512. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +111 -1
  513. package/packages/pi-coding-agent/src/core/resolve-config-value.ts +26 -2
  514. package/packages/pi-coding-agent/src/core/resource-loader.ts +20 -1
  515. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +255 -0
  516. package/packages/pi-coding-agent/src/core/retry-handler.ts +52 -1
  517. package/packages/pi-coding-agent/src/core/settings-manager-security.test.ts +102 -0
  518. package/packages/pi-coding-agent/src/core/settings-manager.ts +44 -3
  519. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +11 -3
  520. package/packages/pi-coding-agent/src/core/tools/read.ts +14 -4
  521. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +92 -0
  522. package/packages/pi-coding-agent/src/index.ts +11 -0
  523. package/packages/pi-coding-agent/src/modes/interactive/components/armin.ts +9 -9
  524. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +0 -2
  525. package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +3 -1
  526. package/packages/pi-coding-agent/src/modes/interactive/components/bordered-loader.ts +1 -1
  527. package/packages/pi-coding-agent/src/modes/interactive/components/branch-summary-message.ts +1 -1
  528. package/packages/pi-coding-agent/src/modes/interactive/components/compaction-summary-message.ts +1 -1
  529. package/packages/pi-coding-agent/src/modes/interactive/components/config-selector.ts +7 -2
  530. package/packages/pi-coding-agent/src/modes/interactive/components/countdown-timer.ts +3 -0
  531. package/packages/pi-coding-agent/src/modes/interactive/components/custom-message.ts +1 -1
  532. package/packages/pi-coding-agent/src/modes/interactive/components/daxnuts.ts +4 -3
  533. package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +2 -2
  534. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +3 -1
  535. package/packages/pi-coding-agent/src/modes/interactive/components/extension-input.ts +1 -0
  536. package/packages/pi-coding-agent/src/modes/interactive/components/extension-selector.ts +4 -0
  537. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +27 -13
  538. package/packages/pi-coding-agent/src/modes/interactive/components/oauth-selector.ts +4 -4
  539. package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +45 -14
  540. package/packages/pi-coding-agent/src/modes/interactive/components/scoped-models-selector.ts +2 -7
  541. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +4 -4
  542. package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +2 -2
  543. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +8 -3
  544. package/packages/pi-coding-agent/src/modes/interactive/components/user-message-selector.ts +3 -2
  545. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +24 -1
  546. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +14 -1
  547. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +35 -3
  548. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +7 -0
  549. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +1 -1
  550. package/packages/pi-coding-agent/src/modes/rpc/remote-terminal.ts +6 -0
  551. package/packages/pi-tui/dist/terminal.d.ts +2 -0
  552. package/packages/pi-tui/dist/terminal.d.ts.map +1 -1
  553. package/packages/pi-tui/dist/terminal.js +9 -0
  554. package/packages/pi-tui/dist/terminal.js.map +1 -1
  555. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  556. package/packages/pi-tui/dist/tui.js +9 -0
  557. package/packages/pi-tui/dist/tui.js.map +1 -1
  558. package/packages/pi-tui/src/terminal.ts +14 -0
  559. package/packages/pi-tui/src/tui.ts +8 -0
  560. package/pkg/dist/modes/interactive/theme/themes.js +1 -1
  561. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  562. package/scripts/ensure-workspace-builds.cjs +45 -14
  563. package/src/resources/agents/researcher.md +1 -1
  564. package/src/resources/extensions/ask-user-questions.ts +21 -3
  565. package/src/resources/extensions/async-jobs/extension-manifest.json +1 -1
  566. package/src/resources/extensions/bg-shell/extension-manifest.json +1 -1
  567. package/src/resources/extensions/browser-tools/extension-manifest.json +1 -1
  568. package/src/resources/extensions/claude-code-cli/partial-builder.ts +13 -6
  569. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +63 -35
  570. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +28 -0
  571. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +108 -1
  572. package/src/resources/extensions/context7/extension-manifest.json +1 -1
  573. package/src/resources/extensions/get-secrets-from-user.ts +8 -5
  574. package/src/resources/extensions/google-search/extension-manifest.json +1 -1
  575. package/src/resources/extensions/google-search/index.ts +2 -1
  576. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  577. package/src/resources/extensions/gsd/auto/phases.ts +43 -34
  578. package/src/resources/extensions/gsd/auto-artifact-paths.ts +2 -2
  579. package/src/resources/extensions/gsd/auto-dashboard.ts +37 -19
  580. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -2
  581. package/src/resources/extensions/gsd/auto-model-selection.ts +26 -5
  582. package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
  583. package/src/resources/extensions/gsd/auto-prompts.ts +1 -1
  584. package/src/resources/extensions/gsd/auto-recovery.ts +12 -5
  585. package/src/resources/extensions/gsd/auto-start.ts +35 -26
  586. package/src/resources/extensions/gsd/auto-worktree.ts +193 -9
  587. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +31 -0
  588. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +85 -8
  589. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +38 -1
  590. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +41 -35
  591. package/src/resources/extensions/gsd/bootstrap/system-context.ts +72 -12
  592. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +75 -0
  593. package/src/resources/extensions/gsd/captures.ts +63 -3
  594. package/src/resources/extensions/gsd/codebase-generator.ts +351 -0
  595. package/src/resources/extensions/gsd/commands/catalog.ts +10 -1
  596. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  597. package/src/resources/extensions/gsd/commands-codebase.ts +164 -0
  598. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +46 -4
  599. package/src/resources/extensions/gsd/complexity-classifier.ts +8 -6
  600. package/src/resources/extensions/gsd/db-writer.ts +140 -7
  601. package/src/resources/extensions/gsd/doctor-git-checks.ts +75 -1
  602. package/src/resources/extensions/gsd/doctor-proactive.ts +35 -1
  603. package/src/resources/extensions/gsd/doctor-providers.ts +2 -1
  604. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +5 -4
  605. package/src/resources/extensions/gsd/doctor-types.ts +2 -0
  606. package/src/resources/extensions/gsd/doctor.ts +3 -1
  607. package/src/resources/extensions/gsd/error-classifier.ts +13 -11
  608. package/src/resources/extensions/gsd/extension-manifest.json +16 -1
  609. package/src/resources/extensions/gsd/forensics.ts +144 -20
  610. package/src/resources/extensions/gsd/git-service.ts +119 -3
  611. package/src/resources/extensions/gsd/gitignore.ts +33 -0
  612. package/src/resources/extensions/gsd/gsd-db.ts +43 -7
  613. package/src/resources/extensions/gsd/guided-flow.ts +114 -45
  614. package/src/resources/extensions/gsd/health-widget-core.ts +34 -0
  615. package/src/resources/extensions/gsd/health-widget.ts +17 -0
  616. package/src/resources/extensions/gsd/index.ts +1 -0
  617. package/src/resources/extensions/gsd/memory-extractor.ts +8 -0
  618. package/src/resources/extensions/gsd/migrate-external.ts +9 -1
  619. package/src/resources/extensions/gsd/milestone-validation-gates.ts +56 -0
  620. package/src/resources/extensions/gsd/model-cost-table.ts +19 -0
  621. package/src/resources/extensions/gsd/model-router.ts +35 -1
  622. package/src/resources/extensions/gsd/native-git-bridge.ts +41 -0
  623. package/src/resources/extensions/gsd/notifications.ts +16 -0
  624. package/src/resources/extensions/gsd/parallel-eligibility.ts +15 -2
  625. package/src/resources/extensions/gsd/parallel-merge.ts +87 -4
  626. package/src/resources/extensions/gsd/parsers-legacy.ts +22 -3
  627. package/src/resources/extensions/gsd/paths.ts +44 -0
  628. package/src/resources/extensions/gsd/preferences-models.ts +14 -1
  629. package/src/resources/extensions/gsd/preferences-types.ts +10 -1
  630. package/src/resources/extensions/gsd/preferences.ts +13 -15
  631. package/src/resources/extensions/gsd/prompt-loader.ts +4 -1
  632. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  633. package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -2
  634. package/src/resources/extensions/gsd/prompts/discuss-headless.md +1 -1
  635. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  636. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -1
  637. package/src/resources/extensions/gsd/prompts/forensics.md +2 -2
  638. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
  639. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +1 -1
  640. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  641. package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
  642. package/src/resources/extensions/gsd/prompts/triage-captures.md +1 -0
  643. package/src/resources/extensions/gsd/repo-identity.ts +186 -11
  644. package/src/resources/extensions/gsd/rethink.ts +6 -0
  645. package/src/resources/extensions/gsd/roadmap-slices.ts +5 -4
  646. package/src/resources/extensions/gsd/state.ts +84 -32
  647. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +29 -0
  648. package/src/resources/extensions/gsd/tests/auto-mode-interactive-guard.test.ts +71 -0
  649. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +71 -1
  650. package/src/resources/extensions/gsd/tests/captures.test.ts +103 -0
  651. package/src/resources/extensions/gsd/tests/cli-provider-rate-limit.test.ts +47 -0
  652. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +488 -0
  653. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +27 -0
  654. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +21 -0
  655. package/src/resources/extensions/gsd/tests/completion-hierarchy-guards.test.ts +192 -0
  656. package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +4 -4
  657. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +131 -0
  658. package/src/resources/extensions/gsd/tests/db-writer.test.ts +7 -12
  659. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +78 -5
  660. package/src/resources/extensions/gsd/tests/derive-state.test.ts +29 -0
  661. package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +47 -0
  662. package/src/resources/extensions/gsd/tests/discuss-empty-db-fallback.test.ts +127 -0
  663. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +40 -0
  664. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +20 -1
  665. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -0
  666. package/src/resources/extensions/gsd/tests/dynamic-routing-default.test.ts +20 -0
  667. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +74 -0
  668. package/src/resources/extensions/gsd/tests/event-replay-idempotency.test.ts +140 -0
  669. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +129 -0
  670. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +96 -0
  671. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +31 -0
  672. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +125 -12
  673. package/src/resources/extensions/gsd/tests/gsdroot-worktree-detection.test.ts +164 -0
  674. package/src/resources/extensions/gsd/tests/guided-flow-dynamic-routing.test.ts +135 -0
  675. package/src/resources/extensions/gsd/tests/guided-flow-session-isolation.test.ts +97 -0
  676. package/src/resources/extensions/gsd/tests/health-widget.test.ts +67 -0
  677. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +107 -0
  678. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +111 -1
  679. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +134 -0
  680. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +59 -0
  681. package/src/resources/extensions/gsd/tests/integration/doctor-false-positives.test.ts +243 -0
  682. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +72 -0
  683. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +68 -0
  684. package/src/resources/extensions/gsd/tests/integration/gitignore-staging-2570.test.ts +150 -0
  685. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +110 -0
  686. package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +1 -1
  687. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +959 -0
  688. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +85 -2
  689. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +105 -0
  690. package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +116 -0
  691. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +34 -0
  692. package/src/resources/extensions/gsd/tests/model-router.test.ts +68 -3
  693. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +28 -0
  694. package/src/resources/extensions/gsd/tests/notifications.test.ts +45 -0
  695. package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +159 -0
  696. package/src/resources/extensions/gsd/tests/parallel-eligibility-ghost.test.ts +150 -0
  697. package/src/resources/extensions/gsd/tests/plan-milestone-title.test.ts +70 -0
  698. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +33 -1
  699. package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +297 -0
  700. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +29 -0
  701. package/src/resources/extensions/gsd/tests/prompt-loader-replacement.test.ts +178 -0
  702. package/src/resources/extensions/gsd/tests/prompt-tool-names.test.ts +69 -0
  703. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +38 -0
  704. package/src/resources/extensions/gsd/tests/queue-execution-guard.test.ts +157 -0
  705. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +90 -0
  706. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +117 -0
  707. package/src/resources/extensions/gsd/tests/reconciliation-edge-cases.test.ts +162 -0
  708. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +97 -0
  709. package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +134 -0
  710. package/src/resources/extensions/gsd/tests/slice-disk-reconcile.test.ts +233 -0
  711. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +305 -0
  712. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +405 -0
  713. package/src/resources/extensions/gsd/tests/state-derivation-parity.test.ts +257 -0
  714. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +1628 -0
  715. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +106 -0
  716. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +174 -0
  717. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +221 -0
  718. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +44 -0
  719. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +2 -1
  720. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +8 -0
  721. package/src/resources/extensions/gsd/tests/uat-stuck-loop-orphaned-worktree.test.ts +289 -0
  722. package/src/resources/extensions/gsd/tests/unit-ownership.test.ts +100 -17
  723. package/src/resources/extensions/gsd/tests/vacuum-recovery.test.ts +154 -0
  724. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +4 -1
  725. package/src/resources/extensions/gsd/tests/verdict-parser.test.ts +156 -0
  726. package/src/resources/extensions/gsd/tests/verification-operational-gate.test.ts +82 -0
  727. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +48 -0
  728. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +92 -0
  729. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -2
  730. package/src/resources/extensions/gsd/tests/worktree-db-respawn-truncation.test.ts +140 -0
  731. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +101 -0
  732. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +48 -1
  733. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +29 -5
  734. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +95 -0
  735. package/src/resources/extensions/gsd/tools/complete-task.ts +36 -74
  736. package/src/resources/extensions/gsd/tools/plan-milestone.ts +13 -1
  737. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +36 -0
  738. package/src/resources/extensions/gsd/tools/validate-milestone.ts +20 -2
  739. package/src/resources/extensions/gsd/triage-resolution.ts +23 -6
  740. package/src/resources/extensions/gsd/types.ts +4 -2
  741. package/src/resources/extensions/gsd/undo.ts +2 -2
  742. package/src/resources/extensions/gsd/unit-ownership.ts +206 -35
  743. package/src/resources/extensions/gsd/verdict-parser.ts +21 -6
  744. package/src/resources/extensions/gsd/watch/header-renderer.ts +275 -0
  745. package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
  746. package/src/resources/extensions/gsd/workflow-manifest.ts +22 -5
  747. package/src/resources/extensions/gsd/workflow-projections.ts +97 -64
  748. package/src/resources/extensions/gsd/workflow-reconcile.ts +39 -10
  749. package/src/resources/extensions/gsd/workspace-index.ts +30 -0
  750. package/src/resources/extensions/gsd/worktree-manager.ts +120 -1
  751. package/src/resources/extensions/gsd/worktree-resolver.ts +22 -3
  752. package/src/resources/extensions/mcp-client/index.ts +13 -7
  753. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +55 -0
  754. package/src/resources/extensions/ollama/index.ts +130 -0
  755. package/src/resources/extensions/ollama/model-capabilities.ts +145 -0
  756. package/src/resources/extensions/ollama/ollama-client.ts +196 -0
  757. package/src/resources/extensions/ollama/ollama-commands.ts +248 -0
  758. package/src/resources/extensions/ollama/ollama-discovery.ts +106 -0
  759. package/src/resources/extensions/ollama/ollama-tool.ts +218 -0
  760. package/src/resources/extensions/ollama/tests/model-capabilities.test.ts +162 -0
  761. package/src/resources/extensions/ollama/tests/ollama-client.test.ts +38 -0
  762. package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +28 -0
  763. package/src/resources/extensions/ollama/types.ts +130 -0
  764. package/src/resources/extensions/search-the-web/extension-manifest.json +1 -1
  765. package/src/resources/extensions/search-the-web/url-utils.ts +19 -0
  766. package/src/resources/extensions/shared/interview-ui.ts +12 -1
  767. package/src/resources/extensions/shared/tests/ask-user-freetext.test.ts +156 -0
  768. package/src/resources/skills/create-gsd-extension/SKILL.md +5 -3
  769. package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +5 -4
  770. package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +2 -2
  771. package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +4 -4
  772. package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +5 -3
  773. package/dist/web/standalone/.next/static/chunks/6502.8b732f67a11b11b4.js +0 -9
  774. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +0 -1
  775. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +0 -79
  776. /package/dist/web/standalone/.next/static/{5DLsjFHdSB6_a1EDQVjr7 → nUA6d2OJrDSVq9RNb-c8b}/_buildManifest.js +0 -0
  777. /package/dist/web/standalone/.next/static/{5DLsjFHdSB6_a1EDQVjr7 → nUA6d2OJrDSVq9RNb-c8b}/_ssgManifest.js +0 -0
@@ -163,7 +163,30 @@ export function resolveModelId(modelId, availableModels, currentProvider) {
163
163
  return availableModels.find(m => m.id.toLowerCase() === lower
164
164
  || `${m.provider}/${m.id}`.toLowerCase() === lower);
165
165
  }
166
- // Bare ID — prefer current provider, then first available
167
- const exactProviderMatch = availableModels.find(m => m.id === modelId && m.provider === currentProvider);
168
- return exactProviderMatch ?? availableModels.find(m => m.id === modelId);
166
+ // Bare ID — resolve with provider precedence to avoid silent misrouting.
167
+ // Extension providers (e.g. claude-code) expose the same model IDs as their
168
+ // upstream API providers but route through a subprocess with different
169
+ // context, tool visibility, and cost characteristics (#2905). Bare IDs in
170
+ // PREFERENCES.md must resolve to the canonical API provider, not to an
171
+ // extension wrapper that happens to be the current session provider.
172
+ const candidates = availableModels.filter(m => m.id === modelId);
173
+ if (candidates.length === 0)
174
+ return undefined;
175
+ if (candidates.length === 1)
176
+ return candidates[0];
177
+ // Extension / CLI-wrapper providers that should never win bare-ID resolution
178
+ // when a first-class API provider also offers the same model.
179
+ const EXTENSION_PROVIDERS = new Set(["claude-code"]);
180
+ // Prefer currentProvider only when it is a first-class API provider
181
+ if (currentProvider && !EXTENSION_PROVIDERS.has(currentProvider)) {
182
+ const providerMatch = candidates.find(m => m.provider === currentProvider);
183
+ if (providerMatch)
184
+ return providerMatch;
185
+ }
186
+ // Prefer "anthropic" as the canonical provider for Anthropic models
187
+ const anthropicMatch = candidates.find(m => m.provider === "anthropic");
188
+ if (anthropicMatch)
189
+ return anthropicMatch;
190
+ // Fall back to first non-extension candidate, or any candidate
191
+ return candidates.find(m => !EXTENSION_PROVIDERS.has(m.provider)) ?? candidates[0];
169
192
  }
@@ -11,6 +11,7 @@
11
11
  * Extracted from handleAgentEnd() in auto.ts.
12
12
  */
13
13
  import { deriveState } from "./state.js";
14
+ import { logWarning, logError } from "./workflow-logger.js";
14
15
  import { loadFile, parseSummary, resolveAllOverrides } from "./files.js";
15
16
  import { loadPrompt } from "./prompt-loader.js";
16
17
  import { resolveSliceFile, resolveTaskFile, resolveMilestoneFile, resolveTasksDir, buildTaskFileName, } from "./paths.js";
@@ -319,18 +320,18 @@ export async function postUnitPreVerification(pctx, opts) {
319
320
  ctx.ui.notify(`Triage: ${triageResult.quickTasks.length} quick-task${triageResult.quickTasks.length === 1 ? "" : "s"} queued for execution.`, "info");
320
321
  }
321
322
  for (const action of triageResult.actions) {
322
- process.stderr.write(`gsd-triage: ${action}\n`);
323
+ logWarning("engine", `triage resolution: ${action}`);
323
324
  }
324
325
  }
325
326
  catch (err) {
326
- process.stderr.write(`gsd-triage: resolution execution failed: ${err.message}\n`);
327
+ logError("engine", "triage resolution failed", { error: err.message });
327
328
  }
328
329
  }
329
330
  // Rogue file detection — safety net for LLM bypassing completion tools (D003)
330
331
  try {
331
332
  const rogueFiles = detectRogueFileWrites(s.currentUnit.type, s.currentUnit.id, s.basePath);
332
333
  for (const rogue of rogueFiles) {
333
- process.stderr.write(`gsd-rogue: detected rogue file write: ${rogue.path} (unit: ${rogue.unitId})\n`);
334
+ logWarning("engine", "rogue file write detected", { path: rogue.path, unitId: rogue.unitId });
334
335
  ctx.ui.notify(`Rogue file write detected: ${rogue.path}`, "warning");
335
336
  }
336
337
  }
@@ -372,7 +373,18 @@ export async function postUnitPreVerification(pctx, opts) {
372
373
  // When artifact verification fails for a unit type that has a known expected
373
374
  // artifact, return "retry" so the caller re-dispatches with failure context
374
375
  // instead of blindly re-dispatching the same unit (#1571).
375
- if (!triggerArtifactVerified) {
376
+ //
377
+ // HOWEVER, if the DB is unavailable (db_unavailable), the artifact was never
378
+ // written because the completion tool failed at the infra level. Retrying
379
+ // can never succeed and produces a costly re-dispatch loop (#2517).
380
+ if (!triggerArtifactVerified && !isDbAvailable()) {
381
+ // DB infra failure — do NOT retry; the completion tool returned
382
+ // db_unavailable so the artifact was never written. Retrying would
383
+ // produce an infinite re-dispatch loop (#2517).
384
+ debugLog("postUnit", { phase: "artifact-verify-skip-db-unavailable", unitType: s.currentUnit.type, unitId: s.currentUnit.id });
385
+ ctx.ui.notify(`Artifact missing for ${s.currentUnit.type} ${s.currentUnit.id} but DB is unavailable — skipping retry to avoid loop (#2517)`, "error");
386
+ }
387
+ else if (!triggerArtifactVerified) {
376
388
  const hasExpectedArtifact = resolveExpectedArtifactPath(s.currentUnit.type, s.currentUnit.id, s.basePath) !== null;
377
389
  if (hasExpectedArtifact) {
378
390
  const retryKey = `${s.currentUnit.type}:${s.currentUnit.id}`;
@@ -1403,7 +1403,7 @@ export async function buildRunUatPrompt(mid, sliceId, uatPath, uatContent, base)
1403
1403
  if (projectInline)
1404
1404
  inlined.push(projectInline);
1405
1405
  const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`);
1406
- const uatResultPath = join(base, relSliceFile(base, mid, sliceId, "UAT"));
1406
+ const uatResultPath = join(base, relSliceFile(base, mid, sliceId, "ASSESSMENT"));
1407
1407
  const uatType = getUatType(uatContent);
1408
1408
  return loadPrompt("run-uat", {
1409
1409
  workingDirectory: base,
@@ -11,6 +11,7 @@ import { clearParseCache } from "./files.js";
11
11
  import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from "./parsers-legacy.js";
12
12
  import { isDbAvailable, getTask, getSlice, getSliceTasks, updateTaskStatus } from "./gsd-db.js";
13
13
  import { isValidationTerminal } from "./state.js";
14
+ import { getErrorMessage } from "./error-utils.js";
14
15
  import { nativeConflictFiles, nativeCommit, nativeCheckoutTheirs, nativeAddPaths, nativeMergeAbort, nativeResetHard, } from "./native-git-bridge.js";
15
16
  import { resolveSlicePath, resolveSliceFile, resolveTasksDir, resolveTaskFiles, relMilestoneFile, relSliceFile, buildSliceFileName, resolveMilestoneFile, clearPathCache, resolveGsdRootFile, } from "./paths.js";
16
17
  import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, } from "node:fs";
@@ -425,12 +426,19 @@ export function reconcileMergeState(basePath, ctx) {
425
426
  if (conflictedFiles.length === 0) {
426
427
  // All conflicts resolved — finalize the merge/squash commit
427
428
  try {
428
- nativeCommit(basePath, ""); // --no-edit equivalent: use empty message placeholder
429
- const mode = hasMergeHead ? "merge" : "squash commit";
430
- ctx.ui.notify(`Finalized leftover ${mode} from prior session.`, "info");
429
+ const commitSha = nativeCommit(basePath, ""); // --no-edit equivalent: use empty message placeholder
430
+ if (commitSha) {
431
+ const mode = hasMergeHead ? "merge" : "squash commit";
432
+ ctx.ui.notify(`Finalized leftover ${mode} from prior session.`, "info");
433
+ }
434
+ else {
435
+ ctx.ui.notify("No new commit needed for leftover merge/squash state — already committed.", "info");
436
+ }
431
437
  }
432
- catch {
433
- // Commit may already exist; non-fatal
438
+ catch (err) {
439
+ const errorMessage = getErrorMessage(err);
440
+ ctx.ui.notify(`Failed to finalize leftover merge/squash commit: ${errorMessage}`, "error");
441
+ return false;
434
442
  }
435
443
  }
436
444
  else {
@@ -30,15 +30,14 @@ import { initRoutingHistory } from "./routing-history.js";
30
30
  import { restoreHookState, resetHookState } from "./post-unit-hooks.js";
31
31
  import { resetProactiveHealing, setLevelChangeCallback } from "./doctor-proactive.js";
32
32
  import { snapshotSkills } from "./skill-discovery.js";
33
- import { isDbAvailable, getMilestone, openDatabase } from "./gsd-db.js";
33
+ import { isDbAvailable, getMilestone } from "./gsd-db.js";
34
34
  import { hideFooter } from "./auto-dashboard.js";
35
- import { resolveProjectRootDbPath } from "./bootstrap/dynamic-tools.js";
36
35
  import { debugLog, enableDebug, isDebugEnabled, getDebugLogPath, } from "./debug-logger.js";
37
36
  import { parseUnitId } from "./unit-id.js";
38
- import { setLogBasePath } from "./workflow-logger.js";
39
37
  import { existsSync, mkdirSync, readdirSync, statSync, unlinkSync, } from "node:fs";
40
38
  import { join } from "node:path";
41
39
  import { sep as pathSep } from "node:path";
40
+ import { resolveProjectRootDbPath } from "./bootstrap/dynamic-tools.js";
42
41
  /**
43
42
  * Bootstrap a fresh auto-mode session. Handles everything from git init
44
43
  * through secrets collection, returning when ready for the first
@@ -47,23 +46,33 @@ import { sep as pathSep } from "node:path";
47
46
  * Returns false if the bootstrap aborted (e.g., guided flow returned,
48
47
  * concurrent session detected). Returns true when ready to dispatch.
49
48
  */
50
- /** Guard: tracks consecutive bootstrap attempts that found phase === "complete".
51
- * Prevents the recursive dialog loop described in #1348 where
52
- * bootstrapAutoSession showSmartEntry checkAutoStartAfterDiscuss startAuto
53
- * cycles indefinitely when the discuss workflow doesn't produce a milestone. */
54
- let _consecutiveCompleteBootstraps = 0;
55
- const MAX_CONSECUTIVE_COMPLETE_BOOTSTRAPS = 2;
49
+ /**
50
+ * Open the project-root DB before the first deriveState call (#2841).
51
+ * When auto-mode starts cold (no prior DB handle), state derivation that
52
+ * touches DB-backed helpers (queue-order, task status) silently falls back
53
+ * to markdown-only data, producing stale or incomplete state. Opening the
54
+ * DB first ensures deriveState sees the full picture on its very first run.
55
+ */
56
56
  async function openProjectDbIfPresent(basePath) {
57
57
  const gsdDbPath = resolveProjectRootDbPath(basePath);
58
- if (!existsSync(gsdDbPath) || isDbAvailable())
58
+ if (!existsSync(gsdDbPath))
59
+ return;
60
+ if (isDbAvailable())
59
61
  return;
60
62
  try {
63
+ const { openDatabase } = await import("./gsd-db.js");
61
64
  openDatabase(gsdDbPath);
62
65
  }
63
- catch (err) {
64
- process.stderr.write(`gsd-db: failed to open existing database: ${err.message}\n`);
66
+ catch {
67
+ /* non-fatal DB lifecycle block below will retry */
65
68
  }
66
69
  }
70
+ /** Guard: tracks consecutive bootstrap attempts that found phase === "complete".
71
+ * Prevents the recursive dialog loop described in #1348 where
72
+ * bootstrapAutoSession → showSmartEntry → checkAutoStartAfterDiscuss → startAuto
73
+ * cycles indefinitely when the discuss workflow doesn't produce a milestone. */
74
+ let _consecutiveCompleteBootstraps = 0;
75
+ const MAX_CONSECUTIVE_COMPLETE_BOOTSTRAPS = 2;
67
76
  export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, requestedStepMode, deps) {
68
77
  const { shouldUseWorktreeIsolation, registerSigtermHandler, lockBase, buildResolver, } = deps;
69
78
  const lockResult = acquireSessionLock(base);
@@ -120,10 +129,13 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
120
129
  ensureGitignore(base, { manageGitignore });
121
130
  if (manageGitignore !== false)
122
131
  untrackRuntimeFiles(base);
123
- // Bootstrap .gsd/ if it doesn't exist
132
+ // Bootstrap milestones/ if it doesn't exist.
133
+ // Check milestones/ directly — ensureGsdSymlink above already created .gsd/,
134
+ // so checking .gsd/ existence would be dead code (#2942).
124
135
  const gsdDir = join(base, ".gsd");
125
- if (!existsSync(gsdDir)) {
126
- mkdirSync(join(gsdDir, "milestones"), { recursive: true });
136
+ const milestonesPath = join(gsdDir, "milestones");
137
+ if (!existsSync(milestonesPath)) {
138
+ mkdirSync(milestonesPath, { recursive: true });
127
139
  try {
128
140
  nativeAddAll(base);
129
141
  nativeCommit(base, "chore: init gsd");
@@ -178,13 +190,13 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
178
190
  });
179
191
  ctx.ui.notify(`Debug logging enabled → ${getDebugLogPath()}`, "info");
180
192
  }
181
- // Open the project DB before the first derive so resume uses DB truth
182
- // immediately on cold starts instead of falling back to markdown (#2841).
183
- await openProjectDbIfPresent(base);
184
193
  // Invalidate caches before initial state derivation
185
194
  invalidateAllCaches();
186
195
  // Clean stale runtime unit files for completed milestones (#887)
187
196
  cleanStaleRuntimeUnits(gsdRoot(base), (mid) => !!resolveMilestoneFile(base, mid, "SUMMARY"));
197
+ // Open the project-root DB before deriveState so DB-backed state
198
+ // derivation (queue-order, task status) works on a cold start (#2841).
199
+ await openProjectDbIfPresent(base);
188
200
  let state = await deriveState(base);
189
201
  // Stale worktree state recovery (#654)
190
202
  if (state.activeMilestone &&
@@ -336,7 +348,6 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
336
348
  s.verbose = verboseMode;
337
349
  s.cmdCtx = ctx;
338
350
  s.basePath = base;
339
- setLogBasePath(base);
340
351
  s.unitDispatchCount.clear();
341
352
  s.unitRecoveryCount.clear();
342
353
  s.lastBudgetAlertLevel = 0;
@@ -392,14 +403,15 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
392
403
  }
393
404
  }
394
405
  // ── DB lifecycle ──
395
- const gsdDbPath = resolveProjectRootDbPath(s.basePath);
406
+ const gsdDbPath = join(s.basePath, ".gsd", "gsd.db");
396
407
  const gsdDirPath = join(s.basePath, ".gsd");
397
408
  if (existsSync(gsdDirPath) && !existsSync(gsdDbPath)) {
398
409
  const hasDecisions = existsSync(join(gsdDirPath, "DECISIONS.md"));
399
410
  const hasRequirements = existsSync(join(gsdDirPath, "REQUIREMENTS.md"));
400
411
  const hasMilestones = existsSync(join(gsdDirPath, "milestones"));
401
412
  try {
402
- openDatabase(gsdDbPath);
413
+ const { openDatabase: openDb } = await import("./gsd-db.js");
414
+ openDb(gsdDbPath);
403
415
  if (hasDecisions || hasRequirements || hasMilestones) {
404
416
  const { migrateFromMarkdown } = await import("./md-importer.js");
405
417
  migrateFromMarkdown(s.basePath);
@@ -411,7 +423,8 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
411
423
  }
412
424
  if (existsSync(gsdDbPath) && !isDbAvailable()) {
413
425
  try {
414
- openDatabase(gsdDbPath);
426
+ const { openDatabase: openDb } = await import("./gsd-db.js");
427
+ openDb(gsdDbPath);
415
428
  }
416
429
  catch (err) {
417
430
  process.stderr.write(`gsd-db: failed to open existing database: ${err.message}\n`);
@@ -5,7 +5,7 @@
5
5
  * manual `/worktree` which uses `worktree/<name>` branches). This module
6
6
  * manages create, enter, detect, and teardown for auto-mode worktrees.
7
7
  */
8
- import { existsSync, cpSync, readFileSync, readdirSync, mkdirSync, realpathSync, rmSync, unlinkSync, lstatSync as lstatSyncFn, } from "node:fs";
8
+ import { existsSync, cpSync, readFileSync, readdirSync, mkdirSync, realpathSync, rmSync, unlinkSync, statSync, lstatSync as lstatSyncFn, } from "node:fs";
9
9
  import { isAbsolute, join, sep as pathSep } from "node:path";
10
10
  import { homedir } from "node:os";
11
11
  import { GSDError, GSD_IO_ERROR, GSD_GIT_ERROR } from "./errors.js";
@@ -20,7 +20,7 @@ import { MergeConflictError, readIntegrationBranch, RUNTIME_EXCLUSION_PATHS } fr
20
20
  import { debugLog } from "./debug-logger.js";
21
21
  import { logWarning } from "./workflow-logger.js";
22
22
  import { loadEffectiveGSDPreferences } from "./preferences.js";
23
- import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeWorkingTreeStatus, nativeAddAllWithExclusions, nativeCommit, nativeCheckoutBranch, nativeMergeSquash, nativeConflictFiles, nativeCheckoutTheirs, nativeAddPaths, nativeRmForce, nativeBranchDelete, nativeBranchExists, nativeDiffNumstat, nativeUpdateRef, nativeIsAncestor, } from "./native-git-bridge.js";
23
+ import { nativeGetCurrentBranch, nativeDetectMainBranch, nativeWorkingTreeStatus, nativeAddAllWithExclusions, nativeCommit, nativeCheckoutBranch, nativeMergeSquash, nativeConflictFiles, nativeCheckoutTheirs, nativeAddPaths, nativeRmForce, nativeBranchDelete, nativeBranchExists, nativeDiffNumstat, nativeUpdateRef, nativeIsAncestor, nativeMergeAbort, } from "./native-git-bridge.js";
24
24
  const gsdHome = process.env.GSD_HOME || join(homedir(), ".gsd");
25
25
  const PROJECT_PREFERENCES_FILE = "PREFERENCES.md";
26
26
  const LEGACY_PROJECT_PREFERENCES_FILE = "preferences.md";
@@ -39,6 +39,7 @@ const ROOT_STATE_FILES = [
39
39
  "QUEUE.md",
40
40
  "completed-units.json",
41
41
  "metrics.json",
42
+ "mcp.json",
42
43
  // NOTE: project preferences are intentionally NOT in ROOT_STATE_FILES.
43
44
  // Forward-sync (main → worktree) is handled explicitly in syncGsdStateToWorktree().
44
45
  // Back-sync (worktree → main) must NEVER overwrite the project root's copy
@@ -56,6 +57,65 @@ function isSamePath(a, b) {
56
57
  return false;
57
58
  }
58
59
  }
60
+ // ─── ASSESSMENT Force-Sync Helper (#2821) ─────────────────────────────────
61
+ /** Regex matching YAML frontmatter `verdict:` field. */
62
+ const VERDICT_RE = /verdict:\s*[\w-]+/i;
63
+ /**
64
+ * Walk a milestone directory and force-overwrite ASSESSMENT files in the
65
+ * destination when the source copy contains a `verdict:` field.
66
+ *
67
+ * This is the targeted fix for the UAT stuck-loop (#2821): the main
68
+ * safeCopyRecursive uses force:false to protect worktree-authoritative
69
+ * files (#1886), but ASSESSMENT files written by run-uat must be
70
+ * forward-synced when the project root has a verdict. Without this,
71
+ * the worktree retains a stale FAIL or missing ASSESSMENT and
72
+ * checkNeedsRunUat re-dispatches run-uat indefinitely.
73
+ *
74
+ * Only overwrites when the source has a verdict — never clobbers a
75
+ * worktree ASSESSMENT with a verdictless project-root copy.
76
+ */
77
+ function forceOverwriteAssessmentsWithVerdict(srcMilestoneDir, dstMilestoneDir) {
78
+ if (!existsSync(srcMilestoneDir))
79
+ return;
80
+ // Walk slices/<SID>/ looking for *-ASSESSMENT.md files
81
+ const slicesDir = join(srcMilestoneDir, "slices");
82
+ if (!existsSync(slicesDir))
83
+ return;
84
+ try {
85
+ for (const sliceEntry of readdirSync(slicesDir, { withFileTypes: true })) {
86
+ if (!sliceEntry.isDirectory())
87
+ continue;
88
+ const srcSliceDir = join(slicesDir, sliceEntry.name);
89
+ const dstSliceDir = join(dstMilestoneDir, "slices", sliceEntry.name);
90
+ try {
91
+ for (const fileEntry of readdirSync(srcSliceDir, { withFileTypes: true })) {
92
+ if (!fileEntry.isFile())
93
+ continue;
94
+ if (!fileEntry.name.endsWith("-ASSESSMENT.md"))
95
+ continue;
96
+ const srcFile = join(srcSliceDir, fileEntry.name);
97
+ try {
98
+ const srcContent = readFileSync(srcFile, "utf-8");
99
+ if (!VERDICT_RE.test(srcContent))
100
+ continue; // no verdict in source — skip
101
+ // Source has a verdict — force-copy into worktree
102
+ mkdirSync(dstSliceDir, { recursive: true });
103
+ safeCopy(srcFile, join(dstSliceDir, fileEntry.name), { force: true });
104
+ }
105
+ catch {
106
+ /* non-fatal per file */
107
+ }
108
+ }
109
+ }
110
+ catch {
111
+ /* non-fatal per slice */
112
+ }
113
+ }
114
+ }
115
+ catch {
116
+ /* non-fatal */
117
+ }
118
+ }
59
119
  // ─── Module State ──────────────────────────────────────────────────────────
60
120
  /** Original project root before chdir into auto-worktree. */
61
121
  let originalBase = null;
@@ -147,16 +207,31 @@ export function syncProjectRootToWorktree(projectRoot, worktreePath_, milestoneI
147
207
  // by validate-milestone) get clobbered by stale project root copies,
148
208
  // causing an infinite re-validation loop (#1886).
149
209
  safeCopyRecursive(join(prGsd, "milestones", milestoneId), join(wtGsd, "milestones", milestoneId), { force: false });
210
+ // Force-sync ASSESSMENT files that have a verdict from project root (#2821).
211
+ // The additive-only copy above preserves worktree-authoritative files, but
212
+ // ASSESSMENT files are special: after run-uat writes a verdict and post-unit
213
+ // syncs it to the project root, the worktree may retain a stale copy (e.g.
214
+ // verdict:fail while the project root has verdict:pass from a retry). On
215
+ // session resume the DB is rebuilt from disk, and if the stale ASSESSMENT
216
+ // persists, checkNeedsRunUat finds no passing verdict → re-dispatches
217
+ // run-uat indefinitely (stuck-loop ×9).
218
+ forceOverwriteAssessmentsWithVerdict(join(prGsd, "milestones", milestoneId), join(wtGsd, "milestones", milestoneId));
150
219
  // Forward-sync completed-units.json from project root to worktree.
151
220
  // Project root is authoritative for completion state after crash recovery;
152
221
  // without this, the worktree re-dispatches already-completed units (#1886).
153
222
  safeCopy(join(prGsd, "completed-units.json"), join(wtGsd, "completed-units.json"), { force: true });
154
- // Delete worktree gsd.db so it rebuilds from the freshly synced files.
155
- // Stale DB rows are the root cause of the infinite skip loop (#853).
223
+ // Delete worktree gsd.db ONLY if it is empty (0 bytes).
224
+ // An empty DB is stale/corrupt and should be rebuilt (#853).
225
+ // A non-empty DB was populated by gsd-migrate on respawn and must be
226
+ // preserved — deleting it truncates the file to 0 bytes when
227
+ // openDatabase re-creates it, causing "no such table" failures (#2815).
156
228
  try {
157
229
  const wtDb = join(wtGsd, "gsd.db");
158
230
  if (existsSync(wtDb)) {
159
- unlinkSync(wtDb);
231
+ const size = statSync(wtDb).size;
232
+ if (size === 0) {
233
+ unlinkSync(wtDb);
234
+ }
160
235
  }
161
236
  }
162
237
  catch {
@@ -855,6 +930,7 @@ function copyPlanningArtifacts(srcBase, wtPath) {
855
930
  "STATE.md",
856
931
  "KNOWLEDGE.md",
857
932
  "OVERRIDES.md",
933
+ "mcp.json",
858
934
  ]) {
859
935
  safeCopy(join(srcGsd, file), join(dstGsd, file), { force: true });
860
936
  }
@@ -1195,7 +1271,17 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1195
1271
  encoding: "utf-8",
1196
1272
  }).trim();
1197
1273
  if (status) {
1198
- execFileSync("git", ["stash", "push", "--include-untracked", "-m", `gsd: pre-merge stash for ${milestoneId}`], { cwd: originalBasePath_, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" });
1274
+ // Use --include-untracked to stash untracked files that would block
1275
+ // the squash merge, but EXCLUDE .gsd/milestones/ (#2505).
1276
+ // --include-untracked without exclusion sweeps queued milestone
1277
+ // CONTEXT files into the stash. If stash pop later fails, those files
1278
+ // are permanently trapped in the stash entry and lost on the next
1279
+ // stash push or drop.
1280
+ execFileSync("git", [
1281
+ "stash", "push", "--include-untracked",
1282
+ "-m", `gsd: pre-merge stash for ${milestoneId}`,
1283
+ "--", ":(exclude).gsd/milestones",
1284
+ ], { cwd: originalBasePath_, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" });
1199
1285
  stashed = true;
1200
1286
  }
1201
1287
  }
@@ -1203,6 +1289,72 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1203
1289
  // Stash failure is non-fatal — proceed without stash and let the merge
1204
1290
  // report the dirty tree if it fails.
1205
1291
  }
1292
+ // 7a. Shelter queued milestone directories before the squash merge (#2505).
1293
+ // The milestone branch may contain copies of queued milestone dirs (via
1294
+ // copyPlanningArtifacts), so `git merge --squash` rejects when those same
1295
+ // files exist as untracked in the working tree. Temporarily move them to
1296
+ // a backup location, then restore after the merge+commit.
1297
+ const milestonesDir = join(gsdRoot(originalBasePath_), "milestones");
1298
+ const shelterDir = join(gsdRoot(originalBasePath_), ".milestone-shelter");
1299
+ const shelteredDirs = [];
1300
+ // Helper: restore sheltered milestone directories (#2505).
1301
+ // Called on both success and error paths to ensure queued CONTEXT files
1302
+ // are never permanently lost.
1303
+ const restoreShelter = () => {
1304
+ if (shelteredDirs.length === 0)
1305
+ return;
1306
+ for (const dirName of shelteredDirs) {
1307
+ try {
1308
+ mkdirSync(milestonesDir, { recursive: true });
1309
+ cpSync(join(shelterDir, dirName), join(milestonesDir, dirName), { recursive: true, force: true });
1310
+ }
1311
+ catch { /* best-effort */ }
1312
+ }
1313
+ try {
1314
+ rmSync(shelterDir, { recursive: true, force: true });
1315
+ }
1316
+ catch { /* best-effort */ }
1317
+ };
1318
+ try {
1319
+ if (existsSync(milestonesDir)) {
1320
+ const entries = readdirSync(milestonesDir, { withFileTypes: true });
1321
+ for (const entry of entries) {
1322
+ if (!entry.isDirectory())
1323
+ continue;
1324
+ // Only shelter directories that do NOT belong to the milestone being merged
1325
+ if (entry.name === milestoneId)
1326
+ continue;
1327
+ const srcDir = join(milestonesDir, entry.name);
1328
+ const dstDir = join(shelterDir, entry.name);
1329
+ try {
1330
+ mkdirSync(shelterDir, { recursive: true });
1331
+ cpSync(srcDir, dstDir, { recursive: true, force: true });
1332
+ rmSync(srcDir, { recursive: true, force: true });
1333
+ shelteredDirs.push(entry.name);
1334
+ }
1335
+ catch {
1336
+ // Non-fatal — if shelter fails, the merge may still succeed
1337
+ }
1338
+ }
1339
+ }
1340
+ }
1341
+ catch {
1342
+ // Non-fatal — proceed with merge; untracked files may block it
1343
+ }
1344
+ // 7b. Clean up stale merge state before attempting squash merge (#2912).
1345
+ // A leftover MERGE_HEAD (from a previous failed merge, libgit2 native path,
1346
+ // or interrupted operation) causes `git merge --squash` to refuse with
1347
+ // "fatal: You have not concluded your merge (MERGE_HEAD exists)".
1348
+ // Defensively remove merge artifacts before starting.
1349
+ try {
1350
+ const gitDir_ = resolveGitDir(originalBasePath_);
1351
+ for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
1352
+ const p = join(gitDir_, f);
1353
+ if (existsSync(p))
1354
+ unlinkSync(p);
1355
+ }
1356
+ }
1357
+ catch { /* best-effort */ }
1206
1358
  // 8. Squash merge — auto-resolve .gsd/ state file conflicts (#530)
1207
1359
  const mergeResult = nativeMergeSquash(originalBasePath_, milestoneBranch);
1208
1360
  if (!mergeResult.success) {
@@ -1210,6 +1362,17 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1210
1362
  // untracked .gsd/ files left by syncStateToProjectRoot). Preserve the
1211
1363
  // milestone branch so commits are not lost.
1212
1364
  if (mergeResult.conflicts.includes("__dirty_working_tree__")) {
1365
+ // Defensively clean merge state — the native path may leave MERGE_HEAD
1366
+ // even when the merge is rejected (#2912).
1367
+ try {
1368
+ const gitDir_ = resolveGitDir(originalBasePath_);
1369
+ for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
1370
+ const p = join(gitDir_, f);
1371
+ if (existsSync(p))
1372
+ unlinkSync(p);
1373
+ }
1374
+ }
1375
+ catch { /* best-effort */ }
1213
1376
  // Pop stash before throwing so local work is not lost.
1214
1377
  if (stashed) {
1215
1378
  try {
@@ -1221,6 +1384,7 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1221
1384
  }
1222
1385
  catch { /* stash pop conflict is non-fatal */ }
1223
1386
  }
1387
+ restoreShelter();
1224
1388
  // Restore cwd so the caller is not stranded on the integration branch
1225
1389
  process.chdir(previousCwd);
1226
1390
  // Surface the actual dirty filenames from git stderr instead of
@@ -1258,6 +1422,22 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1258
1422
  }
1259
1423
  // If there are still real code conflicts, escalate
1260
1424
  if (codeConflicts.length > 0) {
1425
+ // Abort merge state so MERGE_HEAD is not left on disk (#2912).
1426
+ // libgit2's merge creates MERGE_HEAD even for squash merges; if left
1427
+ // dangling, subsequent merges fail and doctor reports corrupt state.
1428
+ try {
1429
+ nativeMergeAbort(originalBasePath_);
1430
+ }
1431
+ catch { /* best-effort */ }
1432
+ try {
1433
+ const gitDir_ = resolveGitDir(originalBasePath_);
1434
+ for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
1435
+ const p = join(gitDir_, f);
1436
+ if (existsSync(p))
1437
+ unlinkSync(p);
1438
+ }
1439
+ }
1440
+ catch { /* best-effort */ }
1261
1441
  // Pop stash before throwing so local work is not lost (#2151).
1262
1442
  if (stashed) {
1263
1443
  try {
@@ -1269,6 +1449,7 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1269
1449
  }
1270
1450
  catch { /* stash pop conflict is non-fatal */ }
1271
1451
  }
1452
+ restoreShelter();
1272
1453
  throw new MergeConflictError(codeConflicts, "squash", milestoneBranch, mainBranch);
1273
1454
  }
1274
1455
  }
@@ -1277,15 +1458,19 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1277
1458
  // 9. Commit (handle nothing-to-commit gracefully)
1278
1459
  const commitResult = nativeCommit(originalBasePath_, commitMessage);
1279
1460
  const nothingToCommit = commitResult === null;
1280
- // 9a. Clean up SQUASH_MSG left by git merge --squash (#1853).
1461
+ // 9a. Clean up merge state files left by git merge --squash (#1853, #2912).
1281
1462
  // git only removes SQUASH_MSG when the commit reads it directly (plain
1282
1463
  // `git commit`). nativeCommit uses `-F -` (stdin) or libgit2, neither
1283
- // of which trigger git's SQUASH_MSG cleanup. If left on disk, doctor
1284
- // reports `corrupt_merge_state` on every subsequent run.
1464
+ // of which trigger git's SQUASH_MSG cleanup. MERGE_HEAD is created by
1465
+ // libgit2's merge even in squash mode and is not removed by nativeCommit.
1466
+ // If left on disk, doctor reports `corrupt_merge_state` on every subsequent run.
1285
1467
  try {
1286
- const squashMsgPath = join(resolveGitDir(originalBasePath_), "SQUASH_MSG");
1287
- if (existsSync(squashMsgPath))
1288
- unlinkSync(squashMsgPath);
1468
+ const gitDir_ = resolveGitDir(originalBasePath_);
1469
+ for (const f of ["SQUASH_MSG", "MERGE_MSG", "MERGE_HEAD"]) {
1470
+ const p = join(gitDir_, f);
1471
+ if (existsSync(p))
1472
+ unlinkSync(p);
1473
+ }
1289
1474
  }
1290
1475
  catch { /* best-effort */ }
1291
1476
  // 9a-ii. Restore stashed files now that the merge+commit is complete (#2151).
@@ -1345,6 +1530,8 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
1345
1530
  }
1346
1531
  }
1347
1532
  }
1533
+ // 9a-iii. Restore sheltered queued milestone directories (#2505).
1534
+ restoreShelter();
1348
1535
  // 9b. Safety check (#1792): if nothing was committed, verify the milestone
1349
1536
  // work is already on the integration branch before allowing teardown.
1350
1537
  // Compare only non-.gsd/ paths — .gsd/ state files diverge normally and
@@ -48,6 +48,30 @@ export async function handleAgentEnd(pi, event, ctx) {
48
48
  return;
49
49
  const lastMsg = event.messages[event.messages.length - 1];
50
50
  if (lastMsg && "stopReason" in lastMsg && lastMsg.stopReason === "aborted") {
51
+ // Empty content with aborted stopReason is a non-fatal agent stop (the LLM
52
+ // chose to end without producing output). Only pause on genuine fatal aborts
53
+ // that carry error context — e.g. errorMessage field or non-empty content
54
+ // indicating a mid-stream failure. (#2695)
55
+ const content = "content" in lastMsg ? lastMsg.content : undefined;
56
+ const hasEmptyContent = Array.isArray(content) && content.length === 0;
57
+ const hasErrorMessage = "errorMessage" in lastMsg && !!lastMsg.errorMessage;
58
+ if (hasEmptyContent && !hasErrorMessage) {
59
+ // Non-fatal: treat as a normal agent end so the loop can continue
60
+ // instead of entering a stuck re-dispatch cycle.
61
+ try {
62
+ resetRetryState(retryState);
63
+ resolveAgentEnd(event);
64
+ }
65
+ catch (err) {
66
+ const message = err instanceof Error ? err.message : String(err);
67
+ ctx.ui.notify(`Auto-mode error after empty-content abort: ${message}. Stopping auto-mode.`, "error");
68
+ try {
69
+ await pauseAuto(ctx, pi);
70
+ }
71
+ catch { /* best-effort */ }
72
+ }
73
+ return;
74
+ }
51
75
  await pauseAuto(ctx, pi);
52
76
  return;
53
77
  }
@@ -57,6 +81,14 @@ export async function handleAgentEnd(pi, event, ctx) {
57
81
  const explicitRetryAfterMs = ("retryAfterMs" in lastMsg && typeof lastMsg.retryAfterMs === "number") ? lastMsg.retryAfterMs : undefined;
58
82
  // ── 1. Classify ──────────────────────────────────────────────────────
59
83
  const cls = classifyError(errorMsg, explicitRetryAfterMs);
84
+ // Cap rate-limit backoff for CLI-style providers (openai-codex, google-gemini-cli)
85
+ // which use per-user quotas with shorter windows (#2922).
86
+ if (cls.kind === "rate-limit") {
87
+ const currentProvider = ctx.model?.provider;
88
+ if (currentProvider === "openai-codex" || currentProvider === "google-gemini-cli") {
89
+ cls.retryAfterMs = Math.min(cls.retryAfterMs, 30_000);
90
+ }
91
+ }
60
92
  // ── 2. Decide & Act ──────────────────────────────────────────────────
61
93
  // --- Network errors: same-model retry with backoff ---
62
94
  if (cls.kind === "network") {