@omnicross/subscriptions 0.3.0 → 0.4.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
@@ -9,7 +9,7 @@ import { TransformerChainExecutor } from '@omnicross/core/transformer/Transforme
9
9
  import { TransformerService } from '@omnicross/core/transformer/TransformerService';
10
10
  import { Transformer } from '@omnicross/core/transformer/types';
11
11
  export { FetchLike } from '@omnicross/core/auth/GeminiCodeAssistProjectResolver';
12
- export { claudeOAuth, codexOAuth, geminiOAuth } from './oauth.cjs';
12
+ export { COPILOT_GITHUB_HEADERS, claudeOAuth, codexOAuth, copilotOAuth, geminiOAuth, grokOAuth, kimiFingerprintHeaders, kimiOAuth } from './oauth.cjs';
13
13
  import { ImageProvider } from '@omnicross/core/image-generation';
14
14
  import { ImageCapabilityEvidenceLayer, ImageQuality, ImageBackground, ImageOutputFormat, ImageModeration } from '@omnicross/contracts/image-generation-types';
15
15
 
@@ -49,6 +49,23 @@ interface SubscriptionCredentialStore {
49
49
  refreshCodexToken(): Promise<boolean>;
50
50
  /** Force a Gemini (Google) OAuth token refresh; `true` on success. */
51
51
  refreshGeminiToken(): Promise<boolean>;
52
+ /**
53
+ * Force a Kimi Code OAuth token refresh; `true` on success. OPTIONAL for
54
+ * lightweight test doubles (the kimi strategy catches its absence like a
55
+ * failed refresh) — the daemon's store implements it.
56
+ */
57
+ refreshKimiToken?(): Promise<boolean>;
58
+ /**
59
+ * Force a Grok (xAI SuperGrok) OAuth token refresh; `true` on success.
60
+ * OPTIONAL for lightweight test doubles (the grok strategy catches its
61
+ * absence like a failed refresh) — the daemon's store implements it.
62
+ */
63
+ refreshGrokToken?(): Promise<boolean>;
64
+ /**
65
+ * "Refresh" a GitHub Copilot token — a LOCAL no-op (ghu_ tokens are
66
+ * long-lived with no exchange endpoint). OPTIONAL like the others.
67
+ */
68
+ refreshCopilotToken?(): Promise<boolean>;
52
69
  /** Current valid OpenCodeGo static API key; `null` if none. */
53
70
  getValidOpenCodeGoApiKey(): Promise<string | null>;
54
71
  /**
@@ -351,6 +368,62 @@ declare class SubscriptionDispatcher {
351
368
  private buildRequestSummary;
352
369
  }
353
370
 
371
+ /**
372
+ * GitHub Copilot model-wire map — which of the catalog's three wires each
373
+ * served model rides, and the per-wire upstream path + provider transformer
374
+ * chain. Verified ids/wires from the audit source's frozen census; models are
375
+ * grouped by wire exactly as `SUBSCRIPTION_MODEL_CATALOG.copilot` lists them.
376
+ *
377
+ * The three faces live on ONE host (the Copilot API base):
378
+ * - anthropic-messages → `/v1/messages` (Claude family; same-format relay
379
+ * for Anthropic-shape clients — the URL suffix is what the core plan
380
+ * builder keys same-format detection on)
381
+ * - openai-responses → `/v1/responses`
382
+ * - openai chat → `/v1/chat/completions`
383
+ *
384
+ * @module @omnicross/subscriptions/copilot/models
385
+ */
386
+ /** The three Copilot wire shapes. */
387
+ type CopilotWire = 'anthropic' | 'responses' | 'chat';
388
+ /** Classify a resolved model id; UNKNOWN ids fall to the responses wire (the
389
+ * newest models land there first). */
390
+ declare function copilotWireFor(modelId: string): CopilotWire;
391
+ /** The per-wire upstream PATH under the Copilot API base. */
392
+ declare function copilotPathFor(wire: CopilotWire): string;
393
+ /** The per-wire provider transformer chain (mirrors the opencodego shape seam). */
394
+ declare function copilotTransformerNamesForWire(wire: CopilotWire): readonly string[];
395
+ /** Resolve the account-effective Copilot API base (discovered endpoint wins). */
396
+ declare function copilotBaseUrl(config: {
397
+ apiEndpoint?: string;
398
+ enterpriseUrl?: string;
399
+ } | undefined): string;
400
+ /**
401
+ * The GitHub REST base for an account (identity / quota / discovery probes).
402
+ * GHE domains route to `api.<domain>` — the data-residency plane convention
403
+ * (e.g. `company.ghe.com` → `api.company.ghe.com`); an explicit scheme or
404
+ * `api.` prefix is honored verbatim, personal accounts stay on api.github.com.
405
+ * Self-hosted GHES `/api/v3` path-style hosts are NOT derived here — pass the
406
+ * full `api.<host>` (or scheme-qualified) form via `enterpriseUrl`.
407
+ */
408
+ declare function copilotGitHubApiBase(enterpriseUrl?: string): string;
409
+
410
+ /**
411
+ * Default OpenCodeGo upstream URLs (both provider halves).
412
+ *
413
+ * There are two provider halves under the same account key:
414
+ * - GO (`opencode-go`): `https://opencode.ai/zen/go/v1/...` — chat + anthropic.
415
+ * - ZEN (`opencode-zen`): `https://opencode.ai/zen/v1/...` — chat + anthropic
416
+ * + responses + gemini (per-model colon-method).
417
+ *
418
+ * The user may override each half's host independently:
419
+ * - `OpenCodeGoTokenConfig.baseUrl` → GO half.
420
+ * - `OpenCodeGoTokenConfig.zenBaseUrl` → ZEN half.
421
+ * A go-half override NEVER redirects zen traffic and vice-versa.
422
+ */
423
+
424
+ /** Strip a trailing slash and `/v1[/]*` suffix from a user override host. */
425
+ declare function normalizeOpenCodeGoBaseUrl(base: string): string;
426
+
354
427
  /** Safe evidence request; accountId is trusted-process input and must not be logged. */
355
428
  interface CodexImageCapabilityEvidenceRequest {
356
429
  readonly accountId: string;
@@ -445,4 +518,4 @@ interface CodexImageLiveVerifier {
445
518
  }
446
519
  declare function createCodexImageLiveVerifier(options: CodexImageLiveVerifierOptions): CodexImageLiveVerifier;
447
520
 
448
- export { type CodexImageCapabilityEvidence, type CodexImageCapabilityEvidenceRequest, type CodexImageCapabilityEvidenceSource, type CodexImageCapabilityObservation, type CodexImageCapabilityObservedResponseFields, type CodexImageCapabilityTestedRequest, type CodexImageLiveVerificationRequest, type CodexImageLiveVerifier, type CodexImageLiveVerifierOptions, type CodexSubscriptionImageProviderOptions, DEFAULT_ACCOUNT_PRIORITY, type DispatchRequest, type DispatcherHooks, type ImageExecutionAccountKey, type ImageExecutionScheduler, type ImageExecutionSchedulerGrant, type ImageExecutionSchedulerRequest, LAST_USED_PERSIST_THROTTLE_MS, SESSION_AFFINITY_TTL_MS, type SchedulableAccount, type SelectInput, type SelectResult, SubscriptionAccountSelector, SubscriptionAccountService, type SubscriptionCredentialStore, SubscriptionDispatcher, SubscriptionProviderRegistry, createCodexImageLiveVerifier, createCodexSubscriptionImageProvider, getSubscriptionAccountService, getSubscriptionProviderRegistry, setSubscriptionAccountService, setSubscriptionProviderRegistry };
521
+ export { type CodexImageCapabilityEvidence, type CodexImageCapabilityEvidenceRequest, type CodexImageCapabilityEvidenceSource, type CodexImageCapabilityObservation, type CodexImageCapabilityObservedResponseFields, type CodexImageCapabilityTestedRequest, type CodexImageLiveVerificationRequest, type CodexImageLiveVerifier, type CodexImageLiveVerifierOptions, type CodexSubscriptionImageProviderOptions, DEFAULT_ACCOUNT_PRIORITY, type DispatchRequest, type DispatcherHooks, type ImageExecutionAccountKey, type ImageExecutionScheduler, type ImageExecutionSchedulerGrant, type ImageExecutionSchedulerRequest, LAST_USED_PERSIST_THROTTLE_MS, SESSION_AFFINITY_TTL_MS, type SchedulableAccount, type SelectInput, type SelectResult, SubscriptionAccountSelector, SubscriptionAccountService, type SubscriptionCredentialStore, SubscriptionDispatcher, SubscriptionProviderRegistry, copilotBaseUrl, copilotGitHubApiBase, copilotPathFor, copilotTransformerNamesForWire, copilotWireFor, createCodexImageLiveVerifier, createCodexSubscriptionImageProvider, getSubscriptionAccountService, getSubscriptionProviderRegistry, normalizeOpenCodeGoBaseUrl, setSubscriptionAccountService, setSubscriptionProviderRegistry };
package/dist/index.d.ts CHANGED
@@ -9,7 +9,7 @@ import { TransformerChainExecutor } from '@omnicross/core/transformer/Transforme
9
9
  import { TransformerService } from '@omnicross/core/transformer/TransformerService';
10
10
  import { Transformer } from '@omnicross/core/transformer/types';
11
11
  export { FetchLike } from '@omnicross/core/auth/GeminiCodeAssistProjectResolver';
12
- export { claudeOAuth, codexOAuth, geminiOAuth } from './oauth.js';
12
+ export { COPILOT_GITHUB_HEADERS, claudeOAuth, codexOAuth, copilotOAuth, geminiOAuth, grokOAuth, kimiFingerprintHeaders, kimiOAuth } from './oauth.js';
13
13
  import { ImageProvider } from '@omnicross/core/image-generation';
14
14
  import { ImageCapabilityEvidenceLayer, ImageQuality, ImageBackground, ImageOutputFormat, ImageModeration } from '@omnicross/contracts/image-generation-types';
15
15
 
@@ -49,6 +49,23 @@ interface SubscriptionCredentialStore {
49
49
  refreshCodexToken(): Promise<boolean>;
50
50
  /** Force a Gemini (Google) OAuth token refresh; `true` on success. */
51
51
  refreshGeminiToken(): Promise<boolean>;
52
+ /**
53
+ * Force a Kimi Code OAuth token refresh; `true` on success. OPTIONAL for
54
+ * lightweight test doubles (the kimi strategy catches its absence like a
55
+ * failed refresh) — the daemon's store implements it.
56
+ */
57
+ refreshKimiToken?(): Promise<boolean>;
58
+ /**
59
+ * Force a Grok (xAI SuperGrok) OAuth token refresh; `true` on success.
60
+ * OPTIONAL for lightweight test doubles (the grok strategy catches its
61
+ * absence like a failed refresh) — the daemon's store implements it.
62
+ */
63
+ refreshGrokToken?(): Promise<boolean>;
64
+ /**
65
+ * "Refresh" a GitHub Copilot token — a LOCAL no-op (ghu_ tokens are
66
+ * long-lived with no exchange endpoint). OPTIONAL like the others.
67
+ */
68
+ refreshCopilotToken?(): Promise<boolean>;
52
69
  /** Current valid OpenCodeGo static API key; `null` if none. */
53
70
  getValidOpenCodeGoApiKey(): Promise<string | null>;
54
71
  /**
@@ -351,6 +368,62 @@ declare class SubscriptionDispatcher {
351
368
  private buildRequestSummary;
352
369
  }
353
370
 
371
+ /**
372
+ * GitHub Copilot model-wire map — which of the catalog's three wires each
373
+ * served model rides, and the per-wire upstream path + provider transformer
374
+ * chain. Verified ids/wires from the audit source's frozen census; models are
375
+ * grouped by wire exactly as `SUBSCRIPTION_MODEL_CATALOG.copilot` lists them.
376
+ *
377
+ * The three faces live on ONE host (the Copilot API base):
378
+ * - anthropic-messages → `/v1/messages` (Claude family; same-format relay
379
+ * for Anthropic-shape clients — the URL suffix is what the core plan
380
+ * builder keys same-format detection on)
381
+ * - openai-responses → `/v1/responses`
382
+ * - openai chat → `/v1/chat/completions`
383
+ *
384
+ * @module @omnicross/subscriptions/copilot/models
385
+ */
386
+ /** The three Copilot wire shapes. */
387
+ type CopilotWire = 'anthropic' | 'responses' | 'chat';
388
+ /** Classify a resolved model id; UNKNOWN ids fall to the responses wire (the
389
+ * newest models land there first). */
390
+ declare function copilotWireFor(modelId: string): CopilotWire;
391
+ /** The per-wire upstream PATH under the Copilot API base. */
392
+ declare function copilotPathFor(wire: CopilotWire): string;
393
+ /** The per-wire provider transformer chain (mirrors the opencodego shape seam). */
394
+ declare function copilotTransformerNamesForWire(wire: CopilotWire): readonly string[];
395
+ /** Resolve the account-effective Copilot API base (discovered endpoint wins). */
396
+ declare function copilotBaseUrl(config: {
397
+ apiEndpoint?: string;
398
+ enterpriseUrl?: string;
399
+ } | undefined): string;
400
+ /**
401
+ * The GitHub REST base for an account (identity / quota / discovery probes).
402
+ * GHE domains route to `api.<domain>` — the data-residency plane convention
403
+ * (e.g. `company.ghe.com` → `api.company.ghe.com`); an explicit scheme or
404
+ * `api.` prefix is honored verbatim, personal accounts stay on api.github.com.
405
+ * Self-hosted GHES `/api/v3` path-style hosts are NOT derived here — pass the
406
+ * full `api.<host>` (or scheme-qualified) form via `enterpriseUrl`.
407
+ */
408
+ declare function copilotGitHubApiBase(enterpriseUrl?: string): string;
409
+
410
+ /**
411
+ * Default OpenCodeGo upstream URLs (both provider halves).
412
+ *
413
+ * There are two provider halves under the same account key:
414
+ * - GO (`opencode-go`): `https://opencode.ai/zen/go/v1/...` — chat + anthropic.
415
+ * - ZEN (`opencode-zen`): `https://opencode.ai/zen/v1/...` — chat + anthropic
416
+ * + responses + gemini (per-model colon-method).
417
+ *
418
+ * The user may override each half's host independently:
419
+ * - `OpenCodeGoTokenConfig.baseUrl` → GO half.
420
+ * - `OpenCodeGoTokenConfig.zenBaseUrl` → ZEN half.
421
+ * A go-half override NEVER redirects zen traffic and vice-versa.
422
+ */
423
+
424
+ /** Strip a trailing slash and `/v1[/]*` suffix from a user override host. */
425
+ declare function normalizeOpenCodeGoBaseUrl(base: string): string;
426
+
354
427
  /** Safe evidence request; accountId is trusted-process input and must not be logged. */
355
428
  interface CodexImageCapabilityEvidenceRequest {
356
429
  readonly accountId: string;
@@ -445,4 +518,4 @@ interface CodexImageLiveVerifier {
445
518
  }
446
519
  declare function createCodexImageLiveVerifier(options: CodexImageLiveVerifierOptions): CodexImageLiveVerifier;
447
520
 
448
- export { type CodexImageCapabilityEvidence, type CodexImageCapabilityEvidenceRequest, type CodexImageCapabilityEvidenceSource, type CodexImageCapabilityObservation, type CodexImageCapabilityObservedResponseFields, type CodexImageCapabilityTestedRequest, type CodexImageLiveVerificationRequest, type CodexImageLiveVerifier, type CodexImageLiveVerifierOptions, type CodexSubscriptionImageProviderOptions, DEFAULT_ACCOUNT_PRIORITY, type DispatchRequest, type DispatcherHooks, type ImageExecutionAccountKey, type ImageExecutionScheduler, type ImageExecutionSchedulerGrant, type ImageExecutionSchedulerRequest, LAST_USED_PERSIST_THROTTLE_MS, SESSION_AFFINITY_TTL_MS, type SchedulableAccount, type SelectInput, type SelectResult, SubscriptionAccountSelector, SubscriptionAccountService, type SubscriptionCredentialStore, SubscriptionDispatcher, SubscriptionProviderRegistry, createCodexImageLiveVerifier, createCodexSubscriptionImageProvider, getSubscriptionAccountService, getSubscriptionProviderRegistry, setSubscriptionAccountService, setSubscriptionProviderRegistry };
521
+ export { type CodexImageCapabilityEvidence, type CodexImageCapabilityEvidenceRequest, type CodexImageCapabilityEvidenceSource, type CodexImageCapabilityObservation, type CodexImageCapabilityObservedResponseFields, type CodexImageCapabilityTestedRequest, type CodexImageLiveVerificationRequest, type CodexImageLiveVerifier, type CodexImageLiveVerifierOptions, type CodexSubscriptionImageProviderOptions, DEFAULT_ACCOUNT_PRIORITY, type DispatchRequest, type DispatcherHooks, type ImageExecutionAccountKey, type ImageExecutionScheduler, type ImageExecutionSchedulerGrant, type ImageExecutionSchedulerRequest, LAST_USED_PERSIST_THROTTLE_MS, SESSION_AFFINITY_TTL_MS, type SchedulableAccount, type SelectInput, type SelectResult, SubscriptionAccountSelector, SubscriptionAccountService, type SubscriptionCredentialStore, SubscriptionDispatcher, SubscriptionProviderRegistry, copilotBaseUrl, copilotGitHubApiBase, copilotPathFor, copilotTransformerNamesForWire, copilotWireFor, createCodexImageLiveVerifier, createCodexSubscriptionImageProvider, getSubscriptionAccountService, getSubscriptionProviderRegistry, normalizeOpenCodeGoBaseUrl, setSubscriptionAccountService, setSubscriptionProviderRegistry };
package/dist/index.js CHANGED
@@ -1,8 +1,19 @@
1
1
  import {
2
+ COPILOT_API_HEADERS,
3
+ COPILOT_GITHUB_HEADERS,
2
4
  claude_exports,
3
5
  codex_exports,
4
- gemini_exports
5
- } from "./chunk-4HYDPKHR.js";
6
+ copilotBaseUrl,
7
+ copilotGitHubApiBase,
8
+ copilotPathFor,
9
+ copilotTransformerNamesForWire,
10
+ copilotWireFor,
11
+ copilot_exports,
12
+ gemini_exports,
13
+ grok_exports,
14
+ kimiFingerprintHeaders,
15
+ kimi_exports
16
+ } from "./chunk-L77HJY6V.js";
6
17
  import {
7
18
  accountSupportsModel,
8
19
  remapReportForAccount
@@ -125,13 +136,19 @@ var ACCOUNTS_KEY = {
125
136
  claude: "claudeAccounts",
126
137
  codex: "codexAccounts",
127
138
  gemini: "geminiAccounts",
128
- opencodego: "opencodegoAccounts"
139
+ opencodego: "opencodegoAccounts",
140
+ kimi: "kimiAccounts",
141
+ grok: "grokAccounts",
142
+ copilot: "copilotAccounts"
129
143
  };
130
144
  var ACTIVE_KEY = {
131
145
  claude: "activeClaudeAccountId",
132
146
  codex: "activeCodexAccountId",
133
147
  gemini: "activeGeminiAccountId",
134
- opencodego: "activeOpencodegoAccountId"
148
+ opencodego: "activeOpencodegoAccountId",
149
+ kimi: "activeKimiAccountId",
150
+ grok: "activeGrokAccountId",
151
+ copilot: "activeCopilotAccountId"
135
152
  };
136
153
  function gateSchedulable(accounts, providerId, health, now, resolvedModel, supportedModelsById) {
137
154
  if (!health && !resolvedModel || accounts.length < 2) return accounts;
@@ -421,13 +438,20 @@ var OAuthBearerAuthStrategy = class {
421
438
  return;
422
439
  }
423
440
  headers["Authorization"] = `Bearer ${token}`;
441
+ if (this.providerId === "kimi") {
442
+ const deviceId = await this.resolveKimiDeviceId(hints?.sessionKey);
443
+ Object.assign(headers, kimiFingerprintHeaders(deviceId));
444
+ }
445
+ if (this.providerId === "copilot") {
446
+ Object.assign(headers, COPILOT_API_HEADERS);
447
+ }
424
448
  }
425
449
  async onUnauthorized(sessionKey) {
426
450
  const byId = await refreshSelectedAccount(this.selector, this.tokens, this.mutex, this.providerId, sessionKey);
427
451
  if (byId !== null) return byId;
428
452
  return this.mutex.run(`${this.providerId}:refresh`, async () => {
429
453
  try {
430
- return this.providerId === "codex" ? await this.tokens.refreshCodexToken() : await this.tokens.refreshGeminiToken();
454
+ return this.refreshActive();
431
455
  } catch (err) {
432
456
  console.warn(`[OAuthBearerAuthStrategy] ${this.providerId} refresh failed:`, err);
433
457
  return false;
@@ -436,7 +460,7 @@ var OAuthBearerAuthStrategy = class {
436
460
  }
437
461
  async describeStatus() {
438
462
  const config = await this.tokens.getFullConfig();
439
- const entry = this.providerId === "codex" ? config.codex : config.gemini;
463
+ const entry = this.tokenBlock(config);
440
464
  if (!entry?.accessToken) {
441
465
  return { providerId: this.providerId, ok: false, reason: "missing-credential" };
442
466
  }
@@ -453,22 +477,61 @@ var OAuthBearerAuthStrategy = class {
453
477
  /** Read the current token, refreshing in-line if it's within the lead window. */
454
478
  async resolveAccessToken() {
455
479
  const config = await this.tokens.getFullConfig();
456
- const entry = this.providerId === "codex" ? config.codex : config.gemini;
480
+ const entry = this.tokenBlock(config);
457
481
  if (!entry?.accessToken) return null;
458
482
  const expiresAtMs = entry.expiresAt ? new Date(entry.expiresAt).getTime() : 0;
459
483
  const expiringSoon = expiresAtMs > 0 && Date.now() >= expiresAtMs - REFRESH_LEAD_MS;
460
484
  if (expiringSoon && entry.refreshToken) {
461
485
  const refreshed = await this.mutex.run(`${this.providerId}:refresh`, async () => {
462
- return this.providerId === "codex" ? await this.tokens.refreshCodexToken() : await this.tokens.refreshGeminiToken();
486
+ return this.refreshActive();
463
487
  });
464
488
  if (!refreshed) return null;
465
489
  const fresh = await this.tokens.getFullConfig();
466
- const freshEntry = this.providerId === "codex" ? fresh.codex : fresh.gemini;
467
- return freshEntry?.accessToken ?? null;
490
+ return this.tokenBlock(fresh)?.accessToken ?? null;
468
491
  }
469
492
  if (entry.status === "expired") return null;
470
493
  return entry.accessToken;
471
494
  }
495
+ /** The active account's refresh, dispatched per provider. */
496
+ refreshActive() {
497
+ switch (this.providerId) {
498
+ case "codex":
499
+ return this.tokens.refreshCodexToken();
500
+ case "gemini":
501
+ return this.tokens.refreshGeminiToken();
502
+ case "kimi":
503
+ return this.tokens.refreshKimiToken ? this.tokens.refreshKimiToken() : Promise.resolve(false);
504
+ case "grok":
505
+ return this.tokens.refreshGrokToken ? this.tokens.refreshGrokToken() : Promise.resolve(false);
506
+ case "copilot":
507
+ return this.tokens.refreshCopilotToken ? this.tokens.refreshCopilotToken() : Promise.resolve(false);
508
+ }
509
+ }
510
+ tokenBlock(config) {
511
+ switch (this.providerId) {
512
+ case "codex":
513
+ return config.codex;
514
+ case "gemini":
515
+ return config.gemini;
516
+ case "kimi":
517
+ return config.kimi;
518
+ case "grok":
519
+ return config.grok;
520
+ case "copilot":
521
+ return config.copilot;
522
+ }
523
+ }
524
+ /**
525
+ * Best-effort device id for the fingerprint header. Selection already ran in
526
+ * `applyHeaders`; rather than re-deriving it, read the active block's id (a
527
+ * pool-served non-active account momentarily reports the active id — the
528
+ * header is per-INSTALL identity, so this is cosmetic, not auth).
529
+ */
530
+ async resolveKimiDeviceId(_sessionKey) {
531
+ void _sessionKey;
532
+ const config = await this.tokens.getFullConfig();
533
+ return config.kimi?.deviceId ?? config.kimiAccounts?.[0]?.tokens.deviceId;
534
+ }
472
535
  };
473
536
 
474
537
  // src/auth/PassThroughAuthStrategy.ts
@@ -615,7 +678,10 @@ var DISPLAY_NAMES = {
615
678
  claude: "Claude (Anthropic OAuth)",
616
679
  codex: "Codex (ChatGPT OAuth)",
617
680
  gemini: "Gemini (Google OAuth)",
618
- opencodego: "OpenCodeGo (Bearer key)"
681
+ opencodego: "OpenCodeGo (Bearer key)",
682
+ kimi: "Kimi Code (Moonshot OAuth)",
683
+ grok: "Grok (xAI SuperGrok OAuth)",
684
+ copilot: "Copilot (GitHub OAuth)"
619
685
  };
620
686
  var SubscriptionAccountService = class {
621
687
  mutex = new RefreshMutex();
@@ -629,7 +695,10 @@ var SubscriptionAccountService = class {
629
695
  ["claude", new PassThroughAuthStrategy(tokens, this.mutex, this.selector, health)],
630
696
  ["codex", new OAuthBearerAuthStrategy("codex", tokens, this.mutex, this.selector, health)],
631
697
  ["gemini", new OAuthBearerAuthStrategy("gemini", tokens, this.mutex, this.selector, health)],
632
- ["opencodego", new StaticBearerAuthStrategy(tokens, this.selector, health)]
698
+ ["opencodego", new StaticBearerAuthStrategy(tokens, this.selector, health)],
699
+ ["kimi", new OAuthBearerAuthStrategy("kimi", tokens, this.mutex, this.selector, health)],
700
+ ["grok", new OAuthBearerAuthStrategy("grok", tokens, this.mutex, this.selector, health)],
701
+ ["copilot", new OAuthBearerAuthStrategy("copilot", tokens, this.mutex, this.selector, health)]
633
702
  ]);
634
703
  }
635
704
  /** Returns the strategy bound to a subscription provider, or `null` for unknown ids. */
@@ -1079,7 +1148,10 @@ var SubscriptionProviderRegistry = class {
1079
1148
  const codex = this.accounts.getStrategy("codex");
1080
1149
  const gemini = this.accounts.getStrategy("gemini");
1081
1150
  const opencodego = this.accounts.getStrategy("opencodego");
1082
- if (!claude || !codex || !gemini || !opencodego) {
1151
+ const kimi = this.accounts.getStrategy("kimi");
1152
+ const grok = this.accounts.getStrategy("grok");
1153
+ const copilot = this.accounts.getStrategy("copilot");
1154
+ if (!claude || !codex || !gemini || !opencodego || !kimi || !grok || !copilot) {
1083
1155
  throw new Error("[SubscriptionProviderRegistry] Missing strategy in SubscriptionAccountService");
1084
1156
  }
1085
1157
  this.profiles = /* @__PURE__ */ new Map([
@@ -1221,6 +1293,67 @@ var SubscriptionProviderRegistry = class {
1221
1293
  // profile sets it — claude / codex / gemini leave it UNSET (no-op).
1222
1294
  recordModelOutcome: (modelId, ok) => ok ? this.breaker.recordSuccess(modelId) : this.breaker.recordFailure(modelId)
1223
1295
  }
1296
+ ],
1297
+ [
1298
+ "kimi",
1299
+ {
1300
+ providerId: "kimi",
1301
+ displayName: "Kimi Code (Moonshot OAuth)",
1302
+ authStrategy: kimi,
1303
+ mode: "transformer",
1304
+ // Kimi Code's subscription surface speaks standard Anthropic Messages
1305
+ // at `api.kimi.com/coding/v1/messages` (plus an OpenAI chat face on
1306
+ // /chat/completions that a BYO kimi row already covers). The messages
1307
+ // URL ending in `/v1/messages` makes the core plan builder treat it as
1308
+ // same-format — the SDK's Anthropic body relays verbatim, with the
1309
+ // OAuth bearer + X-Msh-* fingerprint headers injected by the strategy.
1310
+ resolveUpstreamUrl: () => "https://api.kimi.com/coding/v1/messages",
1311
+ // Route-to only (Responses/Chat ingress): Unified → Anthropic Messages.
1312
+ providerTransformerNames: ["anthropic"],
1313
+ modelTransformerNames: []
1314
+ }
1315
+ ],
1316
+ [
1317
+ "grok",
1318
+ {
1319
+ providerId: "grok",
1320
+ displayName: "Grok (xAI SuperGrok OAuth)",
1321
+ authStrategy: grok,
1322
+ mode: "transformer",
1323
+ // SuperGrok's subscription surface speaks the OpenAI Responses API at
1324
+ // `api.x.ai/v1/responses` with the OAuth access token as Bearer (the
1325
+ // same token shape the paid API-key product uses on this endpoint).
1326
+ // Mirrors the codex profile: Unified → Responses via the
1327
+ // `openai-response` encoder; effort negotiation is capability-driven
1328
+ // (the omit-effort grok models carry `thinkingLevels: ['none']` in the
1329
+ // canonical registry, so `reasoning.effort` is never sent to them).
1330
+ resolveUpstreamUrl: () => "https://api.x.ai/v1/responses",
1331
+ providerTransformerNames: ["openai-response"],
1332
+ modelTransformerNames: []
1333
+ }
1334
+ ],
1335
+ [
1336
+ "copilot",
1337
+ {
1338
+ providerId: "copilot",
1339
+ displayName: "Copilot (GitHub OAuth)",
1340
+ authStrategy: copilot,
1341
+ mode: "transformer",
1342
+ // GitHub Copilot serves THREE wires on ONE host, per model (the
1343
+ // opencodego shape-seam pattern): the Claude family rides
1344
+ // anthropic-messages at `/v1/messages` (same-format verbatim relay
1345
+ // for Anthropic-shape clients), the GPT/Grok/mai-code families ride
1346
+ // Responses at `/v1/responses`, and the Gemini/Kimi/raptor families
1347
+ // ride chat-completions at `/v1/chat/completions`. The base honors
1348
+ // the account's discovered `apiEndpoint` (or GHE domain) via the
1349
+ // threaded config, defaulting to api.githubcopilot.com. The identity
1350
+ // header set (incl. X-GitHub-Api-Version, which unlocks long-context
1351
+ // tiers) is injected by the auth strategy.
1352
+ resolveUpstreamUrl: (model, config) => `${copilotBaseUrl(config)}${copilotPathFor(copilotWireFor(model))}`,
1353
+ resolveProviderTransformerNames: (model) => copilotTransformerNamesForWire(copilotWireFor(model)),
1354
+ providerTransformerNames: ["openai-response"],
1355
+ modelTransformerNames: []
1356
+ }
1224
1357
  ]
1225
1358
  ]);
1226
1359
  }
@@ -2534,6 +2667,7 @@ function createCodexImageLiveVerifier(options) {
2534
2667
  return new DefaultCodexImageLiveVerifier(options);
2535
2668
  }
2536
2669
  export {
2670
+ COPILOT_GITHUB_HEADERS,
2537
2671
  DEFAULT_ACCOUNT_PRIORITY,
2538
2672
  LAST_USED_PERSIST_THROTTLE_MS,
2539
2673
  SESSION_AFFINITY_TTL_MS,
@@ -2543,11 +2677,21 @@ export {
2543
2677
  SubscriptionProviderRegistry,
2544
2678
  claude_exports as claudeOAuth,
2545
2679
  codex_exports as codexOAuth,
2680
+ copilotBaseUrl,
2681
+ copilotGitHubApiBase,
2682
+ copilot_exports as copilotOAuth,
2683
+ copilotPathFor,
2684
+ copilotTransformerNamesForWire,
2685
+ copilotWireFor,
2546
2686
  createCodexImageLiveVerifier,
2547
2687
  createCodexSubscriptionImageProvider,
2548
2688
  gemini_exports as geminiOAuth,
2549
2689
  getSubscriptionAccountService,
2550
2690
  getSubscriptionProviderRegistry,
2691
+ grok_exports as grokOAuth,
2692
+ kimiFingerprintHeaders,
2693
+ kimi_exports as kimiOAuth,
2694
+ normalizeOpenCodeGoBaseUrl,
2551
2695
  setSubscriptionAccountService,
2552
2696
  setSubscriptionProviderRegistry
2553
2697
  };
package/dist/oauth.cjs CHANGED
@@ -2,10 +2,20 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkUXUMAXZJcjs = require('./chunk-UXUMAXZJ.cjs');
5
+
6
+
7
+
8
+
9
+
10
+ var _chunkQKWL53TJcjs = require('./chunk-QKWL53TJ.cjs');
6
11
  require('./chunk-75ZPJI57.cjs');
7
12
 
8
13
 
9
14
 
10
15
 
11
- exports.claudeOAuth = _chunkUXUMAXZJcjs.claude_exports; exports.codexOAuth = _chunkUXUMAXZJcjs.codex_exports; exports.geminiOAuth = _chunkUXUMAXZJcjs.gemini_exports;
16
+
17
+
18
+
19
+
20
+
21
+ exports.COPILOT_GITHUB_HEADERS = _chunkQKWL53TJcjs.COPILOT_GITHUB_HEADERS; exports.claudeOAuth = _chunkQKWL53TJcjs.claude_exports; exports.codexOAuth = _chunkQKWL53TJcjs.codex_exports; exports.copilotOAuth = _chunkQKWL53TJcjs.copilot_exports; exports.geminiOAuth = _chunkQKWL53TJcjs.gemini_exports; exports.grokOAuth = _chunkQKWL53TJcjs.grok_exports; exports.kimiFingerprintHeaders = _chunkQKWL53TJcjs.kimiFingerprintHeaders; exports.kimiOAuth = _chunkQKWL53TJcjs.kimi_exports;