tokentracker-cli 1.5.15 → 1.5.16

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.
Files changed (115) hide show
  1. package/dashboard/dist/assets/{AchievementBadge-CwjI28oT.js → AchievementBadge-CnnJGct8.js} +1 -1
  2. package/dashboard/dist/assets/{AchievementsPage-Dq544fjX.js → AchievementsPage-CFkUJVxy.js} +2 -2
  3. package/dashboard/dist/assets/{AchievementsSection-DufV6nod.js → AchievementsSection-CoLQX04M.js} +1 -1
  4. package/dashboard/dist/assets/{BadgeDetailModal-vw8xydKu.js → BadgeDetailModal-s8rObEHY.js} +1 -1
  5. package/dashboard/dist/assets/{BotAnimated-De0anwsh.js → BotAnimated-BmBnL-i8.js} +1 -1
  6. package/dashboard/dist/assets/{Card-CuSeWBDM.js → Card-BIqie5mN.js} +1 -1
  7. package/dashboard/dist/assets/{CloudCheckoutPage-CxFcOwAj.js → CloudCheckoutPage-B_c8Q58A.js} +1 -1
  8. package/dashboard/dist/assets/{CloudPage-Beb7_JLW.js → CloudPage-CfW_pDf2.js} +2 -2
  9. package/dashboard/dist/assets/{CommandPalette-PsUq2iRS.js → CommandPalette-BRryGPVJ.js} +1 -1
  10. package/dashboard/dist/assets/{CommunityStatsModal-b54WaPbK.js → CommunityStatsModal-Cyh1Q9Fw.js} +1 -1
  11. package/dashboard/dist/assets/{ConfirmModal-_NdunIh5.js → ConfirmModal-DWBYqpLJ.js} +1 -1
  12. package/dashboard/dist/assets/{Controls-5Is6MWln.js → Controls-CPSiCzVW.js} +1 -1
  13. package/dashboard/dist/assets/{DashboardPage-C0n0qC7h.js → DashboardPage-JcS1xwUm.js} +1 -1
  14. package/dashboard/dist/assets/{DateRangePopover-C3WfGy-0.js → DateRangePopover-DjuS6888.js} +1 -1
  15. package/dashboard/dist/assets/{DevicePage-Vn6k-mGd.js → DevicePage-DZ3qiDbT.js} +1 -1
  16. package/dashboard/dist/assets/{DialogClose-CXttnna-.js → DialogClose-CfORRnoT.js} +1 -1
  17. package/dashboard/dist/assets/DialogDescription-ChihKLnm.js +1 -0
  18. package/dashboard/dist/assets/{DialogTitle-B0cNIo0E.js → DialogTitle-DZO6-sTI.js} +1 -1
  19. package/dashboard/dist/assets/{ElectricLogo-DC3XSfIu.js → ElectricLogo-BzR7mRin.js} +1 -1
  20. package/dashboard/dist/assets/{FadeIn-H7S3TMHi.js → FadeIn-BxHaUvz_.js} +1 -1
  21. package/dashboard/dist/assets/{HeaderGithubStar-xgbIo5OP.js → HeaderGithubStar-KGzKAmuQ.js} +1 -1
  22. package/dashboard/dist/assets/{HoverTooltip-CpzM5Dju.js → HoverTooltip-C6pASVDN.js} +1 -1
  23. package/dashboard/dist/assets/{IpCheckPage-BdV7S4dY.js → IpCheckPage-BJ8TROZC.js} +1 -1
  24. package/dashboard/dist/assets/{LandingPage-D9f28ryO.js → LandingPage-B15GRFpI.js} +2 -2
  25. package/dashboard/dist/assets/{LeaderboardPage--WUFpkBI.js → LeaderboardPage-C3hJ2Gh3.js} +2 -2
  26. package/dashboard/dist/assets/{LeaderboardProBadge-CEvrQ75Y.js → LeaderboardProBadge-CRfBTxpt.js} +1 -1
  27. package/dashboard/dist/assets/{LeaderboardProfileModal-Bn0HFr5h.js → LeaderboardProfileModal-DTGmcjWF.js} +3 -3
  28. package/dashboard/dist/assets/{LeaderboardProfilePage-DJ7fQI68.js → LeaderboardProfilePage-BD04D7ML.js} +1 -1
  29. package/dashboard/dist/assets/{LimitsPage-7tPDheuX.js → LimitsPage-LsDCIUKd.js} +1 -1
  30. package/dashboard/dist/assets/{LocalOnlyNotice-DlGbVQS8.js → LocalOnlyNotice-B3XQKD8k.js} +1 -1
  31. package/dashboard/dist/assets/{LoginCard-BZZmzUGh.js → LoginCard-DF1XcskU.js} +1 -1
  32. package/dashboard/dist/assets/{LoginModal-BT5_bIxU.js → LoginModal-DuyVT0Tt.js} +1 -1
  33. package/dashboard/dist/assets/{LoginPage-DMjDUPPi.js → LoginPage-kge4kJKa.js} +1 -1
  34. package/dashboard/dist/assets/{PetPage-Dk3j6ITn.js → PetPage-DuYtsKza.js} +2 -2
  35. package/dashboard/dist/assets/{PopoverPopup-pugRu3RC.js → PopoverPopup-BkNNS3VG.js} +1 -1
  36. package/dashboard/dist/assets/{ProviderIcon-CtmL1CmY.js → ProviderIcon-z2TKXPlS.js} +1 -1
  37. package/dashboard/dist/assets/{ResetPasswordPage-BB6U7t8P.js → ResetPasswordPage-CXM9E6d1.js} +1 -1
  38. package/dashboard/dist/assets/{Select-7w1su8lw.js → Select-CeoAayzi.js} +1 -1
  39. package/dashboard/dist/assets/{SelectItemText-CaEUmWkj.js → SelectItemText-CRxvAgUV.js} +1 -1
  40. package/dashboard/dist/assets/{SelfHostPage-DctWoF-A.js → SelfHostPage-Cavstn-d.js} +1 -1
  41. package/dashboard/dist/assets/{ServiceStatusPage-Dg3ljEXC.js → ServiceStatusPage-CdIeM_DX.js} +1 -1
  42. package/dashboard/dist/assets/{SessionsPage-B1dvW-be.js → SessionsPage-DPihAS26.js} +1 -1
  43. package/dashboard/dist/assets/{SettingsPage-DuXSX1R2.js → SettingsPage-zxOsLeE5.js} +3 -3
  44. package/dashboard/dist/assets/{SkillsPage-CvXQFgc9.js → SkillsPage-BRGonzsC.js} +1 -1
  45. package/dashboard/dist/assets/{TokenGalaxy-DKC8Rk_Y.js → TokenGalaxy-D9-huQJ_.js} +1 -1
  46. package/dashboard/dist/assets/{TooltipPopup-Dp9EpHLG.js → TooltipPopup-BS99Tf44.js} +1 -1
  47. package/dashboard/dist/assets/{TrendMonitor-DWnlBn3H.js → TrendMonitor-DlNT4ObY.js} +1 -1
  48. package/dashboard/dist/assets/{WidgetsPage-GECNmb1Q.js → WidgetsPage-DTFnmTwq.js} +1 -1
  49. package/dashboard/dist/assets/{WrappedPage-Dq_1lOnb.js → WrappedPage-DwMdnusQ.js} +1 -1
  50. package/dashboard/dist/assets/{__vite-browser-external-CkF0pdTJ.js → __vite-browser-external-DR_a-OTS.js} +2 -2
  51. package/dashboard/dist/assets/{agent-logos-Dqe3Vrah.js → agent-logos-D6kTooyz.js} +1 -1
  52. package/dashboard/dist/assets/{arrow-left-Cr_2QnDu.js → arrow-left-jpuJhYL4.js} +1 -1
  53. package/dashboard/dist/assets/{arrow-right-BsK2sJgt.js → arrow-right-n1hLkwiK.js} +1 -1
  54. package/dashboard/dist/assets/{arrow-up-right-DkWMGqXo.js → arrow-up-right-fZmEfh7R.js} +1 -1
  55. package/dashboard/dist/assets/{calendar-days-BB9VV438.js → calendar-days-B0LdECvD.js} +1 -1
  56. package/dashboard/dist/assets/{check-bpSCJZWh.js → check-CcnNd8bi.js} +1 -1
  57. package/dashboard/dist/assets/{chevron-down-CtECtDmx.js → chevron-down-DhbHBjVC.js} +1 -1
  58. package/dashboard/dist/assets/{cloud-checkout-C4PrzKhN.js → cloud-checkout-9XOoux-p.js} +1 -1
  59. package/dashboard/dist/assets/{composite-BHisG82k.js → composite-DIDAkYhy.js} +1 -1
  60. package/dashboard/dist/assets/{copy-Dmxzd-Sw.js → copy-BNDBunFG.js} +1 -1
  61. package/dashboard/dist/assets/{download-CkdQzw2w.js → download-wlqdqJmq.js} +1 -1
  62. package/dashboard/dist/assets/{external-link-C971FjvC.js → external-link-BvssZ_45.js} +1 -1
  63. package/dashboard/dist/assets/{flame-mKbp7kxw.js → flame-DP8IUT3E.js} +1 -1
  64. package/dashboard/dist/assets/{format-tokens-C35FrJnH.js → format-tokens-DMsx_fWk.js} +1 -1
  65. package/dashboard/dist/assets/{gift-BX2lSOmc.js → gift-zF4D6O4a.js} +1 -1
  66. package/dashboard/dist/assets/{icons-ov92u52T.js → icons-Batw5aOg.js} +1 -1
  67. package/dashboard/dist/assets/{index-DF03nIHb.js → index-3qKpTOzz.js} +1 -1
  68. package/dashboard/dist/assets/{index-9OCL-BL8.js → index-Cqla2Zq5.js} +1 -1
  69. package/dashboard/dist/assets/{index-Bgm38oHe.js → index-Dc8PQ8ZR.js} +1 -1
  70. package/dashboard/dist/assets/{index-Ca5xkNrK.js → index-dCfimErX.js} +1 -1
  71. package/dashboard/dist/assets/{info-B-f9hWcw.js → info-DcUyOPKG.js} +1 -1
  72. package/dashboard/dist/assets/{link-2-l1wuezTo.js → link-2-CS-cWLmx.js} +1 -1
  73. package/dashboard/dist/assets/{loader-circle-Lmjrs8XX.js → loader-circle-DKc-gwgL.js} +1 -1
  74. package/dashboard/dist/assets/{local-usage-transfer-Ds6cF41d.js → local-usage-transfer-bHATORmq.js} +1 -1
  75. package/dashboard/dist/assets/{modifiers.esm-tVlltJXO.js → modifiers.esm-B4QifJzx.js} +1 -1
  76. package/dashboard/dist/assets/{monitor-smartphone-XRiYiY8u.js → monitor-smartphone-D8vpN9Jv.js} +1 -1
  77. package/dashboard/dist/assets/{play-DaD9EMjk.js → play-D70P7DVT.js} +1 -1
  78. package/dashboard/dist/assets/{plus-D30fbsKQ.js → plus-YomnSdqY.js} +1 -1
  79. package/dashboard/dist/assets/{provider-display-CKdhBOwz.js → provider-display-VXu7Hzwq.js} +1 -1
  80. package/dashboard/dist/assets/{react-BY0y0K4x.js → react-CUO9Gs2G.js} +1 -1
  81. package/dashboard/dist/assets/{safePolygon-CSG_P7rG.js → safePolygon-CbVKM3Lv.js} +1 -1
  82. package/dashboard/dist/assets/{search-Kiq8wVHA.js → search-BUi1hAmV.js} +1 -1
  83. package/dashboard/dist/assets/{server-CjovGBGz.js → server-B-agbJYI.js} +1 -1
  84. package/dashboard/dist/assets/{shield-check-DF9MmMCq.js → shield-check-yHx3fQDo.js} +1 -1
  85. package/dashboard/dist/assets/{skills-api-CEzr6p92.js → skills-api-DojEO2dS.js} +1 -1
  86. package/dashboard/dist/assets/{sortable.esm-D7jd9mE_.js → sortable.esm-r4Lz4ugj.js} +1 -1
  87. package/dashboard/dist/assets/{store-D9_jo_do.js → store-GzQbKyT-.js} +1 -1
  88. package/dashboard/dist/assets/{terminal-CLOlvzR-.js → terminal-BLCZgZTm.js} +1 -1
  89. package/dashboard/dist/assets/{trash-DIe0fsDD.js → trash-BFGtCBJS.js} +1 -1
  90. package/dashboard/dist/assets/{use-community-stats-gDkdiRBz.js → use-community-stats-DGdLAa8L.js} +1 -1
  91. package/dashboard/dist/assets/{use-latest-request-guard-tXGuKvua.js → use-latest-request-guard-l39bM4s0.js} +1 -1
  92. package/dashboard/dist/assets/{use-limits-display-prefs-CCuLFy00.js → use-limits-display-prefs-JcWgMNA0.js} +1 -1
  93. package/dashboard/dist/assets/{use-native-settings-hgYqaiR7.js → use-native-settings-0sXFw6mq.js} +1 -1
  94. package/dashboard/dist/assets/{use-ordered-list-D6-YzYJI.js → use-ordered-list-mRdyZ18r.js} +1 -1
  95. package/dashboard/dist/assets/use-reduced-motion-D2g3iGbi.js +1 -0
  96. package/dashboard/dist/assets/{use-transform-BEiXvAuE.js → use-transform-CbJqMa_Y.js} +1 -1
  97. package/dashboard/dist/assets/{use-usage-limits-BlwtyPtT.js → use-usage-limits-qQKS4sHR.js} +1 -1
  98. package/dashboard/dist/assets/{useCurrency-CwCGJLHb.js → useCurrency-BJyZCVtd.js} +1 -1
  99. package/dashboard/dist/assets/{usePositioner-BqHtRIrE.js → usePositioner-zsiJqVGU.js} +1 -1
  100. package/dashboard/dist/assets/{useTokenFormat-BUNBUX-x.js → useTokenFormat-DxEKSp5H.js} +1 -1
  101. package/dashboard/dist/assets/{zap-C0RFs2qQ.js → zap-D40-8VPk.js} +1 -1
  102. package/dashboard/dist/index.html +1 -1
  103. package/dashboard/dist/ip-check.html +1 -1
  104. package/dashboard/dist/leaderboard.html +1 -1
  105. package/dashboard/dist/share.html +1 -1
  106. package/package.json +1 -1
  107. package/src/lib/ark-agent-plan-limits.js +26 -55
  108. package/src/lib/ark-coding-plan-limits.js +31 -62
  109. package/src/lib/cloud-account.js +29 -3
  110. package/src/lib/local-api.js +92 -5
  111. package/src/lib/pricing/curated-overrides.json +8 -0
  112. package/src/lib/pricing/seed-snapshot.json +1 -1
  113. package/src/lib/qoder-limits.js +35 -69
  114. package/dashboard/dist/assets/DialogDescription-C3KGos_G.js +0 -1
  115. package/dashboard/dist/assets/use-reduced-motion-DfbDxs5a.js +0 -1
@@ -6,6 +6,7 @@ const net = require("node:net");
6
6
  const os = require("node:os");
7
7
  const path = require("node:path");
8
8
  const { fetchQoderCnCliLimits } = require("./qoder-cn-cli-limits");
9
+ const { createLimitsCache } = require("./limits-cache");
9
10
 
10
11
  const QODER_SITES = {
11
12
  international: {
@@ -406,18 +407,40 @@ function writeQoderActivityCache(window, {
406
407
  } catch (_error) {}
407
408
  }
408
409
 
409
- function qoderLimitsCachePath({ home = os.homedir(), namespace } = {}) {
410
- const file = namespace
410
+ // The active region partitions the cache by filename (cn vs global); the
411
+ // record itself stays account-agnostic. A window without a parseable reset is
412
+ // kept only within the 12h unknown-reset TTL, and the global max-age only
413
+ // bounds snapshots with no future-dated window — a dated survivor outlives it.
414
+ // Provenance must describe the data's age, not the transport (#955): a fresh
415
+ // hit re-serves the winning source it was written with, an older hit honestly
416
+ // reports the disk cache.
417
+ const qoderLimitsCache = createLimitsCache({
418
+ file: ({ namespace }) => (namespace
411
419
  ? `qoder-${namespace}-usage-limits-cache.json`
412
- : QODER_LIMITS_CACHE_FILE;
413
- return path.join(home, ".tokentracker", "tracker", file);
414
- }
420
+ : QODER_LIMITS_CACHE_FILE),
421
+ key: "qoder",
422
+ maxAgeMs: QODER_LIMITS_CACHE_MAX_AGE_MS,
423
+ maxAgeGate: "ifNoDatedSurvivor",
424
+ unknownResetTtlMs: QODER_LIMITS_CACHE_UNKNOWN_RESET_TTL_MS,
425
+ fields: {
426
+ plan_label: "string",
427
+ quota_exceeded: "boolTrue",
428
+ // Remember the winning source so a fresh re-serve keeps honest provenance
429
+ // instead of always claiming "disk-cache" (#955).
430
+ source: { write: (record) => (typeof record?.source === "string" ? record.source : null) },
431
+ },
432
+ windowKeys: ["primary_window", "secondary_window", "tertiary_window"],
433
+ // tertiary_window is written only when present and read back only when it
434
+ // survives — primary/secondary always appear (null when dead).
435
+ sparseWindowKeys: ["tertiary_window"],
436
+ stale: "byAge",
437
+ freshTtlMs: QODER_LIMITS_CACHE_FRESH_TTL_MS,
438
+ cachedFlag: true,
439
+ source: "provenance",
440
+ });
415
441
 
416
- function qoderCachedWindow(window, { cachedAtMs, nowMs } = {}) {
417
- if (!window || typeof window !== "object") return null;
418
- const resetAtMs = Date.parse(window.reset_at || "");
419
- if (Number.isFinite(resetAtMs)) return resetAtMs > nowMs ? window : null;
420
- return nowMs - cachedAtMs <= QODER_LIMITS_CACHE_UNKNOWN_RESET_TTL_MS ? window : null;
442
+ function qoderLimitsCachePath({ home = os.homedir(), namespace } = {}) {
443
+ return qoderLimitsCache.path({ home, namespace });
421
444
  }
422
445
 
423
446
  function readQoderLimitsCache({
@@ -425,44 +448,7 @@ function readQoderLimitsCache({
425
448
  nowMs = Date.now(),
426
449
  namespace,
427
450
  } = {}) {
428
- try {
429
- const raw = JSON.parse(fs.readFileSync(qoderLimitsCachePath({ home, namespace }), "utf8"))?.qoder;
430
- const cachedAtMs = Date.parse(raw?.cached_at || "");
431
- if (!Number.isFinite(cachedAtMs) || cachedAtMs > nowMs + 60_000) return null;
432
- const primaryWindow = qoderCachedWindow(raw.primary_window, { cachedAtMs, nowMs });
433
- const secondaryWindow = qoderCachedWindow(raw.secondary_window, { cachedAtMs, nowMs });
434
- const tertiaryWindow = qoderCachedWindow(raw.tertiary_window, { cachedAtMs, nowMs });
435
- if (!primaryWindow && !secondaryWindow && !tertiaryWindow) return null;
436
- const hasUnexpiredDatedWindow = [primaryWindow, secondaryWindow, tertiaryWindow]
437
- .some((window) => Number.isFinite(Date.parse(window?.reset_at || "")));
438
- if (nowMs - cachedAtMs > QODER_LIMITS_CACHE_MAX_AGE_MS && !hasUnexpiredDatedWindow) {
439
- return null;
440
- }
441
- // Provenance must describe the data's age, not the transport (#955): a
442
- // successful refresh writes this cache and immediately floors later log
443
- // scans, so the next refresh re-serves the same payload. Marking every
444
- // hit stale/disk-cache made the Limits page permanently partial.
445
- const ageMs = nowMs - cachedAtMs;
446
- const fresh = ageMs <= QODER_LIMITS_CACHE_FRESH_TTL_MS;
447
- const writtenSource = typeof raw.source === "string" && raw.source.trim()
448
- ? raw.source.trim()
449
- : null;
450
- return {
451
- configured: true,
452
- error: null,
453
- plan_label: typeof raw.plan_label === "string" ? raw.plan_label : null,
454
- quota_exceeded: raw.quota_exceeded === true,
455
- primary_window: primaryWindow,
456
- secondary_window: secondaryWindow,
457
- ...(tertiaryWindow ? { tertiary_window: tertiaryWindow } : {}),
458
- cached: true,
459
- stale: !fresh,
460
- cached_at: raw.cached_at,
461
- source: fresh && writtenSource ? writtenSource : "disk-cache",
462
- };
463
- } catch (_error) {
464
- return null;
465
- }
451
+ return qoderLimitsCache.read({ home, nowMs, namespace });
466
452
  }
467
453
 
468
454
  function writeQoderLimitsCache(limits, {
@@ -470,27 +456,7 @@ function writeQoderLimitsCache(limits, {
470
456
  nowMs = Date.now(),
471
457
  namespace,
472
458
  } = {}) {
473
- if (!limits?.configured || limits.error || (!limits.primary_window && !limits.secondary_window && !limits.tertiary_window)) return;
474
- const cachePath = qoderLimitsCachePath({ home, namespace });
475
- const payload = {
476
- qoder: {
477
- plan_label: limits.plan_label || null,
478
- quota_exceeded: limits.quota_exceeded === true,
479
- primary_window: limits.primary_window || null,
480
- secondary_window: limits.secondary_window || null,
481
- ...(limits.tertiary_window ? { tertiary_window: limits.tertiary_window } : {}),
482
- // Remember the winning source so a fresh re-serve keeps honest
483
- // provenance instead of always claiming "disk-cache" (#955).
484
- source: typeof limits.source === "string" ? limits.source : null,
485
- cached_at: new Date(nowMs).toISOString(),
486
- },
487
- };
488
- try {
489
- fs.mkdirSync(path.dirname(cachePath), { recursive: true });
490
- const tmpPath = `${cachePath}.${process.pid}.tmp`;
491
- fs.writeFileSync(tmpPath, JSON.stringify(payload, null, 2), { encoding: "utf8", mode: 0o600 });
492
- fs.renameSync(tmpPath, cachePath);
493
- } catch (_error) {}
459
+ qoderLimitsCache.write(limits, { home, nowMs, namespace });
494
460
  }
495
461
 
496
462
  function buildQoderActivityHeaders(authStatus, {
@@ -1 +0,0 @@
1
- import{r as n,J as a}from"./__vite-browser-external-CkF0pdTJ.js";import{u as p}from"./DialogTitle-B0cNIo0E.js";import{u as c}from"./composite-BHisG82k.js";const x=n.forwardRef(function(e,r){const{render:l,className:u,style:m,id:s,...t}=e,i=p(),o=c(s);return i.useSyncedValueWithCleanup("descriptionElementId",o),a("p",e,{ref:r,props:[{id:o},t]})});export{x as D};
@@ -1 +0,0 @@
1
- import{r as o}from"./__vite-browser-external-CkF0pdTJ.js";import{h as r,i as t,p as s}from"./react-BY0y0K4x.js";function i(){!r.current&&t();const[e]=o.useState(s.current);return e}export{i as u};