tokentracker-cli 1.3.16 → 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.
Files changed (145) 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 +5 -4
  5. package/README.zh-CN.md +5 -4
  6. package/dashboard/dist/assets/{AchievementBadge-D5sRTMmp.js → AchievementBadge-WGbdoboF.js} +1 -1
  7. package/dashboard/dist/assets/{AchievementsPage-CaiCfchd.js → AchievementsPage-BvybbsXv.js} +2 -2
  8. package/dashboard/dist/assets/{AchievementsSection-D6dTxdUd.js → AchievementsSection-ChNzTFSR.js} +1 -1
  9. package/dashboard/dist/assets/{BadgeDetailModal-C0UrWb9m.js → BadgeDetailModal-DhI9Ejz3.js} +1 -1
  10. package/dashboard/dist/assets/{BotAnimated-CgpBB5FZ.js → BotAnimated-Bch0Yxej.js} +1 -1
  11. package/dashboard/dist/assets/{Card-CuwBiIYz.js → Card-DWdL7d1T.js} +1 -1
  12. package/dashboard/dist/assets/{CloudCheckoutPage-BNCnBR0h.js → CloudCheckoutPage-BjGoOz6P.js} +1 -1
  13. package/dashboard/dist/assets/{CloudPage-CuYXUQnv.js → CloudPage-Btb6a97x.js} +2 -2
  14. package/dashboard/dist/assets/{CommandPalette-CV6a_7yK.js → CommandPalette-DwP3k7LE.js} +1 -1
  15. package/dashboard/dist/assets/{CommunityStatsModal-Dw-64Tig.js → CommunityStatsModal-mzqLxpwE.js} +1 -1
  16. package/dashboard/dist/assets/{ConfirmModal-CoFO1Nas.js → ConfirmModal-Dm76q4EX.js} +1 -1
  17. package/dashboard/dist/assets/{Controls-DB9eQ_rg.js → Controls-ClZjOBoD.js} +1 -1
  18. package/dashboard/dist/assets/DashboardPage-Doc8f4NL.js +1 -0
  19. package/dashboard/dist/assets/{DateRangePopover-DgZEnn4X.js → DateRangePopover-vfTUePPg.js} +1 -1
  20. package/dashboard/dist/assets/DevicePage-Jjg5q0C2.js +1 -0
  21. package/dashboard/dist/assets/{DialogClose-BR9QrB34.js → DialogClose-Ci5mPZ6X.js} +1 -1
  22. package/dashboard/dist/assets/DialogDescription-Di5ev5K6.js +1 -0
  23. package/dashboard/dist/assets/DialogTitle-DI21oZxH.js +1 -0
  24. package/dashboard/dist/assets/{ElectricLogo-nrlBy-l9.js → ElectricLogo-DfeZBwPZ.js} +1 -1
  25. package/dashboard/dist/assets/{FadeIn-CyJJ3l_P.js → FadeIn-C7SIILTc.js} +1 -1
  26. package/dashboard/dist/assets/{HeaderGithubStar-C7BX7loS.js → HeaderGithubStar-RStLbadn.js} +1 -1
  27. package/dashboard/dist/assets/{HoverTooltip-KGluh6sO.js → HoverTooltip-DI7uAp1_.js} +1 -1
  28. package/dashboard/dist/assets/{IpCheckPage-Ci2ybTDg.js → IpCheckPage-DTZNTJVh.js} +1 -1
  29. package/dashboard/dist/assets/{LandingPage-C9N17IpV.js → LandingPage-Df5scNlw.js} +2 -2
  30. package/dashboard/dist/assets/{LeaderboardPage-Cco7iFen.js → LeaderboardPage-Ck3SqtnI.js} +2 -2
  31. package/dashboard/dist/assets/{LeaderboardProBadge-tmm5NN8p.js → LeaderboardProBadge-CGx6m7R6.js} +1 -1
  32. package/dashboard/dist/assets/{LeaderboardProfileModal-WhjsvZ9Q.js → LeaderboardProfileModal-DuP7rgfv.js} +3 -3
  33. package/dashboard/dist/assets/{LeaderboardProfilePage-Ba3oVu5z.js → LeaderboardProfilePage-B5qUJkZX.js} +1 -1
  34. package/dashboard/dist/assets/{LimitsPage-CUa46XJy.js → LimitsPage-Bv_Lcvcz.js} +1 -1
  35. package/dashboard/dist/assets/{LocalOnlyNotice-BSewrWlY.js → LocalOnlyNotice-Cg4y02JM.js} +1 -1
  36. package/dashboard/dist/assets/{LoginCard-CUWn0Tz4.js → LoginCard-Wz0uJKXx.js} +1 -1
  37. package/dashboard/dist/assets/{LoginModal-UKk3xCsV.js → LoginModal-C13v_Gs0.js} +1 -1
  38. package/dashboard/dist/assets/{LoginPage-BhxiWgc5.js → LoginPage-COH9xXtd.js} +1 -1
  39. package/dashboard/dist/assets/{PetPage-BRyxC-Iu.js → PetPage-BWCnURub.js} +2 -2
  40. package/dashboard/dist/assets/PopoverPopup-Dw811N-_.js +1 -0
  41. package/dashboard/dist/assets/{ProviderIcon-htNu1RTN.js → ProviderIcon-CHxhYzK-.js} +1 -1
  42. package/dashboard/dist/assets/{ResetPasswordPage-DawMNiM1.js → ResetPasswordPage-Ll6jshqg.js} +1 -1
  43. package/dashboard/dist/assets/Select-BbooQ3sa.js +1 -0
  44. package/dashboard/dist/assets/SelectItemText-DBiW70wi.js +1 -0
  45. package/dashboard/dist/assets/{SelfHostPage-BMCMrt5I.js → SelfHostPage-BMHJxz5q.js} +1 -1
  46. package/dashboard/dist/assets/{ServiceStatusPage-e_7xC0RY.js → ServiceStatusPage-D6LH0ac-.js} +1 -1
  47. package/dashboard/dist/assets/{SessionsPage-Xr2FJa6E.js → SessionsPage-Mrer6v17.js} +2 -2
  48. package/dashboard/dist/assets/SettingsPage-D_7P_y_l.js +5 -0
  49. package/dashboard/dist/assets/SkillsPage-Ka7xm-1v.js +1 -0
  50. package/dashboard/dist/assets/{TokenGalaxy--6ijNK6P.js → TokenGalaxy-BEURDPFq.js} +1 -1
  51. package/dashboard/dist/assets/TooltipPopup-ZiuFFARC.js +1 -0
  52. package/dashboard/dist/assets/{TrendMonitor-DjIZyzxp.js → TrendMonitor-H73lyGEf.js} +1 -1
  53. package/dashboard/dist/assets/{WidgetsPage-CzCqGbb4.js → WidgetsPage-_7iCvyTk.js} +1 -1
  54. package/dashboard/dist/assets/{WrappedPage-B0RMtpvr.js → WrappedPage-DEXNb6-k.js} +1 -1
  55. package/dashboard/dist/assets/__vite-browser-external-BkNP5Ecj.js +45 -0
  56. package/dashboard/dist/assets/{agent-logos-CSlyeabY.js → agent-logos-OVBc_0cF.js} +1 -1
  57. package/dashboard/dist/assets/{arrow-left-DaqMiXTO.js → arrow-left-DDphsclm.js} +1 -1
  58. package/dashboard/dist/assets/{arrow-right-B1p9R8vH.js → arrow-right-B1aNq0Ki.js} +1 -1
  59. package/dashboard/dist/assets/{arrow-up-right-CK_9HuEh.js → arrow-up-right-yTM9azz_.js} +1 -1
  60. package/dashboard/dist/assets/{calendar-days-BVyCx4dJ.js → calendar-days-D22ithNF.js} +1 -1
  61. package/dashboard/dist/assets/{check-DIfCVsPJ.js → check-Dk7tknvE.js} +1 -1
  62. package/dashboard/dist/assets/{chevron-down-DrWxRBXX.js → chevron-down-DdyEzQ4f.js} +1 -1
  63. package/dashboard/dist/assets/{cloud-checkout-DOxBG7oS.js → cloud-checkout-BJjbipnH.js} +1 -1
  64. package/dashboard/dist/assets/composite-DEqP00XV.js +1 -0
  65. package/dashboard/dist/assets/{download-CEXAmejX.js → download-C9ixNyzn.js} +1 -1
  66. package/dashboard/dist/assets/{external-link-tDBZy6QP.js → external-link-DL4HSsLw.js} +1 -1
  67. package/dashboard/dist/assets/{flame-86y9Xf0g.js → flame-DqNH65nB.js} +1 -1
  68. package/dashboard/dist/assets/{format-tokens-BNN9k5mV.js → format-tokens-CyVjKz4I.js} +1 -1
  69. package/dashboard/dist/assets/{gift-BEOvq2zc.js → gift-ChJQQe_G.js} +1 -1
  70. package/dashboard/dist/assets/{host-mode-UjbNKxFB.js → host-mode-DpUDpoOz.js} +1 -1
  71. package/dashboard/dist/assets/{icons-DJmZD0si.js → icons-CJiHeOaU.js} +1 -1
  72. package/dashboard/dist/assets/{index-BwUwnqE0.js → index-72LQsAaf.js} +1 -1
  73. package/dashboard/dist/assets/{index-B8kizz-s.js → index-BucEg3fu.js} +1 -1
  74. package/dashboard/dist/assets/{index-Ci3CZ-2g.js → index-CrFlTSra.js} +1 -1
  75. package/dashboard/dist/assets/{info-ynVg8RzK.js → info-DReYqxC7.js} +1 -1
  76. package/dashboard/dist/assets/{link-2-B9SLPcBg.js → link-2-kIZbhK2S.js} +1 -1
  77. package/dashboard/dist/assets/{loader-circle-FTE9k7Sk.js → loader-circle-1An-X85y.js} +1 -1
  78. package/dashboard/dist/assets/{modifiers.esm-B4babCm_.js → modifiers.esm-FoVheEKT.js} +1 -1
  79. package/dashboard/dist/assets/module-DOCYJaxl.js +3 -0
  80. package/dashboard/dist/assets/{monitor-smartphone-CNzgbo-M.js → monitor-smartphone-Ch6lr_P2.js} +1 -1
  81. package/dashboard/dist/assets/{play-9W4Ua21o.js → play-CbJ6ZF1K.js} +1 -1
  82. package/dashboard/dist/assets/{plus-BA85lApI.js → plus-C-5ID3a9.js} +1 -1
  83. package/dashboard/dist/assets/{provider-display-D1ETarsz.js → provider-display-BFzRtoL2.js} +2 -2
  84. package/dashboard/dist/assets/{react-VsHxeqq7.js → react-D4CR_fLQ.js} +1 -1
  85. package/dashboard/dist/assets/safePolygon-DP21Ibqj.js +1 -0
  86. package/dashboard/dist/assets/{search-Svi--7CN.js → search-CaznkY7U.js} +1 -1
  87. package/dashboard/dist/assets/{server-CgHdX6TE.js → server-CUOmC6xZ.js} +1 -1
  88. package/dashboard/dist/assets/{shield-check-Cjv-T4aT.js → shield-check-Dr2KBMmA.js} +1 -1
  89. package/dashboard/dist/assets/{skills-api-Cn8hEYL4.js → skills-api-BAz_fblS.js} +1 -1
  90. package/dashboard/dist/assets/{sortable.esm-g3UcmvFU.js → sortable.esm-knEfm5hE.js} +1 -1
  91. package/dashboard/dist/assets/store-CL97jcij.js +1 -0
  92. package/dashboard/dist/assets/{terminal-o0jvDfI0.js → terminal-EjFyreWj.js} +1 -1
  93. package/dashboard/dist/assets/{trash-0cqpTyN6.js → trash-ByqaZXkQ.js} +1 -1
  94. package/dashboard/dist/assets/{use-community-stats-BFgORaJS.js → use-community-stats-Bs4RDJZE.js} +1 -1
  95. package/dashboard/dist/assets/{use-latest-request-guard-9eZP_jA5.js → use-latest-request-guard-CG3Ir1cP.js} +1 -1
  96. package/dashboard/dist/assets/{use-limits-display-prefs-BjO3hsmw.js → use-limits-display-prefs-tACgCxeR.js} +1 -1
  97. package/dashboard/dist/assets/{use-native-settings-YKn-htVo.js → use-native-settings-CWjXyJXi.js} +1 -1
  98. package/dashboard/dist/assets/{use-ordered-list-D5h4UwhF.js → use-ordered-list-DsuC9JQa.js} +1 -1
  99. package/dashboard/dist/assets/use-reduced-motion-CwFguzkm.js +1 -0
  100. package/dashboard/dist/assets/{use-session-efficiency-pref-BShLuIbk.js → use-session-efficiency-pref-NeoJE8BL.js} +1 -1
  101. package/dashboard/dist/assets/{use-transform-DVZHJPVD.js → use-transform-BWGKOsya.js} +1 -1
  102. package/dashboard/dist/assets/{use-usage-limits-BhJbW76K.js → use-usage-limits-CFWFNwHS.js} +1 -1
  103. package/dashboard/dist/assets/{useCurrency-BmEbDVaa.js → useCurrency-B_C4_P5x.js} +1 -1
  104. package/dashboard/dist/assets/usePositioner-B0L5_o38.js +1 -0
  105. package/dashboard/dist/assets/{useTokenFormat-CBlBP2aA.js → useTokenFormat-DH1GWHSU.js} +1 -1
  106. package/dashboard/dist/assets/{zap-cML2-Nx4.js → zap-Chv1p7pS.js} +1 -1
  107. package/dashboard/dist/index.html +13 -11
  108. package/dashboard/dist/ip-check.html +1 -1
  109. package/dashboard/dist/leaderboard.html +1 -1
  110. package/dashboard/dist/llms.txt +3 -2
  111. package/dashboard/dist/share.html +1 -1
  112. package/package.json +3 -3
  113. package/src/commands/doctor.js +15 -1
  114. package/src/commands/init.js +9 -0
  115. package/src/commands/status.js +21 -3
  116. package/src/commands/sync.js +59 -4
  117. package/src/lib/cloud-device-token.js +77 -10
  118. package/src/lib/cloud-usage-reset.js +115 -0
  119. package/src/lib/diagnostics.js +5 -2
  120. package/src/lib/kimi-model-repair.js +173 -0
  121. package/src/lib/kimi-session.js +216 -0
  122. package/src/lib/local-api.js +46 -1
  123. package/src/lib/pricing/index.js +2 -1
  124. package/src/lib/pricing/seed-snapshot.json +1 -1
  125. package/src/lib/qoder-cn-cli-limits.js +9 -7
  126. package/src/lib/qoder-limits.js +45 -15
  127. package/src/lib/rollout.js +408 -4
  128. package/src/lib/session-analytics.js +47 -9
  129. package/dashboard/dist/assets/DashboardPage-sZKijU6h.js +0 -1
  130. package/dashboard/dist/assets/DevicePage-YCnJnsmz.js +0 -1
  131. package/dashboard/dist/assets/DialogDescription-Cx1R3WT7.js +0 -1
  132. package/dashboard/dist/assets/DialogTitle-ck8f1qeP.js +0 -1
  133. package/dashboard/dist/assets/PopoverPopup-D-Tpl294.js +0 -1
  134. package/dashboard/dist/assets/Select-6WChWtqK.js +0 -1
  135. package/dashboard/dist/assets/SelectItemText-DRmxMwo5.js +0 -1
  136. package/dashboard/dist/assets/SettingsPage-Bxq2Mhxz.js +0 -5
  137. package/dashboard/dist/assets/SkillsPage-CEIBW63c.js +0 -1
  138. package/dashboard/dist/assets/TooltipPopup--TLYUg0c.js +0 -1
  139. package/dashboard/dist/assets/__vite-browser-external-BsOjTB8Q.js +0 -45
  140. package/dashboard/dist/assets/composite-W1R1XwoE.js +0 -1
  141. package/dashboard/dist/assets/module-BNnaKM__.js +0 -3
  142. package/dashboard/dist/assets/safePolygon-CCDOsx-z.js +0 -1
  143. package/dashboard/dist/assets/store-D2gn9bSV.js +0 -1
  144. package/dashboard/dist/assets/use-reduced-motion-C83gmg0F.js +0 -1
  145. package/dashboard/dist/assets/usePositioner-nY0YNa-6.js +0 -1
@@ -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
- const runtime = resolveRuntimeConfig({
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
 
@@ -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");
@@ -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: Boolean(config?.deviceToken),
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: ${config?.deviceToken ? "set" : "unset"}`,
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"}`,
@@ -1300,7 +1315,7 @@ async function cmdStatus(argv = []) {
1300
1315
  ? `- Kimi Code: passive reader (${kimiWireFiles.length + kimiCodeWireFiles.length} wire.jsonl file${(kimiWireFiles.length + kimiCodeWireFiles.length) !== 1 ? "s" : ""} found, directories: ${kimiActive.join(" | ") || "none"})`
1301
1316
  : null,
1302
1317
  kiroCliInstalled
1303
- ? `- Kiro CLI: passive reader (${kiroCliFileCount} session file${kiroCliFileCount !== 1 ? "s" : ""} found, SQLite ${kiroCliDbFound ? "found" : "not found"}, installs: ${kiroCliActive.join(" | ")}; tokens approximated from char lengths and merged under 'kiro')`
1318
+ ? `- Kiro CLI: passive reader (${kiroCliFileCount} session file${kiroCliFileCount !== 1 ? "s" : ""} found, SQLite ${kiroCliDbFound ? "found" : "not found"}, installs: ${kiroCliActive.join(" | ")}; missing token counts use new-text estimates at ~4 chars/token, excluding re-sent history, system context and cache usage; model-rate costs are separate from Kiro credit charges; merged under 'kiro')`
1304
1319
  : null,
1305
1320
  kiroIdeInstalled
1306
1321
  ? `- Kiro IDE: passive reader (${kiroIdeActive.join(" | ")})`
@@ -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,
@@ -5,6 +5,8 @@ const fssync = require("node:fs");
5
5
  const cp = require("node:child_process");
6
6
  const readline = require("node:readline");
7
7
  const { functionUrlFor, fetchFunctionResponse } = require("../lib/function-url");
8
+ const { cloudUsageResetBlocksUpload, finishCloudDeviceUsageReset } = require("../lib/cloud-usage-reset");
9
+ const { KIMI_MODEL_REPAIR_KEY, repairKimiModelAttribution } = require("../lib/kimi-model-repair");
8
10
 
9
11
  const { resolveInstallPaths, resolveZcodeNativeDbPath, resolveMimoNativeDbPath, ensureFlatCursor } = require("../lib/install-resolver");
10
12
  const { multiInstallParse, mergeBothFileSources } = require("../lib/multi-install-parser");
@@ -100,6 +102,8 @@ const {
100
102
  parseCraftIncremental,
101
103
  resolveReasonixTelemetryFiles,
102
104
  parseReasonixIncremental,
105
+ resolveMuseSessionFiles,
106
+ parseMuseIncremental,
103
107
  resolveGrokBuildSessions,
104
108
  parseGrokBuildIncremental,
105
109
  resolveAntigravityDbPath,
@@ -347,6 +351,7 @@ const AUTO_SYNC_SOURCES = new Set([
347
351
  "lmstudio",
348
352
  "mimo",
349
353
  "minimax-code",
354
+ "muse",
350
355
  "omo",
351
356
  "omp",
352
357
  "opencode",
@@ -369,6 +374,7 @@ const BACKGROUND_AUTO_SYNC_SOURCES = new Set([
369
374
  "acode",
370
375
  "codex",
371
376
  "every-code",
377
+ "muse",
372
378
  "reasonix",
373
379
  ]);
374
380
 
@@ -542,7 +548,13 @@ async function cmdSync(argv, context = {}) {
542
548
  // Hooks, native publication and detached retries must honor the saved opt-in.
543
549
  const requiresCloudSyncPref = opts.auto || opts.background || opts.fromRetry || opts.fromNotify || opts.fromOpenclaw ||
544
550
  Boolean(process.env.TOKENTRACKER_LOCAL_SYNC_ATTEMPT_ID);
545
- const canUpload = () => !requiresCloudSyncPref || readCloudSyncEnabled(trackerDir);
551
+ let cloudResetRuntime = null;
552
+ const canUpload = () => !cloudUsageResetBlocksUpload(trackerDir, {
553
+ ownerId: process.env.TOKENTRACKER_CLOUD_OWNER_ID,
554
+ baseUrl: cloudResetRuntime?.baseUrl || process.env.TOKENTRACKER_INSFORGE_BASE_URL,
555
+ deviceId: process.env.TOKENTRACKER_CLOUD_DEVICE_ID,
556
+ }) &&
557
+ (!requiresCloudSyncPref || readCloudSyncEnabled(trackerDir));
546
558
 
547
559
  await ensureDir(trackerDir);
548
560
  if (opts.fromOpenclaw) {
@@ -2508,6 +2520,17 @@ async function cmdSync(argv, context = {}) {
2508
2520
  const kimiWireFiles = sourceAllowed("kimi")
2509
2521
  ? mergeBothFileSources({ resolveFiles: resolveKimiWireFiles, env: process.env })
2510
2522
  : [];
2523
+ const kimiCodeWireFiles = sourceAllowed("kimi-code")
2524
+ ? mergeBothFileSources({ resolveFiles: resolveKimiCodeWireFiles, env: process.env })
2525
+ : [];
2526
+ if (isFullSourceScan && sourceAllowed("kimi") && sourceAllowed("kimi-code")) {
2527
+ await repairKimiModelAttribution({
2528
+ cursors, queuePath, queueStatePath,
2529
+ legacyFiles: kimiWireFiles, officialFiles: kimiCodeWireFiles,
2530
+ parseLegacy: parseKimiIncremental, parseOfficial: parseKimiCodeIncremental,
2531
+ env: process.env,
2532
+ });
2533
+ }
2511
2534
  if (kimiWireFiles.length > 0) {
2512
2535
  if (progress?.enabled) {
2513
2536
  progress.start(`Parsing Kimi Code ${renderBar(0)} | buckets 0`);
@@ -2533,9 +2556,6 @@ async function cmdSync(argv, context = {}) {
2533
2556
 
2534
2557
  // ── Kimi Code official (@moonshot-ai/kimi-code, ~/.kimi-code) ──
2535
2558
  let kimiCodeResult = { recordsProcessed: 0, eventsAggregated: 0, bucketsQueued: 0 };
2536
- const kimiCodeWireFiles = sourceAllowed("kimi-code")
2537
- ? mergeBothFileSources({ resolveFiles: resolveKimiCodeWireFiles, env: process.env })
2538
- : [];
2539
2559
  if (kimiCodeWireFiles.length > 0) {
2540
2560
  if (progress?.enabled) {
2541
2561
  progress.start(`Parsing Kimi Code (official) ${renderBar(0)} | buckets 0`);
@@ -2899,6 +2919,25 @@ async function cmdSync(argv, context = {}) {
2899
2919
  }
2900
2920
  }
2901
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
+
2902
2941
  // ── Grok Build (xAI) ──
2903
2942
  let grokResult = {
2904
2943
  recordsProcessed: 0,
@@ -3357,6 +3396,7 @@ async function cmdSync(argv, context = {}) {
3357
3396
  minimaxCodeResult.recordsProcessed +
3358
3397
  craftResult.recordsProcessed +
3359
3398
  reasonixResult.recordsProcessed +
3399
+ museResult.recordsProcessed +
3360
3400
  grokResult.recordsProcessed +
3361
3401
  copilotResult.recordsProcessed +
3362
3402
  lmstudioResult.recordsProcessed +
@@ -3403,6 +3443,7 @@ async function cmdSync(argv, context = {}) {
3403
3443
  minimaxCodeResult.bucketsQueued +
3404
3444
  craftResult.bucketsQueued +
3405
3445
  reasonixResult.bucketsQueued +
3446
+ museResult.bucketsQueued +
3406
3447
  grokResult.bucketsQueued +
3407
3448
  copilotResult.bucketsQueued +
3408
3449
  lmstudioResult.bucketsQueued +
@@ -3434,6 +3475,7 @@ async function cmdSync(argv, context = {}) {
3434
3475
  !codexColdAuditDue &&
3435
3476
  !codexFallbackRetryRan &&
3436
3477
  !grokHookSignalConsumed &&
3478
+ !cursors.migrations?.[KIMI_MODEL_REPAIR_KEY]?.pendingCompaction &&
3437
3479
  !opts.repairGrok;
3438
3480
 
3439
3481
  if (syncDiagnostics) {
@@ -3458,6 +3500,12 @@ async function cmdSync(argv, context = {}) {
3458
3500
  deferredCodexAuditSyncs + 1,
3459
3501
  );
3460
3502
  }
3503
+ if (cursors.migrations?.[KIMI_MODEL_REPAIR_KEY]?.pendingCompaction) {
3504
+ const state = (await readJson(queueStatePath)) || { offset: 0 };
3505
+ await compactPendingQueue({ queuePath, offset: Number(state.offset || 0), minPendingBytes: 0 });
3506
+ cursors.migrations[KIMI_MODEL_REPAIR_KEY].pendingCompaction = false;
3507
+ await cursorStore.commit(cursors);
3508
+ }
3461
3509
  if (grokHookSignalConsumed && grokHookSignalPath) {
3462
3510
  await fs.unlink(grokHookSignalPath).catch(() => {});
3463
3511
  }
@@ -3490,6 +3538,7 @@ async function cmdSync(argv, context = {}) {
3490
3538
  const runtime = Object.hasOwn(process.env, "TOKENTRACKER_LOCAL_SYNC_DEVICE_TOKEN")
3491
3539
  ? { ...resolvedRuntime, deviceToken: resolvedRuntime.configurationError ? null : process.env.TOKENTRACKER_LOCAL_SYNC_DEVICE_TOKEN }
3492
3540
  : resolvedRuntime;
3541
+ cloudResetRuntime = runtime;
3493
3542
 
3494
3543
  let uploadResult = { inserted: 0, skipped: 0 };
3495
3544
  let uploadAttempted = false;
@@ -3658,6 +3707,12 @@ async function cmdSync(argv, context = {}) {
3658
3707
  // and can keep auto retry alive even after cloud sync has drained.
3659
3708
  const pendingBytes = Math.max(0, queueSize - Number(afterState.offset || 0));
3660
3709
 
3710
+ if (pendingBytes === 0 && canUpload() && runtime.deviceToken) {
3711
+ await finishCloudDeviceUsageReset({ trackerDir, ownerId: process.env.TOKENTRACKER_CLOUD_OWNER_ID,
3712
+ baseUrl: runtime.baseUrl, anonKey: runtime.anonKey, deviceToken: runtime.deviceToken,
3713
+ deviceId: process.env.TOKENTRACKER_CLOUD_DEVICE_ID });
3714
+ }
3715
+
3661
3716
  if (pendingBytes <= 0 || !canUpload()) {
3662
3717
  await clearAutoRetry(trackerDir);
3663
3718
  } else if (opts.auto && uploadAttempted && !opts.publishAccount) {
@@ -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
- let fd;
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
- module.exports = { createCloudDeviceTokenStore };
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
+ };
@@ -0,0 +1,115 @@
1
+ const fs = require("node:fs");
2
+ const fsp = require("node:fs/promises");
3
+ const path = require("node:path");
4
+ const crypto = require("node:crypto");
5
+ const { openLock, writeFileAtomic } = require("./fs");
6
+ const { functionUrlFor, fetchFunctionResponse } = require("./function-url");
7
+
8
+ const MARKER = "cloud-usage-reset.json";
9
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
10
+ const failure = (code, status = 409) => Object.assign(new Error(code), { code, status });
11
+ const sameBase = (a, b) => String(a).replace(/\/$/, "") === String(b).replace(/\/$/, "");
12
+
13
+ function readCloudUsageReset(trackerDir) {
14
+ let raw;
15
+ try { raw = fs.readFileSync(path.join(trackerDir, MARKER), "utf8"); }
16
+ catch (error) { if (error.code === "ENOENT") return null; throw error; }
17
+ let value;
18
+ try { value = JSON.parse(raw); } catch { throw failure("cloud_usage_reset_invalid_state"); }
19
+ if (value?.version !== 1 || !UUID.test(value.operationId) || !UUID.test(value.deviceId) ||
20
+ !UUID.test(value.ownerId) || !/^https?:\/\//.test(value.baseUrl || "") ||
21
+ !["prepared", "uploading"].includes(value.phase)) throw failure("cloud_usage_reset_invalid_state");
22
+ return value;
23
+ }
24
+
25
+ function cloudUsageResetBlocksUpload(trackerDir, { ownerId, baseUrl, deviceId } = {}) {
26
+ try {
27
+ const marker = readCloudUsageReset(trackerDir);
28
+ return Boolean(marker && (marker.phase === "prepared" || marker.ownerId !== ownerId ||
29
+ !sameBase(marker.baseUrl, baseUrl) || (deviceId && marker.deviceId !== deviceId)));
30
+ }
31
+ catch { return true; }
32
+ }
33
+
34
+ async function writeMarker(trackerDir, marker) {
35
+ await writeFileAtomic(path.join(trackerDir, MARKER), JSON.stringify(marker) + "\n", { mode: 0o600 });
36
+ }
37
+
38
+ async function requestReset({ baseUrl, anonKey, authorization, body, fetchImpl = fetchFunctionResponse }) {
39
+ const response = await fetchImpl(functionUrlFor(baseUrl, "tokentracker-device-usage-reset"), {
40
+ method: "POST",
41
+ headers: { "Content-Type": "application/json", Accept: "application/json", Authorization: `Bearer ${authorization}`,
42
+ ...(anonKey ? { apikey: anonKey } : {}) },
43
+ signal: AbortSignal.timeout(60_000),
44
+ body: JSON.stringify(body),
45
+ });
46
+ const data = await response.json().catch(() => ({}));
47
+ if (!response.ok || data.ok !== true) throw failure(data.code || "cloud_usage_reset_failed", response.status || 502);
48
+ if (data.operation_id !== body.operation_id) throw failure("cloud_usage_reset_invalid_response", 502);
49
+ return data;
50
+ }
51
+
52
+ // Called only after the local bridge has bound the JWT to its current device.
53
+ // The marker precedes the remote mutation: an interrupted request must retry the
54
+ // same operation, never clear already-replayed history a second time.
55
+ async function resetCloudDeviceUsage({ trackerDir, ownerId, deviceId, baseUrl, anonKey, accessToken,
56
+ isCurrent = () => true, fetchImpl }) {
57
+ if (!UUID.test(ownerId) || !UUID.test(deviceId) || !accessToken) throw failure("auth_required", 401);
58
+ const lock = await openLock(path.join(trackerDir, "sync.lock"), { quietIfLocked: true });
59
+ if (!lock) throw failure("cloud_usage_reset_sync_busy");
60
+ try {
61
+ if (!isCurrent()) throw failure("auth_session_changed");
62
+ let marker = readCloudUsageReset(trackerDir);
63
+ const newOperation = !marker;
64
+ if (marker && (marker.ownerId !== ownerId || marker.deviceId !== deviceId || !sameBase(marker.baseUrl, baseUrl))) {
65
+ throw failure("cloud_usage_reset_owner_changed");
66
+ }
67
+ if (marker?.phase === "uploading") return { ok: true, operation_id: marker.operationId, status: "uploading" };
68
+ if (!marker) {
69
+ marker = { version: 1, operationId: crypto.randomUUID(), ownerId, deviceId, baseUrl, phase: "prepared" };
70
+ await writeMarker(trackerDir, marker);
71
+ }
72
+ if (!isCurrent()) throw failure("auth_session_changed");
73
+ const result = await requestReset({ baseUrl, anonKey, authorization: accessToken, fetchImpl,
74
+ body: { action: "reset", device_id: deviceId, operation_id: marker.operationId } }).catch(async error => {
75
+ // A definitive first-request rejection did not erase anything. Unknown
76
+ // outcomes and retries retain their operation so they cannot erase twice.
77
+ if (newOperation && [400, 401, 403, 404, 409, 422].includes(error.status)) {
78
+ await fsp.unlink(path.join(trackerDir, MARKER));
79
+ }
80
+ throw error;
81
+ });
82
+ if (result.device_id !== deviceId || !["reset", "complete"].includes(result.status)) {
83
+ throw failure("cloud_usage_reset_invalid_response", 502);
84
+ }
85
+ if (!isCurrent()) throw failure("auth_session_changed");
86
+ await writeFileAtomic(path.join(trackerDir, "queue.state.json"),
87
+ JSON.stringify({ offset: 0, updatedAt: new Date().toISOString() }) + "\n", { mode: 0o600 });
88
+ await fsp.unlink(path.join(trackerDir, "upload.throttle.json")).catch(error => { if (error.code !== "ENOENT") throw error; });
89
+ marker.phase = "uploading";
90
+ await writeMarker(trackerDir, marker);
91
+ return { ...result, status: "uploading" };
92
+ } finally { await lock.release(); }
93
+ }
94
+
95
+ // sync owns sync.lock here. Only its fully acknowledged queue can finish the
96
+ // operation; a partial batch/checkpoint or another account leaves it pending.
97
+ async function finishCloudDeviceUsageReset({ trackerDir, ownerId, deviceId, baseUrl, anonKey, deviceToken, fetchImpl }) {
98
+ const marker = readCloudUsageReset(trackerDir);
99
+ if (!marker || marker.phase !== "uploading" || marker.ownerId !== ownerId || (deviceId && marker.deviceId !== deviceId) || !sameBase(marker.baseUrl, baseUrl)) return false;
100
+ if (!deviceToken) return false;
101
+ const queuePath = path.join(trackerDir, "queue.jsonl");
102
+ const size = await fsp.stat(queuePath).then(stat => stat.size).catch(error => { if (error.code === "ENOENT") return 0; throw error; });
103
+ let offset;
104
+ try { offset = JSON.parse(await fsp.readFile(path.join(trackerDir, "queue.state.json"), "utf8")).offset; }
105
+ catch { throw failure("cloud_usage_reset_invalid_offset"); }
106
+ if (!Number.isSafeInteger(offset) || offset < 0 || offset > size) throw failure("cloud_usage_reset_invalid_offset");
107
+ if (offset !== size) return false;
108
+ const result = await requestReset({ baseUrl, anonKey, authorization: deviceToken, fetchImpl,
109
+ body: { action: "refresh", operation_id: marker.operationId } });
110
+ if (result.status !== "complete" || result.device_id !== marker.deviceId) throw failure("cloud_usage_reset_invalid_response", 502);
111
+ await fsp.unlink(path.join(trackerDir, MARKER));
112
+ return true;
113
+ }
114
+
115
+ module.exports = { readCloudUsageReset, cloudUsageResetBlocksUpload, resetCloudDeviceUsage, finishCloudDeviceUsageReset };
@@ -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.
@@ -228,7 +229,7 @@ async function collectTrackerDiagnostics({
228
229
  ? { wsl_mode: wsl.getWslMode(process.env), wsl_installs: kiroWslInstalls }
229
230
  : {}),
230
231
  cli_approximation:
231
- "Kiro CLI does not persist explicit token counts (billing is credit-based on Bedrock). Tokens are approximated at 4 chars/token from user prompt chars and assistant response chars. Source rows that came through this path have model='kiro-cli-agent' when the underlying model is unknown (auto-routing); known Bedrock ARNs canonicalize to their short name (e.g. claude-sonnet-4).",
232
+ "When Kiro CLI does not report token counts, tokens are estimated at ~4 chars/token from new user messages, tool outputs and assistant text. The estimate does not measure re-sent history, system context or cache usage, and can substantially undercount tool-heavy requests. contextUsage percentages are not converted to tokens because their denominator and request correspondence are not established. Dollar amounts use model rates, not Kiro credit charges; recorded usage_summary credits remain separate. Source rows use model='kiro-cli-agent' when the underlying model is unknown; known Bedrock ARNs canonicalize to their short name (e.g. claude-sonnet-4).",
232
233
  merge_policy:
233
234
  "Kiro IDE and Kiro CLI both emit source='kiro' in queue.jsonl so token, cost, heatmap, and leaderboard aggregations merge transparently. Use this block to distinguish sub-path contributions.",
234
235
  },
@@ -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?.deviceToken ? "set" : "unset",
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
  },