tokentracker-cli 1.1.3 → 1.1.5

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 (120) hide show
  1. package/README.de.md +5 -4
  2. package/README.ja.md +5 -4
  3. package/README.ko.md +5 -4
  4. package/README.md +20 -4
  5. package/README.zh-CN.md +5 -4
  6. package/dashboard/dist/assets/{AchievementBadge-dt_UDU_h.js → AchievementBadge-ClUmGxBJ.js} +1 -1
  7. package/dashboard/dist/assets/{AchievementsPage-B5DJ3S9l.js → AchievementsPage-BB0DFE3m.js} +2 -2
  8. package/dashboard/dist/assets/{AchievementsSection-CDxcyig2.js → AchievementsSection-BMCSk63s.js} +1 -1
  9. package/dashboard/dist/assets/{BadgeDetailModal-Cp98zNn2.js → BadgeDetailModal-DzJtvuKO.js} +1 -1
  10. package/dashboard/dist/assets/{BotAnimated-CR7MiUpo.js → BotAnimated-BviEasW4.js} +1 -1
  11. package/dashboard/dist/assets/{Card-C8IdDvlg.js → Card-BoHr-wLc.js} +1 -1
  12. package/dashboard/dist/assets/{ClawdAnimated-COeTlW8z.js → ClawdAnimated-Bwm8BfqY.js} +2 -2
  13. package/dashboard/dist/assets/{CommandPalette-Co9k2CCc.js → CommandPalette-Rb0Gfcg9.js} +1 -1
  14. package/dashboard/dist/assets/{CommunityStatsModal-C6XQeRgw.js → CommunityStatsModal-Ck7R7Q-d.js} +1 -1
  15. package/dashboard/dist/assets/{ConfirmModal-Ai4182O-.js → ConfirmModal-52Fu9wOi.js} +1 -1
  16. package/dashboard/dist/assets/{Controls-BbKzN-Pe.js → Controls-YlGr187A.js} +1 -1
  17. package/dashboard/dist/assets/DashboardPage-BRim2Rt6.js +1 -0
  18. package/dashboard/dist/assets/{DevicePage-CZbrtJmb.js → DevicePage-3mmhzfgd.js} +1 -1
  19. package/dashboard/dist/assets/{DialogClose-DMl8tAoX.js → DialogClose-D1KfBYUS.js} +1 -1
  20. package/dashboard/dist/assets/DialogDescription-BhWwQSSg.js +1 -0
  21. package/dashboard/dist/assets/{DialogTitle-BJxpp2t-.js → DialogTitle-DKye2nJK.js} +1 -1
  22. package/dashboard/dist/assets/{FadeIn-hU_MXl6R.js → FadeIn-mJp_ZFst.js} +1 -1
  23. package/dashboard/dist/assets/{HeaderGithubStar-CM5RSxxN.js → HeaderGithubStar-B2R_aqp9.js} +1 -1
  24. package/dashboard/dist/assets/{HoverTooltip-BZKfQyZQ.js → HoverTooltip-ElY02914.js} +1 -1
  25. package/dashboard/dist/assets/{IpCheckPage-BjDx-zja.js → IpCheckPage-CNzPUe3x.js} +1 -1
  26. package/dashboard/dist/assets/{LandingPage-CAt8BCDv.js → LandingPage-L25-CxXg.js} +2 -2
  27. package/dashboard/dist/assets/{LeaderboardAvatar-DiCrakjI.js → LeaderboardAvatar-BT7x5wAP.js} +1 -1
  28. package/dashboard/dist/assets/{LeaderboardPage-Dj3pHv6U.js → LeaderboardPage-bPce9gOU.js} +2 -2
  29. package/dashboard/dist/assets/{LeaderboardProfileModal-DEWbcP9p.js → LeaderboardProfileModal-DPrFGAp6.js} +3 -3
  30. package/dashboard/dist/assets/{LeaderboardProfilePage-CTbWHQkY.js → LeaderboardProfilePage-j2D1pwYO.js} +1 -1
  31. package/dashboard/dist/assets/{LimitsPage-V-98OUhF.js → LimitsPage-CSED1kBx.js} +1 -1
  32. package/dashboard/dist/assets/{LocalOnlyNotice-a4PqtUZY.js → LocalOnlyNotice-D6OERWez.js} +1 -1
  33. package/dashboard/dist/assets/{LoginCard-oD1A2Ru8.js → LoginCard-HgmRdIn8.js} +1 -1
  34. package/dashboard/dist/assets/{LoginModal-D8aSmxok.js → LoginModal-BSlEmKOV.js} +1 -1
  35. package/dashboard/dist/assets/{LoginPage-DIjhBv2X.js → LoginPage-HQAhowvh.js} +1 -1
  36. package/dashboard/dist/assets/{PetPage-D7601BTX.js → PetPage-DnbYfu-z.js} +1 -1
  37. package/dashboard/dist/assets/{PopoverPopup-aPnmKopO.js → PopoverPopup-DnyVdfB8.js} +1 -1
  38. package/dashboard/dist/assets/{ProviderIcon-rwyfcNlT.js → ProviderIcon-D8kgkZlR.js} +1 -1
  39. package/dashboard/dist/assets/{ResetPasswordPage-AF3SBgW2.js → ResetPasswordPage-ChtXGykP.js} +1 -1
  40. package/dashboard/dist/assets/{SegmentedControl-fnlScNMT.js → SegmentedControl-dHUpXqFk.js} +1 -1
  41. package/dashboard/dist/assets/{Select-DDjC3RjB.js → Select-C0tpjNiq.js} +1 -1
  42. package/dashboard/dist/assets/{SelectItemText-VhBWE2O8.js → SelectItemText-C3G_w14k.js} +1 -1
  43. package/dashboard/dist/assets/{ServiceStatusPage-BL3qqEsp.js → ServiceStatusPage-D6x4e1r8.js} +1 -1
  44. package/dashboard/dist/assets/{SessionsPage-DXYiuP2x.js → SessionsPage-DZH1QMWd.js} +1 -1
  45. package/dashboard/dist/assets/{SettingsPage-DTeA_ahr.js → SettingsPage-DGmDb2R4.js} +2 -2
  46. package/dashboard/dist/assets/{SkillsPage-CtTRwVQH.js → SkillsPage-ChloCHPa.js} +1 -1
  47. package/dashboard/dist/assets/{TokenGalaxy-CifK91V7.js → TokenGalaxy-DOC9wlkv.js} +1 -1
  48. package/dashboard/dist/assets/{ToolbarRootContext-ClGAIYoa.js → ToolbarRootContext-BB_d-qdY.js} +1 -1
  49. package/dashboard/dist/assets/{TrendMonitor-D1evFHRM.js → TrendMonitor-DVVzYdc7.js} +1 -1
  50. package/dashboard/dist/assets/{WidgetsPage-Cq4RYJDE.js → WidgetsPage-DHVSyU0i.js} +1 -1
  51. package/dashboard/dist/assets/{WrappedPage-CoC5RJH7.js → WrappedPage-BDi28nRt.js} +1 -1
  52. package/dashboard/dist/assets/__vite-browser-external-Bnc5aBhq.js +45 -0
  53. package/dashboard/dist/assets/{agent-logos-QLdA9OeA.js → agent-logos-BiGvZiLq.js} +1 -1
  54. package/dashboard/dist/assets/{arrow-up-right-BYLgB3bH.js → arrow-up-right-SvD82rok.js} +1 -1
  55. package/dashboard/dist/assets/{check-DfnIvqZD.js → check-jL5XErEW.js} +1 -1
  56. package/dashboard/dist/assets/{composite--JllTpIX.js → composite-DM6geXPA.js} +1 -1
  57. package/dashboard/dist/assets/{copy-ClKVBIgD.js → copy-Dy_GIzj2.js} +1 -1
  58. package/dashboard/dist/assets/{download-Di1-UFJX.js → download-BW_FS7nX.js} +1 -1
  59. package/dashboard/dist/assets/{external-link-D7zPVFLO.js → external-link-2RIovvCT.js} +1 -1
  60. package/dashboard/dist/assets/{flame-BMJTxjVg.js → flame-CIRJIxxA.js} +1 -1
  61. package/dashboard/dist/assets/{format-tokens-DCZM5Nfn.js → format-tokens-CT8ahEK4.js} +1 -1
  62. package/dashboard/dist/assets/{icons-I615W2IU.js → icons-7J1WD0C-.js} +1 -1
  63. package/dashboard/dist/assets/{index-BX3CXVdD.js → index-D3iSSyYr.js} +1 -1
  64. package/dashboard/dist/assets/{index-CwczM3BZ.js → index-Ddb2A6Mx.js} +1 -1
  65. package/dashboard/dist/assets/{index-BejnmdPe.js → index-_vJl6sF7.js} +1 -1
  66. package/dashboard/dist/assets/{info-CFJPny5Q.js → info-BjVWcOOC.js} +1 -1
  67. package/dashboard/dist/assets/{link-2-D1ydWh_w.js → link-2-CyRWnHWE.js} +1 -1
  68. package/dashboard/dist/assets/{loader-circle-Cq-J-OFg.js → loader-circle-DUpG5zah.js} +1 -1
  69. package/dashboard/dist/assets/{maximize-2-kIoSq57I.js → maximize-2-BVGCRkFZ.js} +1 -1
  70. package/dashboard/dist/assets/{modifiers.esm-CLojthuF.js → modifiers.esm-CZI7rED4.js} +1 -1
  71. package/dashboard/dist/assets/module-WSx8viXK.js +3 -0
  72. package/dashboard/dist/assets/{monitor-smartphone-DX2qWHYV.js → monitor-smartphone-DfBtd01T.js} +1 -1
  73. package/dashboard/dist/assets/{plus-B-JEpo3V.js → plus-CvbLCvjV.js} +1 -1
  74. package/dashboard/dist/assets/{provider-display-DJDdrTAS.js → provider-display-DC46GLrv.js} +2 -2
  75. package/dashboard/dist/assets/{react-Ctoe8iLl.js → react-mYr3J8Vw.js} +1 -1
  76. package/dashboard/dist/assets/{search-BTSQrlW-.js → search-CFaS1rSj.js} +1 -1
  77. package/dashboard/dist/assets/{skills-api-DKQyM8h7.js → skills-api-B1N6seFa.js} +1 -1
  78. package/dashboard/dist/assets/{sortable.esm-pOEL13xU.js → sortable.esm-BE2GiQaC.js} +1 -1
  79. package/dashboard/dist/assets/{store-B2RplzvW.js → store-DwBbExah.js} +1 -1
  80. package/dashboard/dist/assets/{terminal-BH_6_EW_.js → terminal-Bl2BuO9x.js} +1 -1
  81. package/dashboard/dist/assets/{trash-CC444Mz6.js → trash-D8beb27Y.js} +1 -1
  82. package/dashboard/dist/assets/{use-community-stats-CBXLdD_j.js → use-community-stats-DJG1DsXR.js} +1 -1
  83. package/dashboard/dist/assets/{use-latest-request-guard-DMuPfZQI.js → use-latest-request-guard-DYK8iyOM.js} +1 -1
  84. package/dashboard/dist/assets/{use-limits-display-prefs-CmsGTBA4.js → use-limits-display-prefs-BGmcFVX3.js} +1 -1
  85. package/dashboard/dist/assets/{use-ordered-list-BNJNpXjB.js → use-ordered-list-Cqia_VIq.js} +1 -1
  86. package/dashboard/dist/assets/use-reduced-motion-CmCk9Sb5.js +1 -0
  87. package/dashboard/dist/assets/{use-session-efficiency-pref-g_0ISxe1.js → use-session-efficiency-pref-Mj3OeVGZ.js} +1 -1
  88. package/dashboard/dist/assets/{use-transform-D36BHcXk.js → use-transform-D4BQIBHx.js} +1 -1
  89. package/dashboard/dist/assets/{use-usage-limits-Dxw3vzsD.js → use-usage-limits-BFrO7Mtq.js} +1 -1
  90. package/dashboard/dist/assets/{useCurrency-V2FE4TMo.js → useCurrency-CYJavR2h.js} +1 -1
  91. package/dashboard/dist/assets/{useTokenFormat-CEOwvzMt.js → useTokenFormat-CKruI7SP.js} +1 -1
  92. package/dashboard/dist/assets/{zap-BS7ZU76I.js → zap-a82fG76c.js} +1 -1
  93. package/dashboard/dist/brand-logos/trae.svg +1 -0
  94. package/dashboard/dist/index.html +13 -11
  95. package/dashboard/dist/ip-check.html +1 -1
  96. package/dashboard/dist/leaderboard.html +1 -1
  97. package/dashboard/dist/llms.txt +3 -2
  98. package/dashboard/dist/share.html +1 -1
  99. package/package.json +6 -4
  100. package/src/commands/init.js +9 -7
  101. package/src/commands/status.js +66 -11
  102. package/src/commands/sync.js +115 -11
  103. package/src/lib/codex-context-breakdown.js +3 -1
  104. package/src/lib/diagnostics.js +20 -1
  105. package/src/lib/doctor.js +30 -0
  106. package/src/lib/pricing/curated-overrides.json +7 -0
  107. package/src/lib/pricing/matcher.js +5 -0
  108. package/src/lib/pricing/seed-snapshot.json +1 -1
  109. package/src/lib/rollout.js +197 -18
  110. package/src/lib/scan-roots.js +277 -0
  111. package/src/lib/session-analytics.js +98 -16
  112. package/src/lib/trae-db.js +127 -0
  113. package/src/lib/trae-snapshot.js +230 -0
  114. package/src/lib/trae-sqlite.js +143 -0
  115. package/src/lib/trae-usage.js +121 -0
  116. package/dashboard/dist/assets/DashboardPage-DTcVGG4e.js +0 -1
  117. package/dashboard/dist/assets/DialogDescription-haPz7CX9.js +0 -1
  118. package/dashboard/dist/assets/__vite-browser-external-BDugA6I0.js +0 -45
  119. package/dashboard/dist/assets/module-DtWfRKM4.js +0 -3
  120. package/dashboard/dist/assets/use-reduced-motion-CNpG-Yoi.js +0 -1
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+
3
+ // TRAE stores the last request's usage alongside optional whole-turn prompt
4
+ // and completion counters. Reconcile the request first: its total cannot
5
+ // validate a whole-turn count, and its cache count is not a whole-turn count.
6
+ function normalizeTraeUsage(raw, { model } = {}) {
7
+ let usage = raw;
8
+ if (typeof usage === "string") {
9
+ try { usage = JSON.parse(usage); } catch { return null; }
10
+ }
11
+ if (!usage || typeof usage !== "object" || Array.isArray(usage)) return null;
12
+ const fields = [
13
+ "prompt_tokens", "prompt_tokens_total", "input_tokens",
14
+ "completion_tokens", "completion_tokens_total", "output_tokens",
15
+ "cache_read_input_tokens", "cache_creation_input_tokens",
16
+ "reasoning_tokens", "reasoning_output_tokens", "total_tokens",
17
+ ];
18
+ for (const field of fields) {
19
+ if (usage[field] != null && (!Number.isSafeInteger(usage[field]) || usage[field] < 0)) {
20
+ return null;
21
+ }
22
+ }
23
+ for (const [left, right] of [["prompt_tokens", "input_tokens"],
24
+ ["completion_tokens", "output_tokens"], ["reasoning_tokens", "reasoning_output_tokens"]]) {
25
+ if (usage[left] != null && usage[right] != null && usage[left] !== usage[right]) return null;
26
+ }
27
+ if (!["prompt_tokens", "prompt_tokens_total", "input_tokens", "completion_tokens",
28
+ "completion_tokens_total", "output_tokens"].some((field) => usage[field] != null)) {
29
+ return null;
30
+ }
31
+ const input = usage.prompt_tokens ?? usage.input_tokens ?? usage.prompt_tokens_total ?? 0;
32
+ const output = usage.completion_tokens ?? usage.output_tokens ?? usage.completion_tokens_total ?? 0;
33
+ const aggregateInput = usage.prompt_tokens_total > 0 ? usage.prompt_tokens_total : input;
34
+ const aggregateOutput = usage.completion_tokens_total > 0 ? usage.completion_tokens_total : output;
35
+ if (aggregateInput < input || aggregateOutput < output) return null;
36
+ const cached = usage.cache_read_input_tokens ?? 0;
37
+ let written = usage.cache_creation_input_tokens ?? 0;
38
+ let reasoning = usage.reasoning_tokens ?? usage.reasoning_output_tokens ?? 0;
39
+ let estimated = false;
40
+ const isGemini = /^gemini(?:-|$)/i.test(normalizeTraeModel(model ?? usage.name));
41
+ // Some TRAE Gemini rows copy the cache-read counter into the write field,
42
+ // even when their sum exceeds the entire prompt. Gemini's GenerateContent
43
+ // metadata reports cachedContentTokenCount, not an additional write count.
44
+ // Keep the reported read and mark this narrow compatibility repair estimated.
45
+ if (isGemini && cached > 0 && written === cached && cached + written > input) {
46
+ written = 0;
47
+ estimated = true;
48
+ }
49
+ // Older TRAE Gemini rows omit thoughts while retaining Gemini's total
50
+ // (prompt + candidates + thoughts). Infer only that documented residual,
51
+ // never an arbitrary provider's unexplained total.
52
+ if (isGemini && usage.reasoning_tokens == null && usage.reasoning_output_tokens == null &&
53
+ usage.total_tokens > input + output && written === 0 && cached <= input) {
54
+ reasoning = usage.total_tokens - input - output;
55
+ estimated = true;
56
+ }
57
+ // A total is necessary to distinguish inclusive/exclusive counters when
58
+ // cache or reasoning is present. Missing metadata must not imply $0 usage
59
+ // or guessed input. A zero *_total field means unset, not an empty turn.
60
+ if (usage.total_tokens == null && (cached || written || reasoning)) return null;
61
+ const total = usage.total_tokens ?? (input + output);
62
+ if (!Number.isSafeInteger(total)) return null;
63
+ const candidates = new Map();
64
+ for (const includedCache of new Set([cached + written, cached, 0])) {
65
+ for (const includedReasoning of new Set([reasoning, 0])) {
66
+ const noncached = input - includedCache;
67
+ const nonreasoning = output - includedReasoning;
68
+ if (noncached < 0 || nonreasoning < 0) continue;
69
+ if (noncached + cached + written + nonreasoning + reasoning !== total) continue;
70
+ const totals = {
71
+ input_tokens: noncached,
72
+ cached_input_tokens: cached,
73
+ cache_creation_input_tokens: written,
74
+ output_tokens: nonreasoning,
75
+ reasoning_output_tokens: reasoning,
76
+ total_tokens: total,
77
+ };
78
+ candidates.set(JSON.stringify(totals), totals);
79
+ }
80
+ }
81
+ if (candidates.size !== 1) return null;
82
+ const totals = candidates.values().next().value;
83
+ if (aggregateInput !== input || aggregateOutput !== output) {
84
+ // The *_total counters cover the whole turn; the cache and reasoning fields
85
+ // describe its final request. The difference in prompt tokens has no cache
86
+ // split, so it counts toward total_tokens but no priced column. Completion
87
+ // tokens are priced the same with or without caching and stay in output.
88
+ const unpriced = aggregateInput - input;
89
+ totals.output_tokens += aggregateOutput - output;
90
+ totals.total_tokens += unpriced + aggregateOutput - output;
91
+ if (unpriced > 0) totals.unpriced_input_tokens = unpriced;
92
+ }
93
+ if (Object.values(totals).some((value) => !Number.isSafeInteger(value))) return null;
94
+ if (estimated) totals.usage_precision = "estimated";
95
+ return totals;
96
+ }
97
+
98
+ function normalizeTraeModel(value) {
99
+ if (typeof value !== "string") return "trae-unknown";
100
+ const model = value.trim().split("__")[0].toLowerCase().replace(/\s+/g, "-");
101
+ // TRAE's display alias otherwise fuzzy-matches a regional Sonnet SKU and
102
+ // loses cache pricing. Sonnet 4 has the fixed 2025-05-14 API model id.
103
+ if (model === "claude-4-sonnet") return "claude-sonnet-4-20250514";
104
+ return model && model !== "-" && !model.includes("|") ? model : "trae-unknown";
105
+ }
106
+
107
+ function traeTimestamp(value) {
108
+ if (value == null || value === "") return null;
109
+ let millis;
110
+ if (typeof value === "number" || (typeof value === "string" && /^\d+(\.\d+)?$/.test(value))) {
111
+ const numeric = Number(value);
112
+ millis = numeric < 100_000_000_000 ? numeric * 1000 : numeric;
113
+ } else if (typeof value === "string") {
114
+ millis = Date.parse(value);
115
+ }
116
+ if (!Number.isFinite(millis) || millis <= 0) return null;
117
+ const date = new Date(millis);
118
+ return Number.isFinite(date.getTime()) ? date.toISOString() : null;
119
+ }
120
+
121
+ module.exports = { normalizeTraeUsage, normalizeTraeModel, traeTimestamp };