ccclub 0.3.14 → 0.3.16
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.
- package/dist/index.js +44 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1709,8 +1709,10 @@ async function getUpdateResult() {
|
|
|
1709
1709
|
|
|
1710
1710
|
// src/commands/rank.ts
|
|
1711
1711
|
var ACTIVE_THRESHOLD_MS = 15 * 60 * 1e3;
|
|
1712
|
+
var AGENT_ORDER = ["claude", "codex", "opencode", "amp", "pi"];
|
|
1712
1713
|
async function rankCommand(options) {
|
|
1713
1714
|
const config = await requireConfig();
|
|
1715
|
+
const includeCache = options.cache !== false;
|
|
1714
1716
|
if (!isHookInstalled()) await installHook();
|
|
1715
1717
|
if (!isHeartbeatInstalled()) await installHeartbeat();
|
|
1716
1718
|
if (needsFullSync()) {
|
|
@@ -1805,11 +1807,15 @@ async function rankCommand(options) {
|
|
|
1805
1807
|
const me = rankData.rankings.find((r) => r.userId === config.userId);
|
|
1806
1808
|
if (me) me.usageSnapshot = localSnapshot;
|
|
1807
1809
|
}
|
|
1808
|
-
printGroup(rankData, code, period, config,
|
|
1810
|
+
printGroup(rankData, code, period, config, includeCache, options.all);
|
|
1809
1811
|
if (activityData) renderActivity(activityData, range);
|
|
1810
1812
|
if (i < groupResults.length - 1) console.log("");
|
|
1811
1813
|
}
|
|
1812
|
-
|
|
1814
|
+
if (includeCache) {
|
|
1815
|
+
console.log(theme.muted("\n Tokens include cache by default. Use ") + theme.text("--no-cache") + theme.muted(" to show input + output + reasoning only."));
|
|
1816
|
+
} else {
|
|
1817
|
+
console.log(theme.muted("\n Tokens = input + output + reasoning ") + theme.warning("(cache excluded)") + theme.muted(". Cost still includes cache."));
|
|
1818
|
+
}
|
|
1813
1819
|
const update = await getUpdateResult();
|
|
1814
1820
|
if (update) {
|
|
1815
1821
|
console.log(theme.warningBold("\n Update available") + theme.muted(`: ${update.current} \u2192 ${update.latest} Run `) + theme.linkText("npm i -g ccclub@latest"));
|
|
@@ -1833,7 +1839,7 @@ function formatTokens(n) {
|
|
|
1833
1839
|
}
|
|
1834
1840
|
return String(n);
|
|
1835
1841
|
}
|
|
1836
|
-
function printGroup(data, code, period, config, showCache =
|
|
1842
|
+
function printGroup(data, code, period, config, showCache = true, showAll = false) {
|
|
1837
1843
|
if (data.rankings.length === 0) {
|
|
1838
1844
|
console.log(theme.title(`
|
|
1839
1845
|
${data.group.name}`));
|
|
@@ -1845,10 +1851,12 @@ function printGroup(data, code, period, config, showCache = false, showAll = fal
|
|
|
1845
1851
|
${data.group.name}`));
|
|
1846
1852
|
const periodLabel = { daily: "TODAY", yesterday: "YESTERDAY", weekly: "7 DAYS", monthly: "30 DAYS", "all-time": "ALL TIME" };
|
|
1847
1853
|
const now = Date.now();
|
|
1848
|
-
const
|
|
1854
|
+
const activeEntries = data.rankings.filter((r) => isEntryActive(r, now));
|
|
1855
|
+
const activeCount = activeEntries.length;
|
|
1849
1856
|
console.log(theme.muted(` ${periodLabel[period] || period.toUpperCase()} \xB7 ${data.start.slice(0, 10)} \u2192 ${data.end.slice(0, 10)} \xB7 ${data.group.memberCount} members`));
|
|
1850
1857
|
if (activeCount > 0) {
|
|
1851
|
-
|
|
1858
|
+
const activeSplit = formatActiveSourceSplit(activeEntries);
|
|
1859
|
+
console.log(theme.success(` ${activeCount} active`) + (activeSplit ? ` ${activeSplit}` : ""));
|
|
1852
1860
|
}
|
|
1853
1861
|
console.log("");
|
|
1854
1862
|
const activeRankings = showAll || data.rankings.length <= 15 ? data.rankings : data.rankings.filter((r) => r.costUSD > 0 || r.userId === config.userId);
|
|
@@ -1945,6 +1953,34 @@ function isEntryActive(entry, now) {
|
|
|
1945
1953
|
const activeAt = new Date(value).getTime();
|
|
1946
1954
|
return Number.isFinite(activeAt) && now - activeAt < ACTIVE_THRESHOLD_MS;
|
|
1947
1955
|
}
|
|
1956
|
+
function activeSourceForEntry(entry) {
|
|
1957
|
+
return entry.lastActiveSource ?? entry.agents?.[0];
|
|
1958
|
+
}
|
|
1959
|
+
function formatActiveSourceSplit(entries) {
|
|
1960
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1961
|
+
for (const entry of entries) {
|
|
1962
|
+
const source = activeSourceForEntry(entry);
|
|
1963
|
+
if (!source) continue;
|
|
1964
|
+
counts.set(source, (counts.get(source) ?? 0) + 1);
|
|
1965
|
+
}
|
|
1966
|
+
const sources = AGENT_ORDER.filter((source) => (counts.get(source) ?? 0) > 0);
|
|
1967
|
+
if (sources.length === 0) return "";
|
|
1968
|
+
if (sources.length === 2 && sources.includes("claude") && sources.includes("codex")) {
|
|
1969
|
+
return [
|
|
1970
|
+
theme.muted("Claude"),
|
|
1971
|
+
theme.successBold(String(counts.get("claude") ?? 0)) + theme.faint(":"),
|
|
1972
|
+
theme.successBold(String(counts.get("codex") ?? 0)),
|
|
1973
|
+
theme.muted("Codex")
|
|
1974
|
+
].join(" ");
|
|
1975
|
+
}
|
|
1976
|
+
return sources.map((source) => formatActiveSourceScore(source, counts.get(source) ?? 0, false)).join(theme.faint(" \xB7 "));
|
|
1977
|
+
}
|
|
1978
|
+
function formatActiveSourceScore(source, count, countFirst) {
|
|
1979
|
+
const icon = source === "claude" ? theme.gold("\u25CF") : source === "codex" ? theme.linkText("\u25CF") : theme.success("\u25CF");
|
|
1980
|
+
const label = source === "claude" ? "Claude" : formatAgentLabel(source);
|
|
1981
|
+
const coloredCount = theme.successBold(String(count));
|
|
1982
|
+
return countFirst ? `${coloredCount} ${icon} ${theme.muted(label)}` : `${icon} ${theme.muted(label)} ${coloredCount}`;
|
|
1983
|
+
}
|
|
1948
1984
|
function podiumStyle(rank) {
|
|
1949
1985
|
if (rank === 1) return theme.gold;
|
|
1950
1986
|
if (rank === 2) return theme.silver;
|
|
@@ -2357,7 +2393,7 @@ async function hookCommand() {
|
|
|
2357
2393
|
}
|
|
2358
2394
|
|
|
2359
2395
|
// src/index.ts
|
|
2360
|
-
var VERSION = "0.3.
|
|
2396
|
+
var VERSION = "0.3.16";
|
|
2361
2397
|
startUpdateCheck(VERSION);
|
|
2362
2398
|
var program = new Command();
|
|
2363
2399
|
if (process.argv.slice(2).includes("-v")) {
|
|
@@ -2365,7 +2401,7 @@ if (process.argv.slice(2).includes("-v")) {
|
|
|
2365
2401
|
process.exit(0);
|
|
2366
2402
|
}
|
|
2367
2403
|
program.name("ccclub").description("Claude Code, Codex, OpenCode, Amp, and pi-agent usage leaderboard among friends").version(VERSION);
|
|
2368
|
-
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").
|
|
2404
|
+
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").addOption(new Option("--cache", "Include cache tokens in count (default)").hideHelp()).option("--no-cache", "Exclude cache tokens from token counts").option("--all", "Show all members including those with no activity").action(rankCommand);
|
|
2369
2405
|
program.command("init").description("Create a group and get started (first-time setup)").action(initCommand);
|
|
2370
2406
|
program.command("join").description("Join a group with a 6-letter invite code").argument("[invite-code]", "6-character invite code").action((code) => {
|
|
2371
2407
|
if (!code) {
|
|
@@ -2402,7 +2438,7 @@ Leaderboard options:
|
|
|
2402
2438
|
-d <period> Time window: 1 | 7 | 30 | all (default: today)
|
|
2403
2439
|
-g <code> Show a specific group
|
|
2404
2440
|
--global Global public leaderboard
|
|
2405
|
-
--cache
|
|
2441
|
+
--no-cache Exclude cache tokens from token totals
|
|
2406
2442
|
--all Show all members including inactive ones
|
|
2407
2443
|
|
|
2408
2444
|
Examples:
|