tokentracker-cli 0.94.1 → 0.95.1

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 (126) hide show
  1. package/README.de.md +9 -7
  2. package/README.ja.md +8 -6
  3. package/README.ko.md +8 -6
  4. package/README.md +23 -10
  5. package/README.zh-CN.md +8 -6
  6. package/dashboard/dist/assets/{AchievementBadge-DnmgEa4q.js → AchievementBadge-Cyju9OnL.js} +1 -1
  7. package/dashboard/dist/assets/{AchievementsPage-B7YTbAuK.js → AchievementsPage-Bh2dQR-I.js} +2 -2
  8. package/dashboard/dist/assets/{AchievementsSection-CwgT5sqH.js → AchievementsSection-DSFAM0Zp.js} +1 -1
  9. package/dashboard/dist/assets/{BadgeDetailModal-Dets6jzW.js → BadgeDetailModal-CgVF0VI0.js} +1 -1
  10. package/dashboard/dist/assets/{BotAnimated-5KwUvC9F.js → BotAnimated-DI-rTxI9.js} +1 -1
  11. package/dashboard/dist/assets/{Card-jf9w-4-N.js → Card-DAlV-PSI.js} +1 -1
  12. package/dashboard/dist/assets/{ClawdAnimated-CGxDVQ0c.js → ClawdAnimated-oOYKgcpq.js} +2 -2
  13. package/dashboard/dist/assets/{CommandPalette-B1bUUf32.js → CommandPalette-bYE5uD63.js} +1 -1
  14. package/dashboard/dist/assets/CommunityStatsModal-DCx0sQjk.js +1 -0
  15. package/dashboard/dist/assets/{ConfirmModal-BR-aIRH9.js → ConfirmModal-DrYf9m15.js} +1 -1
  16. package/dashboard/dist/assets/{Controls-CbHsJAqV.js → Controls-DAift9Z4.js} +1 -1
  17. package/dashboard/dist/assets/DashboardPage-CLswnOil.js +1 -0
  18. package/dashboard/dist/assets/{DevicePage-DDlicLLn.js → DevicePage-uWLgMC4Z.js} +1 -1
  19. package/dashboard/dist/assets/{DialogClose-B89uLXqp.js → DialogClose-NitVrdVC.js} +1 -1
  20. package/dashboard/dist/assets/DialogDescription-CQuJCP4L.js +1 -0
  21. package/dashboard/dist/assets/{DialogTitle-jOyycYKF.js → DialogTitle-CA_ZstJL.js} +1 -1
  22. package/dashboard/dist/assets/{FadeIn-BEND42ze.js → FadeIn-CIkYDamA.js} +1 -1
  23. package/dashboard/dist/assets/{HeaderGithubStar-Dacl1WGS.js → HeaderGithubStar-CYTJNLpL.js} +1 -1
  24. package/dashboard/dist/assets/{HoverTooltip-B2Mh2LTi.js → HoverTooltip-jh3sI8NC.js} +1 -1
  25. package/dashboard/dist/assets/{IpCheckPage-CPEuRhiU.js → IpCheckPage-Brpe-N7B.js} +1 -1
  26. package/dashboard/dist/assets/{LandingPage-BYWNR_dx.js → LandingPage-D4PjaNcN.js} +2 -2
  27. package/dashboard/dist/assets/{LeaderboardAvatar-B9_5LDVj.js → LeaderboardAvatar-D9dc6frq.js} +1 -1
  28. package/dashboard/dist/assets/{LeaderboardPage-_Hl1NaIa.js → LeaderboardPage-CEuqopiC.js} +2 -2
  29. package/dashboard/dist/assets/{LeaderboardProfileModal-Cydp7CyA.js → LeaderboardProfileModal-TeYdXeIA.js} +3 -3
  30. package/dashboard/dist/assets/{LeaderboardProfilePage-Dz0ecujs.js → LeaderboardProfilePage-DmtuwJkL.js} +1 -1
  31. package/dashboard/dist/assets/{LimitsPage-CmdT2qOZ.js → LimitsPage-BJW3teYA.js} +2 -2
  32. package/dashboard/dist/assets/{LocalOnlyNotice-DhuPGUkw.js → LocalOnlyNotice-V8_KFKOD.js} +1 -1
  33. package/dashboard/dist/assets/{LoginCard-DQtHaX_5.js → LoginCard-ud0lCY_u.js} +1 -1
  34. package/dashboard/dist/assets/{LoginModal-DvpPRnYV.js → LoginModal-Bnemx4UD.js} +1 -1
  35. package/dashboard/dist/assets/{LoginPage-DOjfmdwb.js → LoginPage-v89BHssa.js} +1 -1
  36. package/dashboard/dist/assets/{PetPage-Dd6U9fh2.js → PetPage-Bg9kEi7o.js} +1 -1
  37. package/dashboard/dist/assets/{PopoverPopup-B1V01u10.js → PopoverPopup-CCHVwh0w.js} +1 -1
  38. package/dashboard/dist/assets/{ProviderIcon-BLRe55c7.js → ProviderIcon-BecpRylD.js} +1 -1
  39. package/dashboard/dist/assets/{ResetPasswordPage-BJ95vy1S.js → ResetPasswordPage-CsUtFeUr.js} +1 -1
  40. package/dashboard/dist/assets/{SegmentedControl-DacS_m9M.js → SegmentedControl-3rBqbzW_.js} +1 -1
  41. package/dashboard/dist/assets/{Select-bQDO5BEA.js → Select-DZ2ll7Qv.js} +1 -1
  42. package/dashboard/dist/assets/{SelectItemText-CUGrs9CY.js → SelectItemText-Dr1W47W6.js} +1 -1
  43. package/dashboard/dist/assets/{ServiceStatusPage-CsERvmVC.js → ServiceStatusPage-Cc1LXdAh.js} +1 -1
  44. package/dashboard/dist/assets/{SessionsPage-0VvqEfPx.js → SessionsPage-ytOFN1h9.js} +1 -1
  45. package/dashboard/dist/assets/{SettingsPage-9EHh2HfD.js → SettingsPage-2wYQ2ly6.js} +2 -2
  46. package/dashboard/dist/assets/SkillsPage-BEDAwBTN.js +1 -0
  47. package/dashboard/dist/assets/{TokenGalaxy-DSKTHQSs.js → TokenGalaxy-DxG0dBeG.js} +1 -1
  48. package/dashboard/dist/assets/{ToolbarRootContext-DP4mQLbq.js → ToolbarRootContext-DG1pr5UP.js} +1 -1
  49. package/dashboard/dist/assets/TrendMonitor-CeuEQ0XC.js +19 -0
  50. package/dashboard/dist/assets/{WidgetsPage-Cr6Wg9QX.js → WidgetsPage-ALDlZ5aR.js} +1 -1
  51. package/dashboard/dist/assets/{WrappedPage-DqQvRcnA.js → WrappedPage-BF59ouR-.js} +1 -1
  52. package/dashboard/dist/assets/{__vite-browser-external-BHz2N7Ih.css → __vite-browser-external-CCMdjCX2.css} +1 -1
  53. package/dashboard/dist/assets/__vite-browser-external-DXtgoDkV.js +45 -0
  54. package/dashboard/dist/assets/{agent-logos-BjIh_mqf.js → agent-logos-D6Ya1qw1.js} +1 -1
  55. package/dashboard/dist/assets/{arrow-up-right-BIhbN0NO.js → arrow-up-right-DUR69elJ.js} +1 -1
  56. package/dashboard/dist/assets/{check-U-wNzPvd.js → check-9_1xp5h5.js} +1 -1
  57. package/dashboard/dist/assets/{composite-BR91CxNl.js → composite-CEzovOpb.js} +1 -1
  58. package/dashboard/dist/assets/{copy-Bw3hXBCu.js → copy-DEoLQqJE.js} +1 -1
  59. package/dashboard/dist/assets/{download-WOqcQzvK.js → download-BNjfcJ1g.js} +1 -1
  60. package/dashboard/dist/assets/{external-link-BZtf6WfS.js → external-link-fV_WJ5f_.js} +1 -1
  61. package/dashboard/dist/assets/{flame-B5kp2VI9.js → flame-DqpuFJ14.js} +1 -1
  62. package/dashboard/dist/assets/{format-tokens-BOCnuMuJ.js → format-tokens-CatddjmK.js} +1 -1
  63. package/dashboard/dist/assets/{icons-CA3FiIa_.js → icons-CBT1KI7V.js} +1 -1
  64. package/dashboard/dist/assets/{index-DjWC63Bs.js → index-BK3SzL7v.js} +1 -1
  65. package/dashboard/dist/assets/{index-DQaanK52.js → index-_2LEUZTl.js} +1 -1
  66. package/dashboard/dist/assets/{index-mEG0HZ-a.js → index-tK7s2SeO.js} +1 -1
  67. package/dashboard/dist/assets/{info-Djer9i3-.js → info-DBotcfT9.js} +1 -1
  68. package/dashboard/dist/assets/{limits-providers-F-RnNFAb.js → limits-providers-CjMU709b.js} +1 -1
  69. package/dashboard/dist/assets/{link-2-DV4ocD0l.js → link-2-Wc54x2fh.js} +1 -1
  70. package/dashboard/dist/assets/{loader-circle-DJK72c-o.js → loader-circle-nRhGIddE.js} +1 -1
  71. package/dashboard/dist/assets/{maximize-2-BwBA_lMm.js → maximize-2-Dw3_GuKW.js} +1 -1
  72. package/dashboard/dist/assets/{modifiers.esm-B3sl4qyZ.js → modifiers.esm-rTZ5BUxp.js} +1 -1
  73. package/dashboard/dist/assets/module-xpSFyNBK.js +3 -0
  74. package/dashboard/dist/assets/{monitor-smartphone-BUTpM4ng.js → monitor-smartphone-CNVAqV_N.js} +1 -1
  75. package/dashboard/dist/assets/{plus-BA9RP5L6.js → plus-B5oPOXhp.js} +1 -1
  76. package/dashboard/dist/assets/{provider-display-DqsJzGSr.js → provider-display-DhAUWfC6.js} +2 -2
  77. package/dashboard/dist/assets/{react-BYw5AVSz.js → react-BKACWrsB.js} +1 -1
  78. package/dashboard/dist/assets/{search-BzcnFWVD.js → search-DgddmV09.js} +1 -1
  79. package/dashboard/dist/assets/{skills-api-vAME1P7G.js → skills-api-BT1uiqeq.js} +1 -1
  80. package/dashboard/dist/assets/{sortable.esm-BpEiRqqI.js → sortable.esm-UCoNfZ6z.js} +1 -1
  81. package/dashboard/dist/assets/{store-GeT5fhRX.js → store-ZswY8Voz.js} +1 -1
  82. package/dashboard/dist/assets/{terminal-CZCMYQ8K.js → terminal-BtQyotJS.js} +1 -1
  83. package/dashboard/dist/assets/{trash-2-DzlWEwKO.js → trash-2-Dc_NLbWs.js} +1 -1
  84. package/dashboard/dist/assets/{use-community-stats-DOvJfj-i.js → use-community-stats-yOKag_ou.js} +1 -1
  85. package/dashboard/dist/assets/use-latest-request-guard-BEiszvlI.js +1 -0
  86. package/dashboard/dist/assets/{use-limits-display-prefs-BmLs4HyN.js → use-limits-display-prefs-C-l_Mxvy.js} +1 -1
  87. package/dashboard/dist/assets/{use-ordered-list-BgozDSSV.js → use-ordered-list-CKjRaO6K.js} +1 -1
  88. package/dashboard/dist/assets/use-reduced-motion-BlOkflqU.js +1 -0
  89. package/dashboard/dist/assets/{use-session-efficiency-pref-HP1ckVkS.js → use-session-efficiency-pref-DPI_--W2.js} +1 -1
  90. package/dashboard/dist/assets/{use-transform-B4VSogOx.js → use-transform-BQUem5OA.js} +1 -1
  91. package/dashboard/dist/assets/use-usage-limits-lvkMBnNR.js +1 -0
  92. package/dashboard/dist/assets/{useCurrency-CSuzCBAL.js → useCurrency-C5xhS1QV.js} +1 -1
  93. package/dashboard/dist/assets/{useTokenFormat-ClnL9OFe.js → useTokenFormat-FBMikfEq.js} +1 -1
  94. package/dashboard/dist/assets/{zap-C_T9CCiS.js → zap-BsCNYelz.js} +1 -1
  95. package/dashboard/dist/brand-logos/lmstudio.svg +12 -0
  96. package/dashboard/dist/brand-logos/unsloth.svg +1 -0
  97. package/dashboard/dist/index.html +16 -12
  98. package/dashboard/dist/ip-check.html +2 -2
  99. package/dashboard/dist/leaderboard.html +2 -2
  100. package/dashboard/dist/llms.txt +4 -2
  101. package/dashboard/dist/share.html +2 -2
  102. package/package.json +2 -2
  103. package/src/commands/device-login.js +5 -10
  104. package/src/commands/init.js +28 -1
  105. package/src/commands/serve.js +6 -0
  106. package/src/commands/status.js +75 -8
  107. package/src/commands/sync.js +189 -18
  108. package/src/lib/cloud-account.js +102 -29
  109. package/src/lib/fs.js +30 -0
  110. package/src/lib/local-api.js +99 -13
  111. package/src/lib/pricing/index.js +5 -0
  112. package/src/lib/pricing/matcher.js +15 -0
  113. package/src/lib/pricing/seed-snapshot.json +1 -1
  114. package/src/lib/rollout.js +1418 -28
  115. package/src/lib/usage-limits.js +507 -55
  116. package/src/lib/zcode-limits.js +65 -8
  117. package/dashboard/dist/assets/CommunityStatsModal-DRDpZycV.js +0 -1
  118. package/dashboard/dist/assets/DashboardPage-B5XMQoxy.js +0 -1
  119. package/dashboard/dist/assets/DialogDescription-DiVbwvTR.js +0 -1
  120. package/dashboard/dist/assets/SkillsPage-B1AcLX41.js +0 -1
  121. package/dashboard/dist/assets/TrendMonitor-rabtcE5w.js +0 -19
  122. package/dashboard/dist/assets/__vite-browser-external-C8KwSyTz.js +0 -45
  123. package/dashboard/dist/assets/chevron-right-Du-QVNj4.js +0 -1
  124. package/dashboard/dist/assets/module-D2D5r9gC.js +0 -3
  125. package/dashboard/dist/assets/use-reduced-motion-Bc3RFJdg.js +0 -1
  126. package/dashboard/dist/assets/use-usage-limits-DNNhD2H6.js +0 -1
@@ -95,7 +95,33 @@ function loadZcodeProviderAvailability({ home, env } = {}) {
95
95
  }
96
96
  }
97
97
 
98
- function loadZcodeSelectedPlanProviderKeys({ home, env } = {}) {
98
+ /**
99
+ * Decode routing identifiers from a complete team selection for the given family.
100
+ * Returns null for personal, malformed, or legacy project-only selections.
101
+ * @returns {{ organizationId: string, projectId: string } | null}
102
+ */
103
+ function parseZcodeTeamContext(selection, family) {
104
+ if (family !== "bigmodel" && family !== "zai") return null;
105
+ const prefix = `team-plan:builtin:${family}-coding-plan:`;
106
+ if (!selection.startsWith(prefix)) return null;
107
+ const parts = selection.slice(prefix.length).split(":");
108
+ // ZCode 3.10.x stores product:organization:project. Older project-only
109
+ // selections do not identify an organization, so do not guess its scope.
110
+ if (parts.length !== 3) return null;
111
+ try {
112
+ const [productId, organizationId, projectId] = parts.map((part) => decodeURIComponent(part.trim()).trim());
113
+ if (!productId || !organizationId || !projectId) return null;
114
+ return { organizationId, projectId };
115
+ } catch (_error) {
116
+ return null;
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Read selected plans in active-family order, retaining each plan's team scope.
122
+ * Only the provider key and decoded organization/project identifiers are retained.
123
+ */
124
+ function loadZcodeSelectedPlans({ home, env } = {}) {
99
125
  const zcodeHome = resolveZcodeHome({ home, env });
100
126
  const settingPath = path.join(zcodeHome, "v2", "setting.json");
101
127
  if (!fs.existsSync(settingPath)) return [];
@@ -109,7 +135,8 @@ function loadZcodeSelectedPlanProviderKeys({ home, env } = {}) {
109
135
  for (const key of domains) {
110
136
  const raw = typeof selected[key] === "string" ? selected[key].trim() : "";
111
137
  const match = raw.match(/builtin:(?:bigmodel|zai)-(?:start|coding)-plan/);
112
- if (match && !out.includes(match[0])) out.push(match[0]);
138
+ if (!match || out.some((plan) => plan.providerKey === match[0])) continue;
139
+ out.push({ providerKey: match[0], teamContext: parseZcodeTeamContext(raw, key) });
113
140
  }
114
141
  return out;
115
142
  } catch (_error) {
@@ -117,6 +144,11 @@ function loadZcodeSelectedPlanProviderKeys({ home, env } = {}) {
117
144
  }
118
145
  }
119
146
 
147
+ /** Return the ordered provider keys without exposing the internal team context. */
148
+ function loadZcodeSelectedPlanProviderKeys(options = {}) {
149
+ return loadZcodeSelectedPlans(options).map((plan) => plan.providerKey);
150
+ }
151
+
120
152
  function resolveZcodeCredentialsPath({ home, env } = {}) {
121
153
  return path.join(resolveZcodeHome({ home, env }), "v2", "credentials.json");
122
154
  }
@@ -246,6 +278,10 @@ function resolveZcodeProviderQuotaUrl(providerKey, provider, env = process.env)
246
278
  return `${origin.replace(/\/$/, "")}${ZCODE_MONITOR_QUOTA_PATH}`;
247
279
  }
248
280
 
281
+ /**
282
+ * Build quota/billing candidates from enabled providers and their existing keys.
283
+ * Selected plans take precedence; team scope stays attached to its own provider.
284
+ */
249
285
  function loadZcodeAuthCandidates({ home, env } = {}) {
250
286
  const zcodeHome = resolveZcodeHome({ home, env });
251
287
  const configPath = path.join(zcodeHome, "v2", "config.json");
@@ -262,7 +298,8 @@ function loadZcodeAuthCandidates({ home, env } = {}) {
262
298
  ];
263
299
  const availability = loadZcodeProviderAvailability({ home, env });
264
300
  const hasAvailability = Object.keys(availability).length > 0;
265
- const selectedCandidates = loadZcodeSelectedPlanProviderKeys({ home, env })
301
+ const selectedPlans = loadZcodeSelectedPlans({ home, env });
302
+ const selectedCandidates = selectedPlans.map((plan) => plan.providerKey)
266
303
  .filter((key) => defaultCandidates.includes(key));
267
304
  const availableCandidates = defaultCandidates.filter((key) => availability?.[key]?.status === "available");
268
305
  const candidates = [
@@ -279,6 +316,7 @@ function loadZcodeAuthCandidates({ home, env } = {}) {
279
316
  const apiKey = typeof provider?.options?.apiKey === "string" ? provider.options.apiKey.trim() : "";
280
317
  const billingBaseUrl = resolveZcodeProviderBillingBaseUrl(key, provider, env);
281
318
  const quotaUrl = resolveZcodeProviderQuotaUrl(key, provider, env);
319
+ const teamContext = selectedPlans.find((plan) => plan.providerKey === key)?.teamContext;
282
320
  const credentialApiKey = resolveZcodeCredentialAuth(key, { home, env });
283
321
  const authEntries = [
284
322
  credentialApiKey ? { apiKey: credentialApiKey, authSource: "credential:zcodejwttoken" } : null,
@@ -296,6 +334,7 @@ function loadZcodeAuthCandidates({ home, env } = {}) {
296
334
  baseUrl: provider?.options?.baseURL || null,
297
335
  billingBaseUrl,
298
336
  quotaUrl,
337
+ ...(teamContext ? { teamContext } : {}),
299
338
  availability: availability?.[key]?.status || null,
300
339
  });
301
340
  }
@@ -465,13 +504,26 @@ async function fetchZcodeBilling(apiKey, { fetchImpl = fetch, baseUrl, env, home
465
504
  return res.json();
466
505
  }
467
506
 
468
- async function fetchZcodeCodingPlanQuota(apiKey, { fetchImpl = fetch, quotaUrl } = {}) {
507
+ /**
508
+ * Fetch quota using the existing provider key and optional team routing metadata.
509
+ * Organization/project IDs select the subscription at the resolved provider URL;
510
+ * they do not choose the destination or include the contents of the settings file.
511
+ */
512
+ async function fetchZcodeCodingPlanQuota(apiKey, { fetchImpl = fetch, quotaUrl, teamContext } = {}) {
513
+ const headers = {
514
+ authorization: apiKey,
515
+ Accept: "application/json",
516
+ };
517
+ if (teamContext?.organizationId && teamContext?.projectId) {
518
+ const url = new URL(quotaUrl);
519
+ url.searchParams.set("type", "2");
520
+ quotaUrl = url.toString();
521
+ headers["bigmodel-organization"] = teamContext.organizationId;
522
+ headers["bigmodel-project"] = teamContext.projectId;
523
+ }
469
524
  const res = await fetchImpl(quotaUrl, {
470
525
  method: "GET",
471
- headers: {
472
- authorization: apiKey,
473
- Accept: "application/json",
474
- },
526
+ headers,
475
527
  });
476
528
  if (res.status === 401 || res.status === 403) {
477
529
  throw new Error("Not authenticated with ZCode coding plan. Run `zcode` in Terminal to log in.");
@@ -697,6 +749,10 @@ function zcodeLogFallbackResult(logRecord, errors = []) {
697
749
  };
698
750
  }
699
751
 
752
+ /**
753
+ * Return normalized quota windows, trying eligible providers and recent billing logs.
754
+ * Credentials and internal team routing identifiers are omitted from the result.
755
+ */
700
756
  async function fetchZcodeLimits({ home, env, fetchImpl = fetch, nowMs = Date.now() } = {}) {
701
757
  if (!isZcodeInstalled({ home, env })) {
702
758
  return { configured: false };
@@ -715,6 +771,7 @@ async function fetchZcodeLimits({ home, env, fetchImpl = fetch, nowMs = Date.now
715
771
  ? await fetchZcodeCodingPlanQuota(auth.apiKey, {
716
772
  fetchImpl,
717
773
  quotaUrl: auth.quotaUrl,
774
+ teamContext: auth.teamContext,
718
775
  })
719
776
  : await fetchZcodeBilling(auth.apiKey, {
720
777
  fetchImpl,
@@ -1 +0,0 @@
1
- import{m as L,j as e,$ as R,n as P,r as D,c as n,X as z,l as S}from"./__vite-browser-external-C8KwSyTz.js";import{m as M}from"./react-BYw5AVSz.js";import{A as K,W as U}from"./icons-CA3FiIa_.js";import{u as B}from"./useTokenFormat-ClnL9OFe.js";import{P as F}from"./ProviderIcon-BLRe55c7.js";import{T as G}from"./TrendMonitor-rabtcE5w.js";import{T as W}from"./AchievementBadge-DnmgEa4q.js";import{T as V}from"./terminal-CZCMYQ8K.js";import{D as X,a as Y,b as Z,c as H,d as q,e as J}from"./DialogTitle-jOyycYKF.js";import{D as Q}from"./DialogDescription-DiVbwvTR.js";import{D as ee}from"./DialogClose-B89uLXqp.js";import"./useCurrency-CSuzCBAL.js";import"./chevron-right-Du-QVNj4.js";import"./PopoverPopup-B1V01u10.js";import"./store-GeT5fhRX.js";import"./composite-BR91CxNl.js";import"./ToolbarRootContext-DP4mQLbq.js";import"./maximize-2-BwBA_lMm.js";import"./use-reduced-motion-Bc3RFJdg.js";import"./zap-C_T9CCiS.js";import"./flame-B5kp2VI9.js";const ae=[["path",{d:"M16 17h6v-6",key:"t6n2it"}],["path",{d:"m22 17-8.5-8.5-5 5L2 7",key:"x473p"}]],te=L("trending-down",ae),O=10,_={input:"var(--community-token-input)",cache_read:"var(--community-token-cache-read)",cache_write:"var(--community-token-cache-write)",output:"var(--community-token-output)",reasoning:"var(--community-token-reasoning)"},re={CLAUDE:"var(--community-claude)",CODEX:"var(--community-codex)",GEMINI:"var(--community-gemini)",CURSOR:"var(--community-cursor)",OPENCODE:"var(--community-opencode)",HERMES:"var(--community-hermes)",KIMI:"var(--community-kimi)",MIMO:"var(--community-mimo)",COPILOT:"var(--community-copilot)",KIRO:"var(--community-kiro)",GROK:"var(--community-grok)",DEEPSEEK:"var(--community-deepseek)",ZCODE:"var(--community-zcode)",WORKBUDDY:"var(--community-workbuddy)",MINIMAX:"var(--community-minimax)",DROID:"var(--community-droid)"};function ie(t){return re[String(t||"").toUpperCase()]||"var(--community-muted)"}const se=[[/claude|fable|opus|sonnet|haiku/,"CLAUDE"],[/gpt|codex|o3|o4/,"CODEX"],[/gemini/,"GEMINI"],[/composer|cursor/,"CURSOR"],[/kimi/,"KIMI"],[/mimo/,"MIMO"],[/copilot/,"COPILOT"],[/kiro/,"KIRO"],[/grok/,"GROK"],[/deepseek/,"DEEPSEEK"],[/glm/,"ZCODE"],[/hy3/,"WORKBUDDY"],[/minimax/,"MINIMAX"]],g=["overview","providers","community","models"];function oe(t){const s=String(t||"").toLowerCase(),a=se.find(([i])=>i.test(s));return a?a[1]:""}function u(t){const s=Number(t);return Number.isFinite(s)?`${s.toFixed(1)}%`:"—"}function p(t){return S(Number(t)||0)}function ne(t){return t?new Date(`${t}T00:00:00Z`).toLocaleDateString(void 0,{month:"short",day:"numeric",timeZone:"UTC"}):""}function k(){return e.jsx("div",{className:"flex h-full min-h-40 items-center justify-center text-xs text-oai-gray-400",children:n("leaderboard.community.modal.no_data")})}function b({children:t,detail:s}){return e.jsxs("div",{className:"mb-3 flex items-baseline justify-between gap-4",children:[e.jsx("h3",{className:"text-xs font-medium uppercase tracking-wide text-oai-gray-500 dark:text-oai-gray-400",children:t}),s?e.jsx("span",{className:"text-xs text-oai-gray-400",children:s}):null]})}function C({value:t,label:s}){const a=Number(t);if(!Number.isFinite(a))return null;const i=Math.sign(a)!==-1,r=i?W:te;return e.jsxs("span",{className:`inline-flex items-center gap-1 text-xs font-medium tabular-nums ${i?"text-emerald-600 dark:text-emerald-400":"text-rose-600 dark:text-rose-400"}`,title:s,children:[e.jsx(r,{className:"size-3","aria-hidden":"true"}),i?"+":"",a.toFixed(1),"%"]})}function j({label:t,value:s,title:a,delta:i,deltaLabel:r}){return e.jsxs("div",{className:"min-w-0",children:[e.jsx("div",{className:"truncate text-xs font-medium text-oai-gray-500 dark:text-oai-gray-400",children:t}),e.jsxs("div",{className:"mt-1 flex min-w-0 items-baseline gap-2",children:[e.jsx("span",{className:"truncate text-xl font-semibold leading-none tracking-tight text-oai-black tabular-nums dark:text-white",title:a,children:s}),e.jsx(C,{value:i,label:r})]})]})}function I({fillWidth:t,share:s,color:a="var(--oai-blue)",ariaLabel:i,dataAttrs:r,children:o}){return e.jsxs("div",{...r,className:"group relative grid min-h-11 grid-cols-[minmax(0,1fr)_auto] items-center gap-3 overflow-hidden px-2.5 transition-colors hover:bg-oai-gray-50 dark:hover:bg-oai-gray-900/60",children:[e.jsx("div",{className:"pointer-events-none absolute inset-y-0 left-0 opacity-[0.15] transition-opacity group-hover:opacity-[0.22] dark:opacity-[0.24] dark:group-hover:opacity-[0.32]",style:{width:`${t}%`,backgroundColor:a},role:"progressbar","aria-label":i,"aria-valuemin":"0","aria-valuemax":"100","aria-valuenow":Number(s)||0}),o]})}function A({rank:t,provider:s,name:a,fillWidth:i,share:r,tokens:o,tokensTitle:l,dataAttrs:c}){return e.jsxs(I,{fillWidth:i,share:r,color:ie(s),ariaLabel:`${a} ${u(r)}`,dataAttrs:c,children:[e.jsxs("div",{className:"relative flex min-w-0 items-center gap-2.5",children:[e.jsx("span",{className:`w-5 shrink-0 text-xs tabular-nums ${t<=3?"font-semibold text-oai-gray-700 dark:text-oai-gray-200":"text-oai-gray-400"}`,children:t}),e.jsx("span",{className:"grid size-6 shrink-0 place-items-center text-oai-gray-700 dark:text-oai-gray-200",children:e.jsx(F,{provider:s,size:15})}),e.jsx("span",{className:"truncate text-xs font-medium text-oai-gray-700 dark:text-oai-gray-200",title:a,children:a})]}),e.jsxs("div",{className:"relative min-w-[4.5rem] text-right",children:[e.jsx("div",{className:"text-xs font-semibold text-oai-black tabular-nums dark:text-white",title:l,children:o}),e.jsx("div",{className:"text-xs text-oai-gray-500 tabular-nums dark:text-oai-gray-400",children:u(r)})]})]})}function le({rows:t,formatTokensTooltip:s}){return t.length?e.jsxs("div",{className:"mt-7",children:[e.jsx(b,{children:n("leaderboard.community.modal.token_mix")}),e.jsx("div",{className:"flex h-1.5 overflow-hidden bg-oai-gray-100 dark:bg-oai-gray-800",children:t.map(a=>e.jsx("div",{style:{width:`${Math.max(Number(a.share)||0,0)}%`,backgroundColor:_[a.key]||"var(--community-muted)"},title:`${n(`leaderboard.community.modal.token_mix.${a.key}`)} · ${u(a.share)}`},a.key))}),e.jsx("div",{className:"mt-3 flex flex-wrap gap-x-5 gap-y-1.5",children:t.map(a=>e.jsxs("span",{className:"inline-flex items-center gap-1.5 text-xs text-oai-gray-500 dark:text-oai-gray-400",title:s(a.tokens),children:[e.jsx("span",{className:"size-2",style:{backgroundColor:_[a.key]||"var(--community-muted)"}}),n(`leaderboard.community.modal.token_mix.${a.key}`),e.jsx("span",{className:"tabular-nums text-oai-gray-700 dark:text-oai-gray-200",children:u(a.share)})]},a.key))})]}):null}function f({label:t,value:s,title:a,delta:i,deltaLabel:r,className:o=""}){return e.jsxs("div",{className:`min-w-0 ${o}`,children:[e.jsx("div",{className:"truncate text-xs text-oai-gray-500 dark:text-oai-gray-400",children:t}),e.jsxs("div",{className:"mt-1 flex min-w-0 items-baseline gap-2",children:[e.jsx("span",{className:"truncate text-base font-semibold leading-none tracking-tight tabular-nums text-oai-black dark:text-white",title:a,children:s}),e.jsx(C,{value:i,label:r})]})]})}function de({trendRows:t,activeDevelopers30d:s,developerGrowthPct:a,formatTokens:i,formatTokensTooltip:r}){if(!t.length)return null;const o=t.reduce((m,h)=>m+h.value,0),l=t.reduce((m,h)=>m.value<h.value?h:m,t[0]),c=o/t.length;return e.jsxs("div",{className:"mt-5 grid grid-cols-3 divide-x divide-oai-gray-100 border-y border-oai-gray-100 py-3.5 dark:divide-oai-gray-800/80 dark:border-oai-gray-800/80",children:[e.jsx(f,{className:"pr-4",label:n("leaderboard.community.modal.daily_average"),value:i(c),title:r(c)}),e.jsx(f,{className:"px-4",label:`${n("leaderboard.community.modal.peak_day")} · ${l.day}`,value:i(l.value),title:r(l.value)}),e.jsx(f,{className:"pl-4",label:n("leaderboard.community.modal.active_30d"),value:p(s),title:Number(s).toLocaleString(),delta:a,deltaLabel:n("leaderboard.community.modal.vs_previous_week")})]})}function me({trendRows:t,mix:s,activeDevelopers30d:a,developerGrowthPct:i,formatTokens:r,formatTokensTooltip:o}){return!t.length&&!s.length?e.jsx(k,{}):e.jsxs("div",{children:[e.jsx(b,{detail:n("leaderboard.community.modal.utc_note"),children:n("leaderboard.community.modal.community_activity")}),e.jsx(G,{embedded:!0,rows:t,from:t[0]?.day,to:t.at(-1)?.day,chartHeightClass:"h-44"}),e.jsx(de,{trendRows:t,activeDevelopers30d:a,developerGrowthPct:i,formatTokens:r,formatTokensTooltip:o}),e.jsx(le,{rows:s,formatTokensTooltip:o})]})}function ce({rows:t,maxShare:s,formatTokens:a,formatTokensTooltip:i}){return t.length?e.jsx("div",{className:"space-y-0.5",children:t.map((r,o)=>e.jsx(A,{rank:o+1,dataAttrs:{"data-provider-rank":o+1,"data-provider-name":r.name},provider:String(r.name).toUpperCase(),name:r.name,fillWidth:Math.max((Number(r.share)||0)/s*100,2),share:r.share,tokens:a(r.tokens),tokensTitle:i(r.tokens)},r.name))}):e.jsx(k,{})}function xe({rows:t,maxShare:s,formatTokens:a,formatTokensTooltip:i}){return t.length?e.jsx("div",{className:"space-y-0.5",children:t.map((r,o)=>{const l=Number(r.share)||0;return e.jsx(A,{rank:o+1,dataAttrs:{"data-model-rank":o+1,"data-model-name":r.name},provider:oe(r.name),name:r.name,fillWidth:Math.max(l/s*100,2),share:l,tokens:a(r.tokens),tokensTitle:i(r.tokens)},r.name)})}):e.jsx(k,{})}function ue({name:t}){const s=String(t||"").toLowerCase();return s==="darwin"?e.jsx(K,{className:"size-3.5"}):s==="win32"?e.jsx(U,{className:"size-3.5"}):e.jsx(V,{className:"size-4","aria-hidden":"true"})}const he=.175,ye=.3;function ge({bands:t,formatTokensTooltip:s}){const a=t.reduce((r,o)=>Math.max(r,Number(o.developer_share)||0),0)||1,i=r=>`${n(`leaderboard.community.modal.band.${r.key}`)} · ${n("leaderboard.community.modal.developer_count",{count:p(r.developers)})} (${s(r.tokens)})`;return e.jsxs("div",{children:[e.jsx("div",{className:"flex gap-2 border-b border-oai-gray-200 dark:border-oai-gray-800",children:t.map((r,o)=>{const l=Number(r.developer_share)||0,c=Math.max(l/a*80,2);return e.jsxs("div",{className:"relative h-32 min-w-0 flex-1",title:i(r),children:[e.jsx("div",{role:"progressbar","aria-label":n("leaderboard.community.modal.developer_share_title",{share:u(l)}),"aria-valuemin":"0","aria-valuemax":"100","aria-valuenow":l,className:"absolute inset-x-0 bottom-0",style:{height:`${c}%`,backgroundColor:"var(--oai-blue)",opacity:ye+o*he}}),e.jsx("div",{className:"absolute inset-x-0 text-center text-xs font-medium tabular-nums text-oai-gray-700 dark:text-oai-gray-200",style:{bottom:`calc(${c}% + 4px)`},children:u(l)})]},r.key)})}),e.jsx("div",{className:"mt-2 flex gap-2",children:t.map(r=>e.jsxs("div",{className:"min-w-0 flex-1 text-center",title:i(r),children:[e.jsx("div",{className:"truncate text-xs font-medium text-oai-gray-700 dark:text-oai-gray-200",children:n(`leaderboard.community.modal.band.${r.key}`)}),e.jsx("div",{className:"truncate text-xs tabular-nums text-oai-gray-500 dark:text-oai-gray-400",children:p(r.developers)})]},r.key))})]})}function pe({bands:t,platforms:s,formatTokensTooltip:a}){return!t.length&&!s.length?e.jsx(k,{}):e.jsxs("div",{className:"space-y-8",children:[t.length?e.jsxs("div",{children:[e.jsx(b,{children:n("leaderboard.community.modal.usage_distribution")}),e.jsx(ge,{bands:t,formatTokensTooltip:a})]}):null,s.length?e.jsxs("div",{children:[e.jsx(b,{children:n("leaderboard.community.modal.platforms")}),e.jsx("div",{className:"space-y-0.5",children:s.map(i=>e.jsxs(I,{fillWidth:Math.max(Number(i.share)||0,1),share:i.share,ariaLabel:`${n(`leaderboard.community.modal.platform.${i.name}`)} ${u(i.share)}`,children:[e.jsxs("div",{className:"relative flex min-w-0 items-center gap-2.5",children:[e.jsx("span",{className:"grid size-6 shrink-0 place-items-center text-oai-gray-700 dark:text-oai-gray-200",children:e.jsx(ue,{name:i.name})}),e.jsx("span",{className:"truncate text-xs font-medium text-oai-gray-700 dark:text-oai-gray-200",children:n(`leaderboard.community.modal.platform.${i.name}`)})]}),e.jsxs("div",{className:"relative min-w-[4.5rem] text-right",children:[e.jsx("div",{className:"text-xs font-semibold text-oai-black tabular-nums dark:text-white",children:u(i.share)}),e.jsx("div",{className:"text-xs text-oai-gray-500 tabular-nums dark:text-oai-gray-400",title:Number(i.machines||0).toLocaleString(),children:n("leaderboard.community.modal.machine_count",{count:p(i.machines)})})]})]},i.name))})]}):null]})}function ve({isOpen:t,onClose:s,communityStats:a}){const{formatTokens:i,formatTokensTooltip:r}=B(),[o,l]=D.useState("overview"),c=a?.status==="ready",m=D.useMemo(()=>{if(!c)return null;const d=(Array.isArray(a.providers)?a.providers:[]).slice(0,O),x=(Array.isArray(a.topModels)?a.topModels:[]).slice(0,O),y=v=>v.reduce((E,$)=>Math.max(E,Number($.share)||0),0)||1;return{providers:d,models:x,providersMaxShare:y(d),modelsMaxShare:y(x),trendRows:(Array.isArray(a.dailyGrowth)?a.dailyGrowth:[]).map(v=>({day:ne(v.day),value:Number(v.tokens)||0})),mix:Array.isArray(a.tokenMix)?a.tokenMix:[],bands:Array.isArray(a.userDistribution)?a.userDistribution:[],platforms:Array.isArray(a.platforms)?a.platforms:[]}},[c,a]);if(!m)return null;const h=Number(a.tokenFloor)||0,N=Number(a.activeDevelopersTotal)||Number(a.totalEntries)||0,w=Number(a.tokens30d)||0,T=d=>{if(d.key!=="ArrowRight"&&d.key!=="ArrowLeft")return;d.preventDefault();const x=d.key==="ArrowRight"?1:-1,y=g[(g.indexOf(o)+x+g.length)%g.length];l(y),d.currentTarget.querySelector(`[data-tab-id="${y}"]`)?.focus()};return e.jsx(X,{open:t,onOpenChange:d=>!d&&s(),children:e.jsxs(Y,{children:[e.jsx(Z,{className:"fixed inset-0 z-[100] bg-black/50 backdrop-blur-[3px] transition-opacity duration-200 ease-out data-[ending-style]:opacity-0 data-[starting-style]:opacity-0"}),e.jsx(H,{className:"fixed inset-0 z-[101] flex items-center justify-center p-2 sm:p-5",children:e.jsxs(q,{className:"relative flex h-[min(42rem,92vh)] w-full max-w-xl flex-col overflow-hidden rounded-2xl bg-white shadow-2xl ring-1 ring-black/10 transition-[opacity,transform] duration-[220ms] ease-[cubic-bezier(0.16,1,0.3,1)] data-[ending-style]:translate-y-3 data-[ending-style]:scale-[0.98] data-[ending-style]:opacity-0 data-[starting-style]:translate-y-3 data-[starting-style]:scale-[0.98] data-[starting-style]:opacity-0 dark:bg-oai-gray-950 dark:ring-white/10",children:[e.jsxs("header",{"data-testid":"community-metrics-header",className:"shrink-0 px-5 pt-5 sm:px-6",children:[e.jsxs("div",{className:"flex items-start justify-between gap-4",children:[e.jsxs("div",{children:[e.jsx(J,{className:"text-lg font-semibold tracking-[-0.02em] text-oai-black dark:text-white",children:n("leaderboard.community.modal.title")}),e.jsx(Q,{className:"sr-only",children:n("leaderboard.community.modal.description")})]}),e.jsx(ee,{className:"-mr-1 -mt-1 grid size-8 place-items-center rounded-full text-oai-gray-400 transition-colors hover:bg-black/5 hover:text-oai-black dark:hover:bg-white/10 dark:hover:text-white","aria-label":n("shared.dialog.close"),children:e.jsx(z,{className:"size-4"})})]}),e.jsxs("div",{className:"mt-4 grid grid-cols-3 gap-x-5",children:[e.jsx(j,{label:n("leaderboard.community.modal.total_tokens"),value:i(h),title:r(h)}),e.jsx(j,{label:n("leaderboard.community.modal.tokens_30d"),value:i(w),title:r(w),delta:a.tokenGrowthPct,deltaLabel:n("leaderboard.community.modal.vs_previous_week")}),e.jsx(j,{label:n("leaderboard.community.modal.contributors"),value:p(N),title:N.toLocaleString()})]}),e.jsx("div",{className:"mt-4 flex items-end overflow-x-auto border-b border-oai-gray-100 dark:border-oai-gray-900",role:"tablist","aria-label":n("leaderboard.community.modal.views"),onKeyDown:T,children:g.map(d=>{const x=o===d;return e.jsxs("button",{type:"button",role:"tab","data-tab-id":d,"aria-selected":x,tabIndex:x?0:-1,onClick:()=>l(d),className:`relative mr-5 h-10 shrink-0 text-sm font-medium transition-colors last:mr-0 ${x?"text-oai-black dark:text-white":"text-oai-gray-500 hover:text-oai-gray-700 dark:text-oai-gray-400 dark:hover:text-oai-gray-200"}`,children:[n(`leaderboard.community.modal.tab.${d}`),x?e.jsx(M.span,{layoutId:"community-metrics-tab-underline",className:"absolute inset-x-0 -bottom-px h-0.5 rounded-full bg-oai-black dark:bg-white",transition:{type:"spring",stiffness:420,damping:34}}):null]},d)})})]}),e.jsx("div",{"data-testid":"community-metrics-content",className:"min-h-0 flex-1 overflow-y-auto px-5 py-5 sm:px-6",children:e.jsxs(M.div,{initial:{opacity:0,y:4},animate:{opacity:1,y:0},transition:{duration:.18,ease:[.16,1,.3,1]},className:"h-full",children:[o==="overview"?e.jsx(me,{trendRows:m.trendRows,mix:m.mix,activeDevelopers30d:Number(a.activeDevelopers30d)||0,developerGrowthPct:a.developerGrowthPct,formatTokens:i,formatTokensTooltip:r}):null,o==="providers"?e.jsx(ce,{rows:m.providers,maxShare:m.providersMaxShare,formatTokens:i,formatTokensTooltip:r}):null,o==="community"?e.jsx(pe,{bands:m.bands,platforms:m.platforms,formatTokensTooltip:r}):null,o==="models"?e.jsx(xe,{rows:m.models,maxShare:m.modelsMaxShare,formatTokens:i,formatTokensTooltip:r}):null]},o)})]})})]})})}function Ke(t){return e.jsx(R,{mode:P.COMPACT,children:e.jsx(ve,{...t})})}export{Ke as CommunityStatsModal};