tokentracker-cli 0.77.1 → 0.78.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.
- package/README.de.md +24 -3
- package/README.ja.md +3 -3
- package/README.ko.md +3 -3
- package/README.md +24 -3
- package/README.zh-CN.md +3 -3
- package/dashboard/dist/assets/ActivityHeatmap-5352XxLR.js +42 -0
- package/dashboard/dist/assets/{Card-DP2HT77t.js → Card-Ca_hYHhx.js} +1 -1
- package/dashboard/dist/assets/{ClawdAnimated-ScYRJSG0.js → ClawdAnimated-DSgOS5ND.js} +1 -1
- package/dashboard/dist/assets/{CommunityStatsModal-CU46JMkg.js → CommunityStatsModal-o8uQVQxu.js} +1 -1
- package/dashboard/dist/assets/ConfirmModal-D1hi9XUf.js +1 -0
- package/dashboard/dist/assets/Controls-CwnKP56V.js +1 -0
- package/dashboard/dist/assets/DashboardPage-CDv0TIOL.js +19 -0
- package/dashboard/dist/assets/{DevicePage-BL9ew9-m.js → DevicePage-BlfIHcZX.js} +1 -1
- package/dashboard/dist/assets/DialogClose-CismfYwe.js +1 -0
- package/dashboard/dist/assets/DialogDescription-DWKp1yez.js +1 -0
- package/dashboard/dist/assets/{DialogTitle-Oqnn_dIL.js → DialogTitle-DuuTVbUb.js} +1 -1
- package/dashboard/dist/assets/{FadeIn-CFLwnHqt.js → FadeIn-DpnitRKo.js} +1 -1
- package/dashboard/dist/assets/{HeaderGithubStar-B397ELF4.js → HeaderGithubStar-D6zy-ADl.js} +1 -1
- package/dashboard/dist/assets/{IpCheckPage-CamsHe6o.js → IpCheckPage-yUNp0VNe.js} +1 -1
- package/dashboard/dist/assets/LandingPage-BvmpAaVn.js +4314 -0
- package/dashboard/dist/assets/LeaderboardAvatar-2WTIeXye.js +1 -0
- package/dashboard/dist/assets/LeaderboardPage-Bq3-VO7w.js +2 -0
- package/dashboard/dist/assets/{LeaderboardProfileModal-BIe6gBNu.js → LeaderboardProfileModal-DH0EEK6q.js} +3 -3
- package/dashboard/dist/assets/{LeaderboardProfilePage-DeVBEYtg.js → LeaderboardProfilePage-uJAng2JE.js} +3 -3
- package/dashboard/dist/assets/{LimitsPage-6I5EU7qe.js → LimitsPage-D8UohgJm.js} +2 -2
- package/dashboard/dist/assets/{LocalOnlyNotice-AyYKZloH.js → LocalOnlyNotice-Dv_BnDVV.js} +1 -1
- package/dashboard/dist/assets/{LoginPage-D8smF1gU.js → LoginPage-D6b6DZU3.js} +1 -1
- package/dashboard/dist/assets/PetPage-DfpBkuCa.js +1 -0
- package/dashboard/dist/assets/{PopoverPopup-DRWhz-bY.js → PopoverPopup-CjzdZn-9.js} +1 -1
- package/dashboard/dist/assets/{ResetPasswordPage-CzSqJfuA.js → ResetPasswordPage-BnOCFkwe.js} +1 -1
- package/dashboard/dist/assets/Select-CHtQAiLD.js +1 -0
- package/dashboard/dist/assets/{SelectItemText-DEYadcIK.js → SelectItemText-Vjqvf8wO.js} +1 -1
- package/dashboard/dist/assets/SettingsPage-B-iHGL4q.js +1 -0
- package/dashboard/dist/assets/SkillsPage-DtG2aV-q.js +1 -0
- package/dashboard/dist/assets/WidgetsPage-4kqTtWfK.js +1 -0
- package/dashboard/dist/assets/{WrappedPage-BuP9KXqF.js → WrappedPage-DMMRpani.js} +1 -1
- package/dashboard/dist/assets/agent-logos-D0vYkEpX.js +1 -0
- package/dashboard/dist/assets/{arrow-up-right-cFMBPEVS.js → arrow-up-right-BAQYGZkR.js} +1 -1
- package/dashboard/dist/assets/check-C3RPBZiS.js +1 -0
- package/dashboard/dist/assets/{copy-DYx8X3ZO.js → copy-gG_BLBs8.js} +1 -1
- package/dashboard/dist/assets/{download-B-hXZWKj.js → download-BQOcg3gT.js} +1 -1
- package/dashboard/dist/assets/{format-tokens-CngV51wN.js → format-tokens-CGK6lQAf.js} +1 -1
- package/dashboard/dist/assets/{info-qVF2hV50.js → info-C_BrDrcq.js} +1 -1
- package/dashboard/dist/assets/{link-2-DR-yGZFS.js → link-2-DFwCBbIZ.js} +1 -1
- package/dashboard/dist/assets/{loader-circle-0k9uueb5.js → loader-circle-BMFI_BJ8.js} +1 -1
- package/dashboard/dist/assets/{main-B8lT0e78.css → main-Dy8Y_qst.css} +1 -1
- package/dashboard/dist/assets/main-w0hAaCsy.js +1190 -0
- package/dashboard/dist/assets/{trash-2-DpxBaV_1.js → trash-2-GeZ6IzgV.js} +1 -1
- package/dashboard/dist/assets/{use-community-stats-Cbij-V8j.js → use-community-stats-pC8cmVof.js} +1 -1
- package/dashboard/dist/assets/{use-limits-display-prefs-q0TuryM0.js → use-limits-display-prefs-DnFpPcA3.js} +1 -1
- package/dashboard/dist/assets/use-native-settings-CvcOSUhn.js +1 -0
- package/dashboard/dist/assets/{use-ordered-list-CH-J7c04.js → use-ordered-list-CbMroVZ8.js} +2 -2
- package/dashboard/dist/assets/{use-quality-per-dollar-pref-DKLmkwxe.js → use-quality-per-dollar-pref-Bn3Al6yX.js} +1 -1
- package/dashboard/dist/assets/{use-usage-limits-DrmF6I_t.js → use-usage-limits-D08q_Dr8.js} +1 -1
- package/dashboard/dist/assets/{useCurrency-DwygZqrs.js → useCurrency-h3kqF52v.js} +1 -1
- package/dashboard/dist/assets/{useScrollLock-DVCKuErg.js → useScrollLock-9au2731u.js} +1 -1
- package/dashboard/dist/index.html +2 -2
- package/dashboard/dist/share.html +2 -2
- package/package.json +1 -1
- package/src/commands/status.js +293 -30
- package/src/commands/sync.js +494 -104
- package/src/lib/install-resolver.js +1 -0
- package/src/lib/local-api.js +202 -56
- package/src/lib/pricing/seed-snapshot.json +1 -1
- package/src/lib/rollout.js +1329 -40
- package/dashboard/dist/assets/ActivityHeatmap-DTZh551Z.js +0 -42
- package/dashboard/dist/assets/ConfirmModal-BYvz0dzg.js +0 -1
- package/dashboard/dist/assets/Controls-DPElSq0S.js +0 -1
- package/dashboard/dist/assets/DashboardPage-CN0buIso.js +0 -19
- package/dashboard/dist/assets/DialogClose-cqXrG903.js +0 -1
- package/dashboard/dist/assets/DialogDescription-Bo0iWtYz.js +0 -1
- package/dashboard/dist/assets/LandingPage-D4ygTHwO.js +0 -4312
- package/dashboard/dist/assets/LeaderboardAvatar-B39rNGCV.js +0 -1
- package/dashboard/dist/assets/LeaderboardPage-BFUOxX6P.js +0 -2
- package/dashboard/dist/assets/PetPage-BlMYvJn2.js +0 -1
- package/dashboard/dist/assets/Select-Cb8n7kQO.js +0 -1
- package/dashboard/dist/assets/SettingsPage-DlHXcFdJ.js +0 -1
- package/dashboard/dist/assets/SkillsPage--Kcv1pxG.js +0 -1
- package/dashboard/dist/assets/WidgetsPage-DwtJ9CKU.js +0 -1
- package/dashboard/dist/assets/agent-logos-DbwDXgg1.js +0 -1
- package/dashboard/dist/assets/check-t_ltRp2A.js +0 -1
- package/dashboard/dist/assets/main-CU04bNYH.js +0 -1172
- package/dashboard/dist/assets/use-native-settings-BCzogs1L.js +0 -1
package/src/commands/status.js
CHANGED
|
@@ -60,22 +60,26 @@ const {
|
|
|
60
60
|
resolveGrokBuildSessions,
|
|
61
61
|
resolveHermesPath,
|
|
62
62
|
resolveHermesDbPath,
|
|
63
|
+
resolveCopilotSessionStorePaths,
|
|
64
|
+
describeCopilotSessionStoreDb,
|
|
63
65
|
resolveCopilotAppDbPath,
|
|
64
66
|
resolveCopilotAppDbPaths,
|
|
65
67
|
probeWslDistros,
|
|
66
68
|
} = require("../lib/rollout");
|
|
67
69
|
const wsl = require("../lib/wsl-probe");
|
|
68
|
-
const { getWslMode, isInvalidWslMode, shouldProbeWsl } = wsl;
|
|
70
|
+
const { getWslMode, isInvalidWslMode, shouldProbeWsl, discoverWslHome } = wsl;
|
|
69
71
|
const { resolveInstallPaths } = require("../lib/install-resolver");
|
|
70
72
|
const { probeGrokHookState, resolveGrokHome } = require("../lib/grok-hook");
|
|
71
73
|
|
|
72
74
|
function formatResolvedPaths(paths, filename) {
|
|
73
75
|
const active = [];
|
|
74
76
|
if (paths.native) {
|
|
75
|
-
|
|
77
|
+
const file = filename ? path.join(paths.native, filename) : paths.native;
|
|
78
|
+
try { if (fssync.existsSync(file)) active.push(`native: ${file}`); } catch (_e) {}
|
|
76
79
|
}
|
|
77
80
|
if (paths.wsl) {
|
|
78
|
-
|
|
81
|
+
const file = filename ? path.join(paths.wsl, filename) : paths.wsl;
|
|
82
|
+
try { if (fssync.existsSync(file)) active.push(`WSL: ${file}`); } catch (_e) {}
|
|
79
83
|
}
|
|
80
84
|
return active;
|
|
81
85
|
}
|
|
@@ -105,11 +109,11 @@ async function cmdStatus(argv = []) {
|
|
|
105
109
|
const codeConfigPath = path.join(codeHome, "config.toml");
|
|
106
110
|
const claudeSettingsPath = path.join(home, ".claude", "settings.json");
|
|
107
111
|
const codebuddySettingsPath = path.join(
|
|
108
|
-
process.env
|
|
112
|
+
resolveCodebuddyHome(process.env) || path.join(home, ".codebuddy"),
|
|
109
113
|
"settings.json",
|
|
110
114
|
);
|
|
111
115
|
const workbuddySettingsPath = path.join(
|
|
112
|
-
process.env
|
|
116
|
+
resolveWorkbuddyHome(process.env) || path.join(home, ".workbuddy"),
|
|
113
117
|
"settings.json",
|
|
114
118
|
);
|
|
115
119
|
const geminiConfigDir = resolveGeminiConfigDir({ home, env: process.env });
|
|
@@ -224,7 +228,7 @@ async function cmdStatus(argv = []) {
|
|
|
224
228
|
// CodeBuddy — passive scan only (no hooks). Surface the file count so
|
|
225
229
|
// operators can confirm JSONL sessions and extension logs are discovered.
|
|
226
230
|
const codebuddyHome = resolveCodebuddyHome(process.env);
|
|
227
|
-
const codebuddyInstalled = fssync.existsSync(codebuddyHome);
|
|
231
|
+
const codebuddyInstalled = Boolean(codebuddyHome && fssync.existsSync(codebuddyHome));
|
|
228
232
|
const codebuddyFiles = codebuddyInstalled
|
|
229
233
|
? resolveCodebuddyProjectFiles(process.env)
|
|
230
234
|
: [];
|
|
@@ -232,7 +236,7 @@ async function cmdStatus(argv = []) {
|
|
|
232
236
|
// WorkBuddy — passive scan (sibling Claude-Code fork). Surface both the
|
|
233
237
|
// recursive JSONL count and SQLite fallback so operators can confirm coverage.
|
|
234
238
|
const workbuddyHome = resolveWorkbuddyHome(process.env);
|
|
235
|
-
const workbuddyInstalled = fssync.existsSync(workbuddyHome);
|
|
239
|
+
const workbuddyInstalled = Boolean(workbuddyHome && fssync.existsSync(workbuddyHome));
|
|
236
240
|
const workbuddyFiles = workbuddyInstalled
|
|
237
241
|
? resolveWorkbuddyProjectFiles(process.env)
|
|
238
242
|
: [];
|
|
@@ -254,7 +258,7 @@ async function cmdStatus(argv = []) {
|
|
|
254
258
|
|
|
255
259
|
// Craft Agents — passive scan only (no hooks).
|
|
256
260
|
const craftConfigDir = resolveCraftConfigDir(process.env);
|
|
257
|
-
const craftInstalled = fssync.existsSync(craftConfigDir);
|
|
261
|
+
const craftInstalled = Boolean(craftConfigDir && fssync.existsSync(craftConfigDir));
|
|
258
262
|
const craftFiles = craftInstalled ? resolveCraftSessionFiles(process.env) : [];
|
|
259
263
|
|
|
260
264
|
// Kilo CLI (kilo.ai @kilocode/plugin) — passive scan of kilo.db.
|
|
@@ -297,6 +301,87 @@ async function cmdStatus(argv = []) {
|
|
|
297
301
|
const zcodeInstalled = zcodeActive.length > 0;
|
|
298
302
|
const zcodeDbPath = zcodeActive.join(" | ");
|
|
299
303
|
|
|
304
|
+
// OpenCode (JSON files + SQLite DB) — passive scan of storage/message/ and opencode.db.
|
|
305
|
+
const opencodeStorageNativeValue = process.env.OPENCODE_HOME || path.join(xdgDataHome, "opencode");
|
|
306
|
+
const wslOpencodeStorageDir = process.platform === "win32" && shouldProbeWsl(process.env)
|
|
307
|
+
? discoverWslHome(".local/share/opencode")
|
|
308
|
+
: null;
|
|
309
|
+
const opencodeStoragePaths = resolveInstallPaths({
|
|
310
|
+
nativeValue: opencodeStorageNativeValue,
|
|
311
|
+
wslValue: wslOpencodeStorageDir,
|
|
312
|
+
});
|
|
313
|
+
const opencodeStorageActive = formatResolvedPaths(opencodeStoragePaths);
|
|
314
|
+
|
|
315
|
+
const opencodeDbNativeValue = process.env.OPENCODE_HOME || path.join(xdgDataHome, "opencode");
|
|
316
|
+
const wslOpencodeDbDir = process.platform === "win32" && shouldProbeWsl(process.env)
|
|
317
|
+
? discoverWslHome(".local/share/opencode")
|
|
318
|
+
: null;
|
|
319
|
+
const opencodeDbPaths = resolveInstallPaths({
|
|
320
|
+
nativeValue: opencodeDbNativeValue,
|
|
321
|
+
wslValue: wslOpencodeDbDir,
|
|
322
|
+
});
|
|
323
|
+
const opencodeDbActive = formatResolvedPaths(opencodeDbPaths, "opencode.db");
|
|
324
|
+
const opencodeInstalled = opencodeStorageActive.length > 0 || opencodeDbActive.length > 0;
|
|
325
|
+
|
|
326
|
+
// Every Code (passive sessions scan)
|
|
327
|
+
const codePaths = resolveInstallPaths({
|
|
328
|
+
nativeValue: process.env.CODE_HOME || path.join(home, ".code"),
|
|
329
|
+
wslDir: ".code",
|
|
330
|
+
});
|
|
331
|
+
const codeActive = formatResolvedPaths(codePaths, "sessions");
|
|
332
|
+
const codeInstalled = codeActive.length > 0;
|
|
333
|
+
|
|
334
|
+
// Gemini CLI & Antigravity (shared home)
|
|
335
|
+
const geminiPaths = resolveInstallPaths({
|
|
336
|
+
nativeValue: process.env.GEMINI_HOME || path.join(home, ".gemini"),
|
|
337
|
+
wslDir: ".gemini",
|
|
338
|
+
});
|
|
339
|
+
const geminiActive = formatResolvedPaths(geminiPaths);
|
|
340
|
+
const geminiInstalledStatus = geminiActive.length > 0;
|
|
341
|
+
|
|
342
|
+
// Gemini CLI (passive sessions scan)
|
|
343
|
+
const geminiCliActive = formatResolvedPaths(geminiPaths, "tmp");
|
|
344
|
+
const geminiCliInstalled = geminiCliActive.length > 0;
|
|
345
|
+
|
|
346
|
+
// Antigravity (passive brains scan)
|
|
347
|
+
const antigravityActive = [];
|
|
348
|
+
if (geminiPaths.native) {
|
|
349
|
+
const dirs = [
|
|
350
|
+
path.join(geminiPaths.native, "antigravity", "brain"),
|
|
351
|
+
path.join(geminiPaths.native, "antigravity-ide", "brain"),
|
|
352
|
+
path.join(geminiPaths.native, "antigravity-cli", "brain"),
|
|
353
|
+
];
|
|
354
|
+
if (dirs.some(d => { try { return fssync.existsSync(d); } catch (_) { return false; } })) {
|
|
355
|
+
antigravityActive.push(`native: ${geminiPaths.native}`);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (geminiPaths.wsl) {
|
|
359
|
+
const dirs = [
|
|
360
|
+
path.join(geminiPaths.wsl, "antigravity", "brain"),
|
|
361
|
+
path.join(geminiPaths.wsl, "antigravity-ide", "brain"),
|
|
362
|
+
path.join(geminiPaths.wsl, "antigravity-cli", "brain"),
|
|
363
|
+
];
|
|
364
|
+
if (dirs.some(d => { try { return fssync.existsSync(d); } catch (_) { return false; } })) {
|
|
365
|
+
antigravityActive.push(`WSL: ${geminiPaths.wsl}`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
const antigravityInstalled = antigravityActive.length > 0;
|
|
369
|
+
|
|
370
|
+
// Codex CLI (passive sessions scan)
|
|
371
|
+
const codexPaths = resolveInstallPaths({
|
|
372
|
+
nativeValue: process.env.CODEX_HOME || path.join(home, ".codex"),
|
|
373
|
+
wslDir: ".codex",
|
|
374
|
+
});
|
|
375
|
+
const codexActive = formatResolvedPaths(codexPaths, "sessions");
|
|
376
|
+
const codexInstalledStatus = codexActive.length > 0;
|
|
377
|
+
|
|
378
|
+
// Kimi (passive sessions scan)
|
|
379
|
+
const kimiPaths = resolveInstallPaths({
|
|
380
|
+
nativeValue: path.join(home, ".kimi"),
|
|
381
|
+
wslDir: ".kimi",
|
|
382
|
+
});
|
|
383
|
+
const kimiActive = formatResolvedPaths(kimiPaths, "sessions");
|
|
384
|
+
|
|
300
385
|
// Kilo Code VS Code extension — passive scan of all VS Code-family
|
|
301
386
|
// globalStorage/kilocode.kilo-code/tasks/ ui_messages.json files.
|
|
302
387
|
const kilocodeTaskFiles = resolveKilocodeTaskFiles(process.env);
|
|
@@ -338,9 +423,15 @@ async function cmdStatus(argv = []) {
|
|
|
338
423
|
// install / WSL auto-discovery. Surface the resolved path (UNC included) and,
|
|
339
424
|
// on Windows, the discovered distros so WSL users can debug "why no sync"
|
|
340
425
|
// without guessing the right UNC alias (#87).
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
426
|
+
const hermesPaths = resolveInstallPaths({
|
|
427
|
+
nativeValue: process.env.TOKENTRACKER_HERMES_HOME || (process.platform === "win32" && typeof process.env.LOCALAPPDATA === "string"
|
|
428
|
+
? path.join(process.env.LOCALAPPDATA.trim(), "hermes")
|
|
429
|
+
: path.join(home, ".hermes")),
|
|
430
|
+
wslDir: ".hermes",
|
|
431
|
+
});
|
|
432
|
+
const hermesActive = formatResolvedPaths(hermesPaths, "state.db");
|
|
433
|
+
const hermesInstalled = hermesActive.length > 0;
|
|
434
|
+
const hermesPath = hermesActive.join(" | ");
|
|
344
435
|
const wslDistros = process.platform === "win32" && shouldProbeWsl(process.env) ? probeWslDistros() : [];
|
|
345
436
|
|
|
346
437
|
const copilotToken = readCopilotOauthToken({ home });
|
|
@@ -349,14 +440,123 @@ async function cmdStatus(argv = []) {
|
|
|
349
440
|
const copilotAppExistingPaths = copilotAppDbPaths.filter((p) => {
|
|
350
441
|
try { return fssync.existsSync(p); } catch (_e) { return false; }
|
|
351
442
|
});
|
|
443
|
+
const copilotStorePaths = Array.from(
|
|
444
|
+
new Set([
|
|
445
|
+
...resolveCopilotSessionStorePaths(process.env),
|
|
446
|
+
...Object.keys(cursors?.copilotStore?.dbs || {}),
|
|
447
|
+
]),
|
|
448
|
+
);
|
|
449
|
+
const copilotStoreExistingPaths = copilotStorePaths.filter((p) => {
|
|
450
|
+
try { return fssync.existsSync(p); } catch (_e) { return false; }
|
|
451
|
+
});
|
|
452
|
+
const copilotStoreDetails = [];
|
|
453
|
+
const copilotStoreInspectionErrors = [];
|
|
454
|
+
for (const storePath of copilotStoreExistingPaths) {
|
|
455
|
+
try {
|
|
456
|
+
copilotStoreDetails.push(describeCopilotSessionStoreDb(storePath));
|
|
457
|
+
} catch (err) {
|
|
458
|
+
copilotStoreInspectionErrors.push(
|
|
459
|
+
`${storePath}: ${err && err.message ? err.message : String(err)}`,
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
const copilotStoreCursor =
|
|
464
|
+
cursors?.copilotStore && typeof cursors.copilotStore === "object"
|
|
465
|
+
? cursors.copilotStore
|
|
466
|
+
: {};
|
|
467
|
+
const copilotStoreDbStates =
|
|
468
|
+
copilotStoreCursor.dbs && typeof copilotStoreCursor.dbs === "object"
|
|
469
|
+
? copilotStoreCursor.dbs
|
|
470
|
+
: {};
|
|
471
|
+
const copilotStatusPathKey = (dbPath) => {
|
|
472
|
+
const normalized = path.normalize(dbPath);
|
|
473
|
+
return process.platform === "win32" ? normalized.toLowerCase() : normalized;
|
|
474
|
+
};
|
|
475
|
+
const existingCopilotStoreKeys = new Set(
|
|
476
|
+
copilotStoreExistingPaths.map(copilotStatusPathKey),
|
|
477
|
+
);
|
|
478
|
+
const adoptedCopilotStores = Object.entries(copilotStoreDbStates).filter(
|
|
479
|
+
([, state]) => state?.adoptedAt,
|
|
480
|
+
);
|
|
481
|
+
const missingAdoptedCopilotStores = adoptedCopilotStores
|
|
482
|
+
.map(([dbPath]) => dbPath)
|
|
483
|
+
.filter((dbPath) => !existingCopilotStoreKeys.has(copilotStatusPathKey(dbPath)));
|
|
484
|
+
const copilotStoreDegradedReasons = [
|
|
485
|
+
...missingAdoptedCopilotStores.map(
|
|
486
|
+
(dbPath) => `canonical store unavailable: ${dbPath}`,
|
|
487
|
+
),
|
|
488
|
+
...copilotStoreInspectionErrors.map(
|
|
489
|
+
(message) => `store inspection failed: ${message}`,
|
|
490
|
+
),
|
|
491
|
+
...Object.entries(copilotStoreDbStates)
|
|
492
|
+
.filter(([, state]) => state?.lastError)
|
|
493
|
+
.map(([dbPath, state]) => `${dbPath}: ${state.lastError}`),
|
|
494
|
+
];
|
|
495
|
+
const malformedCopilotEvents = Object.values(copilotStoreDbStates).reduce(
|
|
496
|
+
(sum, state) => sum + Math.max(0, Number(state?.malformedEventCount) || 0),
|
|
497
|
+
0,
|
|
498
|
+
);
|
|
499
|
+
if (malformedCopilotEvents > 0) {
|
|
500
|
+
copilotStoreDegradedReasons.push(
|
|
501
|
+
`${malformedCopilotEvents} event${malformedCopilotEvents === 1 ? "" : "s"} lack a valid timestamp`,
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
const copilotResetGapEvents = Object.values(copilotStoreDbStates).reduce(
|
|
505
|
+
(sum, state) => sum + Math.max(0, Number(state?.resetGapEventCount) || 0),
|
|
506
|
+
0,
|
|
507
|
+
);
|
|
508
|
+
if (copilotResetGapEvents > 0) {
|
|
509
|
+
copilotStoreDegradedReasons.push(
|
|
510
|
+
`${copilotResetGapEvents} event${copilotResetGapEvents === 1 ? "" : "s"} were baselined during a legacy cursor/reset race`,
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
const copilotStoreCanonical =
|
|
514
|
+
copilotStoreCursor.active === true && adoptedCopilotStores.length > 0;
|
|
515
|
+
const copilotStoreDegraded = copilotStoreDegradedReasons.length > 0;
|
|
516
|
+
const copilotStoreStatus = {
|
|
517
|
+
store_paths: copilotStoreExistingPaths,
|
|
518
|
+
store_path: copilotStorePaths[0] || null,
|
|
519
|
+
store_has_file: copilotStoreExistingPaths.length > 0,
|
|
520
|
+
store_details: copilotStoreDetails.map((detail) => ({
|
|
521
|
+
path: detail.path,
|
|
522
|
+
schema_version: detail.schemaVersion,
|
|
523
|
+
event_count: detail.eventCount,
|
|
524
|
+
last_event_id: detail.lastEventId,
|
|
525
|
+
last_event_at: detail.lastEventAt,
|
|
526
|
+
})),
|
|
527
|
+
canonical: copilotStoreCanonical,
|
|
528
|
+
source_mode: copilotStoreCanonical
|
|
529
|
+
? copilotStoreDegraded
|
|
530
|
+
? "canonical-degraded"
|
|
531
|
+
: "canonical"
|
|
532
|
+
: copilotStoreExistingPaths.length > 0
|
|
533
|
+
? "awaiting-adoption"
|
|
534
|
+
: "legacy",
|
|
535
|
+
precision: copilotStoreCanonical
|
|
536
|
+
? "exact-post-adoption; aggregate-pre-adoption"
|
|
537
|
+
: "aggregate",
|
|
538
|
+
coverage: copilotStoreCanonical
|
|
539
|
+
? "per-request-post-adoption; legacy-aggregate-pre-adoption"
|
|
540
|
+
: "legacy-aggregate",
|
|
541
|
+
malformed_event_count: malformedCopilotEvents,
|
|
542
|
+
reset_gap_event_count: copilotResetGapEvents,
|
|
543
|
+
degraded: copilotStoreDegraded,
|
|
544
|
+
degraded_reasons: copilotStoreDegradedReasons,
|
|
545
|
+
recommended_action: copilotStoreDegraded
|
|
546
|
+
? "Restore or repair the Copilot session store, then run `tokentracker sync`."
|
|
547
|
+
: null,
|
|
548
|
+
};
|
|
549
|
+
const copilotAppStatus = {
|
|
550
|
+
app_db_path: resolveCopilotAppDbPath(process.env),
|
|
551
|
+
app_db_paths: copilotAppExistingPaths,
|
|
552
|
+
app_db_has_file: copilotAppExistingPaths.length > 0,
|
|
553
|
+
app_db_mode: copilotStoreCanonical ? "observe-only" : "legacy-writer",
|
|
554
|
+
};
|
|
352
555
|
const copilotLines = formatCopilotLines({
|
|
353
556
|
token: copilotToken,
|
|
354
557
|
otel: copilotOtel,
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
app_db_paths: copilotAppExistingPaths,
|
|
358
|
-
app_db_has_file: copilotAppExistingPaths.length > 0,
|
|
359
|
-
},
|
|
558
|
+
sessionStore: copilotStoreStatus,
|
|
559
|
+
appDb: copilotAppStatus,
|
|
360
560
|
});
|
|
361
561
|
|
|
362
562
|
// Detect passive-mode providers exactly once — both the JSON/light path
|
|
@@ -473,9 +673,8 @@ async function cmdStatus(argv = []) {
|
|
|
473
673
|
otel_has_files: Boolean(copilotOtel.otel_has_files),
|
|
474
674
|
otel_path: copilotOtel.otel_path || null,
|
|
475
675
|
otel_enabled: Boolean(copilotOtel.otel_enabled),
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
app_db_paths: copilotAppExistingPaths,
|
|
676
|
+
...copilotStoreStatus,
|
|
677
|
+
...copilotAppStatus,
|
|
479
678
|
},
|
|
480
679
|
passive_mode: {
|
|
481
680
|
active: isPassiveModeActive(passiveProviders),
|
|
@@ -524,7 +723,7 @@ async function cmdStatus(argv = []) {
|
|
|
524
723
|
`- OpenClaw session plugin conversation access: ${openclawSessionPluginState?.conversationAccess ? "set" : "unset"}`,
|
|
525
724
|
`- OpenClaw hook (legacy): ${openclawHookState?.configured ? "set" : "unset"}`,
|
|
526
725
|
kimiInstalled || kimiCodeInstalled
|
|
527
|
-
? `- Kimi Code: passive reader (${kimiWireFiles.length + kimiCodeWireFiles.length} wire.jsonl file${(kimiWireFiles.length + kimiCodeWireFiles.length) !== 1 ? "s" : ""} found)`
|
|
726
|
+
? `- Kimi Code: passive reader (${kimiWireFiles.length + kimiCodeWireFiles.length} wire.jsonl file${(kimiWireFiles.length + kimiCodeWireFiles.length) !== 1 ? "s" : ""} found, directories: ${kimiActive.join(" | ") || "none"})`
|
|
528
727
|
: null,
|
|
529
728
|
kiroCliInstalled
|
|
530
729
|
? `- Kiro CLI: SQLite data.sqlite3 found (tokens approximated from char lengths, merged under 'kiro' source)`
|
|
@@ -553,6 +752,24 @@ async function cmdStatus(argv = []) {
|
|
|
553
752
|
zcodeInstalled
|
|
554
753
|
? `- ZCode: passive reader (${zcodeDbPath})`
|
|
555
754
|
: null,
|
|
755
|
+
opencodeInstalled
|
|
756
|
+
? `- OpenCode: passive reader (storage: ${opencodeStorageActive.join(" | ") || "not found"}, DB: ${opencodeDbActive.join(" | ") || "not found"})`
|
|
757
|
+
: null,
|
|
758
|
+
codeInstalled
|
|
759
|
+
? `- Every Code: sessions found (${codeActive.join(" | ")})`
|
|
760
|
+
: null,
|
|
761
|
+
geminiCliInstalled
|
|
762
|
+
? `- Gemini CLI: sessions found (${geminiCliActive.join(" | ")})`
|
|
763
|
+
: null,
|
|
764
|
+
antigravityInstalled
|
|
765
|
+
? `- Antigravity: brain found (${antigravityActive.join(" | ")})`
|
|
766
|
+
: null,
|
|
767
|
+
(!geminiCliInstalled && !antigravityInstalled && geminiInstalledStatus)
|
|
768
|
+
? `- Gemini CLI / Antigravity: home found (${geminiActive.join(" | ")})`
|
|
769
|
+
: null,
|
|
770
|
+
codexInstalledStatus
|
|
771
|
+
? `- Codex CLI: sessions found (${codexActive.join(" | ")})`
|
|
772
|
+
: null,
|
|
556
773
|
kilocodeInstalled
|
|
557
774
|
? `- Kilo Code (VS Code extension): passive reader (${kilocodeTaskFiles.length} task${kilocodeTaskFiles.length !== 1 ? "s" : ""} across ${new Set(kilocodeTaskFiles.map((t) => t.ide)).size} IDE${new Set(kilocodeTaskFiles.map((t) => t.ide)).size !== 1 ? "s" : ""})`
|
|
558
775
|
: null,
|
|
@@ -607,13 +824,30 @@ async function cmdStatus(argv = []) {
|
|
|
607
824
|
);
|
|
608
825
|
}
|
|
609
826
|
|
|
610
|
-
function
|
|
611
|
-
|
|
827
|
+
function formatCopilotStoreDetail(detail) {
|
|
828
|
+
return `${detail.path} (schema ${detail.schema_version ?? "?"}, ${detail.event_count ?? 0} events, last id ${detail.last_event_id ?? 0}${detail.last_event_at ? ` at ${detail.last_event_at}` : ""})`;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
function formatCopilotLines({ token, otel, sessionStore, appDb }) {
|
|
832
|
+
if (
|
|
833
|
+
!token &&
|
|
834
|
+
!otel.otel_has_files &&
|
|
835
|
+
!sessionStore?.store_has_file &&
|
|
836
|
+
!appDb?.app_db_has_file
|
|
837
|
+
) {
|
|
838
|
+
return [];
|
|
839
|
+
}
|
|
612
840
|
const limitsState = token
|
|
613
841
|
? "set (via GitHub OAuth)"
|
|
614
842
|
: "unset (no Copilot OAuth token found)";
|
|
843
|
+
const storeDetail = (sessionStore?.store_details || [])
|
|
844
|
+
.map(formatCopilotStoreDetail)
|
|
845
|
+
.join(", ");
|
|
846
|
+
const storeState = sessionStore?.store_has_file
|
|
847
|
+
? `${sessionStore.source_mode || "set"} (${storeDetail || (sessionStore.store_paths || []).join(", ")}; precision ${sessionStore.precision || "unknown"}; coverage ${sessionStore.coverage || "unknown"})`
|
|
848
|
+
: `not found (${sessionStore?.store_path || "unknown"})`;
|
|
615
849
|
const appDbState = appDb?.app_db_has_file
|
|
616
|
-
?
|
|
850
|
+
? `${appDb.app_db_mode || "set"} (${(appDb.app_db_paths || []).join(", ")})`
|
|
617
851
|
: `not found (${appDb?.app_db_path || "unknown"})`;
|
|
618
852
|
const usageState = otel.otel_has_files
|
|
619
853
|
? `set (${otel.otel_path || otel.otel_default_dir})`
|
|
@@ -622,12 +856,19 @@ function formatCopilotLines({ token, otel, appDb }) {
|
|
|
622
856
|
: "unset (OTEL export not enabled)";
|
|
623
857
|
const lines = [
|
|
624
858
|
`- GitHub Copilot limits: ${limitsState}`,
|
|
625
|
-
`- GitHub Copilot usage (App
|
|
626
|
-
`- GitHub Copilot usage (
|
|
859
|
+
`- GitHub Copilot usage (App/CLI store): ${storeState}`,
|
|
860
|
+
`- GitHub Copilot usage (App DB legacy baseline): ${appDbState}`,
|
|
861
|
+
`- GitHub Copilot usage (OTEL Chat/legacy CLI): ${usageState}`,
|
|
627
862
|
];
|
|
628
|
-
|
|
863
|
+
for (const reason of sessionStore?.degraded_reasons || []) {
|
|
864
|
+
lines.push(` Degraded: ${reason}`);
|
|
865
|
+
}
|
|
866
|
+
if (sessionStore?.recommended_action) {
|
|
867
|
+
lines.push(` Action: ${sessionStore.recommended_action}`);
|
|
868
|
+
}
|
|
869
|
+
if (!sessionStore?.store_has_file && !otel.otel_has_files) {
|
|
629
870
|
lines.push(
|
|
630
|
-
" To track Copilot CLI / Chat extension token usage, add to your shell profile:",
|
|
871
|
+
" To track older Copilot CLI / Chat extension token usage, add to your shell profile:",
|
|
631
872
|
" export COPILOT_OTEL_ENABLED=true",
|
|
632
873
|
" export COPILOT_OTEL_EXPORTER_TYPE=file",
|
|
633
874
|
` export COPILOT_OTEL_FILE_EXPORTER_PATH="${otel.otel_default_dir}/copilot-otel-$(date +%Y%m%d).jsonl"`,
|
|
@@ -745,22 +986,44 @@ function renderLightTable(summary) {
|
|
|
745
986
|
(summary.copilot.token_set ||
|
|
746
987
|
summary.copilot.otel_enabled ||
|
|
747
988
|
summary.copilot.otel_has_files ||
|
|
989
|
+
summary.copilot.store_has_file ||
|
|
748
990
|
summary.copilot.app_db_has_file);
|
|
749
991
|
if (copilotDetected) {
|
|
750
992
|
push(
|
|
751
|
-
"Copilot App
|
|
993
|
+
"Copilot App/CLI store",
|
|
994
|
+
summary.copilot.store_has_file
|
|
995
|
+
? `${summary.copilot.source_mode || "set"}: ${
|
|
996
|
+
(summary.copilot.store_details || [])
|
|
997
|
+
.map(formatCopilotStoreDetail)
|
|
998
|
+
.join(", ") ||
|
|
999
|
+
(summary.copilot.store_paths || [summary.copilot.store_path])
|
|
1000
|
+
.filter(Boolean)
|
|
1001
|
+
.join(", ")
|
|
1002
|
+
}`
|
|
1003
|
+
: `not found (${summary.copilot.store_path || "unknown"})`,
|
|
1004
|
+
);
|
|
1005
|
+
push(
|
|
1006
|
+
"Copilot App DB legacy baseline",
|
|
752
1007
|
summary.copilot.app_db_has_file
|
|
753
|
-
? (summary.copilot.app_db_paths || [summary.copilot.app_db_path]).filter(Boolean).join(", ")
|
|
1008
|
+
? `${summary.copilot.app_db_mode || "set"}: ${(summary.copilot.app_db_paths || [summary.copilot.app_db_path]).filter(Boolean).join(", ")}`
|
|
754
1009
|
: `not found (${summary.copilot.app_db_path || "unknown"})`,
|
|
755
1010
|
);
|
|
756
1011
|
push(
|
|
757
|
-
"Copilot OTEL",
|
|
1012
|
+
"Copilot OTEL Chat/legacy CLI",
|
|
758
1013
|
summary.copilot.otel_has_files
|
|
759
1014
|
? summary.copilot.otel_path || "files found"
|
|
760
1015
|
: summary.copilot.otel_enabled
|
|
761
1016
|
? "enabled, no files"
|
|
762
1017
|
: "not enabled",
|
|
763
1018
|
);
|
|
1019
|
+
push("Copilot precision", summary.copilot.precision);
|
|
1020
|
+
push("Copilot coverage", summary.copilot.coverage);
|
|
1021
|
+
for (const reason of summary.copilot.degraded_reasons || []) {
|
|
1022
|
+
push("Copilot degraded", reason);
|
|
1023
|
+
}
|
|
1024
|
+
if (summary.copilot.recommended_action) {
|
|
1025
|
+
push("Copilot action", summary.copilot.recommended_action);
|
|
1026
|
+
}
|
|
764
1027
|
}
|
|
765
1028
|
|
|
766
1029
|
if (summary.passive_mode) {
|