zidane 9.1.14 → 9.1.16

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 (286) hide show
  1. package/dist/acp-cli.js +10 -10
  2. package/dist/{acp-CNLIFVV9.js → acp-fylEUqkx.js} +11 -11
  3. package/dist/{acp-CNLIFVV9.js.map → acp-fylEUqkx.js.map} +1 -1
  4. package/dist/acp.d.ts +2 -2
  5. package/dist/acp.js +1 -1
  6. package/dist/{agent-B_RXMaJN.js → agent-DFUxWdyg.js} +61 -155
  7. package/dist/agent-DFUxWdyg.js.map +1 -0
  8. package/dist/agent.d.ts +1 -1
  9. package/dist/agent.js +2 -2
  10. package/dist/{allowed-tools-CVcayWT7.js → allowed-tools-WLqA9mVe.js} +3 -3
  11. package/dist/{allowed-tools-CVcayWT7.js.map → allowed-tools-WLqA9mVe.js.map} +1 -1
  12. package/dist/{anthropic-Bsz-QTFD.js → anthropic-DlLGsijI.js} +5 -5
  13. package/dist/{anthropic-Bsz-QTFD.js.map → anthropic-DlLGsijI.js.map} +1 -1
  14. package/dist/{auth-store-port-7YV5Ecs_.js → auth-store-port-CWl5l-4U.js} +2 -2
  15. package/dist/{auth-store-port-7YV5Ecs_.js.map → auth-store-port-CWl5l-4U.js.map} +1 -1
  16. package/dist/{auto-update-restart-CiYNo3ey.js → auto-update-restart-DZ0hfstQ.js} +33 -33
  17. package/dist/{auto-update-restart-CiYNo3ey.js.map → auto-update-restart-DZ0hfstQ.js.map} +1 -1
  18. package/dist/{browser-entry-DQtxFXNM.d.ts → browser-entry-B5lDeRIa.d.ts} +4 -4
  19. package/dist/{browser-entry-DQtxFXNM.d.ts.map → browser-entry-B5lDeRIa.d.ts.map} +1 -1
  20. package/dist/channels.d.ts +5 -5
  21. package/dist/channels.js +1 -1
  22. package/dist/chat/browser.d.ts +3 -3
  23. package/dist/chat/browser.js +2 -2
  24. package/dist/chat/pure.d.ts +4 -4
  25. package/dist/chat/pure.js +1 -1
  26. package/dist/chat.d.ts +4 -4
  27. package/dist/chat.js +17 -17
  28. package/dist/{cli-shared-B1DuVD1x.js → cli-shared-By7xZXZ9.js} +4 -4
  29. package/dist/{cli-shared-B1DuVD1x.js.map → cli-shared-By7xZXZ9.js.map} +1 -1
  30. package/dist/{client-QWwqT6rw.d.ts → client-C1K4hh7B.d.ts} +2 -2
  31. package/dist/{client-QWwqT6rw.d.ts.map → client-C1K4hh7B.d.ts.map} +1 -1
  32. package/dist/{client-core-DBIK0mLO.d.ts → client-core-eugtzdxB.d.ts} +4 -4
  33. package/dist/{client-core-DBIK0mLO.d.ts.map → client-core-eugtzdxB.d.ts.map} +1 -1
  34. package/dist/{connection-loop-DV95THTm.d.ts → connection-loop-D4rfJNjP.d.ts} +4 -4
  35. package/dist/{connection-loop-DV95THTm.d.ts.map → connection-loop-D4rfJNjP.d.ts.map} +1 -1
  36. package/dist/{context-transport-CNkw7e59.js → context-transport-VqYIIzbN.js} +2 -2
  37. package/dist/{context-transport-CNkw7e59.js.map → context-transport-VqYIIzbN.js.map} +1 -1
  38. package/dist/contexts/daytona.d.ts +1 -1
  39. package/dist/contexts/daytona.js +1 -1
  40. package/dist/contexts/e2b.d.ts +1 -1
  41. package/dist/{credentials-DusprtsC.js → credentials-DCjZSZYv.js} +9 -9
  42. package/dist/{credentials-DusprtsC.js.map → credentials-DCjZSZYv.js.map} +1 -1
  43. package/dist/{cwd-picker-8b8wyRw_.js → cwd-picker-DHzlbyDU.js} +3 -3
  44. package/dist/{cwd-picker-8b8wyRw_.js.map → cwd-picker-DHzlbyDU.js.map} +1 -1
  45. package/dist/daemon-cli.js +3 -3
  46. package/dist/{daytona-Nr4g-WwO.js → daytona-gZ63sEYi.js} +2 -2
  47. package/dist/{daytona-Nr4g-WwO.js.map → daytona-gZ63sEYi.js.map} +1 -1
  48. package/dist/{debug-log-CT7yHyZC.js → debug-log-BgaYGg-6.js} +2 -2
  49. package/dist/{debug-log-CT7yHyZC.js.map → debug-log-BgaYGg-6.js.map} +1 -1
  50. package/dist/{decisions-CkQYLwAj.js → decisions-DZjZAVFe.js} +2 -2
  51. package/dist/{decisions-CkQYLwAj.js.map → decisions-DZjZAVFe.js.map} +1 -1
  52. package/dist/{discovery-BXU8LxYW.js → discovery-B19e1lR_.js} +6 -6
  53. package/dist/{discovery-BXU8LxYW.js.map → discovery-B19e1lR_.js.map} +1 -1
  54. package/dist/durable/sqlite.d.ts +2 -2
  55. package/dist/durable/sqlite.js +2 -2
  56. package/dist/durable.d.ts +1 -1
  57. package/dist/durable.js +1 -1
  58. package/dist/{engine-CIQGA6mR.js → engine-CabTSO_l.js} +5 -5
  59. package/dist/{engine-CIQGA6mR.js.map → engine-CabTSO_l.js.map} +1 -1
  60. package/dist/{environment-credentials-C2nLEpDJ.js → environment-credentials-C4iXqezG.js} +3 -3
  61. package/dist/{environment-credentials-C2nLEpDJ.js.map → environment-credentials-C4iXqezG.js.map} +1 -1
  62. package/dist/{errors-BOcRncxO.js → errors-DMUkkRXB.js} +4 -1
  63. package/dist/{errors-BOcRncxO.js.map → errors-DMUkkRXB.js.map} +1 -1
  64. package/dist/errors.d.ts +2 -2
  65. package/dist/errors.js +2 -2
  66. package/dist/{eval-CDb8jqv8.js → eval-BLMd9aGP.js} +4 -4
  67. package/dist/{eval-CDb8jqv8.js.map → eval-BLMd9aGP.js.map} +1 -1
  68. package/dist/eval.d.ts +1 -1
  69. package/dist/eval.js +1 -1
  70. package/dist/{executor-Dh7SvipK.js → executor-BWe1lts3.js} +2 -2
  71. package/dist/{executor-Dh7SvipK.js.map → executor-BWe1lts3.js.map} +1 -1
  72. package/dist/extensions/testing.d.ts +1 -1
  73. package/dist/extensions/testing.js +2 -2
  74. package/dist/{extensions-CZQGNuIo.js → extensions-D-SsXKa1.js} +8 -8
  75. package/dist/{extensions-CZQGNuIo.js.map → extensions-D-SsXKa1.js.map} +1 -1
  76. package/dist/{extensions-client-BqjGEKXz.d.ts → extensions-client-DEY47_KE.d.ts} +4 -4
  77. package/dist/{extensions-client-BqjGEKXz.d.ts.map → extensions-client-DEY47_KE.d.ts.map} +1 -1
  78. package/dist/extensions.d.ts +1 -1
  79. package/dist/extensions.js +5 -5
  80. package/dist/{fetch-url-CpNH8yBJ.js → fetch-url-Bi4dFdiC.js} +2 -2
  81. package/dist/{fetch-url-CpNH8yBJ.js.map → fetch-url-Bi4dFdiC.js.map} +1 -1
  82. package/dist/{fold-rules-B3axwe7R.d.ts → fold-rules-DQ-xV5NK.d.ts} +2 -2
  83. package/dist/{fold-rules-B3axwe7R.d.ts.map → fold-rules-DQ-xV5NK.d.ts.map} +1 -1
  84. package/dist/{google-CIV1r4wo.js → google-M4QkSSpL.js} +6 -6
  85. package/dist/{google-CIV1r4wo.js.map → google-M4QkSSpL.js.map} +1 -1
  86. package/dist/{headless-BNIg5W-5.js → headless-DKFo2gSY.js} +6 -6
  87. package/dist/{headless-BNIg5W-5.js.map → headless-DKFo2gSY.js.map} +1 -1
  88. package/dist/{headless-format-CvOd8YOP.js → headless-format-6tD5Yo3J.js} +3 -3
  89. package/dist/{headless-format-CvOd8YOP.js.map → headless-format-6tD5Yo3J.js.map} +1 -1
  90. package/dist/headless.d.ts +1 -1
  91. package/dist/headless.js +2 -2
  92. package/dist/{history-announce-C1GNdDNe.js → history-announce-BSfQ7-8k.js} +2 -2
  93. package/dist/{history-announce-C1GNdDNe.js.map → history-announce-BSfQ7-8k.js.map} +1 -1
  94. package/dist/history-worker.js +3 -3
  95. package/dist/{host-signals-DOfBZFxb.js → host-signals-DM_Xzcq_.js} +5 -5
  96. package/dist/{host-signals-DOfBZFxb.js.map → host-signals-DM_Xzcq_.js.map} +1 -1
  97. package/dist/{host-H6QiGbBp.js → host-uJizkMso.js} +12 -12
  98. package/dist/{host-H6QiGbBp.js.map → host-uJizkMso.js.map} +1 -1
  99. package/dist/{host-version-Cile5HOK.js → host-version-BJOeS7sf.js} +2 -2
  100. package/dist/{host-version-Cile5HOK.js.map → host-version-BJOeS7sf.js.map} +1 -1
  101. package/dist/{index-C1A0RHDG.d.ts → index-BJjEWOHI.d.ts} +9 -9
  102. package/dist/{index-C1A0RHDG.d.ts.map → index-BJjEWOHI.d.ts.map} +1 -1
  103. package/dist/{index-C6rzc-tt.d.ts → index-BZM8tu4L.d.ts} +44 -3
  104. package/dist/index-BZM8tu4L.d.ts.map +1 -0
  105. package/dist/{index-CaRlR8je.d.ts → index-CSrP8IT4.d.ts} +4 -4
  106. package/dist/{index-CaRlR8je.d.ts.map → index-CSrP8IT4.d.ts.map} +1 -1
  107. package/dist/index.d.ts +3 -3
  108. package/dist/index.js +35 -35
  109. package/dist/{interactions-protocol-DHEIwAf0.js → interactions-protocol-B51z46aG.js} +4 -2
  110. package/dist/interactions-protocol-B51z46aG.js.map +1 -0
  111. package/dist/{interpolate-PbifVQ5m.js → interpolate-B2JXLwZ_.js} +2 -2
  112. package/dist/{interpolate-PbifVQ5m.js.map → interpolate-B2JXLwZ_.js.map} +1 -1
  113. package/dist/ipc/browser-types.d.ts +42 -1
  114. package/dist/ipc/browser-types.d.ts.map +1 -1
  115. package/dist/ipc/browser.d.ts +3 -3
  116. package/dist/ipc/remote.d.ts +6 -6
  117. package/dist/ipc/remote.js +3 -3
  118. package/dist/ipc.d.ts +9 -9
  119. package/dist/ipc.js +8 -8
  120. package/dist/{links-DG9nLRcE.js → links-CQzInDNL.js} +8 -8
  121. package/dist/{links-DG9nLRcE.js.map → links-CQzInDNL.js.map} +1 -1
  122. package/dist/{loaded-entry-Cq98M9G6.js → loaded-entry-BIUop7YQ.js} +2 -2
  123. package/dist/{loaded-entry-Cq98M9G6.js.map → loaded-entry-BIUop7YQ.js.map} +1 -1
  124. package/dist/{mcp-f-bGGZWr.js → mcp-BbELoUcf.js} +3 -3
  125. package/dist/{mcp-f-bGGZWr.js.map → mcp-BbELoUcf.js.map} +1 -1
  126. package/dist/mcp.d.ts +1 -1
  127. package/dist/mcp.js +1 -1
  128. package/dist/{media-type-C4-zzcVm.d.ts → media-type-BfwpfY8z.d.ts} +6 -4
  129. package/dist/media-type-BfwpfY8z.d.ts.map +1 -0
  130. package/dist/{memory-B_AlonvP.js → memory-C7i3xfUK.js} +31 -31
  131. package/dist/{memory-B_AlonvP.js.map → memory-C7i3xfUK.js.map} +1 -1
  132. package/dist/{memory-B6hZdrvq.js → memory-Ddc9S26T.js} +2 -2
  133. package/dist/{memory-B6hZdrvq.js.map → memory-Ddc9S26T.js.map} +1 -1
  134. package/dist/{messages-CJfSVi7C.js → messages-Dk0N0lyy.js} +2 -2
  135. package/dist/{messages-CJfSVi7C.js.map → messages-Dk0N0lyy.js.map} +1 -1
  136. package/dist/{model-test-FWBNOTrM.js → model-test-BBn6heIR.js} +2 -2
  137. package/dist/{model-test-FWBNOTrM.js.map → model-test-BBn6heIR.js.map} +1 -1
  138. package/dist/{move-session-BQRMh2KP.js → move-session-DpXVAWUe.js} +3 -3
  139. package/dist/{move-session-BQRMh2KP.js.map → move-session-DpXVAWUe.js.map} +1 -1
  140. package/dist/{oauth-Dv-_W_gh.js → oauth-DXDy4q56.js} +2 -2
  141. package/dist/{oauth-Dv-_W_gh.js.map → oauth-DXDy4q56.js.map} +1 -1
  142. package/dist/{openai-h63vQhcu.js → openai-BAFg-2LW.js} +5 -5
  143. package/dist/{openai-h63vQhcu.js.map → openai-BAFg-2LW.js.map} +1 -1
  144. package/dist/{openai-compat-Cs8ZjU7a.js → openai-compat-D01UA-p6.js} +2 -2
  145. package/dist/{openai-compat-Cs8ZjU7a.js.map → openai-compat-D01UA-p6.js.map} +1 -1
  146. package/dist/{openrouter-Bq2Goqwl.js → openrouter-CqNTuIXi.js} +2 -2
  147. package/dist/{openrouter-Bq2Goqwl.js.map → openrouter-CqNTuIXi.js.map} +1 -1
  148. package/dist/output/stream-json.d.ts +1 -1
  149. package/dist/output/stream-json.js +1 -1
  150. package/dist/output/terminal.d.ts +1 -1
  151. package/dist/{path-display-D86C4tNR.js → path-display-C0DA5a7h.js} +3 -3
  152. package/dist/{path-display-D86C4tNR.js.map → path-display-C0DA5a7h.js.map} +1 -1
  153. package/dist/{plugins-CTXOe3uF.js → plugins-CUH-81TD.js} +2 -2
  154. package/dist/{plugins-CTXOe3uF.js.map → plugins-CUH-81TD.js.map} +1 -1
  155. package/dist/plugins.d.ts +1 -1
  156. package/dist/plugins.js +1 -1
  157. package/dist/{presets-BFe490bV.js → presets-DmGdfb1h.js} +3 -3
  158. package/dist/{presets-BFe490bV.js.map → presets-DmGdfb1h.js.map} +1 -1
  159. package/dist/presets.d.ts +1 -1
  160. package/dist/presets.js +1 -1
  161. package/dist/{protocol-BI4ouSmd.d.ts → protocol-BpIqbP7H.d.ts} +5 -5
  162. package/dist/{protocol-BI4ouSmd.d.ts.map → protocol-BpIqbP7H.d.ts.map} +1 -1
  163. package/dist/{provider-usage-format-a3XF5wwo.js → provider-usage-format-B3eaRZ3C.js} +2 -2
  164. package/dist/{provider-usage-format-a3XF5wwo.js.map → provider-usage-format-B3eaRZ3C.js.map} +1 -1
  165. package/dist/providers/anthropic.d.ts +1 -1
  166. package/dist/providers/anthropic.js +1 -1
  167. package/dist/providers/arcee.d.ts +1 -1
  168. package/dist/providers/arcee.js +1 -1
  169. package/dist/providers/baseten.d.ts +1 -1
  170. package/dist/providers/baseten.js +1 -1
  171. package/dist/providers/cerebras.d.ts +1 -1
  172. package/dist/providers/cerebras.js +1 -1
  173. package/dist/providers/google.d.ts +1 -1
  174. package/dist/providers/google.js +1 -1
  175. package/dist/providers/local.d.ts +1 -1
  176. package/dist/providers/local.js +1 -1
  177. package/dist/providers/neuralwatt.d.ts +1 -1
  178. package/dist/providers/neuralwatt.js +1 -1
  179. package/dist/providers/openai-compat.d.ts +1 -1
  180. package/dist/providers/openai-compat.js +1 -1
  181. package/dist/providers/openai.d.ts +1 -1
  182. package/dist/providers/openai.js +1 -1
  183. package/dist/providers/openrouter.d.ts +1 -1
  184. package/dist/providers/openrouter.js +1 -1
  185. package/dist/providers/xai.d.ts +1 -1
  186. package/dist/providers/xai.js +1 -1
  187. package/dist/{providers-BaXSunrg.js → providers-C8z2tHmr.js} +3 -3
  188. package/dist/{providers-BaXSunrg.js.map → providers-C8z2tHmr.js.map} +1 -1
  189. package/dist/{providers-D1R4pV9A.js → providers-sbsV3Dow.js} +2 -2
  190. package/dist/{providers-D1R4pV9A.js.map → providers-sbsV3Dow.js.map} +1 -1
  191. package/dist/providers.d.ts +1 -1
  192. package/dist/providers.js +8 -8
  193. package/dist/{read-state-BKsz2MGU.js → read-state-DjNe-x5w.js} +2 -2
  194. package/dist/{read-state-BKsz2MGU.js.map → read-state-DjNe-x5w.js.map} +1 -1
  195. package/dist/{readonly-db-CCipEHWH.js → readonly-db-DWkbo_i8.js} +3 -3
  196. package/dist/{readonly-db-CCipEHWH.js.map → readonly-db-DWkbo_i8.js.map} +1 -1
  197. package/dist/{registry-BRdTiDh6.js → registry-BNRZ5wbK.js} +2 -2
  198. package/dist/{registry-BRdTiDh6.js.map → registry-BNRZ5wbK.js.map} +1 -1
  199. package/dist/{registry-DwqeuuBp.js → registry-BdVIaVtY.js} +2 -2
  200. package/dist/{registry-DwqeuuBp.js.map → registry-BdVIaVtY.js.map} +1 -1
  201. package/dist/{registry-GSZteJD2.js → registry-VvjySKBj.js} +4 -4
  202. package/dist/{registry-GSZteJD2.js.map → registry-VvjySKBj.js.map} +1 -1
  203. package/dist/{remote-hosts-COJwOygg.js → remote-hosts-CqFvdema.js} +4 -4
  204. package/dist/{remote-hosts-COJwOygg.js.map → remote-hosts-CqFvdema.js.map} +1 -1
  205. package/dist/restate.d.ts +1 -1
  206. package/dist/restate.d.ts.map +1 -1
  207. package/dist/restate.js +7 -5
  208. package/dist/restate.js.map +1 -1
  209. package/dist/{run-fence-u3JLb97F.js → run-fence-DvsI_A_f.js} +2 -2
  210. package/dist/{run-fence-u3JLb97F.js.map → run-fence-DvsI_A_f.js.map} +1 -1
  211. package/dist/{server-C0J2gQM1.js → server-r63yA72Y.js} +4 -4
  212. package/dist/{server-C0J2gQM1.js.map → server-r63yA72Y.js.map} +1 -1
  213. package/dist/session/sqlite.d.ts +1 -1
  214. package/dist/session/sqlite.js +2 -2
  215. package/dist/{session-mSbW11Ip.js → session-BfVAbrAN.js} +159 -3
  216. package/dist/session-BfVAbrAN.js.map +1 -0
  217. package/dist/session.d.ts +1 -1
  218. package/dist/session.js +2 -2
  219. package/dist/{setting-reFf6GmB.js → setting-BYx02qvD.js} +9 -9
  220. package/dist/setting-BYx02qvD.js.map +1 -0
  221. package/dist/{settings-keys-5lsRFsnB.js → settings-keys-DrV5QupV.js} +2 -2
  222. package/dist/{settings-keys-5lsRFsnB.js.map → settings-keys-DrV5QupV.js.map} +1 -1
  223. package/dist/{skills-Cr8hsjhi.js → skills-BDBvOQvl.js} +4 -4
  224. package/dist/{skills-Cr8hsjhi.js.map → skills-BDBvOQvl.js.map} +1 -1
  225. package/dist/{skills-use-D5iu3SlV.js → skills-use-CFNAI-0X.js} +3 -3
  226. package/dist/{skills-use-D5iu3SlV.js.map → skills-use-CFNAI-0X.js.map} +1 -1
  227. package/dist/skills.d.ts +1 -1
  228. package/dist/skills.js +3 -3
  229. package/dist/{sqlite-runtime-B9D1ONFK.js → sqlite-runtime-8yVB1Xth.js} +4 -4
  230. package/dist/{sqlite-runtime-B9D1ONFK.js.map → sqlite-runtime-8yVB1Xth.js.map} +1 -1
  231. package/dist/{sqlite-runtime-DIm7NoKL.d.ts → sqlite-runtime-GC5dycgG.d.ts} +2 -2
  232. package/dist/sqlite-runtime-GC5dycgG.d.ts.map +1 -0
  233. package/dist/{sqlite-store-DeiWJzgB.js → sqlite-store-B25DaBQ9.js} +3 -3
  234. package/dist/{sqlite-store-DeiWJzgB.js.map → sqlite-store-B25DaBQ9.js.map} +1 -1
  235. package/dist/{sqlite-usage-BCndaumO.js → sqlite-usage-ws1FwwLX.js} +2 -2
  236. package/dist/{sqlite-usage-BCndaumO.js.map → sqlite-usage-ws1FwwLX.js.map} +1 -1
  237. package/dist/{src-DeX_eA-0.js → src-COaAqMYi.js} +4 -4
  238. package/dist/{src-DeX_eA-0.js.map → src-COaAqMYi.js.map} +1 -1
  239. package/dist/{store-CLEopFzP.js → store-DnMkgq_O.js} +3 -3
  240. package/dist/{store-CLEopFzP.js.map → store-DnMkgq_O.js.map} +1 -1
  241. package/dist/{system-freeze-DWfDARGA.js → system-freeze-DWJ2GyCG.js} +3 -3
  242. package/dist/{system-freeze-DWfDARGA.js.map → system-freeze-DWJ2GyCG.js.map} +1 -1
  243. package/dist/{timeout-Cz9dRF8Q.d.ts → timeout-Cyx3VGPz.d.ts} +27 -2
  244. package/dist/{timeout-Cz9dRF8Q.d.ts.map → timeout-Cyx3VGPz.d.ts.map} +1 -1
  245. package/dist/tools/fetch-url.d.ts +1 -1
  246. package/dist/tools/fetch-url.js +1 -1
  247. package/dist/tools/web-search.d.ts +1 -1
  248. package/dist/tools/web-search.js +2 -2
  249. package/dist/{tools-DLFy7bxx.js → tools-D8n2FgIk.js} +4 -4
  250. package/dist/{tools-DLFy7bxx.js.map → tools-D8n2FgIk.js.map} +1 -1
  251. package/dist/tools.d.ts +1 -1
  252. package/dist/tools.js +5 -5
  253. package/dist/tui.d.ts +11 -11
  254. package/dist/tui.js +32 -32
  255. package/dist/{types-1wGM0024.d.ts → types-D3VoG6Lp.d.ts} +2 -2
  256. package/dist/{types-1wGM0024.d.ts.map → types-D3VoG6Lp.d.ts.map} +1 -1
  257. package/dist/types-D5z_3G9j.js.map +1 -1
  258. package/dist/types.d.ts +2 -2
  259. package/dist/types.js +1 -1
  260. package/dist/{version-DqcCaf-_.js → version-rvHvyOuO.js} +2 -2
  261. package/dist/{version-DqcCaf-_.js.map → version-rvHvyOuO.js.map} +1 -1
  262. package/dist/{wait-task-Ck4XhjFg.js → wait-task-CkPNYwpm.js} +3 -3
  263. package/dist/{wait-task-Ck4XhjFg.js.map → wait-task-CkPNYwpm.js.map} +1 -1
  264. package/dist/{wire-DbP63Y8A.js → wire-BDJTQnec.js} +2 -2
  265. package/dist/{wire-DbP63Y8A.js.map → wire-BDJTQnec.js.map} +1 -1
  266. package/dist/{workspace-exec-stream-C6UKT6fv.js → workspace-exec-stream-DOEbNFwD.js} +2 -2
  267. package/dist/{workspace-exec-stream-C6UKT6fv.js.map → workspace-exec-stream-DOEbNFwD.js.map} +1 -1
  268. package/dist/{write-file-DDmmYHCP.js → write-file-PUIjMyBQ.js} +6 -6
  269. package/dist/{write-file-DDmmYHCP.js.map → write-file-PUIjMyBQ.js.map} +1 -1
  270. package/dist/{ws-BMFzJWKU.js → ws-bht1x_18.js} +4 -4
  271. package/dist/{ws-BMFzJWKU.js.map → ws-bht1x_18.js.map} +1 -1
  272. package/dist/{ws-client-CyC2uIrs.js → ws-client-DI9vhWPM.js} +2 -2
  273. package/dist/{ws-client-CyC2uIrs.js.map → ws-client-DI9vhWPM.js.map} +1 -1
  274. package/dist/{xai-CrTQbLVe.js → xai-B0Zoc_3K.js} +3 -3
  275. package/dist/{xai-CrTQbLVe.js.map → xai-B0Zoc_3K.js.map} +1 -1
  276. package/docs/ARCHITECTURE.md +1 -0
  277. package/docs/DURABILITY.md +1 -1
  278. package/docs/RESTATE.md +2 -0
  279. package/package.json +1 -1
  280. package/dist/agent-B_RXMaJN.js.map +0 -1
  281. package/dist/index-C6rzc-tt.d.ts.map +0 -1
  282. package/dist/interactions-protocol-DHEIwAf0.js.map +0 -1
  283. package/dist/media-type-C4-zzcVm.d.ts.map +0 -1
  284. package/dist/session-mSbW11Ip.js.map +0 -1
  285. package/dist/setting-reFf6GmB.js.map +0 -1
  286. package/dist/sqlite-runtime-DIm7NoKL.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-Dv-_W_gh.js","names":[],"sources":["../src/providers/oauth-registry.ts","../src/providers/anthropic-oauth-error.ts","../src/providers/oauth.ts"],"sourcesContent":["/**\n * Local OAuth provider registry.\n *\n * pi-ai 0.80.8 removed its global OAuth registry (`registerOAuthProvider`,\n * `getOAuthApiKey`, `OAuthProviderInterface`) and the public low-level\n * refresh helpers in favor of canonical `Provider.auth.oauth` objects\n * resolved through a `Models` collection + `CredentialStore`. zidane's\n * credential architecture (shared `.credentials.json`, cross-process refresh\n * locks in `./oauth.ts`, themed login flows in `src/chat/oauth-page/`)\n * predates that and owns storage itself, so this module reproduces the\n * removed registry surface locally with the same semantics.\n *\n * Nothing protocol-level is duplicated here: token refresh for the built-in\n * providers delegates to pi-ai's canonical `auth.oauth.refresh` flows via the\n * public `providers/*` subpaths (lazily imported, so processes that never\n * authenticate don't load provider code).\n */\n\nimport type { OAuthAuth } from '@earendil-works/pi-ai'\nimport type { OAuthCredentials, OAuthLoginCallbacks } from '@earendil-works/pi-ai/oauth'\nimport { errorMessage } from '../errors'\nimport { GOOGLE_VERTEX_OAUTH_ID, refreshGoogleToken } from './google-oauth'\n\n/**\n * Provider-owned OAuth flow. Mirrors the interface pi-ai exported from\n * `@earendil-works/pi-ai/oauth` up to 0.80.6 — kept as a local type so\n * zidane's descriptor seam (`ProviderDescriptor.oauthProvider`) and provider\n * extensions (e.g. `extensions/bolt`) stay source-compatible across the\n * upstream removal.\n */\nexport interface OAuthProviderInterface {\n /** Unique id of the flow, used as the registry key and credentials-file key. */\n readonly id: string\n /** Display name of the provider. */\n readonly name: string\n\n /** Run the login flow, return credentials to persist. */\n login: (callbacks: OAuthLoginCallbacks) => Promise<OAuthCredentials>\n\n /** Whether login uses a local callback server and supports manual code input. */\n usesCallbackServer?: boolean\n\n /**\n * Login honors zidane's `callbackServer: false`: for a client of a remote\n * host it binds no loopback listener and reads the redirect from\n * `onManualCodeInput` (`awaitAuthorizationCode` in `zidane/oauth` does\n * both). Declaring it lets the flow run from another computer.\n */\n supportsRemoteCallback?: boolean\n\n /** Refresh expired credentials, return updated credentials to persist. */\n refreshToken: (credentials: OAuthCredentials) => Promise<OAuthCredentials>\n\n /** Convert credentials to an API key string for the provider. */\n getApiKey: (credentials: OAuthCredentials) => string\n}\n\n/**\n * Run a canonical pi-ai `OAuthAuth.refresh` from a bare refresh token.\n * pi-ai's built-in refresh implementations only read `credential.refresh`,\n * so the placeholder access/expires fields are never observed.\n *\n * The canonical result is an `OAuthCredential` tagged `type: 'oauth'`. Strip\n * the tag before returning: refresh results get merged into stored\n * `.credentials.json` entries and `onOAuthRefresh` hook payloads (see\n * `resolveOAuthApiKey` in `./oauth.ts`), whose documented shape carries\n * zidane's own `kind` tag — letting pi-ai's `type` leak through would\n * silently drift the on-disk shape.\n */\nasync function refreshViaCanonicalFlow(\n providerId: string,\n oauth: OAuthAuth | undefined,\n refreshToken: string,\n): Promise<OAuthCredentials> {\n if (!oauth)\n throw new Error(`pi-ai provider ${providerId} exposes no OAuth flow`)\n // pi-ai 0.84 made `signal` a required second argument. These refreshers are\n // called from token-expiry paths that carry no cancellation of their own, so\n // a never-aborting signal keeps the pre-0.84 behavior exactly — same idiom as\n // `completion-core.ts`.\n const { type: _type, ...credentials }\n = await oauth.refresh(\n { type: 'oauth', access: '', refresh: refreshToken, expires: 0 },\n new AbortController().signal,\n )\n return credentials\n}\n\n/**\n * pi-ai ≥ 0.85 loads each OAuth flow module through a VARIABLE specifier\n * (`auth/oauth/load.js`: `import(rewrite(\"./anthropic.ts\"))`) precisely so\n * bundlers cannot follow it. Fine under plain Node/Bun where the file sits\n * next to `load.js`; fatal inside anything bundled — the compiled `zidane`\n * binary, the packaged Electron main — where the refresh path died with\n * `Cannot find module './anthropic.js'` and the user was told to re-run auth\n * for a token that was perfectly renewable.\n *\n * pi-ai ships the escape hatch for exactly this: `bun-oauth` statically\n * imports every flow and registers them with the loader. We call it lazily,\n * once, right before the first refresh — a static specifier the bundler DOES\n * follow — so every host (TUI binary, GUI, daemon, SDK) refreshes the same\n * way. Idempotent; failure to register falls through to the loader's own\n * behavior (works unbundled, so nothing gets worse).\n */\nlet bundledFlowsReady: Promise<void> | null = null\nexport function ensureBundledOAuthFlows(): Promise<void> {\n bundledFlowsReady ??= import('@earendil-works/pi-ai/bun-oauth')\n .then(({ registerBunOAuthFlows }) => {\n registerBunOAuthFlows()\n })\n .catch(() => {\n bundledFlowsReady = null\n })\n return bundledFlowsReady\n}\n\n/**\n * Refresh an Anthropic (Claude Pro/Max) OAuth token. Drop-in replacement for\n * the `refreshAnthropicToken` pi-ai exported until 0.80.6; delegates to the\n * canonical flow on `anthropicProvider().auth.oauth`.\n *\n * @param refreshToken - Refresh token of the stored credentials.\n */\nexport async function refreshAnthropicToken(refreshToken: string): Promise<OAuthCredentials> {\n await ensureBundledOAuthFlows()\n const { anthropicProvider } = await import('@earendil-works/pi-ai/providers/anthropic')\n return refreshViaCanonicalFlow('anthropic', anthropicProvider().auth.oauth, refreshToken)\n}\n\n/**\n * Refresh an OpenAI Codex (ChatGPT) OAuth token. Drop-in replacement for the\n * removed `refreshOpenAICodexToken`; the canonical flow still derives\n * `accountId` from the refreshed access token's JWT claims, so the returned\n * credentials keep the extra field older callers persisted.\n *\n * @param refreshToken - Refresh token of the stored credentials.\n */\nexport async function refreshOpenAICodexToken(refreshToken: string): Promise<OAuthCredentials> {\n await ensureBundledOAuthFlows()\n const { openaiCodexProvider } = await import('@earendil-works/pi-ai/providers/openai-codex')\n return refreshViaCanonicalFlow('openai-codex', openaiCodexProvider().auth.oauth, refreshToken)\n}\n\n/**\n * Built-in registry seeds. Every id whose stored credential can expire has to\n * be seeded here, because zidane's lazy token refresh (`getOAuthApiKey` inside\n * `resolveOAuthApiKey`) resolves through the registry — an unseeded id is not a\n * degraded path but a dead end, with no way to renew the session. That is wider\n * than the Anthropic / OpenAI Codex pair pi-ai's removed registry pre-seeded:\n * flows zidane implements itself (xAI) need seeding just as much.\n *\n * Login is intentionally unsupported here: interactive login always goes\n * through `ProviderDescriptor.oauthProvider` (the themed flows in\n * `src/chat/oauth-page/`), never through the registry.\n */\nfunction builtinProvider(\n id: string,\n name: string,\n refreshToken: (credentials: OAuthCredentials) => Promise<OAuthCredentials>,\n): OAuthProviderInterface {\n return {\n id,\n name,\n login: async () => {\n throw new Error(`OAuth login for ${id} must run through a provider descriptor flow, not the registry`)\n },\n refreshToken,\n getApiKey: credentials => credentials.access,\n }\n}\n\n/**\n * Seed id for the xAI Grok OAuth flow. Duplicated from\n * `XAI_OAUTH_PROVIDER_ID` in `../chat/oauth-page/xai` rather than imported:\n * that module pulls in `node:http` and the PKCE helpers at module scope, and\n * this registry is loaded by every consumer that resolves a credential. The\n * ids are pinned together by a test, so the duplication cannot drift.\n */\nconst XAI_SEED_ID = 'xai-oauth'\n\n/**\n * Refresh an xAI Grok token. Imported lazily so seeding the registry does not\n * drag the login flow's `node:http` callback server into every consumer —\n * and so the static import edge back to this module stays type-only, leaving\n * no runtime cycle.\n *\n * Unlike the Anthropic / Codex seeds, this receives the FULL credential rather\n * than a bare refresh token: xAI stores its resolved `token_endpoint` (and the\n * cached discovery doc) alongside the tokens, and dropping them would force a\n * fresh OIDC discovery round-trip on every refresh — and discard the validated\n * endpoint that `refreshXaiToken` re-checks before posting the refresh token\n * to it.\n */\nasync function refreshXaiTokenSeed(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n const { refreshXaiToken } = await import('../chat/oauth-page/xai')\n return refreshXaiToken(credentials)\n}\n\n/**\n * Seed id for the Cursor OAuth flow. Duplicated from\n * `CURSOR_OAUTH_PROVIDER_ID` for the same reason as {@link XAI_SEED_ID}, and\n * pinned to it by a test.\n */\nconst CURSOR_SEED_ID = 'cursor'\n\n/**\n * Refresh a Cursor token. Lazy for the same reason as the xAI seed: the login\n * module owns a callback server, and seeding must not drag it into every\n * consumer that merely resolves a credential.\n */\nasync function refreshCursorTokenSeed(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n const { refreshCursorToken } = await import('../chat/oauth-page/cursor')\n return refreshCursorToken(credentials)\n}\n\n/**\n * Exported so tests that register a throwaway provider can remove it from the\n * same slot rather than re-deriving the key with a copied string: the registry\n * exposes no unregister, and a `Symbol.for` looked up from a duplicated literal\n * would silently stop matching if this key were ever renamed, leaving the test\n * provider resident in shared state. Deliberately kept out of the package's\n * public surface — `./index.ts` re-exports this module by explicit name list.\n */\nexport const REGISTRY_SLOT = Symbol.for('zidane.oauth-provider-registry')\n\n/**\n * Ids of the flows seeded below. Extension providers can't take them over\n * (`src/extensions/provider-oauth.ts`): that would route the refresh of the\n * user's own Claude, ChatGPT, Grok, Cursor or Google tokens through extension\n * code. Pinned to the seed list by a test.\n */\nexport const BUILTIN_OAUTH_PROVIDER_IDS: ReadonlySet<string> = new Set([\n 'anthropic',\n 'openai-codex',\n XAI_SEED_ID,\n CURSOR_SEED_ID,\n GOOGLE_VERTEX_OAUTH_ID,\n])\n\n/**\n * The registry map is anchored on a process-wide `globalThis` slot rather\n * than module state. The pi-ai registry this replaces lived in pi-ai's own\n * module, so every copy of zidane code in a process shared one map — and two\n * copies is a real configuration, not a hypothetical: a host running from\n * `src` while a disk-loaded extension resolves `'zidane'` to `dist` through\n * ordinary node_modules resolution (see `import()` in\n * `src/extensions/discovery.ts`). The extension registers its flow at setup;\n * `resolveOAuthApiKey` looks it up only once a stored token expires — with\n * per-module maps that fails as a deferred \"Unknown OAuth provider\", which is\n * nasty to debug. `Symbol.for` restores the process-wide sharing. Whichever\n * copy touches the slot first seeds the built-ins, so a `dist` consumer can end\n * up refreshing through the `src` copy's closure (and vice versa). That is\n * harmless because the seeds are STATELESS refresh delegations — they close over\n * no module state and no configuration, so the two copies compute the same\n * result from the same stored credential. It is that property, not where the\n * refresh happens to be implemented, that makes first-copy-wins safe: it holds\n * equally for the seeds that delegate to pi-ai's canonical flows and for the\n * xAI one implemented in `../chat/oauth-page/xai`.\n */\nfunction oauthProviderRegistry(): Map<string, OAuthProviderInterface> {\n const slots = globalThis as { [key: symbol]: Map<string, OAuthProviderInterface> | undefined }\n slots[REGISTRY_SLOT] ??= new Map(\n [\n builtinProvider('anthropic', 'Anthropic (Claude Pro/Max)', c => refreshAnthropicToken(c.refresh)),\n builtinProvider('openai-codex', 'OpenAI (ChatGPT Plus/Pro)', c => refreshOpenAICodexToken(c.refresh)),\n // xAI is NOT built into pi-ai, so unlike the two above there is no\n // canonical flow to delegate to — `../chat/oauth-page/xai` implements it.\n // It is seeded here anyway because seeding is what makes refresh work for\n // consumers that never import `chat/providers.ts` or `auth.ts`, whose\n // module-scope `registerXaiOAuthProvider()` call is otherwise the ONLY\n // thing that registers it. A library consumer resolving a stored\n // credential through `getOAuthApiKey` got `Unknown OAuth provider:\n // xai-oauth` and had no way to renew a session — a dead end rather than a\n // degraded path. The interactive login half still comes from\n // `registerXaiOAuthProvider(renderPage)`, which replaces this seed.\n builtinProvider(XAI_SEED_ID, 'xAI Grok (SuperGrok / X Premium+)', refreshXaiTokenSeed),\n // Cursor has the identical shape: its flow lives in\n // `../chat/oauth-page/cursor`, which registers it only as a module-scope\n // side effect of importing `chat/providers.ts` / `auth.ts`.\n builtinProvider(CURSOR_SEED_ID, 'Cursor', refreshCursorTokenSeed),\n // The Vertex provider renews its \"Sign in with Google\" grant through\n // `resolveOAuthApiKey`, so the refresh must resolve with no sign-in UI\n // registered. It lives in the core (`./google-oauth`, no callback server)\n // and is imported directly; the grant carries the OAuth client it was\n // minted with, which is why seeds get the FULL credential.\n builtinProvider(GOOGLE_VERTEX_OAUTH_ID, 'Google (Vertex AI)', refreshGoogleToken),\n ].map(provider => [provider.id, provider]),\n )\n return slots[REGISTRY_SLOT]\n}\n\n/**\n * Register (or replace) an OAuth provider by id.\n * @param provider - Flow to register. Replaces any flow with the same `id`.\n */\nexport function registerOAuthProvider(provider: OAuthProviderInterface): void {\n oauthProviderRegistry().set(provider.id, provider)\n}\n\n/**\n * Remove a flow registered with {@link registerOAuthProvider}, but only while\n * it is still the one registered under its id: a newer registration of the\n * same id (a reloaded extension, another live registry) survives. Built-in\n * flows are never removed.\n *\n * @param provider - The flow object that was registered.\n * @returns Whether it was removed.\n */\nexport function unregisterOAuthProvider(provider: OAuthProviderInterface): boolean {\n if (BUILTIN_OAUTH_PROVIDER_IDS.has(provider.id))\n return false\n const registry = oauthProviderRegistry()\n if (registry.get(provider.id) !== provider)\n return false\n return registry.delete(provider.id)\n}\n\n/**\n * Get a registered OAuth provider by id.\n * @param id - Id of the flow to look up.\n */\nexport function getOAuthProvider(id: string): OAuthProviderInterface | undefined {\n return oauthProviderRegistry().get(id)\n}\n\n/**\n * Get an API key for a provider from OAuth credentials, refreshing expired\n * tokens through the registered flow. Same contract as the pi-ai original\n * (`null` when no credentials are stored for the provider, throws on unknown\n * provider or refresh failure), with two deliberate additions:\n *\n * - refresh failures keep the underlying reason — the original discarded it,\n * leaving invalid_grant (needs re-login) indistinguishable from a transient\n * network error.\n * - `options.force` rotates regardless of the local expiry, for 401 recovery\n * when the server revoked the grant before our stored timestamp said so.\n * Expressed as a flag rather than by handing this function a credential\n * with a doctored `expires`: callers persist whatever comes back, so a\n * fabricated expiry that a provider echoes through would land in the\n * credential store. See `resolveOAuthApiKey` in `./oauth.ts`.\n *\n * @param providerId - Id of the registered flow.\n * @param credentials - Stored credentials keyed by provider id.\n * @param options - Set `force` to refresh even when the credential has not expired.\n */\nexport async function getOAuthApiKey(\n providerId: string,\n credentials: Record<string, OAuthCredentials>,\n options?: { force?: boolean },\n): Promise<{ newCredentials: OAuthCredentials, apiKey: string } | null> {\n const provider = oauthProviderRegistry().get(providerId)\n if (!provider)\n throw new Error(`Unknown OAuth provider: ${providerId}`)\n\n let creds = credentials[providerId]\n if (!creds)\n return null\n\n if (needsRefresh(creds, options?.force)) {\n try {\n creds = await provider.refreshToken(creds)\n }\n catch (err) {\n throw new Error(`Failed to refresh OAuth token for ${providerId}: ${errorMessage(err)}`, { cause: err })\n }\n }\n\n return { newCredentials: creds, apiKey: provider.getApiKey(creds) }\n}\n\nfunction needsRefresh(credentials: OAuthCredentials, force?: boolean): boolean {\n return force === true || Date.now() >= credentials.expires\n}\n\n/**\n * The API key {@link getOAuthApiKey} would return without refreshing: set when\n * `providerId` is registered and `credentials` have not expired, else\n * `undefined` (the caller takes the refresh path).\n */\nexport function freshOAuthApiKey(providerId: string, credentials: OAuthCredentials): string | undefined {\n const provider = oauthProviderRegistry().get(providerId)\n if (!provider || needsRefresh(credentials))\n return undefined\n return provider.getApiKey(credentials)\n}\n","type RefreshFailure = 'sign-in' | 'retry' | 'account' | 'upgrade' | 'unknown'\n\n/** What a refresh failure's reason says to do: sign in again, retry, see an admin, upgrade, or nothing known. */\nexport function classifyRefreshFailure(reason: string): RefreshFailure {\n // Classify evidence, not a bare 401/403 or the generic refresh wrapper.\n if (/\\bclaude(?: code)?\\b.+(?:outdated|unsupported version|version .*?(?:required|newer)|upgrade|update your)/i.test(reason)\n || /\\b(?:outdated|unsupported) claude(?: code)?\\b/i.test(reason)) {\n return 'upgrade'\n }\n if (/\\b(?:invalid_scope|insufficient_scope|permission_denied|access_denied|permission denied|insufficient scope|insufficient permissions?)\\b|\\b(?:organization|organisation|org|enterprise)\\b.{1,80}\\b(?:policy|disabled|restricted|denied|not allowed)\\b/i.test(reason))\n return 'account'\n if (/\\binvalid_grant\\b|\\b(?:token|grant|credentials?)\\b.{1,40}\\b(?:has been |was |is )?revoked\\b|\\brevoked (?:token|grant|credentials?)\\b/i.test(reason))\n return 'sign-in'\n if (/\\b(?:fetch failed|failed to fetch|network|ECONNRESET|ECONNREFUSED|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|timeout|timed out|temporarily_unavailable|server_error|rate_limit(?:_exceeded)?|too many requests|service unavailable)\\b|\\b(?:HTTP|status|failed:)(?:\\s*[:=])?\\s*(?:5\\d\\d|429|408)\\b/i.test(reason))\n return 'retry'\n return 'unknown'\n}\n\n/** Keep the resolver's preserved reason; only explicit grant rejection warrants login. */\nexport function anthropicOAuthRefreshError(reason: string, providerId?: string): string {\n const prefix = providerId\n ? `OAuth token refresh failed for \"${providerId}\".`\n : 'Anthropic OAuth token refresh failed.'\n let guidance: string\n switch (classifyRefreshFailure(reason)) {\n case 'sign-in':\n guidance = providerId ? 'Sign in again.' : 'Sign in again with `bun run auth --anthropic`.'\n break\n case 'retry':\n guidance = 'Check connectivity or service availability, then retry.'\n break\n case 'account':\n guidance = 'Check account access and organization policy with your administrator; repeated login may not help.'\n break\n case 'upgrade':\n guidance = 'Upgrade and restart the running app or daemon to update its Claude client compatibility.'\n break\n default:\n guidance = 'Inspect the underlying error before changing credentials.'\n }\n return `${prefix} ${guidance} ${reason}`\n}\n","import type { OAuthCredentials } from '@earendil-works/pi-ai/oauth'\nimport type { StreamCallbacks } from '.'\nimport type { AuthFailure, AuthFailureKind } from '../errors'\nimport type { OAuthRefreshHookContext } from '../types'\nimport { Buffer } from 'node:buffer'\nimport { randomUUID } from 'node:crypto'\nimport { existsSync, linkSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from 'node:fs'\nimport { homedir, hostname } from 'node:os'\nimport { dirname, resolve } from 'node:path'\nimport { isDeepStrictEqual } from 'node:util'\nimport { writeFileAtomic } from '../atomic-write'\nimport { credentialSlotOf } from '../chat/cred-keys'\nimport { AgentAuthError, errorMessage } from '../errors'\nimport { classifyRefreshFailure } from './anthropic-oauth-error'\nimport { freshOAuthApiKey, getOAuthApiKey, registerOAuthProvider } from './oauth-registry'\n\ntype GetOAuthApiKey = typeof getOAuthApiKey\n\n/**\n * Resolve the creds-file path at call time rather than module-load time, so\n * env changes between import and first OAuth use (test suites, multi-project\n * CLIs) are honored.\n *\n * Order:\n * 1. `ZIDANE_CREDENTIALS_PATH` — explicit override. The chat host sets this\n * at launch to point at the credentials file in its storage directory, so\n * the harness providers find the same file the host manages.\n * 2. `~/.credentials.json` — home-anchored default.\n *\n * The working directory is never consulted: launching zidane inside an\n * untrusted checkout would let that repo plant a `.credentials.json` and\n * become the credential source (and receive rotated refresh tokens on the next\n * refresh persist). Same trust model as the TUI's legacy-file migration in\n * `chat/credentials.ts`, which only honors the home-anchored location.\n */\nexport function credentialsFilePath(): string {\n return process.env.ZIDANE_CREDENTIALS_PATH ?? resolve(homedir(), '.credentials.json')\n}\n\n/**\n * POSIX mode for credentials on disk. Read+write for the owner only — refresh\n * tokens and API keys leak if the file is world-readable on a shared box.\n * Ignored on Windows.\n */\nconst CREDENTIALS_FILE_MODE = 0o600\n\ninterface RefreshResult {\n apiKey: string\n event?: OAuthRefreshHookContext\n}\n\nconst refreshLocks = new Map<string, Promise<RefreshResult>>()\nconst storeIds = new WeakMap<object, number>()\nlet nextStoreId = 0\nfunction identity(value: object): number {\n let id = storeIds.get(value)\n if (id === undefined) {\n id = ++nextStoreId\n storeIds.set(value, id)\n }\n return id\n}\n\n/**\n * Register a custom OAuth flow with the local registry (`./oauth-registry`)\n * so lazy refresh through {@link resolveOAuthApiKey} can resolve `providerId`.\n *\n * Public because provider extensions need it: without registration,\n * `getOAuthApiKey('<id>', …)` throws `Unknown OAuth provider` the first time a\n * stored token expires. Idempotent per id (the registry is a keyed map).\n * Returns a promise for API stability.\n *\n * @param provider - OAuth flow definition to register, keyed by its `id`.\n */\nexport async function registerCustomOAuthProvider(\n provider: import('./oauth-registry').OAuthProviderInterface,\n): Promise<void> {\n registerOAuthProvider(provider)\n}\n\n/** Credential params shared by OAuth-capable providers: a static key or runtime OAuth credentials. */\nexport interface OAuthParams {\n /** Static API key or OAuth access token sent as is, bypassing credential lookup and refresh. */\n apiKey?: string\n /** OAuth access token supplied at runtime. Used together with `refresh` and `expires` to refresh without a credentials file. */\n access?: string\n /** OAuth refresh token supplied at runtime. */\n refresh?: string\n /** Expiry of `access` as a Unix timestamp in milliseconds. */\n expires?: number\n /**\n * Run on ONE stored account of the provider instead of its active one: the\n * credential's stable id (`ProviderCredential.id`, see `chat/credentials`).\n * Resolved to the slot holding it on every token read and refresh, so\n * promoting another account mid-session never moves this provider to it.\n * The provider's env key is ignored while pinned (it is the active\n * credential's, not this account's). A missing account fails the call with\n * {@link pinnedAccountMissingError} — never a silent fallback to another\n * account.\n */\n account?: string\n}\n\n/**\n * Why a call pinned to `account` cannot run: the account is no longer stored.\n *\n * @param provider - Provider name as the user knows it, put in the message.\n */\nexport function pinnedAccountMissingError(provider: string): string {\n return `The ${provider} account this session runs on is no longer signed in. Sign in again, or pick another account in the model picker.`\n}\n\n/**\n * The stored OAuth credential of `baseKey` whose stable id is `account`, as\n * the provider-side reader sees it; `undefined` when no slot holds it.\n *\n * @param baseKey - Provider key the credential is stored under (e.g. `anthropic`).\n * @param account - Stable id of the account to read.\n * @param path - Credentials file; defaults to the user's.\n */\nexport function readAccountOAuthCredential(baseKey: string, account: string, path = credentialsFilePath()): OAuthCredentials | undefined {\n const all = readOAuthCredentialsAt(resolve(path))\n const slot = credentialSlotOf(all, baseKey, account)\n return slot ? all[slot] : undefined\n}\n\n/**\n * Whether a credential string is an OAuth *access token* rather than a real,\n * static API key. Anthropic OAuth tokens are prefixed `sk-ant-oat`; OpenAI\n * Codex OAuth access tokens are JWTs (`eyJ...`). Used to decide whether an\n * env-provided value can be refreshed (OAuth) or must be sent verbatim (API key).\n *\n * @param value - Credential string to classify.\n */\nexport function isOAuthAccessToken(value: string): boolean {\n return value.startsWith('sk-ant-oat') || isJwtLikeAccessToken(value)\n}\n\nfunction isJwtLikeAccessToken(value: string): boolean {\n const parts = value.split('.')\n if (parts.length !== 3 || !parts[0]?.startsWith('eyJ'))\n return false\n try {\n const header = JSON.parse(Buffer.from(parts[0], 'base64url').toString('utf8')) as unknown\n return Boolean(header && typeof header === 'object' && 'alg' in header)\n }\n catch {\n return false\n }\n}\n\n/**\n * Pull a complete `{ access, refresh, expires }` triple out of provider params\n * when (and only when) all three OAuth fields are present and well-typed.\n * Returns `undefined` for the static-api-key path. Shared by the OAuth-capable\n * providers so the runtime-credential guard can't drift between them.\n *\n * @param params - Provider params that may carry runtime OAuth credentials.\n */\nexport function extractRuntimeCredentials(\n params?: OAuthParams,\n): { access: string, refresh: string, expires: number } | undefined {\n if (\n typeof params?.access === 'string'\n && typeof params.refresh === 'string'\n && typeof params.expires === 'number'\n ) {\n return { access: params.access, refresh: params.refresh, expires: params.expires }\n }\n return undefined\n}\n\n/** Options for {@link resolveOAuthApiKey}. */\nexport interface ResolveOAuthApiKeyOptions<TParams extends OAuthParams = OAuthParams> {\n /** Provider name used in error messages and in the refresh event. */\n provider: string\n /** Id of the registered OAuth flow and the default credentials-file key. */\n providerId: string\n /** Provider params. A static `apiKey`, runtime credentials or a pinned `account` take precedence over the credentials file. */\n params?: TParams\n /** Name of an environment variable holding a static key. Used when the value is not an OAuth access token, or when no stored credential exists. */\n envKey?: string\n /** Extra keys of `params` copied into the runtime credentials, for providers whose credentials carry more than `access`, `refresh` and `expires`. */\n extraCredentialKeys?: (keyof TParams & string)[]\n /** Message of the error thrown when no credential is found. */\n missingError: string\n /** Builds the message of the error thrown when refreshing fails. Receives the failure reason. */\n refreshError: (reason: string) => string\n /** Reads the credentials store. Defaults to the shared credentials file. */\n readCredentials?: () => Record<string, OAuthCredentials | undefined>\n /** Synchronous provider-local patch writer; injected stores own cross-process coordination. */\n writeCredentials?: (credentials: Record<string, OAuthCredentials | undefined>) => void\n /** Replaces the registry lookup that exchanges stored credentials for an API key and refreshes them when expired. */\n getOAuthApiKey?: GetOAuthApiKey\n /**\n * Force a refresh even when the credential's local expiry is still in the\n * future (for one-shot 401 recovery). Reaches the refresh helper as an\n * explicit flag, so no credential with a fabricated expiry ever exists to\n * leak into the store — see {@link getOAuthApiKey}.\n */\n forceRefresh?: boolean\n /** Access token rejected by the server; a different token found under lock is reused instead of rotated again. */\n rejectedAccess?: string\n /**\n * Credentials-file key to read and persist, when it differs from\n * `providerId`. A provider holding several OAuth accounts parks the\n * non-active ones under sibling keys (`anthropic#account:1`); refreshing one\n * of those must rotate THAT slot, under its own lock, while the registered\n * flow is still looked up by `providerId`. Defaults to `providerId`.\n */\n credentialKey?: string\n /**\n * Credentials file to use instead of {@link credentialsFilePath}. Callers that\n * already know the data directory (the usage probes) pass it so the default\n * store's locking and coalescing apply to the right file without depending\n * on `ZIDANE_CREDENTIALS_PATH` having been exported.\n */\n credentialsPath?: string\n /** What signs in with this credential, for the {@link AgentAuthError} a failure throws. Defaults to `provider`. */\n authSource?: AuthFailure['source']\n}\n\n/**\n * Read the shared credentials file.\n *\n * Returns `{}` when the file is missing OR when the file exists but is corrupted\n * / not valid JSON. Corrupt-file tolerance is important: the refresh-then-persist\n * path below writes atomically, but older builds wrote in place and could have\n * truncated the file on a crash. Treating corruption as \"no stored creds\" lets\n * users re-auth without manually deleting the file.\n *\n * Supports two on-disk shapes:\n * 1. **Legacy** (untagged): `{ \"anthropic\": { access, refresh, expires, ... } }`\n * — written by older `bun run auth`.\n * 2. **New** (kind-tagged): `{ \"anthropic\": { kind: 'oauth', access, refresh, expires, ... } }`\n * — written by the TUI. Entries with `kind: 'apikey'` are skipped — those\n * reach providers via env vars set at TUI launch (see `applyApiKeyEnv`).\n */\nexport function readOAuthCredentials(): Record<string, OAuthCredentials | undefined> {\n return readOAuthCredentialsAt(credentialsFilePath())\n}\n\nfunction readOAuthCredentialsAt(path: string): Record<string, OAuthCredentials | undefined> {\n if (!existsSync(path))\n return {}\n\n try {\n const raw = readFileSync(path, 'utf-8')\n const parsed = JSON.parse(raw)\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))\n return {}\n const result: Record<string, OAuthCredentials | undefined> = {}\n for (const [key, value] of Object.entries(parsed)) {\n if (!value || typeof value !== 'object' || Array.isArray(value))\n continue\n const v = value as Record<string, unknown>\n // New schema: explicit `kind` tag.\n if (v.kind === 'apikey')\n continue\n // Both new (`kind: 'oauth'`) and legacy (untagged) entries have `access`;\n // the harmless `kind` field is allowed by `OAuthCredentials`'s\n // `[key: string]: unknown` index signature. Validate the required\n // fields explicitly so the assignment doesn't need a double-cast.\n if (\n typeof v.access === 'string'\n && typeof v.refresh === 'string'\n && typeof v.expires === 'number'\n ) {\n result[key] = { ...v, access: v.access, refresh: v.refresh, expires: v.expires }\n }\n }\n return result\n }\n catch {\n return {}\n }\n}\n\nfunction processAlive(pid: number): boolean {\n try {\n process.kill(pid, 0)\n return true\n }\n catch (err) {\n return (err as NodeJS.ErrnoException).code === 'EPERM'\n }\n}\n\n/**\n * Age past which a lock whose holder cannot be checked is abandoned. Every\n * holder releases within seconds: a refresh is one token request with a 30 s\n * timeout, a credentials write is synchronous.\n */\nconst UNJUDGED_LOCK_STALE_MS = 2 * 60_000\n\n/**\n * Remove a lock whose holder process is gone (killed mid-refresh, its\n * `finally` never ran). Moved aside first so a lock taken meanwhile is\n * never deleted: a live one moved by mistake is put back without clobbering.\n */\nfunction evictDeadHolder(lockPath: string): boolean {\n let owner: string\n let modified: number\n try {\n owner = readFileSync(lockPath, 'utf8')\n modified = statSync(lockPath).mtimeMs\n }\n catch {\n return false\n }\n // `pid:host:uuid`. A pid recorded under another host name (shared home,\n // container, or this Mac after its name changed with the network) or an\n // unreadable record says nothing about the holder: evict it only once it\n // is older than any holder keeps a lock.\n const parts = owner.split(':')\n const pid = Number(parts[0])\n const judged = parts.slice(1, -1).join(':') === hostname() && Number.isInteger(pid) && pid > 0\n if (judged ? processAlive(pid) : Date.now() - modified < UNJUDGED_LOCK_STALE_MS)\n return false\n const aside = `${lockPath}.${randomUUID()}.stale`\n try {\n renameSync(lockPath, aside)\n }\n catch {\n return false\n }\n let same = false\n try {\n same = readFileSync(aside, 'utf8') === owner\n }\n catch { /* Unreadable: treat as not the judged record. */ }\n if (!same) {\n try {\n linkSync(aside, lockPath)\n }\n catch { /* Someone holds the name again. */ }\n }\n rmSync(aside, { force: true })\n return same\n}\n\n/**\n * Never steal a lock from a live holder on this host based on age: a suspended\n * holder may still own it. A lock whose recorded pid no longer exists on this\n * host is taken over, and so is an old one whose holder cannot be checked.\n */\nfunction tryAcquireLock(lockPath: string, evict = true): (() => void) | undefined {\n const owner = `${process.pid}:${hostname()}:${randomUUID()}`\n try {\n writeFileSync(lockPath, owner, { flag: 'wx', mode: CREDENTIALS_FILE_MODE })\n }\n catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'EEXIST')\n return evict && evictDeadHolder(lockPath) ? tryAcquireLock(lockPath, false) : undefined\n throw err\n }\n return () => {\n try {\n if (readFileSync(lockPath, 'utf8') === owner)\n unlinkSync(lockPath)\n }\n catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT')\n throw err\n }\n }\n}\n\n/**\n * Run `fn` while holding the cross-process lock `<path>.lock`. Polls every 20 ms\n * and throws after 2 seconds without the lock. Shared by refresh persistence\n * and interactive credential mutations.\n *\n * @param path - Credentials file the lock guards.\n * @param fn - Synchronous work to run under the lock.\n */\nexport function withCredentialsLock<T>(path: string, fn: () => T): T {\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 })\n const deadline = Date.now() + 2000\n let release = tryAcquireLock(`${path}.lock`)\n while (!release) {\n if (Date.now() >= deadline)\n throw new Error('Timed out waiting for credentials lock')\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 20)\n release = tryAcquireLock(`${path}.lock`)\n }\n try {\n return fn()\n }\n finally {\n release()\n }\n}\n\n/** How long a refresh waits for another process's refresh of the same credential. */\nconst REFRESH_LOCK_WAIT_MS = 30_000\n\n/**\n * Wait for the refresh lock at `lockPath`.\n *\n * @param lockPath - The lock file.\n * @param timedOut - The error to throw once the wait is over, given the holder's pid when it is on this host.\n */\nasync function acquireRefreshLock(lockPath: string, timedOut: (holderPid: number | undefined) => Error): Promise<() => void> {\n mkdirSync(dirname(lockPath), { recursive: true, mode: 0o700 })\n const deadline = Date.now() + REFRESH_LOCK_WAIT_MS\n while (true) {\n const release = tryAcquireLock(lockPath)\n if (release)\n return release\n if (Date.now() >= deadline)\n throw timedOut(lockHolderPid(lockPath))\n await new Promise(resolve => setTimeout(resolve, 50))\n }\n}\n\n/** The pid recorded in a lock (`pid:host:uuid`) when the holder runs on this host. */\nfunction lockHolderPid(lockPath: string): number | undefined {\n try {\n const parts = readFileSync(lockPath, 'utf8').split(':')\n const pid = Number(parts[0])\n return parts.slice(1, -1).join(':') === hostname() && Number.isInteger(pid) && pid > 0 ? pid : undefined\n }\n catch {\n return undefined\n }\n}\n\n/** A refresh failure's reason, as the kind of sign-in failure it is. */\nfunction refreshFailureKind(reason: string): AuthFailureKind {\n switch (classifyRefreshFailure(reason)) {\n case 'sign-in':\n return 'revoked'\n case 'retry':\n return 'network'\n default:\n return 'expired'\n }\n}\n\nfunction readRawCredentials(path: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf8'))\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))\n return parsed\n }\n catch { /* Missing or corrupt file. */ }\n return {}\n}\n\nfunction writeCredentialPatch(path: string, credentials: Record<string, unknown>): void {\n const merged = { ...readRawCredentials(path), ...credentials }\n for (const [key, value] of Object.entries(merged)) {\n if (value === undefined)\n delete merged[key]\n }\n writeFileAtomic(path, JSON.stringify(merged, null, 2), { mode: CREDENTIALS_FILE_MODE })\n}\n\n/**\n * Incoming entries are a provider-local patch, not a read-time snapshot.\n * @param credentials - Entries to merge into the credentials file. An `undefined` value removes that key.\n */\nexport function writeOAuthCredentials(credentials: Record<string, OAuthCredentials | undefined>) {\n const path = credentialsFilePath()\n withCredentialsLock(path, () => writeCredentialPatch(path, credentials))\n}\n\n/**\n * Builds OAuth credentials from the runtime `access`, `refresh` and `expires` params, plus any listed extra keys that are set. Returns `undefined` when one of the three is missing.\n *\n * @param params - Provider params that may carry runtime credentials.\n * @param extraKeys - Extra `params` keys to copy into the credentials.\n */\nexport function credentialsFromParams<TParams extends OAuthParams>(params?: TParams, extraKeys: (keyof TParams & string)[] = []): OAuthCredentials | undefined {\n if (typeof params?.access !== 'string' || typeof params.refresh !== 'string' || typeof params.expires !== 'number')\n return undefined\n\n const extras = Object.fromEntries(\n extraKeys\n .map(key => [key, params[key]])\n .filter(([, value]) => value !== undefined),\n )\n\n return {\n access: params.access,\n refresh: params.refresh,\n expires: params.expires,\n ...extras,\n }\n}\n\n/**\n * Resolves the API key for an OAuth provider.\n * Returns a static `apiKey`, runtime `access` token or env key as is, otherwise reads the stored credentials and refreshes them when expired. Refreshed credentials are persisted and concurrent refreshes of the same credential are shared. Throws `missingError` when no credential exists and `refreshError` when the refresh fails.\n *\n * @param options - Provider identity, credential sources and error messages.\n * @param callbacks - Hooks called with refresh events and credential-resolution stages.\n */\nexport async function resolveOAuthApiKey<TParams extends OAuthParams>(\n options: ResolveOAuthApiKeyOptions<TParams>,\n callbacks?: Pick<StreamCallbacks, 'onOAuthRefresh'> & { onOAuthStage?: (stage: 'credentials' | 'refresh' | 'shared-refresh') => void },\n): Promise<string> {\n if (typeof options.params?.apiKey === 'string') {\n if (isOAuthAccessToken(options.params.apiKey))\n callbacks?.onOAuthStage?.('credentials')\n return options.params.apiKey\n }\n const paramsCredentials = credentialsFromParams(options.params, options.extraCredentialKeys)\n if (!paramsCredentials && typeof options.params?.access === 'string') {\n callbacks?.onOAuthStage?.('credentials')\n return options.params.access\n }\n\n // Capture the store before awaiting: environment changes cannot redirect writes.\n const path = resolve(options.credentialsPath ?? credentialsFilePath())\n const usingDefaultStore = !options.readCredentials && !options.writeCredentials\n const read = options.readCredentials ?? (() => readOAuthCredentialsAt(path))\n const write = options.writeCredentials ?? (patch => withCredentialsLock(path, () => writeCredentialPatch(path, patch)))\n const baseKey = options.credentialKey ?? options.providerId\n // A pinned account names a credential, not a slot: find where it sits NOW.\n const pinned = paramsCredentials ? undefined : options.params?.account\n const pinnedSlot = pinned ? credentialSlotOf(read(), baseKey, pinned) : undefined\n const authFailure = (kind: AuthFailureKind, extra: Partial<AuthFailure> = {}): AuthFailure => ({\n kind,\n source: options.authSource ?? 'provider',\n provider: options.provider,\n providerId: options.providerId,\n ...extra,\n })\n if (pinned && !pinnedSlot)\n throw new AgentAuthError(pinnedAccountMissingError(options.provider), authFailure('missing', { accountId: pinned }))\n const slot = pinnedSlot ?? baseKey\n const envValue = options.envKey && !pinned ? process.env[options.envKey] : undefined\n if (!paramsCredentials && envValue && (!isOAuthAccessToken(envValue) || !read()[slot])) {\n if (isOAuthAccessToken(envValue))\n callbacks?.onOAuthStage?.('credentials')\n return envValue\n }\n\n callbacks?.onOAuthStage?.('credentials')\n const source = paramsCredentials ? 'params' : 'file'\n const initial = paramsCredentials ?? read()[slot]\n // Fast path for a stored credential that needs no refresh (the default\n // registry's rule): no refresh locks, re-read or persist, which on that path\n // only re-read the file and compared it. Runs once per turn.\n if (source === 'file' && initial && !options.forceRefresh && !options.getOAuthApiKey) {\n const apiKey = freshOAuthApiKey(options.providerId, initial)\n if (apiKey !== undefined)\n return apiKey\n }\n const store = usingDefaultStore ? path : [identity(options.readCredentials ?? readOAuthCredentials), identity(options.writeCredentials ?? writeOAuthCredentials)]\n const key = JSON.stringify([source, options.providerId, slot, source === 'file' ? store : null, initial, options.forceRefresh === true, options.rejectedAccess, identity(options.getOAuthApiKey ?? getOAuthApiKey)])\n // Promotion, renames and id backfills move a pinned account between slots:\n // lock it by id, and find its slot again right before each read and write.\n const slotNow = (): string | undefined => pinned ? credentialSlotOf(read(), baseKey, pinned) : slot\n // An unpinned refresh of an account with an id takes the same lock as a pinned one.\n const initialId = (initial as { id?: unknown } | undefined)?.id\n const accountId = pinned ?? (source === 'file' && typeof initialId === 'string' ? initialId : undefined)\n const lockName = accountId ? `${baseKey}@${accountId}` : slot\n const initialLabel = (initial as { label?: unknown } | undefined)?.label\n const account: Partial<AuthFailure> = {\n ...(accountId ? { accountId } : {}),\n ...(typeof initialLabel === 'string' && initialLabel ? { accountLabel: initialLabel } : {}),\n }\n const lockTimedOut = (holderPid: number | undefined): Error => new AgentAuthError(\n `Another zidane process${holderPid ? ` (pid ${holderPid})` : ''} has been refreshing the ${options.provider} sign-in for ${REFRESH_LOCK_WAIT_MS / 1000}s without finishing. Retry, or sign in again if it keeps happening.`,\n authFailure('busy', { ...account, ...(holderPid ? { holderPid } : {}) }),\n )\n\n let task = refreshLocks.get(key)\n if (task)\n callbacks?.onOAuthStage?.('shared-refresh')\n if (!task) {\n task = run()\n refreshLocks.set(key, task)\n // Delete before callbacks run; a failing subscriber must not poison peers.\n void task.finally(() => refreshLocks.delete(key)).catch(() => {})\n }\n const result = await task\n if (result.event) {\n await callbacks?.onOAuthRefresh?.({\n ...structuredClone(result.event),\n provider: options.provider,\n })\n }\n return result.apiKey\n\n async function run(): Promise<RefreshResult> {\n const releases: Array<() => void> = []\n try {\n if (source === 'file' && usingDefaultStore) {\n // @deprecated Drop the legacy lock in the release after this one: v8.0.4 locks the slot, not the account.\n // Taking the legacy slot lock first keeps them from spending the same refresh token.\n // Fixed order (legacy, then account) means two new processes cannot deadlock.\n if (lockName !== slot)\n releases.push(await acquireRefreshLock(`${path}.refresh-${encodeURIComponent(slot)}.lock`, lockTimedOut))\n releases.push(await acquireRefreshLock(`${path}.refresh-${encodeURIComponent(lockName)}.lock`, lockTimedOut))\n }\n const at = paramsCredentials ? slot : slotNow()\n const current = paramsCredentials ?? (at ? read()[at] : undefined)\n if (!current)\n throw new AgentAuthError(options.missingError, authFailure('missing', account))\n const generation = structuredClone(current)\n let result: Awaited<ReturnType<GetOAuthApiKey>>\n try {\n const stillRejected = options.rejectedAccess === undefined || current.access === options.rejectedAccess\n if (current.expires <= Date.now() || (options.forceRefresh && stillRejected))\n callbacks?.onOAuthStage?.('refresh')\n result = await (options.getOAuthApiKey ?? getOAuthApiKey)(\n options.providerId,\n { [options.providerId]: current },\n { force: options.forceRefresh === true && stillRejected },\n )\n }\n catch (err) {\n const reason = errorMessage(err)\n throw new AgentAuthError(options.refreshError(reason), authFailure(refreshFailureKind(reason), account), { cause: err })\n }\n if (!result)\n throw new AgentAuthError(options.refreshError(options.missingError), authFailure('missing', account))\n const refreshed = { ...generation, ...result.newCredentials }\n if (source === 'file') {\n const persist = () => {\n const target = slotNow()\n if (!target || !isDeepStrictEqual(read()[target], generation))\n throw new Error('OAuth credentials changed during refresh; retry with current credentials')\n if (result.newCredentials !== current) {\n const patch = { [target]: refreshed }\n if (usingDefaultStore)\n writeCredentialPatch(path, patch)\n else\n write(patch)\n }\n }\n if (usingDefaultStore)\n withCredentialsLock(path, persist)\n else\n persist()\n }\n return {\n apiKey: result.apiKey,\n ...(result.newCredentials !== current\n ? { event: {\n provider: options.provider,\n providerId: options.providerId,\n source,\n previousCredentials: generation,\n credentials: refreshed,\n } }\n : {}),\n }\n }\n finally {\n for (const release of releases.reverse())\n release()\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"oauth-DXDy4q56.js","names":[],"sources":["../src/providers/oauth-registry.ts","../src/providers/anthropic-oauth-error.ts","../src/providers/oauth.ts"],"sourcesContent":["/**\n * Local OAuth provider registry.\n *\n * pi-ai 0.80.8 removed its global OAuth registry (`registerOAuthProvider`,\n * `getOAuthApiKey`, `OAuthProviderInterface`) and the public low-level\n * refresh helpers in favor of canonical `Provider.auth.oauth` objects\n * resolved through a `Models` collection + `CredentialStore`. zidane's\n * credential architecture (shared `.credentials.json`, cross-process refresh\n * locks in `./oauth.ts`, themed login flows in `src/chat/oauth-page/`)\n * predates that and owns storage itself, so this module reproduces the\n * removed registry surface locally with the same semantics.\n *\n * Nothing protocol-level is duplicated here: token refresh for the built-in\n * providers delegates to pi-ai's canonical `auth.oauth.refresh` flows via the\n * public `providers/*` subpaths (lazily imported, so processes that never\n * authenticate don't load provider code).\n */\n\nimport type { OAuthAuth } from '@earendil-works/pi-ai'\nimport type { OAuthCredentials, OAuthLoginCallbacks } from '@earendil-works/pi-ai/oauth'\nimport { errorMessage } from '../errors'\nimport { GOOGLE_VERTEX_OAUTH_ID, refreshGoogleToken } from './google-oauth'\n\n/**\n * Provider-owned OAuth flow. Mirrors the interface pi-ai exported from\n * `@earendil-works/pi-ai/oauth` up to 0.80.6 — kept as a local type so\n * zidane's descriptor seam (`ProviderDescriptor.oauthProvider`) and provider\n * extensions (e.g. `extensions/bolt`) stay source-compatible across the\n * upstream removal.\n */\nexport interface OAuthProviderInterface {\n /** Unique id of the flow, used as the registry key and credentials-file key. */\n readonly id: string\n /** Display name of the provider. */\n readonly name: string\n\n /** Run the login flow, return credentials to persist. */\n login: (callbacks: OAuthLoginCallbacks) => Promise<OAuthCredentials>\n\n /** Whether login uses a local callback server and supports manual code input. */\n usesCallbackServer?: boolean\n\n /**\n * Login honors zidane's `callbackServer: false`: for a client of a remote\n * host it binds no loopback listener and reads the redirect from\n * `onManualCodeInput` (`awaitAuthorizationCode` in `zidane/oauth` does\n * both). Declaring it lets the flow run from another computer.\n */\n supportsRemoteCallback?: boolean\n\n /** Refresh expired credentials, return updated credentials to persist. */\n refreshToken: (credentials: OAuthCredentials) => Promise<OAuthCredentials>\n\n /** Convert credentials to an API key string for the provider. */\n getApiKey: (credentials: OAuthCredentials) => string\n}\n\n/**\n * Run a canonical pi-ai `OAuthAuth.refresh` from a bare refresh token.\n * pi-ai's built-in refresh implementations only read `credential.refresh`,\n * so the placeholder access/expires fields are never observed.\n *\n * The canonical result is an `OAuthCredential` tagged `type: 'oauth'`. Strip\n * the tag before returning: refresh results get merged into stored\n * `.credentials.json` entries and `onOAuthRefresh` hook payloads (see\n * `resolveOAuthApiKey` in `./oauth.ts`), whose documented shape carries\n * zidane's own `kind` tag — letting pi-ai's `type` leak through would\n * silently drift the on-disk shape.\n */\nasync function refreshViaCanonicalFlow(\n providerId: string,\n oauth: OAuthAuth | undefined,\n refreshToken: string,\n): Promise<OAuthCredentials> {\n if (!oauth)\n throw new Error(`pi-ai provider ${providerId} exposes no OAuth flow`)\n // pi-ai 0.84 made `signal` a required second argument. These refreshers are\n // called from token-expiry paths that carry no cancellation of their own, so\n // a never-aborting signal keeps the pre-0.84 behavior exactly — same idiom as\n // `completion-core.ts`.\n const { type: _type, ...credentials }\n = await oauth.refresh(\n { type: 'oauth', access: '', refresh: refreshToken, expires: 0 },\n new AbortController().signal,\n )\n return credentials\n}\n\n/**\n * pi-ai ≥ 0.85 loads each OAuth flow module through a VARIABLE specifier\n * (`auth/oauth/load.js`: `import(rewrite(\"./anthropic.ts\"))`) precisely so\n * bundlers cannot follow it. Fine under plain Node/Bun where the file sits\n * next to `load.js`; fatal inside anything bundled — the compiled `zidane`\n * binary, the packaged Electron main — where the refresh path died with\n * `Cannot find module './anthropic.js'` and the user was told to re-run auth\n * for a token that was perfectly renewable.\n *\n * pi-ai ships the escape hatch for exactly this: `bun-oauth` statically\n * imports every flow and registers them with the loader. We call it lazily,\n * once, right before the first refresh — a static specifier the bundler DOES\n * follow — so every host (TUI binary, GUI, daemon, SDK) refreshes the same\n * way. Idempotent; failure to register falls through to the loader's own\n * behavior (works unbundled, so nothing gets worse).\n */\nlet bundledFlowsReady: Promise<void> | null = null\nexport function ensureBundledOAuthFlows(): Promise<void> {\n bundledFlowsReady ??= import('@earendil-works/pi-ai/bun-oauth')\n .then(({ registerBunOAuthFlows }) => {\n registerBunOAuthFlows()\n })\n .catch(() => {\n bundledFlowsReady = null\n })\n return bundledFlowsReady\n}\n\n/**\n * Refresh an Anthropic (Claude Pro/Max) OAuth token. Drop-in replacement for\n * the `refreshAnthropicToken` pi-ai exported until 0.80.6; delegates to the\n * canonical flow on `anthropicProvider().auth.oauth`.\n *\n * @param refreshToken - Refresh token of the stored credentials.\n */\nexport async function refreshAnthropicToken(refreshToken: string): Promise<OAuthCredentials> {\n await ensureBundledOAuthFlows()\n const { anthropicProvider } = await import('@earendil-works/pi-ai/providers/anthropic')\n return refreshViaCanonicalFlow('anthropic', anthropicProvider().auth.oauth, refreshToken)\n}\n\n/**\n * Refresh an OpenAI Codex (ChatGPT) OAuth token. Drop-in replacement for the\n * removed `refreshOpenAICodexToken`; the canonical flow still derives\n * `accountId` from the refreshed access token's JWT claims, so the returned\n * credentials keep the extra field older callers persisted.\n *\n * @param refreshToken - Refresh token of the stored credentials.\n */\nexport async function refreshOpenAICodexToken(refreshToken: string): Promise<OAuthCredentials> {\n await ensureBundledOAuthFlows()\n const { openaiCodexProvider } = await import('@earendil-works/pi-ai/providers/openai-codex')\n return refreshViaCanonicalFlow('openai-codex', openaiCodexProvider().auth.oauth, refreshToken)\n}\n\n/**\n * Built-in registry seeds. Every id whose stored credential can expire has to\n * be seeded here, because zidane's lazy token refresh (`getOAuthApiKey` inside\n * `resolveOAuthApiKey`) resolves through the registry — an unseeded id is not a\n * degraded path but a dead end, with no way to renew the session. That is wider\n * than the Anthropic / OpenAI Codex pair pi-ai's removed registry pre-seeded:\n * flows zidane implements itself (xAI) need seeding just as much.\n *\n * Login is intentionally unsupported here: interactive login always goes\n * through `ProviderDescriptor.oauthProvider` (the themed flows in\n * `src/chat/oauth-page/`), never through the registry.\n */\nfunction builtinProvider(\n id: string,\n name: string,\n refreshToken: (credentials: OAuthCredentials) => Promise<OAuthCredentials>,\n): OAuthProviderInterface {\n return {\n id,\n name,\n login: async () => {\n throw new Error(`OAuth login for ${id} must run through a provider descriptor flow, not the registry`)\n },\n refreshToken,\n getApiKey: credentials => credentials.access,\n }\n}\n\n/**\n * Seed id for the xAI Grok OAuth flow. Duplicated from\n * `XAI_OAUTH_PROVIDER_ID` in `../chat/oauth-page/xai` rather than imported:\n * that module pulls in `node:http` and the PKCE helpers at module scope, and\n * this registry is loaded by every consumer that resolves a credential. The\n * ids are pinned together by a test, so the duplication cannot drift.\n */\nconst XAI_SEED_ID = 'xai-oauth'\n\n/**\n * Refresh an xAI Grok token. Imported lazily so seeding the registry does not\n * drag the login flow's `node:http` callback server into every consumer —\n * and so the static import edge back to this module stays type-only, leaving\n * no runtime cycle.\n *\n * Unlike the Anthropic / Codex seeds, this receives the FULL credential rather\n * than a bare refresh token: xAI stores its resolved `token_endpoint` (and the\n * cached discovery doc) alongside the tokens, and dropping them would force a\n * fresh OIDC discovery round-trip on every refresh — and discard the validated\n * endpoint that `refreshXaiToken` re-checks before posting the refresh token\n * to it.\n */\nasync function refreshXaiTokenSeed(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n const { refreshXaiToken } = await import('../chat/oauth-page/xai')\n return refreshXaiToken(credentials)\n}\n\n/**\n * Seed id for the Cursor OAuth flow. Duplicated from\n * `CURSOR_OAUTH_PROVIDER_ID` for the same reason as {@link XAI_SEED_ID}, and\n * pinned to it by a test.\n */\nconst CURSOR_SEED_ID = 'cursor'\n\n/**\n * Refresh a Cursor token. Lazy for the same reason as the xAI seed: the login\n * module owns a callback server, and seeding must not drag it into every\n * consumer that merely resolves a credential.\n */\nasync function refreshCursorTokenSeed(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n const { refreshCursorToken } = await import('../chat/oauth-page/cursor')\n return refreshCursorToken(credentials)\n}\n\n/**\n * Exported so tests that register a throwaway provider can remove it from the\n * same slot rather than re-deriving the key with a copied string: the registry\n * exposes no unregister, and a `Symbol.for` looked up from a duplicated literal\n * would silently stop matching if this key were ever renamed, leaving the test\n * provider resident in shared state. Deliberately kept out of the package's\n * public surface — `./index.ts` re-exports this module by explicit name list.\n */\nexport const REGISTRY_SLOT = Symbol.for('zidane.oauth-provider-registry')\n\n/**\n * Ids of the flows seeded below. Extension providers can't take them over\n * (`src/extensions/provider-oauth.ts`): that would route the refresh of the\n * user's own Claude, ChatGPT, Grok, Cursor or Google tokens through extension\n * code. Pinned to the seed list by a test.\n */\nexport const BUILTIN_OAUTH_PROVIDER_IDS: ReadonlySet<string> = new Set([\n 'anthropic',\n 'openai-codex',\n XAI_SEED_ID,\n CURSOR_SEED_ID,\n GOOGLE_VERTEX_OAUTH_ID,\n])\n\n/**\n * The registry map is anchored on a process-wide `globalThis` slot rather\n * than module state. The pi-ai registry this replaces lived in pi-ai's own\n * module, so every copy of zidane code in a process shared one map — and two\n * copies is a real configuration, not a hypothetical: a host running from\n * `src` while a disk-loaded extension resolves `'zidane'` to `dist` through\n * ordinary node_modules resolution (see `import()` in\n * `src/extensions/discovery.ts`). The extension registers its flow at setup;\n * `resolveOAuthApiKey` looks it up only once a stored token expires — with\n * per-module maps that fails as a deferred \"Unknown OAuth provider\", which is\n * nasty to debug. `Symbol.for` restores the process-wide sharing. Whichever\n * copy touches the slot first seeds the built-ins, so a `dist` consumer can end\n * up refreshing through the `src` copy's closure (and vice versa). That is\n * harmless because the seeds are STATELESS refresh delegations — they close over\n * no module state and no configuration, so the two copies compute the same\n * result from the same stored credential. It is that property, not where the\n * refresh happens to be implemented, that makes first-copy-wins safe: it holds\n * equally for the seeds that delegate to pi-ai's canonical flows and for the\n * xAI one implemented in `../chat/oauth-page/xai`.\n */\nfunction oauthProviderRegistry(): Map<string, OAuthProviderInterface> {\n const slots = globalThis as { [key: symbol]: Map<string, OAuthProviderInterface> | undefined }\n slots[REGISTRY_SLOT] ??= new Map(\n [\n builtinProvider('anthropic', 'Anthropic (Claude Pro/Max)', c => refreshAnthropicToken(c.refresh)),\n builtinProvider('openai-codex', 'OpenAI (ChatGPT Plus/Pro)', c => refreshOpenAICodexToken(c.refresh)),\n // xAI is NOT built into pi-ai, so unlike the two above there is no\n // canonical flow to delegate to — `../chat/oauth-page/xai` implements it.\n // It is seeded here anyway because seeding is what makes refresh work for\n // consumers that never import `chat/providers.ts` or `auth.ts`, whose\n // module-scope `registerXaiOAuthProvider()` call is otherwise the ONLY\n // thing that registers it. A library consumer resolving a stored\n // credential through `getOAuthApiKey` got `Unknown OAuth provider:\n // xai-oauth` and had no way to renew a session — a dead end rather than a\n // degraded path. The interactive login half still comes from\n // `registerXaiOAuthProvider(renderPage)`, which replaces this seed.\n builtinProvider(XAI_SEED_ID, 'xAI Grok (SuperGrok / X Premium+)', refreshXaiTokenSeed),\n // Cursor has the identical shape: its flow lives in\n // `../chat/oauth-page/cursor`, which registers it only as a module-scope\n // side effect of importing `chat/providers.ts` / `auth.ts`.\n builtinProvider(CURSOR_SEED_ID, 'Cursor', refreshCursorTokenSeed),\n // The Vertex provider renews its \"Sign in with Google\" grant through\n // `resolveOAuthApiKey`, so the refresh must resolve with no sign-in UI\n // registered. It lives in the core (`./google-oauth`, no callback server)\n // and is imported directly; the grant carries the OAuth client it was\n // minted with, which is why seeds get the FULL credential.\n builtinProvider(GOOGLE_VERTEX_OAUTH_ID, 'Google (Vertex AI)', refreshGoogleToken),\n ].map(provider => [provider.id, provider]),\n )\n return slots[REGISTRY_SLOT]\n}\n\n/**\n * Register (or replace) an OAuth provider by id.\n * @param provider - Flow to register. Replaces any flow with the same `id`.\n */\nexport function registerOAuthProvider(provider: OAuthProviderInterface): void {\n oauthProviderRegistry().set(provider.id, provider)\n}\n\n/**\n * Remove a flow registered with {@link registerOAuthProvider}, but only while\n * it is still the one registered under its id: a newer registration of the\n * same id (a reloaded extension, another live registry) survives. Built-in\n * flows are never removed.\n *\n * @param provider - The flow object that was registered.\n * @returns Whether it was removed.\n */\nexport function unregisterOAuthProvider(provider: OAuthProviderInterface): boolean {\n if (BUILTIN_OAUTH_PROVIDER_IDS.has(provider.id))\n return false\n const registry = oauthProviderRegistry()\n if (registry.get(provider.id) !== provider)\n return false\n return registry.delete(provider.id)\n}\n\n/**\n * Get a registered OAuth provider by id.\n * @param id - Id of the flow to look up.\n */\nexport function getOAuthProvider(id: string): OAuthProviderInterface | undefined {\n return oauthProviderRegistry().get(id)\n}\n\n/**\n * Get an API key for a provider from OAuth credentials, refreshing expired\n * tokens through the registered flow. Same contract as the pi-ai original\n * (`null` when no credentials are stored for the provider, throws on unknown\n * provider or refresh failure), with two deliberate additions:\n *\n * - refresh failures keep the underlying reason — the original discarded it,\n * leaving invalid_grant (needs re-login) indistinguishable from a transient\n * network error.\n * - `options.force` rotates regardless of the local expiry, for 401 recovery\n * when the server revoked the grant before our stored timestamp said so.\n * Expressed as a flag rather than by handing this function a credential\n * with a doctored `expires`: callers persist whatever comes back, so a\n * fabricated expiry that a provider echoes through would land in the\n * credential store. See `resolveOAuthApiKey` in `./oauth.ts`.\n *\n * @param providerId - Id of the registered flow.\n * @param credentials - Stored credentials keyed by provider id.\n * @param options - Set `force` to refresh even when the credential has not expired.\n */\nexport async function getOAuthApiKey(\n providerId: string,\n credentials: Record<string, OAuthCredentials>,\n options?: { force?: boolean },\n): Promise<{ newCredentials: OAuthCredentials, apiKey: string } | null> {\n const provider = oauthProviderRegistry().get(providerId)\n if (!provider)\n throw new Error(`Unknown OAuth provider: ${providerId}`)\n\n let creds = credentials[providerId]\n if (!creds)\n return null\n\n if (needsRefresh(creds, options?.force)) {\n try {\n creds = await provider.refreshToken(creds)\n }\n catch (err) {\n throw new Error(`Failed to refresh OAuth token for ${providerId}: ${errorMessage(err)}`, { cause: err })\n }\n }\n\n return { newCredentials: creds, apiKey: provider.getApiKey(creds) }\n}\n\nfunction needsRefresh(credentials: OAuthCredentials, force?: boolean): boolean {\n return force === true || Date.now() >= credentials.expires\n}\n\n/**\n * The API key {@link getOAuthApiKey} would return without refreshing: set when\n * `providerId` is registered and `credentials` have not expired, else\n * `undefined` (the caller takes the refresh path).\n */\nexport function freshOAuthApiKey(providerId: string, credentials: OAuthCredentials): string | undefined {\n const provider = oauthProviderRegistry().get(providerId)\n if (!provider || needsRefresh(credentials))\n return undefined\n return provider.getApiKey(credentials)\n}\n","type RefreshFailure = 'sign-in' | 'retry' | 'account' | 'upgrade' | 'unknown'\n\n/** What a refresh failure's reason says to do: sign in again, retry, see an admin, upgrade, or nothing known. */\nexport function classifyRefreshFailure(reason: string): RefreshFailure {\n // Classify evidence, not a bare 401/403 or the generic refresh wrapper.\n if (/\\bclaude(?: code)?\\b.+(?:outdated|unsupported version|version .*?(?:required|newer)|upgrade|update your)/i.test(reason)\n || /\\b(?:outdated|unsupported) claude(?: code)?\\b/i.test(reason)) {\n return 'upgrade'\n }\n if (/\\b(?:invalid_scope|insufficient_scope|permission_denied|access_denied|permission denied|insufficient scope|insufficient permissions?)\\b|\\b(?:organization|organisation|org|enterprise)\\b.{1,80}\\b(?:policy|disabled|restricted|denied|not allowed)\\b/i.test(reason))\n return 'account'\n if (/\\binvalid_grant\\b|\\b(?:token|grant|credentials?)\\b.{1,40}\\b(?:has been |was |is )?revoked\\b|\\brevoked (?:token|grant|credentials?)\\b/i.test(reason))\n return 'sign-in'\n if (/\\b(?:fetch failed|failed to fetch|network|ECONNRESET|ECONNREFUSED|ETIMEDOUT|ENOTFOUND|EAI_AGAIN|timeout|timed out|temporarily_unavailable|server_error|rate_limit(?:_exceeded)?|too many requests|service unavailable)\\b|\\b(?:HTTP|status|failed:)(?:\\s*[:=])?\\s*(?:5\\d\\d|429|408)\\b/i.test(reason))\n return 'retry'\n return 'unknown'\n}\n\n/** Keep the resolver's preserved reason; only explicit grant rejection warrants login. */\nexport function anthropicOAuthRefreshError(reason: string, providerId?: string): string {\n const prefix = providerId\n ? `OAuth token refresh failed for \"${providerId}\".`\n : 'Anthropic OAuth token refresh failed.'\n let guidance: string\n switch (classifyRefreshFailure(reason)) {\n case 'sign-in':\n guidance = providerId ? 'Sign in again.' : 'Sign in again with `bun run auth --anthropic`.'\n break\n case 'retry':\n guidance = 'Check connectivity or service availability, then retry.'\n break\n case 'account':\n guidance = 'Check account access and organization policy with your administrator; repeated login may not help.'\n break\n case 'upgrade':\n guidance = 'Upgrade and restart the running app or daemon to update its Claude client compatibility.'\n break\n default:\n guidance = 'Inspect the underlying error before changing credentials.'\n }\n return `${prefix} ${guidance} ${reason}`\n}\n","import type { OAuthCredentials } from '@earendil-works/pi-ai/oauth'\nimport type { StreamCallbacks } from '.'\nimport type { AuthFailure, AuthFailureKind } from '../errors'\nimport type { OAuthRefreshHookContext } from '../types'\nimport { Buffer } from 'node:buffer'\nimport { randomUUID } from 'node:crypto'\nimport { existsSync, linkSync, mkdirSync, readFileSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from 'node:fs'\nimport { homedir, hostname } from 'node:os'\nimport { dirname, resolve } from 'node:path'\nimport { isDeepStrictEqual } from 'node:util'\nimport { writeFileAtomic } from '../atomic-write'\nimport { credentialSlotOf } from '../chat/cred-keys'\nimport { AgentAuthError, errorMessage } from '../errors'\nimport { classifyRefreshFailure } from './anthropic-oauth-error'\nimport { freshOAuthApiKey, getOAuthApiKey, registerOAuthProvider } from './oauth-registry'\n\ntype GetOAuthApiKey = typeof getOAuthApiKey\n\n/**\n * Resolve the creds-file path at call time rather than module-load time, so\n * env changes between import and first OAuth use (test suites, multi-project\n * CLIs) are honored.\n *\n * Order:\n * 1. `ZIDANE_CREDENTIALS_PATH` — explicit override. The chat host sets this\n * at launch to point at the credentials file in its storage directory, so\n * the harness providers find the same file the host manages.\n * 2. `~/.credentials.json` — home-anchored default.\n *\n * The working directory is never consulted: launching zidane inside an\n * untrusted checkout would let that repo plant a `.credentials.json` and\n * become the credential source (and receive rotated refresh tokens on the next\n * refresh persist). Same trust model as the TUI's legacy-file migration in\n * `chat/credentials.ts`, which only honors the home-anchored location.\n */\nexport function credentialsFilePath(): string {\n return process.env.ZIDANE_CREDENTIALS_PATH ?? resolve(homedir(), '.credentials.json')\n}\n\n/**\n * POSIX mode for credentials on disk. Read+write for the owner only — refresh\n * tokens and API keys leak if the file is world-readable on a shared box.\n * Ignored on Windows.\n */\nconst CREDENTIALS_FILE_MODE = 0o600\n\ninterface RefreshResult {\n apiKey: string\n event?: OAuthRefreshHookContext\n}\n\nconst refreshLocks = new Map<string, Promise<RefreshResult>>()\nconst storeIds = new WeakMap<object, number>()\nlet nextStoreId = 0\nfunction identity(value: object): number {\n let id = storeIds.get(value)\n if (id === undefined) {\n id = ++nextStoreId\n storeIds.set(value, id)\n }\n return id\n}\n\n/**\n * Register a custom OAuth flow with the local registry (`./oauth-registry`)\n * so lazy refresh through {@link resolveOAuthApiKey} can resolve `providerId`.\n *\n * Public because provider extensions need it: without registration,\n * `getOAuthApiKey('<id>', …)` throws `Unknown OAuth provider` the first time a\n * stored token expires. Idempotent per id (the registry is a keyed map).\n * Returns a promise for API stability.\n *\n * @param provider - OAuth flow definition to register, keyed by its `id`.\n */\nexport async function registerCustomOAuthProvider(\n provider: import('./oauth-registry').OAuthProviderInterface,\n): Promise<void> {\n registerOAuthProvider(provider)\n}\n\n/** Credential params shared by OAuth-capable providers: a static key or runtime OAuth credentials. */\nexport interface OAuthParams {\n /** Static API key or OAuth access token sent as is, bypassing credential lookup and refresh. */\n apiKey?: string\n /** OAuth access token supplied at runtime. Used together with `refresh` and `expires` to refresh without a credentials file. */\n access?: string\n /** OAuth refresh token supplied at runtime. */\n refresh?: string\n /** Expiry of `access` as a Unix timestamp in milliseconds. */\n expires?: number\n /**\n * Run on ONE stored account of the provider instead of its active one: the\n * credential's stable id (`ProviderCredential.id`, see `chat/credentials`).\n * Resolved to the slot holding it on every token read and refresh, so\n * promoting another account mid-session never moves this provider to it.\n * The provider's env key is ignored while pinned (it is the active\n * credential's, not this account's). A missing account fails the call with\n * {@link pinnedAccountMissingError} — never a silent fallback to another\n * account.\n */\n account?: string\n}\n\n/**\n * Why a call pinned to `account` cannot run: the account is no longer stored.\n *\n * @param provider - Provider name as the user knows it, put in the message.\n */\nexport function pinnedAccountMissingError(provider: string): string {\n return `The ${provider} account this session runs on is no longer signed in. Sign in again, or pick another account in the model picker.`\n}\n\n/**\n * The stored OAuth credential of `baseKey` whose stable id is `account`, as\n * the provider-side reader sees it; `undefined` when no slot holds it.\n *\n * @param baseKey - Provider key the credential is stored under (e.g. `anthropic`).\n * @param account - Stable id of the account to read.\n * @param path - Credentials file; defaults to the user's.\n */\nexport function readAccountOAuthCredential(baseKey: string, account: string, path = credentialsFilePath()): OAuthCredentials | undefined {\n const all = readOAuthCredentialsAt(resolve(path))\n const slot = credentialSlotOf(all, baseKey, account)\n return slot ? all[slot] : undefined\n}\n\n/**\n * Whether a credential string is an OAuth *access token* rather than a real,\n * static API key. Anthropic OAuth tokens are prefixed `sk-ant-oat`; OpenAI\n * Codex OAuth access tokens are JWTs (`eyJ...`). Used to decide whether an\n * env-provided value can be refreshed (OAuth) or must be sent verbatim (API key).\n *\n * @param value - Credential string to classify.\n */\nexport function isOAuthAccessToken(value: string): boolean {\n return value.startsWith('sk-ant-oat') || isJwtLikeAccessToken(value)\n}\n\nfunction isJwtLikeAccessToken(value: string): boolean {\n const parts = value.split('.')\n if (parts.length !== 3 || !parts[0]?.startsWith('eyJ'))\n return false\n try {\n const header = JSON.parse(Buffer.from(parts[0], 'base64url').toString('utf8')) as unknown\n return Boolean(header && typeof header === 'object' && 'alg' in header)\n }\n catch {\n return false\n }\n}\n\n/**\n * Pull a complete `{ access, refresh, expires }` triple out of provider params\n * when (and only when) all three OAuth fields are present and well-typed.\n * Returns `undefined` for the static-api-key path. Shared by the OAuth-capable\n * providers so the runtime-credential guard can't drift between them.\n *\n * @param params - Provider params that may carry runtime OAuth credentials.\n */\nexport function extractRuntimeCredentials(\n params?: OAuthParams,\n): { access: string, refresh: string, expires: number } | undefined {\n if (\n typeof params?.access === 'string'\n && typeof params.refresh === 'string'\n && typeof params.expires === 'number'\n ) {\n return { access: params.access, refresh: params.refresh, expires: params.expires }\n }\n return undefined\n}\n\n/** Options for {@link resolveOAuthApiKey}. */\nexport interface ResolveOAuthApiKeyOptions<TParams extends OAuthParams = OAuthParams> {\n /** Provider name used in error messages and in the refresh event. */\n provider: string\n /** Id of the registered OAuth flow and the default credentials-file key. */\n providerId: string\n /** Provider params. A static `apiKey`, runtime credentials or a pinned `account` take precedence over the credentials file. */\n params?: TParams\n /** Name of an environment variable holding a static key. Used when the value is not an OAuth access token, or when no stored credential exists. */\n envKey?: string\n /** Extra keys of `params` copied into the runtime credentials, for providers whose credentials carry more than `access`, `refresh` and `expires`. */\n extraCredentialKeys?: (keyof TParams & string)[]\n /** Message of the error thrown when no credential is found. */\n missingError: string\n /** Builds the message of the error thrown when refreshing fails. Receives the failure reason. */\n refreshError: (reason: string) => string\n /** Reads the credentials store. Defaults to the shared credentials file. */\n readCredentials?: () => Record<string, OAuthCredentials | undefined>\n /** Synchronous provider-local patch writer; injected stores own cross-process coordination. */\n writeCredentials?: (credentials: Record<string, OAuthCredentials | undefined>) => void\n /** Replaces the registry lookup that exchanges stored credentials for an API key and refreshes them when expired. */\n getOAuthApiKey?: GetOAuthApiKey\n /**\n * Force a refresh even when the credential's local expiry is still in the\n * future (for one-shot 401 recovery). Reaches the refresh helper as an\n * explicit flag, so no credential with a fabricated expiry ever exists to\n * leak into the store — see {@link getOAuthApiKey}.\n */\n forceRefresh?: boolean\n /** Access token rejected by the server; a different token found under lock is reused instead of rotated again. */\n rejectedAccess?: string\n /**\n * Credentials-file key to read and persist, when it differs from\n * `providerId`. A provider holding several OAuth accounts parks the\n * non-active ones under sibling keys (`anthropic#account:1`); refreshing one\n * of those must rotate THAT slot, under its own lock, while the registered\n * flow is still looked up by `providerId`. Defaults to `providerId`.\n */\n credentialKey?: string\n /**\n * Credentials file to use instead of {@link credentialsFilePath}. Callers that\n * already know the data directory (the usage probes) pass it so the default\n * store's locking and coalescing apply to the right file without depending\n * on `ZIDANE_CREDENTIALS_PATH` having been exported.\n */\n credentialsPath?: string\n /** What signs in with this credential, for the {@link AgentAuthError} a failure throws. Defaults to `provider`. */\n authSource?: AuthFailure['source']\n}\n\n/**\n * Read the shared credentials file.\n *\n * Returns `{}` when the file is missing OR when the file exists but is corrupted\n * / not valid JSON. Corrupt-file tolerance is important: the refresh-then-persist\n * path below writes atomically, but older builds wrote in place and could have\n * truncated the file on a crash. Treating corruption as \"no stored creds\" lets\n * users re-auth without manually deleting the file.\n *\n * Supports two on-disk shapes:\n * 1. **Legacy** (untagged): `{ \"anthropic\": { access, refresh, expires, ... } }`\n * — written by older `bun run auth`.\n * 2. **New** (kind-tagged): `{ \"anthropic\": { kind: 'oauth', access, refresh, expires, ... } }`\n * — written by the TUI. Entries with `kind: 'apikey'` are skipped — those\n * reach providers via env vars set at TUI launch (see `applyApiKeyEnv`).\n */\nexport function readOAuthCredentials(): Record<string, OAuthCredentials | undefined> {\n return readOAuthCredentialsAt(credentialsFilePath())\n}\n\nfunction readOAuthCredentialsAt(path: string): Record<string, OAuthCredentials | undefined> {\n if (!existsSync(path))\n return {}\n\n try {\n const raw = readFileSync(path, 'utf-8')\n const parsed = JSON.parse(raw)\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))\n return {}\n const result: Record<string, OAuthCredentials | undefined> = {}\n for (const [key, value] of Object.entries(parsed)) {\n if (!value || typeof value !== 'object' || Array.isArray(value))\n continue\n const v = value as Record<string, unknown>\n // New schema: explicit `kind` tag.\n if (v.kind === 'apikey')\n continue\n // Both new (`kind: 'oauth'`) and legacy (untagged) entries have `access`;\n // the harmless `kind` field is allowed by `OAuthCredentials`'s\n // `[key: string]: unknown` index signature. Validate the required\n // fields explicitly so the assignment doesn't need a double-cast.\n if (\n typeof v.access === 'string'\n && typeof v.refresh === 'string'\n && typeof v.expires === 'number'\n ) {\n result[key] = { ...v, access: v.access, refresh: v.refresh, expires: v.expires }\n }\n }\n return result\n }\n catch {\n return {}\n }\n}\n\nfunction processAlive(pid: number): boolean {\n try {\n process.kill(pid, 0)\n return true\n }\n catch (err) {\n return (err as NodeJS.ErrnoException).code === 'EPERM'\n }\n}\n\n/**\n * Age past which a lock whose holder cannot be checked is abandoned. Every\n * holder releases within seconds: a refresh is one token request with a 30 s\n * timeout, a credentials write is synchronous.\n */\nconst UNJUDGED_LOCK_STALE_MS = 2 * 60_000\n\n/**\n * Remove a lock whose holder process is gone (killed mid-refresh, its\n * `finally` never ran). Moved aside first so a lock taken meanwhile is\n * never deleted: a live one moved by mistake is put back without clobbering.\n */\nfunction evictDeadHolder(lockPath: string): boolean {\n let owner: string\n let modified: number\n try {\n owner = readFileSync(lockPath, 'utf8')\n modified = statSync(lockPath).mtimeMs\n }\n catch {\n return false\n }\n // `pid:host:uuid`. A pid recorded under another host name (shared home,\n // container, or this Mac after its name changed with the network) or an\n // unreadable record says nothing about the holder: evict it only once it\n // is older than any holder keeps a lock.\n const parts = owner.split(':')\n const pid = Number(parts[0])\n const judged = parts.slice(1, -1).join(':') === hostname() && Number.isInteger(pid) && pid > 0\n if (judged ? processAlive(pid) : Date.now() - modified < UNJUDGED_LOCK_STALE_MS)\n return false\n const aside = `${lockPath}.${randomUUID()}.stale`\n try {\n renameSync(lockPath, aside)\n }\n catch {\n return false\n }\n let same = false\n try {\n same = readFileSync(aside, 'utf8') === owner\n }\n catch { /* Unreadable: treat as not the judged record. */ }\n if (!same) {\n try {\n linkSync(aside, lockPath)\n }\n catch { /* Someone holds the name again. */ }\n }\n rmSync(aside, { force: true })\n return same\n}\n\n/**\n * Never steal a lock from a live holder on this host based on age: a suspended\n * holder may still own it. A lock whose recorded pid no longer exists on this\n * host is taken over, and so is an old one whose holder cannot be checked.\n */\nfunction tryAcquireLock(lockPath: string, evict = true): (() => void) | undefined {\n const owner = `${process.pid}:${hostname()}:${randomUUID()}`\n try {\n writeFileSync(lockPath, owner, { flag: 'wx', mode: CREDENTIALS_FILE_MODE })\n }\n catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'EEXIST')\n return evict && evictDeadHolder(lockPath) ? tryAcquireLock(lockPath, false) : undefined\n throw err\n }\n return () => {\n try {\n if (readFileSync(lockPath, 'utf8') === owner)\n unlinkSync(lockPath)\n }\n catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT')\n throw err\n }\n }\n}\n\n/**\n * Run `fn` while holding the cross-process lock `<path>.lock`. Polls every 20 ms\n * and throws after 2 seconds without the lock. Shared by refresh persistence\n * and interactive credential mutations.\n *\n * @param path - Credentials file the lock guards.\n * @param fn - Synchronous work to run under the lock.\n */\nexport function withCredentialsLock<T>(path: string, fn: () => T): T {\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 })\n const deadline = Date.now() + 2000\n let release = tryAcquireLock(`${path}.lock`)\n while (!release) {\n if (Date.now() >= deadline)\n throw new Error('Timed out waiting for credentials lock')\n Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 20)\n release = tryAcquireLock(`${path}.lock`)\n }\n try {\n return fn()\n }\n finally {\n release()\n }\n}\n\n/** How long a refresh waits for another process's refresh of the same credential. */\nconst REFRESH_LOCK_WAIT_MS = 30_000\n\n/**\n * Wait for the refresh lock at `lockPath`.\n *\n * @param lockPath - The lock file.\n * @param timedOut - The error to throw once the wait is over, given the holder's pid when it is on this host.\n */\nasync function acquireRefreshLock(lockPath: string, timedOut: (holderPid: number | undefined) => Error): Promise<() => void> {\n mkdirSync(dirname(lockPath), { recursive: true, mode: 0o700 })\n const deadline = Date.now() + REFRESH_LOCK_WAIT_MS\n while (true) {\n const release = tryAcquireLock(lockPath)\n if (release)\n return release\n if (Date.now() >= deadline)\n throw timedOut(lockHolderPid(lockPath))\n await new Promise(resolve => setTimeout(resolve, 50))\n }\n}\n\n/** The pid recorded in a lock (`pid:host:uuid`) when the holder runs on this host. */\nfunction lockHolderPid(lockPath: string): number | undefined {\n try {\n const parts = readFileSync(lockPath, 'utf8').split(':')\n const pid = Number(parts[0])\n return parts.slice(1, -1).join(':') === hostname() && Number.isInteger(pid) && pid > 0 ? pid : undefined\n }\n catch {\n return undefined\n }\n}\n\n/** A refresh failure's reason, as the kind of sign-in failure it is. */\nfunction refreshFailureKind(reason: string): AuthFailureKind {\n switch (classifyRefreshFailure(reason)) {\n case 'sign-in':\n return 'revoked'\n case 'retry':\n return 'network'\n default:\n return 'expired'\n }\n}\n\nfunction readRawCredentials(path: string): Record<string, unknown> {\n try {\n const parsed = JSON.parse(readFileSync(path, 'utf8'))\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))\n return parsed\n }\n catch { /* Missing or corrupt file. */ }\n return {}\n}\n\nfunction writeCredentialPatch(path: string, credentials: Record<string, unknown>): void {\n const merged = { ...readRawCredentials(path), ...credentials }\n for (const [key, value] of Object.entries(merged)) {\n if (value === undefined)\n delete merged[key]\n }\n writeFileAtomic(path, JSON.stringify(merged, null, 2), { mode: CREDENTIALS_FILE_MODE })\n}\n\n/**\n * Incoming entries are a provider-local patch, not a read-time snapshot.\n * @param credentials - Entries to merge into the credentials file. An `undefined` value removes that key.\n */\nexport function writeOAuthCredentials(credentials: Record<string, OAuthCredentials | undefined>) {\n const path = credentialsFilePath()\n withCredentialsLock(path, () => writeCredentialPatch(path, credentials))\n}\n\n/**\n * Builds OAuth credentials from the runtime `access`, `refresh` and `expires` params, plus any listed extra keys that are set. Returns `undefined` when one of the three is missing.\n *\n * @param params - Provider params that may carry runtime credentials.\n * @param extraKeys - Extra `params` keys to copy into the credentials.\n */\nexport function credentialsFromParams<TParams extends OAuthParams>(params?: TParams, extraKeys: (keyof TParams & string)[] = []): OAuthCredentials | undefined {\n if (typeof params?.access !== 'string' || typeof params.refresh !== 'string' || typeof params.expires !== 'number')\n return undefined\n\n const extras = Object.fromEntries(\n extraKeys\n .map(key => [key, params[key]])\n .filter(([, value]) => value !== undefined),\n )\n\n return {\n access: params.access,\n refresh: params.refresh,\n expires: params.expires,\n ...extras,\n }\n}\n\n/**\n * Resolves the API key for an OAuth provider.\n * Returns a static `apiKey`, runtime `access` token or env key as is, otherwise reads the stored credentials and refreshes them when expired. Refreshed credentials are persisted and concurrent refreshes of the same credential are shared. Throws `missingError` when no credential exists and `refreshError` when the refresh fails.\n *\n * @param options - Provider identity, credential sources and error messages.\n * @param callbacks - Hooks called with refresh events and credential-resolution stages.\n */\nexport async function resolveOAuthApiKey<TParams extends OAuthParams>(\n options: ResolveOAuthApiKeyOptions<TParams>,\n callbacks?: Pick<StreamCallbacks, 'onOAuthRefresh'> & { onOAuthStage?: (stage: 'credentials' | 'refresh' | 'shared-refresh') => void },\n): Promise<string> {\n if (typeof options.params?.apiKey === 'string') {\n if (isOAuthAccessToken(options.params.apiKey))\n callbacks?.onOAuthStage?.('credentials')\n return options.params.apiKey\n }\n const paramsCredentials = credentialsFromParams(options.params, options.extraCredentialKeys)\n if (!paramsCredentials && typeof options.params?.access === 'string') {\n callbacks?.onOAuthStage?.('credentials')\n return options.params.access\n }\n\n // Capture the store before awaiting: environment changes cannot redirect writes.\n const path = resolve(options.credentialsPath ?? credentialsFilePath())\n const usingDefaultStore = !options.readCredentials && !options.writeCredentials\n const read = options.readCredentials ?? (() => readOAuthCredentialsAt(path))\n const write = options.writeCredentials ?? (patch => withCredentialsLock(path, () => writeCredentialPatch(path, patch)))\n const baseKey = options.credentialKey ?? options.providerId\n // A pinned account names a credential, not a slot: find where it sits NOW.\n const pinned = paramsCredentials ? undefined : options.params?.account\n const pinnedSlot = pinned ? credentialSlotOf(read(), baseKey, pinned) : undefined\n const authFailure = (kind: AuthFailureKind, extra: Partial<AuthFailure> = {}): AuthFailure => ({\n kind,\n source: options.authSource ?? 'provider',\n provider: options.provider,\n providerId: options.providerId,\n ...extra,\n })\n if (pinned && !pinnedSlot)\n throw new AgentAuthError(pinnedAccountMissingError(options.provider), authFailure('missing', { accountId: pinned }))\n const slot = pinnedSlot ?? baseKey\n const envValue = options.envKey && !pinned ? process.env[options.envKey] : undefined\n if (!paramsCredentials && envValue && (!isOAuthAccessToken(envValue) || !read()[slot])) {\n if (isOAuthAccessToken(envValue))\n callbacks?.onOAuthStage?.('credentials')\n return envValue\n }\n\n callbacks?.onOAuthStage?.('credentials')\n const source = paramsCredentials ? 'params' : 'file'\n const initial = paramsCredentials ?? read()[slot]\n // Fast path for a stored credential that needs no refresh (the default\n // registry's rule): no refresh locks, re-read or persist, which on that path\n // only re-read the file and compared it. Runs once per turn.\n if (source === 'file' && initial && !options.forceRefresh && !options.getOAuthApiKey) {\n const apiKey = freshOAuthApiKey(options.providerId, initial)\n if (apiKey !== undefined)\n return apiKey\n }\n const store = usingDefaultStore ? path : [identity(options.readCredentials ?? readOAuthCredentials), identity(options.writeCredentials ?? writeOAuthCredentials)]\n const key = JSON.stringify([source, options.providerId, slot, source === 'file' ? store : null, initial, options.forceRefresh === true, options.rejectedAccess, identity(options.getOAuthApiKey ?? getOAuthApiKey)])\n // Promotion, renames and id backfills move a pinned account between slots:\n // lock it by id, and find its slot again right before each read and write.\n const slotNow = (): string | undefined => pinned ? credentialSlotOf(read(), baseKey, pinned) : slot\n // An unpinned refresh of an account with an id takes the same lock as a pinned one.\n const initialId = (initial as { id?: unknown } | undefined)?.id\n const accountId = pinned ?? (source === 'file' && typeof initialId === 'string' ? initialId : undefined)\n const lockName = accountId ? `${baseKey}@${accountId}` : slot\n const initialLabel = (initial as { label?: unknown } | undefined)?.label\n const account: Partial<AuthFailure> = {\n ...(accountId ? { accountId } : {}),\n ...(typeof initialLabel === 'string' && initialLabel ? { accountLabel: initialLabel } : {}),\n }\n const lockTimedOut = (holderPid: number | undefined): Error => new AgentAuthError(\n `Another zidane process${holderPid ? ` (pid ${holderPid})` : ''} has been refreshing the ${options.provider} sign-in for ${REFRESH_LOCK_WAIT_MS / 1000}s without finishing. Retry, or sign in again if it keeps happening.`,\n authFailure('busy', { ...account, ...(holderPid ? { holderPid } : {}) }),\n )\n\n let task = refreshLocks.get(key)\n if (task)\n callbacks?.onOAuthStage?.('shared-refresh')\n if (!task) {\n task = run()\n refreshLocks.set(key, task)\n // Delete before callbacks run; a failing subscriber must not poison peers.\n void task.finally(() => refreshLocks.delete(key)).catch(() => {})\n }\n const result = await task\n if (result.event) {\n await callbacks?.onOAuthRefresh?.({\n ...structuredClone(result.event),\n provider: options.provider,\n })\n }\n return result.apiKey\n\n async function run(): Promise<RefreshResult> {\n const releases: Array<() => void> = []\n try {\n if (source === 'file' && usingDefaultStore) {\n // @deprecated Drop the legacy lock in the release after this one: v8.0.4 locks the slot, not the account.\n // Taking the legacy slot lock first keeps them from spending the same refresh token.\n // Fixed order (legacy, then account) means two new processes cannot deadlock.\n if (lockName !== slot)\n releases.push(await acquireRefreshLock(`${path}.refresh-${encodeURIComponent(slot)}.lock`, lockTimedOut))\n releases.push(await acquireRefreshLock(`${path}.refresh-${encodeURIComponent(lockName)}.lock`, lockTimedOut))\n }\n const at = paramsCredentials ? slot : slotNow()\n const current = paramsCredentials ?? (at ? read()[at] : undefined)\n if (!current)\n throw new AgentAuthError(options.missingError, authFailure('missing', account))\n const generation = structuredClone(current)\n let result: Awaited<ReturnType<GetOAuthApiKey>>\n try {\n const stillRejected = options.rejectedAccess === undefined || current.access === options.rejectedAccess\n if (current.expires <= Date.now() || (options.forceRefresh && stillRejected))\n callbacks?.onOAuthStage?.('refresh')\n result = await (options.getOAuthApiKey ?? getOAuthApiKey)(\n options.providerId,\n { [options.providerId]: current },\n { force: options.forceRefresh === true && stillRejected },\n )\n }\n catch (err) {\n const reason = errorMessage(err)\n throw new AgentAuthError(options.refreshError(reason), authFailure(refreshFailureKind(reason), account), { cause: err })\n }\n if (!result)\n throw new AgentAuthError(options.refreshError(options.missingError), authFailure('missing', account))\n const refreshed = { ...generation, ...result.newCredentials }\n if (source === 'file') {\n const persist = () => {\n const target = slotNow()\n if (!target || !isDeepStrictEqual(read()[target], generation))\n throw new Error('OAuth credentials changed during refresh; retry with current credentials')\n if (result.newCredentials !== current) {\n const patch = { [target]: refreshed }\n if (usingDefaultStore)\n writeCredentialPatch(path, patch)\n else\n write(patch)\n }\n }\n if (usingDefaultStore)\n withCredentialsLock(path, persist)\n else\n persist()\n }\n return {\n apiKey: result.apiKey,\n ...(result.newCredentials !== current\n ? { event: {\n provider: options.provider,\n providerId: options.providerId,\n source,\n previousCredentials: generation,\n credentials: refreshed,\n } }\n : {}),\n }\n }\n finally {\n for (const release of releases.reverse())\n release()\n }\n }\n}\n"],"mappings":"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"}
@@ -1,10 +1,10 @@
1
- import { C as providerLimitReason, S as matchesToolPairingError, f as classifyErrorPrelude, p as classifyProviderLimit, u as announcedResetMs, x as matchesContextExceeded, y as isRetryableHttpStatus } from "./errors-BOcRncxO.js";
1
+ import { C as providerLimitReason, S as matchesToolPairingError, f as classifyErrorPrelude, p as classifyProviderLimit, u as announcedResetMs, x as matchesContextExceeded, y as isRetryableHttpStatus } from "./errors-DMUkkRXB.js";
2
2
  import { i as documentBlockMarker, n as assertResolvedMediaBlock } from "./types-D5z_3G9j.js";
3
- import { B as lookupModel$1, F as fillEstimatedCost, I as aliasCatalogProviders, T as sanitizeToolSpecs, V as mergeCatalogEntry, W as systemNotesAsText, X as unsupportedMediaError, g as createToolNameBoundary, h as userMessage, m as toolResultsMessage, o as assistantMessage } from "./openai-compat-Cs8ZjU7a.js";
3
+ import { B as lookupModel$1, F as fillEstimatedCost, I as aliasCatalogProviders, T as sanitizeToolSpecs, V as mergeCatalogEntry, W as systemNotesAsText, X as unsupportedMediaError, g as createToolNameBoundary, h as userMessage, m as toolResultsMessage, o as assistantMessage } from "./openai-compat-D01UA-p6.js";
4
4
  import { renderSystemForWire } from "./prompt.js";
5
- import { c as reasoningWireAction, h as SYNTHETIC_TOOL_RESULT_PLACEHOLDER } from "./messages-CJfSVi7C.js";
5
+ import { c as reasoningWireAction, h as SYNTHETIC_TOOL_RESULT_PLACEHOLDER } from "./messages-Dk0N0lyy.js";
6
6
  import { c as DecisionHttpError, d as DecisionUnavailableError, f as DecisionUnsupportedError, i as scoreLevelLabel, l as DecisionInvalidResponseError, n as isPromptParts, r as scoreLevelDescription } from "./wire-aTdQsvj3.js";
7
- import { l as resolveOAuthApiKey, r as extractRuntimeCredentials } from "./oauth-Dv-_W_gh.js";
7
+ import { l as resolveOAuthApiKey, r as extractRuntimeCredentials } from "./oauth-DXDy4q56.js";
8
8
  import { a as imageHttpError, i as imageFromBase64, r as imageCount, t as aspectValue } from "./wire-DH77Z-rr.js";
9
9
  import { n as stream$1, t as stream } from "./pi-ai-responses-DpHLSriS.js";
10
10
  import { Buffer } from "node:buffer";
@@ -954,4 +954,4 @@ function openai(params) {
954
954
  //#endregion
955
955
  export { OPENAI_DECISION_MODELS as a, toPiMessages as i, mapCodexStopReason as n, OPENAI_IMAGE_MODELS as o, openai as r, classifyOpenAIError as t };
956
956
 
957
- //# sourceMappingURL=openai-h63vQhcu.js.map
957
+ //# sourceMappingURL=openai-BAFg-2LW.js.map