ccclub 0.3.8 → 0.3.10

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 (2) hide show
  1. package/dist/index.js +36 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -614,12 +614,21 @@ async function collectCodexUsage() {
614
614
  const entries = [];
615
615
  const turns = [];
616
616
  const seen = /* @__PURE__ */ new Set();
617
+ const seenTurns = /* @__PURE__ */ new Set();
618
+ function addTurn(timestamp, key) {
619
+ if (seenTurns.has(key)) return;
620
+ seenTurns.add(key);
621
+ turns.push({ source, timestamp, key });
622
+ }
617
623
  for (const sessionDir of sessionDirs) {
618
624
  const sessionFiles = files.filter((file) => file.startsWith(`${sessionDir}${sep}`));
619
625
  for (const file of sessionFiles) {
620
626
  const sessionId = sessionIdForFile(sessionDir, file);
621
627
  let previousTotal = null;
622
628
  let currentModel;
629
+ let sawTaskStarted = false;
630
+ const fallbackUserTurns = [];
631
+ const seenFallbackUserTurns = /* @__PURE__ */ new Set();
623
632
  await readJsonlFile(file, (value) => {
624
633
  const record = asRecord(value);
625
634
  if (record == null) return;
@@ -629,6 +638,25 @@ async function collectCodexUsage() {
629
638
  currentModel = extractModelFromPayload(payload) ?? currentModel;
630
639
  return;
631
640
  }
641
+ if (type === "event_msg" && payload?.type === "task_started") {
642
+ const timestamp2 = toIsoTimestamp(payload.started_at ?? record.timestamp);
643
+ if (timestamp2 == null) return;
644
+ const turnId = asString(payload.turn_id);
645
+ const key = turnId != null ? `${source}:${sessionId}:${turnId}` : `${source}:${sessionId}:${timestamp2}:task_started`;
646
+ sawTaskStarted = true;
647
+ addTurn(timestamp2, key);
648
+ return;
649
+ }
650
+ if (type === "event_msg" && payload?.type === "user_message") {
651
+ const timestamp2 = toIsoTimestamp(record.timestamp);
652
+ if (timestamp2 == null) return;
653
+ const key = `${source}:${sessionId}:${timestamp2}:user_message`;
654
+ if (!seenFallbackUserTurns.has(key)) {
655
+ seenFallbackUserTurns.add(key);
656
+ fallbackUserTurns.push({ source, timestamp: timestamp2, key });
657
+ }
658
+ return;
659
+ }
632
660
  if (type !== "event_msg" || payload?.type !== "token_count") return;
633
661
  const timestamp = toIsoTimestamp(record.timestamp);
634
662
  if (timestamp == null) return;
@@ -673,8 +701,10 @@ async function collectCodexUsage() {
673
701
  totalTokens,
674
702
  costUSD: calculateCost(model, inputTokens, rawUsage.outputTokens, 0, cacheReadTokens)
675
703
  });
676
- turns.push({ source, timestamp, key: dedupeKey });
677
704
  });
705
+ if (!sawTaskStarted) {
706
+ for (const turn of fallbackUserTurns) addTurn(turn.timestamp, turn.key);
707
+ }
678
708
  }
679
709
  }
680
710
  return { source, entries, turns, files: files.length, warnings: [] };
@@ -991,6 +1021,7 @@ function aggregateSourceToBlocks(source, entries, humanTurns) {
991
1021
  let reasoningTokens = 0;
992
1022
  let totalTokens = 0;
993
1023
  let costUSD = 0;
1024
+ let lastActivityMs = 0;
994
1025
  for (const entry of currentBlock) {
995
1026
  inputTokens += entry.inputTokens;
996
1027
  outputTokens += entry.outputTokens;
@@ -1011,11 +1042,14 @@ function aggregateSourceToBlocks(source, entries, humanTurns) {
1011
1042
  entry.reasoningTokens || 0
1012
1043
  );
1013
1044
  }
1045
+ const entryMs = new Date(entry.timestamp).getTime();
1046
+ if (Number.isFinite(entryMs) && entryMs > lastActivityMs) lastActivityMs = entryMs;
1014
1047
  }
1015
1048
  blocks.push({
1016
1049
  source,
1017
1050
  blockStart: blockStart.toISOString(),
1018
1051
  blockEnd: blockEnd.toISOString(),
1052
+ lastActivityAt: new Date(lastActivityMs || blockEnd.getTime()).toISOString(),
1019
1053
  inputTokens,
1020
1054
  outputTokens,
1021
1055
  cacheCreationTokens,
@@ -2252,7 +2286,7 @@ async function hookCommand() {
2252
2286
  }
2253
2287
 
2254
2288
  // src/index.ts
2255
- var VERSION = "0.3.8";
2289
+ var VERSION = "0.3.10";
2256
2290
  startUpdateCheck(VERSION);
2257
2291
  var program = new Command();
2258
2292
  if (process.argv.slice(2).includes("-v")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccclub",
3
- "version": "0.3.8",
3
+ "version": "0.3.10",
4
4
  "type": "module",
5
5
  "description": "Claude Code and Codex leaderboard among friends for coding agent tokens and costs",
6
6
  "bin": {