ccclub 0.2.72 → 0.2.73

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 +43 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -396,6 +396,9 @@ import { execSync as execSync2, exec } from "child_process";
396
396
  import { promisify } from "util";
397
397
  import { userInfo as userInfo2 } from "os";
398
398
  var execAsync = promisify(exec);
399
+ var debug = (...args) => {
400
+ if (process.env.CCCLUB_DEBUG) console.error("[usage-debug]", ...args);
401
+ };
399
402
  function parseUtilization(value) {
400
403
  if (typeof value === "number") return Math.round(value * 100) / 100;
401
404
  if (typeof value === "string") {
@@ -406,27 +409,49 @@ function parseUtilization(value) {
406
409
  }
407
410
  async function fetchUsageLimits() {
408
411
  try {
409
- const username = userInfo2().username;
412
+ const username = process.env.USER || process.env.USERNAME || userInfo2().username;
413
+ debug("username:", username);
410
414
  const raw = execSync2(
411
415
  `security find-generic-password -s "Claude Code-credentials" -a "${username}" -w`,
412
416
  { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], timeout: 5e3 }
413
417
  ).trim();
418
+ debug("keychain raw length:", raw.length, "first 40:", raw.slice(0, 40));
414
419
  const credentials = JSON.parse(raw);
415
420
  const accessToken = credentials?.claudeAiOauth?.accessToken;
416
- if (!accessToken || typeof accessToken !== "string") return null;
417
- const curlCmd = `curl -sf --max-time 8 "https://api.anthropic.com/api/oauth/usage" -H "Authorization: Bearer ${accessToken}" -H "anthropic-beta: oauth-2025-04-20" -H "User-Agent: claude-code/2.1.5"`;
421
+ const expiresAt = credentials?.claudeAiOauth?.expiresAt;
422
+ debug("accessToken present:", !!accessToken, "expiresAt:", expiresAt);
423
+ if (!accessToken || typeof accessToken !== "string") {
424
+ debug("returning null: no accessToken");
425
+ return null;
426
+ }
427
+ if (expiresAt && Date.now() / 1e3 > expiresAt) {
428
+ debug("returning null: token expired at", expiresAt);
429
+ return null;
430
+ }
431
+ const curlCmd = `curl -sf --max-time 8 --noproxy '*' "https://api.anthropic.com/api/oauth/usage" -H "Authorization: Bearer ${accessToken}" -H "anthropic-beta: oauth-2025-04-20" -H "User-Agent: claude-code/2.1.5"`;
432
+ debug("running curl...");
418
433
  const { stdout: stdout5 } = await execAsync(curlCmd, { timeout: 9e3 });
419
- if (!stdout5) return null;
434
+ debug("curl stdout length:", stdout5.length, "first 100:", stdout5.slice(0, 100));
435
+ if (!stdout5) {
436
+ debug("returning null: empty stdout");
437
+ return null;
438
+ }
420
439
  const data = JSON.parse(stdout5);
421
- if (data.error) return null;
440
+ if (data.error) {
441
+ debug("returning null: data.error =", data.error);
442
+ return null;
443
+ }
422
444
  const fiveHourRaw = data.five_hour?.utilization;
423
445
  const sevenDayRaw = data.seven_day?.utilization;
424
- return {
446
+ const result = {
425
447
  fiveHour: parseUtilization(fiveHourRaw),
426
448
  sevenDay: parseUtilization(sevenDayRaw),
427
449
  snapshotAt: (/* @__PURE__ */ new Date()).toISOString()
428
450
  };
429
- } catch {
451
+ debug("returning snapshot:", result.fiveHour, result.sevenDay);
452
+ return result;
453
+ } catch (err) {
454
+ debug("caught error:", err instanceof Error ? err.message : String(err));
430
455
  return null;
431
456
  }
432
457
  }
@@ -856,6 +881,12 @@ async function rankCommand(options) {
856
881
  const data = await res.json();
857
882
  if (i === 0) spinner.stop();
858
883
  const localSnapshot = await localUsagePromise;
884
+ if (process.env.CCCLUB_DEBUG) {
885
+ console.error("[usage-debug] localSnapshot:", localSnapshot);
886
+ console.error("[usage-debug] config.userId:", config.userId);
887
+ const dbgMe = data.rankings.find((r) => r.userId === config.userId);
888
+ console.error("[usage-debug] me found:", !!dbgMe, "rankings userIds:", data.rankings.map((r) => r.userId).slice(0, 3));
889
+ }
859
890
  if (localSnapshot) {
860
891
  const me = data.rankings.find((r) => r.userId === config.userId);
861
892
  if (me) me.usageSnapshot = localSnapshot;
@@ -907,8 +938,8 @@ function printGroup(data, code, period, config, showCache = false) {
907
938
  const head = ["#", "Name", "Cost", "Tokens"];
908
939
  const widths = [5, 20, 12, 10];
909
940
  if (hasUsage) {
910
- head.push("Usage (5h/7d)");
911
- widths.push(14);
941
+ head.push("Usage 7d");
942
+ widths.push(10);
912
943
  }
913
944
  if (hasPlan) {
914
945
  head.push("Monthly ROI");
@@ -936,8 +967,8 @@ function printGroup(data, code, period, config, showCache = false) {
936
967
  ];
937
968
  if (hasUsage) {
938
969
  if (entry.usageSnapshot) {
939
- const { fiveHour, sevenDay } = entry.usageSnapshot;
940
- row.push(c(`${Math.round(fiveHour)}%/${Math.round(sevenDay)}%`));
970
+ const { sevenDay } = entry.usageSnapshot;
971
+ row.push(c(`${Math.round(sevenDay)}%`));
941
972
  } else {
942
973
  row.push(chalk6.dim("\u2014"));
943
974
  }
@@ -1307,7 +1338,7 @@ async function hookCommand() {
1307
1338
  }
1308
1339
 
1309
1340
  // src/index.ts
1310
- var VERSION = "0.2.72";
1341
+ var VERSION = "0.2.73";
1311
1342
  startUpdateCheck(VERSION);
1312
1343
  var program = new Command();
1313
1344
  program.name("ccclub").description("Claude Code leaderboard among friends").version(VERSION, "-v, -V, --version");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccclub",
3
- "version": "0.2.72",
3
+ "version": "0.2.73",
4
4
  "type": "module",
5
5
  "description": "Claude Code leaderboard among friends",
6
6
  "bin": {