ccclub 0.3.10 → 0.3.12
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 +57 -20
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -56,20 +56,30 @@ var PLAN_LABELS = {
|
|
|
56
56
|
api: "API"
|
|
57
57
|
};
|
|
58
58
|
var MODEL_PRICING = {
|
|
59
|
-
// Opus 4.5+
|
|
59
|
+
// Claude Opus 4.5+
|
|
60
|
+
"claude-opus-4-7": { input: 5, output: 25, cacheCreation: 6.25, cacheRead: 0.5 },
|
|
60
61
|
"claude-opus-4-6": { input: 5, output: 25, cacheCreation: 6.25, cacheRead: 0.5 },
|
|
62
|
+
"claude-opus-4-5": { input: 5, output: 25, cacheCreation: 6.25, cacheRead: 0.5 },
|
|
61
63
|
"claude-opus-4-5-20251101": { input: 5, output: 25, cacheCreation: 6.25, cacheRead: 0.5 },
|
|
62
64
|
// Opus 4.0–4.1
|
|
63
65
|
"claude-opus-4-1-20250805": { input: 15, output: 75, cacheCreation: 18.75, cacheRead: 1.5 },
|
|
64
66
|
// Sonnet
|
|
67
|
+
"claude-sonnet-4-6": { input: 3, output: 15, cacheCreation: 3.75, cacheRead: 0.3 },
|
|
68
|
+
"claude-sonnet-4-5": { input: 3, output: 15, cacheCreation: 3.75, cacheRead: 0.3 },
|
|
65
69
|
"claude-sonnet-4-5-20250929": { input: 3, output: 15, cacheCreation: 3.75, cacheRead: 0.3 },
|
|
66
70
|
"claude-sonnet-4-20250514": { input: 3, output: 15, cacheCreation: 3.75, cacheRead: 0.3 },
|
|
67
71
|
"claude-3-5-sonnet-20241022": { input: 3, output: 15, cacheCreation: 3.75, cacheRead: 0.3 },
|
|
68
72
|
// Haiku
|
|
69
73
|
"claude-haiku-4-5-20251001": { input: 1, output: 5, cacheCreation: 1.25, cacheRead: 0.1 },
|
|
70
74
|
"claude-3-5-haiku-20241022": { input: 0.8, output: 4, cacheCreation: 1, cacheRead: 0.08 },
|
|
71
|
-
// OpenAI GPT family
|
|
72
|
-
|
|
75
|
+
// OpenAI GPT/Codex family.
|
|
76
|
+
"gpt-5.5": { input: 5, output: 30, cacheCreation: 0, cacheRead: 0.5 },
|
|
77
|
+
"gpt-5.4": { input: 2.5, output: 15, cacheCreation: 0, cacheRead: 0.25 },
|
|
78
|
+
"gpt-5.4-mini": { input: 0.75, output: 4.5, cacheCreation: 0, cacheRead: 0.075 },
|
|
79
|
+
"gpt-5.4-nano": { input: 0.2, output: 1.25, cacheCreation: 0, cacheRead: 0.02 },
|
|
80
|
+
"gpt-5.3-codex": { input: 1.75, output: 14, cacheCreation: 0, cacheRead: 0.175 },
|
|
81
|
+
"gpt-5.2-codex": { input: 1.75, output: 14, cacheCreation: 0, cacheRead: 0.175 },
|
|
82
|
+
"gpt-5-codex": { input: 1.25, output: 10, cacheCreation: 0, cacheRead: 0.125 },
|
|
73
83
|
"gpt-5": { input: 1.25, output: 10, cacheCreation: 0, cacheRead: 0.125 },
|
|
74
84
|
"gpt-5-mini": { input: 0.25, output: 2, cacheCreation: 0, cacheRead: 0.025 },
|
|
75
85
|
"gpt-5-nano": { input: 0.05, output: 0.4, cacheCreation: 0, cacheRead: 5e-3 }
|
|
@@ -78,6 +88,13 @@ var FAMILY_FALLBACK = {
|
|
|
78
88
|
opus: MODEL_PRICING["claude-opus-4-6"],
|
|
79
89
|
sonnet: MODEL_PRICING["claude-sonnet-4-5-20250929"],
|
|
80
90
|
haiku: MODEL_PRICING["claude-haiku-4-5-20251001"],
|
|
91
|
+
"gpt-5.5": MODEL_PRICING["gpt-5.5"],
|
|
92
|
+
"gpt-5.4-mini": MODEL_PRICING["gpt-5.4-mini"],
|
|
93
|
+
"gpt-5.4-nano": MODEL_PRICING["gpt-5.4-nano"],
|
|
94
|
+
"gpt-5.4": MODEL_PRICING["gpt-5.4"],
|
|
95
|
+
"gpt-5.3-codex": MODEL_PRICING["gpt-5.3-codex"],
|
|
96
|
+
"gpt-5.2-codex": MODEL_PRICING["gpt-5.2-codex"],
|
|
97
|
+
"gpt-5-codex": MODEL_PRICING["gpt-5-codex"],
|
|
81
98
|
"gpt-5-nano": MODEL_PRICING["gpt-5-nano"],
|
|
82
99
|
"gpt-5-mini": MODEL_PRICING["gpt-5-mini"],
|
|
83
100
|
"gpt-5": MODEL_PRICING["gpt-5"],
|
|
@@ -241,7 +258,7 @@ function isHookInstalled() {
|
|
|
241
258
|
import { writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
|
|
242
259
|
import { join as join3 } from "path";
|
|
243
260
|
import { homedir as homedir3 } from "os";
|
|
244
|
-
import { existsSync as existsSync3 } from "fs";
|
|
261
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
|
|
245
262
|
import { execFile } from "child_process";
|
|
246
263
|
var PLIST_NAME = "dev.ccclub.sync";
|
|
247
264
|
var LAUNCH_AGENTS_DIR = join3(homedir3(), "Library", "LaunchAgents");
|
|
@@ -278,32 +295,49 @@ function getPlist() {
|
|
|
278
295
|
</dict>
|
|
279
296
|
</plist>`;
|
|
280
297
|
}
|
|
298
|
+
function isCurrentPlist() {
|
|
299
|
+
if (!existsSync3(PLIST_PATH)) return false;
|
|
300
|
+
try {
|
|
301
|
+
return readFileSync2(PLIST_PATH, "utf-8") === getPlist();
|
|
302
|
+
} catch {
|
|
303
|
+
return false;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
async function launchctl(args) {
|
|
307
|
+
await new Promise((resolve2, reject) => {
|
|
308
|
+
execFile("launchctl", args, (err) => err ? reject(err) : resolve2());
|
|
309
|
+
});
|
|
310
|
+
}
|
|
281
311
|
async function installHeartbeat() {
|
|
282
312
|
if (process.platform !== "darwin") {
|
|
283
313
|
return false;
|
|
284
314
|
}
|
|
285
|
-
if (
|
|
315
|
+
if (isCurrentPlist()) {
|
|
286
316
|
return true;
|
|
287
317
|
}
|
|
288
318
|
if (!existsSync3(LAUNCH_AGENTS_DIR)) {
|
|
289
319
|
await mkdir3(LAUNCH_AGENTS_DIR, { recursive: true });
|
|
290
320
|
}
|
|
321
|
+
if (existsSync3(PLIST_PATH)) {
|
|
322
|
+
try {
|
|
323
|
+
await launchctl(["unload", PLIST_PATH]);
|
|
324
|
+
} catch {
|
|
325
|
+
}
|
|
326
|
+
}
|
|
291
327
|
await writeFile3(PLIST_PATH, getPlist());
|
|
292
328
|
try {
|
|
293
|
-
await
|
|
294
|
-
execFile("launchctl", ["load", PLIST_PATH], (err) => err ? reject(err) : resolve2());
|
|
295
|
-
});
|
|
329
|
+
await launchctl(["load", PLIST_PATH]);
|
|
296
330
|
} catch {
|
|
297
331
|
}
|
|
298
332
|
return true;
|
|
299
333
|
}
|
|
300
334
|
function isHeartbeatInstalled() {
|
|
301
|
-
return
|
|
335
|
+
return isCurrentPlist();
|
|
302
336
|
}
|
|
303
337
|
|
|
304
338
|
// src/commands/sync.ts
|
|
305
339
|
import { readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
|
|
306
|
-
import { existsSync as existsSync4, readFileSync as
|
|
340
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
307
341
|
import { join as join11 } from "path";
|
|
308
342
|
import { homedir as homedir11 } from "os";
|
|
309
343
|
import chalk2 from "chalk";
|
|
@@ -1136,7 +1170,7 @@ import { execSync as execSync2, exec } from "child_process";
|
|
|
1136
1170
|
import { promisify } from "util";
|
|
1137
1171
|
import { userInfo as userInfo2, homedir as homedir10 } from "os";
|
|
1138
1172
|
import { join as join10 } from "path";
|
|
1139
|
-
import { readFileSync as
|
|
1173
|
+
import { readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
1140
1174
|
var execAsync = promisify(exec);
|
|
1141
1175
|
var debug = (...args) => {
|
|
1142
1176
|
if (process.env.CCCLUB_DEBUG) console.error("[usage-debug]", ...args);
|
|
@@ -1145,7 +1179,7 @@ var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
|
1145
1179
|
var CACHE_PATH = join10(homedir10(), CCCLUB_CONFIG_DIR, "usage-cache.json");
|
|
1146
1180
|
function readCache(allowStale = false) {
|
|
1147
1181
|
try {
|
|
1148
|
-
const raw =
|
|
1182
|
+
const raw = readFileSync3(CACHE_PATH, "utf-8");
|
|
1149
1183
|
const { snapshot, fetchedAt } = JSON.parse(raw);
|
|
1150
1184
|
if (allowStale || Date.now() - fetchedAt < CACHE_TTL_MS) return snapshot;
|
|
1151
1185
|
} catch {
|
|
@@ -1216,7 +1250,7 @@ async function fetchUsageLimits() {
|
|
|
1216
1250
|
debug("caught error:", err instanceof Error ? err.message : String(err));
|
|
1217
1251
|
}
|
|
1218
1252
|
try {
|
|
1219
|
-
const tmp = JSON.parse(
|
|
1253
|
+
const tmp = JSON.parse(readFileSync3("/tmp/sl-claude-usage", "utf-8"));
|
|
1220
1254
|
if (typeof tmp.fiveHour === "number" && typeof tmp.sevenDay === "number") {
|
|
1221
1255
|
const result = { fiveHour: tmp.fiveHour, sevenDay: tmp.sevenDay, snapshotAt: (/* @__PURE__ */ new Date()).toISOString() };
|
|
1222
1256
|
debug("returning cc-costline cache fallback:", result.fiveHour, result.sevenDay);
|
|
@@ -1242,7 +1276,7 @@ function needsFullSync() {
|
|
|
1242
1276
|
const path = getSyncVersionPath();
|
|
1243
1277
|
if (!existsSync4(path)) return true;
|
|
1244
1278
|
try {
|
|
1245
|
-
const stored =
|
|
1279
|
+
const stored = readFileSync4(path, "utf-8").trim();
|
|
1246
1280
|
return stored !== SYNC_FORMAT_VERSION;
|
|
1247
1281
|
} catch {
|
|
1248
1282
|
return true;
|
|
@@ -1254,7 +1288,7 @@ async function syncCommand(options) {
|
|
|
1254
1288
|
if (options.silent && !options.full) {
|
|
1255
1289
|
if (existsSync4(timePath)) {
|
|
1256
1290
|
try {
|
|
1257
|
-
const ts = parseInt(
|
|
1291
|
+
const ts = parseInt(readFileSync4(timePath, "utf-8").trim(), 10);
|
|
1258
1292
|
if (Date.now() - ts < THROTTLE_MS) return;
|
|
1259
1293
|
} catch {
|
|
1260
1294
|
}
|
|
@@ -1599,7 +1633,7 @@ import Table from "cli-table3";
|
|
|
1599
1633
|
import ora4 from "ora";
|
|
1600
1634
|
|
|
1601
1635
|
// src/update-check.ts
|
|
1602
|
-
import { readFileSync as
|
|
1636
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync5 } from "fs";
|
|
1603
1637
|
import { join as join12 } from "path";
|
|
1604
1638
|
import { homedir as homedir12 } from "os";
|
|
1605
1639
|
var CHECK_INTERVAL_MS = 12 * 60 * 60 * 1e3;
|
|
@@ -1609,7 +1643,7 @@ function startUpdateCheck(currentVersion) {
|
|
|
1609
1643
|
if (process.argv.includes("--silent") || process.argv.includes("-s")) return;
|
|
1610
1644
|
try {
|
|
1611
1645
|
if (existsSync5(CHECK_FILE)) {
|
|
1612
|
-
const ts = parseInt(
|
|
1646
|
+
const ts = parseInt(readFileSync5(CHECK_FILE, "utf-8").trim(), 10);
|
|
1613
1647
|
if (Date.now() - ts < CHECK_INTERVAL_MS) return;
|
|
1614
1648
|
}
|
|
1615
1649
|
} catch {
|
|
@@ -1777,7 +1811,7 @@ function printGroup(data, code, period, config, showCache = false, showAll = fal
|
|
|
1777
1811
|
${data.group.name}`));
|
|
1778
1812
|
const periodLabel = { daily: "TODAY", yesterday: "YESTERDAY", weekly: "7 DAYS", monthly: "30 DAYS", "all-time": "ALL TIME" };
|
|
1779
1813
|
const now = Date.now();
|
|
1780
|
-
const activeCount = data.rankings.filter((r) => r
|
|
1814
|
+
const activeCount = data.rankings.filter((r) => isEntryActive(r, now)).length;
|
|
1781
1815
|
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`));
|
|
1782
1816
|
if (activeCount > 0) {
|
|
1783
1817
|
console.log(theme.success(` ${activeCount} active`));
|
|
@@ -1872,7 +1906,10 @@ function printGroup(data, code, period, config, showCache = false, showAll = fal
|
|
|
1872
1906
|
}
|
|
1873
1907
|
}
|
|
1874
1908
|
function isEntryActive(entry, now) {
|
|
1875
|
-
|
|
1909
|
+
const value = entry.lastActiveAt || entry.lastSync;
|
|
1910
|
+
if (!value) return false;
|
|
1911
|
+
const activeAt = new Date(value).getTime();
|
|
1912
|
+
return Number.isFinite(activeAt) && now - activeAt < ACTIVE_THRESHOLD_MS;
|
|
1876
1913
|
}
|
|
1877
1914
|
function podiumStyle(rank) {
|
|
1878
1915
|
if (rank === 1) return theme.gold;
|
|
@@ -2286,7 +2323,7 @@ async function hookCommand() {
|
|
|
2286
2323
|
}
|
|
2287
2324
|
|
|
2288
2325
|
// src/index.ts
|
|
2289
|
-
var VERSION = "0.3.
|
|
2326
|
+
var VERSION = "0.3.12";
|
|
2290
2327
|
startUpdateCheck(VERSION);
|
|
2291
2328
|
var program = new Command();
|
|
2292
2329
|
if (process.argv.slice(2).includes("-v")) {
|