tokentracker-cli 0.81.2 → 0.82.0

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 (137) hide show
  1. package/dashboard/dist/assets/AchievementBadge-D6iPEEbz.js +1 -0
  2. package/dashboard/dist/assets/AchievementsPage-Jry355YE.js +2 -0
  3. package/dashboard/dist/assets/AchievementsSection-ah-kG00E.js +1 -0
  4. package/dashboard/dist/assets/BadgeDetailModal-FyvUrVvF.js +1 -0
  5. package/dashboard/dist/assets/Card-C3nLScju.js +1 -0
  6. package/dashboard/dist/assets/ClawdAnimated-CLHhE26z.js +1 -0
  7. package/dashboard/dist/assets/CommunityStatsModal-DA3PHLV5.js +1 -0
  8. package/dashboard/dist/assets/ConfirmModal-CTDarLrD.js +1 -0
  9. package/dashboard/dist/assets/DashboardPage-DZIiWc3Y.js +1 -0
  10. package/dashboard/dist/assets/DevicePage-CyXjUO8W.js +1 -0
  11. package/dashboard/dist/assets/DialogDescription-ahxSNUcB.js +1 -0
  12. package/dashboard/dist/assets/DialogTitle-z86PHHyk.js +1 -0
  13. package/dashboard/dist/assets/FadeIn-BDWtfIsO.js +1 -0
  14. package/dashboard/dist/assets/HeaderGithubStar-DE1USQbb.js +1 -0
  15. package/dashboard/dist/assets/{IpCheckPage-CMf9CHFr.js → IpCheckPage-B2SkgT0P.js} +3 -3
  16. package/dashboard/dist/assets/{LandingPage-BT61_TqT.js → LandingPage-PU5gxsfY.js} +165 -165
  17. package/dashboard/dist/assets/LeaderboardAvatar-CaOV_hFE.js +1 -0
  18. package/dashboard/dist/assets/LeaderboardPage-B0JtEyRP.js +2 -0
  19. package/dashboard/dist/assets/{LeaderboardProfileModal-C_kxqOMn.js → LeaderboardProfileModal-DtNEbVH8.js} +4 -4
  20. package/dashboard/dist/assets/{LeaderboardProfilePage-zgNsE0EQ.js → LeaderboardProfilePage-DRklax3-.js} +3 -3
  21. package/dashboard/dist/assets/LimitsPage-Dg0cJa40.js +4 -0
  22. package/dashboard/dist/assets/LocalOnlyNotice-si9PMKya.js +1 -0
  23. package/dashboard/dist/assets/LoginPage-DgLwhXKo.js +1 -0
  24. package/dashboard/dist/assets/PetPage-DEZbjk99.js +1 -0
  25. package/dashboard/dist/assets/PopoverPopup-DX7v1XfE.js +1 -0
  26. package/dashboard/dist/assets/ResetPasswordPage-C6NvRO-Q.js +1 -0
  27. package/dashboard/dist/assets/Select-CH2xVU8X.js +1 -0
  28. package/dashboard/dist/assets/SelectItemText-CCW6JeeN.js +1 -0
  29. package/dashboard/dist/assets/SettingsPage-Cm3uT11D.js +1 -0
  30. package/dashboard/dist/assets/SkillsPage-CljRL6yF.js +1 -0
  31. package/dashboard/dist/assets/TrendMonitor-DM1_WNfw.js +19 -0
  32. package/dashboard/dist/assets/WidgetsPage-mJ1j6hly.js +1 -0
  33. package/dashboard/dist/assets/WrappedPage-Dz71ln4t.js +1 -0
  34. package/dashboard/dist/assets/__vite-browser-external-C7JwykID.css +1 -0
  35. package/dashboard/dist/assets/__vite-browser-external-Eoyj4eG-.js +1341 -0
  36. package/dashboard/dist/assets/agent-logos-D3K_ZRUj.js +1 -0
  37. package/dashboard/dist/assets/arrow-up-right-CT4-gmOS.js +1 -0
  38. package/dashboard/dist/assets/check-B87_qvAg.js +1 -0
  39. package/dashboard/dist/assets/copy-Dtr68epm.js +1 -0
  40. package/dashboard/dist/assets/download-DaWsA_Gj.js +1 -0
  41. package/dashboard/dist/assets/flame-vLBOq0X0.js +1 -0
  42. package/dashboard/dist/assets/format-tokens-C6Pidz3s.js +1 -0
  43. package/dashboard/dist/assets/icons-BaaYJxUN.js +1 -0
  44. package/dashboard/dist/assets/index-lKnLA6Pd.js +1 -0
  45. package/dashboard/dist/assets/info-B46Qt16h.js +1 -0
  46. package/dashboard/dist/assets/limits-providers-13af4PEg.js +1 -0
  47. package/dashboard/dist/assets/link-2-DeN6MJpT.js +1 -0
  48. package/dashboard/dist/assets/loader-circle-ByEuaaSw.js +1 -0
  49. package/dashboard/dist/assets/provider-display-CKbOKeV4.js +42 -0
  50. package/dashboard/dist/assets/terminal-DyicX7lG.js +1 -0
  51. package/dashboard/dist/assets/trash-2-CVCC3DtQ.js +1 -0
  52. package/dashboard/dist/assets/use-community-stats-CExk3D6G.js +1 -0
  53. package/dashboard/dist/assets/use-limits-display-prefs-CRl4uU95.js +1 -0
  54. package/dashboard/dist/assets/use-native-settings-Bi6E9dsE.js +1 -0
  55. package/dashboard/dist/assets/{use-ordered-list-DPbiKnPc.js → use-ordered-list-Dk0p2otw.js} +2 -2
  56. package/dashboard/dist/assets/use-session-efficiency-pref-YAG-OYIh.js +1 -0
  57. package/dashboard/dist/assets/use-transform-lflyghWN.js +1 -0
  58. package/dashboard/dist/assets/use-usage-limits-DJXvJ25Q.js +1 -0
  59. package/dashboard/dist/assets/useCurrency-BtHtcsO5.js +1 -0
  60. package/dashboard/dist/assets/useScrollLock-C2C-Yazq.js +1 -0
  61. package/dashboard/dist/assets/useTokenFormat-BdD057ih.js +1 -0
  62. package/dashboard/dist/assets/zap-DWWma29E.js +1 -0
  63. package/dashboard/dist/index.html +2 -2
  64. package/dashboard/dist/share.html +2 -2
  65. package/package.json +1 -1
  66. package/src/cli.js +6 -0
  67. package/src/commands/serve.js +8 -6
  68. package/src/commands/sessions.js +29 -0
  69. package/src/commands/status.js +2 -1
  70. package/src/commands/sync.js +164 -36
  71. package/src/lib/codex-context-breakdown.js +330 -13
  72. package/src/lib/codex-rollout-parser.js +323 -42
  73. package/src/lib/context-health.js +124 -0
  74. package/src/lib/cursor-store.js +1289 -0
  75. package/src/lib/diagnostics.js +8 -5
  76. package/src/lib/fs.js +254 -16
  77. package/src/lib/git-outcomes.js +147 -0
  78. package/src/lib/local-api.js +151 -20
  79. package/src/lib/outcomes-engine.js +23 -0
  80. package/src/lib/pricing/index.js +8 -0
  81. package/src/lib/pricing/seed-snapshot.json +1 -1
  82. package/src/lib/rollout.js +101 -9
  83. package/src/lib/session-analytics.js +612 -0
  84. package/src/lib/usage-limits.js +21 -0
  85. package/dashboard/dist/assets/AchievementBadge-DXWHZrAL.js +0 -1
  86. package/dashboard/dist/assets/AchievementsPage-BhrQXniL.js +0 -2
  87. package/dashboard/dist/assets/AchievementsSection-gzP3m1Ml.js +0 -1
  88. package/dashboard/dist/assets/BadgeDetailModal-DGKPuvDU.js +0 -1
  89. package/dashboard/dist/assets/Card-BRtYQ-Ot.js +0 -1
  90. package/dashboard/dist/assets/ClawdAnimated-UsNG-qDv.js +0 -1
  91. package/dashboard/dist/assets/CommunityStatsModal-CJQw-P4t.js +0 -1
  92. package/dashboard/dist/assets/ConfirmModal-ByY4GDsy.js +0 -1
  93. package/dashboard/dist/assets/DashboardPage-CuLVnW98.js +0 -19
  94. package/dashboard/dist/assets/DevicePage-D67CxpmR.js +0 -1
  95. package/dashboard/dist/assets/DialogClose-Ci8hkTw5.js +0 -1
  96. package/dashboard/dist/assets/DialogDescription-C9vXUZU0.js +0 -1
  97. package/dashboard/dist/assets/DialogTitle-sLJxKWjv.js +0 -1
  98. package/dashboard/dist/assets/FadeIn-xVds37w6.js +0 -1
  99. package/dashboard/dist/assets/HeaderGithubStar-kK3omgmB.js +0 -1
  100. package/dashboard/dist/assets/LeaderboardAvatar-DyKz6NdT.js +0 -1
  101. package/dashboard/dist/assets/LeaderboardPage-DJ4zihJJ.js +0 -2
  102. package/dashboard/dist/assets/LimitsPage-BiQpqxj8.js +0 -4
  103. package/dashboard/dist/assets/LocalOnlyNotice-DTrrUVbZ.js +0 -1
  104. package/dashboard/dist/assets/LoginPage-BOM9Q2sI.js +0 -1
  105. package/dashboard/dist/assets/PetPage-BURk7RG-.js +0 -1
  106. package/dashboard/dist/assets/PopoverPopup-BV_aoNBd.js +0 -1
  107. package/dashboard/dist/assets/ResetPasswordPage-SBL2LvXC.js +0 -1
  108. package/dashboard/dist/assets/Select-BsRdHde3.js +0 -1
  109. package/dashboard/dist/assets/SelectItemText-DgkrZxIq.js +0 -1
  110. package/dashboard/dist/assets/SettingsPage-DqxVsfnB.js +0 -1
  111. package/dashboard/dist/assets/SkillsPage-B0VfWkOh.js +0 -1
  112. package/dashboard/dist/assets/WidgetsPage-4QQ8wI_g.js +0 -1
  113. package/dashboard/dist/assets/WrappedPage-BK53khVY.js +0 -1
  114. package/dashboard/dist/assets/agent-logos-DXpW_Wmz.js +0 -1
  115. package/dashboard/dist/assets/arrow-up-right-DCc--V5G.js +0 -1
  116. package/dashboard/dist/assets/check-DqxuosV2.js +0 -1
  117. package/dashboard/dist/assets/copy-qChAT7MY.js +0 -1
  118. package/dashboard/dist/assets/download-W9R3sBph.js +0 -1
  119. package/dashboard/dist/assets/flame-0eyhMnfU.js +0 -1
  120. package/dashboard/dist/assets/format-tokens-CkfBUcoa.js +0 -1
  121. package/dashboard/dist/assets/info-DY1O85-U.js +0 -1
  122. package/dashboard/dist/assets/link-2-B_Z66hFT.js +0 -1
  123. package/dashboard/dist/assets/loader-circle-xH40lon2.js +0 -1
  124. package/dashboard/dist/assets/main-CeaB5N36.js +0 -1259
  125. package/dashboard/dist/assets/main-DAc77vwF.css +0 -1
  126. package/dashboard/dist/assets/provider-display-C_XKZQcF.js +0 -42
  127. package/dashboard/dist/assets/trash-2-DVhNJ74r.js +0 -1
  128. package/dashboard/dist/assets/use-community-stats-CO-nr2Vf.js +0 -1
  129. package/dashboard/dist/assets/use-limits-display-prefs-RRqmyoxt.js +0 -1
  130. package/dashboard/dist/assets/use-native-settings-79piPeET.js +0 -1
  131. package/dashboard/dist/assets/use-quality-per-dollar-pref-DyF49QRF.js +0 -1
  132. package/dashboard/dist/assets/use-transform-BvXyGAtb.js +0 -1
  133. package/dashboard/dist/assets/use-usage-limits-BiZ_I-KE.js +0 -1
  134. package/dashboard/dist/assets/useCurrency-D-C1e7eE.js +0 -1
  135. package/dashboard/dist/assets/useScrollLock-BfU2EMvG.js +0 -1
  136. package/dashboard/dist/assets/useTokenFormat-Cm4EvrQp.js +0 -1
  137. package/dashboard/dist/assets/zap-DlAOTwFs.js +0 -1
@@ -167,6 +167,7 @@ async function listOpencodeMessageFiles(storageDir) {
167
167
  async function parseRolloutIncremental({
168
168
  rolloutFiles,
169
169
  cursors,
170
+ codexEventStore,
170
171
  queuePath,
171
172
  projectQueuePath,
172
173
  onProgress,
@@ -200,8 +201,16 @@ async function parseRolloutIncremental({
200
201
  // the claudeHashes pattern: it makes an inode-changing re-scan idempotent so an
201
202
  // external rewrite of a session file (Codex-Manager's atomic provider-patch on
202
203
  // account switch, issue #187) cannot re-count already-counted events.
204
+ const externalCodexEventStore =
205
+ codexEventStore &&
206
+ typeof codexEventStore.has === "function" &&
207
+ typeof codexEventStore.add === "function"
208
+ ? codexEventStore
209
+ : null;
203
210
  const prevCodexHashes = Array.isArray(cursors?.codexHashes) ? cursors.codexHashes : [];
204
- if (!Array.isArray(cursors.codexHashes)) cursors.codexHashes = prevCodexHashes;
211
+ if (!externalCodexEventStore && !Array.isArray(cursors.codexHashes)) {
212
+ cursors.codexHashes = prevCodexHashes;
213
+ }
205
214
  let seenCodexEvents = null;
206
215
  let newCodexEventKeys = null;
207
216
  let newCodexEventKeySet = null;
@@ -229,7 +238,9 @@ async function parseRolloutIncremental({
229
238
  hash_set_constructions: 0,
230
239
  hash_array_materializations: 0,
231
240
  hash_array_materialized_items: 0,
232
- codex_hash_count: prevCodexHashes.length,
241
+ codex_hash_count: externalCodexEventStore
242
+ ? Number(externalCodexEventStore.size || 0)
243
+ : prevCodexHashes.length,
233
244
  });
234
245
  }
235
246
  const ensureNewCodexEventKeys = () => {
@@ -242,6 +253,7 @@ async function parseRolloutIncremental({
242
253
  newCodexEventKeySet.add(key);
243
254
  newCodexEventKeys.push(key);
244
255
  if (seenCodexEvents) seenCodexEvents.add(key);
256
+ externalCodexEventStore?.add(key);
245
257
  };
246
258
  const getAppendOnlyCodexEvents = () => {
247
259
  if (!appendOnlyCodexEvents) {
@@ -258,6 +270,20 @@ async function parseRolloutIncremental({
258
270
  return appendOnlyCodexEvents;
259
271
  };
260
272
  const getHistoricalCodexEvents = () => {
273
+ if (externalCodexEventStore) {
274
+ if (!historicalCodexEvents) {
275
+ historicalCodexEvents = {
276
+ has(key) {
277
+ return Boolean(
278
+ newCodexEventKeySet?.has(key) ||
279
+ externalCodexEventStore.has(key)
280
+ );
281
+ },
282
+ add: recordNewCodexEvent,
283
+ };
284
+ }
285
+ return historicalCodexEvents;
286
+ }
261
287
  if (!seenCodexEvents) {
262
288
  seenCodexEvents = new Set(prevCodexHashes);
263
289
  for (const key of newCodexEventKeys || []) seenCodexEvents.add(key);
@@ -470,11 +496,15 @@ async function parseRolloutIncremental({
470
496
  const projectBucketsQueued = projectEnabled
471
497
  ? await enqueueTouchedProjectBuckets({ projectQueuePath, projectState, projectTouchedBuckets })
472
498
  : 0;
473
- for (const key of newCodexEventKeys || []) prevCodexHashes.push(key);
499
+ if (!externalCodexEventStore) {
500
+ for (const key of newCodexEventKeys || []) prevCodexHashes.push(key);
501
+ }
474
502
  if (syncDiagnostics) {
475
- syncDiagnostics.codex_hash_count = Array.isArray(cursors.codexHashes)
476
- ? cursors.codexHashes.length
477
- : prevCodexHashes.length;
503
+ syncDiagnostics.codex_hash_count = externalCodexEventStore
504
+ ? Number(externalCodexEventStore.size || 0)
505
+ : Array.isArray(cursors.codexHashes)
506
+ ? cursors.codexHashes.length
507
+ : prevCodexHashes.length;
478
508
  }
479
509
  hourlyState.updatedAt = new Date().toISOString();
480
510
  cursors.hourly = hourlyState;
@@ -489,6 +519,7 @@ async function parseRolloutIncremental({
489
519
  async function filterColdCodexRolloutFiles({
490
520
  rolloutFiles,
491
521
  cursors,
522
+ codexCursorStore = null,
492
523
  projectEnabled = false,
493
524
  auditDue = false,
494
525
  nowMs = Date.now(),
@@ -506,18 +537,50 @@ async function filterColdCodexRolloutFiles({
506
537
  0,
507
538
  );
508
539
  syncDiagnostics.discovered_rollouts = discoveredRollouts;
509
- syncDiagnostics.cursor_keys = Object.keys(cursors?.files || {}).length;
540
+ syncDiagnostics.cursor_keys = Number.isFinite(codexCursorStore?.fileCount)
541
+ ? codexCursorStore.fileCount
542
+ : Object.keys(cursors?.files || {}).length;
510
543
  syncDiagnostics.cold_skipped = 0;
511
544
  syncDiagnostics.parse_candidates = discoveredRollouts;
512
545
  }
513
- if (auditDue || !cursors?.files || typeof cursors.files !== "object") {
546
+ if (
547
+ !codexCursorStore &&
548
+ (auditDue || !cursors?.files || typeof cursors.files !== "object")
549
+ ) {
514
550
  return { rolloutFiles: files, skipped: 0 };
515
551
  }
516
552
 
517
553
  const activeDates = activeCodexRolloutDates(files, { nowMs, recentDays });
518
554
  const freshnessCache = new Map();
555
+ const cursorLoadDirectories = new Set();
556
+ const coldDaySkipDecisions = new Map();
519
557
  const out = [];
520
558
  let skipped = 0;
559
+ let cursorStoreRestarted = false;
560
+
561
+ const loadCodexCursorDirectory = async (filePath) => {
562
+ if (!codexCursorStore) return;
563
+ const directory = path.dirname(filePath);
564
+ if (cursorLoadDirectories.has(directory)) return;
565
+ cursorLoadDirectories.add(directory);
566
+ const result = await codexCursorStore.loadCodexFilesForPaths([filePath], cursors);
567
+ if (result?.restarted) cursorStoreRestarted = true;
568
+ };
569
+
570
+ const canSkipCodexDirectory = async (filePath) => {
571
+ if (!codexCursorStore) return false;
572
+ const directory = path.dirname(filePath);
573
+ if (coldDaySkipDecisions.has(directory)) {
574
+ return coldDaySkipDecisions.get(directory);
575
+ }
576
+ const decision = await codexCursorStore.canSkipCodexDay({
577
+ filePath,
578
+ dayInventoryCache: cursors?.codexDayInventoryCache,
579
+ nowMs,
580
+ });
581
+ coldDaySkipDecisions.set(directory, decision);
582
+ return decision;
583
+ };
521
584
 
522
585
  for (const entry of files) {
523
586
  const filePath = typeof entry === "string" ? entry : entry?.path;
@@ -532,10 +595,27 @@ async function filterColdCodexRolloutFiles({
532
595
 
533
596
  const rolloutDate = rolloutDateFromPath(filePath);
534
597
  if (!rolloutDate || activeDates.has(rolloutDate)) {
598
+ await loadCodexCursorDirectory(filePath);
599
+ if (cursorStoreRestarted) break;
535
600
  out.push(entry);
536
601
  continue;
537
602
  }
538
603
 
604
+ if (auditDue) {
605
+ await loadCodexCursorDirectory(filePath);
606
+ if (cursorStoreRestarted) break;
607
+ out.push(entry);
608
+ continue;
609
+ }
610
+
611
+ if (await canSkipCodexDirectory(filePath)) {
612
+ skipped += 1;
613
+ continue;
614
+ }
615
+
616
+ await loadCodexCursorDirectory(filePath);
617
+ if (cursorStoreRestarted) break;
618
+
539
619
  const prev = cursors.files[filePath];
540
620
  const cachedSize = Number(prev?.offset);
541
621
  if (!Number.isFinite(cachedSize) || cachedSize <= 0) {
@@ -563,6 +643,18 @@ async function filterColdCodexRolloutFiles({
563
643
  skipped += 1;
564
644
  }
565
645
 
646
+ if (cursorStoreRestarted) {
647
+ await codexCursorStore.loadCodexFilesForPaths(files, cursors);
648
+ if (syncDiagnostics) {
649
+ syncDiagnostics.cold_skipped = 0;
650
+ syncDiagnostics.parse_candidates = files.reduce(
651
+ (count, entry) => count + (isCodexEntry(entry) ? 1 : 0),
652
+ 0,
653
+ );
654
+ }
655
+ return { rolloutFiles: files, skipped: 0, restarted: true };
656
+ }
657
+
566
658
  if (syncDiagnostics) {
567
659
  syncDiagnostics.cold_skipped = skipped;
568
660
  syncDiagnostics.parse_candidates = out.reduce(
@@ -570,7 +662,7 @@ async function filterColdCodexRolloutFiles({
570
662
  0,
571
663
  );
572
664
  }
573
- return { rolloutFiles: out, skipped };
665
+ return { rolloutFiles: out, skipped, restarted: false };
574
666
  }
575
667
 
576
668
  function activeCodexRolloutDates(