@kenkaiiii/gg-core 5.92.0 → 5.94.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.js CHANGED
@@ -1,5 +1,8 @@
1
1
  import {
2
2
  AuthStorage,
3
+ CLAUDE_CODE_AUTH_KEY,
4
+ CLAUDE_CODE_AUTH_MARKER,
5
+ CLAUDE_CODE_MANIFEST,
3
6
  DEFAULT_MAX_VIDEO_BYTES,
4
7
  GEMINI_API_KEY,
5
8
  GEMINI_API_KEY_BASE_URL,
@@ -13,18 +16,25 @@ import {
13
16
  XAI_OAUTH_KEY,
14
17
  XIAOMI_CREDITS_KEY,
15
18
  XIAOMI_TOKEN_PLAN_BASE_URLS,
19
+ claudeCodeAuthStatus,
20
+ claudeCodeBinaryPath,
21
+ claudeCodeCallbackUrl,
22
+ claudeCodeConfigDir,
23
+ claudeCodeEnv,
24
+ claudeCodeHome,
25
+ claudeCodePlatformKey,
16
26
  clearRuntimeModels,
17
27
  closeLogger,
18
28
  detectMiniMaxBaseUrl,
19
29
  detectXiaomiTokenPlanBaseUrl,
20
30
  dualAuthProvider,
21
31
  dualAuthProviderByOAuthKey,
32
+ ensureClaudeCodeBinary,
33
+ formatClaudeCodeInstallProgress,
22
34
  generatePKCE,
23
35
  getAllModels,
24
36
  getAuthStorageKey,
25
37
  getAuthStorageKeys,
26
- getClaudeCliUserAgent,
27
- getClaudeCodeVersion,
28
38
  getContextWindow,
29
39
  getDefaultModel,
30
40
  getDefaultThinkingLevel,
@@ -39,39 +49,41 @@ import {
39
49
  getVideoByteLimit,
40
50
  grokCliBaseUrl,
41
51
  grokCliHeaders,
52
+ isClaudeCodeAuthMarker,
42
53
  isGrokCliEndpoint,
43
54
  isHiddenProvider,
44
55
  isKimiCodingEndpoint,
56
+ isLegacyClaudeOAuth,
45
57
  isLoggerOpen,
46
58
  isPaidModel,
47
59
  kimiCodeBaseUrl,
48
60
  kimiCodingHeaders,
49
61
  log,
50
- loginAnthropic,
62
+ loginClaudeCode,
51
63
  loginGemini,
52
64
  loginKimi,
53
65
  loginOpenAI,
54
66
  loginXai,
67
+ logoutClaudeCode,
55
68
  oauthStorageKey,
56
69
  openLog,
57
- pendingClaudeCodeVersionRefresh,
58
70
  providerStorageKeys,
59
71
  readStoredBaseUrlSync,
60
- refreshAnthropicToken,
61
72
  refreshGeminiToken,
62
73
  refreshKimiToken,
63
74
  refreshOpenAIToken,
64
75
  refreshXaiToken,
65
76
  registerLogCleanup,
66
77
  registerRuntimeModels,
78
+ resolveClaudeCodeBinary,
67
79
  setProviderCatalog,
68
80
  usesOpenAICodexTransport,
69
81
  withFileLock,
70
82
  withoutPaidTier
71
- } from "./chunk-SDUIKPGO.js";
83
+ } from "./chunk-JLEBGMG4.js";
72
84
  import {
73
85
  getAppPaths
74
- } from "./chunk-2X5L6U4Z.js";
86
+ } from "./chunk-GXOFTHM5.js";
75
87
 
76
88
  // src/openrouter-catalog.ts
77
89
  var OPENROUTER_DEFAULT_BASE_URL = "https://openrouter.ai/api/v1";
@@ -587,18 +599,138 @@ function findProbedModel(probes, modelId) {
587
599
  return void 0;
588
600
  }
589
601
 
602
+ // src/claude-code/usage.ts
603
+ import fsp from "fs/promises";
604
+ import path from "path";
605
+ var USAGE_FILE = "usage.json";
606
+ var WINDOWS = {
607
+ five_hour: { kind: "current", label: "5-hour" },
608
+ seven_day: { kind: "weekly", label: "Weekly" }
609
+ };
610
+ function finite(value) {
611
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
612
+ }
613
+ function toWindow(key, raw) {
614
+ const shape = WINDOWS[key];
615
+ const fraction = finite(raw?.utilization);
616
+ if (!shape || fraction === void 0) return null;
617
+ const resetsAt = finite(raw?.resetsAt);
618
+ return {
619
+ ...shape,
620
+ usedPercent: Math.min(100, Math.max(0, fraction * 100)),
621
+ ...resetsAt !== void 0 ? { resetsAt: resetsAt * 1e3 } : {}
622
+ };
623
+ }
624
+ function mergeClaudeCodeRateLimit(info, previous, now = Date.now()) {
625
+ const reported = info.unifiedWindows ? Object.entries(info.unifiedWindows).map(([key, raw]) => toWindow(key, raw)) : info.rateLimitType ? [toWindow(info.rateLimitType, info)] : [];
626
+ const byKind = new Map(previous?.windows.map((w) => [w.kind, w]) ?? []);
627
+ for (const window of reported) if (window) byKind.set(window.kind, window);
628
+ const windows = [...byKind.values()].sort(
629
+ (a, b) => a.kind === b.kind ? 0 : a.kind === "current" ? -1 : 1
630
+ );
631
+ return { provider: "anthropic", displayName: "Anthropic", windows, fetchedAt: now };
632
+ }
633
+ function usagePath(opts) {
634
+ return path.join(claudeCodeHome(opts), USAGE_FILE);
635
+ }
636
+ async function readClaudeCodeUsage(opts = {}) {
637
+ let parsed;
638
+ try {
639
+ parsed = JSON.parse(await fsp.readFile(usagePath(opts), "utf8"));
640
+ } catch {
641
+ return null;
642
+ }
643
+ if (!Array.isArray(parsed?.windows) || typeof parsed.fetchedAt !== "number") return null;
644
+ const now = opts.now ?? Date.now();
645
+ const windows = parsed.windows.filter(
646
+ (w) => (w.kind === "current" || w.kind === "weekly") && typeof w.usedPercent === "number" && (w.resetsAt === void 0 || w.resetsAt > now)
647
+ );
648
+ return { provider: "anthropic", displayName: "Anthropic", windows, fetchedAt: parsed.fetchedAt };
649
+ }
650
+ var writeQueue = Promise.resolve();
651
+ function recordClaudeCodeRateLimit(info, opts = {}) {
652
+ const write = async () => {
653
+ const now = opts.now ?? Date.now();
654
+ const next = mergeClaudeCodeRateLimit(info, await readClaudeCodeUsage({ ...opts, now }), now);
655
+ if (next.windows.length === 0) return;
656
+ const file = usagePath(opts);
657
+ await fsp.mkdir(path.dirname(file), { recursive: true });
658
+ await fsp.writeFile(file, JSON.stringify(next), "utf8");
659
+ };
660
+ writeQueue = writeQueue.then(write).catch(() => {
661
+ });
662
+ return writeQueue;
663
+ }
664
+ async function clearClaudeCodeUsage(opts = {}) {
665
+ await writeQueue;
666
+ await fsp.rm(usagePath(opts), { force: true }).catch(() => {
667
+ });
668
+ }
669
+
670
+ // src/claude-code/sign-in.ts
671
+ async function signInWithClaudeCode(auth, callbacks, opts = {}) {
672
+ if (!opts.binary && !resolveClaudeCodeBinary(opts)) {
673
+ callbacks.onStatus("Downloading Claude Code (one time)\u2026");
674
+ await ensureClaudeCodeBinary({
675
+ ...opts,
676
+ onProgress: (progress) => {
677
+ callbacks.onStatus(formatClaudeCodeInstallProgress(progress));
678
+ opts.onProgress?.(progress);
679
+ }
680
+ });
681
+ }
682
+ let status = await claudeCodeAuthStatus(opts);
683
+ if (!status.loggedIn) {
684
+ callbacks.onStatus("Opening Claude sign-in\u2026");
685
+ await loginClaudeCode(callbacks, opts);
686
+ status = await claudeCodeAuthStatus(opts);
687
+ }
688
+ if (!status.loggedIn) throw new Error("Claude sign-in didn't finish. Try again.");
689
+ await auth.setClaudeCodeLogin();
690
+ return status;
691
+ }
692
+ async function signOutOfClaudeCode(auth, opts = {}) {
693
+ await auth.clearClaudeCodeLogin();
694
+ await clearClaudeCodeUsage(opts);
695
+ try {
696
+ await logoutClaudeCode(opts);
697
+ } catch (err) {
698
+ log(
699
+ "WARN",
700
+ "auth",
701
+ `claude auth logout failed: ${err instanceof Error ? err.message : String(err)}`
702
+ );
703
+ }
704
+ }
705
+
590
706
  // src/auth-providers.ts
591
707
  var ALL_AUTH_PROVIDERS = [
592
708
  {
593
709
  value: "anthropic",
594
710
  label: "Anthropic",
595
711
  description: "Claude Fable 5.1, Opus 5.5, Opus 5.5 Fast, Sonnet 5.5, Haiku 5.5",
596
- methods: ["oauth"]
712
+ methods: ["oauth", "apikey"],
713
+ apiKeyLabel: "Anthropic",
714
+ methodDetails: {
715
+ oauth: {
716
+ method: "oauth",
717
+ label: "Sign in with Claude",
718
+ billing: "Uses your Claude Pro or Max plan.",
719
+ when: "Runs through Anthropic's Claude Code, which GG Coder downloads once (about 140 MB) the first time you pick this.",
720
+ requires: "A Claude Pro or Max subscription."
721
+ },
722
+ apikey: {
723
+ method: "apikey",
724
+ label: "Anthropic API key",
725
+ billing: "Pay-per-token from an Anthropic Console key.",
726
+ when: "No subscription needed. Used only while you are not signed in with Claude."
727
+ }
728
+ }
597
729
  },
598
730
  {
599
731
  value: "openai",
600
732
  label: "OpenAI",
601
- description: "GPT-6 Astra, GPT-6 Astra Fast, GPT-6.1 Sol, GPT-6.1 Sol Fast, GPT-6 Luna, GPT-6 Luna Fast",
733
+ description: "GPT-6 Astra, GPT-6 Astra Fast, GPT-6.1 Sol, GPT-6.1 Sol Fast, GPT-6.1 Terra, GPT-6.1 Terra Fast, GPT-6 Luna, GPT-6 Luna Fast",
602
734
  methods: ["oauth"]
603
735
  },
604
736
  {
@@ -761,6 +893,9 @@ function authPriorityNote(provider) {
761
893
  if (provider === "gemini") {
762
894
  return "Uses the Gemini API key first when one is set; otherwise the Google sign-in.";
763
895
  }
896
+ if (provider === "anthropic") {
897
+ return "Uses Sign in with Claude while you are signed in; otherwise the Anthropic API key.";
898
+ }
764
899
  const dual = dualAuthProvider(provider);
765
900
  if (!dual) return void 0;
766
901
  return `Uses ${dual.oauthLabel} first; the ${dual.apiKeyLabel} takes over when it runs out, then switches back.`;
@@ -775,7 +910,6 @@ var SubscriptionUsageError = class extends Error {
775
910
  this.name = "SubscriptionUsageError";
776
911
  }
777
912
  };
778
- var ANTHROPIC_USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
779
913
  var CODEX_USAGE_URL = "https://chatgpt.com/backend-api/wham/usage";
780
914
  function finiteNumber(value) {
781
915
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
@@ -843,45 +977,6 @@ async function readUsageResponse(response, now) {
843
977
  throw new SubscriptionUsageError("Subscription usage response was not valid JSON");
844
978
  }
845
979
  }
846
- async function fetchAnthropicUsage(credentials, fetchFn, signal, now) {
847
- const response = await fetchFn(ANTHROPIC_USAGE_URL, {
848
- method: "GET",
849
- signal,
850
- headers: {
851
- Authorization: `Bearer ${credentials.accessToken}`,
852
- Accept: "application/json",
853
- "anthropic-version": "2023-06-01",
854
- "anthropic-beta": "oauth-2025-04-20",
855
- "User-Agent": "ggcoder"
856
- }
857
- });
858
- const data = await readUsageResponse(response, now());
859
- const windows = [];
860
- const currentPercent = clampPercent(data.five_hour?.utilization);
861
- if (currentPercent !== void 0) {
862
- windows.push({
863
- kind: "current",
864
- label: "5-hour",
865
- usedPercent: currentPercent,
866
- resetsAt: isoTimestamp(data.five_hour?.resets_at)
867
- });
868
- }
869
- const weeklyPercent = clampPercent(data.seven_day?.utilization);
870
- if (weeklyPercent !== void 0) {
871
- windows.push({
872
- kind: "weekly",
873
- label: "Weekly",
874
- usedPercent: weeklyPercent,
875
- resetsAt: isoTimestamp(data.seven_day?.resets_at)
876
- });
877
- }
878
- return {
879
- provider: "anthropic",
880
- displayName: "Anthropic",
881
- windows,
882
- fetchedAt: now()
883
- };
884
- }
885
980
  async function fetchCodexUsage(credentials, fetchFn, signal, now) {
886
981
  const headers = {
887
982
  Authorization: `Bearer ${credentials.accessToken}`,
@@ -997,7 +1092,7 @@ async function fetchSubscriptionUsage(provider, credentials, options = {}) {
997
1092
  const now = options.now ?? Date.now;
998
1093
  const signal = AbortSignal.timeout(options.timeoutMs ?? 8e3);
999
1094
  try {
1000
- return provider === "anthropic" ? await fetchAnthropicUsage(credentials, fetchFn, signal, now) : provider === "openai" ? await fetchCodexUsage(credentials, fetchFn, signal, now) : await fetchKimiUsage(credentials, fetchFn, signal, now);
1095
+ return provider === "openai" ? await fetchCodexUsage(credentials, fetchFn, signal, now) : await fetchKimiUsage(credentials, fetchFn, signal, now);
1001
1096
  } catch (error) {
1002
1097
  if (error instanceof SubscriptionUsageError) throw error;
1003
1098
  const message = error instanceof Error ? error.message : String(error);
@@ -1335,7 +1430,7 @@ async function transcribeVoice(fileUrl) {
1335
1430
  // src/auto-update.ts
1336
1431
  import { spawn } from "child_process";
1337
1432
  import fs from "fs";
1338
- import path from "path";
1433
+ import path2 from "path";
1339
1434
  var CHECK_INTERVAL_MS = 60 * 60 * 1e3;
1340
1435
  var FETCH_TIMEOUT_MS = 1e4;
1341
1436
  function compareVersions(a, b) {
@@ -1377,7 +1472,7 @@ function createAutoUpdater(config) {
1377
1472
  function writeState(state) {
1378
1473
  try {
1379
1474
  const filePath = stateFilePath();
1380
- fs.mkdirSync(path.dirname(filePath), { recursive: true, mode: 448 });
1475
+ fs.mkdirSync(path2.dirname(filePath), { recursive: true, mode: 448 });
1381
1476
  fs.writeFileSync(filePath, JSON.stringify(state));
1382
1477
  } catch {
1383
1478
  }
@@ -1503,6 +1598,9 @@ function createAutoUpdater(config) {
1503
1598
  export {
1504
1599
  AUTH_PROVIDERS,
1505
1600
  AuthStorage,
1601
+ CLAUDE_CODE_AUTH_KEY,
1602
+ CLAUDE_CODE_AUTH_MARKER,
1603
+ CLAUDE_CODE_MANIFEST,
1506
1604
  DEFAULT_LOCAL_ENDPOINTS,
1507
1605
  DEFAULT_MAX_VIDEO_BYTES,
1508
1606
  FALLBACK_CONTEXT_WINDOW,
@@ -1525,6 +1623,14 @@ export {
1525
1623
  XIAOMI_TOKEN_PLAN_BASE_URLS,
1526
1624
  authPriorityNote,
1527
1625
  clampThinkingForPlanMode,
1626
+ claudeCodeAuthStatus,
1627
+ claudeCodeBinaryPath,
1628
+ claudeCodeCallbackUrl,
1629
+ claudeCodeConfigDir,
1630
+ claudeCodeEnv,
1631
+ claudeCodeHome,
1632
+ claudeCodePlatformKey,
1633
+ clearClaudeCodeUsage,
1528
1634
  clearLocalDiscoveryCache,
1529
1635
  clearRuntimeModels,
1530
1636
  closeLogger,
@@ -1538,8 +1644,10 @@ export {
1538
1644
  dualAuthProvider,
1539
1645
  dualAuthProviderByOAuthKey,
1540
1646
  endpointRoot,
1647
+ ensureClaudeCodeBinary,
1541
1648
  fetchSubscriptionUsage,
1542
1649
  findProbedModel,
1650
+ formatClaudeCodeInstallProgress,
1543
1651
  formatLocalModelId,
1544
1652
  generatePKCE,
1545
1653
  getAllModels,
@@ -1547,8 +1655,6 @@ export {
1547
1655
  getAuthProvider,
1548
1656
  getAuthStorageKey,
1549
1657
  getAuthStorageKeys,
1550
- getClaudeCliUserAgent,
1551
- getClaudeCodeVersion,
1552
1658
  getContextWindow,
1553
1659
  getDefaultModel,
1554
1660
  getDefaultThinkingLevel,
@@ -1566,9 +1672,11 @@ export {
1566
1672
  getVideoByteLimit,
1567
1673
  grokCliBaseUrl,
1568
1674
  grokCliHeaders,
1675
+ isClaudeCodeAuthMarker,
1569
1676
  isGrokCliEndpoint,
1570
1677
  isHiddenProvider,
1571
1678
  isKimiCodingEndpoint,
1679
+ isLegacyClaudeOAuth,
1572
1680
  isLocalModelId,
1573
1681
  isLoggerOpen,
1574
1682
  isModelLoaded,
@@ -1579,21 +1687,23 @@ export {
1579
1687
  localAuthStorageKey,
1580
1688
  localModelShortName,
1581
1689
  log,
1582
- loginAnthropic,
1690
+ loginClaudeCode,
1583
1691
  loginGemini,
1584
1692
  loginKimi,
1585
1693
  loginOpenAI,
1586
1694
  loginXai,
1695
+ logoutClaudeCode,
1696
+ mergeClaudeCodeRateLimit,
1587
1697
  oauthStorageKey,
1588
1698
  ollamaServedContext,
1589
1699
  openLog,
1590
1700
  parseLocalModelId,
1591
1701
  parseOpenRouterCatalog,
1592
- pendingClaudeCodeVersionRefresh,
1593
1702
  probeEndpoint,
1594
1703
  providerStorageKeys,
1704
+ readClaudeCodeUsage,
1595
1705
  readStoredBaseUrlSync,
1596
- refreshAnthropicToken,
1706
+ recordClaudeCodeRateLimit,
1597
1707
  refreshGeminiToken,
1598
1708
  refreshKimiToken,
1599
1709
  refreshOpenAIToken,
@@ -1601,8 +1711,11 @@ export {
1601
1711
  registerLogCleanup,
1602
1712
  registerRuntimeModels,
1603
1713
  resample,
1714
+ resolveClaudeCodeBinary,
1604
1715
  setProgressCallback,
1605
1716
  setProviderCatalog,
1717
+ signInWithClaudeCode,
1718
+ signOutOfClaudeCode,
1606
1719
  toModelInfo,
1607
1720
  transcribeVoice,
1608
1721
  usesOpenAICodexTransport,