tokentracker-cli 1.4.1 → 1.4.2
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.
- package/README.de.md +5 -4
- package/README.ja.md +5 -4
- package/README.ko.md +5 -4
- package/README.md +5 -4
- package/README.zh-CN.md +5 -4
- package/dashboard/dist/assets/{AchievementBadge-DWECUOAX.js → AchievementBadge-WGbdoboF.js} +1 -1
- package/dashboard/dist/assets/{AchievementsPage-Bakfwwn_.js → AchievementsPage-BvybbsXv.js} +2 -2
- package/dashboard/dist/assets/{AchievementsSection-DiEX2_5U.js → AchievementsSection-ChNzTFSR.js} +1 -1
- package/dashboard/dist/assets/{BadgeDetailModal-ClVMnxVW.js → BadgeDetailModal-DhI9Ejz3.js} +1 -1
- package/dashboard/dist/assets/{BotAnimated-D7eyrAPs.js → BotAnimated-Bch0Yxej.js} +1 -1
- package/dashboard/dist/assets/{Card-CsAQxZZ8.js → Card-DWdL7d1T.js} +1 -1
- package/dashboard/dist/assets/{CloudCheckoutPage-BAN-DtXB.js → CloudCheckoutPage-BjGoOz6P.js} +1 -1
- package/dashboard/dist/assets/{CloudPage-D9sNlUAy.js → CloudPage-Btb6a97x.js} +2 -2
- package/dashboard/dist/assets/{CommandPalette-D9TNT6un.js → CommandPalette-DwP3k7LE.js} +1 -1
- package/dashboard/dist/assets/{CommunityStatsModal-CotRRQNH.js → CommunityStatsModal-mzqLxpwE.js} +1 -1
- package/dashboard/dist/assets/{ConfirmModal-C_il5anp.js → ConfirmModal-Dm76q4EX.js} +1 -1
- package/dashboard/dist/assets/{Controls-Bd1kODP4.js → Controls-ClZjOBoD.js} +1 -1
- package/dashboard/dist/assets/{DashboardPage-De0EL8Hn.js → DashboardPage-Doc8f4NL.js} +1 -1
- package/dashboard/dist/assets/{DateRangePopover-quw6hpxy.js → DateRangePopover-vfTUePPg.js} +1 -1
- package/dashboard/dist/assets/{DevicePage-CP20lVYv.js → DevicePage-Jjg5q0C2.js} +1 -1
- package/dashboard/dist/assets/{DialogClose-BEUL9bD6.js → DialogClose-Ci5mPZ6X.js} +1 -1
- package/dashboard/dist/assets/DialogDescription-Di5ev5K6.js +1 -0
- package/dashboard/dist/assets/{DialogTitle-C--sXGjf.js → DialogTitle-DI21oZxH.js} +1 -1
- package/dashboard/dist/assets/{ElectricLogo-DhP7S1Cu.js → ElectricLogo-DfeZBwPZ.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-BPH15_jE.js → FadeIn-C7SIILTc.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-DziE8s6w.js → HeaderGithubStar-RStLbadn.js} +1 -1
- package/dashboard/dist/assets/{HoverTooltip-tQyY2CuV.js → HoverTooltip-DI7uAp1_.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-BjoB05O7.js → IpCheckPage-DTZNTJVh.js} +1 -1
- package/dashboard/dist/assets/{LandingPage-Cav49COr.js → LandingPage-Df5scNlw.js} +2 -2
- package/dashboard/dist/assets/{LeaderboardPage-CHjFKLvs.js → LeaderboardPage-Ck3SqtnI.js} +2 -2
- package/dashboard/dist/assets/{LeaderboardProBadge-D97MfK5W.js → LeaderboardProBadge-CGx6m7R6.js} +1 -1
- package/dashboard/dist/assets/{LeaderboardProfileModal-NNTwtWSu.js → LeaderboardProfileModal-DuP7rgfv.js} +3 -3
- package/dashboard/dist/assets/{LeaderboardProfilePage-xI81GH3D.js → LeaderboardProfilePage-B5qUJkZX.js} +1 -1
- package/dashboard/dist/assets/{LimitsPage-BPOo3FOW.js → LimitsPage-Bv_Lcvcz.js} +1 -1
- package/dashboard/dist/assets/{LocalOnlyNotice-j8Tijts2.js → LocalOnlyNotice-Cg4y02JM.js} +1 -1
- package/dashboard/dist/assets/{LoginCard-C7_n6J7k.js → LoginCard-Wz0uJKXx.js} +1 -1
- package/dashboard/dist/assets/{LoginModal-DwlNscw5.js → LoginModal-C13v_Gs0.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-BqhWatt2.js → LoginPage-COH9xXtd.js} +1 -1
- package/dashboard/dist/assets/{PetPage-CJlC0V0i.js → PetPage-BWCnURub.js} +2 -2
- package/dashboard/dist/assets/{PopoverPopup-wleZ4DTI.js → PopoverPopup-Dw811N-_.js} +1 -1
- package/dashboard/dist/assets/{ProviderIcon-biLVsOGr.js → ProviderIcon-CHxhYzK-.js} +1 -1
- package/dashboard/dist/assets/{ResetPasswordPage-5Sl45OsN.js → ResetPasswordPage-Ll6jshqg.js} +1 -1
- package/dashboard/dist/assets/{Select-77l2QNqa.js → Select-BbooQ3sa.js} +1 -1
- package/dashboard/dist/assets/{SelectItemText-BQbmtjd3.js → SelectItemText-DBiW70wi.js} +1 -1
- package/dashboard/dist/assets/{SelfHostPage-C8hlgVu4.js → SelfHostPage-BMHJxz5q.js} +1 -1
- package/dashboard/dist/assets/{ServiceStatusPage-DrY9Mef8.js → ServiceStatusPage-D6LH0ac-.js} +1 -1
- package/dashboard/dist/assets/{SessionsPage-BDTsH3Mk.js → SessionsPage-Mrer6v17.js} +1 -1
- package/dashboard/dist/assets/{SettingsPage-C_id9Go3.js → SettingsPage-D_7P_y_l.js} +3 -3
- package/dashboard/dist/assets/{SkillsPage-kb6_5uUk.js → SkillsPage-Ka7xm-1v.js} +1 -1
- package/dashboard/dist/assets/{TokenGalaxy-BoS0yUFS.js → TokenGalaxy-BEURDPFq.js} +1 -1
- package/dashboard/dist/assets/{TooltipPopup-LV1aWIRZ.js → TooltipPopup-ZiuFFARC.js} +1 -1
- package/dashboard/dist/assets/{TrendMonitor-DN-nwcSA.js → TrendMonitor-H73lyGEf.js} +1 -1
- package/dashboard/dist/assets/{WidgetsPage-C6lvwceS.js → WidgetsPage-_7iCvyTk.js} +1 -1
- package/dashboard/dist/assets/{WrappedPage-CfC39wWP.js → WrappedPage-DEXNb6-k.js} +1 -1
- package/dashboard/dist/assets/{__vite-browser-external-DpZbUcLL.js → __vite-browser-external-BkNP5Ecj.js} +2 -2
- package/dashboard/dist/assets/{agent-logos-CvcdCGj5.js → agent-logos-OVBc_0cF.js} +1 -1
- package/dashboard/dist/assets/{arrow-left-BX4LX5TF.js → arrow-left-DDphsclm.js} +1 -1
- package/dashboard/dist/assets/{arrow-right-Aktjo2RL.js → arrow-right-B1aNq0Ki.js} +1 -1
- package/dashboard/dist/assets/{arrow-up-right-kkQt6Du0.js → arrow-up-right-yTM9azz_.js} +1 -1
- package/dashboard/dist/assets/{calendar-days-OvLTNZBH.js → calendar-days-D22ithNF.js} +1 -1
- package/dashboard/dist/assets/{check-v5Ie379p.js → check-Dk7tknvE.js} +1 -1
- package/dashboard/dist/assets/{chevron-down-CPlz1cYW.js → chevron-down-DdyEzQ4f.js} +1 -1
- package/dashboard/dist/assets/{cloud-checkout-C_Rhiwno.js → cloud-checkout-BJjbipnH.js} +1 -1
- package/dashboard/dist/assets/{composite-DD_boZdD.js → composite-DEqP00XV.js} +1 -1
- package/dashboard/dist/assets/{download-NqHXZ-zn.js → download-C9ixNyzn.js} +1 -1
- package/dashboard/dist/assets/{external-link-B0D03J0f.js → external-link-DL4HSsLw.js} +1 -1
- package/dashboard/dist/assets/{flame-av87we58.js → flame-DqNH65nB.js} +1 -1
- package/dashboard/dist/assets/{format-tokens-B43Ehkbb.js → format-tokens-CyVjKz4I.js} +1 -1
- package/dashboard/dist/assets/{gift-CZus7M21.js → gift-ChJQQe_G.js} +1 -1
- package/dashboard/dist/assets/{host-mode-Dd9fzAdq.js → host-mode-DpUDpoOz.js} +1 -1
- package/dashboard/dist/assets/{icons-CnScwnf_.js → icons-CJiHeOaU.js} +1 -1
- package/dashboard/dist/assets/{index-Cj9NdXOj.js → index-72LQsAaf.js} +1 -1
- package/dashboard/dist/assets/{index-BZTIoCof.js → index-BucEg3fu.js} +1 -1
- package/dashboard/dist/assets/{index-D3XPaYEL.js → index-CrFlTSra.js} +1 -1
- package/dashboard/dist/assets/{info-BUmCmjwd.js → info-DReYqxC7.js} +1 -1
- package/dashboard/dist/assets/{link-2-t-wSLB2a.js → link-2-kIZbhK2S.js} +1 -1
- package/dashboard/dist/assets/{loader-circle-DM-FdXeX.js → loader-circle-1An-X85y.js} +1 -1
- package/dashboard/dist/assets/{modifiers.esm-D5AKZNa7.js → modifiers.esm-FoVheEKT.js} +1 -1
- package/dashboard/dist/assets/{monitor-smartphone-CDHFLZS-.js → monitor-smartphone-Ch6lr_P2.js} +1 -1
- package/dashboard/dist/assets/{play-BIQH--yZ.js → play-CbJ6ZF1K.js} +1 -1
- package/dashboard/dist/assets/{plus-CztG5eum.js → plus-C-5ID3a9.js} +1 -1
- package/dashboard/dist/assets/{provider-display-B2gZ38Oh.js → provider-display-BFzRtoL2.js} +2 -2
- package/dashboard/dist/assets/{react-D1u6HsZx.js → react-D4CR_fLQ.js} +1 -1
- package/dashboard/dist/assets/{safePolygon-ClG4WM06.js → safePolygon-DP21Ibqj.js} +1 -1
- package/dashboard/dist/assets/{search-NNy_fIbJ.js → search-CaznkY7U.js} +1 -1
- package/dashboard/dist/assets/{server-N94HJtJY.js → server-CUOmC6xZ.js} +1 -1
- package/dashboard/dist/assets/{shield-check-BGfaKXG9.js → shield-check-Dr2KBMmA.js} +1 -1
- package/dashboard/dist/assets/{skills-api-CWydQc4G.js → skills-api-BAz_fblS.js} +1 -1
- package/dashboard/dist/assets/{sortable.esm-BF83ljWQ.js → sortable.esm-knEfm5hE.js} +1 -1
- package/dashboard/dist/assets/{store-l5WfCa7P.js → store-CL97jcij.js} +1 -1
- package/dashboard/dist/assets/{terminal-CRBThKUQ.js → terminal-EjFyreWj.js} +1 -1
- package/dashboard/dist/assets/{trash-BXN5tg81.js → trash-ByqaZXkQ.js} +1 -1
- package/dashboard/dist/assets/{use-community-stats-dHketgyF.js → use-community-stats-Bs4RDJZE.js} +1 -1
- package/dashboard/dist/assets/{use-latest-request-guard-CdM1Pn_p.js → use-latest-request-guard-CG3Ir1cP.js} +1 -1
- package/dashboard/dist/assets/{use-limits-display-prefs-dOm4SCFU.js → use-limits-display-prefs-tACgCxeR.js} +1 -1
- package/dashboard/dist/assets/{use-native-settings-GL9uAidm.js → use-native-settings-CWjXyJXi.js} +1 -1
- package/dashboard/dist/assets/{use-ordered-list-Btz_NSiA.js → use-ordered-list-DsuC9JQa.js} +1 -1
- package/dashboard/dist/assets/use-reduced-motion-CwFguzkm.js +1 -0
- package/dashboard/dist/assets/{use-session-efficiency-pref-BPZel3HL.js → use-session-efficiency-pref-NeoJE8BL.js} +1 -1
- package/dashboard/dist/assets/{use-transform-D2xePGbE.js → use-transform-BWGKOsya.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-vEmyPwMY.js → use-usage-limits-CFWFNwHS.js} +1 -1
- package/dashboard/dist/assets/{useCurrency-DnhS0llv.js → useCurrency-B_C4_P5x.js} +1 -1
- package/dashboard/dist/assets/{usePositioner-7yozJJJ0.js → usePositioner-B0L5_o38.js} +1 -1
- package/dashboard/dist/assets/{useTokenFormat-DvjyXv8i.js → useTokenFormat-DH1GWHSU.js} +1 -1
- package/dashboard/dist/assets/{zap-CElRpX2w.js → zap-Chv1p7pS.js} +1 -1
- package/dashboard/dist/index.html +13 -11
- package/dashboard/dist/ip-check.html +1 -1
- package/dashboard/dist/leaderboard.html +1 -1
- package/dashboard/dist/llms.txt +3 -2
- package/dashboard/dist/share.html +1 -1
- package/package.json +2 -2
- package/src/commands/doctor.js +15 -1
- package/src/commands/init.js +9 -0
- package/src/commands/status.js +20 -2
- package/src/commands/sync.js +25 -0
- package/src/lib/cloud-device-token.js +77 -10
- package/src/lib/diagnostics.js +4 -1
- package/src/lib/pricing/index.js +2 -1
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/rollout.js +402 -0
- package/dashboard/dist/assets/DialogDescription-DpkD2qwW.js +0 -1
- package/dashboard/dist/assets/use-reduced-motion-D9n2I_eN.js +0 -1
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
"price": "0",
|
|
123
123
|
"priceCurrency": "USD"
|
|
124
124
|
},
|
|
125
|
-
"description": "Local-first AI coding usage tracker for
|
|
125
|
+
"description": "Local-first AI coding usage tracker for 46 tools, with a desktop pet, four widgets, achievements, native macOS and Windows apps, accurate cross-provider deduplication, and no prompt collection."
|
|
126
126
|
},
|
|
127
127
|
{
|
|
128
128
|
"@type": "WebSite",
|
|
@@ -207,7 +207,8 @@
|
|
|
207
207
|
{ "@type": "ListItem", "position": 42, "name": "Command Code" },
|
|
208
208
|
{ "@type": "ListItem", "position": 43, "name": "TRAE" },
|
|
209
209
|
{ "@type": "ListItem", "position": 44, "name": "WorkBuddy AI" },
|
|
210
|
-
{ "@type": "ListItem", "position": 45, "name": "DuMate" }
|
|
210
|
+
{ "@type": "ListItem", "position": 45, "name": "DuMate" },
|
|
211
|
+
{ "@type": "ListItem", "position": 46, "name": "Muse Code" }
|
|
211
212
|
]
|
|
212
213
|
},
|
|
213
214
|
{
|
|
@@ -226,7 +227,7 @@
|
|
|
226
227
|
"name": "Which AI coding CLIs does Token Tracker support?",
|
|
227
228
|
"acceptedAnswer": {
|
|
228
229
|
"@type": "Answer",
|
|
229
|
-
"text": "Token Tracker supports
|
|
230
|
+
"text": "Token Tracker supports 46 AI coding tools, including Claude Code, Codex CLI, AStudio, Cursor, Gemini CLI, Antigravity, Kiro, OpenCode, OpenClaw, Every Code, Hermes Agent, GitHub Copilot, Kimi Code, CodeBuddy, WorkBuddy, WorkBuddy AI, Grok Build, oh-my-pi, OmO, pi, Dots, Prime Agent, Craft Agents, Reasonix, Muse Code, Kilo CLI, Kilo Code, Roo Code, Zed Agent, Goose, Droid, Mimo Code, DuMate, ZCode, Qoder, AnythingLLM Desktop, Claude Science, DeepSeek Harness, TRAE Work CN, LM Studio, Unsloth Studio, Devin CLI, Cline, MiniMax Code, Command Code, and TRAE."
|
|
230
231
|
}
|
|
231
232
|
},
|
|
232
233
|
{
|
|
@@ -258,7 +259,7 @@
|
|
|
258
259
|
"name": "How do I monitor AI token usage and cost across tools?",
|
|
259
260
|
"acceptedAnswer": {
|
|
260
261
|
"@type": "Answer",
|
|
261
|
-
"text": "Install Token Tracker with npx tokentracker-cli. It is an AI token usage and cost tracker that monitors token consumption and spend across all
|
|
262
|
+
"text": "Install Token Tracker with npx tokentracker-cli. It is an AI token usage and cost tracker that monitors token consumption and spend across all 46 supported tools in one dashboard, with per-model pricing across 2,200+ models so you can see cost by model, project, and time window without manual tracking."
|
|
262
263
|
}
|
|
263
264
|
},
|
|
264
265
|
{
|
|
@@ -274,7 +275,7 @@
|
|
|
274
275
|
]
|
|
275
276
|
}
|
|
276
277
|
</script>
|
|
277
|
-
<script type="module" crossorigin src="/assets/__vite-browser-external-
|
|
278
|
+
<script type="module" crossorigin src="/assets/__vite-browser-external-BkNP5Ecj.js"></script>
|
|
278
279
|
<link rel="stylesheet" crossorigin href="/assets/__vite-browser-external-B0m8a6Te.css">
|
|
279
280
|
</head>
|
|
280
281
|
<body>
|
|
@@ -282,7 +283,7 @@
|
|
|
282
283
|
<h1>Token Tracker: monitor AI token usage and cost with a local dashboard and desktop companion</h1>
|
|
283
284
|
<p>
|
|
284
285
|
Token Tracker is a free, open-source, local-first dashboard that automatically tracks and monitors token usage
|
|
285
|
-
and cost across
|
|
286
|
+
and cost across 46 AI coding tools — including Claude Code, OpenAI Codex, AStudio, Cursor, Gemini CLI, LM Studio, and Unsloth Studio. A desktop pet
|
|
286
287
|
reacts to real token activity, four desktop widgets
|
|
287
288
|
keep usage visible, and achievements turn coding history into progress. Native macOS and Windows apps
|
|
288
289
|
sit on top of accurate cross-provider deduplication. Token counts only — never prompts or conversations.
|
|
@@ -307,7 +308,7 @@
|
|
|
307
308
|
<li><strong>Desktop pet</strong> — a pixel companion that reacts to real token burn, streaks, and rest.</li>
|
|
308
309
|
<li><strong>Four desktop widgets</strong> — usage, activity heatmap, top models, and limits at a glance.</li>
|
|
309
310
|
<li><strong>Achievements</strong> — unlock milestones from local and optional account-wide activity.</li>
|
|
310
|
-
<li><strong>Unified usage dashboard</strong> — input, output, cached, and cache-creation tokens across
|
|
311
|
+
<li><strong>Unified usage dashboard</strong> — input, output, cached, and cache-creation tokens across 46 AI coding tools.</li>
|
|
311
312
|
<li><strong>Cost analysis</strong> — per-model pricing across 2,200+ models with an offline snapshot.</li>
|
|
312
313
|
<li><strong>Usage limits view</strong> — live quota and subscription status for 17 providers, with last-good caching for local providers such as Antigravity and Qoder.</li>
|
|
313
314
|
<li><strong>Service Status page</strong> — live operational and incident status from eight official provider status pages.</li>
|
|
@@ -318,11 +319,11 @@
|
|
|
318
319
|
</ul>
|
|
319
320
|
<p><em>Privacy by design</em>: token counts only, never prompts or conversation content. Local-first; cloud sync is optional and powers only the public leaderboard.</p>
|
|
320
321
|
|
|
321
|
-
<h2>Supported AI coding tools (
|
|
322
|
+
<h2>Supported AI coding tools (46)</h2>
|
|
322
323
|
<p>
|
|
323
324
|
Use Token Tracker as a Claude Code token tracker, Codex token tracker, Cursor token tracker,
|
|
324
325
|
Gemini token tracker, OpenCode token tracker, GitHub Copilot token tracker, or DeepSeek Harness token tracker — one dashboard
|
|
325
|
-
covers all
|
|
326
|
+
covers all 46 tools below.
|
|
326
327
|
</p>
|
|
327
328
|
<ul>
|
|
328
329
|
<li><strong>Claude Code</strong> — Anthropic's official coding agent CLI; integrated via SessionEnd hook.</li>
|
|
@@ -349,6 +350,7 @@
|
|
|
349
350
|
<li><strong>Prime Agent</strong> — metadata-only passive usage reader.</li>
|
|
350
351
|
<li><strong>Craft Agents</strong> — passive session reader.</li>
|
|
351
352
|
<li><strong>Reasonix</strong> — passive telemetry reader.</li>
|
|
353
|
+
<li><strong>Muse Code</strong> — passive session reader.</li>
|
|
352
354
|
<li><strong>Kilo CLI</strong> — passive SQLite reader.</li>
|
|
353
355
|
<li><strong>Kilo Code</strong> — passive editor task reader.</li>
|
|
354
356
|
<li><strong>Roo Code</strong> — passive editor task reader.</li>
|
|
@@ -400,7 +402,7 @@
|
|
|
400
402
|
<p>Run <code>npx tokentracker-cli</code>. The CLI auto-detects your AI coding tools, installs hooks, and opens the dashboard.</p>
|
|
401
403
|
|
|
402
404
|
<h3>Which AI coding tools does Token Tracker support?</h3>
|
|
403
|
-
<p>Token Tracker supports
|
|
405
|
+
<p>Token Tracker supports 46 tools: Claude Code, Codex CLI, AStudio, Cursor, Gemini CLI, Antigravity, Kiro, OpenCode, OpenClaw, Every Code, Hermes Agent, GitHub Copilot, Kimi Code, CodeBuddy, WorkBuddy, WorkBuddy AI, Grok Build, oh-my-pi, OmO, pi, Dots, Prime Agent, Craft Agents, Reasonix, Muse Code, Kilo CLI, Kilo Code, Roo Code, Zed Agent, Goose, Droid, Mimo Code, DuMate, ZCode, Qoder, AnythingLLM Desktop, Claude Science, DeepSeek Harness, TRAE Work CN, LM Studio, Unsloth Studio, Devin CLI, Cline, MiniMax Code, Command Code, and TRAE.</p>
|
|
404
406
|
|
|
405
407
|
<h3>Is Token Tracker free and open source?</h3>
|
|
406
408
|
<p>Yes. Source on GitHub at <a href="https://github.com/xiufengsun/TokenTracker">github.com/xiufengsun/TokenTracker</a>; npm package <code>tokentracker-cli</code>.</p>
|
|
@@ -412,7 +414,7 @@
|
|
|
412
414
|
<p>Input, output, cached, and cache-creation tokens per model, project, and time window. It also surfaces usage limits for 17 providers, including Claude, Codex, Cursor, Gemini, Antigravity, Qoder, Qoder CN, Command Code, and Devin.</p>
|
|
413
415
|
|
|
414
416
|
<h3>How do I monitor AI token usage and cost across tools?</h3>
|
|
415
|
-
<p>Token Tracker is an AI token usage and cost tracker: install it with <code>npx tokentracker-cli</code>, and it monitors token consumption and spend across all
|
|
417
|
+
<p>Token Tracker is an AI token usage and cost tracker: install it with <code>npx tokentracker-cli</code>, and it monitors token consumption and spend across all 46 tools in one dashboard, with per-model pricing across 2,200+ models so you can see cost by model, project, and time window without manual tracking.</p>
|
|
416
418
|
|
|
417
419
|
<h3>Does Token Tracker work offline?</h3>
|
|
418
420
|
<p>Yes. Token Tracker is local-first. All parsing, aggregation, and dashboard rendering happen on your machine. Cloud sync is optional and powers only the public leaderboard.</p>
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
]
|
|
165
165
|
}
|
|
166
166
|
</script>
|
|
167
|
-
<script type="module" crossorigin src="/assets/__vite-browser-external-
|
|
167
|
+
<script type="module" crossorigin src="/assets/__vite-browser-external-BkNP5Ecj.js"></script>
|
|
168
168
|
<link rel="stylesheet" crossorigin href="/assets/__vite-browser-external-B0m8a6Te.css">
|
|
169
169
|
</head>
|
|
170
170
|
<body>
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
]
|
|
136
136
|
}
|
|
137
137
|
</script>
|
|
138
|
-
<script type="module" crossorigin src="/assets/__vite-browser-external-
|
|
138
|
+
<script type="module" crossorigin src="/assets/__vite-browser-external-BkNP5Ecj.js"></script>
|
|
139
139
|
<link rel="stylesheet" crossorigin href="/assets/__vite-browser-external-B0m8a6Te.css">
|
|
140
140
|
</head>
|
|
141
141
|
<body>
|
package/dashboard/dist/llms.txt
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Token Tracker LLMs Index
|
|
2
2
|
|
|
3
3
|
Token Tracker is a free, open-source, local-first AI coding usage and cost
|
|
4
|
-
tracker for
|
|
4
|
+
tracker for 46 tools. Its distinctive desktop experience includes a pixel pet
|
|
5
5
|
powered by real token activity, four desktop widgets, and achievements. The
|
|
6
6
|
same data powers a cross-platform CLI, a native macOS menu bar app, a native
|
|
7
7
|
Windows system tray app, and a dashboard. It records token counts and
|
|
@@ -23,7 +23,7 @@ timestamps, never prompts, responses, or source code.
|
|
|
23
23
|
- [npm package](https://www.npmjs.com/package/tokentracker-cli)
|
|
24
24
|
- [Latest release](https://github.com/xiufengsun/TokenTracker/releases/latest)
|
|
25
25
|
|
|
26
|
-
## Supported AI coding tools (
|
|
26
|
+
## Supported AI coding tools (46)
|
|
27
27
|
- Claude Code
|
|
28
28
|
- Codex CLI
|
|
29
29
|
- AStudio
|
|
@@ -47,6 +47,7 @@ timestamps, never prompts, responses, or source code.
|
|
|
47
47
|
- Prime Agent
|
|
48
48
|
- Craft Agents
|
|
49
49
|
- Reasonix
|
|
50
|
+
- Muse Code
|
|
50
51
|
- Kilo CLI
|
|
51
52
|
- Kilo Code
|
|
52
53
|
- Roo Code
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"description": "Shareable Token Tracker dashboard snapshot."
|
|
76
76
|
}
|
|
77
77
|
</script>
|
|
78
|
-
<script type="module" crossorigin src="/assets/__vite-browser-external-
|
|
78
|
+
<script type="module" crossorigin src="/assets/__vite-browser-external-BkNP5Ecj.js"></script>
|
|
79
79
|
<link rel="stylesheet" crossorigin href="/assets/__vite-browser-external-B0m8a6Te.css">
|
|
80
80
|
</head>
|
|
81
81
|
<body>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tokentracker-cli",
|
|
3
|
-
"version": "1.4.
|
|
4
|
-
"description": "Local-first AI coding token usage and cost tracker for
|
|
3
|
+
"version": "1.4.2",
|
|
4
|
+
"description": "Local-first AI coding token usage and cost tracker for 46 tools, with a dashboard, desktop pet, widgets, achievements, and native macOS/Windows apps.",
|
|
5
5
|
"main": "src/cli.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"tokentracker-cli": "bin/tracker.js",
|
package/src/commands/doctor.js
CHANGED
|
@@ -5,6 +5,7 @@ const { readJsonStrict, writeFileAtomic, chmod600IfPossible } = require("../lib/
|
|
|
5
5
|
const { resolveTrackerPaths } = require("../lib/tracker-paths");
|
|
6
6
|
const { collectTrackerDiagnostics } = require("../lib/diagnostics");
|
|
7
7
|
const { resolveRuntimeConfig } = require("../lib/runtime-config");
|
|
8
|
+
const { resolveDeviceTokenPresence } = require("../lib/cloud-device-token");
|
|
8
9
|
const { buildDoctorReport } = require("../lib/doctor");
|
|
9
10
|
|
|
10
11
|
async function cmdDoctor(argv = []) {
|
|
@@ -16,11 +17,24 @@ async function cmdDoctor(argv = []) {
|
|
|
16
17
|
const configStatus = await readJsonStrict(configPath);
|
|
17
18
|
const config =
|
|
18
19
|
configStatus.status === "ok" && isPlainObject(configStatus.value) ? configStatus.value : {};
|
|
19
|
-
|
|
20
|
+
let runtime = resolveRuntimeConfig({
|
|
20
21
|
cli: { baseUrl: opts.baseUrl },
|
|
21
22
|
config,
|
|
22
23
|
env: process.env,
|
|
23
24
|
});
|
|
25
|
+
const deviceTokenPresence = resolveDeviceTokenPresence({
|
|
26
|
+
trackerDir,
|
|
27
|
+
config,
|
|
28
|
+
runtime,
|
|
29
|
+
});
|
|
30
|
+
if (deviceTokenPresence.set && !(typeof runtime.deviceToken === "string" && runtime.deviceToken.trim())) {
|
|
31
|
+
// Sentinel only — doctor reports set/unset and never uses the value for auth.
|
|
32
|
+
runtime = {
|
|
33
|
+
...runtime,
|
|
34
|
+
deviceToken: "present",
|
|
35
|
+
sources: { ...(runtime.sources || {}), deviceToken: deviceTokenPresence.source },
|
|
36
|
+
};
|
|
37
|
+
}
|
|
24
38
|
const diagnostics = await collectTrackerDiagnostics({ home });
|
|
25
39
|
const cliPath = process.argv[1] ? path.resolve(process.argv[1]) : null;
|
|
26
40
|
|
package/src/commands/init.js
CHANGED
|
@@ -79,6 +79,7 @@ const {
|
|
|
79
79
|
resolveAnythingllmDbPath,
|
|
80
80
|
resolveDevinDbPath,
|
|
81
81
|
resolveReasonixHome,
|
|
82
|
+
resolveMuseHome,
|
|
82
83
|
resolveTraeStoragePath,
|
|
83
84
|
} = require("../lib/rollout");
|
|
84
85
|
const { resolveRuntimeConfig, DEFAULT_BASE_URL, normalizeInstanceBaseUrl, assertInsforgeRuntime,
|
|
@@ -141,6 +142,7 @@ const SUPPORTED_PROVIDERS = [
|
|
|
141
142
|
"Prime Agent",
|
|
142
143
|
"Craft Agents",
|
|
143
144
|
"Reasonix",
|
|
145
|
+
"Muse Code",
|
|
144
146
|
"Kilo CLI",
|
|
145
147
|
"Kilo Code",
|
|
146
148
|
"Roo Code",
|
|
@@ -882,6 +884,13 @@ async function applyIntegrationSetup({
|
|
|
882
884
|
}
|
|
883
885
|
}
|
|
884
886
|
|
|
887
|
+
// Muse Code: passive reader of ~/.local/share/muse/sessions/**/session.jsonl.
|
|
888
|
+
{
|
|
889
|
+
if (fssync.existsSync(path.join(resolveMuseHome(process.env), "sessions"))) {
|
|
890
|
+
summary.push({ label: "Muse Code", status: "detected", detail: "Passive session reader (no hook needed)" });
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
|
|
885
894
|
// International TRAE usage is read locally; no hook or vendor login is needed.
|
|
886
895
|
{
|
|
887
896
|
const { resolveTraeDbPaths } = require("../lib/trae-db");
|
package/src/commands/status.js
CHANGED
|
@@ -47,6 +47,7 @@ const {
|
|
|
47
47
|
probeOpenclawSessionPluginState,
|
|
48
48
|
} = require("../lib/openclaw-session-plugin");
|
|
49
49
|
const { resolveTrackerPaths } = require("../lib/tracker-paths");
|
|
50
|
+
const { resolveDeviceTokenPresence } = require("../lib/cloud-device-token");
|
|
50
51
|
const {
|
|
51
52
|
resolveKimiWireFiles,
|
|
52
53
|
resolveKimiCodeWireFiles,
|
|
@@ -74,6 +75,8 @@ const {
|
|
|
74
75
|
resolveCraftConfigDir,
|
|
75
76
|
resolveReasonixHome,
|
|
76
77
|
resolveReasonixTelemetryFiles,
|
|
78
|
+
resolveMuseHome,
|
|
79
|
+
resolveMuseSessionFiles,
|
|
77
80
|
resolveKilocodeTaskFiles,
|
|
78
81
|
resolveRoocodeTaskFiles,
|
|
79
82
|
resolveClineSessionFilesWithStatus,
|
|
@@ -552,6 +555,10 @@ async function cmdStatus(argv = []) {
|
|
|
552
555
|
const reasonixInstalled = Boolean(reasonixHome && fssync.existsSync(reasonixHome));
|
|
553
556
|
const reasonixFiles = reasonixInstalled ? resolveReasonixTelemetryFiles(process.env) : [];
|
|
554
557
|
|
|
558
|
+
// Muse Code (Meta) — passive scan of per-session session.jsonl logs.
|
|
559
|
+
const museInstalled = fssync.existsSync(path.join(resolveMuseHome(process.env), "sessions"));
|
|
560
|
+
const museFiles = museInstalled ? resolveMuseSessionFiles(process.env) : [];
|
|
561
|
+
|
|
555
562
|
// Kilo CLI (kilo.ai @kilocode/plugin) — passive scan of kilo.db.
|
|
556
563
|
const xdgDataHome = process.env.XDG_DATA_HOME || path.join(home, ".local", "share");
|
|
557
564
|
const kiloHome = process.env.KILO_HOME || path.join(xdgDataHome, "kilo");
|
|
@@ -1036,12 +1043,17 @@ async function cmdStatus(argv = []) {
|
|
|
1036
1043
|
},
|
|
1037
1044
|
});
|
|
1038
1045
|
|
|
1046
|
+
const deviceTokenPresence = resolveDeviceTokenPresence({
|
|
1047
|
+
trackerDir,
|
|
1048
|
+
config: config || {},
|
|
1049
|
+
});
|
|
1050
|
+
|
|
1039
1051
|
if (opts.json || opts.light) {
|
|
1040
1052
|
const summary = {
|
|
1041
1053
|
version: pkg.version,
|
|
1042
1054
|
generated_at: new Date().toISOString(),
|
|
1043
1055
|
base_url: config?.baseUrl || null,
|
|
1044
|
-
device_token_set:
|
|
1056
|
+
device_token_set: deviceTokenPresence.set,
|
|
1045
1057
|
queue: {
|
|
1046
1058
|
pending_bytes: pendingBytes,
|
|
1047
1059
|
size_bytes: queueSize,
|
|
@@ -1136,6 +1148,9 @@ async function cmdStatus(argv = []) {
|
|
|
1136
1148
|
reasonix: reasonixInstalled
|
|
1137
1149
|
? { installed: true, files: reasonixFiles.length }
|
|
1138
1150
|
: { installed: false },
|
|
1151
|
+
muse: museInstalled
|
|
1152
|
+
? { installed: true, files: museFiles.length }
|
|
1153
|
+
: { installed: false },
|
|
1139
1154
|
anythingllm: anythingllmInstalled
|
|
1140
1155
|
? { installed: true, detail: anythingllmDbPath }
|
|
1141
1156
|
: { installed: false },
|
|
@@ -1271,7 +1286,7 @@ async function cmdStatus(argv = []) {
|
|
|
1271
1286
|
`TokenTracker v${pkg.version}`,
|
|
1272
1287
|
"Status:",
|
|
1273
1288
|
`- Base URL: ${config?.baseUrl || "unset"}`,
|
|
1274
|
-
`- Device token: ${
|
|
1289
|
+
`- Device token: ${deviceTokenPresence.set ? "set" : "unset"}`,
|
|
1275
1290
|
`- Queue: ${pendingBytes} bytes pending`,
|
|
1276
1291
|
`- Last parse: ${cursors?.updatedAt || "never"}`,
|
|
1277
1292
|
`- Last notify: ${lastNotify || "never"}`,
|
|
@@ -1335,6 +1350,9 @@ async function cmdStatus(argv = []) {
|
|
|
1335
1350
|
reasonixInstalled
|
|
1336
1351
|
? `- Reasonix: passive reader (${reasonixFiles.length} telemetry file${reasonixFiles.length !== 1 ? "s" : ""} found)`
|
|
1337
1352
|
: null,
|
|
1353
|
+
museInstalled
|
|
1354
|
+
? `- Muse Code: passive reader (${museFiles.length} session jsonl file${museFiles.length !== 1 ? "s" : ""} found)`
|
|
1355
|
+
: null,
|
|
1338
1356
|
anythingllmInstalled
|
|
1339
1357
|
? `- AnythingLLM Desktop: passive reader (${anythingllmDbPath})`
|
|
1340
1358
|
: null,
|
package/src/commands/sync.js
CHANGED
|
@@ -102,6 +102,8 @@ const {
|
|
|
102
102
|
parseCraftIncremental,
|
|
103
103
|
resolveReasonixTelemetryFiles,
|
|
104
104
|
parseReasonixIncremental,
|
|
105
|
+
resolveMuseSessionFiles,
|
|
106
|
+
parseMuseIncremental,
|
|
105
107
|
resolveGrokBuildSessions,
|
|
106
108
|
parseGrokBuildIncremental,
|
|
107
109
|
resolveAntigravityDbPath,
|
|
@@ -349,6 +351,7 @@ const AUTO_SYNC_SOURCES = new Set([
|
|
|
349
351
|
"lmstudio",
|
|
350
352
|
"mimo",
|
|
351
353
|
"minimax-code",
|
|
354
|
+
"muse",
|
|
352
355
|
"omo",
|
|
353
356
|
"omp",
|
|
354
357
|
"opencode",
|
|
@@ -371,6 +374,7 @@ const BACKGROUND_AUTO_SYNC_SOURCES = new Set([
|
|
|
371
374
|
"acode",
|
|
372
375
|
"codex",
|
|
373
376
|
"every-code",
|
|
377
|
+
"muse",
|
|
374
378
|
"reasonix",
|
|
375
379
|
]);
|
|
376
380
|
|
|
@@ -2915,6 +2919,25 @@ async function cmdSync(argv, context = {}) {
|
|
|
2915
2919
|
}
|
|
2916
2920
|
}
|
|
2917
2921
|
|
|
2922
|
+
// Muse Code (Meta) — usage counts from per-session session.jsonl logs.
|
|
2923
|
+
let museResult = { recordsProcessed: 0, eventsAggregated: 0, bucketsQueued: 0 };
|
|
2924
|
+
const museFiles = sourceAllowed("muse")
|
|
2925
|
+
? mergeBothFileSources({ resolveFiles: resolveMuseSessionFiles, env: process.env })
|
|
2926
|
+
: [];
|
|
2927
|
+
if (museFiles.length > 0) {
|
|
2928
|
+
try {
|
|
2929
|
+
museResult = await parseMuseIncremental({
|
|
2930
|
+
sessionFiles: museFiles,
|
|
2931
|
+
cursors,
|
|
2932
|
+
queuePath,
|
|
2933
|
+
env: process.env,
|
|
2934
|
+
onProgress: makeProviderProgress("Muse"),
|
|
2935
|
+
});
|
|
2936
|
+
} catch (err) {
|
|
2937
|
+
warnProviderParseFailure("Muse", err, opts);
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
|
|
2918
2941
|
// ── Grok Build (xAI) ──
|
|
2919
2942
|
let grokResult = {
|
|
2920
2943
|
recordsProcessed: 0,
|
|
@@ -3373,6 +3396,7 @@ async function cmdSync(argv, context = {}) {
|
|
|
3373
3396
|
minimaxCodeResult.recordsProcessed +
|
|
3374
3397
|
craftResult.recordsProcessed +
|
|
3375
3398
|
reasonixResult.recordsProcessed +
|
|
3399
|
+
museResult.recordsProcessed +
|
|
3376
3400
|
grokResult.recordsProcessed +
|
|
3377
3401
|
copilotResult.recordsProcessed +
|
|
3378
3402
|
lmstudioResult.recordsProcessed +
|
|
@@ -3419,6 +3443,7 @@ async function cmdSync(argv, context = {}) {
|
|
|
3419
3443
|
minimaxCodeResult.bucketsQueued +
|
|
3420
3444
|
craftResult.bucketsQueued +
|
|
3421
3445
|
reasonixResult.bucketsQueued +
|
|
3446
|
+
museResult.bucketsQueued +
|
|
3422
3447
|
grokResult.bucketsQueued +
|
|
3423
3448
|
copilotResult.bucketsQueued +
|
|
3424
3449
|
lmstudioResult.bucketsQueued +
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
const fs = require("node:fs");
|
|
2
2
|
const path = require("node:path");
|
|
3
3
|
const crypto = require("node:crypto");
|
|
4
|
+
const {
|
|
5
|
+
resolveRuntimeConfig,
|
|
6
|
+
normalizeInstanceBaseUrl,
|
|
7
|
+
} = require("./runtime-config");
|
|
4
8
|
|
|
5
9
|
function validBinding(binding) {
|
|
6
10
|
return ["userId", "baseUrl", "machineId"].every(
|
|
@@ -8,6 +12,27 @@ function validBinding(binding) {
|
|
|
8
12
|
);
|
|
9
13
|
}
|
|
10
14
|
|
|
15
|
+
function readCloudDeviceTokenEntry(filePath) {
|
|
16
|
+
let fd;
|
|
17
|
+
try {
|
|
18
|
+
fd = fs.openSync(filePath, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW || 0));
|
|
19
|
+
if (!fs.fstatSync(fd).isFile()) return null;
|
|
20
|
+
fs.fchmodSync(fd, 0o600);
|
|
21
|
+
const data = JSON.parse(fs.readFileSync(fd, "utf8"));
|
|
22
|
+
if (data?.version === 1 && validBinding(data) && typeof data.token === "string" && data.token) {
|
|
23
|
+
return {
|
|
24
|
+
version: 1,
|
|
25
|
+
userId: data.userId,
|
|
26
|
+
baseUrl: data.baseUrl,
|
|
27
|
+
machineId: data.machineId,
|
|
28
|
+
token: data.token,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
} catch { /* missing or invalid cache requires ordinary issuance */ }
|
|
32
|
+
finally { if (fd !== undefined) fs.closeSync(fd); }
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
11
36
|
// A successful auth refresh supplies the binding. This file never imports a
|
|
12
37
|
// CLI config token, whose owner may belong to another signed-in account.
|
|
13
38
|
function createCloudDeviceTokenStore(filePath) {
|
|
@@ -17,15 +42,7 @@ function createCloudDeviceTokenStore(filePath) {
|
|
|
17
42
|
function load() {
|
|
18
43
|
if (loaded) return entry;
|
|
19
44
|
loaded = true;
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
fd = fs.openSync(filePath, fs.constants.O_RDONLY | (fs.constants.O_NOFOLLOW || 0));
|
|
23
|
-
if (!fs.fstatSync(fd).isFile()) return null;
|
|
24
|
-
fs.fchmodSync(fd, 0o600);
|
|
25
|
-
const data = JSON.parse(fs.readFileSync(fd, "utf8"));
|
|
26
|
-
if (data?.version === 1 && validBinding(data) && typeof data.token === "string" && data.token) entry = data;
|
|
27
|
-
} catch { /* missing or invalid cache requires ordinary issuance */ }
|
|
28
|
-
finally { if (fd !== undefined) fs.closeSync(fd); }
|
|
45
|
+
entry = readCloudDeviceTokenEntry(filePath);
|
|
29
46
|
return entry;
|
|
30
47
|
}
|
|
31
48
|
|
|
@@ -71,4 +88,54 @@ function createCloudDeviceTokenStore(filePath) {
|
|
|
71
88
|
};
|
|
72
89
|
}
|
|
73
90
|
|
|
74
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Presence for status/doctor/diagnostics — same stores upload uses.
|
|
93
|
+
* Prefer config/env/cli (resolveRuntimeConfig); else cloud-device-token.json
|
|
94
|
+
* when baseUrl (+ machineId when known) match. Never clears the store.
|
|
95
|
+
*/
|
|
96
|
+
function resolveDeviceTokenPresence({
|
|
97
|
+
trackerDir,
|
|
98
|
+
config = {},
|
|
99
|
+
runtime = null,
|
|
100
|
+
env = process.env,
|
|
101
|
+
} = {}) {
|
|
102
|
+
const resolved = runtime || resolveRuntimeConfig({ config, env });
|
|
103
|
+
if (typeof resolved?.deviceToken === "string" && resolved.deviceToken.trim()) {
|
|
104
|
+
return {
|
|
105
|
+
set: true,
|
|
106
|
+
source: resolved.sources?.deviceToken || "config",
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!trackerDir || typeof trackerDir !== "string") {
|
|
111
|
+
return { set: false, source: null };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const entry = readCloudDeviceTokenEntry(path.join(trackerDir, "cloud-device-token.json"));
|
|
115
|
+
if (!entry) return { set: false, source: null };
|
|
116
|
+
|
|
117
|
+
const expectedBase =
|
|
118
|
+
normalizeInstanceBaseUrl(resolved?.baseUrl) ||
|
|
119
|
+
(typeof resolved?.baseUrl === "string" ? resolved.baseUrl.trim() : "") ||
|
|
120
|
+
normalizeInstanceBaseUrl(config.baseUrl) ||
|
|
121
|
+
(typeof config.baseUrl === "string" ? config.baseUrl.trim() : "");
|
|
122
|
+
if (expectedBase && entry.baseUrl !== expectedBase) {
|
|
123
|
+
return { set: false, source: null };
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const expectedMachine =
|
|
127
|
+
typeof config.machineId === "string" && config.machineId.trim()
|
|
128
|
+
? config.machineId.trim()
|
|
129
|
+
: null;
|
|
130
|
+
if (expectedMachine && entry.machineId !== expectedMachine) {
|
|
131
|
+
return { set: false, source: null };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return { set: true, source: "cloud-device-token" };
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
module.exports = {
|
|
138
|
+
createCloudDeviceTokenStore,
|
|
139
|
+
resolveDeviceTokenPresence,
|
|
140
|
+
readCloudDeviceTokenEntry,
|
|
141
|
+
};
|
package/src/lib/diagnostics.js
CHANGED
|
@@ -19,6 +19,7 @@ const { probeOpenclawHookState } = require("./openclaw-hook");
|
|
|
19
19
|
const { probeOpenclawSessionPluginState } = require("./openclaw-session-plugin");
|
|
20
20
|
const { probeGrokHookState } = require("./grok-hook");
|
|
21
21
|
const { resolveTrackerPaths } = require("./tracker-paths");
|
|
22
|
+
const { resolveDeviceTokenPresence } = require("./cloud-device-token");
|
|
22
23
|
const wsl = require("./wsl-probe");
|
|
23
24
|
// TASK-011: Kiro paths inlined here to avoid pulling the ~4000-line
|
|
24
25
|
// rollout module on every `tokentracker status` / `diagnostics` call.
|
|
@@ -238,7 +239,9 @@ async function collectTrackerDiagnostics({
|
|
|
238
239
|
},
|
|
239
240
|
config: {
|
|
240
241
|
base_url: typeof config?.baseUrl === "string" ? config.baseUrl : null,
|
|
241
|
-
device_token: config
|
|
242
|
+
device_token: resolveDeviceTokenPresence({ trackerDir, config: config || {} }).set
|
|
243
|
+
? "set"
|
|
244
|
+
: "unset",
|
|
242
245
|
device_id: maskId(config?.deviceId),
|
|
243
246
|
installed_at: typeof config?.installedAt === "string" ? config.installedAt : null,
|
|
244
247
|
},
|
package/src/lib/pricing/index.js
CHANGED
|
@@ -250,7 +250,8 @@ function computeRowCost(row) {
|
|
|
250
250
|
row.source === "acode" ||
|
|
251
251
|
row.source === "every-code" ||
|
|
252
252
|
row.source === "omo" ||
|
|
253
|
-
row.source === "cline"
|
|
253
|
+
row.source === "cline" ||
|
|
254
|
+
row.source === "muse";
|
|
254
255
|
const reasoningCost = reasoningIncludedInOutput
|
|
255
256
|
? 0
|
|
256
257
|
: (row.reasoning_output_tokens || 0) * (pricing.output || 0);
|