@fractaal/pi-ai 0.85.4 → 0.86.2

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 (712) hide show
  1. package/README.md +322 -46
  2. package/dist/api/anthropic-messages.d.ts.map +1 -1
  3. package/dist/api/anthropic-messages.js +403 -140
  4. package/dist/api/anthropic-messages.js.map +1 -1
  5. package/dist/api/anthropic-messages.lazy.d.ts.map +1 -1
  6. package/dist/api/azure-openai-config.d.ts +15 -0
  7. package/dist/api/azure-openai-config.d.ts.map +1 -0
  8. package/dist/api/azure-openai-config.js +76 -0
  9. package/dist/api/azure-openai-config.js.map +1 -0
  10. package/dist/api/azure-openai-responses.d.ts +5 -6
  11. package/dist/api/azure-openai-responses.d.ts.map +1 -1
  12. package/dist/api/azure-openai-responses.js +42 -86
  13. package/dist/api/azure-openai-responses.js.map +1 -1
  14. package/dist/api/azure-openai-responses.lazy.d.ts.map +1 -1
  15. package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  16. package/dist/api/bedrock-converse-stream.js +233 -24
  17. package/dist/api/bedrock-converse-stream.js.map +1 -1
  18. package/dist/api/bedrock-converse-stream.lazy.d.ts.map +1 -1
  19. package/dist/api/bedrock-converse-stream.lazy.js.map +1 -1
  20. package/dist/api/cloudflare-ai-binding.d.ts +77 -0
  21. package/dist/api/cloudflare-ai-binding.d.ts.map +1 -0
  22. package/dist/api/cloudflare-ai-binding.js +72 -0
  23. package/dist/api/cloudflare-ai-binding.js.map +1 -0
  24. package/dist/api/cloudflare-workers-ai-system-one.d.ts +4 -0
  25. package/dist/api/cloudflare-workers-ai-system-one.d.ts.map +1 -0
  26. package/dist/api/cloudflare-workers-ai-system-one.js +48 -0
  27. package/dist/api/cloudflare-workers-ai-system-one.js.map +1 -0
  28. package/dist/api/cloudflare-workers-ai-system-one.lazy.d.ts +3 -0
  29. package/dist/api/cloudflare-workers-ai-system-one.lazy.d.ts.map +1 -0
  30. package/dist/api/cloudflare-workers-ai-system-one.lazy.js +4 -0
  31. package/dist/api/cloudflare-workers-ai-system-one.lazy.js.map +1 -0
  32. package/dist/api/cloudflare.d.ts +2 -0
  33. package/dist/api/cloudflare.d.ts.map +1 -1
  34. package/dist/api/cloudflare.js +2 -0
  35. package/dist/api/cloudflare.js.map +1 -1
  36. package/dist/api/constrained-sampling.d.ts +10 -1
  37. package/dist/api/constrained-sampling.d.ts.map +1 -1
  38. package/dist/api/constrained-sampling.js +137 -4
  39. package/dist/api/constrained-sampling.js.map +1 -1
  40. package/dist/api/github-copilot-headers.d.ts.map +1 -1
  41. package/dist/api/github-copilot-headers.js.map +1 -1
  42. package/dist/api/google-generative-ai.d.ts +2 -2
  43. package/dist/api/google-generative-ai.d.ts.map +1 -1
  44. package/dist/api/google-generative-ai.js +39 -82
  45. package/dist/api/google-generative-ai.js.map +1 -1
  46. package/dist/api/google-generative-ai.lazy.d.ts.map +1 -1
  47. package/dist/api/google-shared.d.ts +27 -5
  48. package/dist/api/google-shared.d.ts.map +1 -1
  49. package/dist/api/google-shared.js +126 -18
  50. package/dist/api/google-shared.js.map +1 -1
  51. package/dist/api/google-vertex.d.ts +2 -2
  52. package/dist/api/google-vertex.d.ts.map +1 -1
  53. package/dist/api/google-vertex.js +42 -73
  54. package/dist/api/google-vertex.js.map +1 -1
  55. package/dist/api/google-vertex.lazy.d.ts.map +1 -1
  56. package/dist/api/lazy.d.ts +5 -1
  57. package/dist/api/lazy.d.ts.map +1 -1
  58. package/dist/api/lazy.js +19 -7
  59. package/dist/api/lazy.js.map +1 -1
  60. package/dist/api/llama-cpp-classify.d.ts +33 -0
  61. package/dist/api/llama-cpp-classify.d.ts.map +1 -0
  62. package/dist/api/llama-cpp-classify.js +365 -0
  63. package/dist/api/llama-cpp-classify.js.map +1 -0
  64. package/dist/api/llama-cpp-classify.lazy.d.ts +3 -0
  65. package/dist/api/llama-cpp-classify.lazy.d.ts.map +1 -0
  66. package/dist/api/llama-cpp-classify.lazy.js +4 -0
  67. package/dist/api/llama-cpp-classify.lazy.js.map +1 -0
  68. package/dist/api/mistral-conversations.d.ts +2 -2
  69. package/dist/api/mistral-conversations.d.ts.map +1 -1
  70. package/dist/api/mistral-conversations.js +250 -69
  71. package/dist/api/mistral-conversations.js.map +1 -1
  72. package/dist/api/mistral-conversations.lazy.d.ts.map +1 -1
  73. package/dist/api/openai-codex-compaction-history.d.ts +2 -2
  74. package/dist/api/openai-codex-compaction-history.d.ts.map +1 -1
  75. package/dist/api/openai-codex-compaction-history.js +1 -2
  76. package/dist/api/openai-codex-compaction-history.js.map +1 -1
  77. package/dist/api/openai-codex-responses.d.ts +1 -1
  78. package/dist/api/openai-codex-responses.d.ts.map +1 -1
  79. package/dist/api/openai-codex-responses.js +107 -60
  80. package/dist/api/openai-codex-responses.js.map +1 -1
  81. package/dist/api/openai-codex-responses.lazy.d.ts.map +1 -1
  82. package/dist/api/openai-codex-responses.lazy.js.map +1 -1
  83. package/dist/api/openai-completions.d.ts +11 -4
  84. package/dist/api/openai-completions.d.ts.map +1 -1
  85. package/dist/api/openai-completions.js +250 -134
  86. package/dist/api/openai-completions.js.map +1 -1
  87. package/dist/api/openai-completions.lazy.d.ts.map +1 -1
  88. package/dist/api/openai-prompt-cache.d.ts.map +1 -1
  89. package/dist/api/openai-prompt-cache.js.map +1 -1
  90. package/dist/api/openai-responses-shared.d.ts +8 -4
  91. package/dist/api/openai-responses-shared.d.ts.map +1 -1
  92. package/dist/api/openai-responses-shared.js +114 -62
  93. package/dist/api/openai-responses-shared.js.map +1 -1
  94. package/dist/api/openai-responses.d.ts.map +1 -1
  95. package/dist/api/openai-responses.js +55 -23
  96. package/dist/api/openai-responses.js.map +1 -1
  97. package/dist/api/openai-responses.lazy.d.ts.map +1 -1
  98. package/dist/api/openrouter-images.d.ts +2 -1
  99. package/dist/api/openrouter-images.d.ts.map +1 -1
  100. package/dist/api/openrouter-images.js +1 -0
  101. package/dist/api/openrouter-images.js.map +1 -1
  102. package/dist/api/openrouter-images.lazy.d.ts.map +1 -1
  103. package/dist/api/openrouter-images.lazy.js.map +1 -1
  104. package/dist/api/pi-messages.d.ts +5 -3
  105. package/dist/api/pi-messages.d.ts.map +1 -1
  106. package/dist/api/pi-messages.js +10 -3
  107. package/dist/api/pi-messages.js.map +1 -1
  108. package/dist/api/pi-messages.lazy.d.ts.map +1 -1
  109. package/dist/api/simple-options.d.ts +10 -3
  110. package/dist/api/simple-options.d.ts.map +1 -1
  111. package/dist/api/simple-options.js +31 -11
  112. package/dist/api/simple-options.js.map +1 -1
  113. package/dist/api/system-one-shared.d.ts +23 -0
  114. package/dist/api/system-one-shared.d.ts.map +1 -0
  115. package/dist/api/system-one-shared.js +183 -0
  116. package/dist/api/system-one-shared.js.map +1 -0
  117. package/dist/api/transform-messages.d.ts.map +1 -1
  118. package/dist/api/transform-messages.js +21 -7
  119. package/dist/api/transform-messages.js.map +1 -1
  120. package/dist/api/typesafe-system-one.d.ts +4 -0
  121. package/dist/api/typesafe-system-one.d.ts.map +1 -0
  122. package/dist/api/typesafe-system-one.js +19 -0
  123. package/dist/api/typesafe-system-one.js.map +1 -0
  124. package/dist/api/typesafe-system-one.lazy.d.ts +3 -0
  125. package/dist/api/typesafe-system-one.lazy.d.ts.map +1 -0
  126. package/dist/api/typesafe-system-one.lazy.js +4 -0
  127. package/dist/api/typesafe-system-one.lazy.js.map +1 -0
  128. package/dist/auth/context.d.ts.map +1 -1
  129. package/dist/auth/context.js.map +1 -1
  130. package/dist/auth/credential-store.d.ts +6 -6
  131. package/dist/auth/credential-store.d.ts.map +1 -1
  132. package/dist/auth/credential-store.js +22 -11
  133. package/dist/auth/credential-store.js.map +1 -1
  134. package/dist/auth/helpers.d.ts +1 -0
  135. package/dist/auth/helpers.d.ts.map +1 -1
  136. package/dist/auth/helpers.js +8 -3
  137. package/dist/auth/helpers.js.map +1 -1
  138. package/dist/auth/oauth/anthropic.d.ts.map +1 -1
  139. package/dist/auth/oauth/anthropic.js +78 -131
  140. package/dist/auth/oauth/anthropic.js.map +1 -1
  141. package/dist/auth/oauth/callback-server.d.ts +55 -0
  142. package/dist/auth/oauth/callback-server.d.ts.map +1 -0
  143. package/dist/auth/oauth/callback-server.js +146 -0
  144. package/dist/auth/oauth/callback-server.js.map +1 -0
  145. package/dist/auth/oauth/device-code.d.ts +2 -1
  146. package/dist/auth/oauth/device-code.d.ts.map +1 -1
  147. package/dist/auth/oauth/device-code.js +5 -5
  148. package/dist/auth/oauth/device-code.js.map +1 -1
  149. package/dist/auth/oauth/github-copilot.d.ts.map +1 -1
  150. package/dist/auth/oauth/github-copilot.js +121 -41
  151. package/dist/auth/oauth/github-copilot.js.map +1 -1
  152. package/dist/auth/oauth/kimi-coding.d.ts.map +1 -1
  153. package/dist/auth/oauth/kimi-coding.js +5 -6
  154. package/dist/auth/oauth/kimi-coding.js.map +1 -1
  155. package/dist/auth/oauth/load.d.ts +4 -0
  156. package/dist/auth/oauth/load.d.ts.map +1 -1
  157. package/dist/auth/oauth/load.js +10 -0
  158. package/dist/auth/oauth/load.js.map +1 -1
  159. package/dist/auth/oauth/meta.d.ts +17 -0
  160. package/dist/auth/oauth/meta.d.ts.map +1 -0
  161. package/dist/auth/oauth/meta.js +190 -0
  162. package/dist/auth/oauth/meta.js.map +1 -0
  163. package/dist/auth/oauth/openai-chatgpt.d.ts +9 -0
  164. package/dist/auth/oauth/openai-chatgpt.d.ts.map +1 -0
  165. package/dist/auth/oauth/openai-chatgpt.js +263 -0
  166. package/dist/auth/oauth/openai-chatgpt.js.map +1 -0
  167. package/dist/auth/oauth/openai-codex-errors.d.ts.map +1 -1
  168. package/dist/auth/oauth/openai-codex-errors.js.map +1 -1
  169. package/dist/auth/oauth/openai-codex.d.ts +1 -1
  170. package/dist/auth/oauth/openai-codex.d.ts.map +1 -1
  171. package/dist/auth/oauth/openai-codex.js +23 -152
  172. package/dist/auth/oauth/openai-codex.js.map +1 -1
  173. package/dist/auth/oauth/openrouter.d.ts +1 -1
  174. package/dist/auth/oauth/openrouter.d.ts.map +1 -1
  175. package/dist/auth/oauth/openrouter.js +25 -144
  176. package/dist/auth/oauth/openrouter.js.map +1 -1
  177. package/dist/auth/oauth/pkce.d.ts.map +1 -1
  178. package/dist/auth/oauth/pkce.js.map +1 -1
  179. package/dist/auth/oauth/radius.d.ts +1 -1
  180. package/dist/auth/oauth/radius.d.ts.map +1 -1
  181. package/dist/auth/oauth/radius.js +26 -93
  182. package/dist/auth/oauth/radius.js.map +1 -1
  183. package/dist/auth/oauth/xai.d.ts.map +1 -1
  184. package/dist/auth/oauth/xai.js +3 -2
  185. package/dist/auth/oauth/xai.js.map +1 -1
  186. package/dist/auth/resolve.d.ts +19 -9
  187. package/dist/auth/resolve.d.ts.map +1 -1
  188. package/dist/auth/resolve.js +72 -53
  189. package/dist/auth/resolve.js.map +1 -1
  190. package/dist/auth/types.d.ts +29 -8
  191. package/dist/auth/types.d.ts.map +1 -1
  192. package/dist/auth/types.js.map +1 -1
  193. package/dist/bedrock-provider.d.ts.map +1 -1
  194. package/dist/bun-oauth.d.ts.map +1 -1
  195. package/dist/bun-oauth.js +4 -0
  196. package/dist/bun-oauth.js.map +1 -1
  197. package/dist/cli.d.ts.map +1 -1
  198. package/dist/cli.js +4 -1
  199. package/dist/cli.js.map +1 -1
  200. package/dist/compat/extension-oauth-types.d.ts.map +1 -1
  201. package/dist/compat.d.ts +3 -3
  202. package/dist/compat.d.ts.map +1 -1
  203. package/dist/compat.js +9 -6
  204. package/dist/compat.js.map +1 -1
  205. package/dist/env-api-keys.d.ts +5 -0
  206. package/dist/env-api-keys.d.ts.map +1 -1
  207. package/dist/env-api-keys.js +10 -1
  208. package/dist/env-api-keys.js.map +1 -1
  209. package/dist/image-models.d.ts +19 -8
  210. package/dist/image-models.d.ts.map +1 -1
  211. package/dist/image-models.js +14 -13
  212. package/dist/image-models.js.map +1 -1
  213. package/dist/images-api-registry.d.ts +7 -7
  214. package/dist/images-api-registry.d.ts.map +1 -1
  215. package/dist/images-api-registry.js.map +1 -1
  216. package/dist/images.d.ts +7 -2
  217. package/dist/images.d.ts.map +1 -1
  218. package/dist/images.js +5 -0
  219. package/dist/images.js.map +1 -1
  220. package/dist/index.d.ts +4 -3
  221. package/dist/index.d.ts.map +1 -1
  222. package/dist/index.js +3 -2
  223. package/dist/index.js.map +1 -1
  224. package/dist/legacy-api-aliases.d.ts.map +1 -1
  225. package/dist/model-catalog.d.ts +25 -9
  226. package/dist/model-catalog.d.ts.map +1 -1
  227. package/dist/model-catalog.js +14 -2
  228. package/dist/model-catalog.js.map +1 -1
  229. package/dist/models-store.d.ts +12 -14
  230. package/dist/models-store.d.ts.map +1 -1
  231. package/dist/models-store.js +6 -3
  232. package/dist/models-store.js.map +1 -1
  233. package/dist/models.d.ts +138 -47
  234. package/dist/models.d.ts.map +1 -1
  235. package/dist/models.generated.d.ts +136 -38
  236. package/dist/models.generated.d.ts.map +1 -1
  237. package/dist/models.generated.js +136 -38
  238. package/dist/models.generated.js.map +1 -1
  239. package/dist/models.js +390 -104
  240. package/dist/models.js.map +1 -1
  241. package/dist/oauth.d.ts.map +1 -1
  242. package/dist/providers/all.d.ts +19 -13
  243. package/dist/providers/all.d.ts.map +1 -1
  244. package/dist/providers/all.js +33 -23
  245. package/dist/providers/all.js.map +1 -1
  246. package/dist/providers/amazon-bedrock.d.ts.map +1 -1
  247. package/dist/providers/amazon-bedrock.js +15 -7
  248. package/dist/providers/amazon-bedrock.js.map +1 -1
  249. package/dist/providers/amazon-bedrock.models.d.ts +4 -2
  250. package/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
  251. package/dist/providers/amazon-bedrock.models.js +4 -2
  252. package/dist/providers/amazon-bedrock.models.js.map +1 -1
  253. package/dist/providers/ant-ling.d.ts.map +1 -1
  254. package/dist/providers/ant-ling.js.map +1 -1
  255. package/dist/providers/ant-ling.models.d.ts +4 -2
  256. package/dist/providers/ant-ling.models.d.ts.map +1 -1
  257. package/dist/providers/ant-ling.models.js +4 -2
  258. package/dist/providers/ant-ling.models.js.map +1 -1
  259. package/dist/providers/anthropic.d.ts.map +1 -1
  260. package/dist/providers/anthropic.js +39 -8
  261. package/dist/providers/anthropic.js.map +1 -1
  262. package/dist/providers/anthropic.models.d.ts +4 -2
  263. package/dist/providers/anthropic.models.d.ts.map +1 -1
  264. package/dist/providers/anthropic.models.js +4 -2
  265. package/dist/providers/anthropic.models.js.map +1 -1
  266. package/dist/providers/azure.d.ts +3 -0
  267. package/dist/providers/azure.d.ts.map +1 -0
  268. package/dist/providers/azure.js +46 -0
  269. package/dist/providers/azure.js.map +1 -0
  270. package/dist/providers/azure.models.d.ts +6 -0
  271. package/dist/providers/azure.models.d.ts.map +1 -0
  272. package/dist/providers/azure.models.js +8 -0
  273. package/dist/providers/azure.models.js.map +1 -0
  274. package/dist/providers/baseten.d.ts +3 -0
  275. package/dist/providers/baseten.d.ts.map +1 -0
  276. package/dist/providers/baseten.js +15 -0
  277. package/dist/providers/baseten.js.map +1 -0
  278. package/dist/providers/baseten.models.d.ts +6 -0
  279. package/dist/providers/baseten.models.d.ts.map +1 -0
  280. package/dist/providers/baseten.models.js +8 -0
  281. package/dist/providers/baseten.models.js.map +1 -0
  282. package/dist/providers/cerebras.d.ts.map +1 -1
  283. package/dist/providers/cerebras.js.map +1 -1
  284. package/dist/providers/cerebras.models.d.ts +4 -2
  285. package/dist/providers/cerebras.models.d.ts.map +1 -1
  286. package/dist/providers/cerebras.models.js +4 -2
  287. package/dist/providers/cerebras.models.js.map +1 -1
  288. package/dist/providers/cloudflare-ai-gateway.d.ts +3 -1
  289. package/dist/providers/cloudflare-ai-gateway.d.ts.map +1 -1
  290. package/dist/providers/cloudflare-ai-gateway.js +4 -0
  291. package/dist/providers/cloudflare-ai-gateway.js.map +1 -1
  292. package/dist/providers/cloudflare-ai-gateway.models.d.ts +4 -2
  293. package/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -1
  294. package/dist/providers/cloudflare-ai-gateway.models.js +4 -2
  295. package/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
  296. package/dist/providers/cloudflare-auth.d.ts.map +1 -1
  297. package/dist/providers/cloudflare-auth.js +15 -10
  298. package/dist/providers/cloudflare-auth.js.map +1 -1
  299. package/dist/providers/cloudflare-stream.d.ts +6 -2
  300. package/dist/providers/cloudflare-stream.d.ts.map +1 -1
  301. package/dist/providers/cloudflare-stream.js +6 -0
  302. package/dist/providers/cloudflare-stream.js.map +1 -1
  303. package/dist/providers/cloudflare-workers-ai.d.ts.map +1 -1
  304. package/dist/providers/cloudflare-workers-ai.js +10 -3
  305. package/dist/providers/cloudflare-workers-ai.js.map +1 -1
  306. package/dist/providers/cloudflare-workers-ai.models.d.ts +4 -2
  307. package/dist/providers/cloudflare-workers-ai.models.d.ts.map +1 -1
  308. package/dist/providers/cloudflare-workers-ai.models.js +4 -2
  309. package/dist/providers/cloudflare-workers-ai.models.js.map +1 -1
  310. package/dist/providers/data/.manifest.json +1 -1
  311. package/dist/providers/data/amazon-bedrock.json +1 -1
  312. package/dist/providers/data/ant-ling.json +1 -1
  313. package/dist/providers/data/anthropic.json +1 -1
  314. package/dist/providers/data/azure.json +1 -0
  315. package/dist/providers/data/baseten.json +1 -0
  316. package/dist/providers/data/cerebras.json +1 -1
  317. package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  318. package/dist/providers/data/cloudflare-workers-ai.json +1 -1
  319. package/dist/providers/data/deepseek.json +1 -1
  320. package/dist/providers/data/fireworks.json +1 -1
  321. package/dist/providers/data/github-copilot.json +1 -1
  322. package/dist/providers/data/google-vertex.json +1 -1
  323. package/dist/providers/data/google.json +1 -1
  324. package/dist/providers/data/groq.json +1 -1
  325. package/dist/providers/data/huggingface.json +1 -1
  326. package/dist/providers/data/kimi-coding.json +1 -1
  327. package/dist/providers/data/meta.json +1 -0
  328. package/dist/providers/data/minimax-cn.json +1 -1
  329. package/dist/providers/data/minimax.json +1 -1
  330. package/dist/providers/data/mistral.json +1 -1
  331. package/dist/providers/data/moonshotai-cn.json +1 -1
  332. package/dist/providers/data/moonshotai.json +1 -1
  333. package/dist/providers/data/nvidia.json +1 -1
  334. package/dist/providers/data/openai-codex.json +1 -1
  335. package/dist/providers/data/openai.json +1 -1
  336. package/dist/providers/data/opencode-go.json +1 -1
  337. package/dist/providers/data/opencode.json +1 -1
  338. package/dist/providers/data/openrouter.json +1 -1
  339. package/dist/providers/data/qwen-token-plan-cn.json +1 -1
  340. package/dist/providers/data/qwen-token-plan-individual.json +1 -0
  341. package/dist/providers/data/qwen-token-plan.json +1 -1
  342. package/dist/providers/data/radius.json +1 -0
  343. package/dist/providers/data/together.json +1 -1
  344. package/dist/providers/data/typesafe.json +1 -0
  345. package/dist/providers/data/vercel-ai-gateway.json +1 -1
  346. package/dist/providers/data/xai.json +1 -1
  347. package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
  348. package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
  349. package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
  350. package/dist/providers/data/xiaomi.json +1 -1
  351. package/dist/providers/data/zai-coding-cn.json +1 -1
  352. package/dist/providers/data/zai.json +1 -1
  353. package/dist/providers/deepseek.d.ts.map +1 -1
  354. package/dist/providers/deepseek.js.map +1 -1
  355. package/dist/providers/deepseek.models.d.ts +4 -2
  356. package/dist/providers/deepseek.models.d.ts.map +1 -1
  357. package/dist/providers/deepseek.models.js +4 -2
  358. package/dist/providers/deepseek.models.js.map +1 -1
  359. package/dist/providers/faux.d.ts +19 -13
  360. package/dist/providers/faux.d.ts.map +1 -1
  361. package/dist/providers/faux.js +109 -18
  362. package/dist/providers/faux.js.map +1 -1
  363. package/dist/providers/fireworks.d.ts.map +1 -1
  364. package/dist/providers/fireworks.js.map +1 -1
  365. package/dist/providers/fireworks.models.d.ts +4 -2
  366. package/dist/providers/fireworks.models.d.ts.map +1 -1
  367. package/dist/providers/fireworks.models.js +4 -2
  368. package/dist/providers/fireworks.models.js.map +1 -1
  369. package/dist/providers/github-copilot.d.ts.map +1 -1
  370. package/dist/providers/github-copilot.js +1 -1
  371. package/dist/providers/github-copilot.js.map +1 -1
  372. package/dist/providers/github-copilot.models.d.ts +4 -2
  373. package/dist/providers/github-copilot.models.d.ts.map +1 -1
  374. package/dist/providers/github-copilot.models.js +4 -2
  375. package/dist/providers/github-copilot.models.js.map +1 -1
  376. package/dist/providers/google-vertex.d.ts.map +1 -1
  377. package/dist/providers/google-vertex.js +15 -7
  378. package/dist/providers/google-vertex.js.map +1 -1
  379. package/dist/providers/google-vertex.models.d.ts +4 -2
  380. package/dist/providers/google-vertex.models.d.ts.map +1 -1
  381. package/dist/providers/google-vertex.models.js +4 -2
  382. package/dist/providers/google-vertex.models.js.map +1 -1
  383. package/dist/providers/google.d.ts.map +1 -1
  384. package/dist/providers/google.js.map +1 -1
  385. package/dist/providers/google.models.d.ts +4 -2
  386. package/dist/providers/google.models.d.ts.map +1 -1
  387. package/dist/providers/google.models.js +4 -2
  388. package/dist/providers/google.models.js.map +1 -1
  389. package/dist/providers/groq.d.ts.map +1 -1
  390. package/dist/providers/groq.js.map +1 -1
  391. package/dist/providers/groq.models.d.ts +4 -2
  392. package/dist/providers/groq.models.d.ts.map +1 -1
  393. package/dist/providers/groq.models.js +4 -2
  394. package/dist/providers/groq.models.js.map +1 -1
  395. package/dist/providers/huggingface.d.ts.map +1 -1
  396. package/dist/providers/huggingface.js.map +1 -1
  397. package/dist/providers/huggingface.models.d.ts +4 -2
  398. package/dist/providers/huggingface.models.d.ts.map +1 -1
  399. package/dist/providers/huggingface.models.js +4 -2
  400. package/dist/providers/huggingface.models.js.map +1 -1
  401. package/dist/providers/images/register-builtins.d.ts +1 -1
  402. package/dist/providers/images/register-builtins.d.ts.map +1 -1
  403. package/dist/providers/images/register-builtins.js.map +1 -1
  404. package/dist/providers/kimi-coding.d.ts.map +1 -1
  405. package/dist/providers/kimi-coding.js +1 -0
  406. package/dist/providers/kimi-coding.js.map +1 -1
  407. package/dist/providers/kimi-coding.models.d.ts +4 -2
  408. package/dist/providers/kimi-coding.models.d.ts.map +1 -1
  409. package/dist/providers/kimi-coding.models.js +4 -2
  410. package/dist/providers/kimi-coding.models.js.map +1 -1
  411. package/dist/providers/meta.d.ts +3 -0
  412. package/dist/providers/meta.d.ts.map +1 -0
  413. package/dist/providers/meta.js +24 -0
  414. package/dist/providers/meta.js.map +1 -0
  415. package/dist/providers/meta.models.d.ts +6 -0
  416. package/dist/providers/meta.models.d.ts.map +1 -0
  417. package/dist/providers/meta.models.js +8 -0
  418. package/dist/providers/meta.models.js.map +1 -0
  419. package/dist/providers/minimax-cn.d.ts.map +1 -1
  420. package/dist/providers/minimax-cn.js.map +1 -1
  421. package/dist/providers/minimax-cn.models.d.ts +4 -2
  422. package/dist/providers/minimax-cn.models.d.ts.map +1 -1
  423. package/dist/providers/minimax-cn.models.js +4 -2
  424. package/dist/providers/minimax-cn.models.js.map +1 -1
  425. package/dist/providers/minimax.d.ts.map +1 -1
  426. package/dist/providers/minimax.js.map +1 -1
  427. package/dist/providers/minimax.models.d.ts +4 -2
  428. package/dist/providers/minimax.models.d.ts.map +1 -1
  429. package/dist/providers/minimax.models.js +4 -2
  430. package/dist/providers/minimax.models.js.map +1 -1
  431. package/dist/providers/mistral.d.ts.map +1 -1
  432. package/dist/providers/mistral.js.map +1 -1
  433. package/dist/providers/mistral.models.d.ts +4 -2
  434. package/dist/providers/mistral.models.d.ts.map +1 -1
  435. package/dist/providers/mistral.models.js +4 -2
  436. package/dist/providers/mistral.models.js.map +1 -1
  437. package/dist/providers/moonshotai-cn.d.ts.map +1 -1
  438. package/dist/providers/moonshotai-cn.js.map +1 -1
  439. package/dist/providers/moonshotai-cn.models.d.ts +4 -2
  440. package/dist/providers/moonshotai-cn.models.d.ts.map +1 -1
  441. package/dist/providers/moonshotai-cn.models.js +4 -2
  442. package/dist/providers/moonshotai-cn.models.js.map +1 -1
  443. package/dist/providers/moonshotai.d.ts.map +1 -1
  444. package/dist/providers/moonshotai.js.map +1 -1
  445. package/dist/providers/moonshotai.models.d.ts +4 -2
  446. package/dist/providers/moonshotai.models.d.ts.map +1 -1
  447. package/dist/providers/moonshotai.models.js +4 -2
  448. package/dist/providers/moonshotai.models.js.map +1 -1
  449. package/dist/providers/nvidia.d.ts.map +1 -1
  450. package/dist/providers/nvidia.js.map +1 -1
  451. package/dist/providers/nvidia.models.d.ts +4 -2
  452. package/dist/providers/nvidia.models.d.ts.map +1 -1
  453. package/dist/providers/nvidia.models.js +4 -2
  454. package/dist/providers/nvidia.models.js.map +1 -1
  455. package/dist/providers/openai-codex-catalog.d.ts +1 -0
  456. package/dist/providers/openai-codex-catalog.d.ts.map +1 -1
  457. package/dist/providers/openai-codex-catalog.js +19 -10
  458. package/dist/providers/openai-codex-catalog.js.map +1 -1
  459. package/dist/providers/openai-codex.d.ts.map +1 -1
  460. package/dist/providers/openai-codex.js +5 -1
  461. package/dist/providers/openai-codex.js.map +1 -1
  462. package/dist/providers/openai-codex.models.d.ts +4 -2
  463. package/dist/providers/openai-codex.models.d.ts.map +1 -1
  464. package/dist/providers/openai-codex.models.js +4 -2
  465. package/dist/providers/openai-codex.models.js.map +1 -1
  466. package/dist/providers/openai.d.ts.map +1 -1
  467. package/dist/providers/openai.js +11 -2
  468. package/dist/providers/openai.js.map +1 -1
  469. package/dist/providers/openai.models.d.ts +4 -2
  470. package/dist/providers/openai.models.d.ts.map +1 -1
  471. package/dist/providers/openai.models.js +4 -2
  472. package/dist/providers/openai.models.js.map +1 -1
  473. package/dist/providers/opencode-go.d.ts.map +1 -1
  474. package/dist/providers/opencode-go.js +5 -4
  475. package/dist/providers/opencode-go.js.map +1 -1
  476. package/dist/providers/opencode-go.models.d.ts +4 -2
  477. package/dist/providers/opencode-go.models.d.ts.map +1 -1
  478. package/dist/providers/opencode-go.models.js +4 -2
  479. package/dist/providers/opencode-go.models.js.map +1 -1
  480. package/dist/providers/opencode-headers.d.ts +4 -0
  481. package/dist/providers/opencode-headers.d.ts.map +1 -0
  482. package/dist/providers/opencode-headers.js +22 -0
  483. package/dist/providers/opencode-headers.js.map +1 -0
  484. package/dist/providers/opencode.d.ts +3 -1
  485. package/dist/providers/opencode.d.ts.map +1 -1
  486. package/dist/providers/opencode.js +10 -6
  487. package/dist/providers/opencode.js.map +1 -1
  488. package/dist/providers/opencode.models.d.ts +4 -2
  489. package/dist/providers/opencode.models.d.ts.map +1 -1
  490. package/dist/providers/opencode.models.js +4 -2
  491. package/dist/providers/opencode.models.js.map +1 -1
  492. package/dist/providers/openrouter.d.ts +1 -1
  493. package/dist/providers/openrouter.d.ts.map +1 -1
  494. package/dist/providers/openrouter.js +16 -3
  495. package/dist/providers/openrouter.js.map +1 -1
  496. package/dist/providers/openrouter.models.d.ts +4 -2
  497. package/dist/providers/openrouter.models.d.ts.map +1 -1
  498. package/dist/providers/openrouter.models.js +4 -2
  499. package/dist/providers/openrouter.models.js.map +1 -1
  500. package/dist/providers/qwen-token-plan-cn.d.ts.map +1 -1
  501. package/dist/providers/qwen-token-plan-cn.js.map +1 -1
  502. package/dist/providers/qwen-token-plan-cn.models.d.ts +4 -2
  503. package/dist/providers/qwen-token-plan-cn.models.d.ts.map +1 -1
  504. package/dist/providers/qwen-token-plan-cn.models.js +4 -2
  505. package/dist/providers/qwen-token-plan-cn.models.js.map +1 -1
  506. package/dist/providers/qwen-token-plan-individual.d.ts +3 -0
  507. package/dist/providers/qwen-token-plan-individual.d.ts.map +1 -0
  508. package/dist/providers/qwen-token-plan-individual.js +15 -0
  509. package/dist/providers/qwen-token-plan-individual.js.map +1 -0
  510. package/dist/providers/qwen-token-plan-individual.models.d.ts +6 -0
  511. package/dist/providers/qwen-token-plan-individual.models.d.ts.map +1 -0
  512. package/dist/providers/qwen-token-plan-individual.models.js +8 -0
  513. package/dist/providers/qwen-token-plan-individual.models.js.map +1 -0
  514. package/dist/providers/qwen-token-plan.d.ts.map +1 -1
  515. package/dist/providers/qwen-token-plan.js.map +1 -1
  516. package/dist/providers/qwen-token-plan.models.d.ts +4 -2
  517. package/dist/providers/qwen-token-plan.models.d.ts.map +1 -1
  518. package/dist/providers/qwen-token-plan.models.js +4 -2
  519. package/dist/providers/qwen-token-plan.models.js.map +1 -1
  520. package/dist/providers/radius-config.d.ts.map +1 -1
  521. package/dist/providers/radius-config.js.map +1 -1
  522. package/dist/providers/radius.d.ts.map +1 -1
  523. package/dist/providers/radius.js +53 -29
  524. package/dist/providers/radius.js.map +1 -1
  525. package/dist/providers/radius.models.d.ts +6 -0
  526. package/dist/providers/radius.models.d.ts.map +1 -0
  527. package/dist/providers/radius.models.js +8 -0
  528. package/dist/providers/radius.models.js.map +1 -0
  529. package/dist/providers/together.d.ts.map +1 -1
  530. package/dist/providers/together.js.map +1 -1
  531. package/dist/providers/together.models.d.ts +4 -2
  532. package/dist/providers/together.models.d.ts.map +1 -1
  533. package/dist/providers/together.models.js +4 -2
  534. package/dist/providers/together.models.js.map +1 -1
  535. package/dist/providers/typesafe.d.ts +3 -0
  536. package/dist/providers/typesafe.d.ts.map +1 -0
  537. package/dist/providers/typesafe.js +18 -0
  538. package/dist/providers/typesafe.js.map +1 -0
  539. package/dist/providers/typesafe.models.d.ts +6 -0
  540. package/dist/providers/typesafe.models.d.ts.map +1 -0
  541. package/dist/providers/typesafe.models.js +8 -0
  542. package/dist/providers/typesafe.models.js.map +1 -0
  543. package/dist/providers/vercel-ai-gateway.d.ts.map +1 -1
  544. package/dist/providers/vercel-ai-gateway.js +5 -2
  545. package/dist/providers/vercel-ai-gateway.js.map +1 -1
  546. package/dist/providers/vercel-ai-gateway.models.d.ts +4 -2
  547. package/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
  548. package/dist/providers/vercel-ai-gateway.models.js +4 -2
  549. package/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  550. package/dist/providers/xai.d.ts +1 -1
  551. package/dist/providers/xai.d.ts.map +1 -1
  552. package/dist/providers/xai.js +2 -5
  553. package/dist/providers/xai.js.map +1 -1
  554. package/dist/providers/xai.models.d.ts +4 -2
  555. package/dist/providers/xai.models.d.ts.map +1 -1
  556. package/dist/providers/xai.models.js +4 -2
  557. package/dist/providers/xai.models.js.map +1 -1
  558. package/dist/providers/xiaomi-token-plan-ams.d.ts.map +1 -1
  559. package/dist/providers/xiaomi-token-plan-ams.js.map +1 -1
  560. package/dist/providers/xiaomi-token-plan-ams.models.d.ts +4 -2
  561. package/dist/providers/xiaomi-token-plan-ams.models.d.ts.map +1 -1
  562. package/dist/providers/xiaomi-token-plan-ams.models.js +4 -2
  563. package/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -1
  564. package/dist/providers/xiaomi-token-plan-cn.d.ts.map +1 -1
  565. package/dist/providers/xiaomi-token-plan-cn.js.map +1 -1
  566. package/dist/providers/xiaomi-token-plan-cn.models.d.ts +4 -2
  567. package/dist/providers/xiaomi-token-plan-cn.models.d.ts.map +1 -1
  568. package/dist/providers/xiaomi-token-plan-cn.models.js +4 -2
  569. package/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -1
  570. package/dist/providers/xiaomi-token-plan-sgp.d.ts.map +1 -1
  571. package/dist/providers/xiaomi-token-plan-sgp.js.map +1 -1
  572. package/dist/providers/xiaomi-token-plan-sgp.models.d.ts +4 -2
  573. package/dist/providers/xiaomi-token-plan-sgp.models.d.ts.map +1 -1
  574. package/dist/providers/xiaomi-token-plan-sgp.models.js +4 -2
  575. package/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -1
  576. package/dist/providers/xiaomi.d.ts.map +1 -1
  577. package/dist/providers/xiaomi.js.map +1 -1
  578. package/dist/providers/xiaomi.models.d.ts +4 -2
  579. package/dist/providers/xiaomi.models.d.ts.map +1 -1
  580. package/dist/providers/xiaomi.models.js +4 -2
  581. package/dist/providers/xiaomi.models.js.map +1 -1
  582. package/dist/providers/zai-coding-cn.d.ts.map +1 -1
  583. package/dist/providers/zai-coding-cn.js.map +1 -1
  584. package/dist/providers/zai-coding-cn.models.d.ts +4 -2
  585. package/dist/providers/zai-coding-cn.models.d.ts.map +1 -1
  586. package/dist/providers/zai-coding-cn.models.js +4 -2
  587. package/dist/providers/zai-coding-cn.models.js.map +1 -1
  588. package/dist/providers/zai.d.ts.map +1 -1
  589. package/dist/providers/zai.js.map +1 -1
  590. package/dist/providers/zai.models.d.ts +4 -2
  591. package/dist/providers/zai.models.d.ts.map +1 -1
  592. package/dist/providers/zai.models.js +4 -2
  593. package/dist/providers/zai.models.js.map +1 -1
  594. package/dist/session-resources.d.ts.map +1 -1
  595. package/dist/session-resources.js.map +1 -1
  596. package/dist/types.d.ts +414 -126
  597. package/dist/types.d.ts.map +1 -1
  598. package/dist/types.js.map +1 -1
  599. package/dist/utils/abort-signals.d.ts.map +1 -1
  600. package/dist/utils/abort-signals.js.map +1 -1
  601. package/dist/utils/abort.d.ts +8 -0
  602. package/dist/utils/abort.d.ts.map +1 -0
  603. package/dist/utils/abort.js +49 -0
  604. package/dist/utils/abort.js.map +1 -0
  605. package/dist/utils/assistant-message-frame.d.ts +77 -0
  606. package/dist/utils/assistant-message-frame.d.ts.map +1 -0
  607. package/dist/utils/assistant-message-frame.js +425 -0
  608. package/dist/utils/assistant-message-frame.js.map +1 -0
  609. package/dist/utils/diagnostics.d.ts +3 -2
  610. package/dist/utils/diagnostics.d.ts.map +1 -1
  611. package/dist/utils/diagnostics.js.map +1 -1
  612. package/dist/utils/error-body.d.ts.map +1 -1
  613. package/dist/utils/error-body.js +23 -4
  614. package/dist/utils/error-body.js.map +1 -1
  615. package/dist/utils/estimate.d.ts +2 -2
  616. package/dist/utils/estimate.d.ts.map +1 -1
  617. package/dist/utils/estimate.js +8 -29
  618. package/dist/utils/estimate.js.map +1 -1
  619. package/dist/utils/event-stream.d.ts.map +1 -1
  620. package/dist/utils/event-stream.js +25 -7
  621. package/dist/utils/event-stream.js.map +1 -1
  622. package/dist/utils/hash.d.ts.map +1 -1
  623. package/dist/utils/hash.js.map +1 -1
  624. package/dist/utils/headers.d.ts +1 -1
  625. package/dist/utils/headers.d.ts.map +1 -1
  626. package/dist/utils/headers.js +10 -8
  627. package/dist/utils/headers.js.map +1 -1
  628. package/dist/utils/json-parse.d.ts.map +1 -1
  629. package/dist/utils/json-parse.js.map +1 -1
  630. package/dist/utils/model-operations.d.ts +11 -0
  631. package/dist/utils/model-operations.d.ts.map +1 -0
  632. package/dist/utils/model-operations.js +47 -0
  633. package/dist/utils/model-operations.js.map +1 -0
  634. package/dist/utils/models-error.d.ts +8 -0
  635. package/dist/utils/models-error.d.ts.map +1 -0
  636. package/dist/utils/models-error.js +19 -0
  637. package/dist/utils/models-error.js.map +1 -0
  638. package/dist/utils/node-http-proxy.d.ts.map +1 -1
  639. package/dist/utils/node-http-proxy.js +53 -12
  640. package/dist/utils/node-http-proxy.js.map +1 -1
  641. package/dist/utils/oauth-page.d.ts.map +1 -0
  642. package/dist/{auth/oauth → utils}/oauth-page.js +1 -1
  643. package/dist/utils/oauth-page.js.map +1 -0
  644. package/dist/utils/overflow.d.ts +11 -1
  645. package/dist/utils/overflow.d.ts.map +1 -1
  646. package/dist/utils/overflow.js +24 -6
  647. package/dist/utils/overflow.js.map +1 -1
  648. package/dist/utils/pi-user-agent.d.ts +2 -0
  649. package/dist/utils/pi-user-agent.d.ts.map +1 -0
  650. package/dist/utils/pi-user-agent.js +12 -0
  651. package/dist/utils/pi-user-agent.js.map +1 -0
  652. package/dist/utils/provider-env.d.ts.map +1 -1
  653. package/dist/utils/provider-env.js.map +1 -1
  654. package/dist/utils/provider-retry.d.ts.map +1 -1
  655. package/dist/utils/provider-retry.js +3 -2
  656. package/dist/utils/provider-retry.js.map +1 -1
  657. package/dist/utils/retry.d.ts +6 -1
  658. package/dist/utils/retry.d.ts.map +1 -1
  659. package/dist/utils/retry.js +23 -2
  660. package/dist/utils/retry.js.map +1 -1
  661. package/dist/utils/sanitize-unicode.d.ts.map +1 -1
  662. package/dist/utils/sanitize-unicode.js.map +1 -1
  663. package/dist/utils/sleep.d.ts +2 -0
  664. package/dist/utils/sleep.d.ts.map +1 -0
  665. package/dist/utils/sleep.js +15 -0
  666. package/dist/utils/sleep.js.map +1 -0
  667. package/dist/utils/text.d.ts +9 -1
  668. package/dist/utils/text.d.ts.map +1 -1
  669. package/dist/utils/text.js +26 -0
  670. package/dist/utils/text.js.map +1 -1
  671. package/dist/utils/transcript.d.ts +87 -0
  672. package/dist/utils/transcript.d.ts.map +1 -0
  673. package/dist/utils/transcript.js +207 -0
  674. package/dist/utils/transcript.js.map +1 -0
  675. package/dist/utils/typebox-helpers.d.ts.map +1 -1
  676. package/dist/utils/typebox-helpers.js.map +1 -1
  677. package/dist/utils/uuid.d.ts +2 -2
  678. package/dist/utils/uuid.d.ts.map +1 -1
  679. package/dist/utils/uuid.js +35 -39
  680. package/dist/utils/uuid.js.map +1 -1
  681. package/dist/utils/validation.d.ts.map +1 -1
  682. package/dist/utils/validation.js +224 -13
  683. package/dist/utils/validation.js.map +1 -1
  684. package/package.json +21 -15
  685. package/dist/auth/oauth/oauth-page.d.ts.map +0 -1
  686. package/dist/auth/oauth/oauth-page.js.map +0 -1
  687. package/dist/image-models.generated.d.ts +0 -605
  688. package/dist/image-models.generated.d.ts.map +0 -1
  689. package/dist/image-models.generated.js +0 -607
  690. package/dist/image-models.generated.js.map +0 -1
  691. package/dist/images-models.d.ts +0 -95
  692. package/dist/images-models.d.ts.map +0 -1
  693. package/dist/images-models.js +0 -142
  694. package/dist/images-models.js.map +0 -1
  695. package/dist/providers/azure-openai-responses.d.ts +0 -3
  696. package/dist/providers/azure-openai-responses.d.ts.map +0 -1
  697. package/dist/providers/azure-openai-responses.js +0 -14
  698. package/dist/providers/azure-openai-responses.js.map +0 -1
  699. package/dist/providers/azure-openai-responses.models.d.ts +0 -4
  700. package/dist/providers/azure-openai-responses.models.d.ts.map +0 -1
  701. package/dist/providers/azure-openai-responses.models.js +0 -6
  702. package/dist/providers/azure-openai-responses.models.js.map +0 -1
  703. package/dist/providers/data/azure-openai-responses.json +0 -1
  704. package/dist/providers/openrouter-images.d.ts +0 -3
  705. package/dist/providers/openrouter-images.d.ts.map +0 -1
  706. package/dist/providers/openrouter-images.js +0 -22
  707. package/dist/providers/openrouter-images.js.map +0 -1
  708. package/dist/utils/deferred-tools.d.ts +0 -9
  709. package/dist/utils/deferred-tools.d.ts.map +0 -1
  710. package/dist/utils/deferred-tools.js +0 -36
  711. package/dist/utils/deferred-tools.js.map +0 -1
  712. /package/dist/{auth/oauth → utils}/oauth-page.d.ts +0 -0
@@ -1,4 +1,4 @@
1
- import type { Credential, CredentialInfo, CredentialStore } from "./types.ts";
1
+ import type { AuthOperationOptions, Credential, CredentialInfo, CredentialStore } from "./types.ts";
2
2
  /**
3
3
  * Default in-memory credential store. Apps inject persistent stores.
4
4
  * Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.
@@ -7,11 +7,11 @@ import type { Credential, CredentialInfo, CredentialStore } from "./types.ts";
7
7
  export declare class InMemoryCredentialStore implements CredentialStore {
8
8
  private credentials;
9
9
  private chains;
10
- /** Serialize tasks per provider id. */
10
+ /** Serialize tasks per provider id without releasing the chain before active work settles. */
11
11
  private enqueue;
12
- read(providerId: string): Promise<Credential | undefined>;
13
- list(): Promise<readonly CredentialInfo[]>;
14
- modify(providerId: string, fn: (current: Credential | undefined) => Promise<Credential | undefined>): Promise<Credential | undefined>;
15
- delete(providerId: string): Promise<void>;
12
+ read(providerId: string, options?: AuthOperationOptions): Promise<Credential | undefined>;
13
+ list(options?: AuthOperationOptions): Promise<readonly CredentialInfo[]>;
14
+ modify(providerId: string, fn: (current: Credential | undefined) => Promise<Credential | undefined>, options?: AuthOperationOptions): Promise<Credential | undefined>;
15
+ delete(providerId: string, options?: AuthOperationOptions): Promise<void>;
16
16
  }
17
17
  //# sourceMappingURL=credential-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"credential-store.d.ts","sourceRoot":"","sources":["../../src/auth/credential-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE9E;;;;GAIG;AACH,qBAAa,uBAAwB,YAAW,eAAe;IAC9D,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,MAAM,CAAuC;IAErD,uCAAuC;IACvC,OAAO,CAAC,OAAO;IAaT,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAE9D;IAEK,IAAI,IAAI,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAE/C;IAED,MAAM,CACL,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,KAAK,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,GACtE,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAOjC;IAED,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAIxC;CACD","sourcesContent":["import type { Credential, CredentialInfo, CredentialStore } from \"./types.ts\";\n\n/**\n * Default in-memory credential store. Apps inject persistent stores.\n * Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.\n * Writes are serialized per provider through a promise chain.\n */\nexport class InMemoryCredentialStore implements CredentialStore {\n\tprivate credentials = new Map<string, Credential>();\n\tprivate chains = new Map<string, Promise<unknown>>();\n\n\t/** Serialize tasks per provider id. */\n\tprivate enqueue<T>(providerId: string, task: () => Promise<T>): Promise<T> {\n\t\tconst previous = this.chains.get(providerId) ?? Promise.resolve();\n\t\tconst next = (async () => {\n\t\t\tawait previous.catch(() => {});\n\t\t\treturn task();\n\t\t})();\n\t\tthis.chains.set(\n\t\t\tproviderId,\n\t\t\tnext.catch(() => {}),\n\t\t);\n\t\treturn next;\n\t}\n\n\tasync read(providerId: string): Promise<Credential | undefined> {\n\t\treturn this.credentials.get(providerId);\n\t}\n\n\tasync list(): Promise<readonly CredentialInfo[]> {\n\t\treturn [...this.credentials].map(([providerId, credential]) => ({ providerId, type: credential.type }));\n\t}\n\n\tmodify(\n\t\tproviderId: string,\n\t\tfn: (current: Credential | undefined) => Promise<Credential | undefined>,\n\t): Promise<Credential | undefined> {\n\t\treturn this.enqueue(providerId, async () => {\n\t\t\tconst current = this.credentials.get(providerId);\n\t\t\tconst next = await fn(current);\n\t\t\tif (next !== undefined) this.credentials.set(providerId, next);\n\t\t\treturn next ?? current;\n\t\t});\n\t}\n\n\tdelete(providerId: string): Promise<void> {\n\t\treturn this.enqueue(providerId, async () => {\n\t\t\tthis.credentials.delete(providerId);\n\t\t});\n\t}\n}\n"]}
1
+ {"version":3,"file":"credential-store.d.ts","sourceRoot":"","sources":["../../src/auth/credential-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEpG;;;;GAIG;AACH,qBAAa,uBAAwB,YAAW,eAAe;IAC9D,OAAO,CAAC,WAAW,CAAiC;IACpD,OAAO,CAAC,MAAM,CAAuC;IAErD,8FAA8F;IAC9F,OAAO,CAAC,OAAO;IAgBT,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAG9F;IAEK,IAAI,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,cAAc,EAAE,CAAC,CAG7E;IAED,MAAM,CACL,UAAU,EAAE,MAAM,EAClB,EAAE,EAAE,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS,KAAK,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,EACxE,OAAO,CAAC,EAAE,oBAAoB,GAC5B,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAYjC;IAED,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAQxE;CACD"}
@@ -1,3 +1,4 @@
1
+ import { operationSignal, raceWithAbortSignal } from "../utils/abort.js";
1
2
  /**
2
3
  * Default in-memory credential store. Apps inject persistent stores.
3
4
  * Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.
@@ -6,35 +7,45 @@
6
7
  export class InMemoryCredentialStore {
7
8
  credentials = new Map();
8
9
  chains = new Map();
9
- /** Serialize tasks per provider id. */
10
- enqueue(providerId, task) {
10
+ /** Serialize tasks per provider id without releasing the chain before active work settles. */
11
+ enqueue(providerId, task, options) {
12
+ const signal = operationSignal(options?.signal);
11
13
  const previous = this.chains.get(providerId) ?? Promise.resolve();
12
- const next = (async () => {
14
+ const queued = (async () => {
13
15
  await previous.catch(() => { });
16
+ signal.throwIfAborted();
14
17
  return task();
15
18
  })();
16
- this.chains.set(providerId, next.catch(() => { }));
17
- return next;
19
+ const tail = queued.catch(() => { });
20
+ this.chains.set(providerId, tail);
21
+ void tail.then(() => {
22
+ if (this.chains.get(providerId) === tail)
23
+ this.chains.delete(providerId);
24
+ });
25
+ return raceWithAbortSignal(queued, signal);
18
26
  }
19
- async read(providerId) {
27
+ async read(providerId, options) {
28
+ options?.signal?.throwIfAborted();
20
29
  return this.credentials.get(providerId);
21
30
  }
22
- async list() {
31
+ async list(options) {
32
+ options?.signal?.throwIfAborted();
23
33
  return [...this.credentials].map(([providerId, credential]) => ({ providerId, type: credential.type }));
24
34
  }
25
- modify(providerId, fn) {
35
+ modify(providerId, fn, options) {
26
36
  return this.enqueue(providerId, async () => {
27
37
  const current = this.credentials.get(providerId);
28
38
  const next = await fn(current);
39
+ options?.signal?.throwIfAborted();
29
40
  if (next !== undefined)
30
41
  this.credentials.set(providerId, next);
31
42
  return next ?? current;
32
- });
43
+ }, options);
33
44
  }
34
- delete(providerId) {
45
+ delete(providerId, options) {
35
46
  return this.enqueue(providerId, async () => {
36
47
  this.credentials.delete(providerId);
37
- });
48
+ }, options);
38
49
  }
39
50
  }
40
51
  //# sourceMappingURL=credential-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"credential-store.js","sourceRoot":"","sources":["../../src/auth/credential-store.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,OAAO,uBAAuB;IAC3B,WAAW,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC5C,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IAErD,uCAAuC;IAC/B,OAAO,CAAI,UAAkB,EAAE,IAAsB,EAAc;QAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAClE,MAAM,IAAI,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;YACzB,MAAM,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAC,CAAC,CAAC,CAAC;YAC/B,OAAO,IAAI,EAAE,CAAC;QAAA,CACd,CAAC,EAAE,CAAC;QACL,IAAI,CAAC,MAAM,CAAC,GAAG,CACd,UAAU,EACV,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAC,CAAC,CAAC,CACpB,CAAC;QACF,OAAO,IAAI,CAAC;IAAA,CACZ;IAED,KAAK,CAAC,IAAI,CAAC,UAAkB,EAAmC;QAC/D,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAAA,CACxC;IAED,KAAK,CAAC,IAAI,GAAuC;QAChD,OAAO,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAAA,CACxG;IAED,MAAM,CACL,UAAkB,EAClB,EAAwE,EACtC;QAClC,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC;YAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACjD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC;YAC/B,IAAI,IAAI,KAAK,SAAS;gBAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAC/D,OAAO,IAAI,IAAI,OAAO,CAAC;QAAA,CACvB,CAAC,CAAC;IAAA,CACH;IAED,MAAM,CAAC,UAAkB,EAAiB;QACzC,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC;YAC3C,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAAA,CACpC,CAAC,CAAC;IAAA,CACH;CACD","sourcesContent":["import type { Credential, CredentialInfo, CredentialStore } from \"./types.ts\";\n\n/**\n * Default in-memory credential store. Apps inject persistent stores.\n * Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.\n * Writes are serialized per provider through a promise chain.\n */\nexport class InMemoryCredentialStore implements CredentialStore {\n\tprivate credentials = new Map<string, Credential>();\n\tprivate chains = new Map<string, Promise<unknown>>();\n\n\t/** Serialize tasks per provider id. */\n\tprivate enqueue<T>(providerId: string, task: () => Promise<T>): Promise<T> {\n\t\tconst previous = this.chains.get(providerId) ?? Promise.resolve();\n\t\tconst next = (async () => {\n\t\t\tawait previous.catch(() => {});\n\t\t\treturn task();\n\t\t})();\n\t\tthis.chains.set(\n\t\t\tproviderId,\n\t\t\tnext.catch(() => {}),\n\t\t);\n\t\treturn next;\n\t}\n\n\tasync read(providerId: string): Promise<Credential | undefined> {\n\t\treturn this.credentials.get(providerId);\n\t}\n\n\tasync list(): Promise<readonly CredentialInfo[]> {\n\t\treturn [...this.credentials].map(([providerId, credential]) => ({ providerId, type: credential.type }));\n\t}\n\n\tmodify(\n\t\tproviderId: string,\n\t\tfn: (current: Credential | undefined) => Promise<Credential | undefined>,\n\t): Promise<Credential | undefined> {\n\t\treturn this.enqueue(providerId, async () => {\n\t\t\tconst current = this.credentials.get(providerId);\n\t\t\tconst next = await fn(current);\n\t\t\tif (next !== undefined) this.credentials.set(providerId, next);\n\t\t\treturn next ?? current;\n\t\t});\n\t}\n\n\tdelete(providerId: string): Promise<void> {\n\t\treturn this.enqueue(providerId, async () => {\n\t\t\tthis.credentials.delete(providerId);\n\t\t});\n\t}\n}\n"]}
1
+ {"version":3,"file":"credential-store.js","sourceRoot":"","sources":["../../src/auth/credential-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAGzE;;;;GAIG;AACH,MAAM,OAAO,uBAAuB;IAC3B,WAAW,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC5C,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IAErD,8FAA8F;IACtF,OAAO,CAAI,UAAkB,EAAE,IAAsB,EAAE,OAA8B;QAC5F,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAClE,MAAM,MAAM,GAAG,CAAC,KAAK,IAAI,EAAE;YAC1B,MAAM,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAC/B,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,OAAO,IAAI,EAAE,CAAC;QACf,CAAC,CAAC,EAAE,CAAC;QACL,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAClC,KAAK,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;YACnB,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,IAAI;gBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;QACH,OAAO,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,UAAkB,EAAE,OAA8B;QAC5D,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAA8B;QACxC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACzG,CAAC;IAED,MAAM,CACL,UAAkB,EAClB,EAAwE,EACxE,OAA8B;QAE9B,OAAO,IAAI,CAAC,OAAO,CAClB,UAAU,EACV,KAAK,IAAI,EAAE;YACV,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACjD,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC;YAC/B,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;YAClC,IAAI,IAAI,KAAK,SAAS;gBAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YAC/D,OAAO,IAAI,IAAI,OAAO,CAAC;QACxB,CAAC,EACD,OAAO,CACP,CAAC;IACH,CAAC;IAED,MAAM,CAAC,UAAkB,EAAE,OAA8B;QACxD,OAAO,IAAI,CAAC,OAAO,CAClB,UAAU,EACV,KAAK,IAAI,EAAE;YACV,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACrC,CAAC,EACD,OAAO,CACP,CAAC;IACH,CAAC;CACD","sourcesContent":["import { operationSignal, raceWithAbortSignal } from \"../utils/abort.ts\";\nimport type { AuthOperationOptions, Credential, CredentialInfo, CredentialStore } from \"./types.ts\";\n\n/**\n * Default in-memory credential store. Apps inject persistent stores.\n * Keyed by `Provider.id`, one credential per provider; see `CredentialStore`.\n * Writes are serialized per provider through a promise chain.\n */\nexport class InMemoryCredentialStore implements CredentialStore {\n\tprivate credentials = new Map<string, Credential>();\n\tprivate chains = new Map<string, Promise<unknown>>();\n\n\t/** Serialize tasks per provider id without releasing the chain before active work settles. */\n\tprivate enqueue<T>(providerId: string, task: () => Promise<T>, options?: AuthOperationOptions): Promise<T> {\n\t\tconst signal = operationSignal(options?.signal);\n\t\tconst previous = this.chains.get(providerId) ?? Promise.resolve();\n\t\tconst queued = (async () => {\n\t\t\tawait previous.catch(() => {});\n\t\t\tsignal.throwIfAborted();\n\t\t\treturn task();\n\t\t})();\n\t\tconst tail = queued.catch(() => {});\n\t\tthis.chains.set(providerId, tail);\n\t\tvoid tail.then(() => {\n\t\t\tif (this.chains.get(providerId) === tail) this.chains.delete(providerId);\n\t\t});\n\t\treturn raceWithAbortSignal(queued, signal);\n\t}\n\n\tasync read(providerId: string, options?: AuthOperationOptions): Promise<Credential | undefined> {\n\t\toptions?.signal?.throwIfAborted();\n\t\treturn this.credentials.get(providerId);\n\t}\n\n\tasync list(options?: AuthOperationOptions): Promise<readonly CredentialInfo[]> {\n\t\toptions?.signal?.throwIfAborted();\n\t\treturn [...this.credentials].map(([providerId, credential]) => ({ providerId, type: credential.type }));\n\t}\n\n\tmodify(\n\t\tproviderId: string,\n\t\tfn: (current: Credential | undefined) => Promise<Credential | undefined>,\n\t\toptions?: AuthOperationOptions,\n\t): Promise<Credential | undefined> {\n\t\treturn this.enqueue(\n\t\t\tproviderId,\n\t\t\tasync () => {\n\t\t\t\tconst current = this.credentials.get(providerId);\n\t\t\t\tconst next = await fn(current);\n\t\t\t\toptions?.signal?.throwIfAborted();\n\t\t\t\tif (next !== undefined) this.credentials.set(providerId, next);\n\t\t\t\treturn next ?? current;\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n\n\tdelete(providerId: string, options?: AuthOperationOptions): Promise<void> {\n\t\treturn this.enqueue(\n\t\t\tproviderId,\n\t\t\tasync () => {\n\t\t\t\tthis.credentials.delete(providerId);\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n}\n"]}
@@ -15,6 +15,7 @@ export declare function envApiKeyAuth(name: string, envVars: readonly string[]):
15
15
  */
16
16
  export declare function lazyOAuth(input: {
17
17
  name: string;
18
+ isSubscription?: boolean;
18
19
  loginLabel?: string;
19
20
  load: () => Promise<OAuthAuth>;
20
21
  }): OAuthAuth;
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/auth/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAExD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CAkBlF;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,CAAA;CAAE,GAAG,SAAS,CAajH","sourcesContent":["import type { ApiKeyAuth, OAuthAuth } from \"./types.ts\";\n\n/**\n * Standard api-key auth: a stored credential key wins, otherwise the first\n * set env var resolves. Includes a `login` that prompts for the key.\n * Providers with non-standard resolution (provider env, ambient files, IAM)\n * write their own `ApiKeyAuth`.\n */\nexport function envApiKeyAuth(name: string, envVars: readonly string[]): ApiKeyAuth {\n\treturn {\n\t\tname,\n\t\tlogin: async (interaction) => {\n\t\t\tconst key = await interaction.prompt({ type: \"secret\", message: `Enter ${name}` });\n\t\t\treturn { type: \"api_key\", key };\n\t\t},\n\t\tresolve: async ({ ctx, credential }) => {\n\t\t\tif (credential?.key) {\n\t\t\t\treturn { auth: { apiKey: credential.key }, env: credential.env, source: \"stored credential\" };\n\t\t\t}\n\t\t\tfor (const envVar of envVars) {\n\t\t\t\tconst value = await ctx.env(envVar);\n\t\t\t\tif (value) return { auth: { apiKey: value }, source: envVar };\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n\n/**\n * Wraps a dynamically imported `OAuthAuth` so provider definitions can\n * advertise OAuth without importing the implementation. The flow loads on\n * first `login`/`refresh`/`toAuth` call; callers keep Node-only flow code out\n * of bundles by loading through a bundler-opaque dynamic import (variable\n * specifier, see the bedrock lazy wrapper).\n */\nexport function lazyOAuth(input: { name: string; loginLabel?: string; load: () => Promise<OAuthAuth> }): OAuthAuth {\n\tlet promise: Promise<OAuthAuth> | undefined;\n\tconst loaded = () => {\n\t\tpromise ??= input.load();\n\t\treturn promise;\n\t};\n\treturn {\n\t\tname: input.name,\n\t\tloginLabel: input.loginLabel,\n\t\tlogin: async (interaction) => (await loaded()).login(interaction),\n\t\trefresh: async (credential) => (await loaded()).refresh(credential),\n\t\ttoAuth: async (credential) => (await loaded()).toAuth(credential),\n\t};\n}\n"]}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/auth/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAExD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CAsBlF;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC;CAC/B,GAAG,SAAS,CAcZ"}
@@ -8,15 +8,19 @@ export function envApiKeyAuth(name, envVars) {
8
8
  return {
9
9
  name,
10
10
  login: async (interaction) => {
11
+ interaction.signal.throwIfAborted();
11
12
  const key = await interaction.prompt({ type: "secret", message: `Enter ${name}` });
13
+ interaction.signal.throwIfAborted();
12
14
  return { type: "api_key", key };
13
15
  },
14
- resolve: async ({ ctx, credential }) => {
16
+ resolve: async ({ ctx, credential, signal }) => {
17
+ signal.throwIfAborted();
15
18
  if (credential?.key) {
16
19
  return { auth: { apiKey: credential.key }, env: credential.env, source: "stored credential" };
17
20
  }
18
21
  for (const envVar of envVars) {
19
22
  const value = await ctx.env(envVar);
23
+ signal.throwIfAborted();
20
24
  if (value)
21
25
  return { auth: { apiKey: value }, source: envVar };
22
26
  }
@@ -39,9 +43,10 @@ export function lazyOAuth(input) {
39
43
  };
40
44
  return {
41
45
  name: input.name,
46
+ isSubscription: input.isSubscription,
42
47
  loginLabel: input.loginLabel,
43
- login: async (interaction) => (await loaded()).login(interaction),
44
- refresh: async (credential) => (await loaded()).refresh(credential),
48
+ login: async (interaction, options) => (await loaded()).login(interaction, options),
49
+ refresh: async (credential, signal) => (await loaded()).refresh(credential, signal),
45
50
  toAuth: async (credential) => (await loaded()).toAuth(credential),
46
51
  };
47
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/auth/helpers.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,OAA0B,EAAc;IACnF,OAAO;QACN,IAAI;QACJ,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC;YACnF,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;QAAA,CAChC;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;YACvC,IAAI,UAAU,EAAE,GAAG,EAAE,CAAC;gBACrB,OAAO,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;YAC/F,CAAC;YACD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC9B,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACpC,IAAI,KAAK;oBAAE,OAAO,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YAC/D,CAAC;YACD,OAAO,SAAS,CAAC;QAAA,CACjB;KACD,CAAC;AAAA,CACF;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,KAA4E,EAAa;IAClH,IAAI,OAAuC,CAAC;IAC5C,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC;QACpB,OAAO,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC;IAAA,CACf,CAAC;IACF,OAAO;QACN,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC;QACjE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC;QACnE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;KACjE,CAAC;AAAA,CACF","sourcesContent":["import type { ApiKeyAuth, OAuthAuth } from \"./types.ts\";\n\n/**\n * Standard api-key auth: a stored credential key wins, otherwise the first\n * set env var resolves. Includes a `login` that prompts for the key.\n * Providers with non-standard resolution (provider env, ambient files, IAM)\n * write their own `ApiKeyAuth`.\n */\nexport function envApiKeyAuth(name: string, envVars: readonly string[]): ApiKeyAuth {\n\treturn {\n\t\tname,\n\t\tlogin: async (interaction) => {\n\t\t\tconst key = await interaction.prompt({ type: \"secret\", message: `Enter ${name}` });\n\t\t\treturn { type: \"api_key\", key };\n\t\t},\n\t\tresolve: async ({ ctx, credential }) => {\n\t\t\tif (credential?.key) {\n\t\t\t\treturn { auth: { apiKey: credential.key }, env: credential.env, source: \"stored credential\" };\n\t\t\t}\n\t\t\tfor (const envVar of envVars) {\n\t\t\t\tconst value = await ctx.env(envVar);\n\t\t\t\tif (value) return { auth: { apiKey: value }, source: envVar };\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n\n/**\n * Wraps a dynamically imported `OAuthAuth` so provider definitions can\n * advertise OAuth without importing the implementation. The flow loads on\n * first `login`/`refresh`/`toAuth` call; callers keep Node-only flow code out\n * of bundles by loading through a bundler-opaque dynamic import (variable\n * specifier, see the bedrock lazy wrapper).\n */\nexport function lazyOAuth(input: { name: string; loginLabel?: string; load: () => Promise<OAuthAuth> }): OAuthAuth {\n\tlet promise: Promise<OAuthAuth> | undefined;\n\tconst loaded = () => {\n\t\tpromise ??= input.load();\n\t\treturn promise;\n\t};\n\treturn {\n\t\tname: input.name,\n\t\tloginLabel: input.loginLabel,\n\t\tlogin: async (interaction) => (await loaded()).login(interaction),\n\t\trefresh: async (credential) => (await loaded()).refresh(credential),\n\t\ttoAuth: async (credential) => (await loaded()).toAuth(credential),\n\t};\n}\n"]}
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/auth/helpers.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,OAA0B;IACrE,OAAO;QACN,IAAI;QACJ,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE;YAC5B,WAAW,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YACpC,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC;YACnF,WAAW,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YACpC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC;QACjC,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE;YAC9C,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,UAAU,EAAE,GAAG,EAAE,CAAC;gBACrB,OAAO,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;YAC/F,CAAC;YACD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC9B,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACpC,MAAM,CAAC,cAAc,EAAE,CAAC;gBACxB,IAAI,KAAK;oBAAE,OAAO,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YAC/D,CAAC;YACD,OAAO,SAAS,CAAC;QAClB,CAAC;KACD,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,KAKzB;IACA,IAAI,OAAuC,CAAC;IAC5C,MAAM,MAAM,GAAG,GAAG,EAAE;QACnB,OAAO,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC;IAChB,CAAC,CAAC;IACF,OAAO;QACN,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC;QACnF,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC;QACnF,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;KACjE,CAAC;AACH,CAAC","sourcesContent":["import type { ApiKeyAuth, OAuthAuth } from \"./types.ts\";\n\n/**\n * Standard api-key auth: a stored credential key wins, otherwise the first\n * set env var resolves. Includes a `login` that prompts for the key.\n * Providers with non-standard resolution (provider env, ambient files, IAM)\n * write their own `ApiKeyAuth`.\n */\nexport function envApiKeyAuth(name: string, envVars: readonly string[]): ApiKeyAuth {\n\treturn {\n\t\tname,\n\t\tlogin: async (interaction) => {\n\t\t\tinteraction.signal.throwIfAborted();\n\t\t\tconst key = await interaction.prompt({ type: \"secret\", message: `Enter ${name}` });\n\t\t\tinteraction.signal.throwIfAborted();\n\t\t\treturn { type: \"api_key\", key };\n\t\t},\n\t\tresolve: async ({ ctx, credential, signal }) => {\n\t\t\tsignal.throwIfAborted();\n\t\t\tif (credential?.key) {\n\t\t\t\treturn { auth: { apiKey: credential.key }, env: credential.env, source: \"stored credential\" };\n\t\t\t}\n\t\t\tfor (const envVar of envVars) {\n\t\t\t\tconst value = await ctx.env(envVar);\n\t\t\t\tsignal.throwIfAborted();\n\t\t\t\tif (value) return { auth: { apiKey: value }, source: envVar };\n\t\t\t}\n\t\t\treturn undefined;\n\t\t},\n\t};\n}\n\n/**\n * Wraps a dynamically imported `OAuthAuth` so provider definitions can\n * advertise OAuth without importing the implementation. The flow loads on\n * first `login`/`refresh`/`toAuth` call; callers keep Node-only flow code out\n * of bundles by loading through a bundler-opaque dynamic import (variable\n * specifier, see the bedrock lazy wrapper).\n */\nexport function lazyOAuth(input: {\n\tname: string;\n\tisSubscription?: boolean;\n\tloginLabel?: string;\n\tload: () => Promise<OAuthAuth>;\n}): OAuthAuth {\n\tlet promise: Promise<OAuthAuth> | undefined;\n\tconst loaded = () => {\n\t\tpromise ??= input.load();\n\t\treturn promise;\n\t};\n\treturn {\n\t\tname: input.name,\n\t\tisSubscription: input.isSubscription,\n\t\tloginLabel: input.loginLabel,\n\t\tlogin: async (interaction, options) => (await loaded()).login(interaction, options),\n\t\trefresh: async (credential, signal) => (await loaded()).refresh(credential, signal),\n\t\ttoAuth: async (credential) => (await loaded()).toAuth(credential),\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAmB,SAAS,EAAmB,MAAM,aAAa,CAAC;AA4U/E,eAAO,MAAM,cAAc,EAAE,SAQ5B,CAAC","sourcesContent":["/**\n * Anthropic OAuth flow (Claude Pro/Max)\n *\n * NOTE: This module uses Node.js http.createServer for the OAuth callback server.\n * It is only intended for CLI use, not browser environments.\n */\n\nimport type { Server } from \"node:http\";\nimport { getProviderEnvValue } from \"../../utils/provider-env.ts\";\nimport type { AuthInteraction, OAuthAuth, OAuthCredential } from \"../types.ts\";\nimport { oauthErrorHtml, oauthSuccessHtml } from \"./oauth-page.ts\";\nimport { generatePKCE } from \"./pkce.ts\";\n\ntype CallbackServerInfo = {\n\tserver: Server;\n\tredirectUri: string;\n\tcancelWait: () => void;\n\twaitForCode: () => Promise<{ code: string; state: string } | null>;\n};\n\ntype NodeApis = {\n\tcreateServer: typeof import(\"node:http\").createServer;\n};\n\nlet nodeApis: NodeApis | null = null;\nlet nodeApisPromise: Promise<NodeApis> | null = null;\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode(\"OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl\");\nconst AUTHORIZE_URL = \"https://claude.ai/oauth/authorize\";\nconst TOKEN_URL = \"https://platform.claude.com/v1/oauth/token\";\nconst CALLBACK_HOST = getProviderEnvValue(\"PI_OAUTH_CALLBACK_HOST\") || \"127.0.0.1\";\nconst CALLBACK_PORT = 53692;\nconst CALLBACK_PATH = \"/callback\";\nconst REDIRECT_URI = `http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`;\nconst SCOPES =\n\t\"org:create_api_key user:profile user:inference user:sessions:claude_code user:mcp_servers user:file_upload\";\nasync function getNodeApis(): Promise<NodeApis> {\n\tif (nodeApis) return nodeApis;\n\tif (!nodeApisPromise) {\n\t\tif (typeof process === \"undefined\" || (!process.versions?.node && !process.versions?.bun)) {\n\t\t\tthrow new Error(\"Anthropic OAuth is only available in Node.js environments\");\n\t\t}\n\t\tnodeApisPromise = import(\"node:http\").then((httpModule) => ({\n\t\t\tcreateServer: httpModule.createServer,\n\t\t}));\n\t}\n\tnodeApis = await nodeApisPromise;\n\treturn nodeApis;\n}\n\nfunction parseAuthorizationInput(input: string): { code?: string; state?: string } {\n\tconst value = input.trim();\n\tif (!value) return {};\n\n\ttry {\n\t\tconst url = new URL(value);\n\t\treturn {\n\t\t\tcode: url.searchParams.get(\"code\") ?? undefined,\n\t\t\tstate: url.searchParams.get(\"state\") ?? undefined,\n\t\t};\n\t} catch {\n\t\t// not a URL\n\t}\n\n\tif (value.includes(\"#\")) {\n\t\tconst [code, state] = value.split(\"#\", 2);\n\t\treturn { code, state };\n\t}\n\n\tif (value.includes(\"code=\")) {\n\t\tconst params = new URLSearchParams(value);\n\t\treturn {\n\t\t\tcode: params.get(\"code\") ?? undefined,\n\t\t\tstate: params.get(\"state\") ?? undefined,\n\t\t};\n\t}\n\n\treturn { code: value };\n}\n\nfunction formatErrorDetails(error: unknown): string {\n\tif (error instanceof Error) {\n\t\tconst details: string[] = [`${error.name}: ${error.message}`];\n\t\tconst errorWithCode = error as Error & { code?: string; errno?: number | string; cause?: unknown };\n\t\tif (errorWithCode.code) details.push(`code=${errorWithCode.code}`);\n\t\tif (typeof errorWithCode.errno !== \"undefined\") details.push(`errno=${String(errorWithCode.errno)}`);\n\t\tif (typeof error.cause !== \"undefined\") {\n\t\t\tdetails.push(`cause=${formatErrorDetails(error.cause)}`);\n\t\t}\n\t\tif (error.stack) {\n\t\t\tdetails.push(`stack=${error.stack}`);\n\t\t}\n\t\treturn details.join(\"; \");\n\t}\n\treturn String(error);\n}\n\nasync function startCallbackServer(expectedState: string): Promise<CallbackServerInfo> {\n\tconst { createServer } = await getNodeApis();\n\n\treturn new Promise((resolve, reject) => {\n\t\tlet settleWait: ((value: { code: string; state: string } | null) => void) | undefined;\n\t\tconst waitForCodePromise = new Promise<{ code: string; state: string } | null>((resolveWait) => {\n\t\t\tlet settled = false;\n\t\t\tsettleWait = (value) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tresolveWait(value);\n\t\t\t};\n\t\t});\n\n\t\tconst server = createServer((req, res) => {\n\t\t\ttry {\n\t\t\t\tconst url = new URL(req.url || \"\", \"http://localhost\");\n\t\t\t\tif (url.pathname !== CALLBACK_PATH) {\n\t\t\t\t\tres.writeHead(404, { \"Content-Type\": \"text/html; charset=utf-8\" });\n\t\t\t\t\tres.end(oauthErrorHtml(\"Callback route not found.\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst code = url.searchParams.get(\"code\");\n\t\t\t\tconst state = url.searchParams.get(\"state\");\n\t\t\t\tconst error = url.searchParams.get(\"error\");\n\n\t\t\t\tif (error) {\n\t\t\t\t\tres.writeHead(400, { \"Content-Type\": \"text/html; charset=utf-8\" });\n\t\t\t\t\tres.end(oauthErrorHtml(\"Anthropic authentication did not complete.\", `Error: ${error}`));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (!code || !state) {\n\t\t\t\t\tres.writeHead(400, { \"Content-Type\": \"text/html; charset=utf-8\" });\n\t\t\t\t\tres.end(oauthErrorHtml(\"Missing code or state parameter.\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (state !== expectedState) {\n\t\t\t\t\tres.writeHead(400, { \"Content-Type\": \"text/html; charset=utf-8\" });\n\t\t\t\t\tres.end(oauthErrorHtml(\"State mismatch.\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tres.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n\t\t\t\tres.end(oauthSuccessHtml(\"Anthropic authentication completed. You can close this window.\"));\n\t\t\t\tsettleWait?.({ code, state });\n\t\t\t} catch {\n\t\t\t\tres.writeHead(500, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n\t\t\t\tres.end(\"Internal error\");\n\t\t\t}\n\t\t});\n\n\t\tserver.on(\"error\", (err) => {\n\t\t\treject(err);\n\t\t});\n\n\t\tserver.listen(CALLBACK_PORT, CALLBACK_HOST, () => {\n\t\t\tresolve({\n\t\t\t\tserver,\n\t\t\t\tredirectUri: REDIRECT_URI,\n\t\t\t\tcancelWait: () => {\n\t\t\t\t\tsettleWait?.(null);\n\t\t\t\t},\n\t\t\t\twaitForCode: () => waitForCodePromise,\n\t\t\t});\n\t\t});\n\t});\n}\n\nasync function postJson(url: string, body: Record<string, string | number>): Promise<string> {\n\tconst response = await fetch(url, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAccept: \"application/json\",\n\t\t},\n\t\tbody: JSON.stringify(body),\n\t\tsignal: AbortSignal.timeout(30_000),\n\t});\n\n\tconst responseBody = await response.text();\n\n\tif (!response.ok) {\n\t\tthrow new Error(`HTTP request failed. status=${response.status}; url=${url}; body=${responseBody}`);\n\t}\n\n\treturn responseBody;\n}\n\nasync function exchangeAuthorizationCode(\n\tcode: string,\n\tstate: string,\n\tverifier: string,\n\tredirectUri: string,\n): Promise<OAuthCredential> {\n\tlet responseBody: string;\n\ttry {\n\t\tresponseBody = await postJson(TOKEN_URL, {\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tcode,\n\t\t\tstate,\n\t\t\tredirect_uri: redirectUri,\n\t\t\tcode_verifier: verifier,\n\t\t});\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Token exchange request failed. url=${TOKEN_URL}; redirect_uri=${redirectUri}; response_type=authorization_code; details=${formatErrorDetails(error)}`,\n\t\t);\n\t}\n\n\tlet tokenData: { access_token: string; refresh_token: string; expires_in: number };\n\ttry {\n\t\ttokenData = JSON.parse(responseBody) as { access_token: string; refresh_token: string; expires_in: number };\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Token exchange returned invalid JSON. url=${TOKEN_URL}; body=${responseBody}; details=${formatErrorDetails(error)}`,\n\t\t);\n\t}\n\n\treturn {\n\t\ttype: \"oauth\",\n\t\trefresh: tokenData.refresh_token,\n\t\taccess: tokenData.access_token,\n\t\texpires: Date.now() + tokenData.expires_in * 1000 - 5 * 60 * 1000,\n\t};\n}\n\nasync function loginAnthropic(interaction: AuthInteraction): Promise<OAuthCredential> {\n\tconst { verifier, challenge } = await generatePKCE();\n\tconst server = await startCallbackServer(verifier);\n\tconst manualAbort = new AbortController();\n\tlet code: string | undefined;\n\tlet state: string | undefined;\n\tlet manualInput: string | undefined;\n\tlet manualError: Error | undefined;\n\n\ttry {\n\t\tconst authParams = new URLSearchParams({\n\t\t\tcode: \"true\",\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tresponse_type: \"code\",\n\t\t\tredirect_uri: REDIRECT_URI,\n\t\t\tscope: SCOPES,\n\t\t\tcode_challenge: challenge,\n\t\t\tcode_challenge_method: \"S256\",\n\t\t\tstate: verifier,\n\t\t});\n\t\tinteraction.notify({\n\t\t\ttype: \"auth_url\",\n\t\t\turl: `${AUTHORIZE_URL}?${authParams.toString()}`,\n\t\t\tinstructions:\n\t\t\t\t\"Complete login in your browser. If the browser is on another machine, paste the final redirect URL here.\",\n\t\t});\n\n\t\tconst manualPromise = interaction\n\t\t\t.prompt({\n\t\t\t\ttype: \"manual_code\",\n\t\t\t\tmessage: \"Complete login in your browser, or paste the authorization code / redirect URL here:\",\n\t\t\t\tplaceholder: REDIRECT_URI,\n\t\t\t\tsignal: manualAbort.signal,\n\t\t\t})\n\t\t\t.then((input) => {\n\t\t\t\tmanualInput = input;\n\t\t\t\tserver.cancelWait();\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tmanualError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\tserver.cancelWait();\n\t\t\t});\n\n\t\tconst result = await server.waitForCode();\n\t\tif (manualError) throw manualError;\n\t\tif (result?.code) {\n\t\t\tcode = result.code;\n\t\t\tstate = result.state;\n\t\t} else if (manualInput) {\n\t\t\tconst parsed = parseAuthorizationInput(manualInput);\n\t\t\tif (parsed.state && parsed.state !== verifier) throw new Error(\"OAuth state mismatch\");\n\t\t\tcode = parsed.code;\n\t\t\tstate = parsed.state ?? verifier;\n\t\t}\n\n\t\tif (!code) {\n\t\t\tawait manualPromise;\n\t\t\tif (manualError) throw manualError;\n\t\t\tif (manualInput) {\n\t\t\t\tconst parsed = parseAuthorizationInput(manualInput);\n\t\t\t\tif (parsed.state && parsed.state !== verifier) throw new Error(\"OAuth state mismatch\");\n\t\t\t\tcode = parsed.code;\n\t\t\t\tstate = parsed.state ?? verifier;\n\t\t\t}\n\t\t}\n\n\t\tif (!code) throw new Error(\"Missing authorization code\");\n\t\tif (!state) throw new Error(\"Missing OAuth state\");\n\t\tinteraction.notify({ type: \"progress\", message: \"Exchanging authorization code for tokens...\" });\n\t\treturn exchangeAuthorizationCode(code, state, verifier, REDIRECT_URI);\n\t} finally {\n\t\tmanualAbort.abort();\n\t\tserver.server.close();\n\t}\n}\n\n/**\n * Refresh Anthropic OAuth token\n */\nasync function refreshAnthropicToken(refreshToken: string): Promise<OAuthCredential> {\n\tlet responseBody: string;\n\ttry {\n\t\tresponseBody = await postJson(TOKEN_URL, {\n\t\t\tgrant_type: \"refresh_token\",\n\t\t\tclient_id: CLIENT_ID,\n\t\t\trefresh_token: refreshToken,\n\t\t});\n\t} catch (error) {\n\t\tthrow new Error(`Anthropic token refresh request failed. url=${TOKEN_URL}; details=${formatErrorDetails(error)}`);\n\t}\n\n\tlet data: { access_token: string; refresh_token: string; expires_in: number; scope?: string };\n\ttry {\n\t\tdata = JSON.parse(responseBody) as {\n\t\t\taccess_token: string;\n\t\t\trefresh_token: string;\n\t\t\texpires_in: number;\n\t\t\tscope?: string;\n\t\t};\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Anthropic token refresh returned invalid JSON. url=${TOKEN_URL}; body=${responseBody}; details=${formatErrorDetails(error)}`,\n\t\t);\n\t}\n\n\treturn {\n\t\ttype: \"oauth\",\n\t\trefresh: data.refresh_token,\n\t\taccess: data.access_token,\n\t\texpires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000,\n\t};\n}\n\nexport const anthropicOAuth: OAuthAuth = {\n\tname: \"Anthropic (Claude Pro/Max)\",\n\tlogin: loginAnthropic,\n\trefresh: (credential) => refreshAnthropicToken(credential.refresh),\n\n\tasync toAuth(credential) {\n\t\treturn { apiKey: credential.access };\n\t},\n};\n"]}
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,SAAS,EAA4C,MAAM,aAAa,CAAC;AAoQvF,eAAO,MAAM,cAAc,EAAE,SA6B5B,CAAC"}
@@ -5,10 +5,8 @@
5
5
  * It is only intended for CLI use, not browser environments.
6
6
  */
7
7
  import { getProviderEnvValue } from "../../utils/provider-env.js";
8
- import { oauthErrorHtml, oauthSuccessHtml } from "./oauth-page.js";
8
+ import { startOAuthCallbackServer, waitForCallbackOrManualInput } from "./callback-server.js";
9
9
  import { generatePKCE } from "./pkce.js";
10
- let nodeApis = null;
11
- let nodeApisPromise = null;
12
10
  const decode = (s) => atob(s);
13
11
  const CLIENT_ID = decode("OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl");
14
12
  const AUTHORIZE_URL = "https://claude.ai/oauth/authorize";
@@ -17,21 +15,10 @@ const CALLBACK_HOST = getProviderEnvValue("PI_OAUTH_CALLBACK_HOST") || "127.0.0.
17
15
  const CALLBACK_PORT = 53692;
18
16
  const CALLBACK_PATH = "/callback";
19
17
  const REDIRECT_URI = `http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`;
18
+ const COPY_CODE_REDIRECT_URI = "https://platform.claude.com/oauth/code/callback";
19
+ const ANTHROPIC_BROWSER_LOGIN_METHOD = "browser";
20
+ const ANTHROPIC_COPY_CODE_LOGIN_METHOD = "copy_code";
20
21
  const SCOPES = "org:create_api_key user:profile user:inference user:sessions:claude_code user:mcp_servers user:file_upload";
21
- async function getNodeApis() {
22
- if (nodeApis)
23
- return nodeApis;
24
- if (!nodeApisPromise) {
25
- if (typeof process === "undefined" || (!process.versions?.node && !process.versions?.bun)) {
26
- throw new Error("Anthropic OAuth is only available in Node.js environments");
27
- }
28
- nodeApisPromise = import("node:http").then((httpModule) => ({
29
- createServer: httpModule.createServer,
30
- }));
31
- }
32
- nodeApis = await nodeApisPromise;
33
- return nodeApis;
34
- }
35
22
  function parseAuthorizationInput(input) {
36
23
  const value = input.trim();
37
24
  if (!value)
@@ -77,70 +64,7 @@ function formatErrorDetails(error) {
77
64
  }
78
65
  return String(error);
79
66
  }
80
- async function startCallbackServer(expectedState) {
81
- const { createServer } = await getNodeApis();
82
- return new Promise((resolve, reject) => {
83
- let settleWait;
84
- const waitForCodePromise = new Promise((resolveWait) => {
85
- let settled = false;
86
- settleWait = (value) => {
87
- if (settled)
88
- return;
89
- settled = true;
90
- resolveWait(value);
91
- };
92
- });
93
- const server = createServer((req, res) => {
94
- try {
95
- const url = new URL(req.url || "", "http://localhost");
96
- if (url.pathname !== CALLBACK_PATH) {
97
- res.writeHead(404, { "Content-Type": "text/html; charset=utf-8" });
98
- res.end(oauthErrorHtml("Callback route not found."));
99
- return;
100
- }
101
- const code = url.searchParams.get("code");
102
- const state = url.searchParams.get("state");
103
- const error = url.searchParams.get("error");
104
- if (error) {
105
- res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
106
- res.end(oauthErrorHtml("Anthropic authentication did not complete.", `Error: ${error}`));
107
- return;
108
- }
109
- if (!code || !state) {
110
- res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
111
- res.end(oauthErrorHtml("Missing code or state parameter."));
112
- return;
113
- }
114
- if (state !== expectedState) {
115
- res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
116
- res.end(oauthErrorHtml("State mismatch."));
117
- return;
118
- }
119
- res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
120
- res.end(oauthSuccessHtml("Anthropic authentication completed. You can close this window."));
121
- settleWait?.({ code, state });
122
- }
123
- catch {
124
- res.writeHead(500, { "Content-Type": "text/plain; charset=utf-8" });
125
- res.end("Internal error");
126
- }
127
- });
128
- server.on("error", (err) => {
129
- reject(err);
130
- });
131
- server.listen(CALLBACK_PORT, CALLBACK_HOST, () => {
132
- resolve({
133
- server,
134
- redirectUri: REDIRECT_URI,
135
- cancelWait: () => {
136
- settleWait?.(null);
137
- },
138
- waitForCode: () => waitForCodePromise,
139
- });
140
- });
141
- });
142
- }
143
- async function postJson(url, body) {
67
+ async function postJson(url, body, signal) {
144
68
  const response = await fetch(url, {
145
69
  method: "POST",
146
70
  headers: {
@@ -148,7 +72,7 @@ async function postJson(url, body) {
148
72
  Accept: "application/json",
149
73
  },
150
74
  body: JSON.stringify(body),
151
- signal: AbortSignal.timeout(30_000),
75
+ signal: AbortSignal.any([signal, AbortSignal.timeout(30_000)]),
152
76
  });
153
77
  const responseBody = await response.text();
154
78
  if (!response.ok) {
@@ -156,7 +80,7 @@ async function postJson(url, body) {
156
80
  }
157
81
  return responseBody;
158
82
  }
159
- async function exchangeAuthorizationCode(code, state, verifier, redirectUri) {
83
+ async function exchangeAuthorizationCode(code, state, verifier, redirectUri, signal) {
160
84
  let responseBody;
161
85
  try {
162
86
  responseBody = await postJson(TOKEN_URL, {
@@ -166,7 +90,7 @@ async function exchangeAuthorizationCode(code, state, verifier, redirectUri) {
166
90
  state,
167
91
  redirect_uri: redirectUri,
168
92
  code_verifier: verifier,
169
- });
93
+ }, signal);
170
94
  }
171
95
  catch (error) {
172
96
  throw new Error(`Token exchange request failed. url=${TOKEN_URL}; redirect_uri=${redirectUri}; response_type=authorization_code; details=${formatErrorDetails(error)}`);
@@ -187,12 +111,15 @@ async function exchangeAuthorizationCode(code, state, verifier, redirectUri) {
187
111
  }
188
112
  async function loginAnthropic(interaction) {
189
113
  const { verifier, challenge } = await generatePKCE();
190
- const server = await startCallbackServer(verifier);
191
- const manualAbort = new AbortController();
192
- let code;
193
- let state;
194
- let manualInput;
195
- let manualError;
114
+ const callback = await startOAuthCallbackServer({
115
+ providerName: "Anthropic",
116
+ host: CALLBACK_HOST,
117
+ port: CALLBACK_PORT,
118
+ path: CALLBACK_PATH,
119
+ state: verifier,
120
+ complete: async (code) => code,
121
+ signal: interaction.signal,
122
+ }).catch(() => undefined);
196
123
  try {
197
124
  const authParams = new URLSearchParams({
198
125
  code: "true",
@@ -209,70 +136,73 @@ async function loginAnthropic(interaction) {
209
136
  url: `${AUTHORIZE_URL}?${authParams.toString()}`,
210
137
  instructions: "Complete login in your browser. If the browser is on another machine, paste the final redirect URL here.",
211
138
  });
212
- const manualPromise = interaction
213
- .prompt({
214
- type: "manual_code",
139
+ const result = await waitForCallbackOrManualInput(interaction, callback, {
215
140
  message: "Complete login in your browser, or paste the authorization code / redirect URL here:",
216
141
  placeholder: REDIRECT_URI,
217
- signal: manualAbort.signal,
218
- })
219
- .then((input) => {
220
- manualInput = input;
221
- server.cancelWait();
222
- })
223
- .catch((error) => {
224
- manualError = error instanceof Error ? error : new Error(String(error));
225
- server.cancelWait();
226
142
  });
227
- const result = await server.waitForCode();
228
- if (manualError)
229
- throw manualError;
230
- if (result?.code) {
231
- code = result.code;
232
- state = result.state;
143
+ let code;
144
+ let state = verifier;
145
+ if (result.type === "callback") {
146
+ code = result.value;
233
147
  }
234
- else if (manualInput) {
235
- const parsed = parseAuthorizationInput(manualInput);
148
+ else {
149
+ const parsed = parseAuthorizationInput(result.input);
236
150
  if (parsed.state && parsed.state !== verifier)
237
151
  throw new Error("OAuth state mismatch");
238
152
  code = parsed.code;
239
153
  state = parsed.state ?? verifier;
240
154
  }
241
- if (!code) {
242
- await manualPromise;
243
- if (manualError)
244
- throw manualError;
245
- if (manualInput) {
246
- const parsed = parseAuthorizationInput(manualInput);
247
- if (parsed.state && parsed.state !== verifier)
248
- throw new Error("OAuth state mismatch");
249
- code = parsed.code;
250
- state = parsed.state ?? verifier;
251
- }
252
- }
253
155
  if (!code)
254
156
  throw new Error("Missing authorization code");
255
- if (!state)
256
- throw new Error("Missing OAuth state");
257
157
  interaction.notify({ type: "progress", message: "Exchanging authorization code for tokens..." });
258
- return exchangeAuthorizationCode(code, state, verifier, REDIRECT_URI);
158
+ return await exchangeAuthorizationCode(code, state, verifier, REDIRECT_URI, interaction.signal);
259
159
  }
260
160
  finally {
261
- manualAbort.abort();
262
- server.server.close();
161
+ callback?.close();
263
162
  }
264
163
  }
164
+ async function loginAnthropicCopyCode(interaction) {
165
+ const { verifier, challenge } = await generatePKCE();
166
+ const authParams = new URLSearchParams({
167
+ code: "true",
168
+ client_id: CLIENT_ID,
169
+ response_type: "code",
170
+ redirect_uri: COPY_CODE_REDIRECT_URI,
171
+ scope: SCOPES,
172
+ code_challenge: challenge,
173
+ code_challenge_method: "S256",
174
+ state: verifier,
175
+ });
176
+ interaction.notify({
177
+ type: "auth_url",
178
+ url: `${AUTHORIZE_URL}?${authParams.toString()}`,
179
+ instructions: "Complete login in your browser, then copy the code Anthropic shows and paste it here.",
180
+ });
181
+ const input = await interaction.prompt({
182
+ type: "manual_code",
183
+ message: "Paste the code Anthropic shows after you sign in:",
184
+ placeholder: "code#state",
185
+ signal: interaction.signal,
186
+ });
187
+ const parsed = parseAuthorizationInput(input);
188
+ if (parsed.state && parsed.state !== verifier)
189
+ throw new Error("OAuth state mismatch");
190
+ if (!parsed.code)
191
+ throw new Error("Missing authorization code");
192
+ interaction.notify({ type: "progress", message: "Exchanging authorization code for tokens..." });
193
+ return await exchangeAuthorizationCode(parsed.code, parsed.state ?? verifier, verifier, COPY_CODE_REDIRECT_URI, interaction.signal);
194
+ }
265
195
  /**
266
196
  * Refresh Anthropic OAuth token
267
197
  */
268
- async function refreshAnthropicToken(refreshToken) {
198
+ async function refreshAnthropicToken(refreshToken, signal) {
269
199
  let responseBody;
270
200
  try {
271
201
  responseBody = await postJson(TOKEN_URL, {
272
202
  grant_type: "refresh_token",
273
203
  client_id: CLIENT_ID,
274
204
  refresh_token: refreshToken,
275
- });
205
+ }, signal);
276
206
  }
277
207
  catch (error) {
278
208
  throw new Error(`Anthropic token refresh request failed. url=${TOKEN_URL}; details=${formatErrorDetails(error)}`);
@@ -293,8 +223,25 @@ async function refreshAnthropicToken(refreshToken) {
293
223
  }
294
224
  export const anthropicOAuth = {
295
225
  name: "Anthropic (Claude Pro/Max)",
296
- login: loginAnthropic,
297
- refresh: (credential) => refreshAnthropicToken(credential.refresh),
226
+ isSubscription: true,
227
+ async login(interaction) {
228
+ const method = await interaction.prompt({
229
+ type: "select",
230
+ message: "Select Anthropic login method:",
231
+ options: [
232
+ { id: ANTHROPIC_BROWSER_LOGIN_METHOD, label: "Browser login (default)" },
233
+ { id: ANTHROPIC_COPY_CODE_LOGIN_METHOD, label: "Copy code login (headless)" },
234
+ ],
235
+ });
236
+ if (method === ANTHROPIC_COPY_CODE_LOGIN_METHOD) {
237
+ return loginAnthropicCopyCode(interaction);
238
+ }
239
+ if (method !== ANTHROPIC_BROWSER_LOGIN_METHOD) {
240
+ throw new Error(`Unknown Anthropic login method: ${method}`);
241
+ }
242
+ return loginAnthropic(interaction);
243
+ },
244
+ refresh: (credential, signal) => refreshAnthropicToken(credential.refresh, signal),
298
245
  async toAuth(credential) {
299
246
  return { apiKey: credential.access };
300
247
  },
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/auth/oauth/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAazC,IAAI,QAAQ,GAAoB,IAAI,CAAC;AACrC,IAAI,eAAe,GAA6B,IAAI,CAAC;AAErD,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACtC,MAAM,SAAS,GAAG,MAAM,CAAC,kDAAkD,CAAC,CAAC;AAC7E,MAAM,aAAa,GAAG,mCAAmC,CAAC;AAC1D,MAAM,SAAS,GAAG,4CAA4C,CAAC;AAC/D,MAAM,aAAa,GAAG,mBAAmB,CAAC,wBAAwB,CAAC,IAAI,WAAW,CAAC;AACnF,MAAM,aAAa,GAAG,KAAK,CAAC;AAC5B,MAAM,aAAa,GAAG,WAAW,CAAC;AAClC,MAAM,YAAY,GAAG,oBAAoB,aAAa,GAAG,aAAa,EAAE,CAAC;AACzE,MAAM,MAAM,GACX,4GAA4G,CAAC;AAC9G,KAAK,UAAU,WAAW,GAAsB;IAC/C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,IAAI,CAAC,eAAe,EAAE,CAAC;QACtB,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,CAAC;YAC3F,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;QAC9E,CAAC;QACD,eAAe,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YAC3D,YAAY,EAAE,UAAU,CAAC,YAAY;SACrC,CAAC,CAAC,CAAC;IACL,CAAC;IACD,QAAQ,GAAG,MAAM,eAAe,CAAC;IACjC,OAAO,QAAQ,CAAC;AAAA,CAChB;AAED,SAAS,uBAAuB,CAAC,KAAa,EAAqC;IAClF,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IAEtB,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3B,OAAO;YACN,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,SAAS;YAC/C,KAAK,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,SAAS;SACjD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACR,YAAY;IACb,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC1C,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC;QAC1C,OAAO;YACN,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,SAAS;YACrC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,SAAS;SACvC,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAAA,CACvB;AAED,SAAS,kBAAkB,CAAC,KAAc,EAAU;IACnD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAa,CAAC,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9D,MAAM,aAAa,GAAG,KAA4E,CAAC;QACnG,IAAI,aAAa,CAAC,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC;QACnE,IAAI,OAAO,aAAa,CAAC,KAAK,KAAK,WAAW;YAAE,OAAO,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACrG,IAAI,OAAO,KAAK,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YACxC,OAAO,CAAC,IAAI,CAAC,SAAS,kBAAkB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AAAA,CACrB;AAED,KAAK,UAAU,mBAAmB,CAAC,aAAqB,EAA+B;IACtF,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,WAAW,EAAE,CAAC;IAE7C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;QACvC,IAAI,UAAiF,CAAC;QACtF,MAAM,kBAAkB,GAAG,IAAI,OAAO,CAAyC,CAAC,WAAW,EAAE,EAAE,CAAC;YAC/F,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,UAAU,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC;gBACvB,IAAI,OAAO;oBAAE,OAAO;gBACpB,OAAO,GAAG,IAAI,CAAC;gBACf,WAAW,CAAC,KAAK,CAAC,CAAC;YAAA,CACnB,CAAC;QAAA,CACF,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC;YACzC,IAAI,CAAC;gBACJ,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC;gBACvD,IAAI,GAAG,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;oBACpC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;oBACnE,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,2BAA2B,CAAC,CAAC,CAAC;oBACrD,OAAO;gBACR,CAAC;gBAED,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAC1C,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAC5C,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBAE5C,IAAI,KAAK,EAAE,CAAC;oBACX,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;oBACnE,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,4CAA4C,EAAE,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC;oBACzF,OAAO;gBACR,CAAC;gBAED,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBACrB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;oBACnE,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,kCAAkC,CAAC,CAAC,CAAC;oBAC5D,OAAO;gBACR,CAAC;gBAED,IAAI,KAAK,KAAK,aAAa,EAAE,CAAC;oBAC7B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;oBACnE,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAAC;oBAC3C,OAAO;gBACR,CAAC;gBAED,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;gBACnE,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,gEAAgE,CAAC,CAAC,CAAC;gBAC5F,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACR,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,2BAA2B,EAAE,CAAC,CAAC;gBACpE,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YAC3B,CAAC;QAAA,CACD,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,CAAC,CAAC;QAAA,CACZ,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC;YACjD,OAAO,CAAC;gBACP,MAAM;gBACN,WAAW,EAAE,YAAY;gBACzB,UAAU,EAAE,GAAG,EAAE,CAAC;oBACjB,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC;gBAAA,CACnB;gBACD,WAAW,EAAE,GAAG,EAAE,CAAC,kBAAkB;aACrC,CAAC,CAAC;QAAA,CACH,CAAC,CAAC;IAAA,CACH,CAAC,CAAC;AAAA,CACH;AAED,KAAK,UAAU,QAAQ,CAAC,GAAW,EAAE,IAAqC,EAAmB;IAC5F,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QACjC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACR,cAAc,EAAE,kBAAkB;YAClC,MAAM,EAAE,kBAAkB;SAC1B;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAC1B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC;KACnC,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAE3C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,CAAC,MAAM,SAAS,GAAG,UAAU,YAAY,EAAE,CAAC,CAAC;IACrG,CAAC;IAED,OAAO,YAAY,CAAC;AAAA,CACpB;AAED,KAAK,UAAU,yBAAyB,CACvC,IAAY,EACZ,KAAa,EACb,QAAgB,EAChB,WAAmB,EACQ;IAC3B,IAAI,YAAoB,CAAC;IACzB,IAAI,CAAC;QACJ,YAAY,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE;YACxC,UAAU,EAAE,oBAAoB;YAChC,SAAS,EAAE,SAAS;YACpB,IAAI;YACJ,KAAK;YACL,YAAY,EAAE,WAAW;YACzB,aAAa,EAAE,QAAQ;SACvB,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACd,sCAAsC,SAAS,kBAAkB,WAAW,+CAA+C,kBAAkB,CAAC,KAAK,CAAC,EAAE,CACtJ,CAAC;IACH,CAAC;IAED,IAAI,SAA8E,CAAC;IACnF,IAAI,CAAC;QACJ,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAwE,CAAC;IAC7G,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACd,6CAA6C,SAAS,UAAU,YAAY,aAAa,kBAAkB,CAAC,KAAK,CAAC,EAAE,CACpH,CAAC;IACH,CAAC;IAED,OAAO;QACN,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,SAAS,CAAC,aAAa;QAChC,MAAM,EAAE,SAAS,CAAC,YAAY;QAC9B,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,UAAU,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI;KACjE,CAAC;AAAA,CACF;AAED,KAAK,UAAU,cAAc,CAAC,WAA4B,EAA4B;IACrF,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM,YAAY,EAAE,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,WAAW,GAAG,IAAI,eAAe,EAAE,CAAC;IAC1C,IAAI,IAAwB,CAAC;IAC7B,IAAI,KAAyB,CAAC;IAC9B,IAAI,WAA+B,CAAC;IACpC,IAAI,WAA8B,CAAC;IAEnC,IAAI,CAAC;QACJ,MAAM,UAAU,GAAG,IAAI,eAAe,CAAC;YACtC,IAAI,EAAE,MAAM;YACZ,SAAS,EAAE,SAAS;YACpB,aAAa,EAAE,MAAM;YACrB,YAAY,EAAE,YAAY;YAC1B,KAAK,EAAE,MAAM;YACb,cAAc,EAAE,SAAS;YACzB,qBAAqB,EAAE,MAAM;YAC7B,KAAK,EAAE,QAAQ;SACf,CAAC,CAAC;QACH,WAAW,CAAC,MAAM,CAAC;YAClB,IAAI,EAAE,UAAU;YAChB,GAAG,EAAE,GAAG,aAAa,IAAI,UAAU,CAAC,QAAQ,EAAE,EAAE;YAChD,YAAY,EACX,0GAA0G;SAC3G,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,WAAW;aAC/B,MAAM,CAAC;YACP,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,sFAAsF;YAC/F,WAAW,EAAE,YAAY;YACzB,MAAM,EAAE,WAAW,CAAC,MAAM;SAC1B,CAAC;aACD,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;YAChB,WAAW,GAAG,KAAK,CAAC;YACpB,MAAM,CAAC,UAAU,EAAE,CAAC;QAAA,CACpB,CAAC;aACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;YACjB,WAAW,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACxE,MAAM,CAAC,UAAU,EAAE,CAAC;QAAA,CACpB,CAAC,CAAC;QAEJ,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;QAC1C,IAAI,WAAW;YAAE,MAAM,WAAW,CAAC;QACnC,IAAI,MAAM,EAAE,IAAI,EAAE,CAAC;YAClB,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACnB,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QACtB,CAAC;aAAM,IAAI,WAAW,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAC;YACpD,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,KAAK,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;YACvF,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;YACnB,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,QAAQ,CAAC;QAClC,CAAC;QAED,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,MAAM,aAAa,CAAC;YACpB,IAAI,WAAW;gBAAE,MAAM,WAAW,CAAC;YACnC,IAAI,WAAW,EAAE,CAAC;gBACjB,MAAM,MAAM,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAC;gBACpD,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,KAAK,QAAQ;oBAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;gBACvF,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;gBACnB,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,QAAQ,CAAC;YAClC,CAAC;QACF,CAAC;QAED,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QACzD,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACnD,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,6CAA6C,EAAE,CAAC,CAAC;QACjG,OAAO,yBAAyB,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IACvE,CAAC;YAAS,CAAC;QACV,WAAW,CAAC,KAAK,EAAE,CAAC;QACpB,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;AAAA,CACD;AAED;;GAEG;AACH,KAAK,UAAU,qBAAqB,CAAC,YAAoB,EAA4B;IACpF,IAAI,YAAoB,CAAC;IACzB,IAAI,CAAC;QACJ,YAAY,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE;YACxC,UAAU,EAAE,eAAe;YAC3B,SAAS,EAAE,SAAS;YACpB,aAAa,EAAE,YAAY;SAC3B,CAAC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,+CAA+C,SAAS,aAAa,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnH,CAAC;IAED,IAAI,IAAyF,CAAC;IAC9F,IAAI,CAAC;QACJ,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAK7B,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACd,sDAAsD,SAAS,UAAU,YAAY,aAAa,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAC7H,CAAC;IACH,CAAC;IAED,OAAO;QACN,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,IAAI,CAAC,aAAa;QAC3B,MAAM,EAAE,IAAI,CAAC,YAAY;QACzB,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI;KAC5D,CAAC;AAAA,CACF;AAED,MAAM,CAAC,MAAM,cAAc,GAAc;IACxC,IAAI,EAAE,4BAA4B;IAClC,KAAK,EAAE,cAAc;IACrB,OAAO,EAAE,CAAC,UAAU,EAAE,EAAE,CAAC,qBAAqB,CAAC,UAAU,CAAC,OAAO,CAAC;IAElE,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE;QACxB,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;IAAA,CACrC;CACD,CAAC","sourcesContent":["/**\n * Anthropic OAuth flow (Claude Pro/Max)\n *\n * NOTE: This module uses Node.js http.createServer for the OAuth callback server.\n * It is only intended for CLI use, not browser environments.\n */\n\nimport type { Server } from \"node:http\";\nimport { getProviderEnvValue } from \"../../utils/provider-env.ts\";\nimport type { AuthInteraction, OAuthAuth, OAuthCredential } from \"../types.ts\";\nimport { oauthErrorHtml, oauthSuccessHtml } from \"./oauth-page.ts\";\nimport { generatePKCE } from \"./pkce.ts\";\n\ntype CallbackServerInfo = {\n\tserver: Server;\n\tredirectUri: string;\n\tcancelWait: () => void;\n\twaitForCode: () => Promise<{ code: string; state: string } | null>;\n};\n\ntype NodeApis = {\n\tcreateServer: typeof import(\"node:http\").createServer;\n};\n\nlet nodeApis: NodeApis | null = null;\nlet nodeApisPromise: Promise<NodeApis> | null = null;\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode(\"OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl\");\nconst AUTHORIZE_URL = \"https://claude.ai/oauth/authorize\";\nconst TOKEN_URL = \"https://platform.claude.com/v1/oauth/token\";\nconst CALLBACK_HOST = getProviderEnvValue(\"PI_OAUTH_CALLBACK_HOST\") || \"127.0.0.1\";\nconst CALLBACK_PORT = 53692;\nconst CALLBACK_PATH = \"/callback\";\nconst REDIRECT_URI = `http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`;\nconst SCOPES =\n\t\"org:create_api_key user:profile user:inference user:sessions:claude_code user:mcp_servers user:file_upload\";\nasync function getNodeApis(): Promise<NodeApis> {\n\tif (nodeApis) return nodeApis;\n\tif (!nodeApisPromise) {\n\t\tif (typeof process === \"undefined\" || (!process.versions?.node && !process.versions?.bun)) {\n\t\t\tthrow new Error(\"Anthropic OAuth is only available in Node.js environments\");\n\t\t}\n\t\tnodeApisPromise = import(\"node:http\").then((httpModule) => ({\n\t\t\tcreateServer: httpModule.createServer,\n\t\t}));\n\t}\n\tnodeApis = await nodeApisPromise;\n\treturn nodeApis;\n}\n\nfunction parseAuthorizationInput(input: string): { code?: string; state?: string } {\n\tconst value = input.trim();\n\tif (!value) return {};\n\n\ttry {\n\t\tconst url = new URL(value);\n\t\treturn {\n\t\t\tcode: url.searchParams.get(\"code\") ?? undefined,\n\t\t\tstate: url.searchParams.get(\"state\") ?? undefined,\n\t\t};\n\t} catch {\n\t\t// not a URL\n\t}\n\n\tif (value.includes(\"#\")) {\n\t\tconst [code, state] = value.split(\"#\", 2);\n\t\treturn { code, state };\n\t}\n\n\tif (value.includes(\"code=\")) {\n\t\tconst params = new URLSearchParams(value);\n\t\treturn {\n\t\t\tcode: params.get(\"code\") ?? undefined,\n\t\t\tstate: params.get(\"state\") ?? undefined,\n\t\t};\n\t}\n\n\treturn { code: value };\n}\n\nfunction formatErrorDetails(error: unknown): string {\n\tif (error instanceof Error) {\n\t\tconst details: string[] = [`${error.name}: ${error.message}`];\n\t\tconst errorWithCode = error as Error & { code?: string; errno?: number | string; cause?: unknown };\n\t\tif (errorWithCode.code) details.push(`code=${errorWithCode.code}`);\n\t\tif (typeof errorWithCode.errno !== \"undefined\") details.push(`errno=${String(errorWithCode.errno)}`);\n\t\tif (typeof error.cause !== \"undefined\") {\n\t\t\tdetails.push(`cause=${formatErrorDetails(error.cause)}`);\n\t\t}\n\t\tif (error.stack) {\n\t\t\tdetails.push(`stack=${error.stack}`);\n\t\t}\n\t\treturn details.join(\"; \");\n\t}\n\treturn String(error);\n}\n\nasync function startCallbackServer(expectedState: string): Promise<CallbackServerInfo> {\n\tconst { createServer } = await getNodeApis();\n\n\treturn new Promise((resolve, reject) => {\n\t\tlet settleWait: ((value: { code: string; state: string } | null) => void) | undefined;\n\t\tconst waitForCodePromise = new Promise<{ code: string; state: string } | null>((resolveWait) => {\n\t\t\tlet settled = false;\n\t\t\tsettleWait = (value) => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tresolveWait(value);\n\t\t\t};\n\t\t});\n\n\t\tconst server = createServer((req, res) => {\n\t\t\ttry {\n\t\t\t\tconst url = new URL(req.url || \"\", \"http://localhost\");\n\t\t\t\tif (url.pathname !== CALLBACK_PATH) {\n\t\t\t\t\tres.writeHead(404, { \"Content-Type\": \"text/html; charset=utf-8\" });\n\t\t\t\t\tres.end(oauthErrorHtml(\"Callback route not found.\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst code = url.searchParams.get(\"code\");\n\t\t\t\tconst state = url.searchParams.get(\"state\");\n\t\t\t\tconst error = url.searchParams.get(\"error\");\n\n\t\t\t\tif (error) {\n\t\t\t\t\tres.writeHead(400, { \"Content-Type\": \"text/html; charset=utf-8\" });\n\t\t\t\t\tres.end(oauthErrorHtml(\"Anthropic authentication did not complete.\", `Error: ${error}`));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (!code || !state) {\n\t\t\t\t\tres.writeHead(400, { \"Content-Type\": \"text/html; charset=utf-8\" });\n\t\t\t\t\tres.end(oauthErrorHtml(\"Missing code or state parameter.\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (state !== expectedState) {\n\t\t\t\t\tres.writeHead(400, { \"Content-Type\": \"text/html; charset=utf-8\" });\n\t\t\t\t\tres.end(oauthErrorHtml(\"State mismatch.\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tres.writeHead(200, { \"Content-Type\": \"text/html; charset=utf-8\" });\n\t\t\t\tres.end(oauthSuccessHtml(\"Anthropic authentication completed. You can close this window.\"));\n\t\t\t\tsettleWait?.({ code, state });\n\t\t\t} catch {\n\t\t\t\tres.writeHead(500, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n\t\t\t\tres.end(\"Internal error\");\n\t\t\t}\n\t\t});\n\n\t\tserver.on(\"error\", (err) => {\n\t\t\treject(err);\n\t\t});\n\n\t\tserver.listen(CALLBACK_PORT, CALLBACK_HOST, () => {\n\t\t\tresolve({\n\t\t\t\tserver,\n\t\t\t\tredirectUri: REDIRECT_URI,\n\t\t\t\tcancelWait: () => {\n\t\t\t\t\tsettleWait?.(null);\n\t\t\t\t},\n\t\t\t\twaitForCode: () => waitForCodePromise,\n\t\t\t});\n\t\t});\n\t});\n}\n\nasync function postJson(url: string, body: Record<string, string | number>): Promise<string> {\n\tconst response = await fetch(url, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAccept: \"application/json\",\n\t\t},\n\t\tbody: JSON.stringify(body),\n\t\tsignal: AbortSignal.timeout(30_000),\n\t});\n\n\tconst responseBody = await response.text();\n\n\tif (!response.ok) {\n\t\tthrow new Error(`HTTP request failed. status=${response.status}; url=${url}; body=${responseBody}`);\n\t}\n\n\treturn responseBody;\n}\n\nasync function exchangeAuthorizationCode(\n\tcode: string,\n\tstate: string,\n\tverifier: string,\n\tredirectUri: string,\n): Promise<OAuthCredential> {\n\tlet responseBody: string;\n\ttry {\n\t\tresponseBody = await postJson(TOKEN_URL, {\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tcode,\n\t\t\tstate,\n\t\t\tredirect_uri: redirectUri,\n\t\t\tcode_verifier: verifier,\n\t\t});\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Token exchange request failed. url=${TOKEN_URL}; redirect_uri=${redirectUri}; response_type=authorization_code; details=${formatErrorDetails(error)}`,\n\t\t);\n\t}\n\n\tlet tokenData: { access_token: string; refresh_token: string; expires_in: number };\n\ttry {\n\t\ttokenData = JSON.parse(responseBody) as { access_token: string; refresh_token: string; expires_in: number };\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Token exchange returned invalid JSON. url=${TOKEN_URL}; body=${responseBody}; details=${formatErrorDetails(error)}`,\n\t\t);\n\t}\n\n\treturn {\n\t\ttype: \"oauth\",\n\t\trefresh: tokenData.refresh_token,\n\t\taccess: tokenData.access_token,\n\t\texpires: Date.now() + tokenData.expires_in * 1000 - 5 * 60 * 1000,\n\t};\n}\n\nasync function loginAnthropic(interaction: AuthInteraction): Promise<OAuthCredential> {\n\tconst { verifier, challenge } = await generatePKCE();\n\tconst server = await startCallbackServer(verifier);\n\tconst manualAbort = new AbortController();\n\tlet code: string | undefined;\n\tlet state: string | undefined;\n\tlet manualInput: string | undefined;\n\tlet manualError: Error | undefined;\n\n\ttry {\n\t\tconst authParams = new URLSearchParams({\n\t\t\tcode: \"true\",\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tresponse_type: \"code\",\n\t\t\tredirect_uri: REDIRECT_URI,\n\t\t\tscope: SCOPES,\n\t\t\tcode_challenge: challenge,\n\t\t\tcode_challenge_method: \"S256\",\n\t\t\tstate: verifier,\n\t\t});\n\t\tinteraction.notify({\n\t\t\ttype: \"auth_url\",\n\t\t\turl: `${AUTHORIZE_URL}?${authParams.toString()}`,\n\t\t\tinstructions:\n\t\t\t\t\"Complete login in your browser. If the browser is on another machine, paste the final redirect URL here.\",\n\t\t});\n\n\t\tconst manualPromise = interaction\n\t\t\t.prompt({\n\t\t\t\ttype: \"manual_code\",\n\t\t\t\tmessage: \"Complete login in your browser, or paste the authorization code / redirect URL here:\",\n\t\t\t\tplaceholder: REDIRECT_URI,\n\t\t\t\tsignal: manualAbort.signal,\n\t\t\t})\n\t\t\t.then((input) => {\n\t\t\t\tmanualInput = input;\n\t\t\t\tserver.cancelWait();\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tmanualError = error instanceof Error ? error : new Error(String(error));\n\t\t\t\tserver.cancelWait();\n\t\t\t});\n\n\t\tconst result = await server.waitForCode();\n\t\tif (manualError) throw manualError;\n\t\tif (result?.code) {\n\t\t\tcode = result.code;\n\t\t\tstate = result.state;\n\t\t} else if (manualInput) {\n\t\t\tconst parsed = parseAuthorizationInput(manualInput);\n\t\t\tif (parsed.state && parsed.state !== verifier) throw new Error(\"OAuth state mismatch\");\n\t\t\tcode = parsed.code;\n\t\t\tstate = parsed.state ?? verifier;\n\t\t}\n\n\t\tif (!code) {\n\t\t\tawait manualPromise;\n\t\t\tif (manualError) throw manualError;\n\t\t\tif (manualInput) {\n\t\t\t\tconst parsed = parseAuthorizationInput(manualInput);\n\t\t\t\tif (parsed.state && parsed.state !== verifier) throw new Error(\"OAuth state mismatch\");\n\t\t\t\tcode = parsed.code;\n\t\t\t\tstate = parsed.state ?? verifier;\n\t\t\t}\n\t\t}\n\n\t\tif (!code) throw new Error(\"Missing authorization code\");\n\t\tif (!state) throw new Error(\"Missing OAuth state\");\n\t\tinteraction.notify({ type: \"progress\", message: \"Exchanging authorization code for tokens...\" });\n\t\treturn exchangeAuthorizationCode(code, state, verifier, REDIRECT_URI);\n\t} finally {\n\t\tmanualAbort.abort();\n\t\tserver.server.close();\n\t}\n}\n\n/**\n * Refresh Anthropic OAuth token\n */\nasync function refreshAnthropicToken(refreshToken: string): Promise<OAuthCredential> {\n\tlet responseBody: string;\n\ttry {\n\t\tresponseBody = await postJson(TOKEN_URL, {\n\t\t\tgrant_type: \"refresh_token\",\n\t\t\tclient_id: CLIENT_ID,\n\t\t\trefresh_token: refreshToken,\n\t\t});\n\t} catch (error) {\n\t\tthrow new Error(`Anthropic token refresh request failed. url=${TOKEN_URL}; details=${formatErrorDetails(error)}`);\n\t}\n\n\tlet data: { access_token: string; refresh_token: string; expires_in: number; scope?: string };\n\ttry {\n\t\tdata = JSON.parse(responseBody) as {\n\t\t\taccess_token: string;\n\t\t\trefresh_token: string;\n\t\t\texpires_in: number;\n\t\t\tscope?: string;\n\t\t};\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Anthropic token refresh returned invalid JSON. url=${TOKEN_URL}; body=${responseBody}; details=${formatErrorDetails(error)}`,\n\t\t);\n\t}\n\n\treturn {\n\t\ttype: \"oauth\",\n\t\trefresh: data.refresh_token,\n\t\taccess: data.access_token,\n\t\texpires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000,\n\t};\n}\n\nexport const anthropicOAuth: OAuthAuth = {\n\tname: \"Anthropic (Claude Pro/Max)\",\n\tlogin: loginAnthropic,\n\trefresh: (credential) => refreshAnthropicToken(credential.refresh),\n\n\tasync toAuth(credential) {\n\t\treturn { apiKey: credential.access };\n\t},\n};\n"]}
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/auth/oauth/anthropic.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Anthropic OAuth flow (Claude Pro/Max)\n *\n * NOTE: This module uses Node.js http.createServer for the OAuth callback server.\n * It is only intended for CLI use, not browser environments.\n */\n\nimport { getProviderEnvValue } from \"../../utils/provider-env.ts\";\nimport type { OAuthAuth, OAuthCredential, ProviderAuthInteraction } from \"../types.ts\";\nimport { startOAuthCallbackServer, waitForCallbackOrManualInput } from \"./callback-server.ts\";\nimport { generatePKCE } from \"./pkce.ts\";\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode(\"OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl\");\nconst AUTHORIZE_URL = \"https://claude.ai/oauth/authorize\";\nconst TOKEN_URL = \"https://platform.claude.com/v1/oauth/token\";\nconst CALLBACK_HOST = getProviderEnvValue(\"PI_OAUTH_CALLBACK_HOST\") || \"127.0.0.1\";\nconst CALLBACK_PORT = 53692;\nconst CALLBACK_PATH = \"/callback\";\nconst REDIRECT_URI = `http://localhost:${CALLBACK_PORT}${CALLBACK_PATH}`;\nconst COPY_CODE_REDIRECT_URI = \"https://platform.claude.com/oauth/code/callback\";\nconst ANTHROPIC_BROWSER_LOGIN_METHOD = \"browser\";\nconst ANTHROPIC_COPY_CODE_LOGIN_METHOD = \"copy_code\";\nconst SCOPES =\n\t\"org:create_api_key user:profile user:inference user:sessions:claude_code user:mcp_servers user:file_upload\";\n\nfunction parseAuthorizationInput(input: string): { code?: string; state?: string } {\n\tconst value = input.trim();\n\tif (!value) return {};\n\n\ttry {\n\t\tconst url = new URL(value);\n\t\treturn {\n\t\t\tcode: url.searchParams.get(\"code\") ?? undefined,\n\t\t\tstate: url.searchParams.get(\"state\") ?? undefined,\n\t\t};\n\t} catch {\n\t\t// not a URL\n\t}\n\n\tif (value.includes(\"#\")) {\n\t\tconst [code, state] = value.split(\"#\", 2);\n\t\treturn { code, state };\n\t}\n\n\tif (value.includes(\"code=\")) {\n\t\tconst params = new URLSearchParams(value);\n\t\treturn {\n\t\t\tcode: params.get(\"code\") ?? undefined,\n\t\t\tstate: params.get(\"state\") ?? undefined,\n\t\t};\n\t}\n\n\treturn { code: value };\n}\n\nfunction formatErrorDetails(error: unknown): string {\n\tif (error instanceof Error) {\n\t\tconst details: string[] = [`${error.name}: ${error.message}`];\n\t\tconst errorWithCode = error as Error & { code?: string; errno?: number | string; cause?: unknown };\n\t\tif (errorWithCode.code) details.push(`code=${errorWithCode.code}`);\n\t\tif (typeof errorWithCode.errno !== \"undefined\") details.push(`errno=${String(errorWithCode.errno)}`);\n\t\tif (typeof error.cause !== \"undefined\") {\n\t\t\tdetails.push(`cause=${formatErrorDetails(error.cause)}`);\n\t\t}\n\t\tif (error.stack) {\n\t\t\tdetails.push(`stack=${error.stack}`);\n\t\t}\n\t\treturn details.join(\"; \");\n\t}\n\treturn String(error);\n}\n\nasync function postJson(url: string, body: Record<string, string | number>, signal: AbortSignal): Promise<string> {\n\tconst response = await fetch(url, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\tAccept: \"application/json\",\n\t\t},\n\t\tbody: JSON.stringify(body),\n\t\tsignal: AbortSignal.any([signal, AbortSignal.timeout(30_000)]),\n\t});\n\n\tconst responseBody = await response.text();\n\n\tif (!response.ok) {\n\t\tthrow new Error(`HTTP request failed. status=${response.status}; url=${url}; body=${responseBody}`);\n\t}\n\n\treturn responseBody;\n}\n\nasync function exchangeAuthorizationCode(\n\tcode: string,\n\tstate: string,\n\tverifier: string,\n\tredirectUri: string,\n\tsignal: AbortSignal,\n): Promise<OAuthCredential> {\n\tlet responseBody: string;\n\ttry {\n\t\tresponseBody = await postJson(\n\t\t\tTOKEN_URL,\n\t\t\t{\n\t\t\t\tgrant_type: \"authorization_code\",\n\t\t\t\tclient_id: CLIENT_ID,\n\t\t\t\tcode,\n\t\t\t\tstate,\n\t\t\t\tredirect_uri: redirectUri,\n\t\t\t\tcode_verifier: verifier,\n\t\t\t},\n\t\t\tsignal,\n\t\t);\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Token exchange request failed. url=${TOKEN_URL}; redirect_uri=${redirectUri}; response_type=authorization_code; details=${formatErrorDetails(error)}`,\n\t\t);\n\t}\n\n\tlet tokenData: { access_token: string; refresh_token: string; expires_in: number };\n\ttry {\n\t\ttokenData = JSON.parse(responseBody) as { access_token: string; refresh_token: string; expires_in: number };\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Token exchange returned invalid JSON. url=${TOKEN_URL}; body=${responseBody}; details=${formatErrorDetails(error)}`,\n\t\t);\n\t}\n\n\treturn {\n\t\ttype: \"oauth\",\n\t\trefresh: tokenData.refresh_token,\n\t\taccess: tokenData.access_token,\n\t\texpires: Date.now() + tokenData.expires_in * 1000 - 5 * 60 * 1000,\n\t};\n}\n\nasync function loginAnthropic(interaction: ProviderAuthInteraction): Promise<OAuthCredential> {\n\tconst { verifier, challenge } = await generatePKCE();\n\tconst callback = await startOAuthCallbackServer({\n\t\tproviderName: \"Anthropic\",\n\t\thost: CALLBACK_HOST,\n\t\tport: CALLBACK_PORT,\n\t\tpath: CALLBACK_PATH,\n\t\tstate: verifier,\n\t\tcomplete: async (code) => code,\n\t\tsignal: interaction.signal,\n\t}).catch(() => undefined);\n\n\ttry {\n\t\tconst authParams = new URLSearchParams({\n\t\t\tcode: \"true\",\n\t\t\tclient_id: CLIENT_ID,\n\t\t\tresponse_type: \"code\",\n\t\t\tredirect_uri: REDIRECT_URI,\n\t\t\tscope: SCOPES,\n\t\t\tcode_challenge: challenge,\n\t\t\tcode_challenge_method: \"S256\",\n\t\t\tstate: verifier,\n\t\t});\n\t\tinteraction.notify({\n\t\t\ttype: \"auth_url\",\n\t\t\turl: `${AUTHORIZE_URL}?${authParams.toString()}`,\n\t\t\tinstructions:\n\t\t\t\t\"Complete login in your browser. If the browser is on another machine, paste the final redirect URL here.\",\n\t\t});\n\n\t\tconst result = await waitForCallbackOrManualInput(interaction, callback, {\n\t\t\tmessage: \"Complete login in your browser, or paste the authorization code / redirect URL here:\",\n\t\t\tplaceholder: REDIRECT_URI,\n\t\t});\n\t\tlet code: string | undefined;\n\t\tlet state = verifier;\n\t\tif (result.type === \"callback\") {\n\t\t\tcode = result.value;\n\t\t} else {\n\t\t\tconst parsed = parseAuthorizationInput(result.input);\n\t\t\tif (parsed.state && parsed.state !== verifier) throw new Error(\"OAuth state mismatch\");\n\t\t\tcode = parsed.code;\n\t\t\tstate = parsed.state ?? verifier;\n\t\t}\n\n\t\tif (!code) throw new Error(\"Missing authorization code\");\n\t\tinteraction.notify({ type: \"progress\", message: \"Exchanging authorization code for tokens...\" });\n\t\treturn await exchangeAuthorizationCode(code, state, verifier, REDIRECT_URI, interaction.signal);\n\t} finally {\n\t\tcallback?.close();\n\t}\n}\n\nasync function loginAnthropicCopyCode(interaction: ProviderAuthInteraction): Promise<OAuthCredential> {\n\tconst { verifier, challenge } = await generatePKCE();\n\tconst authParams = new URLSearchParams({\n\t\tcode: \"true\",\n\t\tclient_id: CLIENT_ID,\n\t\tresponse_type: \"code\",\n\t\tredirect_uri: COPY_CODE_REDIRECT_URI,\n\t\tscope: SCOPES,\n\t\tcode_challenge: challenge,\n\t\tcode_challenge_method: \"S256\",\n\t\tstate: verifier,\n\t});\n\tinteraction.notify({\n\t\ttype: \"auth_url\",\n\t\turl: `${AUTHORIZE_URL}?${authParams.toString()}`,\n\t\tinstructions: \"Complete login in your browser, then copy the code Anthropic shows and paste it here.\",\n\t});\n\n\tconst input = await interaction.prompt({\n\t\ttype: \"manual_code\",\n\t\tmessage: \"Paste the code Anthropic shows after you sign in:\",\n\t\tplaceholder: \"code#state\",\n\t\tsignal: interaction.signal,\n\t});\n\tconst parsed = parseAuthorizationInput(input);\n\tif (parsed.state && parsed.state !== verifier) throw new Error(\"OAuth state mismatch\");\n\tif (!parsed.code) throw new Error(\"Missing authorization code\");\n\tinteraction.notify({ type: \"progress\", message: \"Exchanging authorization code for tokens...\" });\n\treturn await exchangeAuthorizationCode(\n\t\tparsed.code,\n\t\tparsed.state ?? verifier,\n\t\tverifier,\n\t\tCOPY_CODE_REDIRECT_URI,\n\t\tinteraction.signal,\n\t);\n}\n\n/**\n * Refresh Anthropic OAuth token\n */\nasync function refreshAnthropicToken(refreshToken: string, signal: AbortSignal): Promise<OAuthCredential> {\n\tlet responseBody: string;\n\ttry {\n\t\tresponseBody = await postJson(\n\t\t\tTOKEN_URL,\n\t\t\t{\n\t\t\t\tgrant_type: \"refresh_token\",\n\t\t\t\tclient_id: CLIENT_ID,\n\t\t\t\trefresh_token: refreshToken,\n\t\t\t},\n\t\t\tsignal,\n\t\t);\n\t} catch (error) {\n\t\tthrow new Error(`Anthropic token refresh request failed. url=${TOKEN_URL}; details=${formatErrorDetails(error)}`);\n\t}\n\n\tlet data: { access_token: string; refresh_token: string; expires_in: number; scope?: string };\n\ttry {\n\t\tdata = JSON.parse(responseBody) as {\n\t\t\taccess_token: string;\n\t\t\trefresh_token: string;\n\t\t\texpires_in: number;\n\t\t\tscope?: string;\n\t\t};\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t`Anthropic token refresh returned invalid JSON. url=${TOKEN_URL}; body=${responseBody}; details=${formatErrorDetails(error)}`,\n\t\t);\n\t}\n\n\treturn {\n\t\ttype: \"oauth\",\n\t\trefresh: data.refresh_token,\n\t\taccess: data.access_token,\n\t\texpires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000,\n\t};\n}\n\nexport const anthropicOAuth: OAuthAuth = {\n\tname: \"Anthropic (Claude Pro/Max)\",\n\tisSubscription: true,\n\n\tasync login(interaction) {\n\t\tconst method = await interaction.prompt({\n\t\t\ttype: \"select\",\n\t\t\tmessage: \"Select Anthropic login method:\",\n\t\t\toptions: [\n\t\t\t\t{ id: ANTHROPIC_BROWSER_LOGIN_METHOD, label: \"Browser login (default)\" },\n\t\t\t\t{ id: ANTHROPIC_COPY_CODE_LOGIN_METHOD, label: \"Copy code login (headless)\" },\n\t\t\t],\n\t\t});\n\n\t\tif (method === ANTHROPIC_COPY_CODE_LOGIN_METHOD) {\n\t\t\treturn loginAnthropicCopyCode(interaction);\n\t\t}\n\t\tif (method !== ANTHROPIC_BROWSER_LOGIN_METHOD) {\n\t\t\tthrow new Error(`Unknown Anthropic login method: ${method}`);\n\t\t}\n\n\t\treturn loginAnthropic(interaction);\n\t},\n\n\trefresh: (credential, signal) => refreshAnthropicToken(credential.refresh, signal),\n\n\tasync toAuth(credential) {\n\t\treturn { apiKey: credential.access };\n\t},\n};\n"]}