ccclub 0.2.78 → 0.2.80
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 +55 -18
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -206,9 +206,9 @@ function isHookInstalled() {
|
|
|
206
206
|
|
|
207
207
|
// src/commands/sync.ts
|
|
208
208
|
import { readFile as readFile4, writeFile as writeFile3 } from "fs/promises";
|
|
209
|
-
import { existsSync as existsSync3, readFileSync as
|
|
210
|
-
import { join as
|
|
211
|
-
import { homedir as
|
|
209
|
+
import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
210
|
+
import { join as join5 } from "path";
|
|
211
|
+
import { homedir as homedir5 } from "os";
|
|
212
212
|
import chalk2 from "chalk";
|
|
213
213
|
import ora from "ora";
|
|
214
214
|
|
|
@@ -394,11 +394,30 @@ function formatFetchError(err) {
|
|
|
394
394
|
// src/usage-limits.ts
|
|
395
395
|
import { execSync as execSync2, exec } from "child_process";
|
|
396
396
|
import { promisify } from "util";
|
|
397
|
-
import { userInfo as userInfo2 } from "os";
|
|
397
|
+
import { userInfo as userInfo2, homedir as homedir4 } from "os";
|
|
398
|
+
import { join as join4 } from "path";
|
|
399
|
+
import { readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
398
400
|
var execAsync = promisify(exec);
|
|
399
401
|
var debug = (...args) => {
|
|
400
402
|
if (process.env.CCCLUB_DEBUG) console.error("[usage-debug]", ...args);
|
|
401
403
|
};
|
|
404
|
+
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
405
|
+
var CACHE_PATH = join4(homedir4(), CCCLUB_CONFIG_DIR, "usage-cache.json");
|
|
406
|
+
function readCache(allowStale = false) {
|
|
407
|
+
try {
|
|
408
|
+
const raw = readFileSync2(CACHE_PATH, "utf-8");
|
|
409
|
+
const { snapshot, fetchedAt } = JSON.parse(raw);
|
|
410
|
+
if (allowStale || Date.now() - fetchedAt < CACHE_TTL_MS) return snapshot;
|
|
411
|
+
} catch {
|
|
412
|
+
}
|
|
413
|
+
return null;
|
|
414
|
+
}
|
|
415
|
+
function writeCache(snapshot) {
|
|
416
|
+
try {
|
|
417
|
+
writeFileSync(CACHE_PATH, JSON.stringify({ snapshot, fetchedAt: Date.now() }));
|
|
418
|
+
} catch {
|
|
419
|
+
}
|
|
420
|
+
}
|
|
402
421
|
function parseUtilization(value) {
|
|
403
422
|
if (typeof value === "number") return Math.round(value * 100) / 100;
|
|
404
423
|
if (typeof value === "string") {
|
|
@@ -408,6 +427,11 @@ function parseUtilization(value) {
|
|
|
408
427
|
return 0;
|
|
409
428
|
}
|
|
410
429
|
async function fetchUsageLimits() {
|
|
430
|
+
const cached = readCache();
|
|
431
|
+
if (cached) {
|
|
432
|
+
debug("returning cached snapshot:", cached.fiveHour, cached.sevenDay);
|
|
433
|
+
return cached;
|
|
434
|
+
}
|
|
411
435
|
try {
|
|
412
436
|
const username = process.env.USER || process.env.USERNAME || userInfo2().username;
|
|
413
437
|
debug("username:", username);
|
|
@@ -428,7 +452,7 @@ async function fetchUsageLimits() {
|
|
|
428
452
|
debug("returning null: token expired at", expiresAt);
|
|
429
453
|
return null;
|
|
430
454
|
}
|
|
431
|
-
const curlCmd = `curl -sf --max-time 8
|
|
455
|
+
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"`;
|
|
432
456
|
debug("running curl...");
|
|
433
457
|
const { stdout: stdout5 } = await execAsync(curlCmd, { timeout: 9e3 });
|
|
434
458
|
debug("curl stdout length:", stdout5.length, "first 100:", stdout5.slice(0, 100));
|
|
@@ -449,23 +473,36 @@ async function fetchUsageLimits() {
|
|
|
449
473
|
snapshotAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
450
474
|
};
|
|
451
475
|
debug("returning snapshot:", result.fiveHour, result.sevenDay);
|
|
476
|
+
writeCache(result);
|
|
452
477
|
return result;
|
|
453
478
|
} catch (err) {
|
|
454
479
|
debug("caught error:", err instanceof Error ? err.message : String(err));
|
|
455
|
-
|
|
480
|
+
try {
|
|
481
|
+
const tmp = JSON.parse(readFileSync2("/tmp/sl-claude-usage", "utf-8"));
|
|
482
|
+
if (typeof tmp.fiveHour === "number" && typeof tmp.sevenDay === "number") {
|
|
483
|
+
const result = { fiveHour: tmp.fiveHour, sevenDay: tmp.sevenDay, snapshotAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
484
|
+
debug("returning cc-costline cache fallback:", result.fiveHour, result.sevenDay);
|
|
485
|
+
writeCache(result);
|
|
486
|
+
return result;
|
|
487
|
+
}
|
|
488
|
+
} catch {
|
|
489
|
+
}
|
|
490
|
+
const stale = readCache(true);
|
|
491
|
+
if (stale) debug("returning stale cache as fallback:", stale.fiveHour, stale.sevenDay);
|
|
492
|
+
return stale;
|
|
456
493
|
}
|
|
457
494
|
}
|
|
458
495
|
|
|
459
496
|
// src/commands/sync.ts
|
|
460
497
|
var SYNC_FORMAT_VERSION = "6";
|
|
461
498
|
function getSyncVersionPath() {
|
|
462
|
-
return
|
|
499
|
+
return join5(homedir5(), CCCLUB_CONFIG_DIR, "sync-version");
|
|
463
500
|
}
|
|
464
501
|
function needsFullSync() {
|
|
465
502
|
const path = getSyncVersionPath();
|
|
466
503
|
if (!existsSync3(path)) return true;
|
|
467
504
|
try {
|
|
468
|
-
const stored =
|
|
505
|
+
const stored = readFileSync3(path, "utf-8").trim();
|
|
469
506
|
return stored !== SYNC_FORMAT_VERSION;
|
|
470
507
|
} catch {
|
|
471
508
|
return true;
|
|
@@ -477,13 +514,13 @@ async function syncCommand(options) {
|
|
|
477
514
|
if (options.silent && !options.full) {
|
|
478
515
|
if (existsSync3(timePath)) {
|
|
479
516
|
try {
|
|
480
|
-
const ts = parseInt(
|
|
517
|
+
const ts = parseInt(readFileSync3(timePath, "utf-8").trim(), 10);
|
|
481
518
|
if (Date.now() - ts < THROTTLE_MS) return;
|
|
482
519
|
} catch {
|
|
483
520
|
}
|
|
484
521
|
}
|
|
485
522
|
try {
|
|
486
|
-
|
|
523
|
+
writeFileSync2(timePath, String(Date.now()));
|
|
487
524
|
} catch {
|
|
488
525
|
}
|
|
489
526
|
}
|
|
@@ -492,7 +529,7 @@ async function syncCommand(options) {
|
|
|
492
529
|
} catch {
|
|
493
530
|
if (options.silent) {
|
|
494
531
|
try {
|
|
495
|
-
|
|
532
|
+
writeFileSync2(timePath, "0");
|
|
496
533
|
} catch {
|
|
497
534
|
}
|
|
498
535
|
}
|
|
@@ -780,17 +817,17 @@ import Table from "cli-table3";
|
|
|
780
817
|
import ora4 from "ora";
|
|
781
818
|
|
|
782
819
|
// src/update-check.ts
|
|
783
|
-
import { readFileSync as
|
|
784
|
-
import { join as
|
|
785
|
-
import { homedir as
|
|
820
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync4 } from "fs";
|
|
821
|
+
import { join as join6 } from "path";
|
|
822
|
+
import { homedir as homedir6 } from "os";
|
|
786
823
|
var CHECK_INTERVAL_MS = 12 * 60 * 60 * 1e3;
|
|
787
|
-
var CHECK_FILE =
|
|
824
|
+
var CHECK_FILE = join6(homedir6(), CCCLUB_CONFIG_DIR, "last-update-check");
|
|
788
825
|
var pendingCheck = null;
|
|
789
826
|
function startUpdateCheck(currentVersion) {
|
|
790
827
|
if (process.argv.includes("--silent") || process.argv.includes("-s")) return;
|
|
791
828
|
try {
|
|
792
829
|
if (existsSync4(CHECK_FILE)) {
|
|
793
|
-
const ts = parseInt(
|
|
830
|
+
const ts = parseInt(readFileSync4(CHECK_FILE, "utf-8").trim(), 10);
|
|
794
831
|
if (Date.now() - ts < CHECK_INTERVAL_MS) return;
|
|
795
832
|
}
|
|
796
833
|
} catch {
|
|
@@ -806,7 +843,7 @@ function startUpdateCheck(currentVersion) {
|
|
|
806
843
|
return { latest: data.version, current: currentVersion };
|
|
807
844
|
}
|
|
808
845
|
try {
|
|
809
|
-
|
|
846
|
+
writeFileSync3(CHECK_FILE, String(Date.now()));
|
|
810
847
|
} catch {
|
|
811
848
|
}
|
|
812
849
|
return null;
|
|
@@ -1360,7 +1397,7 @@ async function hookCommand() {
|
|
|
1360
1397
|
}
|
|
1361
1398
|
|
|
1362
1399
|
// src/index.ts
|
|
1363
|
-
var VERSION = "0.2.
|
|
1400
|
+
var VERSION = "0.2.80";
|
|
1364
1401
|
startUpdateCheck(VERSION);
|
|
1365
1402
|
var program = new Command();
|
|
1366
1403
|
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.
|
|
3
|
+
"version": "0.2.80",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Claude Code leaderboard among friends",
|
|
6
6
|
"bin": {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
15
|
+
"prepublishOnly": "npm run build",
|
|
15
16
|
"postinstall": "node scripts/postinstall.cjs",
|
|
16
17
|
"dev": "tsx src/index.ts",
|
|
17
18
|
"test": "vitest run"
|