@kenkaiiii/gg-core 5.36.0 → 5.37.0

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.
package/dist/index.d.cts CHANGED
@@ -195,6 +195,43 @@ interface OAuthLoginCallbacks {
195
195
  * prefer OAuth for the logical `moonshot` provider.
196
196
  */
197
197
  declare const MOONSHOT_OAUTH_KEY = "moonshot-oauth";
198
+ /**
199
+ * Storage key for Grok (xAI) subscription OAuth credentials. Kept distinct from
200
+ * the `xai` API-key entry for the same reason as Kimi's: a user may configure
201
+ * BOTH — a SuperGrok/X Premium subscription plus a metered console key — and we
202
+ * always prefer OAuth for the logical `xai` provider.
203
+ */
204
+ declare const XAI_OAUTH_KEY = "xai-oauth";
205
+ /**
206
+ * A provider that can hold two credentials at once: a refreshable subscription
207
+ * OAuth token and a static API key. One policy governs all of them — see
208
+ * {@link DUAL_AUTH_PROVIDERS} — so adding a provider here is enough to give it
209
+ * OAuth-first resolution, usage-exhaustion fallback, per-method logout and the
210
+ * matching UI affordances.
211
+ */
212
+ interface DualAuthProvider {
213
+ /** Logical provider id, which is also the API-key storage key. */
214
+ provider: string;
215
+ /** Storage key holding the OAuth credential. */
216
+ oauthKey: string;
217
+ /** Human label for the OAuth credential (log/UI wording). */
218
+ oauthLabel: string;
219
+ /** Human label for the API-key credential (log/UI wording). */
220
+ apiKeyLabel: string;
221
+ /** What the user should do to restore OAuth after it went invalid. */
222
+ restoreHint: string;
223
+ }
224
+ /** Dual-auth policy for a logical provider, or undefined if it has just one method. */
225
+ declare function dualAuthProvider(provider: string): DualAuthProvider | undefined;
226
+ /** Dual-auth policy keyed by the OAuth storage key (the reverse lookup). */
227
+ declare function dualAuthProviderByOAuthKey(storageKey: string): DualAuthProvider | undefined;
228
+ /** The OAuth storage key for a dual-auth provider, if it has one. */
229
+ declare function oauthStorageKey(provider: string): string | undefined;
230
+ /**
231
+ * Both storage keys a dual-auth provider may hold, in resolution order
232
+ * (OAuth first). Single-method providers yield just their own key.
233
+ */
234
+ declare function providerStorageKeys(provider: string): string[];
198
235
  /**
199
236
  * Storage key for the Xiaomi API Credits credential (`https://api.xiaomimimo.com/v1`).
200
237
  * Kept distinct from the `xiaomi` Token Plan entry (`token-plan-sgp.xiaomimimo.com`)
@@ -224,6 +261,16 @@ declare class AuthStorage {
224
261
  private data;
225
262
  private filePath;
226
263
  private loaded;
264
+ /**
265
+ * mtime+size of the file as of the cached snapshot (`size: -1` = no file).
266
+ * auth.json is shared: the desktop app writes API keys and disconnects
267
+ * NATIVELY (so they work with no daemon running), and every window/process has
268
+ * its own AuthStorage. A load-once cache therefore goes stale — the sidecar
269
+ * would keep listing models for a provider just disconnected, and hide the
270
+ * ones just connected, until the daemon restarted.
271
+ */
272
+ private snapshotMtimeMs;
273
+ private snapshotSize;
227
274
  /** Per-provider lock to serialize concurrent refresh calls. */
228
275
  private refreshLocks;
229
276
  constructor(filePath?: string);
@@ -242,9 +289,9 @@ declare class AuthStorage {
242
289
  */
243
290
  pickStorageKey(keys: string[]): Promise<string | undefined>;
244
291
  /**
245
- * True if the user has any usable auth for the logical provider. For
246
- * `moonshot` this is satisfied by either the Kimi OAuth credential or the
247
- * Moonshot API key.
292
+ * True if the user has any usable auth for the logical provider. For a
293
+ * dual-auth provider (Kimi/Grok) either the OAuth credential or the API key
294
+ * satisfies it.
248
295
  */
249
296
  hasProviderAuth(provider: string): Promise<boolean>;
250
297
  /** Endpoint ids that currently have a `local:<id>` credential stored. */
@@ -259,20 +306,38 @@ declare class AuthStorage {
259
306
  removeLocalEndpoint(endpointId: string): Promise<void>;
260
307
  /**
261
308
  * True if the active credential for `provider` is a static API key with no
262
- * refresh mechanism. For `moonshot` this is only true when the Kimi OAuth
263
- * credential is absent (a present OAuth credential is refreshable).
309
+ * refresh mechanism. For a dual-auth provider this is only true when its OAuth
310
+ * credential is absent or sidelined (a live OAuth credential is refreshable).
264
311
  */
265
312
  isStaticApiKey(provider: string): Promise<boolean>;
266
313
  /**
267
314
  * The base URL on the credential that is active right now, if any.
268
315
  * Synchronous — call only after load()/resolveCredentials() populated the
269
- * snapshot. For `moonshot` this is the Kimi For Coding URL whenever the
270
- * OAuth entry is the one resolveCredentials would serve (i.e. not currently
271
- * usage-exhausted with an API key configured).
316
+ * snapshot. For a dual-auth provider this is the subscription endpoint (Kimi
317
+ * For Coding, the Grok CLI proxy) whenever the OAuth entry is the one
318
+ * resolveCredentials would serve (i.e. not currently usage-exhausted with an
319
+ * API key configured).
272
320
  */
273
321
  getStoredBaseUrl(provider: string): string | undefined;
274
322
  load(): Promise<void>;
275
323
  private ensureLoaded;
324
+ /**
325
+ * Like {@link ensureLoaded}, but re-reads when the file changed since this
326
+ * snapshot — a cheap stat, not a re-parse. Used by the "what is connected?"
327
+ * readers, which must reflect writes made by another window, the CLI, or the
328
+ * desktop app's native (daemon-free) API-key and disconnect paths.
329
+ *
330
+ * Deliberately NOT used by {@link resolveCredentials}: that path compares the
331
+ * caller's snapshot against the latest file to detect a concurrent re-login,
332
+ * and silently refreshing this instance's view first would destroy the
333
+ * evidence that the token it just had rejected has already been replaced.
334
+ */
335
+ private ensureFresh;
336
+ /**
337
+ * Record the file identity behind the current snapshot, so {@link ensureLoaded}
338
+ * can tell "someone else wrote" from "this is our own write".
339
+ */
340
+ private rememberSnapshot;
276
341
  /**
277
342
  * Apply one provider-scoped mutation to the latest on-disk snapshot.
278
343
  * AuthStorage instances live in every app session/process, so writing this
@@ -290,7 +355,7 @@ declare class AuthStorage {
290
355
  * `resetsAt` (unix SECONDS, from the provider's rate-limit response) or a
291
356
  * 15-minute default when no reset time is known. While the mark is in the
292
357
  * future, `resolveCredentials("moonshot")` serves the Moonshot API key
293
- * instead of the Kimi OAuth credential (when both are configured) — OAuth
358
+ * instead of the subscription OAuth credential (when both are configured) — OAuth
294
359
  * stays the preferred credential and is retried automatically once the mark
295
360
  * lapses. Persisted to auth.json so a restart (or another gg-app window)
296
361
  * doesn't burn a request rediscovering the same exhausted window. No-op if
@@ -411,6 +476,69 @@ declare function loginKimi(callbacks: OAuthLoginCallbacks): Promise<OAuthCredent
411
476
  /** Exchange a refresh token for a fresh Kimi access token. */
412
477
  declare function refreshKimiToken(refreshToken: string): Promise<OAuthCredentials>;
413
478
 
479
+ /**
480
+ * Grok (xAI) subscription OAuth — Device Authorization Grant (RFC 8628).
481
+ *
482
+ * Two form-encoded POST endpoints against xAI's OIDC issuer (`https://auth.x.ai`,
483
+ * advertised by its `/.well-known/openid-configuration`):
484
+ *
485
+ * - `/oauth2/device/code` (client_id + scope) → device + user code
486
+ * - `/oauth2/token` (grant_type=device_code) → poll until authorized
487
+ * - `/oauth2/token` (grant_type=refresh_token) → refresh access token
488
+ *
489
+ * Like Kimi (and unlike Anthropic/OpenAI/Gemini's browser-redirect PKCE) this is
490
+ * a device-code/poll flow: show a URL + code, the user authorizes in a browser on
491
+ * any device, we poll for the token. Deliberately chosen over the loopback PKCE
492
+ * variant because xAI pins the Grok-CLI client's redirect to
493
+ * `http://127.0.0.1:56121/callback` — a fixed port we cannot rebind if it's busy,
494
+ * and unreachable from a container/SSH session. Device code has neither problem.
495
+ *
496
+ * The issued token is used against the Grok CLI's chat proxy
497
+ * (`https://cli-chat-proxy.grok.com/v1`, distinct from the `api.x.ai` API-key
498
+ * endpoint) — that is the surface the `grok-cli:access` scope grants, and it
499
+ * bills against the user's SuperGrok / X Premium subscription instead of metered
500
+ * API credits. We persist that base URL on the credential so the runtime routes
501
+ * there automatically; `grokCliHeaders()` supplies the client identity the proxy
502
+ * requires (attached centrally in gg-ai's `xai` transport).
503
+ *
504
+ * Caveats worth knowing, both observed in the wild and surfaced to users rather
505
+ * than hidden here:
506
+ * - The client id below is xAI's public Grok-CLI desktop client (no secret).
507
+ * Every third-party implementation reuses it; xAI has not published a
508
+ * partner-client program, so subscription OAuth is a best-effort path.
509
+ * - xAI gates proxy access by subscription tier. A perfectly valid login can
510
+ * still be refused at inference time, which is exactly why `xai` keeps its
511
+ * API-key method as a fallback (see AuthStorage's dual-auth resolution).
512
+ */
513
+
514
+ /** Grok CLI chat-proxy base URL the issued OAuth token is used against. */
515
+ declare function grokCliBaseUrl(): string;
516
+ /**
517
+ * Headers the Grok CLI chat proxy requires on every model request. It serves
518
+ * only recognized Grok-CLI clients: without the token-auth marker and a client
519
+ * version it refuses the request. `modelId` populates the model-override header
520
+ * the proxy uses to route a request to the entitled model.
521
+ *
522
+ * Attach these ONLY to the proxy — the `api.x.ai` API-key path must not receive
523
+ * them (see {@link isGrokCliEndpoint}).
524
+ */
525
+ declare function grokCliHeaders(modelId?: string): Record<string, string>;
526
+ /**
527
+ * True if `baseUrl` targets the Grok CLI chat proxy (the URL persisted on Grok
528
+ * OAuth credentials). Callers use this to decide whether to attach
529
+ * {@link grokCliHeaders} and whether a usage/permission rejection should fall
530
+ * back to the xAI API key.
531
+ */
532
+ declare function isGrokCliEndpoint(baseUrl: string | undefined): boolean;
533
+ /**
534
+ * Drive the Grok device-code flow end-to-end. Shows the verification URL + user
535
+ * code via callbacks, opens the browser, and polls until the user authorizes or
536
+ * the device code expires (deadline set by the server).
537
+ */
538
+ declare function loginXai(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials>;
539
+ /** Exchange a refresh token for a fresh Grok access token. */
540
+ declare function refreshXaiToken(refreshToken: string): Promise<OAuthCredentials>;
541
+
414
542
  /**
415
543
  * Minimal Telegram Bot API client using raw fetch().
416
544
  * Supports long polling, markdown messages, inline keyboards, and message splitting.
@@ -584,4 +712,4 @@ interface AutoUpdater {
584
712
  }
585
713
  declare function createAutoUpdater(config: AutoUpdateConfig): AutoUpdater;
586
714
 
587
- export { AuthStorage, type AutoUpdateConfig, type AutoUpdater, DEFAULT_LOCAL_ENDPOINTS, type DiscoverOptions, type DiscoveryResult, FALLBACK_CONTEXT_WINDOW, type InlineButton, LOCAL_API_KEY_PLACEHOLDER, LOCAL_AUTH_KEY_PREFIX, type LocalEndpoint, type LocalEndpointKind, type LocalEndpointProbe, type LocalModel, type LogLevel, MOONSHOT_OAUTH_KEY, ModelInfo, NotLoggedInError, type OAuthCredentials, type OAuthLoginCallbacks, type ProbeOptions, type ProgressCallback, SubscriptionUsageError, type SubscriptionUsageProvider, type SubscriptionUsageSnapshot, type SubscriptionUsageWindow, TelegramBot, type TelegramConfig, type TelegramMessage, type TelegramUpdate, type TelegramVoiceMessage, XIAOMI_CREDITS_KEY, clearLocalDiscoveryCache, closeLogger, createAutoUpdater, decodeOggOpus, discoverLocalModels, downmixToMono, endpointRoot, fetchSubscriptionUsage, findProbedModel, formatLocalModelId, generatePKCE, getClaudeCliUserAgent, getClaudeCodeVersion, getNextThinkingLevel, getSessionId, getSupportedThinkingLevels, isKimiCodingEndpoint, isLocalModelId, isLoggerOpen, isModelLoaded, isThinkingLevelSupported, kimiCodeBaseUrl, kimiCodingHeaders, localAuthStorageKey, log, loginAnthropic, loginGemini, loginKimi, loginOpenAI, openLog, parseLocalModelId, probeEndpoint, readStoredBaseUrlSync, refreshAnthropicToken, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, registerLogCleanup, resample, setProgressCallback, toModelInfo, transcribeVoice, withFileLock };
715
+ export { AuthStorage, type AutoUpdateConfig, type AutoUpdater, DEFAULT_LOCAL_ENDPOINTS, type DiscoverOptions, type DiscoveryResult, type DualAuthProvider, FALLBACK_CONTEXT_WINDOW, type InlineButton, LOCAL_API_KEY_PLACEHOLDER, LOCAL_AUTH_KEY_PREFIX, type LocalEndpoint, type LocalEndpointKind, type LocalEndpointProbe, type LocalModel, type LogLevel, MOONSHOT_OAUTH_KEY, ModelInfo, NotLoggedInError, type OAuthCredentials, type OAuthLoginCallbacks, type ProbeOptions, type ProgressCallback, SubscriptionUsageError, type SubscriptionUsageProvider, type SubscriptionUsageSnapshot, type SubscriptionUsageWindow, TelegramBot, type TelegramConfig, type TelegramMessage, type TelegramUpdate, type TelegramVoiceMessage, XAI_OAUTH_KEY, XIAOMI_CREDITS_KEY, clearLocalDiscoveryCache, closeLogger, createAutoUpdater, decodeOggOpus, discoverLocalModels, downmixToMono, dualAuthProvider, dualAuthProviderByOAuthKey, endpointRoot, fetchSubscriptionUsage, findProbedModel, formatLocalModelId, generatePKCE, getClaudeCliUserAgent, getClaudeCodeVersion, getNextThinkingLevel, getSessionId, getSupportedThinkingLevels, grokCliBaseUrl, grokCliHeaders, isGrokCliEndpoint, isKimiCodingEndpoint, isLocalModelId, isLoggerOpen, isModelLoaded, isThinkingLevelSupported, kimiCodeBaseUrl, kimiCodingHeaders, localAuthStorageKey, log, loginAnthropic, loginGemini, loginKimi, loginOpenAI, loginXai, oauthStorageKey, openLog, parseLocalModelId, probeEndpoint, providerStorageKeys, readStoredBaseUrlSync, refreshAnthropicToken, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, refreshXaiToken, registerLogCleanup, resample, setProgressCallback, toModelInfo, transcribeVoice, withFileLock };
package/dist/index.d.ts CHANGED
@@ -195,6 +195,43 @@ interface OAuthLoginCallbacks {
195
195
  * prefer OAuth for the logical `moonshot` provider.
196
196
  */
197
197
  declare const MOONSHOT_OAUTH_KEY = "moonshot-oauth";
198
+ /**
199
+ * Storage key for Grok (xAI) subscription OAuth credentials. Kept distinct from
200
+ * the `xai` API-key entry for the same reason as Kimi's: a user may configure
201
+ * BOTH — a SuperGrok/X Premium subscription plus a metered console key — and we
202
+ * always prefer OAuth for the logical `xai` provider.
203
+ */
204
+ declare const XAI_OAUTH_KEY = "xai-oauth";
205
+ /**
206
+ * A provider that can hold two credentials at once: a refreshable subscription
207
+ * OAuth token and a static API key. One policy governs all of them — see
208
+ * {@link DUAL_AUTH_PROVIDERS} — so adding a provider here is enough to give it
209
+ * OAuth-first resolution, usage-exhaustion fallback, per-method logout and the
210
+ * matching UI affordances.
211
+ */
212
+ interface DualAuthProvider {
213
+ /** Logical provider id, which is also the API-key storage key. */
214
+ provider: string;
215
+ /** Storage key holding the OAuth credential. */
216
+ oauthKey: string;
217
+ /** Human label for the OAuth credential (log/UI wording). */
218
+ oauthLabel: string;
219
+ /** Human label for the API-key credential (log/UI wording). */
220
+ apiKeyLabel: string;
221
+ /** What the user should do to restore OAuth after it went invalid. */
222
+ restoreHint: string;
223
+ }
224
+ /** Dual-auth policy for a logical provider, or undefined if it has just one method. */
225
+ declare function dualAuthProvider(provider: string): DualAuthProvider | undefined;
226
+ /** Dual-auth policy keyed by the OAuth storage key (the reverse lookup). */
227
+ declare function dualAuthProviderByOAuthKey(storageKey: string): DualAuthProvider | undefined;
228
+ /** The OAuth storage key for a dual-auth provider, if it has one. */
229
+ declare function oauthStorageKey(provider: string): string | undefined;
230
+ /**
231
+ * Both storage keys a dual-auth provider may hold, in resolution order
232
+ * (OAuth first). Single-method providers yield just their own key.
233
+ */
234
+ declare function providerStorageKeys(provider: string): string[];
198
235
  /**
199
236
  * Storage key for the Xiaomi API Credits credential (`https://api.xiaomimimo.com/v1`).
200
237
  * Kept distinct from the `xiaomi` Token Plan entry (`token-plan-sgp.xiaomimimo.com`)
@@ -224,6 +261,16 @@ declare class AuthStorage {
224
261
  private data;
225
262
  private filePath;
226
263
  private loaded;
264
+ /**
265
+ * mtime+size of the file as of the cached snapshot (`size: -1` = no file).
266
+ * auth.json is shared: the desktop app writes API keys and disconnects
267
+ * NATIVELY (so they work with no daemon running), and every window/process has
268
+ * its own AuthStorage. A load-once cache therefore goes stale — the sidecar
269
+ * would keep listing models for a provider just disconnected, and hide the
270
+ * ones just connected, until the daemon restarted.
271
+ */
272
+ private snapshotMtimeMs;
273
+ private snapshotSize;
227
274
  /** Per-provider lock to serialize concurrent refresh calls. */
228
275
  private refreshLocks;
229
276
  constructor(filePath?: string);
@@ -242,9 +289,9 @@ declare class AuthStorage {
242
289
  */
243
290
  pickStorageKey(keys: string[]): Promise<string | undefined>;
244
291
  /**
245
- * True if the user has any usable auth for the logical provider. For
246
- * `moonshot` this is satisfied by either the Kimi OAuth credential or the
247
- * Moonshot API key.
292
+ * True if the user has any usable auth for the logical provider. For a
293
+ * dual-auth provider (Kimi/Grok) either the OAuth credential or the API key
294
+ * satisfies it.
248
295
  */
249
296
  hasProviderAuth(provider: string): Promise<boolean>;
250
297
  /** Endpoint ids that currently have a `local:<id>` credential stored. */
@@ -259,20 +306,38 @@ declare class AuthStorage {
259
306
  removeLocalEndpoint(endpointId: string): Promise<void>;
260
307
  /**
261
308
  * True if the active credential for `provider` is a static API key with no
262
- * refresh mechanism. For `moonshot` this is only true when the Kimi OAuth
263
- * credential is absent (a present OAuth credential is refreshable).
309
+ * refresh mechanism. For a dual-auth provider this is only true when its OAuth
310
+ * credential is absent or sidelined (a live OAuth credential is refreshable).
264
311
  */
265
312
  isStaticApiKey(provider: string): Promise<boolean>;
266
313
  /**
267
314
  * The base URL on the credential that is active right now, if any.
268
315
  * Synchronous — call only after load()/resolveCredentials() populated the
269
- * snapshot. For `moonshot` this is the Kimi For Coding URL whenever the
270
- * OAuth entry is the one resolveCredentials would serve (i.e. not currently
271
- * usage-exhausted with an API key configured).
316
+ * snapshot. For a dual-auth provider this is the subscription endpoint (Kimi
317
+ * For Coding, the Grok CLI proxy) whenever the OAuth entry is the one
318
+ * resolveCredentials would serve (i.e. not currently usage-exhausted with an
319
+ * API key configured).
272
320
  */
273
321
  getStoredBaseUrl(provider: string): string | undefined;
274
322
  load(): Promise<void>;
275
323
  private ensureLoaded;
324
+ /**
325
+ * Like {@link ensureLoaded}, but re-reads when the file changed since this
326
+ * snapshot — a cheap stat, not a re-parse. Used by the "what is connected?"
327
+ * readers, which must reflect writes made by another window, the CLI, or the
328
+ * desktop app's native (daemon-free) API-key and disconnect paths.
329
+ *
330
+ * Deliberately NOT used by {@link resolveCredentials}: that path compares the
331
+ * caller's snapshot against the latest file to detect a concurrent re-login,
332
+ * and silently refreshing this instance's view first would destroy the
333
+ * evidence that the token it just had rejected has already been replaced.
334
+ */
335
+ private ensureFresh;
336
+ /**
337
+ * Record the file identity behind the current snapshot, so {@link ensureLoaded}
338
+ * can tell "someone else wrote" from "this is our own write".
339
+ */
340
+ private rememberSnapshot;
276
341
  /**
277
342
  * Apply one provider-scoped mutation to the latest on-disk snapshot.
278
343
  * AuthStorage instances live in every app session/process, so writing this
@@ -290,7 +355,7 @@ declare class AuthStorage {
290
355
  * `resetsAt` (unix SECONDS, from the provider's rate-limit response) or a
291
356
  * 15-minute default when no reset time is known. While the mark is in the
292
357
  * future, `resolveCredentials("moonshot")` serves the Moonshot API key
293
- * instead of the Kimi OAuth credential (when both are configured) — OAuth
358
+ * instead of the subscription OAuth credential (when both are configured) — OAuth
294
359
  * stays the preferred credential and is retried automatically once the mark
295
360
  * lapses. Persisted to auth.json so a restart (or another gg-app window)
296
361
  * doesn't burn a request rediscovering the same exhausted window. No-op if
@@ -411,6 +476,69 @@ declare function loginKimi(callbacks: OAuthLoginCallbacks): Promise<OAuthCredent
411
476
  /** Exchange a refresh token for a fresh Kimi access token. */
412
477
  declare function refreshKimiToken(refreshToken: string): Promise<OAuthCredentials>;
413
478
 
479
+ /**
480
+ * Grok (xAI) subscription OAuth — Device Authorization Grant (RFC 8628).
481
+ *
482
+ * Two form-encoded POST endpoints against xAI's OIDC issuer (`https://auth.x.ai`,
483
+ * advertised by its `/.well-known/openid-configuration`):
484
+ *
485
+ * - `/oauth2/device/code` (client_id + scope) → device + user code
486
+ * - `/oauth2/token` (grant_type=device_code) → poll until authorized
487
+ * - `/oauth2/token` (grant_type=refresh_token) → refresh access token
488
+ *
489
+ * Like Kimi (and unlike Anthropic/OpenAI/Gemini's browser-redirect PKCE) this is
490
+ * a device-code/poll flow: show a URL + code, the user authorizes in a browser on
491
+ * any device, we poll for the token. Deliberately chosen over the loopback PKCE
492
+ * variant because xAI pins the Grok-CLI client's redirect to
493
+ * `http://127.0.0.1:56121/callback` — a fixed port we cannot rebind if it's busy,
494
+ * and unreachable from a container/SSH session. Device code has neither problem.
495
+ *
496
+ * The issued token is used against the Grok CLI's chat proxy
497
+ * (`https://cli-chat-proxy.grok.com/v1`, distinct from the `api.x.ai` API-key
498
+ * endpoint) — that is the surface the `grok-cli:access` scope grants, and it
499
+ * bills against the user's SuperGrok / X Premium subscription instead of metered
500
+ * API credits. We persist that base URL on the credential so the runtime routes
501
+ * there automatically; `grokCliHeaders()` supplies the client identity the proxy
502
+ * requires (attached centrally in gg-ai's `xai` transport).
503
+ *
504
+ * Caveats worth knowing, both observed in the wild and surfaced to users rather
505
+ * than hidden here:
506
+ * - The client id below is xAI's public Grok-CLI desktop client (no secret).
507
+ * Every third-party implementation reuses it; xAI has not published a
508
+ * partner-client program, so subscription OAuth is a best-effort path.
509
+ * - xAI gates proxy access by subscription tier. A perfectly valid login can
510
+ * still be refused at inference time, which is exactly why `xai` keeps its
511
+ * API-key method as a fallback (see AuthStorage's dual-auth resolution).
512
+ */
513
+
514
+ /** Grok CLI chat-proxy base URL the issued OAuth token is used against. */
515
+ declare function grokCliBaseUrl(): string;
516
+ /**
517
+ * Headers the Grok CLI chat proxy requires on every model request. It serves
518
+ * only recognized Grok-CLI clients: without the token-auth marker and a client
519
+ * version it refuses the request. `modelId` populates the model-override header
520
+ * the proxy uses to route a request to the entitled model.
521
+ *
522
+ * Attach these ONLY to the proxy — the `api.x.ai` API-key path must not receive
523
+ * them (see {@link isGrokCliEndpoint}).
524
+ */
525
+ declare function grokCliHeaders(modelId?: string): Record<string, string>;
526
+ /**
527
+ * True if `baseUrl` targets the Grok CLI chat proxy (the URL persisted on Grok
528
+ * OAuth credentials). Callers use this to decide whether to attach
529
+ * {@link grokCliHeaders} and whether a usage/permission rejection should fall
530
+ * back to the xAI API key.
531
+ */
532
+ declare function isGrokCliEndpoint(baseUrl: string | undefined): boolean;
533
+ /**
534
+ * Drive the Grok device-code flow end-to-end. Shows the verification URL + user
535
+ * code via callbacks, opens the browser, and polls until the user authorizes or
536
+ * the device code expires (deadline set by the server).
537
+ */
538
+ declare function loginXai(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials>;
539
+ /** Exchange a refresh token for a fresh Grok access token. */
540
+ declare function refreshXaiToken(refreshToken: string): Promise<OAuthCredentials>;
541
+
414
542
  /**
415
543
  * Minimal Telegram Bot API client using raw fetch().
416
544
  * Supports long polling, markdown messages, inline keyboards, and message splitting.
@@ -584,4 +712,4 @@ interface AutoUpdater {
584
712
  }
585
713
  declare function createAutoUpdater(config: AutoUpdateConfig): AutoUpdater;
586
714
 
587
- export { AuthStorage, type AutoUpdateConfig, type AutoUpdater, DEFAULT_LOCAL_ENDPOINTS, type DiscoverOptions, type DiscoveryResult, FALLBACK_CONTEXT_WINDOW, type InlineButton, LOCAL_API_KEY_PLACEHOLDER, LOCAL_AUTH_KEY_PREFIX, type LocalEndpoint, type LocalEndpointKind, type LocalEndpointProbe, type LocalModel, type LogLevel, MOONSHOT_OAUTH_KEY, ModelInfo, NotLoggedInError, type OAuthCredentials, type OAuthLoginCallbacks, type ProbeOptions, type ProgressCallback, SubscriptionUsageError, type SubscriptionUsageProvider, type SubscriptionUsageSnapshot, type SubscriptionUsageWindow, TelegramBot, type TelegramConfig, type TelegramMessage, type TelegramUpdate, type TelegramVoiceMessage, XIAOMI_CREDITS_KEY, clearLocalDiscoveryCache, closeLogger, createAutoUpdater, decodeOggOpus, discoverLocalModels, downmixToMono, endpointRoot, fetchSubscriptionUsage, findProbedModel, formatLocalModelId, generatePKCE, getClaudeCliUserAgent, getClaudeCodeVersion, getNextThinkingLevel, getSessionId, getSupportedThinkingLevels, isKimiCodingEndpoint, isLocalModelId, isLoggerOpen, isModelLoaded, isThinkingLevelSupported, kimiCodeBaseUrl, kimiCodingHeaders, localAuthStorageKey, log, loginAnthropic, loginGemini, loginKimi, loginOpenAI, openLog, parseLocalModelId, probeEndpoint, readStoredBaseUrlSync, refreshAnthropicToken, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, registerLogCleanup, resample, setProgressCallback, toModelInfo, transcribeVoice, withFileLock };
715
+ export { AuthStorage, type AutoUpdateConfig, type AutoUpdater, DEFAULT_LOCAL_ENDPOINTS, type DiscoverOptions, type DiscoveryResult, type DualAuthProvider, FALLBACK_CONTEXT_WINDOW, type InlineButton, LOCAL_API_KEY_PLACEHOLDER, LOCAL_AUTH_KEY_PREFIX, type LocalEndpoint, type LocalEndpointKind, type LocalEndpointProbe, type LocalModel, type LogLevel, MOONSHOT_OAUTH_KEY, ModelInfo, NotLoggedInError, type OAuthCredentials, type OAuthLoginCallbacks, type ProbeOptions, type ProgressCallback, SubscriptionUsageError, type SubscriptionUsageProvider, type SubscriptionUsageSnapshot, type SubscriptionUsageWindow, TelegramBot, type TelegramConfig, type TelegramMessage, type TelegramUpdate, type TelegramVoiceMessage, XAI_OAUTH_KEY, XIAOMI_CREDITS_KEY, clearLocalDiscoveryCache, closeLogger, createAutoUpdater, decodeOggOpus, discoverLocalModels, downmixToMono, dualAuthProvider, dualAuthProviderByOAuthKey, endpointRoot, fetchSubscriptionUsage, findProbedModel, formatLocalModelId, generatePKCE, getClaudeCliUserAgent, getClaudeCodeVersion, getNextThinkingLevel, getSessionId, getSupportedThinkingLevels, grokCliBaseUrl, grokCliHeaders, isGrokCliEndpoint, isKimiCodingEndpoint, isLocalModelId, isLoggerOpen, isModelLoaded, isThinkingLevelSupported, kimiCodeBaseUrl, kimiCodingHeaders, localAuthStorageKey, log, loginAnthropic, loginGemini, loginKimi, loginOpenAI, loginXai, oauthStorageKey, openLog, parseLocalModelId, probeEndpoint, providerStorageKeys, readStoredBaseUrlSync, refreshAnthropicToken, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, refreshXaiToken, registerLogCleanup, resample, setProgressCallback, toModelInfo, transcribeVoice, withFileLock };
package/dist/index.js CHANGED
@@ -5,9 +5,12 @@ import {
5
5
  MODELS,
6
6
  MOONSHOT_OAUTH_KEY,
7
7
  NotLoggedInError,
8
+ XAI_OAUTH_KEY,
8
9
  XIAOMI_CREDITS_KEY,
9
10
  clearRuntimeModels,
10
11
  closeLogger,
12
+ dualAuthProvider,
13
+ dualAuthProviderByOAuthKey,
11
14
  generatePKCE,
12
15
  getAllModels,
13
16
  getAuthStorageKey,
@@ -25,6 +28,9 @@ import {
25
28
  getSummaryModel,
26
29
  getToolResultCharLimit,
27
30
  getVideoByteLimit,
31
+ grokCliBaseUrl,
32
+ grokCliHeaders,
33
+ isGrokCliEndpoint,
28
34
  isKimiCodingEndpoint,
29
35
  isLoggerOpen,
30
36
  kimiCodeBaseUrl,
@@ -34,17 +40,21 @@ import {
34
40
  loginGemini,
35
41
  loginKimi,
36
42
  loginOpenAI,
43
+ loginXai,
44
+ oauthStorageKey,
37
45
  openLog,
46
+ providerStorageKeys,
38
47
  readStoredBaseUrlSync,
39
48
  refreshAnthropicToken,
40
49
  refreshGeminiToken,
41
50
  refreshKimiToken,
42
51
  refreshOpenAIToken,
52
+ refreshXaiToken,
43
53
  registerLogCleanup,
44
54
  registerRuntimeModels,
45
55
  usesOpenAICodexTransport,
46
56
  withFileLock
47
- } from "./chunk-C6Q3GFWE.js";
57
+ } from "./chunk-XDE6VUI4.js";
48
58
  import {
49
59
  getAppPaths
50
60
  } from "./chunk-EAIPT76S.js";
@@ -1117,6 +1127,7 @@ export {
1117
1127
  NotLoggedInError,
1118
1128
  SubscriptionUsageError,
1119
1129
  TelegramBot,
1130
+ XAI_OAUTH_KEY,
1120
1131
  XIAOMI_CREDITS_KEY,
1121
1132
  clearLocalDiscoveryCache,
1122
1133
  clearRuntimeModels,
@@ -1125,6 +1136,8 @@ export {
1125
1136
  decodeOggOpus,
1126
1137
  discoverLocalModels,
1127
1138
  downmixToMono,
1139
+ dualAuthProvider,
1140
+ dualAuthProviderByOAuthKey,
1128
1141
  endpointRoot,
1129
1142
  fetchSubscriptionUsage,
1130
1143
  findProbedModel,
@@ -1149,6 +1162,9 @@ export {
1149
1162
  getSupportedThinkingLevels,
1150
1163
  getToolResultCharLimit,
1151
1164
  getVideoByteLimit,
1165
+ grokCliBaseUrl,
1166
+ grokCliHeaders,
1167
+ isGrokCliEndpoint,
1152
1168
  isKimiCodingEndpoint,
1153
1169
  isLocalModelId,
1154
1170
  isLoggerOpen,
@@ -1162,14 +1178,18 @@ export {
1162
1178
  loginGemini,
1163
1179
  loginKimi,
1164
1180
  loginOpenAI,
1181
+ loginXai,
1182
+ oauthStorageKey,
1165
1183
  openLog,
1166
1184
  parseLocalModelId,
1167
1185
  probeEndpoint,
1186
+ providerStorageKeys,
1168
1187
  readStoredBaseUrlSync,
1169
1188
  refreshAnthropicToken,
1170
1189
  refreshGeminiToken,
1171
1190
  refreshKimiToken,
1172
1191
  refreshOpenAIToken,
1192
+ refreshXaiToken,
1173
1193
  registerLogCleanup,
1174
1194
  registerRuntimeModels,
1175
1195
  resample,