@tokz/cli 0.2.11 → 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.
@@ -632,9 +632,7 @@ var codebuffAdapter = {
632
632
  };
633
633
 
634
634
  // src/agents/codex.ts
635
- import { createReadStream } from "fs";
636
- import { access as access5 } from "fs/promises";
637
- import { createInterface } from "readline";
635
+ import { access as access5, readFile as readFile4 } from "fs/promises";
638
636
  import { homedir as homedir6 } from "os";
639
637
  import { join as join6 } from "path";
640
638
  import { glob as glob4 } from "tinyglobby";
@@ -669,13 +667,27 @@ function codexHome(home) {
669
667
  return process.env.CODEX_HOME ?? join6(homedir6(), ".codex");
670
668
  }
671
669
  var DEFAULT_MODEL = "gpt-5";
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
+ }
672
686
  async function parseCodexRollout(file, seen = /* @__PURE__ */ new Set()) {
673
687
  const stats = { file, usageByModel: {}, toolCalls: {}, toolCostUsd: {}, dailyUsage: {} };
674
- const rl = createInterface({ input: createReadStream(file, "utf8"), crlfDelay: Infinity });
675
- let model = DEFAULT_MODEL;
676
- let prev = { input: 0, cached: 0, output: 0, total: 0 };
677
- let turnTools = [];
678
- 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")) {
679
691
  if (!raw.trim()) continue;
680
692
  let obj;
681
693
  try {
@@ -684,15 +696,22 @@ async function parseCodexRollout(file, seen = /* @__PURE__ */ new Set()) {
684
696
  continue;
685
697
  }
686
698
  const parsed = Line.safeParse(obj);
687
- if (!parsed.success) continue;
688
- const { timestamp, type, payload: payload2 } = parsed.data;
689
- 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;
690
709
  if (payload2?.model) model = payload2.model;
691
710
  if (timestamp) {
692
711
  if (!stats.firstTs) stats.firstTs = timestamp;
693
712
  stats.lastTs = timestamp;
694
713
  }
695
- 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;
696
715
  if (toolName) {
697
716
  stats.toolCalls[toolName] = (stats.toolCalls[toolName] ?? 0) + 1;
698
717
  turnTools.push(toolName);
@@ -701,6 +720,19 @@ async function parseCodexRollout(file, seen = /* @__PURE__ */ new Set()) {
701
720
  const last = info?.last_token_usage;
702
721
  const totals = info?.total_token_usage;
703
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;
704
736
  const idTotals = last ?? totals;
705
737
  const dedupKey = `${timestamp ?? ""}|${model}|${idTotals.input_tokens}|${idTotals.cached_input_tokens}|${idTotals.output_tokens}|${idTotals.reasoning_output_tokens}|${idTotals.total_tokens}`;
706
738
  let dInput;
@@ -1031,7 +1063,7 @@ import { homedir as homedir10 } from "os";
1031
1063
  import { join as join10 } from "path";
1032
1064
 
1033
1065
  // src/sqlite.ts
1034
- import { readFile as readFile4 } from "fs/promises";
1066
+ import { readFile as readFile5 } from "fs/promises";
1035
1067
  function u8(b, o) {
1036
1068
  return b[o];
1037
1069
  }
@@ -1171,7 +1203,7 @@ function columnNames(sql) {
1171
1203
  async function readTable(file, table) {
1172
1204
  let buf;
1173
1205
  try {
1174
- buf = await readFile4(file);
1206
+ buf = await readFile5(file);
1175
1207
  } catch {
1176
1208
  return [];
1177
1209
  }
@@ -1499,7 +1531,7 @@ var openclawAdapter = {
1499
1531
  };
1500
1532
 
1501
1533
  // src/agents/opencode.ts
1502
- import { access as access14, readFile as readFile5 } from "fs/promises";
1534
+ import { access as access14, readFile as readFile6 } from "fs/promises";
1503
1535
  import { homedir as homedir15 } from "os";
1504
1536
  import { join as join15 } from "path";
1505
1537
  import { glob as glob10 } from "tinyglobby";
@@ -1530,7 +1562,7 @@ function opencodeRoot(home) {
1530
1562
  }
1531
1563
  async function readJson2(file) {
1532
1564
  try {
1533
- return JSON.parse(await readFile5(file, "utf8"));
1565
+ return JSON.parse(await readFile6(file, "utf8"));
1534
1566
  } catch {
1535
1567
  return void 0;
1536
1568
  }
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-T2V2YHJ2.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.11",
3
+ "version": "0.2.12",
4
4
  "description": "See where your coding agents' tokens and dollars actually go.",
5
5
  "keywords": [
6
6
  "claude",