gsd-pi 2.34.0 → 2.35.0-dev.30eec3f

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 (500) hide show
  1. package/dist/cli.js +7 -2
  2. package/dist/resource-loader.d.ts +1 -1
  3. package/dist/resource-loader.js +13 -1
  4. package/dist/resources/extensions/async-jobs/await-tool.js +0 -2
  5. package/dist/resources/extensions/async-jobs/job-manager.js +0 -6
  6. package/dist/resources/extensions/bg-shell/output-formatter.js +1 -19
  7. package/dist/resources/extensions/bg-shell/process-manager.js +0 -4
  8. package/dist/resources/extensions/bg-shell/types.js +0 -2
  9. package/dist/resources/extensions/context7/index.js +5 -0
  10. package/dist/resources/extensions/get-secrets-from-user.js +2 -30
  11. package/dist/resources/extensions/google-search/index.js +5 -0
  12. package/dist/resources/extensions/gsd/auto-dispatch.js +43 -1
  13. package/dist/resources/extensions/gsd/auto-loop.js +10 -1
  14. package/dist/resources/extensions/gsd/auto-recovery.js +35 -0
  15. package/dist/resources/extensions/gsd/auto-start.js +35 -2
  16. package/dist/resources/extensions/gsd/auto.js +59 -4
  17. package/dist/resources/extensions/gsd/changelog.js +162 -0
  18. package/dist/resources/extensions/gsd/commands-bootstrap.js +1 -0
  19. package/dist/resources/extensions/gsd/commands-handlers.js +2 -2
  20. package/dist/resources/extensions/gsd/commands-inspect.js +10 -3
  21. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +5 -1
  22. package/dist/resources/extensions/gsd/commands.js +8 -1
  23. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  24. package/dist/resources/extensions/gsd/doctor-checks.js +113 -5
  25. package/dist/resources/extensions/gsd/doctor-environment.js +26 -17
  26. package/dist/resources/extensions/gsd/doctor-proactive.js +22 -0
  27. package/dist/resources/extensions/gsd/doctor.js +36 -0
  28. package/dist/resources/extensions/gsd/files.js +11 -2
  29. package/dist/resources/extensions/gsd/gitignore.js +54 -7
  30. package/dist/resources/extensions/gsd/guided-flow.js +5 -3
  31. package/dist/resources/extensions/gsd/health-widget-core.js +96 -0
  32. package/dist/resources/extensions/gsd/health-widget.js +97 -46
  33. package/dist/resources/extensions/gsd/index.js +10 -1
  34. package/dist/resources/extensions/gsd/migrate-external.js +55 -2
  35. package/dist/resources/extensions/gsd/paths.js +74 -7
  36. package/dist/resources/extensions/gsd/post-unit-hooks.js +4 -1
  37. package/dist/resources/extensions/gsd/preferences-validation.js +54 -1
  38. package/dist/resources/extensions/gsd/preferences.js +2 -0
  39. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  40. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  41. package/dist/resources/extensions/gsd/roadmap-mutations.js +55 -0
  42. package/dist/resources/extensions/gsd/session-lock.js +26 -2
  43. package/dist/resources/extensions/gsd/templates/plan.md +8 -0
  44. package/dist/resources/extensions/gsd/worktree-resolver.js +12 -0
  45. package/dist/resources/extensions/mcp-client/index.js +2 -1
  46. package/dist/resources/extensions/remote-questions/remote-command.js +2 -22
  47. package/dist/resources/extensions/shared/mod.js +1 -1
  48. package/dist/resources/extensions/shared/sanitize.js +30 -0
  49. package/dist/resources/extensions/subagent/index.js +6 -14
  50. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
  51. package/package.json +2 -1
  52. package/packages/native/dist/native.d.ts +0 -2
  53. package/packages/native/dist/native.js +0 -2
  54. package/packages/native/src/native.ts +0 -3
  55. package/packages/pi-agent-core/dist/agent-loop.d.ts +14 -0
  56. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  57. package/packages/pi-agent-core/dist/agent-loop.js +24 -27
  58. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  59. package/packages/pi-agent-core/dist/agent.d.ts +1 -0
  60. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  61. package/packages/pi-agent-core/dist/agent.js +11 -22
  62. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  63. package/packages/pi-agent-core/dist/proxy.d.ts +1 -25
  64. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  65. package/packages/pi-agent-core/dist/proxy.js +3 -9
  66. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  67. package/packages/pi-agent-core/src/agent-loop.ts +30 -27
  68. package/packages/pi-agent-core/src/agent.ts +12 -23
  69. package/packages/pi-agent-core/src/proxy.ts +3 -9
  70. package/packages/pi-ai/dist/api-registry.d.ts +0 -2
  71. package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
  72. package/packages/pi-ai/dist/api-registry.js +0 -10
  73. package/packages/pi-ai/dist/api-registry.js.map +1 -1
  74. package/packages/pi-ai/dist/providers/anthropic.d.ts +0 -8
  75. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  76. package/packages/pi-ai/dist/providers/anthropic.js +1 -1
  77. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  78. package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  79. package/packages/pi-ai/dist/providers/azure-openai-responses.js +5 -41
  80. package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  81. package/packages/pi-ai/dist/providers/github-copilot-headers.d.ts +0 -1
  82. package/packages/pi-ai/dist/providers/github-copilot-headers.d.ts.map +1 -1
  83. package/packages/pi-ai/dist/providers/github-copilot-headers.js +1 -1
  84. package/packages/pi-ai/dist/providers/github-copilot-headers.js.map +1 -1
  85. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts +1 -43
  86. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  87. package/packages/pi-ai/dist/providers/google-gemini-cli.js +2 -2
  88. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  89. package/packages/pi-ai/dist/providers/google-shared.d.ts +0 -4
  90. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  91. package/packages/pi-ai/dist/providers/google-shared.js +1 -1
  92. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  93. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  94. package/packages/pi-ai/dist/providers/openai-completions.js +10 -73
  95. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  96. package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  97. package/packages/pi-ai/dist/providers/openai-responses.js +9 -80
  98. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  99. package/packages/pi-ai/dist/providers/openai-shared.d.ts +65 -0
  100. package/packages/pi-ai/dist/providers/openai-shared.d.ts.map +1 -0
  101. package/packages/pi-ai/dist/providers/openai-shared.js +146 -0
  102. package/packages/pi-ai/dist/providers/openai-shared.js.map +1 -0
  103. package/packages/pi-ai/dist/providers/register-builtins.d.ts +0 -1
  104. package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
  105. package/packages/pi-ai/dist/providers/register-builtins.js +1 -1
  106. package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
  107. package/packages/pi-ai/dist/utils/event-stream.d.ts +0 -2
  108. package/packages/pi-ai/dist/utils/event-stream.d.ts.map +1 -1
  109. package/packages/pi-ai/dist/utils/event-stream.js +0 -4
  110. package/packages/pi-ai/dist/utils/event-stream.js.map +1 -1
  111. package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
  112. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +7 -135
  113. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
  114. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
  115. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +7 -135
  116. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
  117. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts +46 -0
  118. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts.map +1 -0
  119. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js +160 -0
  120. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js.map +1 -0
  121. package/packages/pi-ai/dist/utils/overflow.d.ts +0 -4
  122. package/packages/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  123. package/packages/pi-ai/dist/utils/overflow.js +0 -6
  124. package/packages/pi-ai/dist/utils/overflow.js.map +1 -1
  125. package/packages/pi-ai/dist/utils/validation.d.ts +0 -8
  126. package/packages/pi-ai/dist/utils/validation.d.ts.map +1 -1
  127. package/packages/pi-ai/dist/utils/validation.js +0 -14
  128. package/packages/pi-ai/dist/utils/validation.js.map +1 -1
  129. package/packages/pi-ai/src/api-registry.ts +0 -12
  130. package/packages/pi-ai/src/providers/anthropic.ts +1 -1
  131. package/packages/pi-ai/src/providers/azure-openai-responses.ts +11 -45
  132. package/packages/pi-ai/src/providers/github-copilot-headers.ts +1 -1
  133. package/packages/pi-ai/src/providers/google-gemini-cli.ts +2 -2
  134. package/packages/pi-ai/src/providers/google-shared.ts +1 -1
  135. package/packages/pi-ai/src/providers/openai-completions.ts +16 -86
  136. package/packages/pi-ai/src/providers/openai-responses.ts +16 -96
  137. package/packages/pi-ai/src/providers/openai-shared.ts +193 -0
  138. package/packages/pi-ai/src/providers/register-builtins.ts +1 -1
  139. package/packages/pi-ai/src/utils/event-stream.ts +0 -5
  140. package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +14 -162
  141. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +13 -161
  142. package/packages/pi-ai/src/utils/oauth/google-oauth-utils.ts +201 -0
  143. package/packages/pi-ai/src/utils/overflow.ts +1 -8
  144. package/packages/pi-ai/src/utils/validation.ts +0 -15
  145. package/packages/pi-coding-agent/dist/config.d.ts +0 -9
  146. package/packages/pi-coding-agent/dist/config.d.ts.map +1 -1
  147. package/packages/pi-coding-agent/dist/config.js +4 -8
  148. package/packages/pi-coding-agent/dist/config.js.map +1 -1
  149. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +16 -63
  150. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  151. package/packages/pi-coding-agent/dist/core/agent-session.js +104 -641
  152. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  153. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +0 -1
  154. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  155. package/packages/pi-coding-agent/dist/core/auth-storage.js +4 -35
  156. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  157. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  158. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js +5 -43
  159. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
  160. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  161. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +11 -69
  162. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  163. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +40 -0
  164. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
  165. package/packages/pi-coding-agent/dist/core/compaction/utils.js +78 -0
  166. package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
  167. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +77 -0
  168. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -0
  169. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +331 -0
  170. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -0
  171. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.d.ts +0 -4
  172. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  173. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.js +1 -1
  174. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.js.map +1 -1
  175. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +2 -2
  176. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  177. package/packages/pi-coding-agent/dist/core/extensions/index.js +1 -1
  178. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  179. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +15 -5
  180. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  181. package/packages/pi-coding-agent/dist/core/extensions/runner.js +129 -256
  182. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  183. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +49 -42
  184. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  185. package/packages/pi-coding-agent/dist/core/extensions/types.js +2 -21
  186. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  187. package/packages/pi-coding-agent/dist/core/keybindings.d.ts +0 -8
  188. package/packages/pi-coding-agent/dist/core/keybindings.d.ts.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/keybindings.js +2 -2
  190. package/packages/pi-coding-agent/dist/core/keybindings.js.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/lock-utils.d.ts +39 -0
  192. package/packages/pi-coding-agent/dist/core/lock-utils.d.ts.map +1 -0
  193. package/packages/pi-coding-agent/dist/core/lock-utils.js +89 -0
  194. package/packages/pi-coding-agent/dist/core/lock-utils.js.map +1 -0
  195. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts +0 -17
  196. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  197. package/packages/pi-coding-agent/dist/core/lsp/client.js +3 -62
  198. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  199. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts +1 -1
  200. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -1
  201. package/packages/pi-coding-agent/dist/core/lsp/config.js +2 -6
  202. package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -1
  203. package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts +0 -5
  204. package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts.map +1 -1
  205. package/packages/pi-coding-agent/dist/core/lsp/edits.js +1 -1
  206. package/packages/pi-coding-agent/dist/core/lsp/edits.js.map +1 -1
  207. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  208. package/packages/pi-coding-agent/dist/core/lsp/index.js +52 -107
  209. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  210. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts +0 -1
  211. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  212. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -22
  213. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  214. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts +0 -1
  215. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts.map +1 -1
  216. package/packages/pi-coding-agent/dist/core/lsp/types.js +0 -28
  217. package/packages/pi-coding-agent/dist/core/lsp/types.js.map +1 -1
  218. package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts +1 -6
  219. package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts.map +1 -1
  220. package/packages/pi-coding-agent/dist/core/lsp/utils.js +1 -28
  221. package/packages/pi-coding-agent/dist/core/lsp/utils.js.map +1 -1
  222. package/packages/pi-coding-agent/dist/core/messages.d.ts +0 -8
  223. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  224. package/packages/pi-coding-agent/dist/core/messages.js +5 -5
  225. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  226. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +0 -3
  227. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  228. package/packages/pi-coding-agent/dist/core/model-registry.js +1 -3
  229. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  230. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts +1 -26
  231. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  232. package/packages/pi-coding-agent/dist/core/model-resolver.js +3 -59
  233. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  234. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  235. package/packages/pi-coding-agent/dist/core/package-manager.js +2 -4
  236. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  237. package/packages/pi-coding-agent/dist/core/prompt-templates.d.ts +0 -17
  238. package/packages/pi-coding-agent/dist/core/prompt-templates.d.ts.map +1 -1
  239. package/packages/pi-coding-agent/dist/core/prompt-templates.js +2 -2
  240. package/packages/pi-coding-agent/dist/core/prompt-templates.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +2 -4
  242. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  243. package/packages/pi-coding-agent/dist/core/resource-loader.js +46 -60
  244. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  245. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +87 -0
  246. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -0
  247. package/packages/pi-coding-agent/dist/core/retry-handler.js +295 -0
  248. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -0
  249. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +0 -5
  250. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  251. package/packages/pi-coding-agent/dist/core/session-manager.js +5 -32
  252. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  253. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +8 -12
  254. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  255. package/packages/pi-coding-agent/dist/core/settings-manager.js +78 -168
  256. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  257. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/core/skills.js +1 -3
  259. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  260. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  261. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  262. package/packages/pi-coding-agent/dist/index.js +1 -1
  263. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  264. package/packages/pi-coding-agent/dist/migrations.d.ts +0 -16
  265. package/packages/pi-coding-agent/dist/migrations.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/migrations.js +2 -2
  267. package/packages/pi-coding-agent/dist/migrations.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.d.ts +0 -2
  269. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  270. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.js +2 -2
  271. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts +1 -1
  273. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  274. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +9 -26
  275. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
  276. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -13
  278. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts +44 -0
  280. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts.map +1 -0
  281. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js +61 -0
  282. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js.map +1 -0
  283. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  284. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js +6 -9
  285. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js.map +1 -1
  286. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +1 -24
  287. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  288. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +50 -512
  289. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  290. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts +71 -0
  291. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -0
  292. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +514 -0
  293. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -0
  294. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +65 -4
  295. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +6 -23
  297. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  298. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts +12 -0
  299. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -0
  300. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +175 -0
  301. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -0
  302. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts +6 -0
  303. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts.map +1 -0
  304. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js +15 -0
  305. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js.map +1 -0
  306. package/packages/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
  307. package/packages/pi-coding-agent/dist/modes/print-mode.js +2 -30
  308. package/packages/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
  309. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  310. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +2 -28
  311. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  312. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts +19 -0
  313. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts.map +1 -0
  314. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js +45 -0
  315. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js.map +1 -0
  316. package/packages/pi-coding-agent/dist/utils/changelog.d.ts +0 -4
  317. package/packages/pi-coding-agent/dist/utils/changelog.d.ts.map +1 -1
  318. package/packages/pi-coding-agent/dist/utils/changelog.js +1 -1
  319. package/packages/pi-coding-agent/dist/utils/changelog.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/utils/clipboard-image.d.ts +0 -1
  321. package/packages/pi-coding-agent/dist/utils/clipboard-image.d.ts.map +1 -1
  322. package/packages/pi-coding-agent/dist/utils/clipboard-image.js +1 -1
  323. package/packages/pi-coding-agent/dist/utils/clipboard-image.js.map +1 -1
  324. package/packages/pi-coding-agent/dist/utils/error.d.ts +5 -0
  325. package/packages/pi-coding-agent/dist/utils/error.d.ts.map +1 -0
  326. package/packages/pi-coding-agent/dist/utils/error.js +7 -0
  327. package/packages/pi-coding-agent/dist/utils/error.js.map +1 -0
  328. package/packages/pi-coding-agent/dist/utils/photon.d.ts +0 -19
  329. package/packages/pi-coding-agent/dist/utils/photon.d.ts.map +1 -1
  330. package/packages/pi-coding-agent/dist/utils/photon.js +1 -120
  331. package/packages/pi-coding-agent/dist/utils/photon.js.map +1 -1
  332. package/packages/pi-coding-agent/dist/utils/tools-manager.d.ts +0 -1
  333. package/packages/pi-coding-agent/dist/utils/tools-manager.d.ts.map +1 -1
  334. package/packages/pi-coding-agent/dist/utils/tools-manager.js +1 -1
  335. package/packages/pi-coding-agent/dist/utils/tools-manager.js.map +1 -1
  336. package/packages/pi-coding-agent/package.json +1 -1
  337. package/packages/pi-coding-agent/src/config.ts +5 -10
  338. package/packages/pi-coding-agent/src/core/agent-session.ts +117 -745
  339. package/packages/pi-coding-agent/src/core/auth-storage.ts +4 -38
  340. package/packages/pi-coding-agent/src/core/compaction/branch-summarization.ts +7 -53
  341. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +14 -74
  342. package/packages/pi-coding-agent/src/core/compaction/utils.ts +100 -0
  343. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +424 -0
  344. package/packages/pi-coding-agent/src/core/export-html/ansi-to-html.ts +1 -1
  345. package/packages/pi-coding-agent/src/core/extensions/index.ts +1 -21
  346. package/packages/pi-coding-agent/src/core/extensions/runner.ts +119 -256
  347. package/packages/pi-coding-agent/src/core/extensions/types.ts +50 -69
  348. package/packages/pi-coding-agent/src/core/keybindings.ts +2 -2
  349. package/packages/pi-coding-agent/src/core/lock-utils.ts +113 -0
  350. package/packages/pi-coding-agent/src/core/lsp/client.ts +3 -73
  351. package/packages/pi-coding-agent/src/core/lsp/config.ts +2 -10
  352. package/packages/pi-coding-agent/src/core/lsp/edits.ts +1 -1
  353. package/packages/pi-coding-agent/src/core/lsp/index.ts +83 -152
  354. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -23
  355. package/packages/pi-coding-agent/src/core/lsp/types.ts +0 -29
  356. package/packages/pi-coding-agent/src/core/lsp/utils.ts +1 -33
  357. package/packages/pi-coding-agent/src/core/messages.ts +5 -5
  358. package/packages/pi-coding-agent/src/core/model-registry.ts +0 -2
  359. package/packages/pi-coding-agent/src/core/model-resolver.ts +3 -77
  360. package/packages/pi-coding-agent/src/core/package-manager.ts +1 -4
  361. package/packages/pi-coding-agent/src/core/prompt-templates.ts +2 -2
  362. package/packages/pi-coding-agent/src/core/resource-loader.ts +56 -69
  363. package/packages/pi-coding-agent/src/core/retry-handler.ts +359 -0
  364. package/packages/pi-coding-agent/src/core/session-manager.ts +5 -34
  365. package/packages/pi-coding-agent/src/core/settings-manager.ts +87 -166
  366. package/packages/pi-coding-agent/src/core/skills.ts +1 -4
  367. package/packages/pi-coding-agent/src/index.ts +1 -7
  368. package/packages/pi-coding-agent/src/migrations.ts +2 -2
  369. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector-search.ts +2 -2
  370. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +17 -29
  371. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -13
  372. package/packages/pi-coding-agent/src/modes/interactive/components/tree-render-utils.ts +81 -0
  373. package/packages/pi-coding-agent/src/modes/interactive/components/tree-selector.ts +14 -19
  374. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +50 -561
  375. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +653 -0
  376. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +7 -26
  377. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +196 -0
  378. package/packages/pi-coding-agent/src/modes/interactive/utils/shorten-path.ts +14 -0
  379. package/packages/pi-coding-agent/src/modes/print-mode.ts +2 -30
  380. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -28
  381. package/packages/pi-coding-agent/src/modes/shared/command-context-actions.ts +53 -0
  382. package/packages/pi-coding-agent/src/utils/changelog.ts +1 -1
  383. package/packages/pi-coding-agent/src/utils/clipboard-image.ts +1 -1
  384. package/packages/pi-coding-agent/src/utils/error.ts +6 -0
  385. package/packages/pi-coding-agent/src/utils/photon.ts +0 -137
  386. package/packages/pi-coding-agent/src/utils/tools-manager.ts +1 -1
  387. package/packages/pi-tui/dist/components/editor.d.ts +0 -10
  388. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  389. package/packages/pi-tui/dist/components/editor.js +1 -1
  390. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  391. package/packages/pi-tui/dist/components/markdown.d.ts +5 -0
  392. package/packages/pi-tui/dist/components/markdown.d.ts.map +1 -1
  393. package/packages/pi-tui/dist/components/markdown.js +25 -31
  394. package/packages/pi-tui/dist/components/markdown.js.map +1 -1
  395. package/packages/pi-tui/dist/keys.d.ts +0 -4
  396. package/packages/pi-tui/dist/keys.d.ts.map +1 -1
  397. package/packages/pi-tui/dist/keys.js +94 -162
  398. package/packages/pi-tui/dist/keys.js.map +1 -1
  399. package/packages/pi-tui/dist/overlay-layout.d.ts +55 -0
  400. package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -0
  401. package/packages/pi-tui/dist/overlay-layout.js +288 -0
  402. package/packages/pi-tui/dist/overlay-layout.js.map +1 -0
  403. package/packages/pi-tui/dist/tui.d.ts +0 -22
  404. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  405. package/packages/pi-tui/dist/tui.js +6 -272
  406. package/packages/pi-tui/dist/tui.js.map +1 -1
  407. package/packages/pi-tui/dist/utils.d.ts +0 -7
  408. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  409. package/packages/pi-tui/dist/utils.js +0 -44
  410. package/packages/pi-tui/dist/utils.js.map +1 -1
  411. package/packages/pi-tui/src/components/editor.ts +1 -1
  412. package/packages/pi-tui/src/components/markdown.ts +25 -29
  413. package/packages/pi-tui/src/keys.ts +94 -173
  414. package/packages/pi-tui/src/overlay-layout.ts +372 -0
  415. package/packages/pi-tui/src/tui.ts +11 -312
  416. package/packages/pi-tui/src/utils.ts +0 -43
  417. package/pkg/dist/core/export-html/ansi-to-html.d.ts +0 -4
  418. package/pkg/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  419. package/pkg/dist/core/export-html/ansi-to-html.js +1 -1
  420. package/pkg/dist/core/export-html/ansi-to-html.js.map +1 -1
  421. package/pkg/dist/modes/interactive/theme/theme.d.ts +65 -4
  422. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  423. package/pkg/dist/modes/interactive/theme/theme.js +6 -23
  424. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  425. package/pkg/dist/modes/interactive/theme/themes.d.ts +12 -0
  426. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -0
  427. package/pkg/dist/modes/interactive/theme/themes.js +175 -0
  428. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -0
  429. package/pkg/package.json +1 -1
  430. package/src/resources/extensions/async-jobs/await-tool.ts +0 -2
  431. package/src/resources/extensions/async-jobs/job-manager.ts +0 -7
  432. package/src/resources/extensions/bg-shell/output-formatter.ts +0 -17
  433. package/src/resources/extensions/bg-shell/process-manager.ts +0 -4
  434. package/src/resources/extensions/bg-shell/types.ts +0 -12
  435. package/src/resources/extensions/context7/index.ts +7 -0
  436. package/src/resources/extensions/get-secrets-from-user.ts +2 -35
  437. package/src/resources/extensions/google-search/index.ts +7 -0
  438. package/src/resources/extensions/gsd/auto-dispatch.ts +49 -1
  439. package/src/resources/extensions/gsd/auto-loop.ts +11 -1
  440. package/src/resources/extensions/gsd/auto-recovery.ts +39 -0
  441. package/src/resources/extensions/gsd/auto-start.ts +42 -2
  442. package/src/resources/extensions/gsd/auto.ts +61 -3
  443. package/src/resources/extensions/gsd/changelog.ts +213 -0
  444. package/src/resources/extensions/gsd/commands-bootstrap.ts +1 -0
  445. package/src/resources/extensions/gsd/commands-handlers.ts +2 -2
  446. package/src/resources/extensions/gsd/commands-inspect.ts +10 -3
  447. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +5 -1
  448. package/src/resources/extensions/gsd/commands.ts +9 -1
  449. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  450. package/src/resources/extensions/gsd/doctor-checks.ts +107 -5
  451. package/src/resources/extensions/gsd/doctor-environment.ts +26 -16
  452. package/src/resources/extensions/gsd/doctor-proactive.ts +24 -0
  453. package/src/resources/extensions/gsd/doctor-types.ts +9 -1
  454. package/src/resources/extensions/gsd/doctor.ts +35 -0
  455. package/src/resources/extensions/gsd/files.ts +12 -2
  456. package/src/resources/extensions/gsd/gitignore.ts +54 -7
  457. package/src/resources/extensions/gsd/guided-flow.ts +5 -3
  458. package/src/resources/extensions/gsd/health-widget-core.ts +129 -0
  459. package/src/resources/extensions/gsd/health-widget.ts +103 -59
  460. package/src/resources/extensions/gsd/index.ts +10 -1
  461. package/src/resources/extensions/gsd/migrate-external.ts +47 -2
  462. package/src/resources/extensions/gsd/paths.ts +73 -7
  463. package/src/resources/extensions/gsd/post-unit-hooks.ts +5 -1
  464. package/src/resources/extensions/gsd/preferences-validation.ts +54 -1
  465. package/src/resources/extensions/gsd/preferences.ts +2 -0
  466. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  467. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  468. package/src/resources/extensions/gsd/roadmap-mutations.ts +66 -0
  469. package/src/resources/extensions/gsd/session-lock.ts +29 -2
  470. package/src/resources/extensions/gsd/templates/plan.md +8 -0
  471. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +46 -0
  472. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +98 -2
  473. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +59 -3
  474. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +20 -0
  475. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +214 -0
  476. package/src/resources/extensions/gsd/tests/health-widget.test.ts +158 -0
  477. package/src/resources/extensions/gsd/tests/paths.test.ts +113 -0
  478. package/src/resources/extensions/gsd/tests/preferences.test.ts +40 -2
  479. package/src/resources/extensions/gsd/tests/test-utils.ts +165 -0
  480. package/src/resources/extensions/gsd/tests/validate-directory.test.ts +15 -0
  481. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +2 -0
  482. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +32 -0
  483. package/src/resources/extensions/gsd/worktree-resolver.ts +11 -0
  484. package/src/resources/extensions/mcp-client/index.ts +2 -1
  485. package/src/resources/extensions/remote-questions/remote-command.ts +2 -23
  486. package/src/resources/extensions/shared/mod.ts +1 -1
  487. package/src/resources/extensions/shared/sanitize.ts +36 -0
  488. package/src/resources/extensions/subagent/index.ts +6 -12
  489. package/src/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
  490. package/dist/resources/extensions/shared/wizard-ui.js +0 -478
  491. package/packages/pi-coding-agent/dist/modes/interactive/theme/dark.json +0 -85
  492. package/packages/pi-coding-agent/dist/modes/interactive/theme/light.json +0 -84
  493. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.json +0 -335
  494. package/packages/pi-coding-agent/src/modes/interactive/theme/dark.json +0 -85
  495. package/packages/pi-coding-agent/src/modes/interactive/theme/light.json +0 -84
  496. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.json +0 -335
  497. package/pkg/dist/modes/interactive/theme/dark.json +0 -85
  498. package/pkg/dist/modes/interactive/theme/light.json +0 -84
  499. package/pkg/dist/modes/interactive/theme/theme-schema.json +0 -335
  500. package/src/resources/extensions/shared/wizard-ui.ts +0 -551
@@ -0,0 +1,359 @@
1
+ /**
2
+ * RetryHandler - Automatic retry logic with exponential backoff and credential/provider fallback.
3
+ *
4
+ * Handles retryable errors (overloaded, rate limit, server errors) by:
5
+ * 1. Trying alternate credentials for the same provider
6
+ * 2. Falling back to other providers via FallbackResolver
7
+ * 3. Exponential backoff with configurable max retries
8
+ *
9
+ * Context overflow errors are NOT handled here (see compaction).
10
+ */
11
+
12
+ import type { Agent } from "@gsd/pi-agent-core";
13
+ import type { AssistantMessage, Model } from "@gsd/pi-ai";
14
+ import { isContextOverflow } from "@gsd/pi-ai";
15
+ import type { UsageLimitErrorType } from "./auth-storage.js";
16
+ import type { FallbackResolver } from "./fallback-resolver.js";
17
+ import type { ModelRegistry } from "./model-registry.js";
18
+ import type { SettingsManager } from "./settings-manager.js";
19
+ import { sleep } from "../utils/sleep.js";
20
+ import type { AgentSessionEvent } from "./agent-session.js";
21
+
22
+ /** Dependencies injected from AgentSession into RetryHandler */
23
+ export interface RetryHandlerDeps {
24
+ readonly agent: Agent;
25
+ readonly settingsManager: SettingsManager;
26
+ readonly modelRegistry: ModelRegistry;
27
+ readonly fallbackResolver: FallbackResolver;
28
+ getModel: () => Model<any> | undefined;
29
+ getSessionId: () => string;
30
+ emit: (event: AgentSessionEvent) => void;
31
+ /** Called when the retry handler switches to a fallback model */
32
+ onModelChange: (model: Model<any>) => void;
33
+ }
34
+
35
+ export class RetryHandler {
36
+ private _retryAbortController: AbortController | undefined = undefined;
37
+ private _retryAttempt = 0;
38
+ private _retryPromise: Promise<void> | undefined = undefined;
39
+ private _retryResolve: (() => void) | undefined = undefined;
40
+
41
+ constructor(private readonly _deps: RetryHandlerDeps) {}
42
+
43
+ /** Current retry attempt (0 if not retrying) */
44
+ get retryAttempt(): number {
45
+ return this._retryAttempt;
46
+ }
47
+
48
+ /** Whether auto-retry is currently in progress */
49
+ get isRetrying(): boolean {
50
+ return this._retryPromise !== undefined;
51
+ }
52
+
53
+ /** Whether auto-retry is enabled */
54
+ get autoRetryEnabled(): boolean {
55
+ return this._deps.settingsManager.getRetryEnabled();
56
+ }
57
+
58
+ /** Toggle auto-retry setting */
59
+ setAutoRetryEnabled(enabled: boolean): void {
60
+ this._deps.settingsManager.setRetryEnabled(enabled);
61
+ }
62
+
63
+ /**
64
+ * Create a retry promise synchronously for agent_end events.
65
+ * Must be called synchronously from the agent event handler before
66
+ * any async processing, so that waitForRetry() doesn't miss in-flight retries.
67
+ */
68
+ createRetryPromiseForAgentEnd(messages: Array<{ role: string } & Record<string, any>>): void {
69
+ if (this._retryPromise) return;
70
+
71
+ const settings = this._deps.settingsManager.getRetrySettings();
72
+ if (!settings.enabled) return;
73
+
74
+ const lastAssistant = this._findLastAssistantInMessages(messages);
75
+ if (!lastAssistant || !this.isRetryableError(lastAssistant)) return;
76
+
77
+ this._retryPromise = new Promise((resolve) => {
78
+ this._retryResolve = resolve;
79
+ });
80
+ }
81
+
82
+ /**
83
+ * Handle a successful assistant response by resetting retry state.
84
+ * Call this when an assistant message completes without error.
85
+ */
86
+ handleSuccessfulResponse(): void {
87
+ if (this._retryAttempt > 0) {
88
+ this._deps.emit({
89
+ type: "auto_retry_end",
90
+ success: true,
91
+ attempt: this._retryAttempt,
92
+ });
93
+ this._retryAttempt = 0;
94
+ this._resolveRetry();
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Check if an error is retryable (overloaded, rate limit, server errors).
100
+ * Context overflow errors are NOT retryable (handled by compaction instead).
101
+ */
102
+ isRetryableError(message: AssistantMessage): boolean {
103
+ if (message.stopReason !== "error" || !message.errorMessage) return false;
104
+
105
+ // Context overflow is handled by compaction, not retry
106
+ const contextWindow = this._deps.getModel()?.contextWindow ?? 0;
107
+ if (isContextOverflow(message, contextWindow)) return false;
108
+
109
+ const err = message.errorMessage;
110
+ return /overloaded|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated|retry delay|network.?(?:is\s+)?unavailable|credentials.*expired|temporarily backed off/i.test(
111
+ err,
112
+ );
113
+ }
114
+
115
+ /**
116
+ * Handle retryable errors with exponential backoff.
117
+ * When multiple credentials are available, marks the failing credential
118
+ * as backed off and retries immediately with the next one.
119
+ * @returns true if retry was initiated, false if max retries exceeded or disabled
120
+ */
121
+ async handleRetryableError(message: AssistantMessage): Promise<boolean> {
122
+ const settings = this._deps.settingsManager.getRetrySettings();
123
+ if (!settings.enabled) {
124
+ this._resolveRetry();
125
+ return false;
126
+ }
127
+
128
+ // Retry promise is created synchronously in createRetryPromiseForAgentEnd.
129
+ // Keep a defensive fallback here in case a future refactor bypasses that path.
130
+ if (!this._retryPromise) {
131
+ this._retryPromise = new Promise((resolve) => {
132
+ this._retryResolve = resolve;
133
+ });
134
+ }
135
+
136
+ // Try credential fallback before counting against retry budget.
137
+ if (this._deps.getModel() && message.errorMessage) {
138
+ const errorType = this._classifyErrorType(message.errorMessage);
139
+ const isCredentialError = errorType !== "unknown";
140
+ const hasAlternate =
141
+ isCredentialError &&
142
+ this._deps.modelRegistry.authStorage.markUsageLimitReached(
143
+ this._deps.getModel()!.provider,
144
+ this._deps.getSessionId(),
145
+ { errorType },
146
+ );
147
+
148
+ if (hasAlternate) {
149
+ this._removeLastAssistantError();
150
+
151
+ this._deps.emit({
152
+ type: "auto_retry_start",
153
+ attempt: this._retryAttempt + 1,
154
+ maxAttempts: settings.maxRetries,
155
+ delayMs: 0,
156
+ errorMessage: `${message.errorMessage} (switching credential)`,
157
+ });
158
+
159
+ // Retry immediately with the next credential - don't increment _retryAttempt
160
+ setTimeout(() => {
161
+ this._deps.agent.continue().catch(() => {});
162
+ }, 0);
163
+
164
+ return true;
165
+ }
166
+
167
+ // All credentials are backed off. Try cross-provider fallback before giving up.
168
+ if (isCredentialError) {
169
+ const fallbackResult = await this._deps.fallbackResolver.findFallback(
170
+ this._deps.getModel()!,
171
+ errorType,
172
+ );
173
+
174
+ if (fallbackResult) {
175
+ const previousProvider = this._deps.getModel()!.provider;
176
+ this._deps.agent.setModel(fallbackResult.model);
177
+ this._deps.onModelChange(fallbackResult.model);
178
+ this._removeLastAssistantError();
179
+
180
+ this._deps.emit({
181
+ type: "fallback_provider_switch",
182
+ from: `${previousProvider}/${this._deps.getModel()?.id}`,
183
+ to: `${fallbackResult.model.provider}/${fallbackResult.model.id}`,
184
+ reason: fallbackResult.reason,
185
+ });
186
+
187
+ this._deps.emit({
188
+ type: "auto_retry_start",
189
+ attempt: this._retryAttempt + 1,
190
+ maxAttempts: settings.maxRetries,
191
+ delayMs: 0,
192
+ errorMessage: `${message.errorMessage} (${fallbackResult.reason})`,
193
+ });
194
+
195
+ // Retry immediately with fallback provider - don't increment _retryAttempt
196
+ setTimeout(() => {
197
+ this._deps.agent.continue().catch(() => {});
198
+ }, 0);
199
+
200
+ return true;
201
+ }
202
+
203
+ // No fallback available either
204
+ if (errorType === "quota_exhausted") {
205
+ this._deps.emit({
206
+ type: "fallback_chain_exhausted",
207
+ reason: `All providers exhausted for ${this._deps.getModel()!.provider}/${this._deps.getModel()!.id}`,
208
+ });
209
+ this._deps.emit({
210
+ type: "auto_retry_end",
211
+ success: false,
212
+ attempt: this._retryAttempt,
213
+ finalError: message.errorMessage,
214
+ });
215
+ this._retryAttempt = 0;
216
+ this._resolveRetry();
217
+ return false;
218
+ }
219
+ }
220
+ }
221
+
222
+ this._retryAttempt++;
223
+
224
+ if (this._retryAttempt > settings.maxRetries) {
225
+ this._deps.emit({
226
+ type: "auto_retry_end",
227
+ success: false,
228
+ attempt: this._retryAttempt - 1,
229
+ finalError: message.errorMessage,
230
+ });
231
+ this._retryAttempt = 0;
232
+ this._resolveRetry();
233
+ return false;
234
+ }
235
+
236
+ // Use server-requested delay when available, capped by maxDelayMs.
237
+ // Fall back to exponential backoff when no server hint is present.
238
+ const exponentialDelayMs = settings.baseDelayMs * 2 ** (this._retryAttempt - 1);
239
+ let delayMs: number;
240
+ if (message.retryAfterMs !== undefined) {
241
+ const cap = settings.maxDelayMs > 0 ? settings.maxDelayMs : Infinity;
242
+ if (message.retryAfterMs > cap) {
243
+ this._deps.emit({
244
+ type: "auto_retry_end",
245
+ success: false,
246
+ attempt: this._retryAttempt - 1,
247
+ finalError: `Rate limit reset in ${Math.ceil(message.retryAfterMs / 1000)}s (max: ${Math.ceil(cap / 1000)}s). ${message.errorMessage || ""}`.trim(),
248
+ });
249
+ this._retryAttempt = 0;
250
+ this._resolveRetry();
251
+ return false;
252
+ }
253
+ delayMs = message.retryAfterMs;
254
+ } else {
255
+ delayMs = exponentialDelayMs;
256
+ }
257
+
258
+ this._deps.emit({
259
+ type: "auto_retry_start",
260
+ attempt: this._retryAttempt,
261
+ maxAttempts: settings.maxRetries,
262
+ delayMs,
263
+ errorMessage: message.errorMessage || "Unknown error",
264
+ });
265
+
266
+ this._removeLastAssistantError();
267
+
268
+ // Wait with exponential backoff (abortable)
269
+ this._retryAbortController = new AbortController();
270
+ try {
271
+ await sleep(delayMs, this._retryAbortController.signal);
272
+ } catch {
273
+ // Aborted during sleep
274
+ const attempt = this._retryAttempt;
275
+ this._retryAttempt = 0;
276
+ this._retryAbortController = undefined;
277
+ this._deps.emit({
278
+ type: "auto_retry_end",
279
+ success: false,
280
+ attempt,
281
+ finalError: "Retry cancelled",
282
+ });
283
+ this._resolveRetry();
284
+ return false;
285
+ }
286
+ this._retryAbortController = undefined;
287
+
288
+ // Retry via continue() - use setTimeout to break out of event handler chain
289
+ setTimeout(() => {
290
+ this._deps.agent.continue().catch(() => {});
291
+ }, 0);
292
+
293
+ return true;
294
+ }
295
+
296
+ /** Cancel in-progress retry */
297
+ abortRetry(): void {
298
+ this._retryAbortController?.abort();
299
+ this._resolveRetry();
300
+ }
301
+
302
+ /**
303
+ * Wait for any in-progress retry to complete.
304
+ * Returns immediately if no retry is in progress.
305
+ */
306
+ async waitForRetry(): Promise<void> {
307
+ if (this._retryPromise) {
308
+ await this._retryPromise;
309
+ }
310
+ }
311
+
312
+ /** Resolve the pending retry promise */
313
+ resolveRetry(): void {
314
+ this._resolveRetry();
315
+ }
316
+
317
+ // =========================================================================
318
+ // Private helpers
319
+ // =========================================================================
320
+
321
+ private _resolveRetry(): void {
322
+ if (this._retryResolve) {
323
+ this._retryResolve();
324
+ this._retryResolve = undefined;
325
+ this._retryPromise = undefined;
326
+ }
327
+ }
328
+
329
+ private _findLastAssistantInMessages(
330
+ messages: Array<{ role: string } & Record<string, any>>,
331
+ ): AssistantMessage | undefined {
332
+ for (let i = messages.length - 1; i >= 0; i--) {
333
+ const message = messages[i];
334
+ if (message.role === "assistant") {
335
+ return message as AssistantMessage;
336
+ }
337
+ }
338
+ return undefined;
339
+ }
340
+
341
+ /**
342
+ * Classify an error message into a usage-limit error type for credential backoff.
343
+ */
344
+ private _classifyErrorType(errorMessage: string): UsageLimitErrorType {
345
+ const err = errorMessage.toLowerCase();
346
+ if (/quota|billing|exceeded.*limit|usage.*limit/i.test(err)) return "quota_exhausted";
347
+ if (/rate.?limit|too many requests|429/i.test(err)) return "rate_limit";
348
+ if (/500|502|503|504|server.?error|internal.?error|service.?unavailable/i.test(err)) return "server_error";
349
+ return "unknown";
350
+ }
351
+
352
+ /** Remove the last assistant error message from agent state */
353
+ private _removeLastAssistantError(): void {
354
+ const messages = this._deps.agent.state.messages;
355
+ if (messages.length > 0 && messages[messages.length - 1].role === "assistant") {
356
+ this._deps.agent.replaceMessages(messages.slice(0, -1));
357
+ }
358
+ }
359
+ }
@@ -16,8 +16,8 @@ import {
16
16
  import { atomicWriteFileSync } from "./fs-utils.js";
17
17
  import { readdir, readFile, stat } from "fs/promises";
18
18
  import { join, resolve } from "path";
19
- import lockfile from "proper-lockfile";
20
19
  import { getAgentDir as getDefaultAgentDir, getBlobsDir, getSessionsDir } from "../config.js";
20
+ import { tryAcquireLockSync } from "./lock-utils.js";
21
21
  import {
22
22
  type BashExecutionMessage,
23
23
  type CustomMessage,
@@ -577,8 +577,7 @@ function resolveBlobRefsInEntries(entries: FileEntry[], blobStore: BlobStore): v
577
577
  }
578
578
  }
579
579
 
580
- /** Exported for testing */
581
- export function loadEntriesFromFile(filePath: string): FileEntry[] {
580
+ function loadEntriesFromFile(filePath: string): FileEntry[] {
582
581
  if (!existsSync(filePath)) return [];
583
582
 
584
583
  const content = readFileSync(filePath, "utf8");
@@ -620,8 +619,7 @@ function isValidSessionFile(filePath: string): boolean {
620
619
  }
621
620
  }
622
621
 
623
- /** Exported for testing */
624
- export function findMostRecentSession(sessionDir: string): string | null {
622
+ function findMostRecentSession(sessionDir: string): string | null {
625
623
  try {
626
624
  const files = readdirSync(sessionDir)
627
625
  .filter((f) => f.endsWith(".jsonl"))
@@ -955,39 +953,12 @@ export class SessionManager {
955
953
  }
956
954
  }
957
955
 
958
- private acquireSessionLock(path: string): (() => void) | undefined {
959
- const maxAttempts = 10;
960
- const delayMs = 20;
961
- let lastError: unknown;
962
-
963
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
964
- try {
965
- return lockfile.lockSync(path, { realpath: false });
966
- } catch (error) {
967
- const code =
968
- typeof error === "object" && error !== null && "code" in error
969
- ? String((error as { code?: unknown }).code)
970
- : undefined;
971
- if (code !== "ELOCKED" || attempt === maxAttempts) {
972
- // Non-fatal: proceed without lock rather than losing data
973
- return undefined;
974
- }
975
- lastError = error;
976
- const start = Date.now();
977
- while (Date.now() - start < delayMs) {
978
- // Busy-wait to avoid async
979
- }
980
- }
981
- }
982
- return undefined;
983
- }
984
-
985
956
  private _rewriteFile(): void {
986
957
  if (!this.persist || !this.sessionFile) return;
987
958
  const content = `${this.fileEntries.map((e) => JSON.stringify(e)).join("\n")}\n`;
988
959
  let release: (() => void) | undefined;
989
960
  try {
990
- release = this.acquireSessionLock(this.sessionFile);
961
+ release = tryAcquireLockSync(this.sessionFile);
991
962
  atomicWriteFileSync(this.sessionFile, content);
992
963
  } finally {
993
964
  release?.();
@@ -1026,7 +997,7 @@ export class SessionManager {
1026
997
 
1027
998
  let release: (() => void) | undefined;
1028
999
  try {
1029
- release = this.acquireSessionLock(this.sessionFile);
1000
+ release = tryAcquireLockSync(this.sessionFile);
1030
1001
  if (!this.flushed) {
1031
1002
  for (const e of this.fileEntries) {
1032
1003
  const prepared = prepareForPersistence(e, this.blobStore) as FileEntry;