@tokz/cli 0.2.10 → 0.2.12

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.
@@ -206,6 +206,11 @@ async function loadProjects(home = homedir(), onProgress) {
206
206
 
207
207
  // src/agents/usage.ts
208
208
  import { readFile as readFile2 } from "fs/promises";
209
+ function recordDedupKey(r) {
210
+ const scope = r.id ?? r.ts;
211
+ if (!scope) return void 0;
212
+ return `${scope}|${r.model}|${r.input}|${r.output}|${r.cacheRead}|${r.cacheWrite}`;
213
+ }
209
214
  async function readJson(file) {
210
215
  try {
211
216
  return JSON.parse(await readFile2(file, "utf8"));
@@ -230,10 +235,17 @@ async function readJsonl(file) {
230
235
  }
231
236
  return out;
232
237
  }
233
- function sessionFromRecords(file, cwd, records) {
238
+ function sessionFromRecords(file, cwd, records, seen) {
234
239
  const stats = { file, cwd, usageByModel: {}, toolCalls: {}, toolCostUsd: {}, dailyUsage: {} };
235
240
  for (const r of records) {
236
241
  if (r.input + r.output + r.cacheRead + r.cacheWrite === 0) continue;
242
+ if (seen) {
243
+ const key = recordDedupKey(r);
244
+ if (key !== void 0) {
245
+ if (seen.has(key)) continue;
246
+ seen.add(key);
247
+ }
248
+ }
237
249
  if (r.ts) {
238
250
  if (!stats.firstTs || r.ts < stats.firstTs) stats.firstTs = r.ts;
239
251
  if (!stats.lastTs || r.ts > stats.lastTs) stats.lastTs = r.ts;
@@ -558,7 +570,7 @@ function isAssistant(msg) {
558
570
  const role = str(msg, "variant") ?? str(msg, "role");
559
571
  return role === "ai" || role === "agent" || role === "assistant";
560
572
  }
561
- async function parseFile(file) {
573
+ async function parseFile(file, seen) {
562
574
  const arr = await readJson(file);
563
575
  if (!Array.isArray(arr)) return sessionFromRecords(file, void 0, []);
564
576
  let fileTs;
@@ -575,6 +587,7 @@ async function parseFile(file) {
575
587
  records.push({
576
588
  model: str(meta, "model") ?? "codebuff-unknown",
577
589
  ts: str(msg, "timestamp") ?? fileTs,
590
+ id: str(msg, "id") ?? str(msg, "messageId") ?? str(msg, "message_id"),
578
591
  input: pickNum(usage, ["inputTokens", "input_tokens"]),
579
592
  output: pickNum(usage, ["outputTokens", "output_tokens"]),
580
593
  cacheRead: pickNum(usage, ["cacheReadInputTokens", "cache_read_input_tokens", "cachedTokens"]),
@@ -591,10 +604,11 @@ async function loadCodebuffProjects(home, onProgress) {
591
604
  );
592
605
  }
593
606
  const sessions = [];
607
+ const seen = /* @__PURE__ */ new Set();
594
608
  let parsed = 0;
595
609
  for (const f of files) {
596
610
  onProgress?.({ parsed, total: files.length, currentProject: "Codebuff chats" });
597
- sessions.push(await parseFile(f));
611
+ sessions.push(await parseFile(f, seen));
598
612
  parsed += 1;
599
613
  onProgress?.({ parsed, total: files.length, currentProject: "Codebuff chats" });
600
614
  }
@@ -618,9 +632,7 @@ var codebuffAdapter = {
618
632
  };
619
633
 
620
634
  // src/agents/codex.ts
621
- import { createReadStream } from "fs";
622
- import { access as access5 } from "fs/promises";
623
- import { createInterface } from "readline";
635
+ import { access as access5, readFile as readFile4 } from "fs/promises";
624
636
  import { homedir as homedir6 } from "os";
625
637
  import { join as join6 } from "path";
626
638
  import { glob as glob4 } from "tinyglobby";
@@ -642,7 +654,12 @@ var Line = z.object({
642
654
  cwd: z.string().optional(),
643
655
  model: z.string().optional(),
644
656
  name: z.string().optional(),
645
- info: z.object({ total_token_usage: TokenTotals.optional() }).nullish()
657
+ info: z.object({
658
+ total_token_usage: TokenTotals.optional(),
659
+ // Codex writes the per-turn amount here directly; prefer it over
660
+ // differencing cumulative totals.
661
+ last_token_usage: TokenTotals.optional()
662
+ }).nullish()
646
663
  }).passthrough().optional()
647
664
  });
648
665
  function codexHome(home) {
@@ -650,13 +667,27 @@ function codexHome(home) {
650
667
  return process.env.CODEX_HOME ?? join6(homedir6(), ".codex");
651
668
  }
652
669
  var DEFAULT_MODEL = "gpt-5";
653
- async function parseCodexRollout(file) {
670
+ function tsSecond(ts) {
671
+ return (ts ?? "").slice(0, 19);
672
+ }
673
+ function replayBurstSecond(content, lines) {
674
+ const head = content.slice(0, 16384);
675
+ if (!head.includes("thread_spawn") && !head.includes("forked_from_id")) return void 0;
676
+ let first;
677
+ for (const p of lines) {
678
+ const info = p.payload?.type === "token_count" ? p.payload.info : void 0;
679
+ if (!info?.last_token_usage && !info?.total_token_usage) continue;
680
+ const sec = tsSecond(p.timestamp);
681
+ if (first === void 0) first = sec;
682
+ else return first === sec ? first : void 0;
683
+ }
684
+ return void 0;
685
+ }
686
+ async function parseCodexRollout(file, seen = /* @__PURE__ */ new Set()) {
654
687
  const stats = { file, usageByModel: {}, toolCalls: {}, toolCostUsd: {}, dailyUsage: {} };
655
- const rl = createInterface({ input: createReadStream(file, "utf8"), crlfDelay: Infinity });
656
- let model = DEFAULT_MODEL;
657
- let prev = { input: 0, cached: 0, output: 0, total: 0 };
658
- let turnTools = [];
659
- for await (const raw of rl) {
688
+ const content = await readFile4(file, "utf8").catch(() => "");
689
+ const lines = [];
690
+ for (const raw of content.split("\n")) {
660
691
  if (!raw.trim()) continue;
661
692
  let obj;
662
693
  try {
@@ -665,33 +696,79 @@ async function parseCodexRollout(file) {
665
696
  continue;
666
697
  }
667
698
  const parsed = Line.safeParse(obj);
668
- if (!parsed.success) continue;
669
- const { timestamp, type, payload: payload2 } = parsed.data;
670
- if (!stats.cwd) stats.cwd = payload2?.cwd ?? parsed.data.cwd;
699
+ if (parsed.success) lines.push(parsed.data);
700
+ }
701
+ const burstSecond = replayBurstSecond(content, lines);
702
+ let skippingReplay = burstSecond !== void 0;
703
+ let model = DEFAULT_MODEL;
704
+ let prev = { input: 0, cached: 0, output: 0, total: 0 };
705
+ let turnTools = [];
706
+ for (const parsed of lines) {
707
+ const { timestamp, type, payload: payload2 } = parsed;
708
+ if (!stats.cwd) stats.cwd = payload2?.cwd ?? parsed.cwd;
671
709
  if (payload2?.model) model = payload2.model;
672
710
  if (timestamp) {
673
711
  if (!stats.firstTs) stats.firstTs = timestamp;
674
712
  stats.lastTs = timestamp;
675
713
  }
676
- const toolName = payload2?.type === "function_call" || payload2?.type === "custom_tool_call" ? payload2.name : payload2?.type === "local_shell_call" ? "shell" : type === "function_call" ? parsed.data.name : void 0;
714
+ const toolName = payload2?.type === "function_call" || payload2?.type === "custom_tool_call" ? payload2.name : payload2?.type === "local_shell_call" ? "shell" : type === "function_call" ? parsed.name : void 0;
677
715
  if (toolName) {
678
716
  stats.toolCalls[toolName] = (stats.toolCalls[toolName] ?? 0) + 1;
679
717
  turnTools.push(toolName);
680
718
  }
681
- const totals = payload2?.type === "token_count" ? payload2.info?.total_token_usage : void 0;
682
- if (!totals) continue;
683
- const cur = {
684
- input: totals.input_tokens,
685
- cached: totals.cached_input_tokens,
686
- output: totals.output_tokens,
687
- total: totals.total_tokens
688
- };
689
- if (cur.total < prev.total) prev = { input: 0, cached: 0, output: 0, total: 0 };
690
- const dInput = Math.max(0, cur.input - prev.input);
691
- const dCached = Math.max(0, cur.cached - prev.cached);
692
- const dOutput = Math.max(0, cur.output - prev.output);
693
- prev = cur;
719
+ const info = payload2?.type === "token_count" ? payload2.info : void 0;
720
+ const last = info?.last_token_usage;
721
+ const totals = info?.total_token_usage;
722
+ if (!last && !totals) continue;
723
+ if (skippingReplay && tsSecond(timestamp) === burstSecond) {
724
+ if (totals) {
725
+ prev = {
726
+ input: totals.input_tokens,
727
+ cached: totals.cached_input_tokens,
728
+ output: totals.output_tokens,
729
+ total: totals.total_tokens
730
+ };
731
+ }
732
+ turnTools = [];
733
+ continue;
734
+ }
735
+ skippingReplay = false;
736
+ const idTotals = last ?? totals;
737
+ const dedupKey = `${timestamp ?? ""}|${model}|${idTotals.input_tokens}|${idTotals.cached_input_tokens}|${idTotals.output_tokens}|${idTotals.reasoning_output_tokens}|${idTotals.total_tokens}`;
738
+ let dInput;
739
+ let dCached;
740
+ let dOutput;
741
+ if (last) {
742
+ dInput = last.input_tokens;
743
+ dCached = last.cached_input_tokens;
744
+ dOutput = last.output_tokens;
745
+ if (totals) {
746
+ prev = {
747
+ input: totals.input_tokens,
748
+ cached: totals.cached_input_tokens,
749
+ output: totals.output_tokens,
750
+ total: totals.total_tokens
751
+ };
752
+ }
753
+ } else {
754
+ const cur = {
755
+ input: totals.input_tokens,
756
+ cached: totals.cached_input_tokens,
757
+ output: totals.output_tokens,
758
+ total: totals.total_tokens
759
+ };
760
+ if (cur.total < prev.total) prev = { input: 0, cached: 0, output: 0, total: 0 };
761
+ dInput = Math.max(0, cur.input - prev.input);
762
+ dCached = Math.max(0, cur.cached - prev.cached);
763
+ dOutput = Math.max(0, cur.output - prev.output);
764
+ prev = cur;
765
+ }
694
766
  if (dInput + dOutput === 0) continue;
767
+ if (seen.has(dedupKey)) {
768
+ turnTools = [];
769
+ continue;
770
+ }
771
+ seen.add(dedupKey);
695
772
  const delta = {
696
773
  // Codex's input_tokens INCLUDES cached tokens; split them out.
697
774
  inputTokens: Math.max(0, dInput - dCached),
@@ -730,10 +807,11 @@ async function loadCodexProjects(home, onProgress) {
730
807
  }).catch(() => []);
731
808
  if (files.length === 0) return [];
732
809
  const sessions = [];
810
+ const seen = /* @__PURE__ */ new Set();
733
811
  let parsed = 0;
734
812
  for (const f of files) {
735
813
  onProgress?.({ parsed, total: files.length, currentProject: "Codex sessions" });
736
- sessions.push(await parseCodexRollout(f));
814
+ sessions.push(await parseCodexRollout(f, seen));
737
815
  parsed += 1;
738
816
  onProgress?.({ parsed, total: files.length, currentProject: "Codex sessions" });
739
817
  }
@@ -791,9 +869,8 @@ function attrStr(attrs, keys) {
791
869
  }
792
870
  return void 0;
793
871
  }
794
- function parseOtelFile(records) {
872
+ function parseOtelFile(records, seen = /* @__PURE__ */ new Set()) {
795
873
  const bySession = /* @__PURE__ */ new Map();
796
- const seen = /* @__PURE__ */ new Set();
797
874
  for (const rec of records) {
798
875
  const attrs = rec.attributes;
799
876
  if (!attrs || typeof attrs !== "object") continue;
@@ -824,10 +901,11 @@ function parseOtelFile(records) {
824
901
  async function loadCopilotProjects(home, onProgress) {
825
902
  const files = await glob5(["**/*.jsonl"], { cwd: copilotDir(home), absolute: true }).catch(() => []);
826
903
  const bySession = /* @__PURE__ */ new Map();
904
+ const seen = /* @__PURE__ */ new Set();
827
905
  let parsed = 0;
828
906
  for (const f of files) {
829
907
  onProgress?.({ parsed, total: files.length, currentProject: "Copilot otel" });
830
- for (const [session, records] of parseOtelFile(await readJsonl(f))) {
908
+ for (const [session, records] of parseOtelFile(await readJsonl(f), seen)) {
831
909
  const list = bySession.get(session) ?? [];
832
910
  list.push(...records);
833
911
  bySession.set(session, list);
@@ -928,13 +1006,14 @@ function recordFrom(node, model, ts) {
928
1006
  return {
929
1007
  model: str(node, "model") ?? model ?? "gemini-unknown",
930
1008
  ts: str(node, "timestamp") ?? ts,
1009
+ id: str(node, "id") ?? str(node, "messageId") ?? str(node, "message_id") ?? str(node, "responseId"),
931
1010
  input: pickNum(tokens, IN),
932
1011
  output: pickNum(tokens, OUT) + reasoning,
933
1012
  cacheRead: pickNum(tokens, ["cached", "cached_tokens"]),
934
1013
  cacheWrite: 0
935
1014
  };
936
1015
  }
937
- async function parseFile3(file) {
1016
+ async function parseFile3(file, seen) {
938
1017
  const records = [];
939
1018
  const push = (r) => r && records.push(r);
940
1019
  if (file.endsWith(".jsonl")) {
@@ -946,17 +1025,18 @@ async function parseFile3(file) {
946
1025
  if (Array.isArray(messages)) for (const m of messages) push(recordFrom(m, model, void 0));
947
1026
  push(recordFrom(doc, model, void 0));
948
1027
  }
949
- return sessionFromRecords(file, void 0, records);
1028
+ return sessionFromRecords(file, void 0, records, seen);
950
1029
  }
951
1030
  async function loadGeminiProjects(home, onProgress) {
952
1031
  const files = await glob7(["**/*.json", "**/*.jsonl"], { cwd: geminiRoot(home), absolute: true }).catch(
953
1032
  () => []
954
1033
  );
955
1034
  const sessions = [];
1035
+ const seen = /* @__PURE__ */ new Set();
956
1036
  let parsed = 0;
957
1037
  for (const f of files) {
958
1038
  onProgress?.({ parsed, total: files.length, currentProject: "Gemini logs" });
959
- sessions.push(await parseFile3(f));
1039
+ sessions.push(await parseFile3(f, seen));
960
1040
  parsed += 1;
961
1041
  onProgress?.({ parsed, total: files.length, currentProject: "Gemini logs" });
962
1042
  }
@@ -983,7 +1063,7 @@ import { homedir as homedir10 } from "os";
983
1063
  import { join as join10 } from "path";
984
1064
 
985
1065
  // src/sqlite.ts
986
- import { readFile as readFile4 } from "fs/promises";
1066
+ import { readFile as readFile5 } from "fs/promises";
987
1067
  function u8(b, o) {
988
1068
  return b[o];
989
1069
  }
@@ -1123,7 +1203,7 @@ function columnNames(sql) {
1123
1203
  async function readTable(file, table) {
1124
1204
  let buf;
1125
1205
  try {
1126
- buf = await readFile4(file);
1206
+ buf = await readFile5(file);
1127
1207
  } catch {
1128
1208
  return [];
1129
1209
  }
@@ -1325,21 +1405,23 @@ function kimiRoots(home) {
1325
1405
  const h = home ?? homedir13();
1326
1406
  return KIMI_DIRS.map((d) => join13(h, d));
1327
1407
  }
1328
- async function parseFile4(file) {
1408
+ async function parseFile4(file, seen) {
1329
1409
  const records = [];
1330
1410
  for (const line of await readJsonl(file)) {
1331
1411
  const usage = deepFind(line, USAGE_KEYS);
1332
1412
  if (!usage) continue;
1413
+ const idHost = deepFind(line, ["messageId", "message_id", "id"]);
1333
1414
  records.push({
1334
1415
  model: str(line, "model") ?? "kimi-unknown",
1335
1416
  ts: str(line, "timestamp"),
1417
+ id: idHost && (str(idHost, "messageId") ?? str(idHost, "message_id") ?? str(idHost, "id")),
1336
1418
  input: pickNum(usage, ["inputOther", "input_other"]),
1337
1419
  output: pickNum(usage, ["output"]),
1338
1420
  cacheRead: pickNum(usage, ["inputCacheRead", "input_cache_read"]),
1339
1421
  cacheWrite: pickNum(usage, ["inputCacheCreation", "input_cache_creation"])
1340
1422
  });
1341
1423
  }
1342
- return sessionFromRecords(file, void 0, records);
1424
+ return sessionFromRecords(file, void 0, records, seen);
1343
1425
  }
1344
1426
  async function loadKimiProjects(home, onProgress) {
1345
1427
  const files = [];
@@ -1349,10 +1431,11 @@ async function loadKimiProjects(home, onProgress) {
1349
1431
  );
1350
1432
  }
1351
1433
  const sessions = [];
1434
+ const seen = /* @__PURE__ */ new Set();
1352
1435
  let parsed = 0;
1353
1436
  for (const f of files) {
1354
1437
  onProgress?.({ parsed, total: files.length, currentProject: "Kimi sessions" });
1355
- sessions.push(await parseFile4(f));
1438
+ sessions.push(await parseFile4(f, seen));
1356
1439
  parsed += 1;
1357
1440
  onProgress?.({ parsed, total: files.length, currentProject: "Kimi sessions" });
1358
1441
  }
@@ -1390,7 +1473,7 @@ function openclawRoots(home) {
1390
1473
  function modelFrom(obj) {
1391
1474
  return str(obj, "modelId") ?? str(obj, "model");
1392
1475
  }
1393
- async function parseFile5(file) {
1476
+ async function parseFile5(file, seen) {
1394
1477
  const records = [];
1395
1478
  let currentModel;
1396
1479
  for (const line of await readJsonl(file)) {
@@ -1405,13 +1488,14 @@ async function parseFile5(file) {
1405
1488
  records.push({
1406
1489
  model,
1407
1490
  ts: str(l.message, "timestamp") ?? str(l, "timestamp"),
1491
+ id: str(l.message, "id") ?? str(l, "id") ?? str(l.message, "messageId"),
1408
1492
  input: pickNum(usage, ["input"]),
1409
1493
  output: pickNum(usage, ["output"]),
1410
1494
  cacheRead: pickNum(usage, ["cacheRead"]),
1411
1495
  cacheWrite: pickNum(usage, ["cacheWrite"])
1412
1496
  });
1413
1497
  }
1414
- return sessionFromRecords(file, void 0, records);
1498
+ return sessionFromRecords(file, void 0, records, seen);
1415
1499
  }
1416
1500
  async function loadOpenclawProjects(home, onProgress) {
1417
1501
  const files = [];
@@ -1419,10 +1503,11 @@ async function loadOpenclawProjects(home, onProgress) {
1419
1503
  files.push(...await glob9(["**/*.jsonl", "**/*.jsonl.*"], { cwd: root, absolute: true }).catch(() => []));
1420
1504
  }
1421
1505
  const sessions = [];
1506
+ const seen = /* @__PURE__ */ new Set();
1422
1507
  let parsed = 0;
1423
1508
  for (const f of files) {
1424
1509
  onProgress?.({ parsed, total: files.length, currentProject: "OpenClaw sessions" });
1425
- sessions.push(await parseFile5(f));
1510
+ sessions.push(await parseFile5(f, seen));
1426
1511
  parsed += 1;
1427
1512
  onProgress?.({ parsed, total: files.length, currentProject: "OpenClaw sessions" });
1428
1513
  }
@@ -1446,7 +1531,7 @@ var openclawAdapter = {
1446
1531
  };
1447
1532
 
1448
1533
  // src/agents/opencode.ts
1449
- import { access as access14, readFile as readFile5 } from "fs/promises";
1534
+ import { access as access14, readFile as readFile6 } from "fs/promises";
1450
1535
  import { homedir as homedir15 } from "os";
1451
1536
  import { join as join15 } from "path";
1452
1537
  import { glob as glob10 } from "tinyglobby";
@@ -1477,7 +1562,7 @@ function opencodeRoot(home) {
1477
1562
  }
1478
1563
  async function readJson2(file) {
1479
1564
  try {
1480
- return JSON.parse(await readFile5(file, "utf8"));
1565
+ return JSON.parse(await readFile6(file, "utf8"));
1481
1566
  } catch {
1482
1567
  return void 0;
1483
1568
  }
@@ -1566,7 +1651,7 @@ import { glob as glob11 } from "tinyglobby";
1566
1651
  function piRoot(home) {
1567
1652
  return process.env.PI_AGENT_DIR ?? join16(home ?? homedir16(), ".pi", "agent", "sessions");
1568
1653
  }
1569
- async function parseFile6(file) {
1654
+ async function parseFile6(file, seen) {
1570
1655
  const records = [];
1571
1656
  for (const line of await readJsonl(file)) {
1572
1657
  const msg = line.message;
@@ -1575,21 +1660,23 @@ async function parseFile6(file) {
1575
1660
  records.push({
1576
1661
  model: str(msg, "model") ?? "pi-unknown",
1577
1662
  ts: str(line, "timestamp"),
1663
+ id: str(msg, "id") ?? str(line, "id") ?? str(msg, "messageId"),
1578
1664
  input: pickNum(usage, ["input"]),
1579
1665
  output: pickNum(usage, ["output"]),
1580
1666
  cacheRead: pickNum(usage, ["cacheRead"]),
1581
1667
  cacheWrite: pickNum(usage, ["cacheWrite"])
1582
1668
  });
1583
1669
  }
1584
- return sessionFromRecords(file, void 0, records);
1670
+ return sessionFromRecords(file, void 0, records, seen);
1585
1671
  }
1586
1672
  async function loadPiProjects(home, onProgress) {
1587
1673
  const files = await glob11(["**/*.jsonl"], { cwd: piRoot(home), absolute: true }).catch(() => []);
1588
1674
  const sessions = [];
1675
+ const seen = /* @__PURE__ */ new Set();
1589
1676
  let parsed = 0;
1590
1677
  for (const f of files) {
1591
1678
  onProgress?.({ parsed, total: files.length, currentProject: "pi sessions" });
1592
- sessions.push(await parseFile6(f));
1679
+ sessions.push(await parseFile6(f, seen));
1593
1680
  parsed += 1;
1594
1681
  onProgress?.({ parsed, total: files.length, currentProject: "pi sessions" });
1595
1682
  }
@@ -1618,7 +1705,7 @@ import { glob as glob12 } from "tinyglobby";
1618
1705
  function qwenRoot(home) {
1619
1706
  return process.env.QWEN_DATA_DIR ?? join17(home ?? homedir17(), ".qwen");
1620
1707
  }
1621
- async function parseFile7(file) {
1708
+ async function parseFile7(file, seen) {
1622
1709
  const records = [];
1623
1710
  for (const line of await readJsonl(file)) {
1624
1711
  const meta = line.usageMetadata;
@@ -1629,23 +1716,25 @@ async function parseFile7(file) {
1629
1716
  records.push({
1630
1717
  model: str(line, "model") ?? "qwen-unknown",
1631
1718
  ts: str(line, "timestamp"),
1719
+ id: str(line, "id") ?? str(line, "messageId") ?? str(line, "message_id"),
1632
1720
  input: Math.max(0, prompt - cached),
1633
1721
  output: pickNum(meta, ["candidatesTokenCount"]) + reasoning,
1634
1722
  cacheRead: cached,
1635
1723
  cacheWrite: 0
1636
1724
  });
1637
1725
  }
1638
- return sessionFromRecords(file, void 0, records);
1726
+ return sessionFromRecords(file, void 0, records, seen);
1639
1727
  }
1640
1728
  async function loadQwenProjects(home, onProgress) {
1641
1729
  const files = await glob12(["projects/**/*.jsonl"], { cwd: qwenRoot(home), absolute: true }).catch(
1642
1730
  () => []
1643
1731
  );
1644
1732
  const sessions = [];
1733
+ const seen = /* @__PURE__ */ new Set();
1645
1734
  let parsed = 0;
1646
1735
  for (const f of files) {
1647
1736
  onProgress?.({ parsed, total: files.length, currentProject: "Qwen sessions" });
1648
- sessions.push(await parseFile7(f));
1737
+ sessions.push(await parseFile7(f, seen));
1649
1738
  parsed += 1;
1650
1739
  onProgress?.({ parsed, total: files.length, currentProject: "Qwen sessions" });
1651
1740
  }
package/dist/cli.js CHANGED
@@ -276,7 +276,7 @@ program.action(async () => {
276
276
  const [{ render }, React, { Root }, { Fullscreen }] = await Promise.all([
277
277
  import("ink"),
278
278
  import("react"),
279
- import("./Root-ZJO6F6LM.js"),
279
+ import("./Root-FWMJ2TO2.js"),
280
280
  import("./Fullscreen-GK2ZYXHV.js")
281
281
  ]);
282
282
  render(React.createElement(Fullscreen, null, React.createElement(Root)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokz/cli",
3
- "version": "0.2.10",
3
+ "version": "0.2.12",
4
4
  "description": "See where your coding agents' tokens and dollars actually go.",
5
5
  "keywords": [
6
6
  "claude",