tokentracker-cli 0.90.2 → 0.91.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 (105) hide show
  1. package/README.de.md +5 -4
  2. package/README.ja.md +4 -3
  3. package/README.ko.md +4 -3
  4. package/README.md +5 -4
  5. package/README.zh-CN.md +4 -3
  6. package/dashboard/dist/assets/{AchievementBadge-BJl0ibLg.js → AchievementBadge-iyRg0rYF.js} +1 -1
  7. package/dashboard/dist/assets/{AchievementsPage-CV6aNe3g.js → AchievementsPage-CkBm3bN3.js} +2 -2
  8. package/dashboard/dist/assets/{AchievementsSection-DxLHu9EV.js → AchievementsSection-a4Z7VtlP.js} +1 -1
  9. package/dashboard/dist/assets/{BadgeDetailModal-ConoHhIL.js → BadgeDetailModal-DHTN0Ky6.js} +1 -1
  10. package/dashboard/dist/assets/{Card-C_VQxG6G.js → Card-CdygGEqz.js} +1 -1
  11. package/dashboard/dist/assets/{ClawdAnimated-_Mfn4MnU.js → ClawdAnimated-D-Z823Nc.js} +1 -1
  12. package/dashboard/dist/assets/{CommandPalette-CCRCnYY9.js → CommandPalette-VGkj8w2X.js} +1 -1
  13. package/dashboard/dist/assets/{CommunityStatsModal-DuICwpdM.js → CommunityStatsModal-BDT4xqfF.js} +1 -1
  14. package/dashboard/dist/assets/{ConfirmModal-CI27robt.js → ConfirmModal-BIKv4AlL.js} +1 -1
  15. package/dashboard/dist/assets/{Controls-Cwu0gtgj.js → Controls-BkZVm9t1.js} +1 -1
  16. package/dashboard/dist/assets/{DashboardPage-GsFvPie1.js → DashboardPage-BFkdjUdd.js} +1 -1
  17. package/dashboard/dist/assets/{DevicePage-BSK76UQE.js → DevicePage-BGw861bu.js} +1 -1
  18. package/dashboard/dist/assets/{DialogClose-BXQlPs02.js → DialogClose-CSEl6ru8.js} +1 -1
  19. package/dashboard/dist/assets/DialogDescription-DfNXnqay.js +1 -0
  20. package/dashboard/dist/assets/{DialogTitle-DyvhHV1-.js → DialogTitle-CWPdu5V-.js} +1 -1
  21. package/dashboard/dist/assets/{FadeIn-DaP6F4f8.js → FadeIn-CdCANtvs.js} +1 -1
  22. package/dashboard/dist/assets/{HeaderGithubStar-CKB5puCd.js → HeaderGithubStar-dQQnH85f.js} +1 -1
  23. package/dashboard/dist/assets/{HoverTooltip-BG6k61dF.js → HoverTooltip-CqJUI-WG.js} +1 -1
  24. package/dashboard/dist/assets/{IpCheckPage-Oqt1J9S2.js → IpCheckPage-BRqTXlSu.js} +1 -1
  25. package/dashboard/dist/assets/{LandingPage-45qoUn79.js → LandingPage-DhMTgDng.js} +2 -2
  26. package/dashboard/dist/assets/{LeaderboardAvatar-ZgXnaI_N.js → LeaderboardAvatar-BrGcByG1.js} +1 -1
  27. package/dashboard/dist/assets/{LeaderboardPage-C7E_LrFk.js → LeaderboardPage-BmdopPjo.js} +2 -2
  28. package/dashboard/dist/assets/{LeaderboardProfileModal-D6PUcj3b.js → LeaderboardProfileModal-DRZqPo-A.js} +3 -3
  29. package/dashboard/dist/assets/{LeaderboardProfilePage-VcC9DK_B.js → LeaderboardProfilePage-CTbC39KX.js} +1 -1
  30. package/dashboard/dist/assets/{LimitsPage-B9K0RFQD.js → LimitsPage-B7AuLq1S.js} +1 -1
  31. package/dashboard/dist/assets/{LocalOnlyNotice-BGsfKEM9.js → LocalOnlyNotice-DyIAspoq.js} +1 -1
  32. package/dashboard/dist/assets/{LoginCard-j5HVFRdP.js → LoginCard-LcOaKaCK.js} +1 -1
  33. package/dashboard/dist/assets/{LoginModal-N3pWGciC.js → LoginModal-D3bmr_jI.js} +1 -1
  34. package/dashboard/dist/assets/{LoginPage-TGgL0aXF.js → LoginPage-D7SgmEhZ.js} +1 -1
  35. package/dashboard/dist/assets/{PetPage-DPi7OT_4.js → PetPage-5A3Q0zlw.js} +1 -1
  36. package/dashboard/dist/assets/{PopoverPopup-BkptZaPd.js → PopoverPopup-ajEhdI8m.js} +1 -1
  37. package/dashboard/dist/assets/{ProviderIcon-zaz4nwxI.js → ProviderIcon-C4yuu9FG.js} +1 -1
  38. package/dashboard/dist/assets/{ResetPasswordPage-DQ4qdjBD.js → ResetPasswordPage-Bwbt8tH2.js} +1 -1
  39. package/dashboard/dist/assets/{SegmentedControl-CuTrxHXS.js → SegmentedControl-BSa5hMnN.js} +1 -1
  40. package/dashboard/dist/assets/{Select-_Txi2j1D.js → Select-kPKDGb7M.js} +1 -1
  41. package/dashboard/dist/assets/{SelectItemText-DVKhj-YN.js → SelectItemText-DNgLclTV.js} +1 -1
  42. package/dashboard/dist/assets/{ServiceStatusPage-ChflNSK0.js → ServiceStatusPage-C1j7rPDp.js} +1 -1
  43. package/dashboard/dist/assets/{SessionsPage-CHv6xK2J.js → SessionsPage-BgoKs_Yq.js} +1 -1
  44. package/dashboard/dist/assets/{SettingsPage-DkWAYALG.js → SettingsPage-BUaPftV0.js} +2 -2
  45. package/dashboard/dist/assets/{SkillsPage-DnTSlBl-.js → SkillsPage-C5GkzfWW.js} +1 -1
  46. package/dashboard/dist/assets/{TokenGalaxy-yAMCaU-k.js → TokenGalaxy-DZffAa_0.js} +1 -1
  47. package/dashboard/dist/assets/{ToolbarRootContext-BeDIqB0k.js → ToolbarRootContext-CuLP92P_.js} +1 -1
  48. package/dashboard/dist/assets/{TrendMonitor-BthLuYwy.js → TrendMonitor-BKLAKJmT.js} +1 -1
  49. package/dashboard/dist/assets/{WidgetsPage-y_qKZ9Gv.js → WidgetsPage-BUhiCpcq.js} +1 -1
  50. package/dashboard/dist/assets/{WrappedPage-BGUGI6vk.js → WrappedPage-sNFISXVG.js} +1 -1
  51. package/dashboard/dist/assets/{__vite-browser-external-CRvi_9hb.js → __vite-browser-external-Cyw7ZNtj.js} +2 -2
  52. package/dashboard/dist/assets/{agent-logos-DwHwn_cb.js → agent-logos-Bwf2YFHS.js} +1 -1
  53. package/dashboard/dist/assets/{arrow-up-right-CjEesyJI.js → arrow-up-right-BcRkt7hr.js} +1 -1
  54. package/dashboard/dist/assets/{check-KDrH1gwE.js → check-qhr4U2S5.js} +1 -1
  55. package/dashboard/dist/assets/{chevron-right-DseqFm-D.js → chevron-right-iLGEAP7_.js} +1 -1
  56. package/dashboard/dist/assets/{copy-CFJ1QKAQ.js → copy-BhEPCq-q.js} +1 -1
  57. package/dashboard/dist/assets/{download-BQUNGUdh.js → download-D7O1ZzsX.js} +1 -1
  58. package/dashboard/dist/assets/{external-link-BCEOLLH2.js → external-link-CY2kK2hC.js} +1 -1
  59. package/dashboard/dist/assets/{flame-BigtoGg2.js → flame-D4FPuBNn.js} +1 -1
  60. package/dashboard/dist/assets/{format-tokens-CS1GUpAV.js → format-tokens-CVHJ7Hdh.js} +1 -1
  61. package/dashboard/dist/assets/{icons-DpZ1a8Ct.js → icons-B_-51UXa.js} +1 -1
  62. package/dashboard/dist/assets/{index-DFU_yVc5.js → index-ClVWat-1.js} +1 -1
  63. package/dashboard/dist/assets/{index-lGAAw1Rv.js → index-Djv-aJy0.js} +1 -1
  64. package/dashboard/dist/assets/{index-DqkwD6eO.js → index-cwdr25Zm.js} +1 -1
  65. package/dashboard/dist/assets/{info-Br_jtGtO.js → info-DOab0eZz.js} +1 -1
  66. package/dashboard/dist/assets/{limits-providers-CkqO1LMQ.js → limits-providers-CESm2d6B.js} +1 -1
  67. package/dashboard/dist/assets/{link-2-D-nAhkk-.js → link-2-B4LMsC4m.js} +1 -1
  68. package/dashboard/dist/assets/{loader-circle-CuNPuDRR.js → loader-circle-CPx6wpSn.js} +1 -1
  69. package/dashboard/dist/assets/{maximize-2-dlvwitfg.js → maximize-2-C9z8mbdn.js} +1 -1
  70. package/dashboard/dist/assets/{modifiers.esm-ORha_lPI.js → modifiers.esm-5xRgAl_R.js} +1 -1
  71. package/dashboard/dist/assets/{monitor-smartphone-CI2qvlMB.js → monitor-smartphone-B9HAspdR.js} +1 -1
  72. package/dashboard/dist/assets/{provider-display-BNCdZ83n.js → provider-display-C0NS0EvN.js} +2 -2
  73. package/dashboard/dist/assets/{react-Dy9iWvqT.js → react-C45OGvDd.js} +1 -1
  74. package/dashboard/dist/assets/{search-Do7tzc3k.js → search-Bg1qyEdz.js} +1 -1
  75. package/dashboard/dist/assets/{skills-api-CJ-8EFac.js → skills-api-a8pi7UTd.js} +1 -1
  76. package/dashboard/dist/assets/{sortable.esm-BKQg8NHC.js → sortable.esm-CtPp8cFA.js} +1 -1
  77. package/dashboard/dist/assets/{store-SUT-n3k3.js → store-b8zXM1yr.js} +1 -1
  78. package/dashboard/dist/assets/{terminal-BX4DOxd6.js → terminal-CPf0K0Fn.js} +1 -1
  79. package/dashboard/dist/assets/{trash-2-VERlG247.js → trash-2-uorzBdA0.js} +1 -1
  80. package/dashboard/dist/assets/{use-community-stats-BX6_XUdu.js → use-community-stats-DaVwywsM.js} +1 -1
  81. package/dashboard/dist/assets/{use-limits-display-prefs-BpC3tYRw.js → use-limits-display-prefs-UIzz7PJ3.js} +1 -1
  82. package/dashboard/dist/assets/{use-ordered-list-CX-LREPo.js → use-ordered-list-C2XOfMH3.js} +1 -1
  83. package/dashboard/dist/assets/use-reduced-motion-CNyMWBog.js +1 -0
  84. package/dashboard/dist/assets/{use-session-efficiency-pref-B1G8hzVM.js → use-session-efficiency-pref-D5KHakYg.js} +1 -1
  85. package/dashboard/dist/assets/{use-transform-DNCqLbUD.js → use-transform-Cfo_2_id.js} +1 -1
  86. package/dashboard/dist/assets/{use-usage-limits-Cvbvf30m.js → use-usage-limits-CANTpxrA.js} +1 -1
  87. package/dashboard/dist/assets/{useCurrency-EciQmJkm.js → useCurrency-CjvWekKH.js} +1 -1
  88. package/dashboard/dist/assets/{useScrollLock-sLkmam8C.js → useScrollLock-ChQdbuJg.js} +1 -1
  89. package/dashboard/dist/assets/{useTokenFormat-nb9na-2-.js → useTokenFormat-4MY04JPl.js} +1 -1
  90. package/dashboard/dist/assets/{zap-BQOWCMov.js → zap-BSXHFUBb.js} +1 -1
  91. package/dashboard/dist/index.html +26 -24
  92. package/dashboard/dist/ip-check.html +1 -1
  93. package/dashboard/dist/leaderboard.html +1 -1
  94. package/dashboard/dist/llms.txt +3 -2
  95. package/dashboard/dist/share.html +1 -1
  96. package/package.json +2 -2
  97. package/src/commands/init.js +10 -0
  98. package/src/commands/status.js +13 -0
  99. package/src/commands/sync.js +32 -0
  100. package/src/lib/pricing/index.js +6 -1
  101. package/src/lib/pricing/matcher.js +1 -0
  102. package/src/lib/pricing/seed-snapshot.json +1 -1
  103. package/src/lib/rollout.js +123 -13
  104. package/dashboard/dist/assets/DialogDescription-M_lg2jhD.js +0 -1
  105. package/dashboard/dist/assets/use-reduced-motion-DbebVWBw.js +0 -1
@@ -12397,6 +12397,57 @@ function resolvePiDefaultModel() {
12397
12397
  return "pi-unknown";
12398
12398
  }
12399
12399
 
12400
+ // Prime Agent (PrimeIntellect-ai/prime-agent) persists the same metadata-only
12401
+ // assistant usage envelope as pi, but uses a flat sessions directory:
12402
+ // ~/.prime/agent/sessions/<session-id>.jsonl
12403
+ // Keep its path and cursor namespace independent from pi so installations of
12404
+ // both tools can never suppress or double-count each other.
12405
+ function resolvePrimeAgentHome(env = process.env) {
12406
+ if (env.TOKENTRACKER_PRIME_AGENT_HOME) {
12407
+ return expandHomePath(env.TOKENTRACKER_PRIME_AGENT_HOME, env);
12408
+ }
12409
+ const home = env.HOME || require("node:os").homedir();
12410
+ if (process.platform === "win32") {
12411
+ return pickWin32ProviderPath({
12412
+ env,
12413
+ nativeValue: path.join(home, ".prime"),
12414
+ wslProviderDir: ".prime",
12415
+ });
12416
+ }
12417
+ return path.join(home, ".prime");
12418
+ }
12419
+
12420
+ function resolvePrimeAgentDir(env = process.env) {
12421
+ if (env.TOKENTRACKER_PRIME_AGENT_DIR) {
12422
+ return expandHomePath(env.TOKENTRACKER_PRIME_AGENT_DIR, env);
12423
+ }
12424
+ const primeHome = resolvePrimeAgentHome(env);
12425
+ return primeHome ? path.join(primeHome, "agent") : null;
12426
+ }
12427
+
12428
+ function resolvePrimeAgentSessionFiles(env = process.env) {
12429
+ const agentDir = resolvePrimeAgentDir(env);
12430
+ if (!agentDir) return [];
12431
+ const sessionsDir = path.join(agentDir, "sessions");
12432
+ if (!fssync.existsSync(sessionsDir)) return [];
12433
+ const files = [];
12434
+ const walk = (dir) => {
12435
+ let entries;
12436
+ try { entries = fssync.readdirSync(dir, { withFileTypes: true }); } catch { return; }
12437
+ for (const entry of entries) {
12438
+ const full = path.join(dir, entry.name);
12439
+ if (entry.isDirectory()) walk(full);
12440
+ else if (entry.isFile() && entry.name.endsWith(".jsonl")) files.push(full);
12441
+ }
12442
+ };
12443
+ walk(sessionsDir);
12444
+ return files.sort((a, b) => a.localeCompare(b));
12445
+ }
12446
+
12447
+ function resolvePrimeAgentDefaultModel() {
12448
+ return "prime-agent-unknown";
12449
+ }
12450
+
12400
12451
  // Pi is a router: the same session can send turns to Anthropic, GitHub
12401
12452
  // Copilot, or another backend. Keep provider names in the queue source so
12402
12453
  // those turns cannot collapse into one bucket (or inherit the wrong pricing).
@@ -12413,30 +12464,47 @@ function piSourceForProvider(provider) {
12413
12464
  return slug ? `pi-${slug}` : "pi";
12414
12465
  }
12415
12466
 
12416
- async function parsePiIncremental({
12467
+ function primeAgentSourceForProvider(provider) {
12468
+ if (typeof provider !== "string" || !provider.trim()) return "prime-agent";
12469
+ const slug = provider
12470
+ .trim()
12471
+ .toLowerCase()
12472
+ .replace(/[^a-z0-9]+/g, "-")
12473
+ .replace(/^-+|-+$/g, "")
12474
+ .slice(0, 64);
12475
+ return slug ? `prime-agent-${slug}` : "prime-agent";
12476
+ }
12477
+
12478
+ async function parsePiLikeIncremental({
12417
12479
  sessionFiles,
12418
12480
  cursors,
12419
12481
  queuePath,
12420
12482
  onProgress,
12421
12483
  env,
12422
12484
  defaultModel,
12485
+ stateKey,
12486
+ resolveSessionFiles,
12487
+ resolveDefaultModel,
12488
+ sourceForProvider,
12423
12489
  } = {}) {
12424
12490
  await ensureDir(path.dirname(queuePath));
12425
- const piState = cursors.pi && typeof cursors.pi === "object" ? cursors.pi : {};
12426
- const seenIds = new Set(Array.isArray(piState.seenIds) ? piState.seenIds : []);
12491
+ const providerState = cursors[stateKey] && typeof cursors[stateKey] === "object"
12492
+ ? cursors[stateKey]
12493
+ : {};
12494
+ const seenIds = new Set(Array.isArray(providerState.seenIds) ? providerState.seenIds : []);
12427
12495
  const fileOffsets =
12428
- piState.fileOffsets && typeof piState.fileOffsets === "object"
12429
- ? { ...piState.fileOffsets }
12496
+ providerState.fileOffsets && typeof providerState.fileOffsets === "object"
12497
+ ? { ...providerState.fileOffsets }
12430
12498
  : {};
12431
12499
 
12432
12500
  const files = Array.isArray(sessionFiles)
12433
12501
  ? sessionFiles
12434
- : resolvePiSessionFiles(env || process.env);
12435
- const fallbackModel = defaultModel || resolvePiDefaultModel();
12502
+ : resolveSessionFiles(env || process.env);
12503
+ const fallbackModel = defaultModel || resolveDefaultModel();
12436
12504
 
12437
12505
  if (files.length === 0) {
12438
- cursors.pi = {
12439
- ...piState,
12506
+ cursors[stateKey] = {
12507
+ ...providerState,
12440
12508
  seenIds: Array.from(seenIds),
12441
12509
  fileOffsets,
12442
12510
  updatedAt: new Date().toISOString(),
@@ -12463,12 +12531,29 @@ async function parsePiIncremental({
12463
12531
  if (stat.size <= startOffset) continue;
12464
12532
 
12465
12533
  let stream;
12534
+ let streamedBytes = 0;
12535
+ let lastCompleteOffset = startOffset;
12466
12536
  try {
12467
12537
  stream = fssync.createReadStream(filePath, {
12468
12538
  encoding: "utf8",
12469
12539
  start: startOffset,
12470
12540
  });
12471
12541
  } catch { continue; }
12542
+ // readline emits an unterminated final fragment as if it were a line. If
12543
+ // the producer is still writing that JSON object, parsing fails; advancing
12544
+ // to stat.size here would then lose the completed record forever. Track the
12545
+ // last physical newline and commit only through that byte boundary.
12546
+ stream.on("data", (chunk) => {
12547
+ let searchFrom = 0;
12548
+ let newlineIndex;
12549
+ while ((newlineIndex = chunk.indexOf("\n", searchFrom)) !== -1) {
12550
+ lastCompleteOffset = startOffset
12551
+ + streamedBytes
12552
+ + Buffer.byteLength(chunk.slice(0, newlineIndex + 1), "utf8");
12553
+ searchFrom = newlineIndex + 1;
12554
+ }
12555
+ streamedBytes += Buffer.byteLength(chunk, "utf8");
12556
+ });
12472
12557
  const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
12473
12558
 
12474
12559
  for await (const line of rl) {
@@ -12529,7 +12614,7 @@ async function parsePiIncremental({
12529
12614
  : input + output + cacheRead + cacheWrite + reasoningTokens;
12530
12615
 
12531
12616
  const model = normalizeModelInput(msg.model) || fallbackModel;
12532
- const source = piSourceForProvider(msg.provider);
12617
+ const source = sourceForProvider(msg.provider);
12533
12618
 
12534
12619
  const delta = {
12535
12620
  input_tokens: input,
@@ -12561,7 +12646,7 @@ async function parsePiIncremental({
12561
12646
  let postStat = stat;
12562
12647
  try { postStat = fssync.statSync(filePath); } catch {}
12563
12648
  fileOffsets[filePath] = {
12564
- size: postStat.size,
12649
+ size: Math.min(lastCompleteOffset, postStat.size),
12565
12650
  mtimeMs: postStat.mtimeMs,
12566
12651
  ino: postStat.ino,
12567
12652
  };
@@ -12579,8 +12664,8 @@ async function parsePiIncremental({
12579
12664
  const updatedAt = new Date().toISOString();
12580
12665
  hourlyState.updatedAt = updatedAt;
12581
12666
  cursors.hourly = hourlyState;
12582
- cursors.pi = {
12583
- ...piState,
12667
+ cursors[stateKey] = {
12668
+ ...providerState,
12584
12669
  seenIds: cappedSeen,
12585
12670
  fileOffsets,
12586
12671
  updatedAt,
@@ -12589,6 +12674,26 @@ async function parsePiIncremental({
12589
12674
  return { recordsProcessed, eventsAggregated, bucketsQueued };
12590
12675
  }
12591
12676
 
12677
+ async function parsePiIncremental(options = {}) {
12678
+ return parsePiLikeIncremental({
12679
+ ...options,
12680
+ stateKey: "pi",
12681
+ resolveSessionFiles: resolvePiSessionFiles,
12682
+ resolveDefaultModel: resolvePiDefaultModel,
12683
+ sourceForProvider: piSourceForProvider,
12684
+ });
12685
+ }
12686
+
12687
+ async function parsePrimeAgentIncremental(options = {}) {
12688
+ return parsePiLikeIncremental({
12689
+ ...options,
12690
+ stateKey: "primeAgent",
12691
+ resolveSessionFiles: resolvePrimeAgentSessionFiles,
12692
+ resolveDefaultModel: resolvePrimeAgentDefaultModel,
12693
+ sourceForProvider: primeAgentSourceForProvider,
12694
+ });
12695
+ }
12696
+
12592
12697
  // ─────────────────────────────────────────────────────────────────────────────
12593
12698
  // Craft Agents (lukilabs/craft-agents-oss) — passive JSONL reader
12594
12699
  //
@@ -17182,6 +17287,11 @@ module.exports = {
17182
17287
  resolvePiDefaultModel,
17183
17288
  parsePiIncremental,
17184
17289
  piAgentDirCollidesWithOmp,
17290
+ resolvePrimeAgentHome,
17291
+ resolvePrimeAgentDir,
17292
+ resolvePrimeAgentSessionFiles,
17293
+ resolvePrimeAgentDefaultModel,
17294
+ parsePrimeAgentIncremental,
17185
17295
  resolveCraftConfigDir,
17186
17296
  resolveCraftWorkspaceRoots,
17187
17297
  resolveCraftSessionFiles,
@@ -1 +0,0 @@
1
- import{r as n,z as a}from"./__vite-browser-external-CRvi_9hb.js";import{u as p}from"./DialogTitle-DyvhHV1-.js";import{u as c}from"./useScrollLock-sLkmam8C.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-CRvi_9hb.js";import{h as r,i as t,p as s}from"./react-Dy9iWvqT.js";function i(){!r.current&&t();const[e]=o.useState(s.current);return e}export{i as u};