tokentracker-cli 0.87.16 → 0.87.18

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 (98) hide show
  1. package/dashboard/dist/assets/{AchievementBadge-DaKHLTL2.js → AchievementBadge-B-noxcU6.js} +1 -1
  2. package/dashboard/dist/assets/{AchievementsPage-DJdtjodG.js → AchievementsPage-DTdf9pER.js} +2 -2
  3. package/dashboard/dist/assets/{AchievementsSection-DVtxGDIP.js → AchievementsSection-BNXGPvFi.js} +1 -1
  4. package/dashboard/dist/assets/{BadgeDetailModal-CF2dlQkT.js → BadgeDetailModal-GSqDWKWX.js} +1 -1
  5. package/dashboard/dist/assets/{Card-DuQWS5aB.js → Card-DEufcTc9.js} +1 -1
  6. package/dashboard/dist/assets/{ClawdAnimated-l8AN6_pc.js → ClawdAnimated-WUHfwJup.js} +1 -1
  7. package/dashboard/dist/assets/{CommandPalette-DWKyGhWG.js → CommandPalette-v0kzoXyy.js} +1 -1
  8. package/dashboard/dist/assets/{CommunityStatsModal-CoJ9i3QH.js → CommunityStatsModal-BRHJI8FA.js} +1 -1
  9. package/dashboard/dist/assets/{ConfirmModal-DM6A6p4g.js → ConfirmModal-BfV6Otpq.js} +1 -1
  10. package/dashboard/dist/assets/{Controls-DBUMibne.js → Controls-CS8GWl0_.js} +1 -1
  11. package/dashboard/dist/assets/{DashboardPage-BgVXjT0v.js → DashboardPage-DhBSaV1l.js} +1 -1
  12. package/dashboard/dist/assets/{DevicePage-Beby6BhC.js → DevicePage-DwtE5Fo_.js} +1 -1
  13. package/dashboard/dist/assets/{DialogClose-nwx-N3WL.js → DialogClose-BPO4reDI.js} +1 -1
  14. package/dashboard/dist/assets/DialogDescription-CMyelOxq.js +1 -0
  15. package/dashboard/dist/assets/{DialogTitle-Cw53obf0.js → DialogTitle-uApcKgX7.js} +1 -1
  16. package/dashboard/dist/assets/{FadeIn-CTTwoVh-.js → FadeIn-VoGmyP56.js} +1 -1
  17. package/dashboard/dist/assets/{HeaderGithubStar-BvaEHM9B.js → HeaderGithubStar-Di6ma4t7.js} +1 -1
  18. package/dashboard/dist/assets/{HoverTooltip-CbJqz6cF.js → HoverTooltip-CArFeCWP.js} +1 -1
  19. package/dashboard/dist/assets/{IpCheckPage-I0REWeew.js → IpCheckPage-D8kqbSMi.js} +1 -1
  20. package/dashboard/dist/assets/{LandingPage-CuMWPQBC.js → LandingPage-c_hJ2nxC.js} +2 -2
  21. package/dashboard/dist/assets/{LeaderboardAvatar-MHfIP4_U.js → LeaderboardAvatar-NeiaXnPA.js} +1 -1
  22. package/dashboard/dist/assets/{LeaderboardPage-DfDM-dH9.js → LeaderboardPage-D2jZsqZO.js} +2 -2
  23. package/dashboard/dist/assets/{LeaderboardProfileModal-hmpU-JV7.js → LeaderboardProfileModal-DxGYxTRa.js} +3 -3
  24. package/dashboard/dist/assets/{LeaderboardProfilePage-DtUb4dDZ.js → LeaderboardProfilePage-BP0JEfYD.js} +1 -1
  25. package/dashboard/dist/assets/{LimitsPage-CtA0c2G5.js → LimitsPage-BZoohpGz.js} +1 -1
  26. package/dashboard/dist/assets/{LocalOnlyNotice-WI3Oke4U.js → LocalOnlyNotice-BuHpzYH-.js} +1 -1
  27. package/dashboard/dist/assets/{LoginCard-DMprjRI7.js → LoginCard-BVMNSKFS.js} +1 -1
  28. package/dashboard/dist/assets/{LoginModal-DffmK0ro.js → LoginModal-CatV5UrC.js} +1 -1
  29. package/dashboard/dist/assets/{LoginPage-B2ZgB6K7.js → LoginPage-DDFk3URM.js} +1 -1
  30. package/dashboard/dist/assets/{PetPage-D_U7yXgF.js → PetPage-pT1vDCh0.js} +1 -1
  31. package/dashboard/dist/assets/{PopoverPopup-Ph-9l9jU.js → PopoverPopup-BFJqtoaw.js} +1 -1
  32. package/dashboard/dist/assets/{ProviderIcon-D2s_KSYC.js → ProviderIcon-C69eUHWk.js} +1 -1
  33. package/dashboard/dist/assets/{ResetPasswordPage-Cpg2C8BI.js → ResetPasswordPage-D6GnL5_5.js} +1 -1
  34. package/dashboard/dist/assets/{SegmentedControl-C89jlPzS.js → SegmentedControl-BvK1j35H.js} +1 -1
  35. package/dashboard/dist/assets/{Select-BLPgobGl.js → Select-CBtN1wOH.js} +1 -1
  36. package/dashboard/dist/assets/{SelectItemText-CLTEQqQZ.js → SelectItemText-XQ9X1IOx.js} +1 -1
  37. package/dashboard/dist/assets/{ServiceStatusPage-Bd1ec7bz.js → ServiceStatusPage-wTlP_RzP.js} +1 -1
  38. package/dashboard/dist/assets/{SessionsPage-HPbQDLZ5.js → SessionsPage-TvegBwjZ.js} +1 -1
  39. package/dashboard/dist/assets/{SettingsPage-CwfcRYYu.js → SettingsPage-C5YgURIn.js} +1 -1
  40. package/dashboard/dist/assets/{SkillsPage-DflhF8pa.js → SkillsPage-BayYyq-C.js} +1 -1
  41. package/dashboard/dist/assets/{TokenGalaxy-CylVSV2J.js → TokenGalaxy-gt_3rCOw.js} +1 -1
  42. package/dashboard/dist/assets/{ToolbarRootContext-BzBAJ8C5.js → ToolbarRootContext-CpG0zm3q.js} +1 -1
  43. package/dashboard/dist/assets/{TrendMonitor-B0IzqLaN.js → TrendMonitor-D6cF0h6n.js} +1 -1
  44. package/dashboard/dist/assets/{WidgetsPage-Bvt5JCoS.js → WidgetsPage-_nQjtAnd.js} +1 -1
  45. package/dashboard/dist/assets/{WrappedPage-BXjDpjD_.js → WrappedPage-DtMQmuQZ.js} +1 -1
  46. package/dashboard/dist/assets/{__vite-browser-external-CDv96ZcG.js → __vite-browser-external-Bqhup8aJ.js} +2 -2
  47. package/dashboard/dist/assets/{agent-logos-bPIt1QVl.js → agent-logos-CG1y0tsV.js} +1 -1
  48. package/dashboard/dist/assets/{arrow-up-right-C_6NrnRB.js → arrow-up-right-DmhLcspZ.js} +1 -1
  49. package/dashboard/dist/assets/{check-ovHAYNwt.js → check-DXt7dlYY.js} +1 -1
  50. package/dashboard/dist/assets/{chevron-right-BeHvjzPf.js → chevron-right-DMarEqgQ.js} +1 -1
  51. package/dashboard/dist/assets/{copy-DRQHwFKm.js → copy-D0m6z9vO.js} +1 -1
  52. package/dashboard/dist/assets/{download-qPfSWDyf.js → download-Dj1tX49Q.js} +1 -1
  53. package/dashboard/dist/assets/{external-link-t7Qbyp7r.js → external-link-B_bvu1xW.js} +1 -1
  54. package/dashboard/dist/assets/{flame-DlRdMOxO.js → flame-CBIFjOx4.js} +1 -1
  55. package/dashboard/dist/assets/{format-tokens-DP1DrOxZ.js → format-tokens-CE8C2sTz.js} +1 -1
  56. package/dashboard/dist/assets/{icons-DBgKdjpV.js → icons-nu4_bWbA.js} +1 -1
  57. package/dashboard/dist/assets/{index-Dtzl1NhK.js → index-AlRPQrQw.js} +1 -1
  58. package/dashboard/dist/assets/{index-C1wNjCL_.js → index-CdIpBI4N.js} +1 -1
  59. package/dashboard/dist/assets/{index-BFaAjCwg.js → index-DsfdpID-.js} +1 -1
  60. package/dashboard/dist/assets/{info-D9fn_ZQQ.js → info-CexkP1mz.js} +1 -1
  61. package/dashboard/dist/assets/{limits-providers-JyTKN-3e.js → limits-providers-DXVJK24-.js} +1 -1
  62. package/dashboard/dist/assets/{link-2-CmnuQiZs.js → link-2-6feCr-mI.js} +1 -1
  63. package/dashboard/dist/assets/{loader-circle-Bm3FqDLX.js → loader-circle-feKU4f7D.js} +1 -1
  64. package/dashboard/dist/assets/{maximize-2-CutKDynW.js → maximize-2-BLxG6I0w.js} +1 -1
  65. package/dashboard/dist/assets/{modifiers.esm-C94MH21S.js → modifiers.esm-D1VDSw2s.js} +1 -1
  66. package/dashboard/dist/assets/{monitor-smartphone-wSLhNWq5.js → monitor-smartphone-CugIHgUy.js} +1 -1
  67. package/dashboard/dist/assets/{provider-display-CR8o_M3v.js → provider-display-DFPtSj_b.js} +1 -1
  68. package/dashboard/dist/assets/{react-Cc1Ca2uE.js → react-C99FCIQ6.js} +1 -1
  69. package/dashboard/dist/assets/{search-BXeDDAWS.js → search-CMPoVoEF.js} +1 -1
  70. package/dashboard/dist/assets/{skills-api-DBP8kM7W.js → skills-api-DyLPnlv8.js} +1 -1
  71. package/dashboard/dist/assets/{sortable.esm-Cd_ODlnX.js → sortable.esm-Dx5vuG82.js} +1 -1
  72. package/dashboard/dist/assets/{store-lmptvFHG.js → store-DjvTYGJ2.js} +1 -1
  73. package/dashboard/dist/assets/{terminal-965BMhR0.js → terminal-BM-AI-XT.js} +1 -1
  74. package/dashboard/dist/assets/{trash-2-wq5YeaAT.js → trash-2-DvJl0rH6.js} +1 -1
  75. package/dashboard/dist/assets/{use-community-stats-BCIgHdTZ.js → use-community-stats-DATwtzaO.js} +1 -1
  76. package/dashboard/dist/assets/{use-limits-display-prefs-D0MB2ewv.js → use-limits-display-prefs-BRL_U9dY.js} +1 -1
  77. package/dashboard/dist/assets/{use-ordered-list-DrQsh022.js → use-ordered-list-L1R4D2H7.js} +1 -1
  78. package/dashboard/dist/assets/use-reduced-motion-Cn8iurQn.js +1 -0
  79. package/dashboard/dist/assets/{use-session-efficiency-pref-BeBSADa-.js → use-session-efficiency-pref-08qoGmbK.js} +1 -1
  80. package/dashboard/dist/assets/{use-transform-fRpwp-G3.js → use-transform-BFpK-EAD.js} +1 -1
  81. package/dashboard/dist/assets/{use-usage-limits-C0Tk-ghm.js → use-usage-limits-DESyo14u.js} +1 -1
  82. package/dashboard/dist/assets/{useCurrency-BAZNRyKh.js → useCurrency-DEvjfAzI.js} +1 -1
  83. package/dashboard/dist/assets/{useScrollLock-CU659jBG.js → useScrollLock-DwixTWaN.js} +1 -1
  84. package/dashboard/dist/assets/{useTokenFormat-l0Xd62a5.js → useTokenFormat-BZE0Ce_8.js} +1 -1
  85. package/dashboard/dist/assets/{zap-CWFkq16a.js → zap-cQ3QAXar.js} +1 -1
  86. package/dashboard/dist/index.html +1 -1
  87. package/dashboard/dist/ip-check.html +1 -1
  88. package/dashboard/dist/leaderboard.html +1 -1
  89. package/dashboard/dist/share.html +1 -1
  90. package/package.json +1 -1
  91. package/src/commands/status.js +28 -9
  92. package/src/commands/sync.js +18 -4
  93. package/src/lib/install-resolver.js +18 -1
  94. package/src/lib/pricing/seed-snapshot.json +1 -1
  95. package/src/lib/rollout.js +18 -5
  96. package/src/lib/session-analytics.js +55 -1
  97. package/dashboard/dist/assets/DialogDescription-BFVB627n.js +0 -1
  98. package/dashboard/dist/assets/use-reduced-motion-DhNppA5X.js +0 -1
@@ -329,15 +329,28 @@ async function parseRolloutIncremental({
329
329
  }) => {
330
330
  if (rebuildingBaseline) return true;
331
331
  if (prev && (!sameInode || truncated)) return true;
332
- if (sameInode && !truncated && startOffset > 0) return false;
333
- if (prev?.lastTotal) return true;
332
+
333
+ // Same session under another cursor path — the two roots of a `union`
334
+ // install (src/lib/install-resolver.js) reaching one file, or a
335
+ // sessions/ -> archived_sessions/ move. This MUST be decided before the
336
+ // steady-state short-circuit below: the append-only tracker only knows keys
337
+ // written during the current run, so when the other path has nothing new to
338
+ // read it contributes none, and a path whose cursor fell behind (a distro
339
+ // that was briefly unreachable, a TOKENTRACKER_WSL_MODE round-trip) replays
340
+ // its gap into the persisted buckets. Only the persisted set can catch that.
334
341
  const sessionId = codexSessionIdFromPath(filePath);
335
342
  if (!sessionId) return true;
336
343
  const knownPaths = getCursorSessionPaths().get(sessionId);
337
- if (!knownPaths) return false;
338
- for (const knownPath of knownPaths) {
339
- if (knownPath !== filePath) return true;
344
+ if (knownPaths) {
345
+ for (const knownPath of knownPaths) {
346
+ if (knownPath !== filePath) return true;
347
+ }
340
348
  }
349
+
350
+ // Steady state: one path, already read past, not rotated. Everything after
351
+ // our own offset is genuinely new, so skip the persisted-set construction.
352
+ if (sameInode && !truncated && startOffset > 0) return false;
353
+ if (prev?.lastTotal) return true;
341
354
  return false;
342
355
  };
343
356
 
@@ -795,6 +795,59 @@ function providerRoots(home, providerDir, env, deps = {}) {
795
795
  return [...new Set(roots)];
796
796
  }
797
797
 
798
+ // Collapse the same Claude session discovered under more than one root.
799
+ //
800
+ // Codex gets this from its session-id pass below; Claude only ever had per-file
801
+ // message dedup (`claudeMessageDedupKey` inside `scanClaudeSession`), which
802
+ // cannot see a second copy of the same file under a different path spelling.
803
+ // Every discovered path becomes its own row keyed by the resolved file path, so
804
+ // a WSL `$HOME` pointing at the Windows profile — the same files reachable as
805
+ // both `C:\Users\dev\.claude\...` and `\\wsl$\Ubuntu\home\dev\.claude\...` —
806
+ // duplicated sessions in the browser, the project list and the CSV export.
807
+ //
808
+ // Cross-root only, on purpose: a single root is passed through verbatim, so
809
+ // single-install machines are unaffected, and two same-named files inside one
810
+ // tree stay distinct (unproven identity must not delete a session). A basename
811
+ // without a session UUID never participates either.
812
+ function dedupeClaudeFilesAcrossRoots(groups) {
813
+ const rootGroups = (groups || []).filter((group) => Array.isArray(group) && group.length > 0);
814
+ if (rootGroups.length <= 1) return [...new Set(rootGroups[0] || [])];
815
+
816
+ const mtimeOf = (filePath) => {
817
+ try { return fs.statSync(filePath).mtimeMs; } catch { return -Infinity; }
818
+ };
819
+ // Preserve root order for everything kept, so native precedence is stable.
820
+ // Claims are compared only against EARLIER roots: two same-UUID files inside
821
+ // one tree are siblings, not copies, and must both survive.
822
+ const ordered = [];
823
+ const winnerBySession = new Map();
824
+ for (const group of rootGroups) {
825
+ const claimedHere = new Map();
826
+ for (const filePath of group) {
827
+ const id = path.basename(filePath).match(/^([0-9a-f-]{36})\.jsonl$/i)?.[1] || null;
828
+ if (!id || claimedHere.has(id)) {
829
+ // No session identity, or a sibling within this same root.
830
+ if (!ordered.includes(filePath)) ordered.push(filePath);
831
+ continue;
832
+ }
833
+ claimedHere.set(id, filePath);
834
+ const previous = winnerBySession.get(id);
835
+ if (previous === undefined) {
836
+ winnerBySession.set(id, filePath);
837
+ ordered.push(filePath);
838
+ continue;
839
+ }
840
+ if (previous === filePath) continue;
841
+ // Same session in an earlier root: keep the newer file, mirroring Codex.
842
+ if (mtimeOf(filePath) > mtimeOf(previous)) {
843
+ winnerBySession.set(id, filePath);
844
+ ordered[ordered.indexOf(previous)] = filePath;
845
+ }
846
+ }
847
+ }
848
+ return [...new Set(ordered)];
849
+ }
850
+
798
851
  async function discoverSessionFiles(home, env = process.env, deps = {}) {
799
852
  const grokHome = resolveGrokHome(home);
800
853
  const claudeRoots = providerRoots(home, ".claude", env, deps);
@@ -805,7 +858,7 @@ async function discoverSessionFiles(home, env = process.env, deps = {}) {
805
858
  Promise.all(codexRoots.map((r) => listRolloutFilesDeep(path.join(r, "archived_sessions")))),
806
859
  listGrokSessionFiles(path.join(grokHome, "sessions")),
807
860
  ]);
808
- const allClaude = [...new Set(claudeGroups.flat())];
861
+ const allClaude = dedupeClaudeFilesAcrossRoots(claudeGroups);
809
862
  const codex = [...new Set(codexGroups.flat())];
810
863
  const archived = [...new Set(archivedGroups.flat())];
811
864
  // Claude Memory stores thousands of background observer transcripts beside
@@ -1302,4 +1355,5 @@ module.exports = {
1302
1355
  resumeCommandFor,
1303
1356
  sessionsToCsv,
1304
1357
  providerRoots,
1358
+ dedupeClaudeFilesAcrossRoots,
1305
1359
  };
@@ -1 +0,0 @@
1
- import{r as n,z as a}from"./__vite-browser-external-CDv96ZcG.js";import{u as p}from"./DialogTitle-Cw53obf0.js";import{u as c}from"./useScrollLock-CU659jBG.js";const x=n.forwardRef(function(e,r){const{render:l,className:u,style:m,id:s,...t}=e,{store: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-CDv96ZcG.js";import{h as r,i as t,p as s}from"./react-Cc1Ca2uE.js";function i(){!r.current&&t();const[e]=o.useState(s.current);return e}export{i as u};