tokentracker-cli 0.55.0 → 0.56.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-f31ixbyV.js → ActivityHeatmap-B_tfEHcm.js} +1 -1
- package/dashboard/dist/assets/{Card-P4pcpfgk.js → Card-D-kLfqyr.js} +1 -1
- package/dashboard/dist/assets/{DashboardPage-CbKBu564.js → DashboardPage-C97dctZq.js} +1 -1
- package/dashboard/dist/assets/{DevicePage-BYPTGtFL.js → DevicePage-B36WBvsn.js} +1 -1
- package/dashboard/dist/assets/{DialogTitle-BZf_YGYe.js → DialogTitle--VIyiTEE.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-CchoMg8O.js → FadeIn-B8pvdF9J.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-CCp4lXQc.js → HeaderGithubStar-B0gHTi9N.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-FFn_rJ1E.js → IpCheckPage-Bq6MMJHQ.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-Deu1ltMr.js → LandingPage-CZIEkNWt.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardAvatar-R5cgtwIk.js → LeaderboardAvatar-BMRcGGFZ.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardPage-CNfXjJ_i.js → LeaderboardPage-B5ffZ11y.js} +3 -3
- package/dashboard/dist/assets/{LeaderboardProfileModal-Bg5oiqmZ.js → LeaderboardProfileModal-Bz2n03P4.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardProfilePage-DTE6Jfwq.js → LeaderboardProfilePage-BP5loLjy.js} +1 -1
- package/dashboard/dist/assets/LimitsPage-DzJSi6xG.js +2 -0
- package/dashboard/dist/assets/{LocalOnlyNotice-DboBMrlb.js → LocalOnlyNotice-CvfM7Yeu.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-DtILt4Dm.js → LoginPage-D2LALlWv.js} +1 -1
- package/dashboard/dist/assets/{PopoverPopup-B_qSI_Kj.js → PopoverPopup-BAT6qwPl.js} +1 -1
- package/dashboard/dist/assets/{ResetPasswordPage-C-PiZJ1Q.js → ResetPasswordPage-s76Qggro.js} +1 -1
- package/dashboard/dist/assets/{Select-CXseeIjs.js → Select-CMEwM-Mo.js} +1 -1
- package/dashboard/dist/assets/{SelectItemText-DpEjTcov.js → SelectItemText-s-8ZSDQn.js} +1 -1
- package/dashboard/dist/assets/{SettingsPage-pOpyqaby.js → SettingsPage-BKzrvCej.js} +1 -1
- package/dashboard/dist/assets/{SkillsPage-DdIi6lYW.js → SkillsPage-BX5iuYSx.js} +1 -1
- package/dashboard/dist/assets/{WidgetsPage-Chb3bxVH.js → WidgetsPage-CBD2lBZ1.js} +1 -1
- package/dashboard/dist/assets/{WrappedPage-DdmCoaz8.js → WrappedPage-DpNAeMIM.js} +1 -1
- package/dashboard/dist/assets/{agent-logos-YpISvAMw.js → agent-logos-Bggjr2yj.js} +1 -1
- package/dashboard/dist/assets/{arrow-up-right-ThOp2PrF.js → arrow-up-right-C6z7x7NL.js} +1 -1
- package/dashboard/dist/assets/{download-H-ks1oyK.js → download-DBjVOuOZ.js} +1 -1
- package/dashboard/dist/assets/{info-D3b_SGE-.js → info-DJ0Ty3Yt.js} +1 -1
- package/dashboard/dist/assets/main-Bb0Bwbp7.css +1 -0
- package/dashboard/dist/assets/{main-CZFzpc5d.js → main-Cqhrkqr2.js} +6 -3
- package/dashboard/dist/assets/{use-limits-display-prefs-BzB-pF4J.js → use-limits-display-prefs-DddAHmHH.js} +1 -1
- package/dashboard/dist/assets/{use-native-settings-BrJdMq29.js → use-native-settings-Cha6She4.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-CcbaY6uV.js → use-usage-limits-BJXjE59K.js} +1 -1
- package/dashboard/dist/assets/{useCurrency-Bf7zAMJX.js → useCurrency-C63XmlQt.js} +1 -1
- package/dashboard/dist/assets/{useScrollLock-BC_qj4dr.js → useScrollLock-CHF80tR1.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dashboard/dist/share.html +2 -2
- package/package.json +1 -1
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/usage-limits.js +139 -15
- package/dashboard/dist/assets/LimitsPage-plnNcsI8.js +0 -2
- package/dashboard/dist/assets/main-DCfktJsK.css +0 -1
package/src/lib/usage-limits.js
CHANGED
|
@@ -5,6 +5,7 @@ const os = require("node:os");
|
|
|
5
5
|
const path = require("node:path");
|
|
6
6
|
const http = require("node:http");
|
|
7
7
|
const https = require("node:https");
|
|
8
|
+
const { performance } = require("node:perf_hooks");
|
|
8
9
|
|
|
9
10
|
const {
|
|
10
11
|
detectClaudeCodeSubscriptionDetails,
|
|
@@ -174,6 +175,8 @@ async function fetchClaudeUsageLimits(accessToken, { fetchImpl = fetch, maxAttem
|
|
|
174
175
|
// reading mislabels it as "5h". Aligned with steipete/CodexBar's rate-window normalizer.
|
|
175
176
|
const CODEX_SESSION_WINDOW_SECONDS = 18000;
|
|
176
177
|
const CODEX_WEEKLY_WINDOW_SECONDS = 604800;
|
|
178
|
+
const CODEX_RESET_CREDIT_LIST_TIMEOUT_MS = 3000;
|
|
179
|
+
const CODEX_RESET_CREDIT_LIST_TIMEOUT_GUARD_MS = 25;
|
|
177
180
|
|
|
178
181
|
function classifyCodexWindow(window) {
|
|
179
182
|
if (!window || typeof window !== "object") return null;
|
|
@@ -291,9 +294,103 @@ function normalizeCodexSparkRateWindows(additionalRateLimits) {
|
|
|
291
294
|
};
|
|
292
295
|
}
|
|
293
296
|
|
|
297
|
+
function normalizeCodexResetCreditCount(value) {
|
|
298
|
+
return Number.isInteger(value) && value >= 0 ? value : null;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
function normalizeCodexResetCredit(row, nowMs) {
|
|
302
|
+
if (!row || typeof row !== "object" || Array.isArray(row)) return null;
|
|
303
|
+
if (row.status !== "available") return null;
|
|
304
|
+
|
|
305
|
+
const hasResetType = row.reset_type !== undefined && row.reset_type !== null;
|
|
306
|
+
if (hasResetType && row.reset_type !== "codex_rate_limits") return null;
|
|
307
|
+
|
|
308
|
+
const expiresAt = row.expires_at;
|
|
309
|
+
if (typeof expiresAt !== "string") return null;
|
|
310
|
+
const expiresAtMs = Date.parse(expiresAt);
|
|
311
|
+
if (!Number.isFinite(expiresAtMs) || expiresAtMs < nowMs) return null;
|
|
312
|
+
|
|
313
|
+
const credit = {
|
|
314
|
+
status: row.status,
|
|
315
|
+
expires_at: expiresAt,
|
|
316
|
+
};
|
|
317
|
+
if (typeof row.reset_type === "string") {
|
|
318
|
+
credit.reset_type = row.reset_type;
|
|
319
|
+
}
|
|
320
|
+
if (typeof row.granted_at === "string") {
|
|
321
|
+
credit.granted_at = row.granted_at;
|
|
322
|
+
}
|
|
323
|
+
return { credit, expiresAtMs };
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
function normalizeCodexResetCredits(resetCredits, nowMs = Date.now()) {
|
|
327
|
+
if (!resetCredits || typeof resetCredits !== "object" || Array.isArray(resetCredits)) return null;
|
|
328
|
+
|
|
329
|
+
const availableCount = normalizeCodexResetCreditCount(resetCredits.available_count);
|
|
330
|
+
const totalEarnedCount = normalizeCodexResetCreditCount(resetCredits.total_earned_count);
|
|
331
|
+
const normalized = [];
|
|
332
|
+
if (Array.isArray(resetCredits.credits) && availableCount !== 0) {
|
|
333
|
+
for (const row of resetCredits.credits) {
|
|
334
|
+
const entry = normalizeCodexResetCredit(row, nowMs);
|
|
335
|
+
if (entry) normalized.push(entry);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const credits = normalized
|
|
340
|
+
.sort((a, b) => a.expiresAtMs - b.expiresAtMs)
|
|
341
|
+
.slice(0, 50)
|
|
342
|
+
.map((entry) => entry.credit);
|
|
343
|
+
|
|
344
|
+
if (availableCount === null && totalEarnedCount === null && credits.length === 0) {
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return {
|
|
349
|
+
available_count: availableCount,
|
|
350
|
+
total_earned_count: totalEarnedCount,
|
|
351
|
+
credits: availableCount === 0 ? [] : credits,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function codexResetCreditListTimeoutMs(remainingProviderBudgetMs) {
|
|
356
|
+
if (!Number.isFinite(remainingProviderBudgetMs)) {
|
|
357
|
+
return CODEX_RESET_CREDIT_LIST_TIMEOUT_MS;
|
|
358
|
+
}
|
|
359
|
+
if (remainingProviderBudgetMs <= 0) return 0;
|
|
360
|
+
const guardedBudgetMs = Math.floor(remainingProviderBudgetMs - CODEX_RESET_CREDIT_LIST_TIMEOUT_GUARD_MS);
|
|
361
|
+
if (guardedBudgetMs <= 0) return 0;
|
|
362
|
+
return Math.min(CODEX_RESET_CREDIT_LIST_TIMEOUT_MS, guardedBudgetMs);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
async function fetchCodexResetCreditList(fetchImpl, headers, timeoutMs = CODEX_RESET_CREDIT_LIST_TIMEOUT_MS) {
|
|
366
|
+
let timer = null;
|
|
367
|
+
try {
|
|
368
|
+
const request = Promise.resolve()
|
|
369
|
+
.then(() => fetchImpl("https://chatgpt.com/backend-api/wham/rate-limit-reset-credits", {
|
|
370
|
+
method: "GET",
|
|
371
|
+
headers,
|
|
372
|
+
}))
|
|
373
|
+
.then(async (res) => {
|
|
374
|
+
if (!res.ok) return null;
|
|
375
|
+
return normalizeCodexResetCredits(await res.json());
|
|
376
|
+
});
|
|
377
|
+
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
378
|
+
return await request;
|
|
379
|
+
}
|
|
380
|
+
const timeout = new Promise((resolve) => {
|
|
381
|
+
timer = setTimeout(() => resolve(null), timeoutMs);
|
|
382
|
+
});
|
|
383
|
+
return await Promise.race([request, timeout]);
|
|
384
|
+
} catch (_err) {
|
|
385
|
+
return null;
|
|
386
|
+
} finally {
|
|
387
|
+
if (timer) clearTimeout(timer);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
294
391
|
async function fetchCodexUsageLimits(
|
|
295
392
|
accessToken,
|
|
296
|
-
{ fetchImpl = fetch, accountId = null } = {},
|
|
393
|
+
{ fetchImpl = fetch, accountId = null, providerTimeoutMs = DEFAULT_PROVIDER_TIMEOUT_MS } = {},
|
|
297
394
|
) {
|
|
298
395
|
const headers = {
|
|
299
396
|
Authorization: `Bearer ${accessToken}`,
|
|
@@ -305,27 +402,53 @@ async function fetchCodexUsageLimits(
|
|
|
305
402
|
headers["ChatGPT-Account-Id"] = accountId;
|
|
306
403
|
}
|
|
307
404
|
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
405
|
+
const startedAtMs = performance.now();
|
|
406
|
+
const usage = await withProviderTimeout(Promise.resolve()
|
|
407
|
+
.then(() => fetchImpl("https://chatgpt.com/backend-api/wham/usage", {
|
|
408
|
+
method: "GET",
|
|
409
|
+
headers,
|
|
410
|
+
}))
|
|
411
|
+
.then(async (res) => {
|
|
412
|
+
// 401/403/404 from wham means "no usage data available for this auth state" — render
|
|
413
|
+
// a neutral empty state instead of a red "Fetch failed" error.
|
|
414
|
+
if (res.status === 401 || res.status === 403 || res.status === 404) {
|
|
415
|
+
return { body: null };
|
|
416
|
+
}
|
|
417
|
+
if (res.status !== 200) {
|
|
418
|
+
throw new Error(`Codex API returned ${res.status}`);
|
|
419
|
+
}
|
|
420
|
+
return { body: await res.json() };
|
|
421
|
+
}), "Codex", providerTimeoutMs);
|
|
422
|
+
if (!usage.body) {
|
|
315
423
|
return {
|
|
316
424
|
primary_window: null,
|
|
317
425
|
secondary_window: null,
|
|
318
426
|
spark_primary_window: null,
|
|
319
427
|
spark_secondary_window: null,
|
|
428
|
+
reset_credits: null,
|
|
320
429
|
};
|
|
321
430
|
}
|
|
322
|
-
|
|
323
|
-
|
|
431
|
+
const body = usage.body;
|
|
432
|
+
let resetCredits = normalizeCodexResetCredits(body.rate_limit_reset_credits);
|
|
433
|
+
// This semi-private sibling endpoint is read-only; /wham/usage remains the stable count fallback.
|
|
434
|
+
const remainingProviderBudgetMs = Number.isFinite(providerTimeoutMs) && providerTimeoutMs > 0
|
|
435
|
+
? providerTimeoutMs - (performance.now() - startedAtMs)
|
|
436
|
+
: CODEX_RESET_CREDIT_LIST_TIMEOUT_MS;
|
|
437
|
+
const resetCreditListTimeoutMs = codexResetCreditListTimeoutMs(remainingProviderBudgetMs);
|
|
438
|
+
if (resetCreditListTimeoutMs > 0) {
|
|
439
|
+
const resetCreditsList = await fetchCodexResetCreditList(
|
|
440
|
+
fetchImpl,
|
|
441
|
+
headers,
|
|
442
|
+
resetCreditListTimeoutMs,
|
|
443
|
+
);
|
|
444
|
+
if (resetCreditsList) {
|
|
445
|
+
resetCredits = resetCreditsList;
|
|
446
|
+
}
|
|
324
447
|
}
|
|
325
|
-
const body = await res.json();
|
|
326
448
|
return {
|
|
327
449
|
...normalizeCodexRateWindows(body.rate_limit || {}),
|
|
328
450
|
...normalizeCodexSparkRateWindows(body.additional_rate_limits),
|
|
451
|
+
reset_credits: resetCredits,
|
|
329
452
|
};
|
|
330
453
|
}
|
|
331
454
|
|
|
@@ -2174,11 +2297,11 @@ async function fetchUsageLimitsUncached({
|
|
|
2174
2297
|
)
|
|
2175
2298
|
: Promise.resolve(null),
|
|
2176
2299
|
codexToken
|
|
2177
|
-
?
|
|
2178
|
-
|
|
2179
|
-
|
|
2300
|
+
? fetchCodexUsageLimits(codexToken, {
|
|
2301
|
+
fetchImpl: providerFetch,
|
|
2302
|
+
accountId: codexAccountId,
|
|
2180
2303
|
providerTimeoutMs,
|
|
2181
|
-
).then(
|
|
2304
|
+
}).then(
|
|
2182
2305
|
(value) => ({ status: "fulfilled", value }),
|
|
2183
2306
|
(reason) => ({ status: "rejected", reason }),
|
|
2184
2307
|
)
|
|
@@ -2257,6 +2380,7 @@ async function fetchUsageLimitsUncached({
|
|
|
2257
2380
|
secondary_window: codexResult.value.secondary_window,
|
|
2258
2381
|
spark_primary_window: codexResult.value.spark_primary_window,
|
|
2259
2382
|
spark_secondary_window: codexResult.value.spark_secondary_window,
|
|
2383
|
+
reset_credits: codexResult.value.reset_credits,
|
|
2260
2384
|
};
|
|
2261
2385
|
}
|
|
2262
2386
|
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as i,V as M,r as f,G as d,U as C,aG as $,i as D,L as A,aH as W}from"./main-CZFzpc5d.js";import{u as G}from"./use-usage-limits-CcbaY6uV.js";import{L as u,a as H,l as g,b as U,u as z}from"./use-limits-display-prefs-BzB-pF4J.js";import{C as E}from"./Card-P4pcpfgk.js";import{F as B}from"./FadeIn-CchoMg8O.js";import{L as V}from"./LocalOnlyNotice-DboBMrlb.js";import"./arrow-up-right-ThOp2PrF.js";import"./download-H-ks1oyK.js";const X=[3,2,3,3,2,2,3];function h({className:e}){return i.jsx("div",{className:M("rounded bg-oai-gray-200/70 dark:bg-oai-gray-800/70 animate-pulse",e)})}function Y(){return i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx(h,{className:"h-3 w-12 shrink-0"}),i.jsx(h,{className:"flex-1 h-1.5 rounded-full min-w-0"}),i.jsx(h,{className:"h-3 w-[30px] shrink-0"}),i.jsx(h,{className:"h-3 w-6 shrink-0"})]})}function q({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(h,{className:"h-[14px] w-[14px] rounded shrink-0"}),i.jsx(h,{className:M("h-4",r)})]}),Array.from({length:e},(a,n)=>i.jsx(Y,{},n))]})}function J(){return i.jsx(E,{children:i.jsxs("div",{className:"flex flex-col gap-3",children:[i.jsx(h,{className:"h-3.5 w-28"}),X.map((e,t)=>i.jsx(q,{bars:e,index:t},t))]})})}function Q(e,t){if(!(e>0))return null;const r=(e-t)/e;return Number.isFinite(r)?Math.min(Math.max(r,0),1):null}function Z(e,t,r=.03){return e>t+r}function ee(e){const t=Math.max(0,Math.floor(e)),r=Math.floor(t/3600);return r>24?`${Math.floor(r/24)}d`:r>0?`${r}h`:`${Math.floor(t/60)}m`}function te(e,t){if(typeof e.windowSeconds=="number")return e.windowSeconds;if(e.windowSecondsField&&t){const r=t[e.windowSecondsField];return typeof r=="number"&&r>0?r:null}return null}function S(e){return e==null?NaN:typeof e=="number"?e*1e3:Date.parse(e)}function ie({usedPercent:e,windowSeconds:t,resetMs:r,mode:a,now:n=Date.now()}){const o=Math.min(Math.max(Number(e)||0,0),100)/100,s={pacePercent:null,paceOver:!1,expectedPercent:null,runsOutEta:null,projectedEnd:null};if(!(t>0)||!Number.isFinite(r))return s;const c=Math.max(0,(r-n)/1e3),l=Q(t,c);if(l==null)return s;if(s.expectedPercent=Math.round(l*100),s.paceOver=Z(o,l),o>=.05){const m=a==="remaining"?1-l:l;s.pacePercent=m*100}if(l>.02&&o>0){const m=t*l,x=o/m,p=o/l;p>=1&&x>0?s.runsOutEta=ee((1-o)/x):s.projectedEnd=Math.round(Math.min(p,1)*100)}return s}const I={claude:{windows(e){return[{key:"5h",labelKey:"limits.label.claude_5h",window:e.five_hour,pctField:"utilization",resetField:"resets_at",windowSeconds:5*3600},{key:"7d",labelKey:"limits.label.claude_7d",window:e.seven_day,pctField:"utilization",resetField:"resets_at",windowSeconds:7*86400},{key:"opus",labelKey:"limits.label.claude_opus",window:e.seven_day_opus,pctField:"utilization",resetField:"resets_at",windowSeconds:7*86400}]}},codex:{windows(e){return[{key:"5h",labelKey:"limits.label.codex_5h",window:e.primary_window,windowSecondsField:"limit_window_seconds"},{key:"7d",labelKey:"limits.label.codex_7d",window:e.secondary_window,windowSecondsField:"limit_window_seconds"},{key:"spark-5h",labelKey:"limits.label.codex_spark_5h",window:e.spark_primary_window,windowSecondsField:"limit_window_seconds"},{key:"spark-7d",labelKey:"limits.label.codex_spark_7d",window:e.spark_secondary_window,windowSecondsField:"limit_window_seconds"}]}},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,windowSeconds:7*86400},{key:"5h",labelKey:"limits.label.kimi_5h",window:e.secondary_window,windowSeconds:5*3600},{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}]}}},re="shrink-0 text-oai-black dark:text-oai-white";function ne(e){const t=S(e);if(!Number.isFinite(t))return null;const r=t-Date.now();if(r<=0)return d("shared.time.now");const a=Math.floor(r/6e4);if(a<60)return`${a}m`;const n=Math.floor(a/60);return n<24?`${n}h`:`${Math.floor(n/24)}d`}function ae(e,t){const r=t===u.REMAINING?100-e:e;return r>=90?"bg-red-500":r>=70?"bg-amber-500":"bg-emerald-500"}function b(e,t="used_percent"){return e?t==="utilization"?e.utilization:e.used_percent:null}function L(e,t="reset_at"){return e?t==="resets_at"?e.resets_at:e.reset_at:null}function le(e,t){return ie({usedPercent:b(e.window,e.pctField),windowSeconds:te(e,e.window),resetMs:S(L(e.window,e.resetField)),mode:t})}function oe({label:e,pct:t,reset:r,mode:a=u.USED,pacePercent:n=null,paceOver:o=!1}){const s=Math.max(0,Math.min(100,Number(t)||0)),c=a===u.REMAINING?100-s:s,l=Math.round(c),m=c>0&&l===0?Math.max(c,.35):c;let x=String(l);c>0&&l===0&&(x=d("limits.bar.sub_one_percent"));const p=n==null?null:Math.max(0,Math.min(100,n));return i.jsxs("div",{className:"flex items-center gap-2",children:[i.jsx("span",{"data-limit-label":"",className:"text-[11px] text-oai-gray-500 dark:text-oai-gray-400 shrink-0 whitespace-nowrap",style:{width:"var(--tt-limits-label-w)"},children:e}),i.jsxs("div",{className:"relative flex-1 bg-oai-gray-100 dark:bg-oai-gray-700/50 rounded-full h-1.5 overflow-hidden",children:[i.jsx("div",{className:`${ae(c,a)} rounded-full h-full transition-[width] duration-500 ease-out`,style:{width:`${m}%`,minWidth:c>0?"3px":0}}),p!=null&&i.jsxs(i.Fragment,{children:[i.jsx("div",{className:"absolute top-0 h-full bg-oai-gray-100 dark:bg-oai-gray-700/50",style:{left:`calc(${p}% - 3px)`,width:"6px"}}),i.jsx("div",{className:`absolute top-0 h-full ${o?"bg-red-500":"bg-emerald-500"}`,style:{left:`calc(${p}% - 1px)`,width:"2px"}})]})]}),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:[x,"%"]}),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 se(e,t,r){const a=d(e.labelKey),n=r===u.REMAINING,o=l=>n?100-l:l;if(t.expectedPercent==null){const l=Math.round(Math.max(0,Math.min(100,Number(b(e.window,e.pctField))||0)));return n?d("limits.explain.remaining",{label:a,used:o(l)}):d("limits.explain.used",{label:a,used:l})}if(t.paceOver){if(t.runsOutEta)return d("limits.explain.ahead_eta",{label:a,eta:t.runsOutEta});const l=o(t.projectedEnd??100);return d(n?"limits.explain.ahead_pct_remaining":"limits.explain.ahead_pct",{label:a,pct:l})}const s=Math.round(Math.max(0,Math.min(100,Number(b(e.window,e.pctField))||0))),c=o(t.projectedEnd??s);return d(n?"limits.explain.on_track_remaining":"limits.explain.on_track",{label:a,pct:c})}function de({rows:e,mode:t}){if(e.length===0)return null;const r=t===u.REMAINING;return i.jsxs("div",{className:"mt-1 flex flex-col gap-1",children:[e.map(({spec:a,pace:n})=>i.jsx("div",{className:"text-[11px] leading-snug text-oai-gray-600 dark:text-oai-gray-300",children:se(a,n,t)},a.key)),i.jsx("div",{className:"mt-1 pt-1.5 border-t border-oai-gray-200/70 dark:border-oai-gray-700/50 text-[10.5px] leading-snug text-oai-gray-400 dark:text-oai-gray-500",children:d(r?"limits.explain.body_remaining":"limits.explain.body")})]})}function _({name:e,providerId:t,children:r,expandable:a=!1,expanded:n=!1,onToggle:o}){const s=U(t),c=i.jsxs("div",{className:"flex items-center gap-1.5",children:[s?i.jsx(C,{provider:s,size:14,className:re}):null,i.jsx("span",{className:"text-sm font-medium text-oai-black dark:text-oai-white",children:e})]});return a?i.jsxs("div",{role:"button",tabIndex:0,"aria-expanded":n,onClick:o,onKeyDown:l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),o?.())},className:"flex flex-col gap-1.5 -mx-1.5 px-1.5 py-1 rounded-lg cursor-pointer transition-colors hover:bg-oai-gray-50 dark:hover:bg-oai-gray-800/40 aria-expanded:bg-oai-gray-50 dark:aria-expanded:bg-oai-gray-800/40",children:[c,r]}):i.jsxs("div",{className:"flex flex-col gap-1.5",children:[c,r]})}const ce=H;function y({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 me({rows:e,mode:t,extra:r=null}){const a=e.length===0&&!r;return i.jsxs(i.Fragment,{children:[e.map(({spec:n,pace:o})=>i.jsx(oe,{label:d(n.labelKey),pct:b(n.window,n.pctField),reset:ne(L(n.window,n.resetField)),mode:t,pacePercent:o.pacePercent,paceOver:o.paceOver},n.key)),a?i.jsx(y,{children:d("limits.status.no_data")}):null,r]})}function ue(e,t){return e==="kimi_parallel"&&t.parallel_limit?i.jsx(y,{children:d("limits.label.kimi_parallel",{count:t.parallel_limit})}):e==="copilot_otel"&&!t.otel_has_files&&!t.otel_enabled?i.jsx(we,{defaultDir:t.otel_default_dir}):null}function xe(e,t,r,a,n,o){const s=I[e];if(!s)return null;const c=s.windows(t).filter(m=>m.window).map(m=>({spec:m,pace:le(m,a)})),l=ue(s.extra,t);return i.jsxs(_,{name:r,providerId:e,expandable:c.length>0,expanded:n,onToggle:o,children:[i.jsx(me,{mode:a,rows:c,extra:l}),n?i.jsx(de,{rows:c,mode:a}):null]},e)}function pe(e,t,r,a,n){if(!I[e])return null;if(!t?.configured)return i.jsx(_,{name:g(e),providerId:e,children:i.jsx(y,{children:d("limits.status.not_connected")})},e);if(t.error)return i.jsx(_,{name:g(e),providerId:e,children:i.jsx(y,{tone:"error",children:d("shared.error.prefix",{error:t.error})})},e);const o=g(e),s=t.plan_label?`${o} ${t.plan_label}`:o;return xe(e,t,s,r,a,n)}function we({defaultDir:e}){const[t,r]=f.useState(!1),n=["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
|
-
`),o=async s=>{s.stopPropagation();try{await navigator.clipboard.writeText(n),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:d("limits.copilot.otelHint.title")}),i.jsx("div",{className:"mt-0.5 leading-snug",children:d("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:n}),i.jsx("button",{type:"button",onClick:o,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?d("limits.copilot.otelHint.copied"):d("limits.copilot.otelHint.copy")})]})}function he(e){const[t,r]=f.useState(0);return f.useLayoutEffect(()=>{const a=e.current;if(!a)return;const n=a.querySelectorAll("[data-limit-label]");let o=0;const s=n.length>0?document.createElement("canvas").getContext("2d"):null;if(s){const l=window.getComputedStyle(n[0]);s.font=`${l.fontStyle} ${l.fontWeight} ${l.fontSize} ${l.fontFamily}`;for(const m of n)o=Math.max(o,s.measureText(m.textContent).width)}const c=Math.ceil(o);r(l=>l===c?l:c)}),t}function fe({claude:e,codex:t,cursor:r,gemini:a,kimi:n,kiro:o,grok:s,antigravity:c,copilot:l,order:m,visibility:x,displayMode:p}){const P={claude:e,codex:t,cursor:r,gemini:a,kimi:n,kiro:o,grok:s,antigravity:c,copilot:l},k=f.useRef(null),j=he(k),[F,O]=f.useState(null),R=Array.isArray(m)&&m.length>0?m:ce,v=p===u.REMAINING?u.REMAINING:u.USED,K=v===u.REMAINING?d("limits.settings.display_mode_remaining"):d("limits.settings.display_mode_used"),N=R.filter(w=>!x||x[w]!==!1).map(w=>pe(w,P[w],v,F===w,()=>O(T=>T===w?null:w))).filter(Boolean);return i.jsx(B,{delay:.15,children:i.jsx(E,{children:i.jsxs("div",{ref:k,className:"flex flex-col gap-3",style:j>0?{"--tt-limits-label-w":`${j}px`}:void 0,children:[i.jsxs("h3",{className:"text-sm font-medium text-oai-gray-500 dark:text-oai-gray-300 uppercase tracking-wide",children:[d("limits.panel.title"),d("limits.panel.mode_separator"),K]}),N.length>0?N:i.jsx(y,{children:d("limits.status.all_hidden")})]})})})}const ye=typeof window<"u"&&(window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1");function Ee(){const e=$(),{data:t,error:r,isLoading:a}=G(e?{initialRefresh:!0,initialState:e,publishToPreloadCache:!0}:{initialRefresh:!0,publishToPreloadCache:!0}),n=z();return!ye&&!D()?i.jsx("div",{className:"flex flex-col flex-1 text-oai-black dark:text-oai-white font-oai antialiased",children:i.jsx(V,{})}):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:d("nav.limits")}),i.jsx("p",{className:"text-oai-gray-500 dark:text-oai-gray-400 text-sm sm:text-base",children:d("limits.page.subtitle")})]}),i.jsx(A,{to:"/settings","aria-label":d("limits.page.openSettings"),title:d("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(W,{className:"h-4 w-4","aria-hidden":!0})})]}),a?i.jsx(J,{}):i.jsxs(i.Fragment,{children:[r?i.jsx("p",{className:"mb-4 text-sm text-red-500 dark:text-red-400",children:d("shared.error.prefix",{error:r})}):null,i.jsx(fe,{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:n.order,visibility:n.visibility,displayMode:n.displayMode})]})]})})})}export{Ee as LimitsPage};
|