tokentracker-cli 0.44.0 → 0.45.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/dashboard/dist/assets/{ActivityHeatmap-C2y1lgOo.js → ActivityHeatmap-wlmadSUA.js} +1 -1
- package/dashboard/dist/assets/{Card-BJVoMVdB.js → Card-CK6OpUIW.js} +1 -1
- package/dashboard/dist/assets/{DashboardPage-NcjsaIbt.js → DashboardPage-ps2AXAKO.js} +1 -1
- package/dashboard/dist/assets/{DevicePage-EHZwN0AA.js → DevicePage-DB_mig-T.js} +1 -1
- package/dashboard/dist/assets/{DialogTitle-DVWJF7Sh.js → DialogTitle-CtaQVM8M.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-DtXdVuFa.js → FadeIn-DfzGe4N4.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-Cj_NuY82.js → HeaderGithubStar-y0yvef_C.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-DZ4te6Pi.js → IpCheckPage-sVOOm10k.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-CR9hpOA8.js → LandingPage-CjQgv7zi.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardAvatar-DsQv0oYJ.js → LeaderboardAvatar-sdzTrleb.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardPage-C6pR-fls.js → LeaderboardPage-DXvBEjG4.js} +3 -3
- package/dashboard/dist/assets/{LeaderboardProfileModal-DrAB9Pof.js → LeaderboardProfileModal-D1a65plB.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardProfilePage-CMBVCK_9.js → LeaderboardProfilePage-DzjN7fxW.js} +1 -1
- package/dashboard/dist/assets/LimitsPage-DwBFiaav.js +2 -0
- package/dashboard/dist/assets/{LocalOnlyNotice-DysLhDFE.js → LocalOnlyNotice-LhhqHNKr.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-jh8YcJtZ.js → LoginPage-DWRTQC0B.js} +1 -1
- package/dashboard/dist/assets/{PopoverPopup-DJt7HnL-.js → PopoverPopup-BRZ10YDe.js} +1 -1
- package/dashboard/dist/assets/{Select-16iq_C1U.js → Select-XpgQ4GWg.js} +1 -1
- package/dashboard/dist/assets/{SelectItemText-Bwctpnf1.js → SelectItemText-DgBDHxFj.js} +1 -1
- package/dashboard/dist/assets/{SettingsPage-BvA-0-6K.js → SettingsPage-CVk9jLOL.js} +1 -1
- package/dashboard/dist/assets/{SkillsPage-BCgd79rI.js → SkillsPage-Mk89JSte.js} +1 -1
- package/dashboard/dist/assets/WidgetsPage-D7y2Izbf.js +1 -0
- package/dashboard/dist/assets/{WrappedPage-CzyRJXb4.js → WrappedPage-DHLnWW3p.js} +1 -1
- package/dashboard/dist/assets/{agent-logos-3S7JvH_A.js → agent-logos-DZa_UVL5.js} +1 -1
- package/dashboard/dist/assets/{arrow-up-right-SUDWxkx-.js → arrow-up-right-9Yp14B47.js} +1 -1
- package/dashboard/dist/assets/{download-B06KpWLb.js → download-C4A4OPj1.js} +1 -1
- package/dashboard/dist/assets/{info-BYuw8wyW.js → info-4BytsGkj.js} +1 -1
- package/dashboard/dist/assets/{main-CZ7INQ5C.js → main-DdrbbegY.js} +7 -3
- package/dashboard/dist/assets/{use-limits-display-prefs-5el6WphI.js → use-limits-display-prefs-D8judXnf.js} +1 -1
- package/dashboard/dist/assets/{use-native-settings-BsOpSNnV.js → use-native-settings-q_6Jzz-U.js} +1 -1
- package/dashboard/dist/assets/use-usage-limits-yoVhgTFR.js +1 -0
- package/dashboard/dist/assets/{useCurrency-CjB3wfFx.js → useCurrency-Bid8-eMU.js} +1 -1
- package/dashboard/dist/assets/{useScrollLock-Dyho5BJU.js → useScrollLock-D2Y5Bu51.js} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/dashboard/dist/share.html +1 -1
- package/package.json +1 -1
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/usage-limits.js +263 -14
- package/dashboard/dist/assets/LimitsPage-CMAgr4sd.js +0 -2
- package/dashboard/dist/assets/WidgetsPage-DecKPwRh.js +0 -1
- package/dashboard/dist/assets/use-usage-limits-BgRs0aJ1.js +0 -1
package/src/lib/usage-limits.js
CHANGED
|
@@ -30,6 +30,19 @@ const DEFAULT_PROVIDER_TIMEOUT_MS = 15_000;
|
|
|
30
30
|
const ANTIGRAVITY_LIMITS_CACHE_FILE = "usage-limits-cache.json";
|
|
31
31
|
const ANTIGRAVITY_LIMITS_CACHE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
32
32
|
const ANTIGRAVITY_LIMITS_CACHE_UNKNOWN_RESET_TTL_MS = 12 * 60 * 60 * 1000;
|
|
33
|
+
// Claude shares its OAuth usage endpoint budget with Claude Code itself, so a transient
|
|
34
|
+
// 429 is common. Persist the last successful read so the panel can keep showing it instead
|
|
35
|
+
// of flashing a red error. Separate file from Antigravity's (whose writer rewrites the whole
|
|
36
|
+
// file with only its own key, so a shared file would clobber).
|
|
37
|
+
const CLAUDE_LIMITS_CACHE_FILE = "claude-usage-limits-cache.json";
|
|
38
|
+
const CLAUDE_LIMITS_CACHE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
39
|
+
// A 429 from the usage endpoint carries a long `retry-after` (often 20+ minutes). Persist
|
|
40
|
+
// the cooldown so every surface — this process, the menu bar app's embedded server, a later
|
|
41
|
+
// restart — stops calling until it expires. Hammering during the cooldown just renews the
|
|
42
|
+
// penalty, which is what kept the panel stuck on the error.
|
|
43
|
+
const CLAUDE_RATE_LIMIT_FILE = "claude-usage-rate-limit.json";
|
|
44
|
+
const CLAUDE_RATE_LIMIT_DEFAULT_COOLDOWN_SEC = 5 * 60;
|
|
45
|
+
const CLAUDE_RATE_LIMIT_MAX_COOLDOWN_SEC = 60 * 60;
|
|
33
46
|
|
|
34
47
|
function clampPercent(value) {
|
|
35
48
|
if (value === null || value === undefined || value === "") return null;
|
|
@@ -99,6 +112,20 @@ function withProviderTimeout(promise, label, timeoutMs) {
|
|
|
99
112
|
return Promise.race([promise, timeout]).finally(() => clearTimeout(timer));
|
|
100
113
|
}
|
|
101
114
|
|
|
115
|
+
function parseRetryAfterSeconds(headers) {
|
|
116
|
+
const ra = headers?.get ? headers.get("retry-after") : null;
|
|
117
|
+
const sec = ra ? Number.parseInt(ra, 10) : NaN;
|
|
118
|
+
return Number.isFinite(sec) && sec > 0 ? sec : null;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function formatClaudeRateLimitMessage(retryAfterSec) {
|
|
122
|
+
if (Number.isFinite(retryAfterSec) && retryAfterSec > 0) {
|
|
123
|
+
const mins = Math.ceil(retryAfterSec / 60);
|
|
124
|
+
return `Claude API rate limited (429) — retry in ~${mins}m.`;
|
|
125
|
+
}
|
|
126
|
+
return "Claude API rate limited (429) — retry shortly.";
|
|
127
|
+
}
|
|
128
|
+
|
|
102
129
|
async function fetchClaudeUsageLimits(accessToken, { fetchImpl = fetch, maxAttempts = 3 } = {}) {
|
|
103
130
|
const url = "https://api.anthropic.com/api/oauth/usage";
|
|
104
131
|
const headers = {
|
|
@@ -120,9 +147,11 @@ async function fetchClaudeUsageLimits(accessToken, { fetchImpl = fetch, maxAttem
|
|
|
120
147
|
}
|
|
121
148
|
if (!res.ok) {
|
|
122
149
|
if (res.status === 429) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
150
|
+
const retryAfterSec = parseRetryAfterSeconds(res.headers);
|
|
151
|
+
const err = new Error(formatClaudeRateLimitMessage(retryAfterSec));
|
|
152
|
+
err.code = "RATE_LIMITED";
|
|
153
|
+
err.retryAfterSec = retryAfterSec;
|
|
154
|
+
throw err;
|
|
126
155
|
}
|
|
127
156
|
throw new Error(`Claude API returned ${res.status}`);
|
|
128
157
|
}
|
|
@@ -152,10 +181,20 @@ function classifyCodexWindow(window) {
|
|
|
152
181
|
return null;
|
|
153
182
|
}
|
|
154
183
|
|
|
184
|
+
function normalizeCodexRateWindow(window) {
|
|
185
|
+
if (!window || typeof window !== "object" || Array.isArray(window)) return null;
|
|
186
|
+
const usedPercent = clampPercent(window.used_percent);
|
|
187
|
+
if (usedPercent === null) return null;
|
|
188
|
+
return {
|
|
189
|
+
...window,
|
|
190
|
+
used_percent: Math.round(usedPercent),
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
155
194
|
function normalizeCodexRateWindows(rateLimit) {
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
);
|
|
195
|
+
const primary = normalizeCodexRateWindow(rateLimit?.primary_window);
|
|
196
|
+
const secondary = normalizeCodexRateWindow(rateLimit?.secondary_window);
|
|
197
|
+
const candidates = [primary, secondary].filter(Boolean);
|
|
159
198
|
let session = null;
|
|
160
199
|
let weekly = null;
|
|
161
200
|
for (const w of candidates) {
|
|
@@ -167,13 +206,88 @@ function normalizeCodexRateWindows(rateLimit) {
|
|
|
167
206
|
// from unexpected window durations rather than dropping it silently.
|
|
168
207
|
if (!session && !weekly && candidates.length > 0) {
|
|
169
208
|
return {
|
|
170
|
-
primary_window:
|
|
171
|
-
secondary_window:
|
|
209
|
+
primary_window: primary,
|
|
210
|
+
secondary_window: secondary,
|
|
172
211
|
};
|
|
173
212
|
}
|
|
174
213
|
return { primary_window: session, secondary_window: weekly };
|
|
175
214
|
}
|
|
176
215
|
|
|
216
|
+
function isCodexSparkLimit(entry) {
|
|
217
|
+
if (!entry || typeof entry !== "object") return false;
|
|
218
|
+
return [entry.limit_name, entry.metered_feature].some((value) => (
|
|
219
|
+
typeof value === "string" && value.trim().toLowerCase().includes("spark")
|
|
220
|
+
));
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
function codexSparkFallbackCandidates(primary, secondary) {
|
|
224
|
+
const primaryKind = classifyCodexWindow(primary);
|
|
225
|
+
const secondaryKind = classifyCodexWindow(secondary);
|
|
226
|
+
const out = [];
|
|
227
|
+
const primaryDurationMissing = primary
|
|
228
|
+
&& (primary.limit_window_seconds === undefined
|
|
229
|
+
|| primary.limit_window_seconds === null
|
|
230
|
+
|| primary.limit_window_seconds === "");
|
|
231
|
+
|
|
232
|
+
if (primaryKind || secondaryKind) {
|
|
233
|
+
if (!primaryKind && primary && secondaryKind === "weekly") {
|
|
234
|
+
out.push({ kind: "session", window: primary });
|
|
235
|
+
}
|
|
236
|
+
if (!primaryKind && primaryDurationMissing && secondaryKind === "session") {
|
|
237
|
+
out.push({ kind: "weekly", window: primary });
|
|
238
|
+
}
|
|
239
|
+
if (!secondaryKind && secondary && primaryKind === "weekly") {
|
|
240
|
+
out.push({ kind: "session", window: secondary });
|
|
241
|
+
}
|
|
242
|
+
if (!secondaryKind && secondary && primaryKind === "session") {
|
|
243
|
+
out.push({ kind: "weekly", window: secondary });
|
|
244
|
+
}
|
|
245
|
+
return out;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (primary) out.push({ kind: "session", window: primary });
|
|
249
|
+
if (secondary) out.push({ kind: "weekly", window: secondary });
|
|
250
|
+
return out;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function normalizeCodexSparkRateWindows(additionalRateLimits) {
|
|
254
|
+
let session = null;
|
|
255
|
+
let weekly = null;
|
|
256
|
+
if (!Array.isArray(additionalRateLimits)) {
|
|
257
|
+
return { spark_primary_window: null, spark_secondary_window: null };
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const classifiedCandidates = [];
|
|
261
|
+
const fallbackCandidates = [];
|
|
262
|
+
for (const entry of additionalRateLimits) {
|
|
263
|
+
if (!isCodexSparkLimit(entry)) continue;
|
|
264
|
+
const rateLimit = entry.rate_limit;
|
|
265
|
+
if (!rateLimit || typeof rateLimit !== "object") continue;
|
|
266
|
+
|
|
267
|
+
const primary = normalizeCodexRateWindow(rateLimit.primary_window);
|
|
268
|
+
const secondary = normalizeCodexRateWindow(rateLimit.secondary_window);
|
|
269
|
+
for (const window of [primary, secondary]) {
|
|
270
|
+
const kind = classifyCodexWindow(window);
|
|
271
|
+
if (kind) classifiedCandidates.push({ kind, window });
|
|
272
|
+
}
|
|
273
|
+
fallbackCandidates.push(...codexSparkFallbackCandidates(primary, secondary));
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
for (const candidate of classifiedCandidates) {
|
|
277
|
+
if (candidate.kind === "session" && !session) session = candidate.window;
|
|
278
|
+
else if (candidate.kind === "weekly" && !weekly) weekly = candidate.window;
|
|
279
|
+
}
|
|
280
|
+
for (const candidate of fallbackCandidates) {
|
|
281
|
+
if (candidate.kind === "session" && !session) session = candidate.window;
|
|
282
|
+
else if (candidate.kind === "weekly" && !weekly) weekly = candidate.window;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return {
|
|
286
|
+
spark_primary_window: session,
|
|
287
|
+
spark_secondary_window: weekly,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
177
291
|
async function fetchCodexUsageLimits(
|
|
178
292
|
accessToken,
|
|
179
293
|
{ fetchImpl = fetch, accountId = null } = {},
|
|
@@ -195,13 +309,21 @@ async function fetchCodexUsageLimits(
|
|
|
195
309
|
// 401/403/404 from wham means "no usage data available for this auth state" — render
|
|
196
310
|
// a neutral empty state instead of a red "Fetch failed" error.
|
|
197
311
|
if (res.status === 401 || res.status === 403 || res.status === 404) {
|
|
198
|
-
return {
|
|
312
|
+
return {
|
|
313
|
+
primary_window: null,
|
|
314
|
+
secondary_window: null,
|
|
315
|
+
spark_primary_window: null,
|
|
316
|
+
spark_secondary_window: null,
|
|
317
|
+
};
|
|
199
318
|
}
|
|
200
319
|
if (!res.ok) {
|
|
201
320
|
throw new Error(`Codex API returned ${res.status}`);
|
|
202
321
|
}
|
|
203
322
|
const body = await res.json();
|
|
204
|
-
return
|
|
323
|
+
return {
|
|
324
|
+
...normalizeCodexRateWindows(body.rate_limit || {}),
|
|
325
|
+
...normalizeCodexSparkRateWindows(body.additional_rate_limits),
|
|
326
|
+
};
|
|
205
327
|
}
|
|
206
328
|
|
|
207
329
|
function cursorPercentFromCentsUsedLimit(usedRaw, limitRaw) {
|
|
@@ -1271,6 +1393,107 @@ function writeAntigravityLimitsCache(limits, { home, nowMs = Date.now() } = {})
|
|
|
1271
1393
|
} catch (_error) {}
|
|
1272
1394
|
}
|
|
1273
1395
|
|
|
1396
|
+
function resolveClaudeLimitsCachePath({ home } = {}) {
|
|
1397
|
+
return path.join(home || os.homedir(), ".tokentracker", "tracker", CLAUDE_LIMITS_CACHE_FILE);
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
// Claude windows carry their own `resets_at`; a window whose reset has already passed is
|
|
1401
|
+
// stale data, not a usable fallback, so drop it. Windows without a reset stamp are kept
|
|
1402
|
+
// (the overall cached_at max-age gate already bounds them).
|
|
1403
|
+
function isClaudeCacheWindowUsable(window, { nowMs } = {}) {
|
|
1404
|
+
if (!window || typeof window !== "object") return false;
|
|
1405
|
+
const resetAtMs = parseTimeMs(window.resets_at);
|
|
1406
|
+
if (resetAtMs === null) return true;
|
|
1407
|
+
return resetAtMs > nowMs;
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
function hasClaudeWindow(limits) {
|
|
1411
|
+
return Boolean(limits?.five_hour || limits?.seven_day || limits?.seven_day_opus);
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1414
|
+
function normalizeClaudeCachedLimits(raw, { nowMs = Date.now() } = {}) {
|
|
1415
|
+
const cachedAtMs = parseTimeMs(raw?.cached_at);
|
|
1416
|
+
if (!Number.isFinite(cachedAtMs)) return null;
|
|
1417
|
+
if (cachedAtMs > nowMs + 60_000) return null;
|
|
1418
|
+
if (nowMs - cachedAtMs > CLAUDE_LIMITS_CACHE_MAX_AGE_MS) return null;
|
|
1419
|
+
|
|
1420
|
+
const cached = {
|
|
1421
|
+
configured: true,
|
|
1422
|
+
error: null,
|
|
1423
|
+
five_hour: isClaudeCacheWindowUsable(raw?.five_hour, { nowMs }) ? raw.five_hour : null,
|
|
1424
|
+
seven_day: isClaudeCacheWindowUsable(raw?.seven_day, { nowMs }) ? raw.seven_day : null,
|
|
1425
|
+
seven_day_opus: isClaudeCacheWindowUsable(raw?.seven_day_opus, { nowMs }) ? raw.seven_day_opus : null,
|
|
1426
|
+
extra_usage: raw?.extra_usage ?? null,
|
|
1427
|
+
stale: true,
|
|
1428
|
+
cached_at: raw.cached_at,
|
|
1429
|
+
};
|
|
1430
|
+
return hasClaudeWindow(cached) ? cached : null;
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
function readClaudeLimitsCache({ home, nowMs = Date.now() } = {}) {
|
|
1434
|
+
const cachePath = resolveClaudeLimitsCachePath({ home });
|
|
1435
|
+
try {
|
|
1436
|
+
const parsed = JSON.parse(fs.readFileSync(cachePath, "utf8"));
|
|
1437
|
+
return normalizeClaudeCachedLimits(parsed?.claude, { nowMs });
|
|
1438
|
+
} catch (_error) {
|
|
1439
|
+
return null;
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
function writeClaudeLimitsCache(limits, { home, nowMs = Date.now() } = {}) {
|
|
1444
|
+
if (!limits?.configured || limits.error || !hasClaudeWindow(limits)) return;
|
|
1445
|
+
const cachePath = resolveClaudeLimitsCachePath({ home });
|
|
1446
|
+
const payload = {
|
|
1447
|
+
claude: {
|
|
1448
|
+
five_hour: limits.five_hour || null,
|
|
1449
|
+
seven_day: limits.seven_day || null,
|
|
1450
|
+
seven_day_opus: limits.seven_day_opus || null,
|
|
1451
|
+
extra_usage: limits.extra_usage || null,
|
|
1452
|
+
cached_at: new Date(nowMs).toISOString(),
|
|
1453
|
+
},
|
|
1454
|
+
};
|
|
1455
|
+
try {
|
|
1456
|
+
fs.mkdirSync(path.dirname(cachePath), { recursive: true });
|
|
1457
|
+
const tmpPath = `${cachePath}.${process.pid}.tmp`;
|
|
1458
|
+
fs.writeFileSync(tmpPath, JSON.stringify(payload, null, 2), { encoding: "utf8", mode: 0o600 });
|
|
1459
|
+
fs.renameSync(tmpPath, cachePath);
|
|
1460
|
+
} catch (_error) {}
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
function resolveClaudeRateLimitPath({ home } = {}) {
|
|
1464
|
+
return path.join(home || os.homedir(), ".tokentracker", "tracker", CLAUDE_RATE_LIMIT_FILE);
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1467
|
+
// Returns the cooldown expiry in ms if a 429 cooldown is still active, else null.
|
|
1468
|
+
function readClaudeRateLimitRetryAtMs({ home, nowMs = Date.now() } = {}) {
|
|
1469
|
+
try {
|
|
1470
|
+
const parsed = JSON.parse(fs.readFileSync(resolveClaudeRateLimitPath({ home }), "utf8"));
|
|
1471
|
+
const retryAtMs = parseTimeMs(parsed?.retry_at);
|
|
1472
|
+
if (retryAtMs !== null && retryAtMs > nowMs) return retryAtMs;
|
|
1473
|
+
} catch (_error) {}
|
|
1474
|
+
return null;
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
function writeClaudeRateLimitCooldown(retryAfterSec, { home, nowMs = Date.now() } = {}) {
|
|
1478
|
+
const sec = Number.isFinite(retryAfterSec) && retryAfterSec > 0
|
|
1479
|
+
? Math.min(retryAfterSec, CLAUDE_RATE_LIMIT_MAX_COOLDOWN_SEC)
|
|
1480
|
+
: CLAUDE_RATE_LIMIT_DEFAULT_COOLDOWN_SEC;
|
|
1481
|
+
const cachePath = resolveClaudeRateLimitPath({ home });
|
|
1482
|
+
const payload = { retry_at: new Date(nowMs + sec * 1000).toISOString() };
|
|
1483
|
+
try {
|
|
1484
|
+
fs.mkdirSync(path.dirname(cachePath), { recursive: true });
|
|
1485
|
+
const tmpPath = `${cachePath}.${process.pid}.tmp`;
|
|
1486
|
+
fs.writeFileSync(tmpPath, JSON.stringify(payload, null, 2), { encoding: "utf8", mode: 0o600 });
|
|
1487
|
+
fs.renameSync(tmpPath, cachePath);
|
|
1488
|
+
} catch (_error) {}
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
function clearClaudeRateLimitCooldown({ home } = {}) {
|
|
1492
|
+
try {
|
|
1493
|
+
fs.unlinkSync(resolveClaudeRateLimitPath({ home }));
|
|
1494
|
+
} catch (_error) {}
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1274
1497
|
function resolveLsofBinary({ commandRunner } = {}) {
|
|
1275
1498
|
for (const candidate of ["/usr/sbin/lsof", "/usr/bin/lsof"]) {
|
|
1276
1499
|
if (fs.existsSync(candidate)) return candidate;
|
|
@@ -1698,9 +1921,13 @@ async function getUsageLimits({
|
|
|
1698
1921
|
const codexAccountId = codexAuthRefreshed?.accountId || null;
|
|
1699
1922
|
const codexPlanType = codexAuthRefreshed?.planType || null;
|
|
1700
1923
|
|
|
1924
|
+
// Skip the upstream Claude call entirely while a 429 cooldown is active — calling again
|
|
1925
|
+
// just renews the penalty. The result handling below serves cache or a cooldown message.
|
|
1926
|
+
const claudeRetryAtMs = claudeToken ? readClaudeRateLimitRetryAtMs({ home, nowMs }) : null;
|
|
1927
|
+
|
|
1701
1928
|
const providerFetch = withFetchTimeout(fetchImpl, providerTimeoutMs);
|
|
1702
1929
|
const [claudeResult, codexResult, cursor, kimi, gemini, kiro, antigravity, copilot, grok] = await Promise.all([
|
|
1703
|
-
claudeToken
|
|
1930
|
+
claudeToken && !claudeRetryAtMs
|
|
1704
1931
|
? withProviderTimeout(fetchClaudeUsageLimits(claudeToken, { fetchImpl: providerFetch, maxAttempts: 1 }), "Claude", providerTimeoutMs).then(
|
|
1705
1932
|
(value) => ({ status: "fulfilled", value }),
|
|
1706
1933
|
(reason) => ({ status: "rejected", reason }),
|
|
@@ -1733,9 +1960,7 @@ async function getUsageLimits({
|
|
|
1733
1960
|
let claude;
|
|
1734
1961
|
if (!claudeToken) {
|
|
1735
1962
|
claude = { configured: false };
|
|
1736
|
-
} else if (
|
|
1737
|
-
claude = { configured: true, error: claudeResult?.reason?.message || "Unknown error" };
|
|
1738
|
-
} else {
|
|
1963
|
+
} else if (claudeResult && claudeResult.status === "fulfilled") {
|
|
1739
1964
|
claude = {
|
|
1740
1965
|
configured: true,
|
|
1741
1966
|
error: null,
|
|
@@ -1744,6 +1969,28 @@ async function getUsageLimits({
|
|
|
1744
1969
|
seven_day_opus: claudeResult.value.seven_day_opus,
|
|
1745
1970
|
extra_usage: claudeResult.value.extra_usage,
|
|
1746
1971
|
};
|
|
1972
|
+
writeClaudeLimitsCache(claude, { home, nowMs });
|
|
1973
|
+
clearClaudeRateLimitCooldown({ home });
|
|
1974
|
+
} else {
|
|
1975
|
+
// Either a fresh 429 (record its cooldown) or a call we skipped because a cooldown was
|
|
1976
|
+
// already active. Serve the last successful read so the bars stay visible; otherwise
|
|
1977
|
+
// surface an accurate "retry in ~Nm" message rather than the misleading hardcoded one.
|
|
1978
|
+
const reason = claudeResult?.reason;
|
|
1979
|
+
if (reason?.code === "RATE_LIMITED") {
|
|
1980
|
+
writeClaudeRateLimitCooldown(reason.retryAfterSec, { home, nowMs });
|
|
1981
|
+
}
|
|
1982
|
+
const cached = readClaudeLimitsCache({ home, nowMs });
|
|
1983
|
+
if (cached) {
|
|
1984
|
+
claude = cached;
|
|
1985
|
+
} else {
|
|
1986
|
+
const retryAtMs = readClaudeRateLimitRetryAtMs({ home, nowMs }) || claudeRetryAtMs;
|
|
1987
|
+
claude = {
|
|
1988
|
+
configured: true,
|
|
1989
|
+
error: retryAtMs
|
|
1990
|
+
? formatClaudeRateLimitMessage(Math.round((retryAtMs - nowMs) / 1000))
|
|
1991
|
+
: reason?.message || "Unknown error",
|
|
1992
|
+
};
|
|
1993
|
+
}
|
|
1747
1994
|
}
|
|
1748
1995
|
|
|
1749
1996
|
let codex;
|
|
@@ -1766,6 +2013,8 @@ async function getUsageLimits({
|
|
|
1766
2013
|
plan_type: codexPlanType || null,
|
|
1767
2014
|
primary_window: codexResult.value.primary_window,
|
|
1768
2015
|
secondary_window: codexResult.value.secondary_window,
|
|
2016
|
+
spark_primary_window: codexResult.value.spark_primary_window,
|
|
2017
|
+
spark_secondary_window: codexResult.value.spark_secondary_window,
|
|
1769
2018
|
};
|
|
1770
2019
|
}
|
|
1771
2020
|
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as i,V as _,G as o,U as E,r as P,aG as K,i as R,L as S,aH as M}from"./main-CZ7INQ5C.js";import{u as O}from"./use-usage-limits-BgRs0aJ1.js";import{L as s,a as T,l as y,b as C,u as D}from"./use-limits-display-prefs-5el6WphI.js";import{C as k}from"./Card-BJVoMVdB.js";import{F as A}from"./FadeIn-DtXdVuFa.js";import{L as F}from"./LocalOnlyNotice-DysLhDFE.js";import"./arrow-up-right-SUDWxkx-.js";import"./download-B06KpWLb.js";const $=[3,2,3,3,2,2,3];function d({className:e}){return i.jsx("div",{className:_("rounded bg-oai-gray-200/70 dark:bg-oai-gray-800/70 animate-pulse",e)})}function G(){return i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx(d,{className:"h-3 w-12 shrink-0"}),i.jsx(d,{className:"flex-1 h-1.5 rounded-full min-w-0"}),i.jsx(d,{className:"h-3 w-[30px] shrink-0"}),i.jsx(d,{className:"h-3 w-6 shrink-0"})]})}function H({bars:e,index:t}){const r=t%3===0?"w-24":t%3===1?"w-20":"w-[4.5rem]";return i.jsxs("div",{className:"flex flex-col gap-1.5",children:[i.jsxs("div",{className:"flex items-center gap-1.5",children:[i.jsx(d,{className:"h-[14px] w-[14px] rounded shrink-0"}),i.jsx(d,{className:_("h-4",r)})]}),Array.from({length:e},(l,a)=>i.jsx(G,{},a))]})}function B(){return i.jsx(k,{children:i.jsxs("div",{className:"flex flex-col gap-3",children:[i.jsx(d,{className:"h-3.5 w-28"}),$.map((e,t)=>i.jsx(H,{bars:e,index:t},t))]})})}const j={claude:{windows(e){return[{key:"5h",labelKey:"limits.label.claude_5h",window:e.five_hour,pctField:"utilization",resetField:"resets_at"},{key:"7d",labelKey:"limits.label.claude_7d",window:e.seven_day,pctField:"utilization",resetField:"resets_at"},{key:"opus",labelKey:"limits.label.claude_opus",window:e.seven_day_opus,pctField:"utilization",resetField:"resets_at"}]}},codex:{windows(e){return[{key:"5h",labelKey:"limits.label.codex_5h",window:e.primary_window},{key:"7d",labelKey:"limits.label.codex_7d",window:e.secondary_window}]}},cursor:{windows(e){return[{key:"plan",labelKey:"limits.label.cursor_plan",window:e.primary_window},{key:"auto",labelKey:"limits.label.cursor_auto",window:e.secondary_window},{key:"api",labelKey:"limits.label.cursor_api",window:e.tertiary_window}]}},gemini:{windows(e){return[{key:"pro",labelKey:"limits.label.gemini_pro",window:e.primary_window},{key:"flash",labelKey:"limits.label.gemini_flash",window:e.secondary_window},{key:"lite",labelKey:"limits.label.gemini_lite",window:e.tertiary_window}]}},kimi:{extra:"kimi_parallel",windows(e){return[{key:"weekly",labelKey:"limits.label.kimi_weekly",window:e.primary_window},{key:"5h",labelKey:"limits.label.kimi_5h",window:e.secondary_window},{key:"total",labelKey:"limits.label.kimi_total",window:e.tertiary_window}]}},kiro:{windows(e){return[{key:"month",labelKey:"limits.label.kiro_month",window:e.primary_window},{key:"bonus",labelKey:"limits.label.kiro_bonus",window:e.secondary_window}]}},grok:{windows(e){return[{key:"month",labelKey:"limits.label.grok_month",window:e.primary_window},{key:"ondemand",labelKey:"limits.label.grok_ondemand",window:e.secondary_window}]}},antigravity:{windows(e){return[{key:"claude",labelKey:"limits.label.antigravity_claude",window:e.primary_window},{key:"gpro",labelKey:"limits.label.antigravity_gpro",window:e.secondary_window},{key:"flash",labelKey:"limits.label.antigravity_flash",window:e.tertiary_window}]}},copilot:{extra:"copilot_otel",windows(e){return[{key:"premium",labelKey:"limits.label.copilot_premium",window:e.primary_window},{key:"chat",labelKey:"limits.label.copilot_chat",window:e.secondary_window}]}}},U="shrink-0 text-oai-black dark:text-oai-white";function z(e){if(!e)return null;const t=typeof e=="number"?e*1e3:Date.parse(e);if(!Number.isFinite(t))return null;const r=t-Date.now();if(r<=0)return o("shared.time.now");const l=Math.floor(r/6e4);if(l<60)return`${l}m`;const a=Math.floor(l/60);return a<24?`${a}h`:`${Math.floor(a/24)}d`}function W(e,t){const r=t===s.REMAINING?100-e:e;return r>=90?"bg-red-500":r>=70?"bg-amber-500":"bg-emerald-500"}function V({label:e,pct:t,reset:r,mode:l=s.USED}){const a=Math.max(0,Math.min(100,Number(t)||0)),n=l===s.REMAINING?100-a:a,c=Math.round(n),w=n>0&&c===0?Math.max(n,.35):n;let u=String(c);return n>0&&c===0&&(u=o("limits.bar.sub_one_percent")),i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("span",{className:"text-[11px] text-oai-gray-500 dark:text-oai-gray-400 w-12 shrink-0",children:e}),i.jsx("div",{className:"flex-1 bg-oai-gray-100 dark:bg-oai-gray-700/50 rounded-full h-1.5 overflow-hidden",children:i.jsx("div",{className:`${W(n,l)} rounded-full h-full transition-[width] duration-500 ease-out`,style:{width:`${w}%`,minWidth:n>0?"3px":0}})}),i.jsxs("span",{className:"text-[11px] tabular-nums text-oai-gray-500 dark:text-oai-gray-400 w-9 text-right shrink-0 whitespace-nowrap",children:[u,"%"]}),r&&i.jsx("span",{className:"text-[10px] text-oai-gray-400 dark:text-oai-gray-500 w-6 text-right shrink-0",children:r})]})}function h({name:e,providerId:t,children:r}){const l=C(t);return i.jsxs("div",{className:"flex flex-col gap-1.5",children:[i.jsxs("div",{className:"flex items-center gap-1.5",children:[l?i.jsx(E,{provider:l,size:14,className:U}):null,i.jsx("span",{className:"text-sm font-medium text-oai-black dark:text-oai-white",children:e})]}),r]})}const Y=T;function m({children:e,tone:t="neutral"}){const r=t==="error"?"text-red-600 dark:text-red-400":"text-oai-gray-500 dark:text-oai-gray-400";return i.jsx("div",{className:`text-[11px] leading-snug ${r}`,children:e})}function X(e,t="used_percent"){return e?t==="utilization"?e.utilization:e.used_percent:null}function q(e,t="reset_at"){return e?t==="resets_at"?e.resets_at:e.reset_at:null}function J(e,t){return e.filter(r=>r.window).map(r=>i.jsx(V,{label:o(r.labelKey),pct:X(r.window,r.pctField),reset:z(q(r.window,r.resetField)),mode:t},r.key))}function Q({specs:e,mode:t,extra:r=null}){const l=J(e,t),a=l.length===0&&!r;return i.jsxs(i.Fragment,{children:[l,a?i.jsx(m,{children:o("limits.status.no_data")}):null,r]})}function Z(e,t,r,l,a=null){return i.jsx(h,{name:t,providerId:e,children:i.jsx(Q,{mode:r,specs:l,extra:a})},e)}function ee(e,t){return e==="kimi_parallel"&&t.parallel_limit?i.jsx(m,{children:o("limits.label.kimi_parallel",{count:t.parallel_limit})}):e==="copilot_otel"&&!t.otel_has_files&&!t.otel_enabled?i.jsx(re,{defaultDir:t.otel_default_dir}):null}function ie(e,t,r,l){const a=j[e];return a?Z(e,r,l,a.windows(t),ee(a.extra,t)):null}function te(e,t,r){if(!j[e])return null;if(!t?.configured)return i.jsx(h,{name:y(e),providerId:e,children:i.jsx(m,{children:o("limits.status.not_connected")})},e);if(t.error)return i.jsx(h,{name:y(e),providerId:e,children:i.jsx(m,{tone:"error",children:o("shared.error.prefix",{error:t.error})})},e);const l=y(e),a=t.plan_label?`${l} ${t.plan_label}`:l;return ie(e,t,a,r)}function re({defaultDir:e}){const[t,r]=P.useState(!1),a=["export COPILOT_OTEL_ENABLED=true","export COPILOT_OTEL_EXPORTER_TYPE=file",`export COPILOT_OTEL_FILE_EXPORTER_PATH="${e||"$HOME/.copilot/otel"}/copilot-otel-$(date +%Y%m%d).jsonl"`].join(`
|
|
2
|
-
`),n=async()=>{try{await navigator.clipboard.writeText(a),r(!0),setTimeout(()=>r(!1),1600)}catch{}};return i.jsxs("div",{className:"mt-1 rounded-md border border-amber-300/60 dark:border-amber-700/40 bg-amber-50/50 dark:bg-amber-900/10 px-2.5 py-2 text-[11px] text-oai-gray-600 dark:text-oai-gray-300",children:[i.jsx("div",{className:"font-medium text-oai-gray-700 dark:text-oai-gray-200",children:o("limits.copilot.otelHint.title")}),i.jsx("div",{className:"mt-0.5 leading-snug",children:o("limits.copilot.otelHint.body")}),i.jsx("pre",{className:"mt-1.5 overflow-x-auto rounded bg-oai-gray-100 dark:bg-oai-gray-900/60 px-2 py-1.5 font-mono text-[10.5px] leading-tight whitespace-pre",children:a}),i.jsx("button",{type:"button",onClick:n,className:"mt-1 inline-flex items-center gap-1 rounded border border-oai-gray-300 dark:border-oai-gray-700 px-1.5 py-0.5 text-[10.5px] text-oai-gray-700 dark:text-oai-gray-200 hover:bg-oai-gray-100 dark:hover:bg-oai-gray-800 transition-colors",children:t?o("limits.copilot.otelHint.copied"):o("limits.copilot.otelHint.copy")})]})}function ae({claude:e,codex:t,cursor:r,gemini:l,kimi:a,kiro:n,grok:c,antigravity:w,copilot:u,order:p,visibility:f,displayMode:N}){const v={claude:e,codex:t,cursor:r,gemini:l,kimi:a,kiro:n,grok:c,antigravity:w,copilot:u},I=Array.isArray(p)&&p.length>0?p:Y,b=N===s.REMAINING?s.REMAINING:s.USED,L=b===s.REMAINING?o("limits.settings.display_mode_remaining"):o("limits.settings.display_mode_used"),g=I.filter(x=>!f||f[x]!==!1).map(x=>te(x,v[x],b)).filter(Boolean);return i.jsx(A,{delay:.15,children:i.jsx(k,{children:i.jsxs("div",{className:"flex flex-col gap-3",children:[i.jsxs("h3",{className:"text-sm font-medium text-oai-gray-500 dark:text-oai-gray-300 uppercase tracking-wide",children:[o("limits.panel.title"),o("limits.panel.mode_separator"),L]}),g.length>0?g:i.jsx(m,{children:o("limits.status.all_hidden")})]})})})}const le=typeof window<"u"&&(window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1");function we(){const e=K(),{data:t,error:r,isLoading:l}=O(e?{initialRefresh:!0,initialState:e,publishToPreloadCache:!0}:{initialRefresh:!0,publishToPreloadCache:!0}),a=D();return!le&&!R()?i.jsx("div",{className:"flex flex-col flex-1 text-oai-black dark:text-oai-white font-oai antialiased",children:i.jsx(F,{})}):i.jsx("div",{className:"flex flex-col flex-1 text-oai-black dark:text-oai-white font-oai antialiased",children:i.jsx("main",{className:"flex-1 pt-8 sm:pt-10 pb-12 sm:pb-16",children:i.jsxs("div",{className:"mx-auto max-w-6xl px-4 sm:px-6",children:[i.jsxs("div",{className:"flex flex-row items-start justify-between gap-4 mb-8",children:[i.jsxs("div",{className:"min-w-0",children:[i.jsx("h1",{className:"text-3xl sm:text-4xl font-semibold tracking-tight text-oai-black dark:text-white mb-3",children:o("nav.limits")}),i.jsx("p",{className:"text-oai-gray-500 dark:text-oai-gray-400 text-sm sm:text-base",children:o("limits.page.subtitle")})]}),i.jsx(S,{to:"/settings","aria-label":o("limits.page.openSettings"),title:o("limits.page.openSettings"),className:"shrink-0 inline-flex h-9 w-9 items-center justify-center rounded-lg border border-oai-gray-200 dark:border-oai-gray-800 text-oai-gray-600 dark:text-oai-gray-400 hover:bg-oai-gray-100 dark:hover:bg-oai-gray-800 hover:text-oai-black dark:hover:text-white transition-colors no-underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-oai-brand-500",children:i.jsx(M,{className:"h-4 w-4","aria-hidden":!0})})]}),l?i.jsx(B,{}):i.jsxs(i.Fragment,{children:[r?i.jsx("p",{className:"mb-4 text-sm text-red-500 dark:text-red-400",children:o("shared.error.prefix",{error:r})}):null,i.jsx(ae,{claude:t?.claude,codex:t?.codex,cursor:t?.cursor,gemini:t?.gemini,kimi:t?.kimi,kiro:t?.kiro,grok:t?.grok,antigravity:t?.antigravity,copilot:t?.copilot,order:a.order,visibility:a.visibility,displayMode:a.displayMode})]})]})})})}export{we as LimitsPage};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{j as e,G as o,c3 as _,aR as P,r as u,a_ as I,R as B,V as M}from"./main-CZ7INQ5C.js";import{S as D}from"./Select-16iq_C1U.js";import{u as E,T as K}from"./use-native-settings-BsOpSNnV.js";import{F as j,S as G,a as $}from"./FadeIn-DtXdVuFa.js";import{A as z}from"./arrow-up-right-SUDWxkx-.js";import{D as R}from"./download-B06KpWLb.js";import"./SelectItemText-Bwctpnf1.js";import"./useScrollLock-Dyho5BJU.js";import"./Card-BJVoMVdB.js";const H=["todayTokens","todayCost"],F=[{id:"todayTokens",label:"Today Tokens",shortLabel:"Tokens",category:"tokens"},{id:"todayCost",label:"Today Cost",shortLabel:"Cost",category:"cost"},{id:"last7dTokens",label:"Last 7 Days",shortLabel:"7d",category:"tokens"},{id:"totalTokens",label:"Total Tokens",shortLabel:"Total",category:"tokens"},{id:"totalCost",label:"Total Cost",shortLabel:"All $",category:"cost"},{id:"claude5h",label:"Claude 5h Limit",shortLabel:"Cl 5h",category:"limits"},{id:"claude7d",label:"Claude 7d Limit",shortLabel:"Cl 7d",category:"limits"},{id:"codex5h",label:"Codex 5h Limit",shortLabel:"Cx 5h",category:"limits"},{id:"codex7d",label:"Codex 7d Limit",shortLabel:"Cx 7d",category:"limits"},{id:"cursorPlan",label:"Cursor Plan Limit",shortLabel:"Cu Plan",category:"limits"},{id:"cursorAuto",label:"Cursor Auto Limit",shortLabel:"Cu Auto",category:"limits"},{id:"cursorAPI",label:"Cursor API Limit",shortLabel:"Cu API",category:"limits"},{id:"geminiPro",label:"Gemini Pro Limit",shortLabel:"Gm Pro",category:"limits"},{id:"geminiFlash",label:"Gemini Flash Limit",shortLabel:"Gm Flash",category:"limits"},{id:"geminiLite",label:"Gemini Lite Limit",shortLabel:"Gm Lite",category:"limits"},{id:"kimiWeekly",label:"Kimi Weekly Limit",shortLabel:"Km Wk",category:"limits"},{id:"kimi5h",label:"Kimi 5h Limit",shortLabel:"Km 5h",category:"limits"},{id:"kimiTotal",label:"Kimi Total Limit",shortLabel:"Km Tot",category:"limits"},{id:"kiroMonth",label:"Kiro Monthly Limit",shortLabel:"Kr Mo",category:"limits"},{id:"kiroBonus",label:"Kiro Bonus Limit",shortLabel:"Kr Bn",category:"limits"},{id:"copilotPremium",label:"Copilot Premium Limit",shortLabel:"Co Prem",category:"limits"},{id:"copilotChat",label:"Copilot Chat Limit",shortLabel:"Co Chat",category:"limits"},{id:"antigravityClaude",label:"Antigravity Claude Limit",shortLabel:"Ag Cl",category:"limits"},{id:"antigravityGPro",label:"Antigravity Gemini Pro Limit",shortLabel:"Ag GPro",category:"limits"},{id:"antigravityFlash",label:"Antigravity Flash Limit",shortLabel:"Ag Fl",category:"limits"}];function v(t,i=F,r=2){const a=new Set(i.map(n=>n.id)),l=new Set,s=Array.isArray(t)?t.filter(n=>!a.has(n)||l.has(n)?!1:(l.add(n),!0)):[];return(s.length>0?s:H).slice(0,Math.max(1,Number(r)||2))}const O=264,U=124,g="ui-rounded, -apple-system, system-ui",L=["#5A8CF2","#9973E6","#4DB8A6","#E68C59"],V={claude:"#C77DFF",codex:"#34C759",cursor:"#FFCC00",gemini:"#0A84FF"};function X(t){return t>=.9?"#E64D4D":t>=.7?"#D9A633":"#33B866"}function b({size:t="sm",children:i}){const r=t==="lg",a=r?560:264,l=r?32:22;return e.jsx("div",{className:M("flex w-full items-center justify-center rounded-xl bg-oai-gray-100 dark:bg-oai-gray-950/60",r?"py-10 sm:py-14 px-6":"py-6 px-4"),children:e.jsx("div",{className:"overflow-hidden bg-white dark:bg-oai-gray-800 shadow-oai-md dark:shadow-[0_2px_4px_rgba(0,0,0,0.4),0_8px_24px_rgba(0,0,0,0.5)]",style:{width:"100%",maxWidth:a,aspectRatio:`${O} / ${U}`,borderRadius:l},children:i})})}function Y({size:t="sm"}){const i="M0,104 L14,104 C26,98 34,100 44,96 S58,88 68,92 80,100 90,94 102,80 112,82 126,92 136,88 150,74 162,76 178,88 188,86 204,72 216,74 236,84 250,80 L264,80",r=`${i} L264,124 L0,124 Z`,a=`sparkArea-${t}`;return e.jsx(b,{size:t,children:e.jsxs("svg",{viewBox:"0 0 264 124",className:"h-full w-full","aria-hidden":"true",children:[e.jsx("defs",{children:e.jsxs("linearGradient",{id:a,x1:"0",y1:"0",x2:"0",y2:"1",children:[e.jsx("stop",{offset:"0%",stopColor:"#0A84FF",stopOpacity:"0.18"}),e.jsx("stop",{offset:"100%",stopColor:"#0A84FF",stopOpacity:"0"})]})}),e.jsx("text",{x:"14",y:"20",className:"fill-oai-gray-500 dark:fill-oai-gray-400",fontSize:"8",fontWeight:"700",letterSpacing:"0.6",children:"TODAY"}),e.jsx("text",{x:"14",y:"46",className:"fill-oai-black dark:fill-white",fontSize:"22",fontWeight:"700",fontFamily:g,children:"203.2M"}),e.jsx("text",{x:"14",y:"60",className:"fill-oai-gray-500 dark:fill-oai-gray-400",fontSize:"8",fontWeight:"500",fontFamily:g,children:"$129.56 ±0%"}),e.jsx("text",{x:"134",y:"20",className:"fill-oai-gray-500 dark:fill-oai-gray-400",fontSize:"8",fontWeight:"700",letterSpacing:"0.6",children:"7 DAYS"}),e.jsx("text",{x:"134",y:"46",className:"fill-oai-black dark:fill-white",fontSize:"22",fontWeight:"700",fontFamily:g,children:"880.9M"}),e.jsx("text",{x:"134",y:"60",className:"fill-oai-gray-500 dark:fill-oai-gray-400",fontSize:"8",fontWeight:"500",fontFamily:g,children:"$673.61"}),e.jsx("path",{d:r,fill:`url(#${a})`,stroke:"none"}),e.jsx("path",{d:i,fill:"none",stroke:"#0A84FF",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round"})]})})}const N=(()=>{const r=[];for(let a=0;a<26;a++)for(let l=0;l<7;l++){const s=Math.sin((a+1)*12.9898+(l+1)*78.233+17)*43758.5453,c=Math.floor(Math.abs(s-Math.floor(s))*100);r.push({w:a,d:l,v:c})}return r})();function C(t,i){return t<18?i?"#262626":"#e5e5e5":t<38?"rgba(10, 132, 255, 0.28)":t<58?"rgba(10, 132, 255, 0.50)":t<80?"rgba(10, 132, 255, 0.75)":"#0A84FF"}function Z(){return e.jsx(b,{children:e.jsxs("svg",{viewBox:"0 0 264 124",className:"h-full w-full","aria-hidden":"true",children:[e.jsx("g",{transform:`translate(${19.5}, 10)`,className:"hidden dark:inline",children:N.map(s=>e.jsx("rect",{x:s.w*(7.5+1.2),y:s.d*(8+1.2),width:7.5,height:8,rx:"1.3",fill:C(s.v,!0)},`d-${s.w}-${s.d}`))}),e.jsx("g",{transform:`translate(${19.5}, 10)`,className:"dark:hidden",children:N.map(s=>e.jsx("rect",{x:s.w*(7.5+1.2),y:s.d*(8+1.2),width:7.5,height:8,rx:"1.3",fill:C(s.v,!1)},`l-${s.w}-${s.d}`))}),e.jsx("text",{x:19.5,y:"102",className:"fill-oai-black dark:fill-white",fontSize:"10",fontWeight:"700",fontFamily:g,children:"10.3B"}),e.jsx("text",{x:19.5+30,y:"102",className:"fill-oai-gray-500 dark:fill-oai-gray-400",fontSize:"9",fontWeight:"500",children:"tokens · 202 active days"})]})})}function q(){const t=[{name:"claude-opus-4-6",value:"586.4M",pct:59},{name:"claude-sonnet-4-5-20250929",value:"218.7M",pct:22},{name:"gpt-5.4",value:"80.6M",pct:8},{name:"composer-2-fast",value:"52.1M",pct:5}],i=22,r=28,a=14,l=236;return e.jsx(b,{children:e.jsx("svg",{viewBox:"0 0 264 124",className:"h-full w-full","aria-hidden":"true",children:t.map((s,c)=>{const n=r+c*i,h=L[c%L.length];return e.jsxs("g",{children:[e.jsx("circle",{cx:"18",cy:n-3,r:"2.5",fill:h}),e.jsx("text",{x:"26",y:n,className:"fill-oai-black dark:fill-white",fontSize:"9",fontWeight:"500",children:s.name}),e.jsx("text",{x:"218",y:n,textAnchor:"end",className:"fill-oai-gray-500 dark:fill-oai-gray-400",fontSize:"9",fontWeight:"600",fontFamily:g,children:s.value}),e.jsxs("text",{x:"250",y:n,textAnchor:"end",className:"fill-oai-gray-500 dark:fill-oai-gray-400",fontSize:"8",fontWeight:"600",fontFamily:g,children:[s.pct,"%"]}),e.jsx("rect",{x:a,y:n+4,width:l,height:"2.8",rx:"1.4",className:"fill-oai-gray-200 dark:fill-oai-gray-700"}),e.jsx("rect",{x:a,y:n+4,width:Math.max(l*(s.pct/100),4),height:"2.8",rx:"1.4",fill:h})]},s.name)})})})}function J(){const t=[{label:"Claude · 7d",source:"claude",reset:"in 1d",pct:61},{label:"Claude · 5h",source:"claude",reset:"in 4h 28m",pct:4},{label:"Cursor",source:"cursor",reset:"in 25d",pct:51},{label:"Codex · weekly",source:"codex",reset:"in 1d",pct:32}],i=22,r=28,a=14,l=236;return e.jsx(b,{children:e.jsx("svg",{viewBox:"0 0 264 124",className:"h-full w-full","aria-hidden":"true",children:t.map((s,c)=>{const n=r+c*i,h=V[s.source],y=X(s.pct/100);return e.jsxs("g",{children:[e.jsx("circle",{cx:"18",cy:n-3,r:"2.5",fill:h}),e.jsx("text",{x:"26",y:n,className:"fill-oai-black dark:fill-white",fontSize:"9",fontWeight:"500",children:s.label}),e.jsx("text",{x:"218",y:n,textAnchor:"end",className:"fill-oai-gray-500 dark:fill-oai-gray-400",fontSize:"8",fontWeight:"500",fontFamily:g,children:s.reset}),e.jsxs("text",{x:"250",y:n,textAnchor:"end",className:"fill-oai-black dark:fill-white",fontSize:"9",fontWeight:"700",fontFamily:g,children:[s.pct,"%"]}),e.jsx("rect",{x:a,y:n+4,width:l,height:"2.8",rx:"1.4",className:"fill-oai-gray-200 dark:fill-oai-gray-700"}),e.jsx("rect",{x:a,y:n+4,width:Math.max(l*(s.pct/100),4),height:"2.8",rx:"1.4",fill:y})]},s.label)})})})}function Q(t){switch(t.category){case"cost":return"$8.42";case"limits":return"62%";default:return t.id==="last7dTokens"?"1.8B":"203M"}}function ee(t,i){switch(t){case"todayTokens":return o("menubar.metric.today_tokens");case"todayCost":return o("menubar.metric.today_cost");case"last7dTokens":return o("menubar.metric.last_7d_tokens");case"totalTokens":return o("menubar.metric.total_tokens");case"totalCost":return o("menubar.metric.total_cost");case"claude5h":return o("menubar.metric.claude_5h");case"claude7d":return o("menubar.metric.claude_7d");case"codex5h":return o("menubar.metric.codex_5h");case"codex7d":return o("menubar.metric.codex_7d");default:return i}}function te(t,i){const r=new Set(i.map(l=>l.id)),a=t.filter(l=>r.has(l));for(const l of i){if(a.length>=2)break;a.includes(l.id)||a.push(l.id)}return a.slice(0,2)}function ae({slotConfigs:t,showStats:i}){return e.jsx("div",{className:"flex justify-center rounded-xl bg-gradient-to-b from-oai-gray-100 to-oai-gray-200 px-6 py-8 dark:from-oai-gray-950/80 dark:to-oai-gray-900/80",children:e.jsxs("div",{className:"inline-flex items-stretch rounded-md shadow-[0_1px_3px_rgba(0,0,0,0.18)] ring-1 ring-black/10 dark:ring-white/10 px-3",style:{background:"linear-gradient(180deg, #2c2c2e 0%, #1c1c1e 100%)"},children:[e.jsx("div",{className:"flex items-center pl-2 pr-1 py-2.5",children:e.jsx("img",{src:"/clawd/mini/idle-tight.svg",alt:"","aria-hidden":"true",className:"block shrink-0",style:{height:22,width:"auto"},draggable:"false"})}),i?t.map(({slot:r,item:a},l)=>e.jsxs(B.Fragment,{children:[l>0?e.jsx("span",{className:"my-1 w-px bg-white/20","aria-hidden":"true"}):null,e.jsxs("div",{className:M("flex min-w-[52px] flex-col items-center justify-center py-1.5",l===0?"pl-1 pr-2":"px-2"),children:[e.jsx("span",{className:"text-[13px] font-semibold leading-none tabular-nums text-white",children:a?.previewValue||"--"}),e.jsx("span",{className:"mt-[2px] text-[6px] font-semibold uppercase leading-none text-white/75",children:a?.shortLabel||"Metric"})]})]},r)):null]})})}function ie({slot:t,value:i,options:r,disabled:a,onChange:l}){const s=t===0?o("menubar.slot.primary"):o("menubar.slot.secondary");return e.jsxs("div",{className:"flex min-w-0 flex-col gap-1.5",children:[e.jsx("span",{className:"text-[11px] font-semibold uppercase tracking-[0.08em] text-oai-gray-500 dark:text-oai-gray-400",children:s}),e.jsx(D,{value:i,disabled:a,ariaLabel:s,onValueChange:c=>l(t,c),options:r.map(c=>({value:c.id,label:c.displayLabel})),matchTriggerWidth:!0,className:"w-full px-3 py-2 text-sm font-medium"})]})}function S({label:t,hint:i,checked:r,disabled:a,onChange:l}){return e.jsxs("div",{className:"flex items-center justify-between gap-3 py-3",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsx("p",{className:"text-sm font-medium text-oai-black dark:text-white",children:t}),i?e.jsx("p",{className:"mt-0.5 text-xs text-oai-gray-500 dark:text-oai-gray-400",children:i}):null]}),e.jsx(K,{checked:r,disabled:a,onChange:l,ariaLabel:t})]})}function se(){const{available:t,settings:i,setSetting:r}=E(),a=u.useMemo(()=>(Array.isArray(i?.menuBarAvailableItems)?i.menuBarAvailableItems:F).map(m=>({...m,displayLabel:ee(m.id,m.label),previewValue:Q(m)})),[i?.menuBarAvailableItems]),l=Number(i?.menuBarMaxItems)||2,s=u.useMemo(()=>v(i?.menuBarItems,a,l),[a,l,i?.menuBarItems]),c=u.useMemo(()=>te(s,a),[a,s]),n=i?.showStats!==!1,h=d=>{r("menuBarItems",v(d,a,l))},y=(d,m)=>{const x=[...c];x[d===0?1:0]!==m&&(x[d]=m,h(x))},p=[0,1].map(d=>{const m=c[d]||a[d]?.id||"",k=c[d===0?1:0],W=a.filter(f=>f.id===m||f.id!==k),T=a.find(f=>f.id===m);return{slot:d,currentValue:m,options:W,item:T}}),w=i?.animatedIcon!==!1;return e.jsxs("article",{className:"rounded-xl border border-oai-gray-200 bg-white p-5 transition-colors duration-200 dark:border-oai-gray-800 dark:bg-oai-gray-900 sm:p-6",children:[e.jsx(ae,{slotConfigs:p,showStats:n}),e.jsx("div",{className:"mt-5 grid grid-cols-1 gap-3 sm:grid-cols-2 sm:gap-4",children:p.map(({slot:d,currentValue:m,options:x})=>e.jsx(ie,{slot:d,value:m,options:x,disabled:!t||!n,onChange:y},d))}),e.jsxs("div",{className:"mt-5 divide-y divide-oai-gray-100 border-t border-oai-gray-100 dark:divide-oai-gray-800 dark:border-oai-gray-800",children:[e.jsx(S,{label:o("settings.menubar.showStats"),hint:t?o("settings.menubar.showStatsHint"):o("menubar.native_only"),checked:n,disabled:!t,onChange:()=>r("showStats",!n)}),e.jsx(S,{label:o("settings.menubar.animatedIcon"),hint:o("settings.menubar.animatedIconHint"),checked:w,disabled:!t,onChange:()=>r("animatedIcon",!w)})]})]})}function re(){const[t,i]=u.useState("loading");return u.useEffect(()=>{if(typeof window>"u")return;if(I()){i("native");return}const r=(navigator.userAgent||"").toLowerCase(),a=/mac/.test(r)&&!/iphone|ipad/.test(r);i(a?"mac-web":"other")},[]),t}function le(){const t=re();return t==="loading"?e.jsx("div",{className:"h-10 w-40","aria-hidden":"true"}):t==="native"?e.jsxs("button",{type:"button",onClick:()=>_("openWidgetGallery"),className:"inline-flex h-10 items-center gap-2 rounded-lg bg-oai-black px-4 text-sm font-medium text-white transition-colors hover:bg-oai-gray-800 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-oai-brand-500 focus-visible:ring-offset-2 dark:bg-white dark:text-oai-black dark:hover:bg-oai-gray-200",children:[o("widgets.cta.open_gallery"),e.jsx(z,{className:"h-4 w-4","aria-hidden":"true"})]}):t==="mac-web"?e.jsxs("a",{href:"https://github.com/mm7894215/TokenTracker/releases/latest",target:"_blank",rel:"noopener noreferrer",className:"inline-flex h-10 items-center gap-2 rounded-lg bg-oai-black px-4 text-sm font-medium text-white no-underline transition-colors hover:bg-oai-gray-800 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-oai-brand-500 focus-visible:ring-offset-2 dark:bg-white dark:text-oai-black dark:hover:bg-oai-gray-200",children:[e.jsx(R,{className:"h-4 w-4","aria-hidden":"true"}),o("widgets.cta.download")]}):e.jsxs("span",{className:"inline-flex h-10 items-center gap-2 rounded-lg border border-oai-gray-200 bg-oai-gray-50 px-4 text-sm font-medium text-oai-gray-500 dark:border-oai-gray-800 dark:bg-oai-gray-900 dark:text-oai-gray-400",children:[e.jsx(P,{className:"h-4 w-4","aria-hidden":"true"}),o("widgets.cta.macos_only")]})}const oe=[{id:"summary",Preview:Y,nameKey:"widgets.summary.name",descKey:"widgets.summary.description"},{id:"heatmap",Preview:Z,nameKey:"widgets.heatmap.name",descKey:"widgets.heatmap.description"},{id:"topModels",Preview:q,nameKey:"widgets.topModels.name",descKey:"widgets.topModels.description"},{id:"limits",Preview:J,nameKey:"widgets.limits.name",descKey:"widgets.limits.description"}];function ne({Preview:t,nameKey:i,descKey:r}){return e.jsxs("article",{className:"flex h-full flex-col rounded-xl border border-oai-gray-200 bg-white p-4 transition-colors duration-200 dark:border-oai-gray-800 dark:bg-oai-gray-900 sm:p-5",children:[e.jsx(t,{}),e.jsxs("div",{className:"mt-4",children:[e.jsx("h3",{className:"text-[15px] font-semibold text-oai-black dark:text-white",children:o(i)}),e.jsx("p",{className:"mt-1.5 text-sm leading-relaxed text-oai-gray-500 dark:text-oai-gray-400",children:o(r)})]})]})}function A({titleKey:t}){return e.jsx("h2",{className:"mb-4 text-xl font-semibold tracking-tight text-oai-black dark:text-white sm:mb-5 sm:text-2xl",children:o(t)})}function ye(){return e.jsx("div",{className:"flex flex-col flex-1 text-oai-black dark:text-oai-white font-oai antialiased",children:e.jsx("main",{className:"flex-1 pt-8 sm:pt-10 pb-12 sm:pb-16",children:e.jsxs("div",{className:"mx-auto max-w-5xl px-4 sm:px-6",children:[e.jsx(j,{y:12,children:e.jsxs("header",{className:"mb-10 flex items-start justify-between gap-4 sm:mb-12",children:[e.jsx("h1",{className:"text-3xl font-semibold tracking-tight text-oai-black dark:text-white sm:text-4xl",children:o("widgets.page.title")}),e.jsx("div",{className:"shrink-0",children:e.jsx(le,{})})]})}),e.jsx(j,{y:12,delay:.06,children:e.jsxs("section",{"aria-label":o("widgets.menubar.section.title"),className:"mb-12 sm:mb-14",children:[e.jsx(A,{titleKey:"widgets.menubar.section.title"}),e.jsx(se,{})]})}),e.jsxs("section",{"aria-label":o("widgets.gallery.section.title"),children:[e.jsx(A,{titleKey:"widgets.gallery.section.title"}),e.jsx(G,{staggerDelay:.08,initialDelay:.04,children:e.jsx("div",{className:"grid grid-cols-1 gap-4 lg:grid-cols-2 lg:gap-5",children:oe.map(({id:t,Preview:i,nameKey:r,descKey:a})=>e.jsx($,{children:e.jsx(ne,{Preview:i,nameKey:r,descKey:a})},t))})})]})]})})})}export{ye as WidgetsPage};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as a,ab as m,aI as f}from"./main-CZ7INQ5C.js";function p(s){const r=!!s?.initialState,[h,c]=a.useState(()=>r?s?.initialState?.data??null:null),[S,l]=a.useState(()=>r?s?.initialState?.error??null:null),[g,b]=a.useState(!r),i=!!s?.initialRefresh,o=!!s?.publishToPreloadCache,n=a.useCallback((e,t)=>{!o||!e||typeof e!="object"||m(e,{source:t})},[o]),d=a.useCallback(async()=>{try{const e=await f({refresh:!0}),t=e&&typeof e=="object"?e:null;c(t),l(null),n(t,"manual-refresh")}catch(e){l(e?.message||String(e))}},[n]);return a.useEffect(()=>{if(r&&!i)return;let e=!1;return(async()=>{try{const t=await f(i?{refresh:!0}:{});if(e)return;const u=t&&typeof t=="object"?t:null;c(u),l(null),n(u,"page-load")}catch(t){if(e)return;l(t?.message||String(t))}finally{e||b(!1)}})(),()=>{e=!0}},[r,i,n]),{data:h,error:S,isLoading:g,refresh:d}}export{p as u};
|