tokentracker-cli 0.19.0 → 0.21.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/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/dashboard/dist/assets/{Card-ANC9ZmIT.js → Card-jA08WeEw.js} +1 -1
- package/dashboard/dist/assets/{DashboardPage-DpZaCksZ.js → DashboardPage-chDVOYmG.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-WXGyOn0H.js → FadeIn-DqSYXuUL.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-DUkE0Dwd.js → HeaderGithubStar-C11rWv0B.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-BPF8eGpg.js → IpCheckPage-CkEZ9yLK.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-0uTpqpAU.js → LandingPage-BgckTHRQ.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardPage-DzxRJEzb.js → LeaderboardPage-BCNW7UWp.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardProfilePage-C3_oUxhG.js → LeaderboardProfilePage-BLATxMt-.js} +1 -1
- package/dashboard/dist/assets/{LimitsPage-BVuvoeY9.js → LimitsPage-arF--WgR.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-CfkNRmT6.js → LoginPage-DpoFP0va.js} +1 -1
- package/dashboard/dist/assets/{PopoverPopup-CfxiYbJm.js → PopoverPopup-kdgc2H6C.js} +1 -1
- package/dashboard/dist/assets/{ProviderIcon-DiPzAed2.js → ProviderIcon-DV5r9qqP.js} +1 -1
- package/dashboard/dist/assets/{SettingsPage-Devu7beE.js → SettingsPage-Bb22ORmU.js} +1 -1
- package/dashboard/dist/assets/{SkillsPage-CSe8fW4V.js → SkillsPage-xhtBqVKC.js} +1 -1
- package/dashboard/dist/assets/{WidgetsPage-BrLp5YLk.js → WidgetsPage-CUoSVDET.js} +1 -1
- package/dashboard/dist/assets/{chevron-down-nFF6Yj_r.js → chevron-down-DYb2EChD.js} +1 -1
- package/dashboard/dist/assets/{download-DhSZ--68.js → download-C-_8o6dh.js} +1 -1
- package/dashboard/dist/assets/{leaderboard-columns-CvFdXrw5.js → leaderboard-columns-BgzBlYo7.js} +1 -1
- package/dashboard/dist/assets/{main-DtrPNYb7.js → main-11hApDak.js} +3 -3
- package/dashboard/dist/assets/{use-limits-display-prefs-Yy8t7tbB.js → use-limits-display-prefs-BeGKWUuk.js} +1 -1
- package/dashboard/dist/assets/{use-native-settings-uemf9RSH.js → use-native-settings-nTTHktn0.js} +1 -1
- package/dashboard/dist/assets/{use-reduced-motion-DH8DxE18.js → use-reduced-motion-DU8Gm6j1.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-C3vUT6PH.js → use-usage-limits-DTPmEB8Y.js} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/dashboard/dist/share.html +1 -1
- package/package.json +1 -1
- package/src/commands/init.js +9 -5
- package/src/commands/serve.js +0 -12
- package/src/commands/sync.js +370 -7
- package/src/lib/grok-hook.js +86 -7
- package/src/lib/pricing/curated-overrides.json +1 -1
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/rollout.js +403 -140
- package/src/lib/subscriptions.js +92 -40
- package/src/lib/usage-limits.js +104 -19
package/src/lib/subscriptions.js
CHANGED
|
@@ -10,6 +10,10 @@ const { probeOpenclawSessionPluginState } = require("./openclaw-session-plugin")
|
|
|
10
10
|
const OPENAI_AUTH_CLAIM = "https://api.openai.com/auth";
|
|
11
11
|
const MACOS_SECURITY_BIN = "/usr/bin/security";
|
|
12
12
|
const CLAUDE_CODE_KEYCHAIN_SERVICES = ["Claude Code-credentials"];
|
|
13
|
+
// On Linux, Claude Code persists the same OAuth payload as a plain JSON file
|
|
14
|
+
// (~/.claude/.credentials.json) instead of the macOS Keychain. The payload
|
|
15
|
+
// shape is identical: { claudeAiOauth: { accessToken, subscriptionType, ... } }
|
|
16
|
+
const CLAUDE_CODE_CREDENTIALS_FILE = ".credentials.json";
|
|
13
17
|
|
|
14
18
|
function normalizeString(value) {
|
|
15
19
|
if (typeof value !== "string") return null;
|
|
@@ -193,25 +197,56 @@ function readMacosKeychainPassword({ service, securityRunner, timeoutMs } = {})
|
|
|
193
197
|
return trimmed.length > 0 ? trimmed : null;
|
|
194
198
|
}
|
|
195
199
|
|
|
196
|
-
function
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
200
|
+
function readClaudeCodeCredentialsLinuxFile({ home, fsReader } = {}) {
|
|
201
|
+
const homeDir = typeof home === "string" && home ? home : os.homedir();
|
|
202
|
+
const credPath = path.join(homeDir, ".claude", CLAUDE_CODE_CREDENTIALS_FILE);
|
|
203
|
+
const reader = typeof fsReader === "function" ? fsReader : fs.readFileSync;
|
|
204
|
+
try {
|
|
205
|
+
return reader(credPath, "utf8");
|
|
206
|
+
} catch (_e) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
205
210
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
211
|
+
function detectClaudeCodeCredentialsPresence({ platform, securityRunner, home, fsReader } = {}) {
|
|
212
|
+
if (platform === "darwin") {
|
|
213
|
+
for (const service of CLAUDE_CODE_KEYCHAIN_SERVICES) {
|
|
214
|
+
const present = probeMacosKeychainGenericPassword({
|
|
215
|
+
service,
|
|
216
|
+
securityRunner,
|
|
217
|
+
});
|
|
218
|
+
if (!present) continue;
|
|
219
|
+
|
|
220
|
+
// Existence-only probe: do not read secrets or infer paid tier.
|
|
221
|
+
return {
|
|
222
|
+
tool: "claude",
|
|
223
|
+
provider: "anthropic",
|
|
224
|
+
product: "credentials",
|
|
225
|
+
planType: "present",
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
return null;
|
|
213
229
|
}
|
|
214
230
|
|
|
231
|
+
if (platform !== "linux") return null;
|
|
232
|
+
|
|
233
|
+
// Linux: credentials live in ~/.claude/.credentials.json (mode 0600).
|
|
234
|
+
// Existence-only: just check that the file is readable and contains the OAuth key.
|
|
235
|
+
const raw = readClaudeCodeCredentialsLinuxFile({ home, fsReader });
|
|
236
|
+
if (!raw) return null;
|
|
237
|
+
try {
|
|
238
|
+
const payload = JSON.parse(raw);
|
|
239
|
+
if (payload?.claudeAiOauth && typeof payload.claudeAiOauth === "object") {
|
|
240
|
+
return {
|
|
241
|
+
tool: "claude",
|
|
242
|
+
provider: "anthropic",
|
|
243
|
+
product: "credentials",
|
|
244
|
+
planType: "present",
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
} catch (_e) {
|
|
248
|
+
// fall through
|
|
249
|
+
}
|
|
215
250
|
return null;
|
|
216
251
|
}
|
|
217
252
|
|
|
@@ -228,16 +263,21 @@ function extractClaudeKeychainSubscription(payload) {
|
|
|
228
263
|
return { subscriptionType, rateLimitTier };
|
|
229
264
|
}
|
|
230
265
|
|
|
231
|
-
function detectClaudeCodeSubscriptionDetails({ platform, securityRunner } = {}) {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
266
|
+
function detectClaudeCodeSubscriptionDetails({ platform, securityRunner, home, fsReader } = {}) {
|
|
267
|
+
const rawPayloads = [];
|
|
268
|
+
if (platform === "darwin") {
|
|
269
|
+
for (const service of CLAUDE_CODE_KEYCHAIN_SERVICES) {
|
|
270
|
+
const raw = readMacosKeychainPassword({ service, securityRunner });
|
|
271
|
+
if (raw) rawPayloads.push(raw);
|
|
272
|
+
}
|
|
273
|
+
} else if (platform === "linux") {
|
|
274
|
+
const raw = readClaudeCodeCredentialsLinuxFile({ home, fsReader });
|
|
275
|
+
if (raw) rawPayloads.push(raw);
|
|
276
|
+
} else {
|
|
277
|
+
return null;
|
|
278
|
+
}
|
|
240
279
|
|
|
280
|
+
for (const raw of rawPayloads) {
|
|
241
281
|
let payload;
|
|
242
282
|
try {
|
|
243
283
|
payload = JSON.parse(raw);
|
|
@@ -277,14 +317,14 @@ async function collectLocalSubscriptions({
|
|
|
277
317
|
if (opencode) out.push(opencode);
|
|
278
318
|
|
|
279
319
|
if (probeKeychainDetails) {
|
|
280
|
-
const claude = detectClaudeCodeSubscriptionDetails({ platform, securityRunner });
|
|
320
|
+
const claude = detectClaudeCodeSubscriptionDetails({ platform, securityRunner, home });
|
|
281
321
|
if (claude) out.push(claude);
|
|
282
322
|
else if (probeKeychain) {
|
|
283
|
-
const present = detectClaudeCodeCredentialsPresence({ platform, securityRunner });
|
|
323
|
+
const present = detectClaudeCodeCredentialsPresence({ platform, securityRunner, home });
|
|
284
324
|
if (present) out.push(present);
|
|
285
325
|
}
|
|
286
326
|
} else if (probeKeychain) {
|
|
287
|
-
const claude = detectClaudeCodeCredentialsPresence({ platform, securityRunner });
|
|
327
|
+
const claude = detectClaudeCodeCredentialsPresence({ platform, securityRunner, home });
|
|
288
328
|
if (claude) out.push(claude);
|
|
289
329
|
}
|
|
290
330
|
|
|
@@ -314,20 +354,32 @@ async function detectOpenclawSessionIntegration({ home, env }) {
|
|
|
314
354
|
};
|
|
315
355
|
}
|
|
316
356
|
|
|
317
|
-
function readClaudeCodeAccessToken({ platform, securityRunner } = {}) {
|
|
318
|
-
if (platform
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
357
|
+
function readClaudeCodeAccessToken({ platform, securityRunner, home, fsReader } = {}) {
|
|
358
|
+
if (platform === "darwin") {
|
|
359
|
+
for (const service of CLAUDE_CODE_KEYCHAIN_SERVICES) {
|
|
360
|
+
try {
|
|
361
|
+
const raw = readMacosKeychainPassword({ service, securityRunner });
|
|
362
|
+
if (!raw) continue;
|
|
363
|
+
const payload = JSON.parse(raw);
|
|
364
|
+
return normalizeString(payload?.claudeAiOauth?.accessToken);
|
|
365
|
+
} catch (_e) {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
328
368
|
}
|
|
369
|
+
return null;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
if (platform !== "linux") return null;
|
|
373
|
+
|
|
374
|
+
// Linux: Claude Code stores the OAuth payload as a JSON file with mode 0600.
|
|
375
|
+
const raw = readClaudeCodeCredentialsLinuxFile({ home, fsReader });
|
|
376
|
+
if (!raw) return null;
|
|
377
|
+
try {
|
|
378
|
+
const payload = JSON.parse(raw);
|
|
379
|
+
return normalizeString(payload?.claudeAiOauth?.accessToken);
|
|
380
|
+
} catch (_e) {
|
|
381
|
+
return null;
|
|
329
382
|
}
|
|
330
|
-
return null;
|
|
331
383
|
}
|
|
332
384
|
|
|
333
385
|
async function readCodexAccessToken({ home, env } = {}) {
|
package/src/lib/usage-limits.js
CHANGED
|
@@ -25,6 +25,9 @@ const {
|
|
|
25
25
|
let cache = { data: null, fetchedAt: 0 };
|
|
26
26
|
const CACHE_TTL_MS = 2 * 60 * 1000;
|
|
27
27
|
const DEFAULT_PROVIDER_TIMEOUT_MS = 15_000;
|
|
28
|
+
const ANTIGRAVITY_LIMITS_CACHE_FILE = "usage-limits-cache.json";
|
|
29
|
+
const ANTIGRAVITY_LIMITS_CACHE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
30
|
+
const ANTIGRAVITY_LIMITS_CACHE_UNKNOWN_RESET_TTL_MS = 12 * 60 * 60 * 1000;
|
|
28
31
|
|
|
29
32
|
function clampPercent(value) {
|
|
30
33
|
if (value === null || value === undefined || value === "") return null;
|
|
@@ -808,9 +811,15 @@ function runCommand(commandRunner, command, args, options = {}) {
|
|
|
808
811
|
});
|
|
809
812
|
}
|
|
810
813
|
|
|
811
|
-
function
|
|
814
|
+
function whichBinary(binary, { commandRunner } = {}) {
|
|
812
815
|
const result = runCommand(commandRunner, "which", [binary], { timeout: 2000 });
|
|
813
|
-
|
|
816
|
+
if (result?.error || result?.status !== 0) return null;
|
|
817
|
+
const stdout = typeof result?.stdout === "string" ? result.stdout.trim() : "";
|
|
818
|
+
return stdout ? stdout.split("\n")[0] : null;
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
function isBinaryAvailable(binary, { commandRunner } = {}) {
|
|
822
|
+
return whichBinary(binary, { commandRunner }) !== null;
|
|
814
823
|
}
|
|
815
824
|
|
|
816
825
|
function stripAnsi(text) {
|
|
@@ -1173,11 +1182,84 @@ function detectAntigravityProcess({ commandRunner } = {}) {
|
|
|
1173
1182
|
return { configured: false };
|
|
1174
1183
|
}
|
|
1175
1184
|
|
|
1176
|
-
function
|
|
1185
|
+
function resolveAntigravityLimitsCachePath({ home } = {}) {
|
|
1186
|
+
return path.join(home || os.homedir(), ".tokentracker", "tracker", ANTIGRAVITY_LIMITS_CACHE_FILE);
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
function parseTimeMs(value) {
|
|
1190
|
+
if (typeof value !== "string" || !value) return null;
|
|
1191
|
+
const ts = Date.parse(value);
|
|
1192
|
+
return Number.isFinite(ts) && ts > 0 ? ts : null;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
function isCacheWindowUsable(window, { cachedAtMs, nowMs } = {}) {
|
|
1196
|
+
if (!window || typeof window !== "object") return false;
|
|
1197
|
+
const resetAtMs = parseTimeMs(window.reset_at);
|
|
1198
|
+
if (resetAtMs !== null) return resetAtMs > nowMs;
|
|
1199
|
+
return Number.isFinite(cachedAtMs)
|
|
1200
|
+
&& nowMs - cachedAtMs <= ANTIGRAVITY_LIMITS_CACHE_UNKNOWN_RESET_TTL_MS;
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
function hasAntigravityWindow(limits) {
|
|
1204
|
+
return Boolean(limits?.primary_window || limits?.secondary_window || limits?.tertiary_window);
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
function normalizeAntigravityCachedLimits(raw, { nowMs = Date.now() } = {}) {
|
|
1208
|
+
const cachedAtMs = parseTimeMs(raw?.cached_at);
|
|
1209
|
+
if (!Number.isFinite(cachedAtMs)) return null;
|
|
1210
|
+
if (cachedAtMs > nowMs + 60_000) return null;
|
|
1211
|
+
if (nowMs - cachedAtMs > ANTIGRAVITY_LIMITS_CACHE_MAX_AGE_MS) return null;
|
|
1212
|
+
|
|
1213
|
+
const cached = {
|
|
1214
|
+
configured: true,
|
|
1215
|
+
error: null,
|
|
1216
|
+
account_email: typeof raw?.account_email === "string" ? raw.account_email : null,
|
|
1217
|
+
account_plan: typeof raw?.account_plan === "string" ? raw.account_plan : null,
|
|
1218
|
+
primary_window: isCacheWindowUsable(raw?.primary_window, { cachedAtMs, nowMs }) ? raw.primary_window : null,
|
|
1219
|
+
secondary_window: isCacheWindowUsable(raw?.secondary_window, { cachedAtMs, nowMs }) ? raw.secondary_window : null,
|
|
1220
|
+
tertiary_window: isCacheWindowUsable(raw?.tertiary_window, { cachedAtMs, nowMs }) ? raw.tertiary_window : null,
|
|
1221
|
+
cached: true,
|
|
1222
|
+
cached_at: raw.cached_at,
|
|
1223
|
+
};
|
|
1224
|
+
return hasAntigravityWindow(cached) ? cached : null;
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
function readAntigravityLimitsCache({ home, nowMs = Date.now() } = {}) {
|
|
1228
|
+
const cachePath = resolveAntigravityLimitsCachePath({ home });
|
|
1229
|
+
try {
|
|
1230
|
+
const parsed = JSON.parse(fs.readFileSync(cachePath, "utf8"));
|
|
1231
|
+
return normalizeAntigravityCachedLimits(parsed?.antigravity, { nowMs });
|
|
1232
|
+
} catch (_error) {
|
|
1233
|
+
return null;
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
function writeAntigravityLimitsCache(limits, { home, nowMs = Date.now() } = {}) {
|
|
1238
|
+
if (!limits?.configured || limits.error || !hasAntigravityWindow(limits)) return;
|
|
1239
|
+
const cachePath = resolveAntigravityLimitsCachePath({ home });
|
|
1240
|
+
const payload = {
|
|
1241
|
+
antigravity: {
|
|
1242
|
+
account_email: limits.account_email || null,
|
|
1243
|
+
account_plan: limits.account_plan || null,
|
|
1244
|
+
primary_window: limits.primary_window || null,
|
|
1245
|
+
secondary_window: limits.secondary_window || null,
|
|
1246
|
+
tertiary_window: limits.tertiary_window || null,
|
|
1247
|
+
cached_at: new Date(nowMs).toISOString(),
|
|
1248
|
+
},
|
|
1249
|
+
};
|
|
1250
|
+
try {
|
|
1251
|
+
fs.mkdirSync(path.dirname(cachePath), { recursive: true });
|
|
1252
|
+
const tmpPath = `${cachePath}.${process.pid}.tmp`;
|
|
1253
|
+
fs.writeFileSync(tmpPath, JSON.stringify(payload, null, 2), { encoding: "utf8", mode: 0o600 });
|
|
1254
|
+
fs.renameSync(tmpPath, cachePath);
|
|
1255
|
+
} catch (_error) {}
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
function resolveLsofBinary({ commandRunner } = {}) {
|
|
1177
1259
|
for (const candidate of ["/usr/sbin/lsof", "/usr/bin/lsof"]) {
|
|
1178
1260
|
if (fs.existsSync(candidate)) return candidate;
|
|
1179
1261
|
}
|
|
1180
|
-
return
|
|
1262
|
+
return whichBinary("lsof", { commandRunner });
|
|
1181
1263
|
}
|
|
1182
1264
|
|
|
1183
1265
|
function parseListeningPorts(output) {
|
|
@@ -1193,7 +1275,7 @@ function parseListeningPorts(output) {
|
|
|
1193
1275
|
}
|
|
1194
1276
|
|
|
1195
1277
|
function listAntigravityPorts(pid, { commandRunner } = {}) {
|
|
1196
|
-
const lsof = resolveLsofBinary();
|
|
1278
|
+
const lsof = resolveLsofBinary({ commandRunner });
|
|
1197
1279
|
if (!lsof) {
|
|
1198
1280
|
throw new Error("Antigravity port detection needs lsof. Install it, then retry.");
|
|
1199
1281
|
}
|
|
@@ -1446,15 +1528,25 @@ async function probeAntigravityPort(port, csrfToken, { timeoutMs, requestFn } =
|
|
|
1446
1528
|
}
|
|
1447
1529
|
}
|
|
1448
1530
|
|
|
1449
|
-
async function fetchAntigravityLimits({ commandRunner, requestFn, timeoutMs = 8000 } = {}) {
|
|
1531
|
+
async function fetchAntigravityLimits({ home, commandRunner, requestFn, timeoutMs = 8000, nowMs = Date.now() } = {}) {
|
|
1450
1532
|
const processInfo = detectAntigravityProcess({ commandRunner });
|
|
1451
1533
|
if (!processInfo.configured) {
|
|
1452
|
-
return { configured: false };
|
|
1534
|
+
return readAntigravityLimitsCache({ home, nowMs }) || { configured: false };
|
|
1453
1535
|
}
|
|
1454
1536
|
if (processInfo.error) {
|
|
1455
1537
|
return { configured: true, error: processInfo.error };
|
|
1456
1538
|
}
|
|
1457
1539
|
|
|
1540
|
+
const finalize = (payload, normalizeOptions) => {
|
|
1541
|
+
const result = {
|
|
1542
|
+
configured: true,
|
|
1543
|
+
error: null,
|
|
1544
|
+
...normalizeAntigravityResponse(payload, normalizeOptions),
|
|
1545
|
+
};
|
|
1546
|
+
writeAntigravityLimitsCache(result, { home, nowMs });
|
|
1547
|
+
return result;
|
|
1548
|
+
};
|
|
1549
|
+
|
|
1458
1550
|
try {
|
|
1459
1551
|
const ports = listAntigravityPorts(processInfo.pid, { commandRunner });
|
|
1460
1552
|
let workingPort = null;
|
|
@@ -1478,11 +1570,7 @@ async function fetchAntigravityLimits({ commandRunner, requestFn, timeoutMs = 80
|
|
|
1478
1570
|
timeoutMs,
|
|
1479
1571
|
requestFn,
|
|
1480
1572
|
});
|
|
1481
|
-
return
|
|
1482
|
-
configured: true,
|
|
1483
|
-
error: null,
|
|
1484
|
-
...normalizeAntigravityResponse(userStatus),
|
|
1485
|
-
};
|
|
1573
|
+
return finalize(userStatus);
|
|
1486
1574
|
} catch (primaryError) {
|
|
1487
1575
|
const fallbackPort =
|
|
1488
1576
|
Number.isFinite(processInfo.extensionPort) && processInfo.extensionPort > 0
|
|
@@ -1497,11 +1585,7 @@ async function fetchAntigravityLimits({ commandRunner, requestFn, timeoutMs = 80
|
|
|
1497
1585
|
timeoutMs,
|
|
1498
1586
|
requestFn,
|
|
1499
1587
|
});
|
|
1500
|
-
return {
|
|
1501
|
-
configured: true,
|
|
1502
|
-
error: null,
|
|
1503
|
-
...normalizeAntigravityResponse(modelConfigs, { fallbackToConfigs: true }),
|
|
1504
|
-
};
|
|
1588
|
+
return finalize(modelConfigs, { fallbackToConfigs: true });
|
|
1505
1589
|
}
|
|
1506
1590
|
} catch (error) {
|
|
1507
1591
|
const message = error?.message === "timeout"
|
|
@@ -1531,7 +1615,7 @@ async function getUsageLimits({
|
|
|
1531
1615
|
}
|
|
1532
1616
|
|
|
1533
1617
|
const [claudeToken, codexAuth] = await Promise.all([
|
|
1534
|
-
Promise.resolve().then(() => readClaudeCodeAccessToken({ platform, securityRunner })),
|
|
1618
|
+
Promise.resolve().then(() => readClaudeCodeAccessToken({ platform, securityRunner, home })),
|
|
1535
1619
|
readCodexAuthBundle({ home, env }),
|
|
1536
1620
|
]);
|
|
1537
1621
|
|
|
@@ -1594,7 +1678,7 @@ async function getUsageLimits({
|
|
|
1594
1678
|
withProviderTimeout(fetchGeminiLimits({ home, env, fetchImpl: providerFetch, commandRunner }), "Gemini", providerTimeoutMs)
|
|
1595
1679
|
.catch((reason) => ({ configured: true, error: reason?.message || "Unknown error" })),
|
|
1596
1680
|
Promise.resolve().then(() => fetchKiroLimits({ commandRunner, now })),
|
|
1597
|
-
fetchAntigravityLimits({ commandRunner, requestFn }),
|
|
1681
|
+
fetchAntigravityLimits({ home, commandRunner, requestFn, nowMs }),
|
|
1598
1682
|
withProviderTimeout(fetchCopilotLimits({ home, env, fetchImpl: providerFetch }), "GitHub Copilot", providerTimeoutMs)
|
|
1599
1683
|
.catch((reason) => ({ configured: true, error: reason?.message || "Unknown error" })),
|
|
1600
1684
|
]);
|
|
@@ -1670,6 +1754,7 @@ module.exports = {
|
|
|
1670
1754
|
normalizeAntigravityResponse,
|
|
1671
1755
|
parseListeningPorts,
|
|
1672
1756
|
detectAntigravityProcess,
|
|
1757
|
+
fetchAntigravityLimits,
|
|
1673
1758
|
fetchCopilotLimits,
|
|
1674
1759
|
readCopilotOauthToken,
|
|
1675
1760
|
describeCopilotOtelStatus,
|