tokentracker-cli 0.87.2 → 0.87.4
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/{AchievementBadge-C468-Rsw.js → AchievementBadge-jaWv39Mh.js} +1 -1
- package/dashboard/dist/assets/{AchievementsPage-CZWzSdiH.js → AchievementsPage-CqIWdffx.js} +2 -2
- package/dashboard/dist/assets/{AchievementsSection-DXt6VbwH.js → AchievementsSection-RAoIBoQ_.js} +1 -1
- package/dashboard/dist/assets/{BadgeDetailModal-BtGvpqQm.js → BadgeDetailModal-CYaSfxwZ.js} +1 -1
- package/dashboard/dist/assets/{Card-DZ-_fXkw.js → Card-Cl4XFCGL.js} +1 -1
- package/dashboard/dist/assets/{ClawdAnimated-9rXaHo1-.js → ClawdAnimated-DuFB46-u.js} +1 -1
- package/dashboard/dist/assets/{CommandPalette-sqIvZNsH.js → CommandPalette-CLfTNQK0.js} +1 -1
- package/dashboard/dist/assets/{CommunityStatsModal-c8VohIqQ.js → CommunityStatsModal-DCRCXmPl.js} +1 -1
- package/dashboard/dist/assets/{ConfirmModal-Ct2HLdds.js → ConfirmModal-B0IuSw4g.js} +1 -1
- package/dashboard/dist/assets/{Controls-DPtXGUGi.js → Controls-BJF1FutB.js} +1 -1
- package/dashboard/dist/assets/DashboardPage-BFthq-Oc.js +1 -0
- package/dashboard/dist/assets/{DevicePage-Ds4GEuqY.js → DevicePage-iZn2m4Y3.js} +1 -1
- package/dashboard/dist/assets/{DialogClose-B2IAbJG4.js → DialogClose-CdPKVRcX.js} +1 -1
- package/dashboard/dist/assets/DialogDescription-pCAELf1b.js +1 -0
- package/dashboard/dist/assets/{DialogTitle-BIwLH6gA.js → DialogTitle-Ul-NH9HD.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-DPS7_DOB.js → FadeIn-Bb3pNOAn.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-CsSgr9Hd.js → HeaderGithubStar-CtUK-3_x.js} +1 -1
- package/dashboard/dist/assets/{HoverTooltip-CLGZW2d-.js → HoverTooltip-B3TmAZtV.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-DEM_uk69.js → IpCheckPage-CXcY3jc-.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-BQ3YzZ68.js → LandingPage-BK4sn4MV.js} +2 -2
- package/dashboard/dist/assets/{LeaderboardAvatar-ySznr4Ml.js → LeaderboardAvatar-AYzG1gTH.js} +1 -1
- package/dashboard/dist/assets/LeaderboardPage-DhKcc74d.js +2 -0
- package/dashboard/dist/assets/{LeaderboardProfileModal-Drvsb5xF.js → LeaderboardProfileModal-DvmDBmOL.js} +3 -3
- package/dashboard/dist/assets/{LeaderboardProfilePage-BD0P-zZF.js → LeaderboardProfilePage-1_GGQngL.js} +1 -1
- package/dashboard/dist/assets/{LimitsPage-Mbn2mj6S.js → LimitsPage-dSEtf2TB.js} +1 -1
- package/dashboard/dist/assets/{LocalOnlyNotice-BsKgtoVa.js → LocalOnlyNotice-Bo1dtxi6.js} +1 -1
- package/dashboard/dist/assets/{LoginCard-CTQDdHcx.js → LoginCard-BpjNU-ah.js} +1 -1
- package/dashboard/dist/assets/{LoginModal-BxCyLDEW.js → LoginModal-D3_vPG1R.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-ftxnX8g1.js → LoginPage-BoeLhbwK.js} +1 -1
- package/dashboard/dist/assets/{PetPage-CQsfqsm8.js → PetPage-BnkNWvcV.js} +1 -1
- package/dashboard/dist/assets/PopoverPopup-CkaOLLN4.js +1 -0
- package/dashboard/dist/assets/{ProviderIcon-7Tkq9_m6.js → ProviderIcon-B3hZ1YWD.js} +1 -1
- package/dashboard/dist/assets/{ResetPasswordPage-D-MPpQd1.js → ResetPasswordPage-BusTiA5M.js} +1 -1
- package/dashboard/dist/assets/{SegmentedControl-CYFrzu9w.js → SegmentedControl-C_IwmWnO.js} +1 -1
- package/dashboard/dist/assets/{Select-Dp4V9p6t.js → Select-Dj3hUGFb.js} +1 -1
- package/dashboard/dist/assets/SelectItemText-BWaMX4pY.js +1 -0
- package/dashboard/dist/assets/{ServiceStatusPage-BT6hvvLW.js → ServiceStatusPage-BnnCouAs.js} +1 -1
- package/dashboard/dist/assets/{SessionsPage-BopeZBiH.js → SessionsPage-DMU5CiFf.js} +1 -1
- package/dashboard/dist/assets/SettingsPage-_cJl0qwK.js +1 -0
- package/dashboard/dist/assets/{SkillsPage-Cr8O6eOH.js → SkillsPage-Cz3tV65I.js} +1 -1
- package/dashboard/dist/assets/{TokenGalaxy-BoUsrUEs.js → TokenGalaxy-BddGGmti.js} +1 -1
- package/dashboard/dist/assets/{ToolbarRootContext-CwRaHhMN.js → ToolbarRootContext-Q_DQJlr5.js} +1 -1
- package/dashboard/dist/assets/{TrendMonitor-BV2ugEsw.js → TrendMonitor-CVi7mLtI.js} +1 -1
- package/dashboard/dist/assets/{WidgetsPage-B7r4mvrw.js → WidgetsPage-BdIGupvg.js} +1 -1
- package/dashboard/dist/assets/{WrappedPage-CFU9l22i.js → WrappedPage-BB-orT9Q.js} +1 -1
- package/dashboard/dist/assets/{__vite-browser-external-Db9onipF.js → __vite-browser-external-egzerGU6.js} +2 -2
- package/dashboard/dist/assets/{agent-logos-DSSn_SPi.js → agent-logos-B2pH4QTS.js} +1 -1
- package/dashboard/dist/assets/{arrow-up-right-COvrArNz.js → arrow-up-right-CEUtBwnj.js} +1 -1
- package/dashboard/dist/assets/{check-CasSqiev.js → check-Ct-iMhaB.js} +1 -1
- package/dashboard/dist/assets/{chevron-right-B1PMeNoD.js → chevron-right-CIcqYgwy.js} +1 -1
- package/dashboard/dist/assets/{copy-D67vycfp.js → copy-Bx07orpr.js} +1 -1
- package/dashboard/dist/assets/{download-adOCFO2v.js → download-6N9dBj_W.js} +1 -1
- package/dashboard/dist/assets/{external-link-DVanKEuy.js → external-link-B39v_fs8.js} +1 -1
- package/dashboard/dist/assets/{flame-RbiHZM9b.js → flame-xbjyxu-1.js} +1 -1
- package/dashboard/dist/assets/{format-tokens-DhMp1e1L.js → format-tokens-C1ZXX8ed.js} +1 -1
- package/dashboard/dist/assets/{icons-BC0p_aGr.js → icons-D7dTRGnv.js} +1 -1
- package/dashboard/dist/assets/{index-A41xjc83.js → index-BJ8Q1dU0.js} +1 -1
- package/dashboard/dist/assets/{index-DrgBqR3o.js → index-MbSf_y6N.js} +1 -1
- package/dashboard/dist/assets/{index-CaRyTJ6K.js → index-pxtsHew5.js} +1 -1
- package/dashboard/dist/assets/{info-D9LwqlnC.js → info-YSmBFAMa.js} +1 -1
- package/dashboard/dist/assets/{limits-providers-CRHpXhmW.js → limits-providers-BDltKBG_.js} +1 -1
- package/dashboard/dist/assets/{link-2-B5f4qFR0.js → link-2--CbT8swK.js} +1 -1
- package/dashboard/dist/assets/{loader-circle-DCmwZEdS.js → loader-circle-B5Hs89F2.js} +1 -1
- package/dashboard/dist/assets/{maximize-2-BMalEDCZ.js → maximize-2-Cj3P-Bay.js} +1 -1
- package/dashboard/dist/assets/modifiers.esm-BXOR3VJH.js +1 -0
- package/dashboard/dist/assets/{provider-display-qMFRUZHm.js → provider-display-BXtFP7Ak.js} +1 -1
- package/dashboard/dist/assets/{react-BnaPNGj8.js → react-DujpLuOh.js} +1 -1
- package/dashboard/dist/assets/{search-BrqBkLs2.js → search-BswhdD2a.js} +1 -1
- package/dashboard/dist/assets/{skills-api-vo3iM6yD.js → skills-api-CGohvSGo.js} +1 -1
- package/dashboard/dist/assets/sortable.esm-BXiHjoqY.js +5 -0
- package/dashboard/dist/assets/{store-BwMVXuz3.js → store-BTdeRhbU.js} +1 -1
- package/dashboard/dist/assets/{terminal-BiyUh_8k.js → terminal-DawYBEVr.js} +1 -1
- package/dashboard/dist/assets/{trash-2-DAr4sqkX.js → trash-2-CSt4wZ-I.js} +1 -1
- package/dashboard/dist/assets/{use-community-stats-Cg48Zphy.js → use-community-stats-CHZTziox.js} +1 -1
- package/dashboard/dist/assets/{use-limits-display-prefs-DfKtH1Zn.js → use-limits-display-prefs-ChK-GCxK.js} +1 -1
- package/dashboard/dist/assets/use-ordered-list-DyyjthSr.js +1 -0
- package/dashboard/dist/assets/use-reduced-motion-B9hTo-eX.js +1 -0
- package/dashboard/dist/assets/{use-session-efficiency-pref-CMDTCAAd.js → use-session-efficiency-pref-Dv1clCTZ.js} +1 -1
- package/dashboard/dist/assets/{use-transform-B2d9Txt5.js → use-transform-DyBvIIFA.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-CJbTUl9W.js → use-usage-limits-DrhY6h3M.js} +1 -1
- package/dashboard/dist/assets/{useCurrency-B0hJte5f.js → useCurrency-BgFo76Yb.js} +1 -1
- package/dashboard/dist/assets/{useScrollLock-DuosKdSB.js → useScrollLock-DPW-g15w.js} +1 -1
- package/dashboard/dist/assets/{useTokenFormat-DB8pKLFM.js → useTokenFormat-DrVDs8zo.js} +1 -1
- package/dashboard/dist/assets/{zap-rbzC4XgP.js → zap-Dsg_ZyH3.js} +1 -1
- package/dashboard/dist/index.html +1 -1
- package/dashboard/dist/ip-check.html +1 -1
- package/dashboard/dist/leaderboard.html +1 -1
- package/dashboard/dist/share.html +1 -1
- package/package.json +1 -1
- package/src/lib/codex-token-refresh.js +35 -7
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/usage-limits.js +39 -28
- package/dashboard/dist/assets/DashboardPage-C65hbl8o.js +0 -1
- package/dashboard/dist/assets/DialogDescription-DeRza-LI.js +0 -1
- package/dashboard/dist/assets/LeaderboardPage-Br4JCoVE.js +0 -2
- package/dashboard/dist/assets/PopoverPopup-C16r8jQC.js +0 -1
- package/dashboard/dist/assets/SelectItemText-CxhBeoxx.js +0 -1
- package/dashboard/dist/assets/SettingsPage-D03GJJBd.js +0 -1
- package/dashboard/dist/assets/use-ordered-list-CnXfrWeF.js +0 -5
- package/dashboard/dist/assets/use-reduced-motion-BIgYrbON.js +0 -1
package/src/lib/usage-limits.js
CHANGED
|
@@ -523,15 +523,16 @@ async function fetchCodexUsageLimits(
|
|
|
523
523
|
// 401/403/404 from wham means "no usage data available for this auth state" — render
|
|
524
524
|
// a neutral empty state instead of a red "Fetch failed" error.
|
|
525
525
|
if (res.status === 401 || res.status === 403 || res.status === 404) {
|
|
526
|
-
return { body: null };
|
|
526
|
+
return { body: null, status: res.status };
|
|
527
527
|
}
|
|
528
528
|
if (res.status !== 200) {
|
|
529
529
|
throw new Error(`Codex API returned ${res.status}`);
|
|
530
530
|
}
|
|
531
|
-
return { body: await res.json() };
|
|
531
|
+
return { body: await res.json(), status: res.status };
|
|
532
532
|
}), "Codex", providerTimeoutMs);
|
|
533
533
|
if (!usage.body) {
|
|
534
534
|
return {
|
|
535
|
+
upstream_status: usage.status,
|
|
535
536
|
primary_window: null,
|
|
536
537
|
secondary_window: null,
|
|
537
538
|
credit_window: null,
|
|
@@ -558,6 +559,7 @@ async function fetchCodexUsageLimits(
|
|
|
558
559
|
}
|
|
559
560
|
}
|
|
560
561
|
return {
|
|
562
|
+
upstream_status: usage.status,
|
|
561
563
|
...normalizeCodexRateWindows(body.rate_limit || {}),
|
|
562
564
|
credit_window: normalizeCodexCreditWindow(body.spend_control?.individual_limit),
|
|
563
565
|
...normalizeCodexSparkRateWindows(body.additional_rate_limits),
|
|
@@ -3051,14 +3053,14 @@ async function fetchUsageLimitsUncached({
|
|
|
3051
3053
|
]);
|
|
3052
3054
|
const claudePlanType = claudeSubscription?.planType || null;
|
|
3053
3055
|
|
|
3054
|
-
//
|
|
3055
|
-
//
|
|
3056
|
-
//
|
|
3057
|
-
// refresh failure falls through to using the existing (possibly stale) token, then the
|
|
3058
|
-
// 4xx graceful path in fetchCodexUsageLimits surfaces a neutral state instead of red.
|
|
3056
|
+
// Match the official Codex CLI: prefer the access token's JWT expiry and refresh only
|
|
3057
|
+
// within five minutes of it; fall back to last_refresh >8 days for opaque/legacy tokens.
|
|
3058
|
+
// Best-effort: a refresh failure still falls through to the existing access token.
|
|
3059
3059
|
let refreshError = null;
|
|
3060
3060
|
let codexAuthRefreshed = codexAuth;
|
|
3061
|
-
if (codexAuth
|
|
3061
|
+
if (codexAuth
|
|
3062
|
+
&& isTokenStale(codexAuth.lastRefresh, nowMs, codexAuth.accessToken)
|
|
3063
|
+
&& codexAuth.refreshToken) {
|
|
3062
3064
|
try {
|
|
3063
3065
|
const newTokens = await refreshCodexTokens({
|
|
3064
3066
|
refreshToken: codexAuth.refreshToken,
|
|
@@ -3225,28 +3227,18 @@ async function fetchUsageLimitsUncached({
|
|
|
3225
3227
|
claude.service_status = claudeServiceStatus;
|
|
3226
3228
|
}
|
|
3227
3229
|
|
|
3230
|
+
const codexRefreshRequiresReauth = refreshError?.code === "REFRESH_TOKEN_EXPIRED";
|
|
3231
|
+
const codexLiveUsageSucceeded = codexResult?.status === "fulfilled"
|
|
3232
|
+
&& codexResult.value.upstream_status === 200;
|
|
3228
3233
|
let codex;
|
|
3229
3234
|
if (!codexToken) {
|
|
3230
3235
|
codex = { configured: false };
|
|
3231
|
-
} else if (
|
|
3232
|
-
|
|
3233
|
-
//
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
auth_action_required: "reauth",
|
|
3238
|
-
};
|
|
3239
|
-
} else if (!codexResult || codexResult.status === "rejected") {
|
|
3240
|
-
// Live fetch failed or timed out (Codex hits chatgpt.com fresh every poll with no
|
|
3241
|
-
// rate-limit cooldown, so a slow network shows up here often). Serve the last successful
|
|
3242
|
-
// read so the bars stay visible instead of a red error, mirroring the Claude stale path.
|
|
3243
|
-
const cached = readCodexLimitsCache({ home, nowMs });
|
|
3244
|
-
if (cached) {
|
|
3245
|
-
codex = cached;
|
|
3246
|
-
} else {
|
|
3247
|
-
codex = { configured: true, error: codexResult?.reason?.message || "Unknown error" };
|
|
3248
|
-
}
|
|
3249
|
-
} else {
|
|
3236
|
+
} else if (codexResult?.status === "fulfilled"
|
|
3237
|
+
&& (!codexRefreshRequiresReauth || codexLiveUsageSucceeded)) {
|
|
3238
|
+
// A proactive refresh can fail while the existing access token is still valid.
|
|
3239
|
+
// Prefer a confirmed 200 live usage read over the refresh error so usable quota
|
|
3240
|
+
// data is not discarded before the access token actually expires. A neutral
|
|
3241
|
+
// 401/403/404 no-data response must not mask a failed refresh.
|
|
3250
3242
|
codex = {
|
|
3251
3243
|
configured: true,
|
|
3252
3244
|
error: null,
|
|
@@ -3257,13 +3249,32 @@ async function fetchUsageLimitsUncached({
|
|
|
3257
3249
|
spark_primary_window: codexResult.value.spark_primary_window,
|
|
3258
3250
|
spark_secondary_window: codexResult.value.spark_secondary_window,
|
|
3259
3251
|
reset_credits: codexResult.value.reset_credits,
|
|
3260
|
-
// Live read is current as of now; the stale fallback path
|
|
3252
|
+
// Live read is current as of now; the stale fallback path below serves the
|
|
3261
3253
|
// disk cache with `stale: true`. Always emitting both lets the client show a
|
|
3262
3254
|
// data-age label uniformly (see the Claude live-success block).
|
|
3263
3255
|
stale: false,
|
|
3264
3256
|
cached_at: new Date(nowMs).toISOString(),
|
|
3265
3257
|
};
|
|
3266
3258
|
writeCodexLimitsCache(codex, { home, nowMs });
|
|
3259
|
+
} else if (codexRefreshRequiresReauth) {
|
|
3260
|
+
// Refresh token is dead — the user must re-run `codex` to log in again. Surface a
|
|
3261
|
+
// specific, actionable message rather than the generic "Fetch failed", but only
|
|
3262
|
+
// after the existing access token also failed to fetch live usage above.
|
|
3263
|
+
codex = {
|
|
3264
|
+
configured: true,
|
|
3265
|
+
error: refreshError.message,
|
|
3266
|
+
auth_action_required: "reauth",
|
|
3267
|
+
};
|
|
3268
|
+
} else if (!codexResult || codexResult.status === "rejected") {
|
|
3269
|
+
// Live fetch failed or timed out (Codex hits chatgpt.com fresh every poll with no
|
|
3270
|
+
// rate-limit cooldown, so a slow network shows up here often). Serve the last successful
|
|
3271
|
+
// read so the bars stay visible instead of a red error, mirroring the Claude stale path.
|
|
3272
|
+
const cached = readCodexLimitsCache({ home, nowMs });
|
|
3273
|
+
if (cached) {
|
|
3274
|
+
codex = cached;
|
|
3275
|
+
} else {
|
|
3276
|
+
codex = { configured: true, error: codexResult?.reason?.message || "Unknown error" };
|
|
3277
|
+
}
|
|
3267
3278
|
}
|
|
3268
3279
|
|
|
3269
3280
|
const data = {
|