tokentracker-cli 0.2.23 → 0.2.25

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.
@@ -107,7 +107,7 @@
107
107
  ]
108
108
  }
109
109
  </script>
110
- <script type="module" crossorigin src="/assets/main-BYPG1_bI.js"></script>
110
+ <script type="module" crossorigin src="/assets/main-DepLUlUX.js"></script>
111
111
  <link rel="stylesheet" crossorigin href="/assets/main-hwTpulbk.css">
112
112
  </head>
113
113
  <body>
@@ -51,7 +51,7 @@
51
51
  "description": "Shareable Token Tracker dashboard snapshot."
52
52
  }
53
53
  </script>
54
- <script type="module" crossorigin src="/assets/main-BYPG1_bI.js"></script>
54
+ <script type="module" crossorigin src="/assets/main-DepLUlUX.js"></script>
55
55
  <link rel="stylesheet" crossorigin href="/assets/main-hwTpulbk.css">
56
56
  </head>
57
57
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tokentracker-cli",
3
- "version": "0.2.23",
3
+ "version": "0.2.25",
4
4
  "description": "Token usage tracker for AI agent CLIs (Codex, Claude Code, Gemini, OpenCode, OpenClaw)",
5
5
  "main": "src/cli.js",
6
6
  "bin": {
@@ -166,7 +166,7 @@ async function cmdInit(argv) {
166
166
  let deviceId = setup.deviceId;
167
167
 
168
168
  // Cloud account linking — only when explicitly requested via env or flags
169
- const wantCloudLink = setup.pendingBrowserAuth && (opts.linkCode || process.env.VIBEUSAGE_DEVICE_TOKEN || process.env.VIBEUSAGE_ACCESS_TOKEN);
169
+ const wantCloudLink = setup.pendingBrowserAuth && (opts.linkCode || process.env.TOKENTRACKER_DEVICE_TOKEN || process.env.TOKENTRACKER_ACCESS_TOKEN);
170
170
 
171
171
  if (wantCloudLink) {
172
172
  const deviceName = opts.deviceName || os.hostname();
@@ -233,13 +233,9 @@ function renderLocalSuccess() {
233
233
  [
234
234
  "",
235
235
  `${BOLD}Setup complete!${RESET}`,
236
- DIVIDER,
237
- "",
238
- " View your dashboard:",
239
- ` ${CYAN}npx tokentracker${RESET}`,
240
236
  "",
241
- " Token data is collected automatically via hooks.",
242
- " Run the command above anytime to see your usage.",
237
+ " Token data will be collected automatically via hooks.",
238
+ " Launching dashboard...",
243
239
  "",
244
240
  ].join("\n"),
245
241
  );
@@ -762,8 +758,8 @@ const fallbackPkg = ${JSON.stringify(fallbackPkg)};
762
758
  const selfPath = path.resolve(__filename);
763
759
  const home = os.homedir();
764
760
  const debugLogPath = path.join(trackerDir, 'notify.debug.jsonl');
765
- const debugEnabled = ['1', 'true'].includes((process.env.VIBEUSAGE_NOTIFY_DEBUG || '').toLowerCase());
766
- const debugMaxBytesRaw = Number.parseInt(process.env.VIBEUSAGE_NOTIFY_DEBUG_MAX_BYTES || '', 10);
761
+ const debugEnabled = ['1', 'true'].includes((process.env.TOKENTRACKER_NOTIFY_DEBUG || '').toLowerCase());
762
+ const debugMaxBytesRaw = Number.parseInt(process.env.TOKENTRACKER_NOTIFY_DEBUG_MAX_BYTES || '', 10);
767
763
  const debugMaxBytes = Number.isFinite(debugMaxBytesRaw) && debugMaxBytesRaw > 0
768
764
  ? debugMaxBytesRaw
769
765
  : 1_000_000;
@@ -795,7 +791,7 @@ if (debugEnabled) {
795
791
  // Throttle spawn: at most once per 20 seconds.
796
792
  try {
797
793
  const throttlePath = path.join(trackerDir, 'sync.throttle');
798
- let deviceToken = process.env.VIBEUSAGE_DEVICE_TOKEN || null;
794
+ let deviceToken = process.env.TOKENTRACKER_DEVICE_TOKEN || null;
799
795
  if (!deviceToken) {
800
796
  try {
801
797
  const cfg = JSON.parse(fs.readFileSync(configPath, 'utf8'));
@@ -971,5 +967,5 @@ async function copyRuntimeDependencies({ from, to }) {
971
967
  }
972
968
 
973
969
  function isDebugEnabled() {
974
- return process.env.VIBEUSAGE_DEBUG === "1";
970
+ return process.env.TOKENTRACKER_DEBUG === "1";
975
971
  }
@@ -14,6 +14,18 @@ const DEFAULT_PORT = 7890;
14
14
  async function cmdServe(argv) {
15
15
  const opts = parseArgs(argv);
16
16
 
17
+ // 0. First-time setup: if tracker dir doesn't exist, run init first
18
+ const { trackerDir } = await resolveTrackerPaths();
19
+ if (!fssync.existsSync(path.join(trackerDir, "cursors.json"))) {
20
+ process.stdout.write("First time? Setting up Token Tracker...\n\n");
21
+ try {
22
+ const { cmdInit } = require("./init");
23
+ await cmdInit(["--yes"]);
24
+ } catch (e) {
25
+ process.stdout.write(`Init warning: ${e?.message || e}\n`);
26
+ }
27
+ }
28
+
17
29
  // 1. Optional sync
18
30
  if (opts.sync) {
19
31
  process.stdout.write("Syncing local data...\n");
@@ -486,26 +486,26 @@ function normalizeString(value) {
486
486
  function resolveOpenclawSignal({ home, env } = {}) {
487
487
  if (!env) return null;
488
488
 
489
- const agentId = normalizeString(env.VIBEUSAGE_OPENCLAW_AGENT_ID);
490
- const sessionId = normalizeString(env.VIBEUSAGE_OPENCLAW_PREV_SESSION_ID);
489
+ const agentId = normalizeString(env.TOKENTRACKER_OPENCLAW_AGENT_ID);
490
+ const sessionId = normalizeString(env.TOKENTRACKER_OPENCLAW_PREV_SESSION_ID);
491
491
  if (!agentId || !sessionId) return null;
492
492
 
493
493
  const openclawHome =
494
- normalizeString(env.VIBEUSAGE_OPENCLAW_HOME) || path.join(home || os.homedir(), ".openclaw");
494
+ normalizeString(env.TOKENTRACKER_OPENCLAW_HOME) || path.join(home || os.homedir(), ".openclaw");
495
495
  const sessionFile = path.join(openclawHome, "agents", agentId, "sessions", `${sessionId}.jsonl`);
496
496
 
497
497
  const prevTotals = {
498
- totalTokens: normalizeNonNegativeInt(env.VIBEUSAGE_OPENCLAW_PREV_TOTAL_TOKENS),
499
- inputTokens: normalizeNonNegativeInt(env.VIBEUSAGE_OPENCLAW_PREV_INPUT_TOKENS),
500
- outputTokens: normalizeNonNegativeInt(env.VIBEUSAGE_OPENCLAW_PREV_OUTPUT_TOKENS),
501
- model: normalizeString(env.VIBEUSAGE_OPENCLAW_PREV_MODEL),
502
- updatedAt: normalizeIsoOrEpoch(env.VIBEUSAGE_OPENCLAW_PREV_UPDATED_AT),
498
+ totalTokens: normalizeNonNegativeInt(env.TOKENTRACKER_OPENCLAW_PREV_TOTAL_TOKENS),
499
+ inputTokens: normalizeNonNegativeInt(env.TOKENTRACKER_OPENCLAW_PREV_INPUT_TOKENS),
500
+ outputTokens: normalizeNonNegativeInt(env.TOKENTRACKER_OPENCLAW_PREV_OUTPUT_TOKENS),
501
+ model: normalizeString(env.TOKENTRACKER_OPENCLAW_PREV_MODEL),
502
+ updatedAt: normalizeIsoOrEpoch(env.TOKENTRACKER_OPENCLAW_PREV_UPDATED_AT),
503
503
  };
504
504
 
505
505
  return {
506
506
  agentId,
507
507
  sessionId,
508
- sessionKey: normalizeString(env.VIBEUSAGE_OPENCLAW_SESSION_KEY),
508
+ sessionKey: normalizeString(env.TOKENTRACKER_OPENCLAW_SESSION_KEY),
509
509
  openclawHome,
510
510
  sessionFile,
511
511
  prevTotals,
@@ -1,6 +1,6 @@
1
1
  function stripDebugFlag(argv, env = process.env) {
2
2
  const filtered = Array.isArray(argv) ? argv.filter((arg) => arg !== "--debug") : [];
3
- const debugEnv = String(env?.VIBEUSAGE_DEBUG || "") === "1";
3
+ const debugEnv = String(env?.TOKENTRACKER_DEBUG || "") === "1";
4
4
  return { argv: filtered, debug: filtered.length !== (argv || []).length || debugEnv };
5
5
  }
6
6
 
@@ -11,11 +11,11 @@ function loadInsforgeSdk() {
11
11
  }
12
12
 
13
13
  function getAnonKey({ env = process.env } = {}) {
14
- return env.VIBEUSAGE_INSFORGE_ANON_KEY || "";
14
+ return env.TOKENTRACKER_INSFORGE_ANON_KEY || "";
15
15
  }
16
16
 
17
17
  function getHttpTimeoutMs({ env = process.env } = {}) {
18
- const raw = readEnvValue(env, ["VIBEUSAGE_HTTP_TIMEOUT_MS"]);
18
+ const raw = readEnvValue(env, ["TOKENTRACKER_HTTP_TIMEOUT_MS"]);
19
19
  if (raw == null || raw === "") return 20_000;
20
20
  const n = Number(raw);
21
21
  if (!Number.isFinite(n)) return 20_000;
@@ -14,7 +14,7 @@ function resolveOpenclawHookPaths({ home = os.homedir(), trackerDir, env = proce
14
14
  normalizeString(env.OPENCLAW_CONFIG_PATH) || path.join(home, ".openclaw", "openclaw.json");
15
15
 
16
16
  const openclawHome =
17
- normalizeString(env.VIBEUSAGE_OPENCLAW_HOME) ||
17
+ normalizeString(env.TOKENTRACKER_OPENCLAW_HOME) ||
18
18
  normalizeString(env.OPENCLAW_STATE_DIR) ||
19
19
  path.join(home, ".openclaw");
20
20
 
@@ -324,21 +324,21 @@ function buildHookHandler({ trackerDir, packageName = "vibeusage", openclawHome
324
324
  `\n` +
325
325
  ` const env = {\n` +
326
326
  ` ...process.env,\n` +
327
- ` VIBEUSAGE_OPENCLAW_AGENT_ID: agentId,\n` +
328
- ` VIBEUSAGE_OPENCLAW_SESSION_KEY: sessionKey,\n` +
329
- ` VIBEUSAGE_OPENCLAW_PREV_SESSION_ID: sessionId,\n` +
330
- ` VIBEUSAGE_OPENCLAW_HOME: openclawHome\n` +
327
+ ` TOKENTRACKER_OPENCLAW_AGENT_ID: agentId,\n` +
328
+ ` TOKENTRACKER_OPENCLAW_SESSION_KEY: sessionKey,\n` +
329
+ ` TOKENTRACKER_OPENCLAW_PREV_SESSION_ID: sessionId,\n` +
330
+ ` TOKENTRACKER_OPENCLAW_HOME: openclawHome\n` +
331
331
  ` };\n` +
332
332
  ` const prevTotalTokens = toNonNegativeInt(sessionEntry && sessionEntry.totalTokens);\n` +
333
333
  ` const prevInputTokens = toNonNegativeInt(sessionEntry && sessionEntry.inputTokens);\n` +
334
334
  ` const prevOutputTokens = toNonNegativeInt(sessionEntry && sessionEntry.outputTokens);\n` +
335
335
  ` const prevModel = normalize(sessionEntry && sessionEntry.model);\n` +
336
336
  ` const prevUpdatedAt = toIso(sessionEntry && sessionEntry.updatedAt);\n` +
337
- ` if (prevTotalTokens != null) env.VIBEUSAGE_OPENCLAW_PREV_TOTAL_TOKENS = String(prevTotalTokens);\n` +
338
- ` if (prevInputTokens != null) env.VIBEUSAGE_OPENCLAW_PREV_INPUT_TOKENS = String(prevInputTokens);\n` +
339
- ` if (prevOutputTokens != null) env.VIBEUSAGE_OPENCLAW_PREV_OUTPUT_TOKENS = String(prevOutputTokens);\n` +
340
- ` if (prevModel) env.VIBEUSAGE_OPENCLAW_PREV_MODEL = prevModel;\n` +
341
- ` if (prevUpdatedAt) env.VIBEUSAGE_OPENCLAW_PREV_UPDATED_AT = prevUpdatedAt;\n` +
337
+ ` if (prevTotalTokens != null) env.TOKENTRACKER_OPENCLAW_PREV_TOTAL_TOKENS = String(prevTotalTokens);\n` +
338
+ ` if (prevInputTokens != null) env.TOKENTRACKER_OPENCLAW_PREV_INPUT_TOKENS = String(prevInputTokens);\n` +
339
+ ` if (prevOutputTokens != null) env.TOKENTRACKER_OPENCLAW_PREV_OUTPUT_TOKENS = String(prevOutputTokens);\n` +
340
+ ` if (prevModel) env.TOKENTRACKER_OPENCLAW_PREV_MODEL = prevModel;\n` +
341
+ ` if (prevUpdatedAt) env.TOKENTRACKER_OPENCLAW_PREV_UPDATED_AT = prevUpdatedAt;\n` +
342
342
  `\n` +
343
343
  ` const hasLocalRuntime = fs.existsSync(trackerBinPath);\n` +
344
344
  ` const hasLocalDeps = fs.existsSync(depsMarkerPath);\n` +
@@ -18,7 +18,7 @@ function resolveOpenclawSessionPluginPaths({
18
18
  normalizeString(env.OPENCLAW_CONFIG_PATH) || path.join(home, ".openclaw", "openclaw.json");
19
19
 
20
20
  const openclawHome =
21
- normalizeString(env.VIBEUSAGE_OPENCLAW_HOME) ||
21
+ normalizeString(env.TOKENTRACKER_OPENCLAW_HOME) ||
22
22
  normalizeString(env.OPENCLAW_STATE_DIR) ||
23
23
  path.join(home, ".openclaw");
24
24
 
@@ -414,22 +414,22 @@ function buildSessionPluginIndex({ trackerDir, packageName = "vibeusage", opencl
414
414
  `\n` +
415
415
  `function buildSessionEnv({ agentId, sessionId, sessionKey, sessionEntry }) {\n` +
416
416
  ` const out = {\n` +
417
- ` VIBEUSAGE_OPENCLAW_AGENT_ID: agentId,\n` +
418
- ` VIBEUSAGE_OPENCLAW_PREV_SESSION_ID: sessionId,\n` +
419
- ` VIBEUSAGE_OPENCLAW_HOME: openclawHome\n` +
417
+ ` TOKENTRACKER_OPENCLAW_AGENT_ID: agentId,\n` +
418
+ ` TOKENTRACKER_OPENCLAW_PREV_SESSION_ID: sessionId,\n` +
419
+ ` TOKENTRACKER_OPENCLAW_HOME: openclawHome\n` +
420
420
  ` };\n` +
421
421
  ` const key = normalize(sessionKey);\n` +
422
- ` if (key) out.VIBEUSAGE_OPENCLAW_SESSION_KEY = key;\n` +
422
+ ` if (key) out.TOKENTRACKER_OPENCLAW_SESSION_KEY = key;\n` +
423
423
  ` const prevTotalTokens = toNonNegativeInt(sessionEntry && sessionEntry.totalTokens);\n` +
424
424
  ` const prevInputTokens = toNonNegativeInt(sessionEntry && sessionEntry.inputTokens);\n` +
425
425
  ` const prevOutputTokens = toNonNegativeInt(sessionEntry && sessionEntry.outputTokens);\n` +
426
426
  ` const prevModel = normalize(sessionEntry && sessionEntry.model);\n` +
427
427
  ` const prevUpdatedAt = toIso(sessionEntry && sessionEntry.updatedAt);\n` +
428
- ` if (prevTotalTokens != null) out.VIBEUSAGE_OPENCLAW_PREV_TOTAL_TOKENS = String(prevTotalTokens);\n` +
429
- ` if (prevInputTokens != null) out.VIBEUSAGE_OPENCLAW_PREV_INPUT_TOKENS = String(prevInputTokens);\n` +
430
- ` if (prevOutputTokens != null) out.VIBEUSAGE_OPENCLAW_PREV_OUTPUT_TOKENS = String(prevOutputTokens);\n` +
431
- ` if (prevModel) out.VIBEUSAGE_OPENCLAW_PREV_MODEL = prevModel;\n` +
432
- ` if (prevUpdatedAt) out.VIBEUSAGE_OPENCLAW_PREV_UPDATED_AT = prevUpdatedAt;\n` +
428
+ ` if (prevTotalTokens != null) out.TOKENTRACKER_OPENCLAW_PREV_TOTAL_TOKENS = String(prevTotalTokens);\n` +
429
+ ` if (prevInputTokens != null) out.TOKENTRACKER_OPENCLAW_PREV_INPUT_TOKENS = String(prevInputTokens);\n` +
430
+ ` if (prevOutputTokens != null) out.TOKENTRACKER_OPENCLAW_PREV_OUTPUT_TOKENS = String(prevOutputTokens);\n` +
431
+ ` if (prevModel) out.TOKENTRACKER_OPENCLAW_PREV_MODEL = prevModel;\n` +
432
+ ` if (prevUpdatedAt) out.TOKENTRACKER_OPENCLAW_PREV_UPDATED_AT = prevUpdatedAt;\n` +
433
433
  ` return out;\n` +
434
434
  `}\n` +
435
435
  `\n` +
@@ -5,7 +5,7 @@ const fs = require("node:fs/promises");
5
5
  const { ensureDir } = require("./fs");
6
6
 
7
7
  const DEFAULT_PLUGIN_NAME = "vibeusage-tracker.js";
8
- const PLUGIN_MARKER = "VIBEUSAGE_TRACKER_PLUGIN";
8
+ const PLUGIN_MARKER = "TOKENTRACKER_PLUGIN";
9
9
  const DEFAULT_EVENT = "session.updated";
10
10
 
11
11
  function resolveOpencodeConfigDir({ home = os.homedir(), env = process.env } = {}) {
@@ -6,36 +6,36 @@ function resolveRuntimeConfig({ cli = {}, config = {}, env = process.env, defaul
6
6
  const baseUrl = pickString(
7
7
  cli.baseUrl,
8
8
  config.baseUrl,
9
- env?.VIBEUSAGE_INSFORGE_BASE_URL,
9
+ env?.TOKENTRACKER_INSFORGE_BASE_URL,
10
10
  defaults.baseUrl,
11
11
  DEFAULT_BASE_URL,
12
12
  );
13
13
  const dashboardUrl = pickString(
14
14
  cli.dashboardUrl,
15
15
  config.dashboardUrl,
16
- env?.VIBEUSAGE_DASHBOARD_URL,
16
+ env?.TOKENTRACKER_DASHBOARD_URL,
17
17
  defaults.dashboardUrl,
18
18
  DEFAULT_DASHBOARD_URL,
19
19
  );
20
20
  const deviceToken = pickString(
21
21
  cli.deviceToken,
22
22
  config.deviceToken,
23
- env?.VIBEUSAGE_DEVICE_TOKEN,
23
+ env?.TOKENTRACKER_DEVICE_TOKEN,
24
24
  defaults.deviceToken,
25
25
  null,
26
26
  );
27
27
  const httpTimeoutMs = pickHttpTimeoutMs(
28
28
  cli.httpTimeoutMs,
29
29
  config.httpTimeoutMs,
30
- env?.VIBEUSAGE_HTTP_TIMEOUT_MS,
30
+ env?.TOKENTRACKER_HTTP_TIMEOUT_MS,
31
31
  defaults.httpTimeoutMs,
32
32
  DEFAULT_HTTP_TIMEOUT_MS,
33
33
  );
34
- const debug = pickBoolean(cli.debug, config.debug, env?.VIBEUSAGE_DEBUG, defaults.debug, false);
34
+ const debug = pickBoolean(cli.debug, config.debug, env?.TOKENTRACKER_DEBUG, defaults.debug, false);
35
35
  const insforgeAnonKey = pickString(
36
36
  cli.insforgeAnonKey,
37
37
  config.insforgeAnonKey,
38
- env?.VIBEUSAGE_INSFORGE_ANON_KEY,
38
+ env?.TOKENTRACKER_INSFORGE_ANON_KEY,
39
39
  defaults.insforgeAnonKey,
40
40
  "",
41
41
  );
@@ -43,7 +43,7 @@ function resolveRuntimeConfig({ cli = {}, config = {}, env = process.env, defaul
43
43
  const autoRetryNoSpawn = pickBoolean(
44
44
  cli.autoRetryNoSpawn,
45
45
  config.autoRetryNoSpawn,
46
- env?.VIBEUSAGE_AUTO_RETRY_NO_SPAWN,
46
+ env?.TOKENTRACKER_AUTO_RETRY_NO_SPAWN,
47
47
  defaults.autoRetryNoSpawn,
48
48
  false,
49
49
  );