ccclub 0.3.6 → 0.3.7

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 +23 -20
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -585,7 +585,7 @@ function normalizeRawUsage(value) {
585
585
  const cachedInputTokens = asNumber(record.cached_input_tokens ?? record.cache_read_input_tokens);
586
586
  const outputTokens = asNumber(record.output_tokens);
587
587
  const reasoningTokens = asNumber(record.reasoning_output_tokens);
588
- const fallbackTotal = inputTokens + outputTokens + reasoningTokens;
588
+ const fallbackTotal = inputTokens + outputTokens;
589
589
  const totalTokens = asNumber(record.total_tokens) || fallbackTotal;
590
590
  return { inputTokens, cachedInputTokens, outputTokens, reasoningTokens, totalTokens };
591
591
  }
@@ -669,9 +669,9 @@ async function collectCodexUsage() {
669
669
  outputTokens: rawUsage.outputTokens,
670
670
  cacheCreationTokens: 0,
671
671
  cacheReadTokens,
672
- reasoningTokens: rawUsage.reasoningTokens,
672
+ reasoningTokens: 0,
673
673
  totalTokens,
674
- costUSD: calculateCost(model, inputTokens, rawUsage.outputTokens, 0, cacheReadTokens, rawUsage.reasoningTokens)
674
+ costUSD: calculateCost(model, inputTokens, rawUsage.outputTokens, 0, cacheReadTokens)
675
675
  });
676
676
  turns.push({ source, timestamp, key: dedupeKey });
677
677
  });
@@ -1197,7 +1197,7 @@ async function fetchUsageLimits() {
1197
1197
  }
1198
1198
 
1199
1199
  // src/commands/sync.ts
1200
- var SYNC_FORMAT_VERSION = "7";
1200
+ var SYNC_FORMAT_VERSION = "8";
1201
1201
  function getSyncVersionPath() {
1202
1202
  return join11(homedir11(), CCCLUB_CONFIG_DIR, "sync-version");
1203
1203
  }
@@ -1728,7 +1728,6 @@ function printGroup(data, code, period, config, showCache = false, showAll = fal
1728
1728
  const activeRankings = showAll || data.rankings.length <= 15 ? data.rankings : data.rankings.filter((r) => r.costUSD > 0 || r.userId === config.userId);
1729
1729
  const hiddenCount = data.rankings.length - activeRankings.length;
1730
1730
  const hasPlan = activeRankings.some((r) => r.plan);
1731
- const hasUsage = activeRankings.some((r) => r.usageSnapshot);
1732
1731
  const hasAgents = activeRankings.some(
1733
1732
  (r) => r.agents && r.agents.length > 0 && !(r.agents.length === 1 && r.agents[0] === "claude")
1734
1733
  );
@@ -1746,8 +1745,7 @@ function printGroup(data, code, period, config, showCache = false, showAll = fal
1746
1745
  tokens: formatTokens(tokens),
1747
1746
  roi,
1748
1747
  turns: String(entry.chatCount),
1749
- perTurn: entry.chatCount > 0 ? `$${(entry.costUSD / entry.chatCount).toFixed(2)}` : "\u2014",
1750
- usage: entry.usageSnapshot ? `${Math.round(entry.usageSnapshot.sevenDay)}%` : "\u2014"
1748
+ perTurn: entry.chatCount > 0 ? `$${(entry.costUSD / entry.chatCount).toFixed(2)}` : "\u2014"
1751
1749
  };
1752
1750
  });
1753
1751
  const head = ["#", "Name", "Cost", "Tokens"];
@@ -1759,7 +1757,7 @@ function printGroup(data, code, period, config, showCache = false, showAll = fal
1759
1757
  ];
1760
1758
  if (hasAgents) {
1761
1759
  head.splice(2, 0, "Agents");
1762
- widths.splice(2, 0, columnWidth("Agents", plainRows.map((r) => r.agents), 6, 24));
1760
+ widths.splice(2, 0, columnWidth("Agents", plainRows.map((r) => r.agents), 6, 28));
1763
1761
  }
1764
1762
  if (hasPlan) {
1765
1763
  head.push("ROI");
@@ -1770,10 +1768,6 @@ function printGroup(data, code, period, config, showCache = false, showAll = fal
1770
1768
  columnWidth("Turns", plainRows.map((r) => r.turns), 3, 6),
1771
1769
  columnWidth("$/Turn", plainRows.map((r) => r.perTurn), 6, 7)
1772
1770
  );
1773
- if (hasUsage) {
1774
- head.push("Usage");
1775
- widths.push(columnWidth("Usage", plainRows.map((r) => r.usage), 5, 6));
1776
- }
1777
1771
  const table = new Table({
1778
1772
  head: head.map((h) => chalk6.cyan(h)),
1779
1773
  style: { head: [], border: [] },
@@ -1802,9 +1796,6 @@ function printGroup(data, code, period, config, showCache = false, showAll = fal
1802
1796
  }
1803
1797
  row.push(c(plain.turns));
1804
1798
  row.push(entry.chatCount > 0 ? c(plain.perTurn) : chalk6.dim("\u2014"));
1805
- if (hasUsage) {
1806
- row.push(entry.usageSnapshot ? c(plain.usage) : chalk6.dim("\u2014"));
1807
- }
1808
1799
  table.push(row);
1809
1800
  }
1810
1801
  console.log(table.toString());
@@ -1850,7 +1841,7 @@ function formatAgents(entry) {
1850
1841
  if (entry.agentBreakdown.length === 1) {
1851
1842
  return formatAgentLabel(entry.agentBreakdown[0].source);
1852
1843
  }
1853
- const visible = entry.agentBreakdown.slice(0, 2).map((agent) => `${formatAgentLabel(agent.source)} ${agent.percent}%`);
1844
+ const visible = entry.agentBreakdown.slice(0, 2).map((agent) => `${formatAgentLabel(agent.source)} (${agent.percent}%)`);
1854
1845
  if (entry.agentBreakdown.length > visible.length) {
1855
1846
  visible.push(`+${entry.agentBreakdown.length - visible.length}`);
1856
1847
  }
@@ -2237,10 +2228,14 @@ async function hookCommand() {
2237
2228
  }
2238
2229
 
2239
2230
  // src/index.ts
2240
- var VERSION = "0.3.6";
2231
+ var VERSION = "0.3.7";
2241
2232
  startUpdateCheck(VERSION);
2242
2233
  var program = new Command();
2243
- program.name("ccclub").description("Coding agent usage leaderboard among friends").version(VERSION, "-v, -V, --version");
2234
+ if (process.argv.slice(2).includes("-v")) {
2235
+ console.log(VERSION);
2236
+ process.exit(0);
2237
+ }
2238
+ program.name("ccclub").description("Claude Code, Codex, OpenCode, Amp, and pi-agent usage leaderboard among friends").version(VERSION);
2244
2239
  program.command("rank", { isDefault: true, hidden: true }).description("Show leaderboard").option("-d, --days [days]", "Time window: 1 | 7 | 30 | all (default: today)").addOption(new Option("-p, --period [period]").hideHelp()).option("-g, --group <code>", "Group invite code").option("--global", "Show global public ranking").option("--cache", "Include cache tokens in count").option("--all", "Show all members including those with no activity").action(rankCommand);
2245
2240
  program.command("init").description("Create a group and get started (first-time setup)").action(initCommand);
2246
2241
  program.command("join").description("Join a group with a 6-letter invite code").argument("[invite-code]", "6-character invite code").action((code) => {
@@ -2258,7 +2253,7 @@ program.command("join").description("Join a group with a 6-letter invite code").
2258
2253
  }
2259
2254
  return joinCommand(code);
2260
2255
  });
2261
- program.command("sync").description("Upload usage data (runs automatically on session end)").addOption(new Option("-s, --silent").hideHelp()).option("-f, --force", "Force full re-sync of all data").addOption(new Option("--full", "Same as --force").hideHelp()).action(
2256
+ program.command("sync").description("Upload local coding agent usage now (auto-sync also runs after setup)").addOption(new Option("-s, --silent").hideHelp()).option("-f, --force", "Re-scan and upload all local usage logs").addOption(new Option("--full", "Same as --force").hideHelp()).action(
2262
2257
  (options) => syncCommand({ ...options, full: options.full || options.force })
2263
2258
  );
2264
2259
  program.command("profile").description("View or update your profile").option("-n, --name <name>", "Set display name").option("--avatar <url>", "Set avatar URL (empty to reset)").option("--public", "Make profile visible in global ranking").option("--private", "Hide from global ranking").option("--plan <plan>", "pro ($20) | max100 ($100) | max200 ($200) | api | none").option("--url <url>", "Link your name to a URL (GitHub, website, etc.)").action(profileCommand);
@@ -2267,6 +2262,13 @@ program.command("leave").description("Leave a group").argument("[code]", "Group
2267
2262
  program.command("show-data").description("Preview exactly what gets uploaded (privacy check)").action(showDataCommand);
2268
2263
  program.command("hook", { hidden: true }).description("Set up auto-sync hook").action(hookCommand);
2269
2264
  program.addHelpText("after", `
2265
+ Setup:
2266
+ ccclub init Create your group and enable auto-sync
2267
+ ccclub join <code> Join a friend's group
2268
+
2269
+ Supported agents:
2270
+ Claude Code, Codex, OpenCode, Amp, pi-agent
2271
+
2270
2272
  Leaderboard options:
2271
2273
  -d <period> Time window: 1 | 7 | 30 | all (default: today)
2272
2274
  -g <code> Show a specific group
@@ -2275,9 +2277,10 @@ Leaderboard options:
2275
2277
  --all Show all members including inactive ones
2276
2278
 
2277
2279
  Examples:
2280
+ $ npx ccclub init First-time setup
2278
2281
  $ ccclub Show today's leaderboard (default)
2279
2282
  $ ccclub -d 1|7|30|all Time window (default: today)
2280
2283
  $ ccclub --global Global public leaderboard
2281
- $ ccclub sync --force Force full re-sync of all data
2284
+ $ ccclub show-data Preview exactly what gets uploaded
2282
2285
  `);
2283
2286
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccclub",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
4
4
  "type": "module",
5
5
  "description": "Claude Code and Codex leaderboard among friends for coding agent tokens and costs",
6
6
  "bin": {