gsd-pi 2.34.0 → 2.35.0-dev.34ce717

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 (510) hide show
  1. package/README.md +3 -1
  2. package/dist/cli.js +7 -2
  3. package/dist/resource-loader.d.ts +1 -1
  4. package/dist/resource-loader.js +13 -1
  5. package/dist/resources/extensions/async-jobs/await-tool.js +0 -2
  6. package/dist/resources/extensions/async-jobs/job-manager.js +0 -6
  7. package/dist/resources/extensions/bg-shell/output-formatter.js +1 -19
  8. package/dist/resources/extensions/bg-shell/process-manager.js +0 -4
  9. package/dist/resources/extensions/bg-shell/types.js +0 -2
  10. package/dist/resources/extensions/context7/index.js +5 -0
  11. package/dist/resources/extensions/get-secrets-from-user.js +2 -30
  12. package/dist/resources/extensions/google-search/index.js +5 -0
  13. package/dist/resources/extensions/gsd/auto-dispatch.js +43 -1
  14. package/dist/resources/extensions/gsd/auto-loop.js +17 -3
  15. package/dist/resources/extensions/gsd/auto-model-selection.js +15 -3
  16. package/dist/resources/extensions/gsd/auto-recovery.js +35 -0
  17. package/dist/resources/extensions/gsd/auto-start.js +35 -2
  18. package/dist/resources/extensions/gsd/auto.js +59 -4
  19. package/dist/resources/extensions/gsd/changelog.js +162 -0
  20. package/dist/resources/extensions/gsd/commands-bootstrap.js +1 -0
  21. package/dist/resources/extensions/gsd/commands-handlers.js +2 -2
  22. package/dist/resources/extensions/gsd/commands-inspect.js +10 -3
  23. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +5 -1
  24. package/dist/resources/extensions/gsd/commands-rate.js +31 -0
  25. package/dist/resources/extensions/gsd/commands.js +51 -2
  26. package/dist/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  27. package/dist/resources/extensions/gsd/doctor-checks.js +113 -5
  28. package/dist/resources/extensions/gsd/doctor-environment.js +26 -17
  29. package/dist/resources/extensions/gsd/doctor-proactive.js +22 -0
  30. package/dist/resources/extensions/gsd/doctor.js +36 -0
  31. package/dist/resources/extensions/gsd/files.js +11 -2
  32. package/dist/resources/extensions/gsd/gitignore.js +54 -7
  33. package/dist/resources/extensions/gsd/guided-flow.js +12 -4
  34. package/dist/resources/extensions/gsd/health-widget-core.js +96 -0
  35. package/dist/resources/extensions/gsd/health-widget.js +97 -46
  36. package/dist/resources/extensions/gsd/index.js +26 -33
  37. package/dist/resources/extensions/gsd/migrate-external.js +55 -2
  38. package/dist/resources/extensions/gsd/milestone-ids.js +3 -2
  39. package/dist/resources/extensions/gsd/paths.js +74 -7
  40. package/dist/resources/extensions/gsd/post-unit-hooks.js +4 -1
  41. package/dist/resources/extensions/gsd/preferences-validation.js +54 -1
  42. package/dist/resources/extensions/gsd/preferences.js +14 -0
  43. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  44. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  45. package/dist/resources/extensions/gsd/roadmap-mutations.js +55 -0
  46. package/dist/resources/extensions/gsd/session-lock.js +53 -2
  47. package/dist/resources/extensions/gsd/state.js +2 -1
  48. package/dist/resources/extensions/gsd/templates/plan.md +8 -0
  49. package/dist/resources/extensions/gsd/worktree-resolver.js +12 -0
  50. package/dist/resources/extensions/mcp-client/index.js +2 -1
  51. package/dist/resources/extensions/remote-questions/remote-command.js +2 -22
  52. package/dist/resources/extensions/shared/mod.js +1 -1
  53. package/dist/resources/extensions/shared/sanitize.js +30 -0
  54. package/dist/resources/extensions/subagent/index.js +6 -14
  55. package/dist/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
  56. package/package.json +2 -1
  57. package/packages/native/dist/native.d.ts +0 -2
  58. package/packages/native/dist/native.js +0 -2
  59. package/packages/native/src/native.ts +0 -3
  60. package/packages/pi-agent-core/dist/agent-loop.d.ts +14 -0
  61. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  62. package/packages/pi-agent-core/dist/agent-loop.js +24 -27
  63. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  64. package/packages/pi-agent-core/dist/agent.d.ts +1 -0
  65. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  66. package/packages/pi-agent-core/dist/agent.js +11 -22
  67. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  68. package/packages/pi-agent-core/dist/proxy.d.ts +1 -25
  69. package/packages/pi-agent-core/dist/proxy.d.ts.map +1 -1
  70. package/packages/pi-agent-core/dist/proxy.js +3 -9
  71. package/packages/pi-agent-core/dist/proxy.js.map +1 -1
  72. package/packages/pi-agent-core/src/agent-loop.ts +30 -27
  73. package/packages/pi-agent-core/src/agent.ts +12 -23
  74. package/packages/pi-agent-core/src/proxy.ts +3 -9
  75. package/packages/pi-ai/dist/api-registry.d.ts +0 -2
  76. package/packages/pi-ai/dist/api-registry.d.ts.map +1 -1
  77. package/packages/pi-ai/dist/api-registry.js +0 -10
  78. package/packages/pi-ai/dist/api-registry.js.map +1 -1
  79. package/packages/pi-ai/dist/providers/anthropic.d.ts +0 -8
  80. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  81. package/packages/pi-ai/dist/providers/anthropic.js +1 -1
  82. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  83. package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
  84. package/packages/pi-ai/dist/providers/azure-openai-responses.js +5 -41
  85. package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
  86. package/packages/pi-ai/dist/providers/github-copilot-headers.d.ts +0 -1
  87. package/packages/pi-ai/dist/providers/github-copilot-headers.d.ts.map +1 -1
  88. package/packages/pi-ai/dist/providers/github-copilot-headers.js +1 -1
  89. package/packages/pi-ai/dist/providers/github-copilot-headers.js.map +1 -1
  90. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts +1 -43
  91. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  92. package/packages/pi-ai/dist/providers/google-gemini-cli.js +2 -2
  93. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  94. package/packages/pi-ai/dist/providers/google-shared.d.ts +0 -4
  95. package/packages/pi-ai/dist/providers/google-shared.d.ts.map +1 -1
  96. package/packages/pi-ai/dist/providers/google-shared.js +1 -1
  97. package/packages/pi-ai/dist/providers/google-shared.js.map +1 -1
  98. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  99. package/packages/pi-ai/dist/providers/openai-completions.js +10 -73
  100. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  101. package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  102. package/packages/pi-ai/dist/providers/openai-responses.js +9 -80
  103. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  104. package/packages/pi-ai/dist/providers/openai-shared.d.ts +65 -0
  105. package/packages/pi-ai/dist/providers/openai-shared.d.ts.map +1 -0
  106. package/packages/pi-ai/dist/providers/openai-shared.js +146 -0
  107. package/packages/pi-ai/dist/providers/openai-shared.js.map +1 -0
  108. package/packages/pi-ai/dist/providers/register-builtins.d.ts +0 -1
  109. package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
  110. package/packages/pi-ai/dist/providers/register-builtins.js +1 -1
  111. package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
  112. package/packages/pi-ai/dist/utils/event-stream.d.ts +0 -2
  113. package/packages/pi-ai/dist/utils/event-stream.d.ts.map +1 -1
  114. package/packages/pi-ai/dist/utils/event-stream.js +0 -4
  115. package/packages/pi-ai/dist/utils/event-stream.js.map +1 -1
  116. package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
  117. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +7 -135
  118. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
  119. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
  120. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +7 -135
  121. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
  122. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts +46 -0
  123. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.d.ts.map +1 -0
  124. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js +160 -0
  125. package/packages/pi-ai/dist/utils/oauth/google-oauth-utils.js.map +1 -0
  126. package/packages/pi-ai/dist/utils/overflow.d.ts +0 -4
  127. package/packages/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  128. package/packages/pi-ai/dist/utils/overflow.js +0 -6
  129. package/packages/pi-ai/dist/utils/overflow.js.map +1 -1
  130. package/packages/pi-ai/dist/utils/validation.d.ts +0 -8
  131. package/packages/pi-ai/dist/utils/validation.d.ts.map +1 -1
  132. package/packages/pi-ai/dist/utils/validation.js +0 -14
  133. package/packages/pi-ai/dist/utils/validation.js.map +1 -1
  134. package/packages/pi-ai/src/api-registry.ts +0 -12
  135. package/packages/pi-ai/src/providers/anthropic.ts +1 -1
  136. package/packages/pi-ai/src/providers/azure-openai-responses.ts +11 -45
  137. package/packages/pi-ai/src/providers/github-copilot-headers.ts +1 -1
  138. package/packages/pi-ai/src/providers/google-gemini-cli.ts +2 -2
  139. package/packages/pi-ai/src/providers/google-shared.ts +1 -1
  140. package/packages/pi-ai/src/providers/openai-completions.ts +16 -86
  141. package/packages/pi-ai/src/providers/openai-responses.ts +16 -96
  142. package/packages/pi-ai/src/providers/openai-shared.ts +193 -0
  143. package/packages/pi-ai/src/providers/register-builtins.ts +1 -1
  144. package/packages/pi-ai/src/utils/event-stream.ts +0 -5
  145. package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +14 -162
  146. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +13 -161
  147. package/packages/pi-ai/src/utils/oauth/google-oauth-utils.ts +201 -0
  148. package/packages/pi-ai/src/utils/overflow.ts +1 -8
  149. package/packages/pi-ai/src/utils/validation.ts +0 -15
  150. package/packages/pi-coding-agent/dist/config.d.ts +0 -9
  151. package/packages/pi-coding-agent/dist/config.d.ts.map +1 -1
  152. package/packages/pi-coding-agent/dist/config.js +4 -8
  153. package/packages/pi-coding-agent/dist/config.js.map +1 -1
  154. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +16 -63
  155. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  156. package/packages/pi-coding-agent/dist/core/agent-session.js +104 -641
  157. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  158. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +0 -1
  159. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  160. package/packages/pi-coding-agent/dist/core/auth-storage.js +4 -35
  161. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  162. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  163. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js +5 -43
  164. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
  165. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  166. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +11 -69
  167. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  168. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +40 -0
  169. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
  170. package/packages/pi-coding-agent/dist/core/compaction/utils.js +78 -0
  171. package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
  172. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +77 -0
  173. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -0
  174. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +331 -0
  175. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -0
  176. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.d.ts +0 -4
  177. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  178. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.js +1 -1
  179. package/packages/pi-coding-agent/dist/core/export-html/ansi-to-html.js.map +1 -1
  180. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +2 -2
  181. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  182. package/packages/pi-coding-agent/dist/core/extensions/index.js +1 -1
  183. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  184. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +15 -5
  185. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  186. package/packages/pi-coding-agent/dist/core/extensions/runner.js +129 -256
  187. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  188. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +49 -42
  189. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  190. package/packages/pi-coding-agent/dist/core/extensions/types.js +2 -21
  191. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  192. package/packages/pi-coding-agent/dist/core/keybindings.d.ts +0 -8
  193. package/packages/pi-coding-agent/dist/core/keybindings.d.ts.map +1 -1
  194. package/packages/pi-coding-agent/dist/core/keybindings.js +2 -2
  195. package/packages/pi-coding-agent/dist/core/keybindings.js.map +1 -1
  196. package/packages/pi-coding-agent/dist/core/lock-utils.d.ts +39 -0
  197. package/packages/pi-coding-agent/dist/core/lock-utils.d.ts.map +1 -0
  198. package/packages/pi-coding-agent/dist/core/lock-utils.js +89 -0
  199. package/packages/pi-coding-agent/dist/core/lock-utils.js.map +1 -0
  200. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts +0 -17
  201. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  202. package/packages/pi-coding-agent/dist/core/lsp/client.js +3 -62
  203. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  204. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts +1 -1
  205. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -1
  206. package/packages/pi-coding-agent/dist/core/lsp/config.js +2 -6
  207. package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -1
  208. package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts +0 -5
  209. package/packages/pi-coding-agent/dist/core/lsp/edits.d.ts.map +1 -1
  210. package/packages/pi-coding-agent/dist/core/lsp/edits.js +1 -1
  211. package/packages/pi-coding-agent/dist/core/lsp/edits.js.map +1 -1
  212. package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
  213. package/packages/pi-coding-agent/dist/core/lsp/index.js +52 -107
  214. package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
  215. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts +0 -1
  216. package/packages/pi-coding-agent/dist/core/lsp/lspmux.d.ts.map +1 -1
  217. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js +3 -22
  218. package/packages/pi-coding-agent/dist/core/lsp/lspmux.js.map +1 -1
  219. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts +0 -1
  220. package/packages/pi-coding-agent/dist/core/lsp/types.d.ts.map +1 -1
  221. package/packages/pi-coding-agent/dist/core/lsp/types.js +0 -28
  222. package/packages/pi-coding-agent/dist/core/lsp/types.js.map +1 -1
  223. package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts +1 -6
  224. package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts.map +1 -1
  225. package/packages/pi-coding-agent/dist/core/lsp/utils.js +1 -28
  226. package/packages/pi-coding-agent/dist/core/lsp/utils.js.map +1 -1
  227. package/packages/pi-coding-agent/dist/core/messages.d.ts +0 -8
  228. package/packages/pi-coding-agent/dist/core/messages.d.ts.map +1 -1
  229. package/packages/pi-coding-agent/dist/core/messages.js +5 -5
  230. package/packages/pi-coding-agent/dist/core/messages.js.map +1 -1
  231. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +0 -3
  232. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  233. package/packages/pi-coding-agent/dist/core/model-registry.js +1 -3
  234. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  235. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts +1 -26
  236. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  237. package/packages/pi-coding-agent/dist/core/model-resolver.js +3 -59
  238. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  239. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  240. package/packages/pi-coding-agent/dist/core/package-manager.js +2 -4
  241. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  242. package/packages/pi-coding-agent/dist/core/prompt-templates.d.ts +0 -17
  243. package/packages/pi-coding-agent/dist/core/prompt-templates.d.ts.map +1 -1
  244. package/packages/pi-coding-agent/dist/core/prompt-templates.js +2 -2
  245. package/packages/pi-coding-agent/dist/core/prompt-templates.js.map +1 -1
  246. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +2 -4
  247. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  248. package/packages/pi-coding-agent/dist/core/resource-loader.js +46 -60
  249. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  250. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +87 -0
  251. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -0
  252. package/packages/pi-coding-agent/dist/core/retry-handler.js +295 -0
  253. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -0
  254. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +0 -5
  255. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  256. package/packages/pi-coding-agent/dist/core/session-manager.js +5 -32
  257. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  258. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +8 -12
  259. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  260. package/packages/pi-coding-agent/dist/core/settings-manager.js +78 -168
  261. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  262. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  263. package/packages/pi-coding-agent/dist/core/skills.js +1 -3
  264. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  265. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  266. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  267. package/packages/pi-coding-agent/dist/index.js +1 -1
  268. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  269. package/packages/pi-coding-agent/dist/migrations.d.ts +0 -16
  270. package/packages/pi-coding-agent/dist/migrations.d.ts.map +1 -1
  271. package/packages/pi-coding-agent/dist/migrations.js +2 -2
  272. package/packages/pi-coding-agent/dist/migrations.js.map +1 -1
  273. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.d.ts +0 -2
  274. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  275. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.js +2 -2
  276. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  277. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts +1 -1
  278. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  279. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js +9 -26
  280. package/packages/pi-coding-agent/dist/modes/interactive/components/session-selector.js.map +1 -1
  281. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  282. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +1 -13
  283. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  284. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts +44 -0
  285. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.d.ts.map +1 -0
  286. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js +61 -0
  287. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-render-utils.js.map +1 -0
  288. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js +6 -9
  290. package/packages/pi-coding-agent/dist/modes/interactive/components/tree-selector.js.map +1 -1
  291. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +1 -24
  292. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  293. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +50 -512
  294. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  295. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts +71 -0
  296. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -0
  297. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +514 -0
  298. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -0
  299. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +65 -4
  300. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  301. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +6 -23
  302. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  303. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts +12 -0
  304. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -0
  305. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +175 -0
  306. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -0
  307. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts +6 -0
  308. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.d.ts.map +1 -0
  309. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js +15 -0
  310. package/packages/pi-coding-agent/dist/modes/interactive/utils/shorten-path.js.map +1 -0
  311. package/packages/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
  312. package/packages/pi-coding-agent/dist/modes/print-mode.js +2 -30
  313. package/packages/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
  314. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  315. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +2 -28
  316. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  317. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts +19 -0
  318. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.d.ts.map +1 -0
  319. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js +45 -0
  320. package/packages/pi-coding-agent/dist/modes/shared/command-context-actions.js.map +1 -0
  321. package/packages/pi-coding-agent/dist/utils/changelog.d.ts +0 -4
  322. package/packages/pi-coding-agent/dist/utils/changelog.d.ts.map +1 -1
  323. package/packages/pi-coding-agent/dist/utils/changelog.js +1 -1
  324. package/packages/pi-coding-agent/dist/utils/changelog.js.map +1 -1
  325. package/packages/pi-coding-agent/dist/utils/clipboard-image.d.ts +0 -1
  326. package/packages/pi-coding-agent/dist/utils/clipboard-image.d.ts.map +1 -1
  327. package/packages/pi-coding-agent/dist/utils/clipboard-image.js +1 -1
  328. package/packages/pi-coding-agent/dist/utils/clipboard-image.js.map +1 -1
  329. package/packages/pi-coding-agent/dist/utils/error.d.ts +5 -0
  330. package/packages/pi-coding-agent/dist/utils/error.d.ts.map +1 -0
  331. package/packages/pi-coding-agent/dist/utils/error.js +7 -0
  332. package/packages/pi-coding-agent/dist/utils/error.js.map +1 -0
  333. package/packages/pi-coding-agent/dist/utils/photon.d.ts +0 -19
  334. package/packages/pi-coding-agent/dist/utils/photon.d.ts.map +1 -1
  335. package/packages/pi-coding-agent/dist/utils/photon.js +1 -120
  336. package/packages/pi-coding-agent/dist/utils/photon.js.map +1 -1
  337. package/packages/pi-coding-agent/dist/utils/tools-manager.d.ts +0 -1
  338. package/packages/pi-coding-agent/dist/utils/tools-manager.d.ts.map +1 -1
  339. package/packages/pi-coding-agent/dist/utils/tools-manager.js +1 -1
  340. package/packages/pi-coding-agent/dist/utils/tools-manager.js.map +1 -1
  341. package/packages/pi-coding-agent/package.json +1 -1
  342. package/packages/pi-coding-agent/src/config.ts +5 -10
  343. package/packages/pi-coding-agent/src/core/agent-session.ts +117 -745
  344. package/packages/pi-coding-agent/src/core/auth-storage.ts +4 -38
  345. package/packages/pi-coding-agent/src/core/compaction/branch-summarization.ts +7 -53
  346. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +14 -74
  347. package/packages/pi-coding-agent/src/core/compaction/utils.ts +100 -0
  348. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +424 -0
  349. package/packages/pi-coding-agent/src/core/export-html/ansi-to-html.ts +1 -1
  350. package/packages/pi-coding-agent/src/core/extensions/index.ts +1 -21
  351. package/packages/pi-coding-agent/src/core/extensions/runner.ts +119 -256
  352. package/packages/pi-coding-agent/src/core/extensions/types.ts +50 -69
  353. package/packages/pi-coding-agent/src/core/keybindings.ts +2 -2
  354. package/packages/pi-coding-agent/src/core/lock-utils.ts +113 -0
  355. package/packages/pi-coding-agent/src/core/lsp/client.ts +3 -73
  356. package/packages/pi-coding-agent/src/core/lsp/config.ts +2 -10
  357. package/packages/pi-coding-agent/src/core/lsp/edits.ts +1 -1
  358. package/packages/pi-coding-agent/src/core/lsp/index.ts +83 -152
  359. package/packages/pi-coding-agent/src/core/lsp/lspmux.ts +3 -23
  360. package/packages/pi-coding-agent/src/core/lsp/types.ts +0 -29
  361. package/packages/pi-coding-agent/src/core/lsp/utils.ts +1 -33
  362. package/packages/pi-coding-agent/src/core/messages.ts +5 -5
  363. package/packages/pi-coding-agent/src/core/model-registry.ts +0 -2
  364. package/packages/pi-coding-agent/src/core/model-resolver.ts +3 -77
  365. package/packages/pi-coding-agent/src/core/package-manager.ts +1 -4
  366. package/packages/pi-coding-agent/src/core/prompt-templates.ts +2 -2
  367. package/packages/pi-coding-agent/src/core/resource-loader.ts +56 -69
  368. package/packages/pi-coding-agent/src/core/retry-handler.ts +359 -0
  369. package/packages/pi-coding-agent/src/core/session-manager.ts +5 -34
  370. package/packages/pi-coding-agent/src/core/settings-manager.ts +87 -166
  371. package/packages/pi-coding-agent/src/core/skills.ts +1 -4
  372. package/packages/pi-coding-agent/src/index.ts +1 -7
  373. package/packages/pi-coding-agent/src/migrations.ts +2 -2
  374. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector-search.ts +2 -2
  375. package/packages/pi-coding-agent/src/modes/interactive/components/session-selector.ts +17 -29
  376. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1 -13
  377. package/packages/pi-coding-agent/src/modes/interactive/components/tree-render-utils.ts +81 -0
  378. package/packages/pi-coding-agent/src/modes/interactive/components/tree-selector.ts +14 -19
  379. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +50 -561
  380. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +653 -0
  381. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +7 -26
  382. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +196 -0
  383. package/packages/pi-coding-agent/src/modes/interactive/utils/shorten-path.ts +14 -0
  384. package/packages/pi-coding-agent/src/modes/print-mode.ts +2 -30
  385. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -28
  386. package/packages/pi-coding-agent/src/modes/shared/command-context-actions.ts +53 -0
  387. package/packages/pi-coding-agent/src/utils/changelog.ts +1 -1
  388. package/packages/pi-coding-agent/src/utils/clipboard-image.ts +1 -1
  389. package/packages/pi-coding-agent/src/utils/error.ts +6 -0
  390. package/packages/pi-coding-agent/src/utils/photon.ts +0 -137
  391. package/packages/pi-coding-agent/src/utils/tools-manager.ts +1 -1
  392. package/packages/pi-tui/dist/components/editor.d.ts +0 -10
  393. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  394. package/packages/pi-tui/dist/components/editor.js +1 -1
  395. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  396. package/packages/pi-tui/dist/components/markdown.d.ts +5 -0
  397. package/packages/pi-tui/dist/components/markdown.d.ts.map +1 -1
  398. package/packages/pi-tui/dist/components/markdown.js +25 -31
  399. package/packages/pi-tui/dist/components/markdown.js.map +1 -1
  400. package/packages/pi-tui/dist/keys.d.ts +0 -4
  401. package/packages/pi-tui/dist/keys.d.ts.map +1 -1
  402. package/packages/pi-tui/dist/keys.js +94 -162
  403. package/packages/pi-tui/dist/keys.js.map +1 -1
  404. package/packages/pi-tui/dist/overlay-layout.d.ts +55 -0
  405. package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -0
  406. package/packages/pi-tui/dist/overlay-layout.js +288 -0
  407. package/packages/pi-tui/dist/overlay-layout.js.map +1 -0
  408. package/packages/pi-tui/dist/tui.d.ts +0 -22
  409. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  410. package/packages/pi-tui/dist/tui.js +6 -272
  411. package/packages/pi-tui/dist/tui.js.map +1 -1
  412. package/packages/pi-tui/dist/utils.d.ts +0 -7
  413. package/packages/pi-tui/dist/utils.d.ts.map +1 -1
  414. package/packages/pi-tui/dist/utils.js +0 -44
  415. package/packages/pi-tui/dist/utils.js.map +1 -1
  416. package/packages/pi-tui/src/components/editor.ts +1 -1
  417. package/packages/pi-tui/src/components/markdown.ts +25 -29
  418. package/packages/pi-tui/src/keys.ts +94 -173
  419. package/packages/pi-tui/src/overlay-layout.ts +372 -0
  420. package/packages/pi-tui/src/tui.ts +11 -312
  421. package/packages/pi-tui/src/utils.ts +0 -43
  422. package/pkg/dist/core/export-html/ansi-to-html.d.ts +0 -4
  423. package/pkg/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  424. package/pkg/dist/core/export-html/ansi-to-html.js +1 -1
  425. package/pkg/dist/core/export-html/ansi-to-html.js.map +1 -1
  426. package/pkg/dist/modes/interactive/theme/theme.d.ts +65 -4
  427. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  428. package/pkg/dist/modes/interactive/theme/theme.js +6 -23
  429. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  430. package/pkg/dist/modes/interactive/theme/themes.d.ts +12 -0
  431. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -0
  432. package/pkg/dist/modes/interactive/theme/themes.js +175 -0
  433. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -0
  434. package/pkg/package.json +1 -1
  435. package/src/resources/extensions/async-jobs/await-tool.ts +0 -2
  436. package/src/resources/extensions/async-jobs/job-manager.ts +0 -7
  437. package/src/resources/extensions/bg-shell/output-formatter.ts +0 -17
  438. package/src/resources/extensions/bg-shell/process-manager.ts +0 -4
  439. package/src/resources/extensions/bg-shell/types.ts +0 -12
  440. package/src/resources/extensions/context7/index.ts +7 -0
  441. package/src/resources/extensions/get-secrets-from-user.ts +2 -35
  442. package/src/resources/extensions/google-search/index.ts +7 -0
  443. package/src/resources/extensions/gsd/auto-dispatch.ts +49 -1
  444. package/src/resources/extensions/gsd/auto-loop.ts +22 -2
  445. package/src/resources/extensions/gsd/auto-model-selection.ts +23 -2
  446. package/src/resources/extensions/gsd/auto-recovery.ts +39 -0
  447. package/src/resources/extensions/gsd/auto-start.ts +42 -2
  448. package/src/resources/extensions/gsd/auto.ts +61 -3
  449. package/src/resources/extensions/gsd/changelog.ts +213 -0
  450. package/src/resources/extensions/gsd/commands-bootstrap.ts +1 -0
  451. package/src/resources/extensions/gsd/commands-handlers.ts +2 -2
  452. package/src/resources/extensions/gsd/commands-inspect.ts +10 -3
  453. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +5 -1
  454. package/src/resources/extensions/gsd/commands-rate.ts +55 -0
  455. package/src/resources/extensions/gsd/commands.ts +52 -2
  456. package/src/resources/extensions/gsd/docs/preferences-reference.md +10 -0
  457. package/src/resources/extensions/gsd/doctor-checks.ts +107 -5
  458. package/src/resources/extensions/gsd/doctor-environment.ts +26 -16
  459. package/src/resources/extensions/gsd/doctor-proactive.ts +24 -0
  460. package/src/resources/extensions/gsd/doctor-types.ts +9 -1
  461. package/src/resources/extensions/gsd/doctor.ts +35 -0
  462. package/src/resources/extensions/gsd/files.ts +12 -2
  463. package/src/resources/extensions/gsd/gitignore.ts +54 -7
  464. package/src/resources/extensions/gsd/guided-flow.ts +12 -4
  465. package/src/resources/extensions/gsd/health-widget-core.ts +129 -0
  466. package/src/resources/extensions/gsd/health-widget.ts +103 -59
  467. package/src/resources/extensions/gsd/index.ts +30 -33
  468. package/src/resources/extensions/gsd/migrate-external.ts +47 -2
  469. package/src/resources/extensions/gsd/milestone-ids.ts +3 -2
  470. package/src/resources/extensions/gsd/paths.ts +73 -7
  471. package/src/resources/extensions/gsd/post-unit-hooks.ts +5 -1
  472. package/src/resources/extensions/gsd/preferences-validation.ts +54 -1
  473. package/src/resources/extensions/gsd/preferences.ts +16 -1
  474. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  475. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -0
  476. package/src/resources/extensions/gsd/roadmap-mutations.ts +66 -0
  477. package/src/resources/extensions/gsd/session-lock.ts +59 -2
  478. package/src/resources/extensions/gsd/state.ts +2 -1
  479. package/src/resources/extensions/gsd/templates/plan.md +8 -0
  480. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +46 -0
  481. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +98 -2
  482. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +59 -3
  483. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +20 -0
  484. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +214 -0
  485. package/src/resources/extensions/gsd/tests/health-widget.test.ts +158 -0
  486. package/src/resources/extensions/gsd/tests/paths.test.ts +113 -0
  487. package/src/resources/extensions/gsd/tests/preferences.test.ts +40 -2
  488. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +26 -0
  489. package/src/resources/extensions/gsd/tests/test-utils.ts +165 -0
  490. package/src/resources/extensions/gsd/tests/validate-directory.test.ts +15 -0
  491. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +7 -0
  492. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +32 -0
  493. package/src/resources/extensions/gsd/worktree-resolver.ts +11 -0
  494. package/src/resources/extensions/mcp-client/index.ts +2 -1
  495. package/src/resources/extensions/remote-questions/remote-command.ts +2 -23
  496. package/src/resources/extensions/shared/mod.ts +1 -1
  497. package/src/resources/extensions/shared/sanitize.ts +36 -0
  498. package/src/resources/extensions/subagent/index.ts +6 -12
  499. package/src/resources/skills/create-gsd-extension/references/events-reference.md +4 -4
  500. package/dist/resources/extensions/shared/wizard-ui.js +0 -478
  501. package/packages/pi-coding-agent/dist/modes/interactive/theme/dark.json +0 -85
  502. package/packages/pi-coding-agent/dist/modes/interactive/theme/light.json +0 -84
  503. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.json +0 -335
  504. package/packages/pi-coding-agent/src/modes/interactive/theme/dark.json +0 -85
  505. package/packages/pi-coding-agent/src/modes/interactive/theme/light.json +0 -84
  506. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.json +0 -335
  507. package/pkg/dist/modes/interactive/theme/dark.json +0 -85
  508. package/pkg/dist/modes/interactive/theme/light.json +0 -84
  509. package/pkg/dist/modes/interactive/theme/theme-schema.json +0 -335
  510. 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;