@omnicross/subscriptions 0.3.0 → 0.3.1

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.
@@ -1,7 +1,181 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
3
  var _chunk75ZPJI57cjs = require('./chunk-75ZPJI57.cjs');
4
4
 
5
+ // src/oauth/flows/kimi.ts
6
+ var kimi_exports = {};
7
+ _chunk75ZPJI57cjs.__export.call(void 0, kimi_exports, {
8
+ KIMI_CLI_VERSION: () => KIMI_CLI_VERSION,
9
+ KIMI_OAUTH_CONFIG: () => KIMI_OAUTH_CONFIG,
10
+ awaitDeviceToken: () => awaitDeviceToken,
11
+ generateKimiDeviceId: () => generateKimiDeviceId,
12
+ kimiAccountIdFromAccessToken: () => kimiAccountIdFromAccessToken,
13
+ kimiFingerprintHeaders: () => kimiFingerprintHeaders,
14
+ pollDeviceToken: () => pollDeviceToken,
15
+ refreshAccessToken: () => refreshAccessToken,
16
+ requestDeviceAuthorization: () => requestDeviceAuthorization
17
+ });
18
+ var _crypto = require('crypto'); var _crypto2 = _interopRequireDefault(_crypto);
19
+ var _os = require('os'); var os = _interopRequireWildcard(_os);
20
+ var KIMI_OAUTH_CONFIG = {
21
+ clientId: "17e5f671-d194-4dfb-9706-5516cb48c098",
22
+ deviceAuthorizationEndpoint: "https://auth.kimi.com/api/oauth/device_authorization",
23
+ tokenEndpoint: "https://auth.kimi.com/api/oauth/token"
24
+ };
25
+ var KIMI_CLI_VERSION = _nullishCoalesce(process.env["KIMI_CLI_VERSION"], () => ( "1.0.0"));
26
+ function sanitizeHeaderValue(value, fallback = "") {
27
+ const sanitized = value.replace(/[^\x20-\x7E]/g, "").trim();
28
+ return sanitized || fallback;
29
+ }
30
+ function deviceModel() {
31
+ const platform2 = os.platform();
32
+ const label = platform2 === "darwin" ? "macOS" : platform2 === "win32" ? "Windows" : platform2 === "linux" ? "Linux" : platform2;
33
+ return [label, os.release(), os.arch()].filter(Boolean).join(" ").trim();
34
+ }
35
+ function kimiFingerprintHeaders(deviceId) {
36
+ return {
37
+ "User-Agent": `KimiCLI/${KIMI_CLI_VERSION}`,
38
+ "X-Msh-Platform": "kimi_cli",
39
+ "X-Msh-Version": KIMI_CLI_VERSION,
40
+ "X-Msh-Device-Name": sanitizeHeaderValue(os.hostname(), "unknown"),
41
+ "X-Msh-Device-Model": sanitizeHeaderValue(deviceModel(), "unknown"),
42
+ "X-Msh-Os-Version": sanitizeHeaderValue(os.version(), "unknown"),
43
+ ...deviceId ? { "X-Msh-Device-Id": sanitizeHeaderValue(deviceId) } : {}
44
+ };
45
+ }
46
+ function generateKimiDeviceId() {
47
+ return _crypto2.default.randomUUID().replace(/-/g, "");
48
+ }
49
+ async function postFormRaw(fetchImpl, url, params, headers, timeoutMs = 3e4) {
50
+ const controller = new AbortController();
51
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
52
+ let response;
53
+ try {
54
+ response = await fetchImpl(url, {
55
+ method: "POST",
56
+ headers: { "Content-Type": "application/x-www-form-urlencoded", Accept: "application/json", ...headers },
57
+ body: params.toString(),
58
+ signal: controller.signal
59
+ });
60
+ } catch (error) {
61
+ if (controller.signal.aborted) throw new Error("token endpoint timed out");
62
+ throw error;
63
+ } finally {
64
+ clearTimeout(timer);
65
+ }
66
+ const text = await response.text();
67
+ let body;
68
+ try {
69
+ const parsed = JSON.parse(text);
70
+ body = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
71
+ } catch (e2) {
72
+ body = {};
73
+ }
74
+ return { status: response.status, body };
75
+ }
76
+ async function requestDeviceAuthorization(fetchImpl, fingerprint) {
77
+ const { status, body } = await postFormRaw(
78
+ fetchImpl,
79
+ KIMI_OAUTH_CONFIG.deviceAuthorizationEndpoint,
80
+ new URLSearchParams({ client_id: KIMI_OAUTH_CONFIG.clientId }),
81
+ _nullishCoalesce(fingerprint, () => ( {}))
82
+ );
83
+ const userCode = typeof body["user_code"] === "string" ? body["user_code"] : void 0;
84
+ const deviceCode = typeof body["device_code"] === "string" ? body["device_code"] : void 0;
85
+ const verificationUri = typeof body["verification_uri"] === "string" ? body["verification_uri"] : void 0;
86
+ if (status >= 400 || !userCode || !deviceCode || !verificationUri) {
87
+ const message = typeof body["error_description"] === "string" ? body["error_description"] : typeof body["msg"] === "string" ? body["msg"] : `device authorization failed (HTTP ${status})`;
88
+ throw new Error(message);
89
+ }
90
+ return {
91
+ userCode,
92
+ deviceCode,
93
+ verificationUri,
94
+ ...typeof body["verification_uri_complete"] === "string" ? { verificationUriComplete: body["verification_uri_complete"] } : {},
95
+ ...typeof body["interval"] === "number" ? { interval: body["interval"] } : {},
96
+ ...typeof body["expires_in"] === "number" ? { expiresIn: body["expires_in"] } : {}
97
+ };
98
+ }
99
+ async function pollDeviceToken(deviceCode, fetchImpl, fingerprint) {
100
+ const { status, body } = await postFormRaw(
101
+ fetchImpl,
102
+ KIMI_OAUTH_CONFIG.tokenEndpoint,
103
+ new URLSearchParams({
104
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
105
+ client_id: KIMI_OAUTH_CONFIG.clientId,
106
+ device_code: deviceCode
107
+ }),
108
+ _nullishCoalesce(fingerprint, () => ( {}))
109
+ );
110
+ const accessToken = typeof body["access_token"] === "string" ? body["access_token"] : void 0;
111
+ const refreshToken = typeof body["refresh_token"] === "string" ? body["refresh_token"] : void 0;
112
+ if (accessToken && refreshToken) {
113
+ const expiresIn = typeof body["expires_in"] === "number" && body["expires_in"] > 0 ? body["expires_in"] : 3600;
114
+ return { state: "done", accessToken, refreshToken, expiresIn };
115
+ }
116
+ const error = typeof body["error"] === "string" ? body["error"] : void 0;
117
+ if (error === "authorization_pending") return { state: "pending" };
118
+ if (error === "slow_down") return { state: "pending", intervalSeconds: 5 };
119
+ if (status < 400 && !error) return { state: "pending" };
120
+ const message = typeof body["error_description"] === "string" && body["error_description"] ? body["error_description"] : _nullishCoalesce(error, () => ( `device token poll failed (HTTP ${status})`));
121
+ return { state: "failed", message };
122
+ }
123
+ async function awaitDeviceToken(authorization, fetchImpl, options = {}) {
124
+ const sleep = _nullishCoalesce(options.sleep, () => ( ((ms) => new Promise((resolve) => setTimeout(resolve, ms)))));
125
+ const deadline = Date.now() + (_nullishCoalesce(options.deadlineMs, () => ( 15 * 6e4)));
126
+ const baseIntervalMs = _nullishCoalesce(options.intervalMs, () => ( (_nullishCoalesce(authorization.interval, () => ( 5))) * 1e3));
127
+ let intervalMs = Math.max(1e3, baseIntervalMs);
128
+ for (; ; ) {
129
+ const result = await pollDeviceToken(authorization.deviceCode, fetchImpl, options.fingerprint);
130
+ if (result.state === "done") return result;
131
+ if (result.state === "failed") throw new Error(result.message);
132
+ if (result.state === "pending" && result.intervalSeconds) intervalMs += result.intervalSeconds * 1e3;
133
+ _optionalChain([options, 'access', _ => _.onPending, 'optionalCall', _2 => _2()]);
134
+ if (Date.now() + intervalMs > deadline) throw new Error("device authorization timed out");
135
+ await sleep(intervalMs);
136
+ }
137
+ }
138
+ async function refreshAccessToken(refreshToken, fetchImpl, fingerprint) {
139
+ const { status, body } = await postFormRaw(
140
+ fetchImpl,
141
+ KIMI_OAUTH_CONFIG.tokenEndpoint,
142
+ new URLSearchParams({
143
+ grant_type: "refresh_token",
144
+ client_id: KIMI_OAUTH_CONFIG.clientId,
145
+ refresh_token: refreshToken
146
+ }),
147
+ _nullishCoalesce(fingerprint, () => ( {}))
148
+ );
149
+ const accessToken = typeof body["access_token"] === "string" ? body["access_token"] : void 0;
150
+ if (status >= 400 || !accessToken) {
151
+ const message = typeof body["error_description"] === "string" && body["error_description"] ? body["error_description"] : typeof body["error"] === "string" ? body["error"] : `refresh failed (HTTP ${status})`;
152
+ throw new Error(message);
153
+ }
154
+ return {
155
+ accessToken,
156
+ // Kimi rotates the refresh token; keep the old one when the response omits it.
157
+ refreshToken: typeof body["refresh_token"] === "string" && body["refresh_token"] ? body["refresh_token"] : refreshToken,
158
+ expiresIn: typeof body["expires_in"] === "number" && body["expires_in"] > 0 ? body["expires_in"] : 3600
159
+ };
160
+ }
161
+ function kimiAccountIdFromAccessToken(accessToken) {
162
+ const parts = accessToken.split(".");
163
+ if (parts.length !== 3) return void 0;
164
+ try {
165
+ const json = Buffer.from(parts[1], "base64url").toString("utf8");
166
+ const claims = JSON.parse(json);
167
+ if (!claims || typeof claims !== "object" || Array.isArray(claims)) return void 0;
168
+ const record = claims;
169
+ for (const key of ["user_id", "sub"]) {
170
+ const value = record[key];
171
+ if (typeof value === "string" && value.trim()) return value.trim();
172
+ }
173
+ return void 0;
174
+ } catch (e3) {
175
+ return void 0;
176
+ }
177
+ }
178
+
5
179
  // src/oauth/flows/claude.ts
6
180
  var claude_exports = {};
7
181
  _chunk75ZPJI57cjs.__export.call(void 0, claude_exports, {
@@ -9,9 +183,9 @@ _chunk75ZPJI57cjs.__export.call(void 0, claude_exports, {
9
183
  exchangeSetupTokenCode: () => exchangeSetupTokenCode,
10
184
  generateAuthParams: () => generateAuthParams,
11
185
  generateSetupTokenParams: () => generateSetupTokenParams,
12
- refreshAccessToken: () => refreshAccessToken
186
+ refreshAccessToken: () => refreshAccessToken2
13
187
  });
14
- var _crypto = require('crypto'); var _crypto2 = _interopRequireDefault(_crypto);
188
+
15
189
 
16
190
  // src/oauth/fetchPort.ts
17
191
  function errorMessage(error, errorDescription) {
@@ -60,7 +234,7 @@ async function postForm(fetchImpl, url, params, parseErrorMessage, timeoutMs = D
60
234
  let data;
61
235
  try {
62
236
  data = JSON.parse(responseData);
63
- } catch (e2) {
237
+ } catch (e4) {
64
238
  throw new Error(withStatus(parseErrorMessage, response));
65
239
  }
66
240
  if (data.error) {
@@ -83,7 +257,7 @@ async function postJson(fetchImpl, url, body, parseErrorMessage, extraHeaders =
83
257
  let data;
84
258
  try {
85
259
  data = JSON.parse(responseData);
86
- } catch (e3) {
260
+ } catch (e5) {
87
261
  throw new Error(withStatus(parseErrorMessage, response));
88
262
  }
89
263
  if (data.error) {
@@ -165,7 +339,7 @@ function generateSetupTokenParams() {
165
339
  }
166
340
  async function exchangeCodeForTokens(request, fetchImpl) {
167
341
  const { authorizationCode, codeVerifier, state } = request;
168
- const code = _nullishCoalesce(_optionalChain([authorizationCode, 'access', _ => _.split, 'call', _2 => _2("#"), 'access', _3 => _3[0], 'optionalAccess', _4 => _4.split, 'call', _5 => _5("&"), 'access', _6 => _6[0]]), () => ( authorizationCode));
342
+ const code = _nullishCoalesce(_optionalChain([authorizationCode, 'access', _3 => _3.split, 'call', _4 => _4("#"), 'access', _5 => _5[0], 'optionalAccess', _6 => _6.split, 'call', _7 => _7("&"), 'access', _8 => _8[0]]), () => ( authorizationCode));
169
343
  const data = await postJson(
170
344
  fetchImpl,
171
345
  CLAUDE_OAUTH_CONFIG.tokenEndpoint,
@@ -186,12 +360,12 @@ async function exchangeCodeForTokens(request, fetchImpl) {
186
360
  // helper read it from an untyped `data` and declared the field `string`.
187
361
  refreshToken: data.refresh_token,
188
362
  expiresIn: data.expires_in,
189
- scopes: _optionalChain([data, 'access', _7 => _7.scope, 'optionalAccess', _8 => _8.split, 'call', _9 => _9(" ")]) || CLAUDE_OAUTH_CONFIG.scopes
363
+ scopes: _optionalChain([data, 'access', _9 => _9.scope, 'optionalAccess', _10 => _10.split, 'call', _11 => _11(" ")]) || CLAUDE_OAUTH_CONFIG.scopes
190
364
  };
191
365
  }
192
366
  async function exchangeSetupTokenCode(request, fetchImpl) {
193
367
  const { authorizationCode, codeVerifier, state } = request;
194
- const code = _nullishCoalesce(_optionalChain([authorizationCode, 'access', _10 => _10.split, 'call', _11 => _11("#"), 'access', _12 => _12[0], 'optionalAccess', _13 => _13.split, 'call', _14 => _14("&"), 'access', _15 => _15[0]]), () => ( authorizationCode));
368
+ const code = _nullishCoalesce(_optionalChain([authorizationCode, 'access', _12 => _12.split, 'call', _13 => _13("#"), 'access', _14 => _14[0], 'optionalAccess', _15 => _15.split, 'call', _16 => _16("&"), 'access', _17 => _17[0]]), () => ( authorizationCode));
195
369
  const data = await postJson(
196
370
  fetchImpl,
197
371
  CLAUDE_OAUTH_CONFIG.tokenEndpoint,
@@ -209,10 +383,10 @@ async function exchangeSetupTokenCode(request, fetchImpl) {
209
383
  return {
210
384
  accessToken: data.access_token,
211
385
  expiresIn: data.expires_in,
212
- scopes: _optionalChain([data, 'access', _16 => _16.scope, 'optionalAccess', _17 => _17.split, 'call', _18 => _18(" ")]) || SETUP_TOKEN_CONFIG.scopes
386
+ scopes: _optionalChain([data, 'access', _18 => _18.scope, 'optionalAccess', _19 => _19.split, 'call', _20 => _20(" ")]) || SETUP_TOKEN_CONFIG.scopes
213
387
  };
214
388
  }
215
- async function refreshAccessToken(refreshToken, fetchImpl) {
389
+ async function refreshAccessToken2(refreshToken, fetchImpl) {
216
390
  const data = await postJson(
217
391
  fetchImpl,
218
392
  CLAUDE_OAUTH_CONFIG.tokenEndpoint,
@@ -236,7 +410,7 @@ var codex_exports = {};
236
410
  _chunk75ZPJI57cjs.__export.call(void 0, codex_exports, {
237
411
  exchangeCodeForTokens: () => exchangeCodeForTokens2,
238
412
  generateAuthParams: () => generateAuthParams2,
239
- refreshAccessToken: () => refreshAccessToken2
413
+ refreshAccessToken: () => refreshAccessToken3
240
414
  });
241
415
 
242
416
  var CODEX_OAUTH_CONFIG = {
@@ -286,7 +460,7 @@ async function exchangeCodeForTokens2(request, fetchImpl) {
286
460
  expiresIn: data.expires_in
287
461
  };
288
462
  }
289
- async function refreshAccessToken2(refreshToken, fetchImpl) {
463
+ async function refreshAccessToken3(refreshToken, fetchImpl) {
290
464
  const params = new URLSearchParams({
291
465
  grant_type: "refresh_token",
292
466
  client_id: CODEX_OAUTH_CONFIG.clientId,
@@ -312,7 +486,7 @@ var gemini_exports = {};
312
486
  _chunk75ZPJI57cjs.__export.call(void 0, gemini_exports, {
313
487
  exchangeCodeForTokens: () => exchangeCodeForTokens3,
314
488
  generateAuthParams: () => generateAuthParams3,
315
- refreshAccessToken: () => refreshAccessToken3
489
+ refreshAccessToken: () => refreshAccessToken4
316
490
  });
317
491
 
318
492
  var GEMINI_OAUTH_CONFIG = {
@@ -368,7 +542,7 @@ async function exchangeCodeForTokens3(authorizationCode, codeVerifier, fetchImpl
368
542
  expiresIn: data.expires_in
369
543
  };
370
544
  }
371
- async function refreshAccessToken3(refreshToken, fetchImpl) {
545
+ async function refreshAccessToken4(refreshToken, fetchImpl) {
372
546
  const params = new URLSearchParams({
373
547
  grant_type: "refresh_token",
374
548
  client_id: GEMINI_OAUTH_CONFIG.clientId,
@@ -391,4 +565,6 @@ async function refreshAccessToken3(refreshToken, fetchImpl) {
391
565
 
392
566
 
393
567
 
394
- exports.claude_exports = claude_exports; exports.codex_exports = codex_exports; exports.gemini_exports = gemini_exports;
568
+
569
+
570
+ exports.kimiFingerprintHeaders = kimiFingerprintHeaders; exports.kimi_exports = kimi_exports; exports.claude_exports = claude_exports; exports.codex_exports = codex_exports; exports.gemini_exports = gemini_exports;
@@ -2,6 +2,180 @@ import {
2
2
  __export
3
3
  } from "./chunk-MLKGABMK.js";
4
4
 
5
+ // src/oauth/flows/kimi.ts
6
+ var kimi_exports = {};
7
+ __export(kimi_exports, {
8
+ KIMI_CLI_VERSION: () => KIMI_CLI_VERSION,
9
+ KIMI_OAUTH_CONFIG: () => KIMI_OAUTH_CONFIG,
10
+ awaitDeviceToken: () => awaitDeviceToken,
11
+ generateKimiDeviceId: () => generateKimiDeviceId,
12
+ kimiAccountIdFromAccessToken: () => kimiAccountIdFromAccessToken,
13
+ kimiFingerprintHeaders: () => kimiFingerprintHeaders,
14
+ pollDeviceToken: () => pollDeviceToken,
15
+ refreshAccessToken: () => refreshAccessToken,
16
+ requestDeviceAuthorization: () => requestDeviceAuthorization
17
+ });
18
+ import crypto from "crypto";
19
+ import * as os from "os";
20
+ var KIMI_OAUTH_CONFIG = {
21
+ clientId: "17e5f671-d194-4dfb-9706-5516cb48c098",
22
+ deviceAuthorizationEndpoint: "https://auth.kimi.com/api/oauth/device_authorization",
23
+ tokenEndpoint: "https://auth.kimi.com/api/oauth/token"
24
+ };
25
+ var KIMI_CLI_VERSION = process.env["KIMI_CLI_VERSION"] ?? "1.0.0";
26
+ function sanitizeHeaderValue(value, fallback = "") {
27
+ const sanitized = value.replace(/[^\x20-\x7E]/g, "").trim();
28
+ return sanitized || fallback;
29
+ }
30
+ function deviceModel() {
31
+ const platform2 = os.platform();
32
+ const label = platform2 === "darwin" ? "macOS" : platform2 === "win32" ? "Windows" : platform2 === "linux" ? "Linux" : platform2;
33
+ return [label, os.release(), os.arch()].filter(Boolean).join(" ").trim();
34
+ }
35
+ function kimiFingerprintHeaders(deviceId) {
36
+ return {
37
+ "User-Agent": `KimiCLI/${KIMI_CLI_VERSION}`,
38
+ "X-Msh-Platform": "kimi_cli",
39
+ "X-Msh-Version": KIMI_CLI_VERSION,
40
+ "X-Msh-Device-Name": sanitizeHeaderValue(os.hostname(), "unknown"),
41
+ "X-Msh-Device-Model": sanitizeHeaderValue(deviceModel(), "unknown"),
42
+ "X-Msh-Os-Version": sanitizeHeaderValue(os.version(), "unknown"),
43
+ ...deviceId ? { "X-Msh-Device-Id": sanitizeHeaderValue(deviceId) } : {}
44
+ };
45
+ }
46
+ function generateKimiDeviceId() {
47
+ return crypto.randomUUID().replace(/-/g, "");
48
+ }
49
+ async function postFormRaw(fetchImpl, url, params, headers, timeoutMs = 3e4) {
50
+ const controller = new AbortController();
51
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
52
+ let response;
53
+ try {
54
+ response = await fetchImpl(url, {
55
+ method: "POST",
56
+ headers: { "Content-Type": "application/x-www-form-urlencoded", Accept: "application/json", ...headers },
57
+ body: params.toString(),
58
+ signal: controller.signal
59
+ });
60
+ } catch (error) {
61
+ if (controller.signal.aborted) throw new Error("token endpoint timed out");
62
+ throw error;
63
+ } finally {
64
+ clearTimeout(timer);
65
+ }
66
+ const text = await response.text();
67
+ let body;
68
+ try {
69
+ const parsed = JSON.parse(text);
70
+ body = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
71
+ } catch {
72
+ body = {};
73
+ }
74
+ return { status: response.status, body };
75
+ }
76
+ async function requestDeviceAuthorization(fetchImpl, fingerprint) {
77
+ const { status, body } = await postFormRaw(
78
+ fetchImpl,
79
+ KIMI_OAUTH_CONFIG.deviceAuthorizationEndpoint,
80
+ new URLSearchParams({ client_id: KIMI_OAUTH_CONFIG.clientId }),
81
+ fingerprint ?? {}
82
+ );
83
+ const userCode = typeof body["user_code"] === "string" ? body["user_code"] : void 0;
84
+ const deviceCode = typeof body["device_code"] === "string" ? body["device_code"] : void 0;
85
+ const verificationUri = typeof body["verification_uri"] === "string" ? body["verification_uri"] : void 0;
86
+ if (status >= 400 || !userCode || !deviceCode || !verificationUri) {
87
+ const message = typeof body["error_description"] === "string" ? body["error_description"] : typeof body["msg"] === "string" ? body["msg"] : `device authorization failed (HTTP ${status})`;
88
+ throw new Error(message);
89
+ }
90
+ return {
91
+ userCode,
92
+ deviceCode,
93
+ verificationUri,
94
+ ...typeof body["verification_uri_complete"] === "string" ? { verificationUriComplete: body["verification_uri_complete"] } : {},
95
+ ...typeof body["interval"] === "number" ? { interval: body["interval"] } : {},
96
+ ...typeof body["expires_in"] === "number" ? { expiresIn: body["expires_in"] } : {}
97
+ };
98
+ }
99
+ async function pollDeviceToken(deviceCode, fetchImpl, fingerprint) {
100
+ const { status, body } = await postFormRaw(
101
+ fetchImpl,
102
+ KIMI_OAUTH_CONFIG.tokenEndpoint,
103
+ new URLSearchParams({
104
+ grant_type: "urn:ietf:params:oauth:grant-type:device_code",
105
+ client_id: KIMI_OAUTH_CONFIG.clientId,
106
+ device_code: deviceCode
107
+ }),
108
+ fingerprint ?? {}
109
+ );
110
+ const accessToken = typeof body["access_token"] === "string" ? body["access_token"] : void 0;
111
+ const refreshToken = typeof body["refresh_token"] === "string" ? body["refresh_token"] : void 0;
112
+ if (accessToken && refreshToken) {
113
+ const expiresIn = typeof body["expires_in"] === "number" && body["expires_in"] > 0 ? body["expires_in"] : 3600;
114
+ return { state: "done", accessToken, refreshToken, expiresIn };
115
+ }
116
+ const error = typeof body["error"] === "string" ? body["error"] : void 0;
117
+ if (error === "authorization_pending") return { state: "pending" };
118
+ if (error === "slow_down") return { state: "pending", intervalSeconds: 5 };
119
+ if (status < 400 && !error) return { state: "pending" };
120
+ const message = typeof body["error_description"] === "string" && body["error_description"] ? body["error_description"] : error ?? `device token poll failed (HTTP ${status})`;
121
+ return { state: "failed", message };
122
+ }
123
+ async function awaitDeviceToken(authorization, fetchImpl, options = {}) {
124
+ const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
125
+ const deadline = Date.now() + (options.deadlineMs ?? 15 * 6e4);
126
+ const baseIntervalMs = options.intervalMs ?? (authorization.interval ?? 5) * 1e3;
127
+ let intervalMs = Math.max(1e3, baseIntervalMs);
128
+ for (; ; ) {
129
+ const result = await pollDeviceToken(authorization.deviceCode, fetchImpl, options.fingerprint);
130
+ if (result.state === "done") return result;
131
+ if (result.state === "failed") throw new Error(result.message);
132
+ if (result.state === "pending" && result.intervalSeconds) intervalMs += result.intervalSeconds * 1e3;
133
+ options.onPending?.();
134
+ if (Date.now() + intervalMs > deadline) throw new Error("device authorization timed out");
135
+ await sleep(intervalMs);
136
+ }
137
+ }
138
+ async function refreshAccessToken(refreshToken, fetchImpl, fingerprint) {
139
+ const { status, body } = await postFormRaw(
140
+ fetchImpl,
141
+ KIMI_OAUTH_CONFIG.tokenEndpoint,
142
+ new URLSearchParams({
143
+ grant_type: "refresh_token",
144
+ client_id: KIMI_OAUTH_CONFIG.clientId,
145
+ refresh_token: refreshToken
146
+ }),
147
+ fingerprint ?? {}
148
+ );
149
+ const accessToken = typeof body["access_token"] === "string" ? body["access_token"] : void 0;
150
+ if (status >= 400 || !accessToken) {
151
+ const message = typeof body["error_description"] === "string" && body["error_description"] ? body["error_description"] : typeof body["error"] === "string" ? body["error"] : `refresh failed (HTTP ${status})`;
152
+ throw new Error(message);
153
+ }
154
+ return {
155
+ accessToken,
156
+ // Kimi rotates the refresh token; keep the old one when the response omits it.
157
+ refreshToken: typeof body["refresh_token"] === "string" && body["refresh_token"] ? body["refresh_token"] : refreshToken,
158
+ expiresIn: typeof body["expires_in"] === "number" && body["expires_in"] > 0 ? body["expires_in"] : 3600
159
+ };
160
+ }
161
+ function kimiAccountIdFromAccessToken(accessToken) {
162
+ const parts = accessToken.split(".");
163
+ if (parts.length !== 3) return void 0;
164
+ try {
165
+ const json = Buffer.from(parts[1], "base64url").toString("utf8");
166
+ const claims = JSON.parse(json);
167
+ if (!claims || typeof claims !== "object" || Array.isArray(claims)) return void 0;
168
+ const record = claims;
169
+ for (const key of ["user_id", "sub"]) {
170
+ const value = record[key];
171
+ if (typeof value === "string" && value.trim()) return value.trim();
172
+ }
173
+ return void 0;
174
+ } catch {
175
+ return void 0;
176
+ }
177
+ }
178
+
5
179
  // src/oauth/flows/claude.ts
6
180
  var claude_exports = {};
7
181
  __export(claude_exports, {
@@ -9,9 +183,9 @@ __export(claude_exports, {
9
183
  exchangeSetupTokenCode: () => exchangeSetupTokenCode,
10
184
  generateAuthParams: () => generateAuthParams,
11
185
  generateSetupTokenParams: () => generateSetupTokenParams,
12
- refreshAccessToken: () => refreshAccessToken
186
+ refreshAccessToken: () => refreshAccessToken2
13
187
  });
14
- import crypto from "crypto";
188
+ import crypto2 from "crypto";
15
189
 
16
190
  // src/oauth/fetchPort.ts
17
191
  function errorMessage(error, errorDescription) {
@@ -128,9 +302,9 @@ var SETUP_TOKEN_CONFIG = {
128
302
  // Only inference permission, no API key creation
129
303
  };
130
304
  function generatePkce() {
131
- const codeVerifier = crypto.randomBytes(32).toString("base64url");
132
- const codeChallenge = crypto.createHash("sha256").update(codeVerifier).digest("base64url");
133
- const state = crypto.randomBytes(16).toString("hex");
305
+ const codeVerifier = crypto2.randomBytes(32).toString("base64url");
306
+ const codeChallenge = crypto2.createHash("sha256").update(codeVerifier).digest("base64url");
307
+ const state = crypto2.randomBytes(16).toString("hex");
134
308
  return { codeVerifier, codeChallenge, state };
135
309
  }
136
310
  function generateAuthParams() {
@@ -212,7 +386,7 @@ async function exchangeSetupTokenCode(request, fetchImpl) {
212
386
  scopes: data.scope?.split(" ") || SETUP_TOKEN_CONFIG.scopes
213
387
  };
214
388
  }
215
- async function refreshAccessToken(refreshToken, fetchImpl) {
389
+ async function refreshAccessToken2(refreshToken, fetchImpl) {
216
390
  const data = await postJson(
217
391
  fetchImpl,
218
392
  CLAUDE_OAUTH_CONFIG.tokenEndpoint,
@@ -236,9 +410,9 @@ var codex_exports = {};
236
410
  __export(codex_exports, {
237
411
  exchangeCodeForTokens: () => exchangeCodeForTokens2,
238
412
  generateAuthParams: () => generateAuthParams2,
239
- refreshAccessToken: () => refreshAccessToken2
413
+ refreshAccessToken: () => refreshAccessToken3
240
414
  });
241
- import crypto2 from "crypto";
415
+ import crypto3 from "crypto";
242
416
  var CODEX_OAUTH_CONFIG = {
243
417
  clientId: "app_EMoamEEZ73f0CkXaXp7hrann",
244
418
  authorizationEndpoint: "https://auth.openai.com/oauth/authorize",
@@ -247,9 +421,9 @@ var CODEX_OAUTH_CONFIG = {
247
421
  scopes: ["openid", "profile", "email", "offline_access"]
248
422
  };
249
423
  function generateAuthParams2() {
250
- const codeVerifier = crypto2.randomBytes(64).toString("hex");
251
- const codeChallenge = crypto2.createHash("sha256").update(codeVerifier).digest("base64url");
252
- const state = crypto2.randomBytes(16).toString("hex");
424
+ const codeVerifier = crypto3.randomBytes(64).toString("hex");
425
+ const codeChallenge = crypto3.createHash("sha256").update(codeVerifier).digest("base64url");
426
+ const state = crypto3.randomBytes(16).toString("hex");
253
427
  const params = new URLSearchParams({
254
428
  response_type: "code",
255
429
  client_id: CODEX_OAUTH_CONFIG.clientId,
@@ -286,7 +460,7 @@ async function exchangeCodeForTokens2(request, fetchImpl) {
286
460
  expiresIn: data.expires_in
287
461
  };
288
462
  }
289
- async function refreshAccessToken2(refreshToken, fetchImpl) {
463
+ async function refreshAccessToken3(refreshToken, fetchImpl) {
290
464
  const params = new URLSearchParams({
291
465
  grant_type: "refresh_token",
292
466
  client_id: CODEX_OAUTH_CONFIG.clientId,
@@ -312,9 +486,9 @@ var gemini_exports = {};
312
486
  __export(gemini_exports, {
313
487
  exchangeCodeForTokens: () => exchangeCodeForTokens3,
314
488
  generateAuthParams: () => generateAuthParams3,
315
- refreshAccessToken: () => refreshAccessToken3
489
+ refreshAccessToken: () => refreshAccessToken4
316
490
  });
317
- import crypto3 from "crypto";
491
+ import crypto4 from "crypto";
318
492
  var GEMINI_OAUTH_CONFIG = {
319
493
  clientId: "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com",
320
494
  // The Gemini CLI's *public* installed-app OAuth client secret (mirrors the
@@ -328,9 +502,9 @@ var GEMINI_OAUTH_CONFIG = {
328
502
  scopes: ["https://www.googleapis.com/auth/cloud-platform"]
329
503
  };
330
504
  function generateAuthParams3() {
331
- const codeVerifier = crypto3.randomBytes(32).toString("base64url");
332
- const codeChallenge = crypto3.createHash("sha256").update(codeVerifier).digest("base64url");
333
- const state = crypto3.randomBytes(16).toString("hex");
505
+ const codeVerifier = crypto4.randomBytes(32).toString("base64url");
506
+ const codeChallenge = crypto4.createHash("sha256").update(codeVerifier).digest("base64url");
507
+ const state = crypto4.randomBytes(16).toString("hex");
334
508
  const params = new URLSearchParams({
335
509
  client_id: GEMINI_OAUTH_CONFIG.clientId,
336
510
  redirect_uri: GEMINI_OAUTH_CONFIG.redirectUri,
@@ -368,7 +542,7 @@ async function exchangeCodeForTokens3(authorizationCode, codeVerifier, fetchImpl
368
542
  expiresIn: data.expires_in
369
543
  };
370
544
  }
371
- async function refreshAccessToken3(refreshToken, fetchImpl) {
545
+ async function refreshAccessToken4(refreshToken, fetchImpl) {
372
546
  const params = new URLSearchParams({
373
547
  grant_type: "refresh_token",
374
548
  client_id: GEMINI_OAUTH_CONFIG.clientId,
@@ -388,6 +562,8 @@ async function refreshAccessToken3(refreshToken, fetchImpl) {
388
562
  }
389
563
 
390
564
  export {
565
+ kimiFingerprintHeaders,
566
+ kimi_exports,
391
567
  claude_exports,
392
568
  codex_exports,
393
569
  gemini_exports