@kenkaiiii/gg-core 5.94.0 → 5.95.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.
package/dist/index.d.cts CHANGED
@@ -200,13 +200,21 @@ interface OAuthCredentials {
200
200
  * scale the proactive-refresh threshold: short-lived tokens (e.g. Kimi's
201
201
  * 15-min access token) must refresh well before expiry, not 60s prior. */
202
202
  expiresIn?: number;
203
+ /** ChatGPT plan: the validated ID-token subject. Its presence routes OpenAI to the plan transport. */
203
204
  accountId?: string;
205
+ /** Retired Gemini Code Assist project ID; only read to recognise an old sign-in. */
204
206
  projectId?: string;
205
207
  baseUrl?: string;
208
+ /** ChatGPT plan: the client ID OpenAI issued at first sign-in (never `dynamic_agent_client`). */
209
+ clientId?: string;
210
+ /** ChatGPT plan: the last validated ID token, sent back as `id_token_hint`. */
211
+ idToken?: string;
212
+ /** ChatGPT plan: scopes the token response granted. */
213
+ scopes?: string[];
206
214
  /** ms timestamp until which this credential's usage window is exhausted.
207
215
  * Set by AuthStorage.markUsageExhausted() when the provider rejects with a
208
216
  * usage/quota stop; while in the future, resolution may skip this credential
209
- * in favor of a configured fallback (e.g. Kimi OAuth → Moonshot API key). */
217
+ * in favor of a configured fallback (e.g. ChatGPT plan → OpenAI API key). */
210
218
  usageExhaustedUntil?: number;
211
219
  }
212
220
  interface OAuthLoginCallbacks {
@@ -318,21 +326,41 @@ declare function claudeCodeCallbackUrl(manualUrl: string, captured: string): str
318
326
  declare function loginClaudeCode(callbacks: OAuthLoginCallbacks, opts?: ClaudeCodeRunOptions): Promise<void>;
319
327
 
320
328
  /**
321
- * Storage key for Kimi Code OAuth credentials. Kept distinct from the
322
- * `moonshot` API-key entry so a user can configure BOTH and we always
323
- * prefer OAuth for the logical `moonshot` provider.
329
+ * Storage key for the ChatGPT plan sign-in (Continue with ChatGPT). Kept
330
+ * distinct from the `openai` entry, which holds an OpenAI API key, so a user can
331
+ * hold both: the plan serves first and the key covers while its usage is out.
324
332
  */
325
- declare const MOONSHOT_OAUTH_KEY = "moonshot-oauth";
333
+ declare const OPENAI_CHATGPT_KEY = "openai-chatgpt";
326
334
  /**
327
- * Storage key for Grok (xAI) subscription OAuth credentials. Kept distinct from
328
- * the `xai` API-key entry for the same reason as Kimi's: a user may configure
329
- * BOTH — a SuperGrok/X Premium subscription plus a metered console key — and we
330
- * always prefer OAuth for the logical `xai` provider.
335
+ * Storage key for a Kimi Code plan key (Kimi Code Console), served by
336
+ * `api.kimi.com/coding/v1` or `api.kimi.ai/coding/v1`. Kept distinct from the
337
+ * `moonshot` entry, which holds a pay-per-token Moonshot platform key.
331
338
  */
332
- declare const XAI_OAUTH_KEY = "xai-oauth";
339
+ declare const KIMI_CODE_KEY = "kimi-code";
333
340
  /**
334
- * A provider that can hold two credentials at once: a refreshable subscription
335
- * OAuth token and a static API key. One policy governs all of them — see
341
+ * A sign-in GG Coder no longer uses, because it posed as another vendor's app
342
+ * (Codex CLI, Kimi Code CLI, Grok CLI, Gemini CLI) or its token stopped
343
+ * working. The entry is never served; the user is asked once to reconnect.
344
+ */
345
+ interface RetiredSignIn {
346
+ /** Logical provider the credential belonged to. */
347
+ provider: string;
348
+ /** auth.json key holding the retired credential. */
349
+ storageKey: string;
350
+ /** What to tell the user, without CLI/app-specific instructions. */
351
+ message: string;
352
+ }
353
+ declare const RETIRED_SIGN_INS: readonly RetiredSignIn[];
354
+ /** Logical provider for a storage key (`kimi-code` → `moonshot`). */
355
+ declare function storageKeyProvider(storageKey: string): string;
356
+ /**
357
+ * API-key storage keys for a provider whose keys split into a plan key and a
358
+ * pay-per-token key, plan first. Single-key providers yield just their own key.
359
+ */
360
+ declare function apiKeyStorageKeys(provider: string): string[];
361
+ /**
362
+ * A provider that can hold two credentials at once: a refreshable plan sign-in
363
+ * and a static API key. One policy governs all of them — see
336
364
  * {@link DUAL_AUTH_PROVIDERS} — so adding a provider here is enough to give it
337
365
  * OAuth-first resolution, usage-exhaustion fallback, per-method logout and the
338
366
  * matching UI affordances.
@@ -372,9 +400,7 @@ declare const XIAOMI_CREDITS_KEY = "xiaomi-credits";
372
400
  /**
373
401
  * Storage key for a Gemini API key (Google AI Studio, billed per token), served
374
402
  * by the public Gemini API at {@link GEMINI_API_KEY_BASE_URL}. Kept distinct from
375
- * the `gemini` entry, which holds the Code Assist OAuth login: Google stopped
376
- * serving Code Assist to personal accounts on 2026-06-18, so an API key is how
377
- * those accounts reach Gemini at all, and a licensed account may hold both.
403
+ * the `gemini` entry, which held the retired Google sign-in.
378
404
  */
379
405
  declare const GEMINI_API_KEY = "gemini-api";
380
406
  /** Public Gemini API (AI Studio key). The transport routes on this base URL. */
@@ -415,9 +441,11 @@ declare class AuthStorage {
415
441
  private refreshLocks;
416
442
  private readonly detectMiniMaxRegion;
417
443
  private readonly detectXiaomiCluster;
444
+ private readonly detectKimiRegion;
418
445
  constructor(filePath?: string, options?: {
419
446
  detectMiniMaxBaseUrl?: (apiKey: string) => Promise<string | undefined>;
420
447
  detectXiaomiTokenPlanBaseUrl?: (apiKey: string) => Promise<string | undefined>;
448
+ detectKimiCodeBaseUrl?: (apiKey: string) => Promise<string | undefined>;
421
449
  });
422
450
  /** Path to the on-disk auth file. Useful for status output. */
423
451
  get path(): string;
@@ -434,20 +462,28 @@ declare class AuthStorage {
434
462
  */
435
463
  pickStorageKey(keys: string[]): Promise<string | undefined>;
436
464
  /**
437
- * True if the user has any usable auth for the logical provider. For a
438
- * dual-auth provider (Kimi/Grok) either the OAuth credential or the API key
439
- * satisfies it.
465
+ * True if the user has any usable auth for the logical provider: the plan
466
+ * sign-in or any of its API keys. A retired sign-in doesn't count.
440
467
  */
441
468
  hasProviderAuth(provider: string): Promise<boolean>;
469
+ /** True if any of `provider`'s API keys is stored. A retired sign-in in a key slot doesn't count. */
470
+ hasApiKey(provider: string): Promise<boolean>;
471
+ /**
472
+ * `provider`'s first stored API key, never its plan sign-in. For calls that
473
+ * only an API key may make (OpenAI's Images API isn't on the ChatGPT plan).
474
+ */
475
+ resolveApiKey(provider: string): Promise<OAuthCredentials>;
442
476
  /** True when the user signed in with Claude through Claude Code (marker only, no token). */
443
477
  hasClaudeCodeLogin(): Promise<boolean>;
444
478
  /** Record a Claude Code sign-in. Claude Code keeps the token; auth.json gets only the marker. */
445
479
  setClaudeCodeLogin(): Promise<void>;
480
+ /** Retired sign-ins still on disk, so the UI can ask the user to reconnect. */
481
+ legacySignIns(): Promise<RetiredSignIn[]>;
446
482
  /**
447
- * Remove an old GG Claude sign-in token (`sk-ant-oat…`), if any. True when one
448
- * was removed, so the caller can tell the user once to sign in with Claude again.
483
+ * Remove `provider`'s retired sign-in, if any. True when one was removed, so
484
+ * the caller can tell the user once to reconnect.
449
485
  */
450
- takeLegacyClaudeSignIn(): Promise<boolean>;
486
+ takeLegacySignIn(provider: string): Promise<boolean>;
451
487
  clearClaudeCodeLogin(): Promise<void>;
452
488
  /** Endpoint ids that currently have a `local:<id>` credential stored. */
453
489
  listLocalEndpointIds(): Promise<string[]>;
@@ -468,10 +504,10 @@ declare class AuthStorage {
468
504
  /**
469
505
  * The base URL on the credential that is active right now, if any.
470
506
  * Synchronous — call only after load()/resolveCredentials() populated the
471
- * snapshot. For a dual-auth provider this is the subscription endpoint (Kimi
472
- * For Coding, the Grok CLI proxy) whenever the OAuth entry is the one
473
- * resolveCredentials would serve (i.e. not currently usage-exhausted with an
474
- * API key configured).
507
+ * snapshot. For a dual-auth provider this is the plan endpoint whenever the
508
+ * sign-in is the one resolveCredentials would serve (i.e. not currently
509
+ * usage-exhausted with an API key configured); for a plan/pay-per-token key
510
+ * split it is the plan key's endpoint when one is stored.
475
511
  */
476
512
  getStoredBaseUrl(provider: string): string | undefined;
477
513
  load(): Promise<void>;
@@ -510,7 +546,16 @@ declare class AuthStorage {
510
546
  * and was deleted as invalid.
511
547
  */
512
548
  private withMiniMaxRegion;
513
- setCredentials(provider: string, creds: OAuthCredentials): Promise<void>;
549
+ /**
550
+ * A Kimi Code key saved without an endpoint gets the host that issued it
551
+ * (`api.kimi.com` or `api.kimi.ai`), saved so the check runs once.
552
+ */
553
+ private withKimiRegion;
554
+ /**
555
+ * Store `creds` under `storageKey`. Connecting a provider again also removes
556
+ * its retired sign-in, which is what the reconnect notice asked for.
557
+ */
558
+ setCredentials(storageKey: string, creds: OAuthCredentials): Promise<void>;
514
559
  /**
515
560
  * After a 401, move a regional key to the cluster that issued it instead of
516
561
  * treating it as invalid. Only the Xiaomi Token Plan is regional: every key
@@ -524,9 +569,9 @@ declare class AuthStorage {
524
569
  * Mark the credential stored under `storageKey` as usage-exhausted until
525
570
  * `resetsAt` (unix SECONDS, from the provider's rate-limit response) or a
526
571
  * 15-minute default when no reset time is known. While the mark is in the
527
- * future, `resolveCredentials("moonshot")` serves the Moonshot API key
528
- * instead of the subscription OAuth credential (when both are configured) — OAuth
529
- * stays the preferred credential and is retried automatically once the mark
572
+ * future, `resolveCredentials("openai")` serves the OpenAI API key instead of
573
+ * the ChatGPT plan sign-in (when both are configured) — the plan stays the
574
+ * preferred credential and is retried automatically once the mark
530
575
  * lapses. Persisted to auth.json so a restart (or another gg-app window)
531
576
  * doesn't burn a request rediscovering the same exhausted window. No-op if
532
577
  * nothing is stored under `storageKey`.
@@ -577,7 +622,7 @@ declare function signInWithClaudeCode(auth: Pick<AuthStorage, "setClaudeCodeLogi
577
622
  /** Sign out of Claude Code and drop the marker. The marker goes even if `claude auth logout` fails. */
578
623
  declare function signOutOfClaudeCode(auth: Pick<AuthStorage, "clearClaudeCodeLogin">, opts?: ClaudeCodeRunOptions): Promise<void>;
579
624
 
580
- type SubscriptionUsageProvider = "anthropic" | "openai" | "moonshot";
625
+ type SubscriptionUsageProvider = "anthropic" | "moonshot";
581
626
  /** Providers whose usage endpoint we call with a token. Claude reports its own (claude-code/usage.ts). */
582
627
  type FetchedSubscriptionUsageProvider = Exclude<SubscriptionUsageProvider, "anthropic">;
583
628
  interface SubscriptionUsageWindow {
@@ -605,11 +650,11 @@ interface FetchSubscriptionUsageOptions {
605
650
  now?: () => number;
606
651
  }
607
652
  /**
608
- * Fetch subscription quota windows with an already-resolved OAuth credential.
653
+ * Fetch plan quota windows with an already-resolved plan credential.
609
654
  * Tokens stay server-side: callers expose only the normalized percentages and
610
655
  * reset timestamps to their UI.
611
656
  */
612
- declare function fetchSubscriptionUsage(provider: FetchedSubscriptionUsageProvider, credentials: Pick<OAuthCredentials, "accessToken" | "accountId">, options?: FetchSubscriptionUsageOptions): Promise<SubscriptionUsageSnapshot>;
657
+ declare function fetchSubscriptionUsage(provider: FetchedSubscriptionUsageProvider, credentials: Pick<OAuthCredentials, "accessToken" | "baseUrl">, options?: FetchSubscriptionUsageOptions): Promise<SubscriptionUsageSnapshot>;
613
658
 
614
659
  /** The parts of the SDK's `rate_limit_event.rate_limit_info` the usage meter reads. */
615
660
  interface ClaudeCodeRateLimitInfo {
@@ -679,19 +724,41 @@ declare function detectXiaomiTokenPlanBaseUrl(apiKey: string, options?: {
679
724
  timeoutMs?: number;
680
725
  }): Promise<string | undefined>;
681
726
 
727
+ /**
728
+ * Kimi Code plan keys come from the Kimi Code Console and work on the host
729
+ * that issued them: `api.kimi.com` (kimi.com accounts) or `api.kimi.ai`
730
+ * (kimi.ai accounts). The other host rejects the key as invalid.
731
+ */
732
+ declare const KIMI_CODE_DEFAULT_BASE_URL = "https://api.kimi.com/coding/v1";
733
+ declare const KIMI_CODE_OVERSEAS_BASE_URL = "https://api.kimi.ai/coding/v1";
734
+ /**
735
+ * The Kimi Code base URL for the host that issued `apiKey`, found by asking
736
+ * both. Undefined when neither gives a clear answer (offline, timeouts);
737
+ * callers then use {@link KIMI_CODE_DEFAULT_BASE_URL} and may ask again later.
738
+ */
739
+ declare function detectKimiCodeBaseUrl(apiKey: string, options?: {
740
+ fetch?: typeof fetch;
741
+ timeoutMs?: number;
742
+ }): Promise<string | undefined>;
743
+ /** True if `baseUrl` is a Kimi Code plan endpoint (either host). */
744
+ declare function isKimiCodingEndpoint(baseUrl: string | undefined): boolean;
745
+
682
746
  type AuthMethod = "oauth" | "apikey";
683
747
  /**
684
- * One API-key option for a provider that splits auth across multiple distinct
685
- * endpoints/credentials (currently only Xiaomi: Token Plan vs. API Credits).
686
- * Each variant stores under its own auth.json key so a user can hold both at
687
- * once — the model registry picks which one a given model resolves via
688
- * `getAuthStorageKeys()`.
748
+ * One API-key option for a provider that takes two kinds of key: a plan key
749
+ * (the user's subscription) and a pay-per-token key. Each variant stores under
750
+ * its own auth.json key so a user can hold both at once; the model registry
751
+ * picks which one a model resolves via `getAuthStorageKeys()`.
689
752
  */
690
753
  interface ApiKeyVariant {
691
754
  /** Storage key in auth.json (distinct from `value` when multiple variants exist). */
692
755
  key: string;
693
756
  /** Display label, e.g. "Token Plan" or "API Credits". */
694
757
  label: string;
758
+ /** `plan` bills the user's subscription; `payg` bills per token. */
759
+ kind: "plan" | "payg";
760
+ /** What the user spends with this key, e.g. "Uses your Kimi Code plan." */
761
+ billing: string;
695
762
  /** Base URL stored alongside this variant's credential. */
696
763
  baseUrl?: string;
697
764
  }
@@ -709,17 +776,12 @@ interface AuthProviderMeta {
709
776
  /** Fixed base URL stored alongside an API key (e.g. Xiaomi's token plan). */
710
777
  apiKeyBaseUrl?: string;
711
778
  /**
712
- * When a provider's API-key auth splits across multiple endpoints, the
713
- * choices to present (in order). The first variant is the default. Absent
714
- * for every provider with a single API-key credential.
779
+ * When a provider takes both a plan key and a pay-per-token key, the choices
780
+ * to present (in order). The first variant is the default.
715
781
  */
716
782
  apiKeyVariants?: ApiKeyVariant[];
717
- /**
718
- * Per-method guidance overrides. Only providers whose methods differ in
719
- * billing/entitlement (the dual-auth ones) need these; everything else is
720
- * described generically by {@link describeAuthMethods}.
721
- */
722
- methodDetails?: Partial<Record<AuthMethod, AuthMethodMeta>>;
783
+ /** What each method means for this provider (billing, when to pick it). */
784
+ methodDetails: Partial<Record<AuthMethod, AuthMethodMeta>>;
723
785
  }
724
786
  /**
725
787
  * What one auth method means for a provider, so both UIs can answer "which do I
@@ -727,7 +789,7 @@ interface AuthProviderMeta {
727
789
  */
728
790
  interface AuthMethodMeta {
729
791
  method: AuthMethod;
730
- /** Button/row label, e.g. "Sign in with Grok (SuperGrok / X Premium)". */
792
+ /** Button/row label, e.g. "Continue with ChatGPT". */
731
793
  label: string;
732
794
  /** What the user spends on this method. */
733
795
  billing: string;
@@ -736,13 +798,18 @@ interface AuthMethodMeta {
736
798
  /** Prerequisite the user must already have, if any. */
737
799
  requires?: string;
738
800
  }
801
+ /**
802
+ * What a model needs when it runs only on some of its provider's keys (Kimi
803
+ * K2.8 Preview on a Kimi Code plan key, MiMo UltraSpeed on API Credits), named
804
+ * by the variants' labels. Undefined for a model any of the provider's keys runs.
805
+ */
806
+ declare function requiredKeyLabel(provider: string, storageKeys: string[]): string | undefined;
739
807
  /** Every provider a user can connect right now, in login-screen order. */
740
808
  declare const AUTH_PROVIDERS: AuthProviderMeta[];
741
809
  declare function getAuthProvider(value: string): AuthProviderMeta | undefined;
742
810
  /**
743
- * Per-method guidance for a provider, in resolution order. Providers with a
744
- * single method get a generic description; the dual-auth ones (Kimi, Grok) carry
745
- * explicit `methodDetails` because the choice changes what the user is billed.
811
+ * Per-method guidance for a provider, in resolution order. Every provider
812
+ * carries `methodDetails`; the generic fallback only covers a missing entry.
746
813
  */
747
814
  declare function describeAuthMethods(provider: string): AuthMethodMeta[];
748
815
  /**
@@ -760,120 +827,61 @@ declare function generatePKCE(): Promise<{
760
827
  challenge: string;
761
828
  }>;
762
829
 
763
- declare function loginOpenAI(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials>;
764
- declare function refreshOpenAIToken(refreshToken: string): Promise<OAuthCredentials>;
765
-
766
- declare function loginGemini(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials>;
767
- declare function refreshGeminiToken(refreshToken: string): Promise<OAuthCredentials>;
768
-
769
- /**
770
- * Kimi Code OAuth — Device Authorization Grant (RFC 8628).
771
- *
772
- * Mirrors MoonshotAI/kimi-code's managed-auth flow. Three form-encoded
773
- * POST endpoints against the OAuth host (default `https://auth.kimi.com`):
774
- *
775
- * - `/api/oauth/device_authorization` (client_id) → device + user code
776
- * - `/api/oauth/token` (grant_type=device_code) → poll until authorized
777
- * - `/api/oauth/token` (grant_type=refresh_token) → refresh access token
778
- *
779
- * Unlike Anthropic/OpenAI/Gemini (browser-redirect PKCE), this is a
780
- * device-code/poll flow: we show the user a URL + code, they authorize in a
781
- * browser on any device, and we poll for the token.
782
- *
783
- * After login the issued token is used against the managed coding API
784
- * (`https://api.kimi.com/coding/v1`, distinct from the `api.moonshot.ai`
785
- * API-key endpoint) via `Authorization: Bearer <access_token>`. We persist
786
- * that base URL on the credential so the runtime routes there automatically.
787
- */
788
-
789
- /** Managed coding API base URL the issued OAuth token is used against. */
790
- declare function kimiCodeBaseUrl(): string;
791
- /**
792
- * Headers the Kimi For Coding API requires on every model request. The
793
- * managed endpoint gates access to recognized coding agents: requests must
794
- * carry a `kimi_code_cli` platform identity and matching `User-Agent`, or the
795
- * server rejects with "only available for Coding Agents". Attach these to the
796
- * inference client's default headers whenever the Kimi OAuth token is used.
797
- */
798
- declare function kimiCodingHeaders(): Record<string, string>;
799
- /**
800
- * True if `baseUrl` targets the Kimi For Coding managed endpoint (the URL
801
- * persisted on Kimi OAuth credentials). Callers use this to decide whether to
802
- * attach `kimiCodingHeaders()` — the Moonshot API-key path uses a different
803
- * host and must NOT receive the coding-agent identity headers.
804
- */
805
- declare function isKimiCodingEndpoint(baseUrl: string | undefined): boolean;
830
+ /** The scope that lets GG Coder use the user's ChatGPT plan. */
831
+ declare const CHATGPT_PLAN_SCOPE = "chatgpt.tokens.use.direct";
832
+ /** Responses API base for ChatGPT plan inference. */
833
+ declare const CHATGPT_PLAN_BASE_URL = "https://api.openai.com/v1";
834
+ /** Where users review and limit what GG Coder may use of their plan. */
835
+ declare const CHATGPT_USAGE_URL = "https://chatgpt.com/settings/usage";
836
+ declare const CHATGPT_PLAN_NOT_ENABLED_MESSAGE = "ChatGPT plan use isn't enabled for GG Coder. Allow Use your ChatGPT plan, or add an OpenAI API key.";
837
+ /** A sign-in that worked but can't be used to bill the user's ChatGPT plan. */
838
+ declare class ChatGPTPlanNotEnabledError extends Error {
839
+ constructor();
840
+ }
841
+ interface ChatGPTLoginOptions {
842
+ /** Defaults to `~/.gg/openai-host-id`. */
843
+ hostIdFile?: string;
844
+ /** Defaults to `~/.gg/openai-chatgpt-client.json`. */
845
+ registrationFile?: string;
846
+ /** The current sign-in, if any: its ID token skips the account picker. */
847
+ previous?: Pick<OAuthCredentials, "idToken">;
848
+ }
849
+ /** This machine's stable `ext_agent_host_id`, created on first use. */
850
+ declare function getChatGPTHostId(file?: string): Promise<string>;
806
851
  /**
807
- * Drive the Kimi device-code flow end-to-end. Shows the verification URL +
808
- * user code via callbacks, opens the browser, and polls until the user
809
- * authorizes (or a 15-minute local timeout elapses).
852
+ * Continue with ChatGPT. Registers GG Coder for this ChatGPT account on first
853
+ * use (the user names and approves it in the browser), then reuses the issued
854
+ * client ID. Throws {@link ChatGPTPlanNotEnabledError} when the user signed in
855
+ * but didn't allow plan use.
810
856
  */
811
- declare function loginKimi(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials>;
812
- /** Exchange a refresh token for a fresh Kimi access token. */
813
- declare function refreshKimiToken(refreshToken: string): Promise<OAuthCredentials>;
814
-
857
+ declare function loginChatGPT(callbacks: OAuthLoginCallbacks, options?: ChatGPTLoginOptions): Promise<OAuthCredentials>;
815
858
  /**
816
- * Grok (xAI) subscription OAuth — Device Authorization Grant (RFC 8628).
817
- *
818
- * Two form-encoded POST endpoints against xAI's OIDC issuer (`https://auth.x.ai`,
819
- * advertised by its `/.well-known/openid-configuration`):
820
- *
821
- * - `/oauth2/device/code` (client_id + scope) → device + user code
822
- * - `/oauth2/token` (grant_type=device_code) → poll until authorized
823
- * - `/oauth2/token` (grant_type=refresh_token) → refresh access token
824
- *
825
- * Like Kimi (and unlike Anthropic/OpenAI/Gemini's browser-redirect PKCE) this is
826
- * a device-code/poll flow: show a URL + code, the user authorizes in a browser on
827
- * any device, we poll for the token. Deliberately chosen over the loopback PKCE
828
- * variant because xAI pins the Grok-CLI client's redirect to
829
- * `http://127.0.0.1:56121/callback` — a fixed port we cannot rebind if it's busy,
830
- * and unreachable from a container/SSH session. Device code has neither problem.
831
- *
832
- * The issued token is used against the Grok CLI's chat proxy
833
- * (`https://cli-chat-proxy.grok.com/v1`, distinct from the `api.x.ai` API-key
834
- * endpoint) — that is the surface the `grok-cli:access` scope grants, and it
835
- * bills against the user's SuperGrok / X Premium subscription instead of metered
836
- * API credits. We persist that base URL on the credential so the runtime routes
837
- * there automatically; `grokCliHeaders()` supplies the client identity the proxy
838
- * requires (attached centrally in gg-ai's `xai` transport).
839
- *
840
- * Caveats worth knowing, both observed in the wild and surfaced to users rather
841
- * than hidden here:
842
- * - The client id below is xAI's public Grok-CLI desktop client (no secret).
843
- * Every third-party implementation reuses it; xAI has not published a
844
- * partner-client program, so subscription OAuth is a best-effort path.
845
- * - xAI gates proxy access by subscription tier. A perfectly valid login can
846
- * still be refused at inference time, which is exactly why `xai` keeps its
847
- * API-key method as a fallback (see AuthStorage's dual-auth resolution).
848
- */
849
-
850
- /** Grok CLI chat-proxy base URL the issued OAuth token is used against. */
851
- declare function grokCliBaseUrl(): string;
852
- /**
853
- * Headers the Grok CLI chat proxy requires on every model request. It serves
854
- * only recognized Grok-CLI clients: without the token-auth marker and a client
855
- * version it refuses the request. `modelId` populates the model-override header
856
- * the proxy uses to route a request to the entitled model.
857
- *
858
- * Attach these ONLY to the proxy — the `api.x.ai` API-key path must not receive
859
- * them (see {@link isGrokCliEndpoint}).
859
+ * Model ids the signed-in ChatGPT account may use on its plan, from the same
860
+ * `/v1/models` catalog OpenAI tells apps to build their picker from. Hidden
861
+ * entries (`visibility` other than "list") are left out.
860
862
  */
861
- declare function grokCliHeaders(modelId?: string): Record<string, string>;
863
+ declare function fetchChatGPTPlanModels(accessToken: string, fetchFn?: typeof fetch): Promise<string[]>;
864
+ /** The callback query from a pasted URL or query string, or undefined for anything else. */
865
+ declare function parseCallbackInput(input: string): URLSearchParams | undefined;
862
866
  /**
863
- * True if `baseUrl` targets the Grok CLI chat proxy (the URL persisted on Grok
864
- * OAuth credentials). Callers use this to decide whether to attach
865
- * {@link grokCliHeaders} and whether a usage/permission rejection should fall
866
- * back to the xAI API key.
867
+ * Renew the plan token with the issued client ID. The response replaces the
868
+ * access token, its expiry, the granted scopes and the rotating refresh token.
867
869
  */
868
- declare function isGrokCliEndpoint(baseUrl: string | undefined): boolean;
870
+ declare function refreshChatGPTToken(creds: Pick<OAuthCredentials, "refreshToken" | "clientId">): Promise<OAuthCredentials>;
869
871
  /**
870
- * Drive the Grok device-code flow end-to-end. Shows the verification URL + user
871
- * code via callbacks, opens the browser, and polls until the user authorizes or
872
- * the device code expires (deadline set by the server).
872
+ * End the renewable session on sign-out. True when OpenAI confirmed it; callers
873
+ * clear local tokens either way and say so when it wasn't confirmed.
873
874
  */
874
- declare function loginXai(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials>;
875
- /** Exchange a refresh token for a fresh Grok access token. */
876
- declare function refreshXaiToken(refreshToken: string): Promise<OAuthCredentials>;
875
+ declare function revokeChatGPTSignIn(creds: Pick<OAuthCredentials, "refreshToken" | "clientId">, options?: {
876
+ attempts?: number;
877
+ backoffMs?: number;
878
+ }): Promise<boolean>;
879
+ /** Check the ID token's RS256 signature against OpenAI's JWKS, then iss, aud, exp and nonce. */
880
+ declare function verifyIdToken(idToken: string, expected: {
881
+ clientId: string;
882
+ nonce: string;
883
+ now?: number;
884
+ }): Promise<Record<string, unknown>>;
877
885
 
878
886
  /**
879
887
  * Minimal Telegram Bot API client using raw fetch().
@@ -1050,4 +1058,4 @@ interface AutoUpdater {
1050
1058
  }
1051
1059
  declare function createAutoUpdater(config: AutoUpdateConfig): AutoUpdater;
1052
1060
 
1053
- export { AUTH_PROVIDERS, type ApiKeyVariant, type AuthMethod, type AuthMethodMeta, type AuthProviderMeta, AuthStorage, type AutoUpdateConfig, type AutoUpdater, CLAUDE_CODE_AUTH_KEY, CLAUDE_CODE_AUTH_MARKER, CLAUDE_CODE_MANIFEST, type ClaudeCodeAuthStatus, type ClaudeCodeInstallProgress, type ClaudeCodeManifest, type ClaudeCodePlatformAsset, type ClaudeCodeRateLimitInfo, type ClaudeCodeRunOptions, type ClaudeCodeRuntimeOptions, type ClaudeCodeSignInOptions, DEFAULT_LOCAL_ENDPOINTS, type DiscoverOptions, type DiscoveryResult, type DualAuthProvider, type EnsureClaudeCodeOptions, FALLBACK_CONTEXT_WINDOW, type FetchedSubscriptionUsageProvider, GEMINI_API_KEY, GEMINI_API_KEY_BASE_URL, type InlineButton, LOCAL_API_KEY_PLACEHOLDER, LOCAL_AUTH_KEY_PREFIX, type LocalEndpoint, type LocalEndpointKind, type LocalEndpointProbe, type LocalModel, type LogLevel, MINIMAX_CN_BASE_URL, MINIMAX_GLOBAL_BASE_URL, MOONSHOT_OAUTH_KEY, ModelInfo, NotLoggedInError, type OAuthCredentials, type OAuthLoginCallbacks, OPENROUTER_DEFAULT_BASE_URL, PLAN_MODE_THINKING_CAP, type ParsedOpenRouterCatalog, 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, XIAOMI_TOKEN_PLAN_BASE_URLS, authPriorityNote, clampThinkingForPlanMode, claudeCodeAuthStatus, claudeCodeBinaryPath, claudeCodeCallbackUrl, claudeCodeConfigDir, claudeCodeEnv, claudeCodeHome, claudeCodePlatformKey, clearClaudeCodeUsage, clearLocalDiscoveryCache, closeLogger, createAutoUpdater, decodeOggOpus, describeAuthMethods, detectMiniMaxBaseUrl, detectXiaomiTokenPlanBaseUrl, discoverLocalModels, downmixToMono, dualAuthProvider, dualAuthProviderByOAuthKey, endpointRoot, ensureClaudeCodeBinary, fetchSubscriptionUsage, findProbedModel, formatClaudeCodeInstallProgress, formatLocalModelId, generatePKCE, getAuthProvider, getLowestThinkingLevel, getNextThinkingLevel, getSessionId, getSupportedThinkingLevels, grokCliBaseUrl, grokCliHeaders, isClaudeCodeAuthMarker, isGrokCliEndpoint, isKimiCodingEndpoint, isLegacyClaudeOAuth, isLocalModelId, isLoggerOpen, isModelLoaded, isThinkingLevelSupported, kimiCodeBaseUrl, kimiCodingHeaders, localAuthStorageKey, localModelShortName, log, loginClaudeCode, loginGemini, loginKimi, loginOpenAI, loginXai, logoutClaudeCode, mergeClaudeCodeRateLimit, oauthStorageKey, ollamaServedContext, openLog, parseLocalModelId, parseOpenRouterCatalog, probeEndpoint, providerStorageKeys, readClaudeCodeUsage, readStoredBaseUrlSync, recordClaudeCodeRateLimit, refreshGeminiToken, refreshKimiToken, refreshOpenAIToken, refreshXaiToken, registerLogCleanup, resample, resolveClaudeCodeBinary, setProgressCallback, signInWithClaudeCode, signOutOfClaudeCode, toModelInfo, transcribeVoice, withFileLock };
1061
+ export { AUTH_PROVIDERS, type ApiKeyVariant, type AuthMethod, type AuthMethodMeta, type AuthProviderMeta, AuthStorage, type AutoUpdateConfig, type AutoUpdater, CHATGPT_PLAN_BASE_URL, CHATGPT_PLAN_NOT_ENABLED_MESSAGE, CHATGPT_PLAN_SCOPE, CHATGPT_USAGE_URL, CLAUDE_CODE_AUTH_KEY, CLAUDE_CODE_AUTH_MARKER, CLAUDE_CODE_MANIFEST, type ChatGPTLoginOptions, ChatGPTPlanNotEnabledError, type ClaudeCodeAuthStatus, type ClaudeCodeInstallProgress, type ClaudeCodeManifest, type ClaudeCodePlatformAsset, type ClaudeCodeRateLimitInfo, type ClaudeCodeRunOptions, type ClaudeCodeRuntimeOptions, type ClaudeCodeSignInOptions, DEFAULT_LOCAL_ENDPOINTS, type DiscoverOptions, type DiscoveryResult, type DualAuthProvider, type EnsureClaudeCodeOptions, FALLBACK_CONTEXT_WINDOW, type FetchedSubscriptionUsageProvider, GEMINI_API_KEY, GEMINI_API_KEY_BASE_URL, type InlineButton, KIMI_CODE_DEFAULT_BASE_URL, KIMI_CODE_KEY, KIMI_CODE_OVERSEAS_BASE_URL, LOCAL_API_KEY_PLACEHOLDER, LOCAL_AUTH_KEY_PREFIX, type LocalEndpoint, type LocalEndpointKind, type LocalEndpointProbe, type LocalModel, type LogLevel, MINIMAX_CN_BASE_URL, MINIMAX_GLOBAL_BASE_URL, ModelInfo, NotLoggedInError, type OAuthCredentials, type OAuthLoginCallbacks, OPENAI_CHATGPT_KEY, OPENROUTER_DEFAULT_BASE_URL, PLAN_MODE_THINKING_CAP, type ParsedOpenRouterCatalog, type ProbeOptions, type ProgressCallback, RETIRED_SIGN_INS, type RetiredSignIn, SubscriptionUsageError, type SubscriptionUsageProvider, type SubscriptionUsageSnapshot, type SubscriptionUsageWindow, TelegramBot, type TelegramConfig, type TelegramMessage, type TelegramUpdate, type TelegramVoiceMessage, XIAOMI_CREDITS_KEY, XIAOMI_TOKEN_PLAN_BASE_URLS, apiKeyStorageKeys, authPriorityNote, clampThinkingForPlanMode, claudeCodeAuthStatus, claudeCodeBinaryPath, claudeCodeCallbackUrl, claudeCodeConfigDir, claudeCodeEnv, claudeCodeHome, claudeCodePlatformKey, clearClaudeCodeUsage, clearLocalDiscoveryCache, closeLogger, createAutoUpdater, decodeOggOpus, describeAuthMethods, detectKimiCodeBaseUrl, detectMiniMaxBaseUrl, detectXiaomiTokenPlanBaseUrl, discoverLocalModels, downmixToMono, dualAuthProvider, dualAuthProviderByOAuthKey, endpointRoot, ensureClaudeCodeBinary, fetchChatGPTPlanModels, fetchSubscriptionUsage, findProbedModel, formatClaudeCodeInstallProgress, formatLocalModelId, generatePKCE, getAuthProvider, getChatGPTHostId, getLowestThinkingLevel, getNextThinkingLevel, getSessionId, getSupportedThinkingLevels, isClaudeCodeAuthMarker, isKimiCodingEndpoint, isLegacyClaudeOAuth, isLocalModelId, isLoggerOpen, isModelLoaded, isThinkingLevelSupported, localAuthStorageKey, localModelShortName, log, loginChatGPT, loginClaudeCode, logoutClaudeCode, mergeClaudeCodeRateLimit, oauthStorageKey, ollamaServedContext, openLog, parseCallbackInput, parseLocalModelId, parseOpenRouterCatalog, probeEndpoint, providerStorageKeys, readClaudeCodeUsage, readStoredBaseUrlSync, recordClaudeCodeRateLimit, refreshChatGPTToken, registerLogCleanup, requiredKeyLabel, resample, resolveClaudeCodeBinary, revokeChatGPTSignIn, setProgressCallback, signInWithClaudeCode, signOutOfClaudeCode, storageKeyProvider, toModelInfo, transcribeVoice, verifyIdToken, withFileLock };