@xiaoso/dsh-tool-plus 0.1.0-beta.2 → 0.1.0-beta.4

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 (235) hide show
  1. package/README.en.md +122 -0
  2. package/README.md +3 -2
  3. package/THIRD_PARTY_NOTICES.md +4 -35
  4. package/lib/abort-B7izMMna.mjs +51 -0
  5. package/lib/abort-D1_Z5Ut5.mjs +51 -0
  6. package/lib/abort-dIkZBV7Q.mjs +51 -0
  7. package/lib/amazon-bedrock-B0nxT06F.mjs +917 -0
  8. package/lib/amazon-bedrock-D-shAr1X.mjs +917 -0
  9. package/lib/amazon-bedrock-WQhvjHYu.mjs +917 -0
  10. package/lib/anthropic-BWsZFzU8.mjs +262 -0
  11. package/lib/anthropic-CJCauvYz.mjs +3115 -0
  12. package/lib/anthropic-CMT1Qj1t.mjs +3115 -0
  13. package/lib/anthropic-CZghe_9U.mjs +3115 -0
  14. package/lib/anthropic-sCMH7JID.mjs +262 -0
  15. package/lib/anthropic-tTntD8BD.mjs +262 -0
  16. package/lib/api-key-login-BzqNdM2y.mjs +157 -0
  17. package/lib/api-key-login-CWVwvHT1.mjs +157 -0
  18. package/lib/api-key-login-CpzSezsi.mjs +157 -0
  19. package/lib/aws-credentials-8Mgn5MAy.mjs +867 -0
  20. package/lib/aws-credentials-CXryMobh.mjs +867 -0
  21. package/lib/aws-credentials-ChG79ey-.mjs +867 -0
  22. package/lib/azure-openai-responses-CNkHiLUh.mjs +274 -0
  23. package/lib/azure-openai-responses-Cgmc-rbL.mjs +274 -0
  24. package/lib/azure-openai-responses-DuukbD0F.mjs +274 -0
  25. package/lib/bun-shim.mjs +252 -12
  26. package/lib/bundled-references-CSuBco5p.mjs +55 -0
  27. package/lib/bundled-references-Cavaffah.mjs +55 -0
  28. package/lib/bundled-references-sLN0YdXU.mjs +55 -0
  29. package/lib/callback-server-BEFNf-jf.mjs +398 -0
  30. package/lib/callback-server-CQ5Jo8F-.mjs +398 -0
  31. package/lib/callback-server-DDSrZ6l_.mjs +398 -0
  32. package/lib/client.js +111 -41
  33. package/lib/cursor-B3zg7EHj.mjs +273 -0
  34. package/lib/cursor-B6TUEmgP.mjs +135 -0
  35. package/lib/cursor-BIQfBC6V.mjs +135 -0
  36. package/lib/cursor-D8gvtTL3.mjs +135 -0
  37. package/lib/cursor-DNk6eXDd.mjs +5470 -0
  38. package/lib/cursor-DkSX2h3H.mjs +5441 -0
  39. package/lib/cursor-MjSm74IJ.mjs +273 -0
  40. package/lib/cursor-aJrXeYCb.mjs +273 -0
  41. package/lib/cursor-mJQwUKXK.mjs +5441 -0
  42. package/lib/device-code-DBo3B5nh.mjs +51 -0
  43. package/lib/device-code-DIb0FU-H.mjs +51 -0
  44. package/lib/device-code-OI_tQcmc.mjs +51 -0
  45. package/lib/devin-BHZZyMhO.mjs +95 -0
  46. package/lib/devin-BK7DHeca.mjs +114 -0
  47. package/lib/devin-CfMp3cXS.mjs +95 -0
  48. package/lib/devin-CldyPD8K.mjs +95 -0
  49. package/lib/devin-CzRpTUOA.mjs +114 -0
  50. package/lib/devin-D9zR5B_R.mjs +542 -0
  51. package/lib/devin-DXOeNyU7.mjs +542 -0
  52. package/lib/devin-Q1yem3lp.mjs +114 -0
  53. package/lib/devin-vNZTNUON.mjs +542 -0
  54. package/lib/error-B3bevhrs.mjs +1449 -0
  55. package/lib/error-Dd8DIqs-.mjs +1449 -0
  56. package/lib/error-yCSG0mGC.mjs +1449 -0
  57. package/lib/event-stream-BDPi64mK.mjs +151 -0
  58. package/lib/event-stream-BbFZJy-z.mjs +151 -0
  59. package/lib/event-stream-loUa0s1T.mjs +151 -0
  60. package/lib/fs-promises-shim-Bx0fpxuk.mjs +57 -0
  61. package/lib/github-copilot-4GaMtQmg.mjs +208 -0
  62. package/lib/github-copilot-B1yiyVRh.mjs +104 -0
  63. package/lib/github-copilot-B2HGSIJK.mjs +104 -0
  64. package/lib/github-copilot-BWT3eAOF.mjs +208 -0
  65. package/lib/github-copilot-CYkjeTi3.mjs +208 -0
  66. package/lib/github-copilot-jscUZ8Hf.mjs +104 -0
  67. package/lib/gitlab-duo-CM7Ref1H.mjs +155 -0
  68. package/lib/gitlab-duo-akICyfeD.mjs +155 -0
  69. package/lib/gitlab-duo-gubO4FNw.mjs +155 -0
  70. package/lib/gitlab-duo-workflow-BGAF6JDw.mjs +91 -0
  71. package/lib/gitlab-duo-workflow-CSEgYk3N.mjs +91 -0
  72. package/lib/gitlab-duo-workflow-D78tdn8E.mjs +91 -0
  73. package/lib/google-BS4T25Pn.mjs +30 -0
  74. package/lib/google-TFe-7-of.mjs +30 -0
  75. package/lib/google-antigravity-DGmwC2KV.mjs +198 -0
  76. package/lib/google-antigravity-DNYhgTpA.mjs +198 -0
  77. package/lib/google-antigravity-Dlkdhahq.mjs +198 -0
  78. package/lib/google-auth-B6gjsZvg.mjs +232 -0
  79. package/lib/google-auth-De7_s3eo.mjs +232 -0
  80. package/lib/google-auth-DhqpOYrX.mjs +232 -0
  81. package/lib/google-gemini-cli-BG_LRdIV.mjs +850 -0
  82. package/lib/google-gemini-cli-CWu8HvXW.mjs +211 -0
  83. package/lib/google-gemini-cli-Cb97bzQc.mjs +850 -0
  84. package/lib/google-gemini-cli-Cqds_Q5T.mjs +850 -0
  85. package/lib/google-gemini-cli-Dsztq0N5.mjs +211 -0
  86. package/lib/google-gemini-cli-zJhiOcND.mjs +211 -0
  87. package/lib/google-oauth-shared-CuEHaDDj.mjs +147 -0
  88. package/lib/google-oauth-shared-CwNWYdmR.mjs +147 -0
  89. package/lib/google-oauth-shared-yqlyqPPC.mjs +147 -0
  90. package/lib/google-shared-CgKmmdO3.mjs +760 -0
  91. package/lib/google-shared-Dr-VG-ap.mjs +760 -0
  92. package/lib/google-shared-DzhCb9b0.mjs +760 -0
  93. package/lib/google-vertex-BDN2tLaD.mjs +99 -0
  94. package/lib/google-vertex-DopVOQOG.mjs +99 -0
  95. package/lib/google-vertex-kscbkyRb.mjs +99 -0
  96. package/lib/google-zyDOG9x7.mjs +30 -0
  97. package/lib/identity-Da1GPU9a.mjs +219 -0
  98. package/lib/identity-DnB63pS7.mjs +219 -0
  99. package/lib/identity-xRP7_eSR.mjs +219 -0
  100. package/lib/idle-iterator-Baoyn3Hp.mjs +366 -0
  101. package/lib/idle-iterator-C6XbWcuB.mjs +366 -0
  102. package/lib/idle-iterator-DUjKQEGT.mjs +366 -0
  103. package/lib/index.mjs +4608 -3935
  104. package/lib/kimi--wUOWER5.mjs +236 -0
  105. package/lib/kimi-DMVI-zrZ.mjs +236 -0
  106. package/lib/kimi-Dh0pv3WZ.mjs +236 -0
  107. package/lib/markit-BL3cH47U.mjs +1417 -0
  108. package/lib/markit-BNiNY6SE.mjs +1417 -0
  109. package/lib/markit-M0jhziqU.mjs +1417 -0
  110. package/lib/minimax-code-BK-3eBbz.mjs +53 -0
  111. package/lib/minimax-code-DCbuA6Yk.mjs +53 -0
  112. package/lib/minimax-code-Uq8Qu9LW.mjs +53 -0
  113. package/lib/models-CfT4coYT.mjs +104660 -0
  114. package/lib/models-D_XnT6ay.mjs +104660 -0
  115. package/lib/models-SGASygJ3.mjs +104660 -0
  116. package/lib/ollama-BQMGPxtV.mjs +589 -0
  117. package/lib/ollama-DPzBmq89.mjs +589 -0
  118. package/lib/ollama-DoBz5SFm.mjs +589 -0
  119. package/lib/openai-codex-Bi-4S4PX.mjs +255 -0
  120. package/lib/openai-codex-CQL_kvYL.mjs +255 -0
  121. package/lib/openai-codex-Ch8CkT3p.mjs +255 -0
  122. package/lib/openai-codex-responses-CvxL_FMF.mjs +3144 -0
  123. package/lib/openai-codex-responses-Cz-2qpC7.mjs +3144 -0
  124. package/lib/openai-codex-responses-pejZgdZo.mjs +3144 -0
  125. package/lib/openai-completions-CF8IyNtP.mjs +1360 -0
  126. package/lib/openai-completions-DIf361kF.mjs +1360 -0
  127. package/lib/openai-completions-i8doczAk.mjs +1360 -0
  128. package/lib/openai-reasoning-fallback-DGVVLgd1.mjs +286 -0
  129. package/lib/openai-reasoning-fallback-Nj6yB2rY.mjs +286 -0
  130. package/lib/openai-reasoning-fallback-OdJREP1o.mjs +286 -0
  131. package/lib/openai-responses-BqXJInHX.mjs +867 -0
  132. package/lib/openai-responses-DTkBiiy-.mjs +867 -0
  133. package/lib/openai-responses-Db_a-U4-.mjs +867 -0
  134. package/lib/opencode-DaJjcUbf.mjs +38 -0
  135. package/lib/opencode-DhMolSoB.mjs +38 -0
  136. package/lib/opencode-Rq_Q2vAO.mjs +38 -0
  137. package/lib/perplexity-9b-RQ0mV.mjs +194 -0
  138. package/lib/perplexity-C4iLVMUj.mjs +194 -0
  139. package/lib/perplexity-Uu7Jzg5b.mjs +194 -0
  140. package/lib/proxy-DDqrmjjC.mjs +190 -0
  141. package/lib/proxy-ZtUcl6r5.mjs +190 -0
  142. package/lib/proxy-pM_NIv-H.mjs +190 -0
  143. package/lib/request-debug-HJMoJncL.mjs +183 -0
  144. package/lib/sanitize-text-CfcXzw5X.mjs +33 -0
  145. package/lib/scrapers-BkFfcPHj.mjs +9198 -0
  146. package/lib/scrapers-CL-WgdU1.mjs +9198 -0
  147. package/lib/scrapers-CVptboMs.mjs +9198 -0
  148. package/lib/scrapers-CipyKyCH.mjs +9198 -0
  149. package/lib/scrapers-DGfrYhtw.mjs +9198 -0
  150. package/lib/scrapers-DSUPYoUF.mjs +9198 -0
  151. package/lib/scrapers-DZ2GXmp7.mjs +9198 -0
  152. package/lib/scrapers-nhQAvc8d.mjs +9198 -0
  153. package/lib/shell-snapshot-fn-env.sh +67 -43
  154. package/lib/src-BgpusnsB.mjs +5076 -0
  155. package/lib/src-DTid0g4K.mjs +5001 -0
  156. package/lib/src-lDmkSRbm.mjs +5006 -0
  157. package/lib/stream-BlldLkVq.mjs +10236 -0
  158. package/lib/stream-CRtexYLe.mjs +10236 -0
  159. package/lib/stream-C_RAoxJC.mjs +10236 -0
  160. package/lib/stream-markup-healing-2toHXWXM.mjs +491 -0
  161. package/lib/stream-markup-healing-DMsxBx1L.mjs +491 -0
  162. package/lib/stream-markup-healing-KMkiAA00.mjs +491 -0
  163. package/lib/turndown-DN7ByzEI.mjs +667 -0
  164. package/lib/types/client/locales.d.ts +1 -1
  165. package/lib/types/config/fields.d.ts +1 -1
  166. package/lib/types/config/settings.d.ts +25 -3
  167. package/lib/types/config/truncate.d.ts +9 -5
  168. package/lib/types/tools/bash/background.d.ts +1 -1
  169. package/lib/types/tools/bash/bash-executor.d.ts +4 -0
  170. package/lib/types/tools/bash/bash-interceptor.d.ts +10 -8
  171. package/lib/types/tools/bash/cd-workdir.d.ts +35 -0
  172. package/lib/types/tools/bash/non-interactive-env.d.ts +2 -0
  173. package/lib/types/tools/bash/render.d.ts +4 -3
  174. package/lib/types/tools/bash/sanitize-text.d.ts +5 -0
  175. package/lib/types/tools/bash/shell-snapshot.d.ts +4 -1
  176. package/lib/types/tools/bash/shell-tokenize.d.ts +60 -0
  177. package/lib/types/tools/bash/streaming-output.d.ts +12 -212
  178. package/lib/types/tools/bash/which.d.ts +20 -0
  179. package/lib/types/tools/bash/windows-shell.d.ts +31 -0
  180. package/lib/types/tools/edit/adapter/index.d.ts +25 -3
  181. package/lib/types/tools/edit/adapter/tools/auto-generated-guard.d.ts +7 -17
  182. package/lib/types/tools/glob/adapter/index.d.ts +27 -1
  183. package/lib/types/tools/grep/adapter/index.d.ts +29 -1
  184. package/lib/types/tools/omp/edit/dispatch.d.ts +43 -0
  185. package/lib/types/tools/omp/edit/hashline/noop-loop-guard.d.ts +3 -1
  186. package/lib/types/tools/omp/sdk.d.ts +6 -0
  187. package/lib/types/tools/omp/tools/auto-generated-guard.d.ts +20 -0
  188. package/lib/types/tools/omp/tools/fetch.d.ts +2 -0
  189. package/lib/types/tools/omp/tools/read.d.ts +2 -8
  190. package/lib/types/tools/omp/tools/write.d.ts +4 -4
  191. package/lib/types/tools/omp/utils/image-loading.d.ts +10 -36
  192. package/lib/types/tools/read/adapter/index.d.ts +4 -1
  193. package/lib/types/tools/read-image/index.d.ts +4 -0
  194. package/lib/types/tools/shared/auto-generated-guard.dsh.d.ts +16 -4
  195. package/lib/types/tools/shared/bun-shim.d.ts +39 -3
  196. package/lib/types/tools/shared/fs-promises-shim.d.ts +3 -1
  197. package/lib/types/tools/shared/image-bridge.d.ts +98 -0
  198. package/lib/types/tools/shared/omp-prompt.d.ts +17 -9
  199. package/lib/types/tools/shared/session-state.d.ts +9 -3
  200. package/lib/utils-2Wq2eATG.mjs +8119 -0
  201. package/lib/utils-BnX8O3vi.mjs +12303 -0
  202. package/lib/utils-Bw139LTz.mjs +8119 -0
  203. package/lib/utils-CE8N8P4Q.mjs +12315 -0
  204. package/lib/utils-CZw4tVZQ.mjs +12315 -0
  205. package/lib/utils-C_MrQ_0z.mjs +12301 -0
  206. package/lib/utils-CiGN7OHR.mjs +12315 -0
  207. package/lib/utils-Cp76gCyk.mjs +8119 -0
  208. package/lib/utils-D0GRDgAr.mjs +12315 -0
  209. package/lib/utils-D0Z1fyoO.mjs +12299 -0
  210. package/lib/utils-D2YknRk4.mjs +51 -0
  211. package/lib/utils-DppGHXQB.mjs +51 -0
  212. package/lib/utils-DzXZDfYc.mjs +51 -0
  213. package/lib/utils-W8WdSBpX.mjs +12315 -0
  214. package/lib/vision-guard-01qSwFpf.mjs +92 -0
  215. package/lib/vision-guard-BDD4OrKo.mjs +92 -0
  216. package/lib/vision-guard-DzZGaOga.mjs +92 -0
  217. package/lib/wafer-CgtPHerf.mjs +17 -0
  218. package/lib/wafer-DRU0EjZX.mjs +17 -0
  219. package/lib/wafer-cBtrn6q9.mjs +17 -0
  220. package/lib/xai-oauth-Buk8XVvM.mjs +446 -0
  221. package/lib/xai-oauth-CMal8l1O.mjs +446 -0
  222. package/lib/xai-oauth-DPHDXKD7.mjs +446 -0
  223. package/lib/xiaomi-CZgwvX2G.mjs +157 -0
  224. package/lib/xiaomi-D2qT5cAC.mjs +157 -0
  225. package/lib/xiaomi-Dd87KSg5.mjs +157 -0
  226. package/lib/zai-7DWMkEqM.mjs +203 -0
  227. package/lib/zai-C59YnomG.mjs +203 -0
  228. package/lib/zai-CFeOt-53.mjs +203 -0
  229. package/lib/zip-Cg9ANN_U.mjs +1316 -0
  230. package/lib/zip-D36ZKsP8.mjs +1316 -0
  231. package/lib/zip-D6QXpvaJ.mjs +1316 -0
  232. package/package.json +14 -10
  233. package/presets/package.json +1 -1
  234. package/presets/tool-plus-ptc/preset.yml +1 -1
  235. package/presets/tool-plus-standard/preset.yml +1 -1
@@ -0,0 +1,446 @@
1
+ import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
+ __installBunShim();
3
+ import { r as __exportAll } from "./fs-promises-shim-B-9cMxz5.mjs";
4
+ import { c as OAuthError, h as LoginCancelledError } from "./error-yCSG0mGC.mjs";
5
+ import { t as pollOAuthDeviceCodeFlow } from "./device-code-DIb0FU-H.mjs";
6
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/registry/oauth/xai-oauth.ts
7
+ /**
8
+ * xAI Grok OAuth device authorization flow.
9
+ *
10
+ * Requests an RFC 8628 device code, opens xAI's verification page, and polls
11
+ * the discovered token endpoint until the user approves the login.
12
+ */
13
+ var xai_oauth_exports = /* @__PURE__ */ __exportAll({
14
+ buildXAICliBillingUrl: () => buildXAICliBillingUrl,
15
+ extractXAIAccessTokenSubject: () => extractXAIAccessTokenSubject,
16
+ fetchXAIOAuthIdentity: () => fetchXAIOAuthIdentity,
17
+ getXAICliBillingHeaders: () => getXAICliBillingHeaders,
18
+ loginXAIOAuth: () => loginXAIOAuth,
19
+ parseXAIAccessTokenPayload: () => parseXAIAccessTokenPayload,
20
+ refreshXAIOAuthToken: () => refreshXAIOAuthToken,
21
+ validateXAIBillingEndpoint: () => validateXAIBillingEndpoint,
22
+ validateXAIEndpoint: () => validateXAIEndpoint
23
+ });
24
+ const XAI_OAUTH_ISSUER = "https://auth.x.ai";
25
+ const XAI_OAUTH_DISCOVERY_URL = `${XAI_OAUTH_ISSUER}/.well-known/openid-configuration`;
26
+ const XAI_OAUTH_DEVICE_CODE_URL = `${XAI_OAUTH_ISSUER}/oauth2/device/code`;
27
+ const XAI_OAUTH_USERINFO_URL = `${XAI_OAUTH_ISSUER}/oauth2/userinfo`;
28
+ const XAI_OAUTH_CLIENT_ID = "b1a00492-073a-47ea-816f-4c329264a828";
29
+ const XAI_OAUTH_SCOPE = "openid profile email offline_access grok-cli:access api:access";
30
+ const XAI_CLI_BILLING_BASE_URL = "https://cli-chat-proxy.grok.com";
31
+ const XAI_CLI_BILLING_PATH = "/v1/billing";
32
+ const XAI_CLI_BILLING_FORMAT = "credits";
33
+ const ACCESS_TOKEN_CLIENT_SKEW_MS = 3e5;
34
+ const DISCOVERY_TIMEOUT_MS = 15e3;
35
+ const TOKEN_REQUEST_TIMEOUT_MS = 2e4;
36
+ function isRecord(value) {
37
+ return typeof value === "object" && value !== null;
38
+ }
39
+ /**
40
+ * Validate an xAI OIDC endpoint against its scheme and host.
41
+ *
42
+ * The discovery response is long-lived and its token endpoint receives every
43
+ * future refresh token. Rejecting non-HTTPS or non-`x.ai` / `*.x.ai` hosts
44
+ * pins that endpoint to the xAI auth origin.
45
+ *
46
+ * @throws Error with message `Invalid xAI <field>: <url>` when the URL fails
47
+ * either scheme or host validation.
48
+ */
49
+ function isXaiAuthHostname(host) {
50
+ return host === "x.ai" || host.endsWith(".x.ai");
51
+ }
52
+ /** SuperGrok CLI billing proxy host (`cli-chat-proxy.grok.com`), not the OIDC issuer. */
53
+ function isXaiBillingHostname(host) {
54
+ return host === "grok.com" || host.endsWith(".grok.com");
55
+ }
56
+ function validateXAIEndpoint(url, field) {
57
+ let parsed;
58
+ try {
59
+ parsed = new URL(url);
60
+ } catch {
61
+ throw new OAuthError(`Invalid xAI ${field}: ${url}`, {
62
+ kind: "validation",
63
+ provider: "xai"
64
+ });
65
+ }
66
+ if (parsed.protocol !== "https:") throw new OAuthError(`Invalid xAI ${field}: ${url}`, {
67
+ kind: "validation",
68
+ provider: "xai"
69
+ });
70
+ const host = parsed.hostname.toLowerCase();
71
+ if (!host || !isXaiAuthHostname(host)) throw new OAuthError(`Invalid xAI ${field}: ${url}`, {
72
+ kind: "validation",
73
+ provider: "xai"
74
+ });
75
+ return url;
76
+ }
77
+ /**
78
+ * Pin SuperGrok billing URLs to HTTPS `grok.com` / `*.grok.com`.
79
+ * The CLI billing proxy is intentionally not on `*.x.ai`.
80
+ */
81
+ function validateXAIBillingEndpoint(url, field = "billing_url") {
82
+ let parsed;
83
+ try {
84
+ parsed = new URL(url);
85
+ } catch {
86
+ throw new OAuthError(`Invalid xAI ${field}: ${url}`, {
87
+ kind: "validation",
88
+ provider: "xai"
89
+ });
90
+ }
91
+ if (parsed.protocol !== "https:") throw new OAuthError(`Invalid xAI ${field}: ${url}`, {
92
+ kind: "validation",
93
+ provider: "xai"
94
+ });
95
+ const host = parsed.hostname.toLowerCase();
96
+ if (!host || !isXaiBillingHostname(host)) throw new OAuthError(`Invalid xAI ${field}: ${url}`, {
97
+ kind: "validation",
98
+ provider: "xai"
99
+ });
100
+ return url;
101
+ }
102
+ /** Fetch xAI's OIDC discovery document and validate the token endpoint. */
103
+ async function xaiOAuthDiscovery(timeoutMs = DISCOVERY_TIMEOUT_MS, fetchOverride) {
104
+ const fetchImpl = fetchOverride ?? fetch;
105
+ let response;
106
+ try {
107
+ response = await fetchImpl(XAI_OAUTH_DISCOVERY_URL, {
108
+ method: "GET",
109
+ headers: { Accept: "application/json" },
110
+ signal: AbortSignal.timeout(timeoutMs)
111
+ });
112
+ } catch (error) {
113
+ throw new OAuthError(`xAI OIDC discovery failed: ${error instanceof Error ? error.message : String(error)}`, {
114
+ kind: "discovery",
115
+ provider: "xai",
116
+ cause: error
117
+ });
118
+ }
119
+ if (response.status !== 200) throw new OAuthError(`xAI OIDC discovery returned status ${response.status}.`, {
120
+ kind: "discovery",
121
+ provider: "xai",
122
+ status: response.status
123
+ });
124
+ let payload;
125
+ try {
126
+ payload = await response.json();
127
+ } catch (error) {
128
+ throw new OAuthError(`xAI OIDC discovery returned invalid JSON: ${error instanceof Error ? error.message : String(error)}`, {
129
+ kind: "validation",
130
+ provider: "xai",
131
+ cause: error
132
+ });
133
+ }
134
+ if (!isRecord(payload)) throw new OAuthError("xAI OIDC discovery response was not a JSON object.", {
135
+ kind: "validation",
136
+ provider: "xai"
137
+ });
138
+ const tokenEndpoint = typeof payload.token_endpoint === "string" ? payload.token_endpoint.trim() : "";
139
+ if (!tokenEndpoint) throw new OAuthError("xAI OIDC discovery response was missing token_endpoint.", {
140
+ kind: "validation",
141
+ provider: "xai"
142
+ });
143
+ validateXAIEndpoint(tokenEndpoint, "token_endpoint");
144
+ return { token_endpoint: tokenEndpoint };
145
+ }
146
+ /** Decode an xAI access-token JWT payload without verifying its signature. */
147
+ function parseXAIAccessTokenPayload(jwt) {
148
+ try {
149
+ if (typeof jwt !== "string" || !jwt.includes(".")) return null;
150
+ const parts = jwt.split(".");
151
+ if (parts.length < 2) return null;
152
+ const payloadPart = parts[1];
153
+ if (!payloadPart) return null;
154
+ const decoded = Buffer.from(payloadPart, "base64url").toString("utf8");
155
+ const payload = JSON.parse(decoded);
156
+ return isRecord(payload) && !Array.isArray(payload) ? payload : null;
157
+ } catch {
158
+ return null;
159
+ }
160
+ }
161
+ /** Extract the stable xAI subject UUID from an access token. */
162
+ function extractXAIAccessTokenSubject(jwt) {
163
+ const sub = parseXAIAccessTokenPayload(jwt)?.sub;
164
+ return typeof sub === "string" && sub.trim() ? sub.trim() : void 0;
165
+ }
166
+ /** Fetch optional OIDC userinfo for a valid xAI access token. */
167
+ async function fetchXAIOAuthIdentity(accessToken, fetchOverride, signal) {
168
+ const token = accessToken.trim();
169
+ if (!token) return null;
170
+ const fetchImpl = fetchOverride ?? fetch;
171
+ try {
172
+ const response = await fetchImpl(XAI_OAUTH_USERINFO_URL, {
173
+ method: "GET",
174
+ headers: {
175
+ Authorization: `Bearer ${token}`,
176
+ Accept: "application/json"
177
+ },
178
+ redirect: "error",
179
+ signal: signal ? AbortSignal.any([signal, AbortSignal.timeout(DISCOVERY_TIMEOUT_MS)]) : AbortSignal.timeout(DISCOVERY_TIMEOUT_MS)
180
+ });
181
+ if (!response.ok) return null;
182
+ const payload = await response.json();
183
+ if (!isRecord(payload) || Array.isArray(payload)) return null;
184
+ const sub = typeof payload.sub === "string" && payload.sub.trim() ? payload.sub.trim() : void 0;
185
+ const email = typeof payload.email === "string" && payload.email.trim() ? payload.email.trim() : void 0;
186
+ const name = typeof payload.name === "string" && payload.name.trim() ? payload.name.trim() : void 0;
187
+ if (!sub && !email && !name) return null;
188
+ return {
189
+ ...sub ? { accountId: sub } : {},
190
+ ...email ? { email: email.toLowerCase() } : {},
191
+ ...name ? { name } : {}
192
+ };
193
+ } catch {
194
+ return null;
195
+ }
196
+ }
197
+ async function withXAIOAuthIdentity(credentials, fetchOverride, signal) {
198
+ const identity = await fetchXAIOAuthIdentity(credentials.access, fetchOverride, signal);
199
+ const accountId = identity?.accountId ?? credentials.accountId ?? extractXAIAccessTokenSubject(credentials.access);
200
+ const email = identity?.email ?? credentials.email;
201
+ return {
202
+ ...credentials,
203
+ ...accountId ? { accountId } : {},
204
+ ...email ? { email } : {}
205
+ };
206
+ }
207
+ /** Build the SuperGrok CLI billing URL. Pass `""` to omit `format` (unified monthly payload). */
208
+ function buildXAICliBillingUrl(format = XAI_CLI_BILLING_FORMAT) {
209
+ const url = new URL(XAI_CLI_BILLING_PATH, XAI_CLI_BILLING_BASE_URL);
210
+ if (format) url.searchParams.set("format", format);
211
+ return validateXAIBillingEndpoint(url.toString());
212
+ }
213
+ /**
214
+ * Headers for SuperGrok CLI billing (`cli-chat-proxy.grok.com`).
215
+ * Official Grok CLI also sends `X-XAI-Token-Auth: xai-grok-cli` on this host;
216
+ * include it so billing stays on the same product gate as chat inference.
217
+ */
218
+ function getXAICliBillingHeaders(options) {
219
+ return {
220
+ Authorization: `Bearer ${options.accessToken}`,
221
+ Accept: "application/json",
222
+ "X-XAI-Token-Auth": "xai-grok-cli"
223
+ };
224
+ }
225
+ function parseXAIDeviceAuthorization(payload) {
226
+ if (!isRecord(payload)) throw new OAuthError("xAI device-code response was not a JSON object.", {
227
+ kind: "validation",
228
+ provider: "xai"
229
+ });
230
+ const deviceCode = typeof payload.device_code === "string" ? payload.device_code.trim() : "";
231
+ const userCode = typeof payload.user_code === "string" ? payload.user_code.trim() : "";
232
+ const verificationUri = typeof payload.verification_uri === "string" ? payload.verification_uri.trim() : "";
233
+ const verificationUriComplete = typeof payload.verification_uri_complete === "string" ? payload.verification_uri_complete.trim() : "";
234
+ const expiresInSeconds = payload.expires_in;
235
+ const intervalSeconds = payload.interval;
236
+ if (!deviceCode || !userCode || !verificationUri || !verificationUriComplete || typeof expiresInSeconds !== "number" || !Number.isFinite(expiresInSeconds) || expiresInSeconds <= 0 || typeof intervalSeconds !== "number" || !Number.isFinite(intervalSeconds) || intervalSeconds <= 0) throw new OAuthError("xAI device-code response missing or invalid required fields.", {
237
+ kind: "validation",
238
+ provider: "xai"
239
+ });
240
+ validateXAIEndpoint(verificationUri, "verification_uri");
241
+ validateXAIEndpoint(verificationUriComplete, "verification_uri_complete");
242
+ return {
243
+ deviceCode,
244
+ userCode,
245
+ verificationUriComplete,
246
+ expiresInSeconds,
247
+ intervalSeconds
248
+ };
249
+ }
250
+ function parseXAITokenResponse(payload, label, refreshTokenFallback) {
251
+ if (!isRecord(payload)) throw new OAuthError(`${label} was not a JSON object`, {
252
+ kind: "validation",
253
+ provider: "xai"
254
+ });
255
+ const accessToken = typeof payload.access_token === "string" ? payload.access_token : "";
256
+ const refreshToken = (typeof payload.refresh_token === "string" ? payload.refresh_token : "") || refreshTokenFallback || "";
257
+ const expiresInSeconds = payload.expires_in;
258
+ if (!accessToken) throw new OAuthError(`${label} missing access_token`, {
259
+ kind: "validation",
260
+ provider: "xai"
261
+ });
262
+ if (!refreshToken) throw new OAuthError(`${label} missing refresh_token`, {
263
+ kind: "validation",
264
+ provider: "xai"
265
+ });
266
+ if (typeof expiresInSeconds !== "number" || !Number.isFinite(expiresInSeconds)) throw new OAuthError(`${label} missing expires_in`, {
267
+ kind: "validation",
268
+ provider: "xai"
269
+ });
270
+ return {
271
+ access: accessToken,
272
+ refresh: refreshToken,
273
+ expires: Date.now() + expiresInSeconds * 1e3 - ACCESS_TOKEN_CLIENT_SKEW_MS
274
+ };
275
+ }
276
+ async function requestXAIDeviceAuthorization(fetchImpl, signal) {
277
+ let response;
278
+ try {
279
+ const timeoutSignal = AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS);
280
+ response = await fetchImpl(XAI_OAUTH_DEVICE_CODE_URL, {
281
+ method: "POST",
282
+ headers: {
283
+ "Content-Type": "application/x-www-form-urlencoded",
284
+ Accept: "application/json"
285
+ },
286
+ body: new URLSearchParams({
287
+ client_id: XAI_OAUTH_CLIENT_ID,
288
+ scope: XAI_OAUTH_SCOPE
289
+ }),
290
+ signal: signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal
291
+ });
292
+ } catch (error) {
293
+ if (signal?.aborted) throw new LoginCancelledError();
294
+ throw new OAuthError(`xAI device-code request failed: ${error instanceof Error ? error.message : String(error)}`, {
295
+ kind: "device-auth",
296
+ provider: "xai",
297
+ cause: error
298
+ });
299
+ }
300
+ if (!response.ok) {
301
+ let detail = "";
302
+ try {
303
+ detail = (await response.text()).trim();
304
+ } catch {}
305
+ throw new OAuthError(`xAI device-code request failed: ${response.status}${detail ? ` ${detail}` : ""}`, {
306
+ kind: "device-auth",
307
+ provider: "xai",
308
+ status: response.status
309
+ });
310
+ }
311
+ let payload;
312
+ try {
313
+ payload = await response.json();
314
+ } catch (error) {
315
+ throw new OAuthError(`xAI device-code response returned invalid JSON: ${error instanceof Error ? error.message : String(error)}`, {
316
+ kind: "validation",
317
+ provider: "xai",
318
+ cause: error
319
+ });
320
+ }
321
+ return parseXAIDeviceAuthorization(payload);
322
+ }
323
+ async function pollXAIDeviceToken(tokenEndpoint, deviceCode, fetchImpl, signal) {
324
+ let response;
325
+ try {
326
+ const timeoutSignal = AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS);
327
+ response = await fetchImpl(tokenEndpoint, {
328
+ method: "POST",
329
+ headers: {
330
+ "Content-Type": "application/x-www-form-urlencoded",
331
+ Accept: "application/json"
332
+ },
333
+ body: new URLSearchParams({
334
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
335
+ client_id: XAI_OAUTH_CLIENT_ID,
336
+ device_code: deviceCode
337
+ }),
338
+ redirect: "error",
339
+ signal: signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal
340
+ });
341
+ } catch (error) {
342
+ if (signal?.aborted) throw new LoginCancelledError();
343
+ throw new OAuthError(`xAI device-code token polling failed: ${error instanceof Error ? error.message : String(error)}`, {
344
+ kind: "polling",
345
+ provider: "xai",
346
+ cause: error
347
+ });
348
+ }
349
+ let payload;
350
+ try {
351
+ payload = await response.json();
352
+ } catch (error) {
353
+ throw new OAuthError(`xAI device-code token polling returned invalid JSON: ${error instanceof Error ? error.message : String(error)}`, {
354
+ kind: "polling",
355
+ provider: "xai",
356
+ status: response.status,
357
+ cause: error
358
+ });
359
+ }
360
+ if (response.ok) return {
361
+ status: "complete",
362
+ value: parseXAITokenResponse(payload, "xAI device-code token response")
363
+ };
364
+ if (!isRecord(payload)) throw new OAuthError(`xAI device-code token polling failed: ${response.status}`, {
365
+ kind: "polling",
366
+ provider: "xai",
367
+ status: response.status
368
+ });
369
+ const errorCode = typeof payload.error === "string" ? payload.error : "";
370
+ if (errorCode === "authorization_pending") return { status: "pending" };
371
+ if (errorCode === "slow_down") return { status: "slow_down" };
372
+ const detail = (typeof payload.error_description === "string" ? payload.error_description : "") || errorCode || String(response.status);
373
+ throw new OAuthError(`xAI device-code token polling failed: ${detail}`, {
374
+ kind: "polling",
375
+ provider: "xai",
376
+ status: response.status
377
+ });
378
+ }
379
+ /** Log in to xAI Grok with the RFC 8628 device authorization grant. */
380
+ async function loginXAIOAuth(ctrl) {
381
+ const fetchImpl = ctrl.fetch ?? fetch;
382
+ const discovery = await xaiOAuthDiscovery(DISCOVERY_TIMEOUT_MS, fetchImpl);
383
+ const device = await requestXAIDeviceAuthorization(fetchImpl, ctrl.signal);
384
+ ctrl.onAuth?.({
385
+ url: device.verificationUriComplete,
386
+ instructions: `Enter code: ${device.userCode}`
387
+ });
388
+ ctrl.onProgress?.("Waiting for xAI device authorization...");
389
+ return withXAIOAuthIdentity(await pollOAuthDeviceCodeFlow({
390
+ poll: () => pollXAIDeviceToken(discovery.token_endpoint, device.deviceCode, fetchImpl, ctrl.signal),
391
+ intervalSeconds: device.intervalSeconds,
392
+ expiresInSeconds: device.expiresInSeconds,
393
+ signal: ctrl.signal
394
+ }), fetchImpl, ctrl.signal);
395
+ }
396
+ /**
397
+ * Refresh an xAI OAuth access token using a stored refresh_token.
398
+ *
399
+ * Re-runs OIDC discovery and re-validates the token endpoint before sending
400
+ * the stored refresh token.
401
+ */
402
+ async function refreshXAIOAuthToken(refreshToken, fetchOverride) {
403
+ const fetchImpl = fetchOverride ?? fetch;
404
+ if (typeof refreshToken !== "string" || !refreshToken.trim()) throw new OAuthError("missing refresh_token", {
405
+ kind: "validation",
406
+ provider: "xai"
407
+ });
408
+ const response = await fetchImpl(validateXAIEndpoint((await xaiOAuthDiscovery(DISCOVERY_TIMEOUT_MS, fetchImpl)).token_endpoint, "token_endpoint"), {
409
+ method: "POST",
410
+ headers: {
411
+ "Content-Type": "application/x-www-form-urlencoded",
412
+ Accept: "application/json"
413
+ },
414
+ body: new URLSearchParams({
415
+ grant_type: "refresh_token",
416
+ client_id: XAI_OAUTH_CLIENT_ID,
417
+ refresh_token: refreshToken
418
+ }),
419
+ redirect: "error",
420
+ signal: AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS)
421
+ });
422
+ if (!response.ok) {
423
+ let detail = "";
424
+ try {
425
+ detail = (await response.text()).trim();
426
+ } catch {}
427
+ throw new OAuthError(`xAI token refresh failed: ${response.status}${detail ? ` ${detail}` : ""}`, {
428
+ kind: "token-refresh",
429
+ provider: "xai",
430
+ status: response.status
431
+ });
432
+ }
433
+ let payload;
434
+ try {
435
+ payload = await response.json();
436
+ } catch (error) {
437
+ throw new OAuthError(`xAI token refresh returned invalid JSON: ${error instanceof Error ? error.message : String(error)}`, {
438
+ kind: "validation",
439
+ provider: "xai",
440
+ cause: error
441
+ });
442
+ }
443
+ return withXAIOAuthIdentity(parseXAITokenResponse(payload, "xAI token refresh response", refreshToken), fetchImpl);
444
+ }
445
+ //#endregion
446
+ export { xai_oauth_exports as a, getXAICliBillingHeaders as i, extractXAIAccessTokenSubject as n, fetchXAIOAuthIdentity as r, buildXAICliBillingUrl as t };