@xiaoso/dsh-tool-plus 0.1.0-beta.3 → 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 (155) hide show
  1. package/lib/abort-D1_Z5Ut5.mjs +51 -0
  2. package/lib/abort-dIkZBV7Q.mjs +51 -0
  3. package/lib/amazon-bedrock-B0nxT06F.mjs +917 -0
  4. package/lib/amazon-bedrock-WQhvjHYu.mjs +917 -0
  5. package/lib/anthropic-CJCauvYz.mjs +3115 -0
  6. package/lib/anthropic-CZghe_9U.mjs +3115 -0
  7. package/lib/anthropic-sCMH7JID.mjs +262 -0
  8. package/lib/anthropic-tTntD8BD.mjs +262 -0
  9. package/lib/api-key-login-BzqNdM2y.mjs +157 -0
  10. package/lib/api-key-login-CWVwvHT1.mjs +157 -0
  11. package/lib/aws-credentials-CXryMobh.mjs +867 -0
  12. package/lib/aws-credentials-ChG79ey-.mjs +867 -0
  13. package/lib/azure-openai-responses-Cgmc-rbL.mjs +274 -0
  14. package/lib/azure-openai-responses-DuukbD0F.mjs +274 -0
  15. package/lib/bun-shim.mjs +81 -6
  16. package/lib/bundled-references-Cavaffah.mjs +55 -0
  17. package/lib/bundled-references-sLN0YdXU.mjs +55 -0
  18. package/lib/callback-server-CQ5Jo8F-.mjs +398 -0
  19. package/lib/callback-server-DDSrZ6l_.mjs +398 -0
  20. package/lib/client.js +1 -1
  21. package/lib/cursor-B3zg7EHj.mjs +273 -0
  22. package/lib/cursor-B6TUEmgP.mjs +135 -0
  23. package/lib/cursor-D8gvtTL3.mjs +135 -0
  24. package/lib/cursor-DkSX2h3H.mjs +5441 -0
  25. package/lib/cursor-aJrXeYCb.mjs +273 -0
  26. package/lib/cursor-mJQwUKXK.mjs +5441 -0
  27. package/lib/device-code-DBo3B5nh.mjs +51 -0
  28. package/lib/device-code-DIb0FU-H.mjs +51 -0
  29. package/lib/devin-BHZZyMhO.mjs +95 -0
  30. package/lib/devin-BK7DHeca.mjs +114 -0
  31. package/lib/devin-CfMp3cXS.mjs +95 -0
  32. package/lib/devin-D9zR5B_R.mjs +542 -0
  33. package/lib/devin-Q1yem3lp.mjs +114 -0
  34. package/lib/devin-vNZTNUON.mjs +542 -0
  35. package/lib/error-Dd8DIqs-.mjs +1449 -0
  36. package/lib/error-yCSG0mGC.mjs +1449 -0
  37. package/lib/event-stream-BbFZJy-z.mjs +151 -0
  38. package/lib/event-stream-loUa0s1T.mjs +151 -0
  39. package/lib/fs-promises-shim-Bx0fpxuk.mjs +57 -0
  40. package/lib/github-copilot-B1yiyVRh.mjs +104 -0
  41. package/lib/github-copilot-BWT3eAOF.mjs +208 -0
  42. package/lib/github-copilot-CYkjeTi3.mjs +208 -0
  43. package/lib/github-copilot-jscUZ8Hf.mjs +104 -0
  44. package/lib/gitlab-duo-CM7Ref1H.mjs +155 -0
  45. package/lib/gitlab-duo-gubO4FNw.mjs +155 -0
  46. package/lib/gitlab-duo-workflow-BGAF6JDw.mjs +91 -0
  47. package/lib/gitlab-duo-workflow-D78tdn8E.mjs +91 -0
  48. package/lib/google-BS4T25Pn.mjs +30 -0
  49. package/lib/google-TFe-7-of.mjs +30 -0
  50. package/lib/google-antigravity-DGmwC2KV.mjs +198 -0
  51. package/lib/google-antigravity-DNYhgTpA.mjs +198 -0
  52. package/lib/google-auth-B6gjsZvg.mjs +232 -0
  53. package/lib/google-auth-De7_s3eo.mjs +232 -0
  54. package/lib/google-gemini-cli-CWu8HvXW.mjs +211 -0
  55. package/lib/google-gemini-cli-Cb97bzQc.mjs +850 -0
  56. package/lib/google-gemini-cli-Cqds_Q5T.mjs +850 -0
  57. package/lib/google-gemini-cli-Dsztq0N5.mjs +211 -0
  58. package/lib/google-oauth-shared-CuEHaDDj.mjs +147 -0
  59. package/lib/google-oauth-shared-yqlyqPPC.mjs +147 -0
  60. package/lib/google-shared-CgKmmdO3.mjs +760 -0
  61. package/lib/google-shared-Dr-VG-ap.mjs +760 -0
  62. package/lib/google-vertex-BDN2tLaD.mjs +99 -0
  63. package/lib/google-vertex-DopVOQOG.mjs +99 -0
  64. package/lib/identity-Da1GPU9a.mjs +219 -0
  65. package/lib/identity-xRP7_eSR.mjs +219 -0
  66. package/lib/idle-iterator-Baoyn3Hp.mjs +366 -0
  67. package/lib/idle-iterator-DUjKQEGT.mjs +366 -0
  68. package/lib/index.mjs +1731 -1178
  69. package/lib/kimi--wUOWER5.mjs +236 -0
  70. package/lib/kimi-Dh0pv3WZ.mjs +236 -0
  71. package/lib/markit-BL3cH47U.mjs +1417 -0
  72. package/lib/markit-BNiNY6SE.mjs +1417 -0
  73. package/lib/minimax-code-DCbuA6Yk.mjs +53 -0
  74. package/lib/minimax-code-Uq8Qu9LW.mjs +53 -0
  75. package/lib/models-D_XnT6ay.mjs +104660 -0
  76. package/lib/models-SGASygJ3.mjs +104660 -0
  77. package/lib/ollama-DPzBmq89.mjs +589 -0
  78. package/lib/ollama-DoBz5SFm.mjs +589 -0
  79. package/lib/openai-codex-Bi-4S4PX.mjs +255 -0
  80. package/lib/openai-codex-Ch8CkT3p.mjs +255 -0
  81. package/lib/openai-codex-responses-CvxL_FMF.mjs +3144 -0
  82. package/lib/openai-codex-responses-pejZgdZo.mjs +3144 -0
  83. package/lib/openai-completions-CF8IyNtP.mjs +1360 -0
  84. package/lib/openai-completions-DIf361kF.mjs +1360 -0
  85. package/lib/openai-reasoning-fallback-Nj6yB2rY.mjs +286 -0
  86. package/lib/openai-reasoning-fallback-OdJREP1o.mjs +286 -0
  87. package/lib/openai-responses-BqXJInHX.mjs +867 -0
  88. package/lib/openai-responses-Db_a-U4-.mjs +867 -0
  89. package/lib/opencode-DhMolSoB.mjs +38 -0
  90. package/lib/opencode-Rq_Q2vAO.mjs +38 -0
  91. package/lib/perplexity-C4iLVMUj.mjs +194 -0
  92. package/lib/perplexity-Uu7Jzg5b.mjs +194 -0
  93. package/lib/proxy-DDqrmjjC.mjs +190 -0
  94. package/lib/proxy-pM_NIv-H.mjs +190 -0
  95. package/lib/request-debug-HJMoJncL.mjs +183 -0
  96. package/lib/sanitize-text-CfcXzw5X.mjs +33 -0
  97. package/lib/scrapers-BkFfcPHj.mjs +9198 -0
  98. package/lib/scrapers-CVptboMs.mjs +9198 -0
  99. package/lib/scrapers-nhQAvc8d.mjs +9198 -0
  100. package/lib/shell-snapshot-fn-env.sh +67 -43
  101. package/lib/src-BgpusnsB.mjs +5076 -0
  102. package/lib/src-lDmkSRbm.mjs +5006 -0
  103. package/lib/stream-BlldLkVq.mjs +10236 -0
  104. package/lib/stream-CRtexYLe.mjs +10236 -0
  105. package/lib/stream-markup-healing-DMsxBx1L.mjs +491 -0
  106. package/lib/stream-markup-healing-KMkiAA00.mjs +491 -0
  107. package/lib/turndown-DN7ByzEI.mjs +667 -0
  108. package/lib/types/config/settings.d.ts +9 -1
  109. package/lib/types/config/truncate.d.ts +9 -5
  110. package/lib/types/tools/bash/background.d.ts +1 -1
  111. package/lib/types/tools/bash/bash-executor.d.ts +4 -0
  112. package/lib/types/tools/bash/bash-interceptor.d.ts +10 -8
  113. package/lib/types/tools/bash/cd-workdir.d.ts +35 -0
  114. package/lib/types/tools/bash/non-interactive-env.d.ts +2 -0
  115. package/lib/types/tools/bash/render.d.ts +4 -3
  116. package/lib/types/tools/bash/sanitize-text.d.ts +5 -0
  117. package/lib/types/tools/bash/shell-snapshot.d.ts +4 -1
  118. package/lib/types/tools/bash/shell-tokenize.d.ts +60 -0
  119. package/lib/types/tools/bash/streaming-output.d.ts +12 -212
  120. package/lib/types/tools/bash/which.d.ts +20 -0
  121. package/lib/types/tools/bash/windows-shell.d.ts +31 -0
  122. package/lib/types/tools/edit/adapter/index.d.ts +25 -3
  123. package/lib/types/tools/edit/adapter/tools/auto-generated-guard.d.ts +7 -17
  124. package/lib/types/tools/glob/adapter/index.d.ts +27 -1
  125. package/lib/types/tools/grep/adapter/index.d.ts +29 -1
  126. package/lib/types/tools/omp/edit/dispatch.d.ts +43 -0
  127. package/lib/types/tools/omp/edit/hashline/noop-loop-guard.d.ts +3 -1
  128. package/lib/types/tools/omp/tools/auto-generated-guard.d.ts +20 -0
  129. package/lib/types/tools/omp/tools/write.d.ts +4 -4
  130. package/lib/types/tools/shared/auto-generated-guard.dsh.d.ts +16 -4
  131. package/lib/types/tools/shared/bun-shim.d.ts +4 -0
  132. package/lib/types/tools/shared/fs-promises-shim.d.ts +3 -1
  133. package/lib/types/tools/shared/omp-prompt.d.ts +13 -7
  134. package/lib/types/tools/shared/session-state.d.ts +9 -3
  135. package/lib/utils-Bw139LTz.mjs +8119 -0
  136. package/lib/utils-CZw4tVZQ.mjs +12315 -0
  137. package/lib/utils-CiGN7OHR.mjs +12315 -0
  138. package/lib/utils-Cp76gCyk.mjs +8119 -0
  139. package/lib/utils-D0GRDgAr.mjs +12315 -0
  140. package/lib/utils-D2YknRk4.mjs +51 -0
  141. package/lib/utils-DzXZDfYc.mjs +51 -0
  142. package/lib/vision-guard-01qSwFpf.mjs +92 -0
  143. package/lib/vision-guard-DzZGaOga.mjs +92 -0
  144. package/lib/wafer-CgtPHerf.mjs +17 -0
  145. package/lib/wafer-cBtrn6q9.mjs +17 -0
  146. package/lib/xai-oauth-Buk8XVvM.mjs +446 -0
  147. package/lib/xai-oauth-CMal8l1O.mjs +446 -0
  148. package/lib/xiaomi-CZgwvX2G.mjs +157 -0
  149. package/lib/xiaomi-D2qT5cAC.mjs +157 -0
  150. package/lib/zai-7DWMkEqM.mjs +203 -0
  151. package/lib/zai-C59YnomG.mjs +203 -0
  152. package/lib/zip-Cg9ANN_U.mjs +1316 -0
  153. package/lib/zip-D36ZKsP8.mjs +1316 -0
  154. package/package.json +1 -1
  155. package/presets/package.json +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 };
@@ -0,0 +1,157 @@
1
+ import { installBunShim as __installBunShim } from "./bun-shim.mjs";
2
+ __installBunShim();
3
+ import { _ as OnPromptRequiredError, c as OAuthError, h as LoginCancelledError, m as ApiKeyRequiredError } from "./error-yCSG0mGC.mjs";
4
+ //#region node_modules/.pnpm/@oh-my-pi+pi-ai@17.3.5/node_modules/@oh-my-pi/pi-ai/src/registry/oauth/xiaomi.ts
5
+ /**
6
+ * Xiaomi MiMo login flow.
7
+ *
8
+ * Xiaomi MiMo provides OpenAI-compatible models via
9
+ * https://api.xiaomimimo.com/v1.
10
+ *
11
+ * Standard Xiaomi login opens the pay-as-you-go API key console. Token Plan
12
+ * login opens plan management so users copy the regional `tp-...` key.
13
+ */
14
+ const PROVIDER_ID = "xiaomi";
15
+ const PROVIDER_NAME = "Xiaomi MiMo";
16
+ const STANDARD_AUTH_URL = "https://platform.xiaomimimo.com/#/console/api-keys";
17
+ const TOKEN_PLAN_AUTH_URL = "https://platform.xiaomimimo.com/console/plan-manage";
18
+ const STANDARD_API_BASE_URL = "https://api.xiaomimimo.com/v1";
19
+ const TOKEN_PLAN_KEY_PREFIX = "tp-";
20
+ const STANDARD_VALIDATION_MODEL = "mimo-v2.5";
21
+ const TOKEN_PLAN_VALIDATION_MODEL = "mimo-v2.5";
22
+ const TOKEN_PLAN_VALIDATION_ENDPOINTS = {
23
+ sgp: {
24
+ baseUrl: "https://token-plan-sgp.xiaomimimo.com/v1",
25
+ model: TOKEN_PLAN_VALIDATION_MODEL
26
+ },
27
+ ams: {
28
+ baseUrl: "https://token-plan-ams.xiaomimimo.com/v1",
29
+ model: TOKEN_PLAN_VALIDATION_MODEL
30
+ },
31
+ cn: {
32
+ baseUrl: "https://token-plan-cn.xiaomimimo.com/v1",
33
+ model: TOKEN_PLAN_VALIDATION_MODEL
34
+ }
35
+ };
36
+ const TOKEN_PLAN_REGION_NAMES = {
37
+ sgp: "Singapore",
38
+ ams: "Europe",
39
+ cn: "China"
40
+ };
41
+ function isTokenPlanKey(apiKey) {
42
+ return apiKey.startsWith(TOKEN_PLAN_KEY_PREFIX);
43
+ }
44
+ const VALIDATION_TIMEOUT_MS = 15e3;
45
+ async function validateXiaomiApiKey(apiKey, tokenPlanRegion, signal, fetchOverride) {
46
+ const fetchImpl = fetchOverride ?? fetch;
47
+ const endpoints = tokenPlanRegion ? [TOKEN_PLAN_VALIDATION_ENDPOINTS[tokenPlanRegion]] : isTokenPlanKey(apiKey) ? [
48
+ TOKEN_PLAN_VALIDATION_ENDPOINTS.sgp,
49
+ TOKEN_PLAN_VALIDATION_ENDPOINTS.ams,
50
+ TOKEN_PLAN_VALIDATION_ENDPOINTS.cn
51
+ ] : [{
52
+ baseUrl: STANDARD_API_BASE_URL,
53
+ model: STANDARD_VALIDATION_MODEL
54
+ }];
55
+ let lastError = null;
56
+ for (const ep of endpoints) {
57
+ const timeoutSignal = AbortSignal.timeout(VALIDATION_TIMEOUT_MS);
58
+ const requestSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
59
+ try {
60
+ const response = await fetchImpl(`${ep.baseUrl}/chat/completions`, {
61
+ method: "POST",
62
+ headers: {
63
+ "Content-Type": "application/json",
64
+ Authorization: `Bearer ${apiKey}`
65
+ },
66
+ body: JSON.stringify({
67
+ model: ep.model,
68
+ max_tokens: 1,
69
+ messages: [{
70
+ role: "user",
71
+ content: "ping"
72
+ }]
73
+ }),
74
+ signal: requestSignal
75
+ });
76
+ if (response.ok) return;
77
+ if (response.status === 401) {
78
+ let details = "";
79
+ try {
80
+ details = (await response.text()).trim();
81
+ } catch {}
82
+ lastError = new OAuthError(details ? `${PROVIDER_NAME} API key validation failed (${response.status}): ${details}` : `${PROVIDER_NAME} API key validation failed (${response.status})`, {
83
+ kind: "validation",
84
+ provider: PROVIDER_ID,
85
+ status: response.status
86
+ });
87
+ continue;
88
+ }
89
+ let details = "";
90
+ try {
91
+ details = (await response.text()).trim();
92
+ } catch {}
93
+ const message = details ? `${PROVIDER_NAME} API key validation failed (${response.status}): ${details}` : `${PROVIDER_NAME} API key validation failed (${response.status})`;
94
+ throw new OAuthError(message, {
95
+ kind: "validation",
96
+ provider: PROVIDER_ID,
97
+ status: response.status
98
+ });
99
+ } catch (e) {
100
+ if (e instanceof DOMException && e.name === "AbortError" && signal?.aborted) throw e;
101
+ lastError = e instanceof Error ? e : new Error(String(e));
102
+ }
103
+ }
104
+ throw lastError ?? new OAuthError(`${PROVIDER_NAME} API key validation failed`, {
105
+ kind: "validation",
106
+ provider: PROVIDER_ID
107
+ });
108
+ }
109
+ /**
110
+ * Login to Xiaomi MiMo.
111
+ *
112
+ * Opens browser to API keys page, prompts user to paste their API key.
113
+ * Returns the API key directly (not OAuthCredentials - this isn't OAuth).
114
+ */
115
+ async function loginXiaomi(options) {
116
+ const fetchImpl = options.fetch ?? fetch;
117
+ if (!options.onPrompt) throw new OnPromptRequiredError(PROVIDER_NAME);
118
+ options.onAuth?.({
119
+ url: STANDARD_AUTH_URL,
120
+ instructions: "Copy your API key from the Xiaomi MiMo console"
121
+ });
122
+ const apiKey = await options.onPrompt({
123
+ message: "Paste your Xiaomi API key (sk-... or token-plan tp-...)",
124
+ placeholder: "sk-... or tp-..."
125
+ });
126
+ if (options.signal?.aborted) throw new LoginCancelledError();
127
+ const trimmed = apiKey.trim();
128
+ if (!trimmed) throw new ApiKeyRequiredError();
129
+ options.onProgress?.(`Validating ${PROVIDER_ID} API key...`);
130
+ await validateXiaomiApiKey(trimmed, void 0, options.signal, fetchImpl);
131
+ return trimmed;
132
+ }
133
+ /**
134
+ * Login to a regional Xiaomi Token Plan endpoint.
135
+ *
136
+ * Prompts for a token-plan API key and validates it against the selected region.
137
+ */
138
+ async function loginXiaomiTokenPlan(options, region) {
139
+ const fetchImpl = options.fetch ?? fetch;
140
+ if (!options.onPrompt) throw new OnPromptRequiredError(`Xiaomi Token Plan (${TOKEN_PLAN_REGION_NAMES[region]})`);
141
+ options.onAuth?.({
142
+ url: TOKEN_PLAN_AUTH_URL,
143
+ instructions: `Copy your token-plan API key for the ${TOKEN_PLAN_REGION_NAMES[region]} region`
144
+ });
145
+ const apiKey = await options.onPrompt({
146
+ message: `Paste your Xiaomi Token Plan ${TOKEN_PLAN_REGION_NAMES[region]} API key (tp-...)`,
147
+ placeholder: "tp-..."
148
+ });
149
+ if (options.signal?.aborted) throw new LoginCancelledError();
150
+ const trimmed = apiKey.trim();
151
+ if (!trimmed) throw new ApiKeyRequiredError();
152
+ options.onProgress?.(`Validating Xiaomi Token Plan (${TOKEN_PLAN_REGION_NAMES[region]}) API key...`);
153
+ await validateXiaomiApiKey(trimmed, region, options.signal, fetchImpl);
154
+ return trimmed;
155
+ }
156
+ //#endregion
157
+ export { loginXiaomi, loginXiaomiTokenPlan };