ccclub 0.3.10 → 0.3.11

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 +37 -17
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -241,7 +241,7 @@ function isHookInstalled() {
241
241
  import { writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
242
242
  import { join as join3 } from "path";
243
243
  import { homedir as homedir3 } from "os";
244
- import { existsSync as existsSync3 } from "fs";
244
+ import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
245
245
  import { execFile } from "child_process";
246
246
  var PLIST_NAME = "dev.ccclub.sync";
247
247
  var LAUNCH_AGENTS_DIR = join3(homedir3(), "Library", "LaunchAgents");
@@ -278,32 +278,49 @@ function getPlist() {
278
278
  </dict>
279
279
  </plist>`;
280
280
  }
281
+ function isCurrentPlist() {
282
+ if (!existsSync3(PLIST_PATH)) return false;
283
+ try {
284
+ return readFileSync2(PLIST_PATH, "utf-8") === getPlist();
285
+ } catch {
286
+ return false;
287
+ }
288
+ }
289
+ async function launchctl(args) {
290
+ await new Promise((resolve2, reject) => {
291
+ execFile("launchctl", args, (err) => err ? reject(err) : resolve2());
292
+ });
293
+ }
281
294
  async function installHeartbeat() {
282
295
  if (process.platform !== "darwin") {
283
296
  return false;
284
297
  }
285
- if (existsSync3(PLIST_PATH)) {
298
+ if (isCurrentPlist()) {
286
299
  return true;
287
300
  }
288
301
  if (!existsSync3(LAUNCH_AGENTS_DIR)) {
289
302
  await mkdir3(LAUNCH_AGENTS_DIR, { recursive: true });
290
303
  }
304
+ if (existsSync3(PLIST_PATH)) {
305
+ try {
306
+ await launchctl(["unload", PLIST_PATH]);
307
+ } catch {
308
+ }
309
+ }
291
310
  await writeFile3(PLIST_PATH, getPlist());
292
311
  try {
293
- await new Promise((resolve2, reject) => {
294
- execFile("launchctl", ["load", PLIST_PATH], (err) => err ? reject(err) : resolve2());
295
- });
312
+ await launchctl(["load", PLIST_PATH]);
296
313
  } catch {
297
314
  }
298
315
  return true;
299
316
  }
300
317
  function isHeartbeatInstalled() {
301
- return existsSync3(PLIST_PATH);
318
+ return isCurrentPlist();
302
319
  }
303
320
 
304
321
  // src/commands/sync.ts
305
322
  import { readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
306
- import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
323
+ import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
307
324
  import { join as join11 } from "path";
308
325
  import { homedir as homedir11 } from "os";
309
326
  import chalk2 from "chalk";
@@ -1136,7 +1153,7 @@ import { execSync as execSync2, exec } from "child_process";
1136
1153
  import { promisify } from "util";
1137
1154
  import { userInfo as userInfo2, homedir as homedir10 } from "os";
1138
1155
  import { join as join10 } from "path";
1139
- import { readFileSync as readFileSync2, writeFileSync } from "fs";
1156
+ import { readFileSync as readFileSync3, writeFileSync } from "fs";
1140
1157
  var execAsync = promisify(exec);
1141
1158
  var debug = (...args) => {
1142
1159
  if (process.env.CCCLUB_DEBUG) console.error("[usage-debug]", ...args);
@@ -1145,7 +1162,7 @@ var CACHE_TTL_MS = 5 * 60 * 1e3;
1145
1162
  var CACHE_PATH = join10(homedir10(), CCCLUB_CONFIG_DIR, "usage-cache.json");
1146
1163
  function readCache(allowStale = false) {
1147
1164
  try {
1148
- const raw = readFileSync2(CACHE_PATH, "utf-8");
1165
+ const raw = readFileSync3(CACHE_PATH, "utf-8");
1149
1166
  const { snapshot, fetchedAt } = JSON.parse(raw);
1150
1167
  if (allowStale || Date.now() - fetchedAt < CACHE_TTL_MS) return snapshot;
1151
1168
  } catch {
@@ -1216,7 +1233,7 @@ async function fetchUsageLimits() {
1216
1233
  debug("caught error:", err instanceof Error ? err.message : String(err));
1217
1234
  }
1218
1235
  try {
1219
- const tmp = JSON.parse(readFileSync2("/tmp/sl-claude-usage", "utf-8"));
1236
+ const tmp = JSON.parse(readFileSync3("/tmp/sl-claude-usage", "utf-8"));
1220
1237
  if (typeof tmp.fiveHour === "number" && typeof tmp.sevenDay === "number") {
1221
1238
  const result = { fiveHour: tmp.fiveHour, sevenDay: tmp.sevenDay, snapshotAt: (/* @__PURE__ */ new Date()).toISOString() };
1222
1239
  debug("returning cc-costline cache fallback:", result.fiveHour, result.sevenDay);
@@ -1242,7 +1259,7 @@ function needsFullSync() {
1242
1259
  const path = getSyncVersionPath();
1243
1260
  if (!existsSync4(path)) return true;
1244
1261
  try {
1245
- const stored = readFileSync3(path, "utf-8").trim();
1262
+ const stored = readFileSync4(path, "utf-8").trim();
1246
1263
  return stored !== SYNC_FORMAT_VERSION;
1247
1264
  } catch {
1248
1265
  return true;
@@ -1254,7 +1271,7 @@ async function syncCommand(options) {
1254
1271
  if (options.silent && !options.full) {
1255
1272
  if (existsSync4(timePath)) {
1256
1273
  try {
1257
- const ts = parseInt(readFileSync3(timePath, "utf-8").trim(), 10);
1274
+ const ts = parseInt(readFileSync4(timePath, "utf-8").trim(), 10);
1258
1275
  if (Date.now() - ts < THROTTLE_MS) return;
1259
1276
  } catch {
1260
1277
  }
@@ -1599,7 +1616,7 @@ import Table from "cli-table3";
1599
1616
  import ora4 from "ora";
1600
1617
 
1601
1618
  // src/update-check.ts
1602
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync3, existsSync as existsSync5 } from "fs";
1619
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync3, existsSync as existsSync5 } from "fs";
1603
1620
  import { join as join12 } from "path";
1604
1621
  import { homedir as homedir12 } from "os";
1605
1622
  var CHECK_INTERVAL_MS = 12 * 60 * 60 * 1e3;
@@ -1609,7 +1626,7 @@ function startUpdateCheck(currentVersion) {
1609
1626
  if (process.argv.includes("--silent") || process.argv.includes("-s")) return;
1610
1627
  try {
1611
1628
  if (existsSync5(CHECK_FILE)) {
1612
- const ts = parseInt(readFileSync4(CHECK_FILE, "utf-8").trim(), 10);
1629
+ const ts = parseInt(readFileSync5(CHECK_FILE, "utf-8").trim(), 10);
1613
1630
  if (Date.now() - ts < CHECK_INTERVAL_MS) return;
1614
1631
  }
1615
1632
  } catch {
@@ -1777,7 +1794,7 @@ function printGroup(data, code, period, config, showCache = false, showAll = fal
1777
1794
  ${data.group.name}`));
1778
1795
  const periodLabel = { daily: "TODAY", yesterday: "YESTERDAY", weekly: "7 DAYS", monthly: "30 DAYS", "all-time": "ALL TIME" };
1779
1796
  const now = Date.now();
1780
- const activeCount = data.rankings.filter((r) => r.lastSync && now - new Date(r.lastSync).getTime() < ACTIVE_THRESHOLD_MS).length;
1797
+ const activeCount = data.rankings.filter((r) => isEntryActive(r, now)).length;
1781
1798
  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
1799
  if (activeCount > 0) {
1783
1800
  console.log(theme.success(` ${activeCount} active`));
@@ -1872,7 +1889,10 @@ function printGroup(data, code, period, config, showCache = false, showAll = fal
1872
1889
  }
1873
1890
  }
1874
1891
  function isEntryActive(entry, now) {
1875
- return Boolean(entry.lastSync && now - new Date(entry.lastSync).getTime() < ACTIVE_THRESHOLD_MS);
1892
+ const value = entry.lastActiveAt || entry.lastSync;
1893
+ if (!value) return false;
1894
+ const activeAt = new Date(value).getTime();
1895
+ return Number.isFinite(activeAt) && now - activeAt < ACTIVE_THRESHOLD_MS;
1876
1896
  }
1877
1897
  function podiumStyle(rank) {
1878
1898
  if (rank === 1) return theme.gold;
@@ -2286,7 +2306,7 @@ async function hookCommand() {
2286
2306
  }
2287
2307
 
2288
2308
  // src/index.ts
2289
- var VERSION = "0.3.10";
2309
+ var VERSION = "0.3.11";
2290
2310
  startUpdateCheck(VERSION);
2291
2311
  var program = new Command();
2292
2312
  if (process.argv.slice(2).includes("-v")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccclub",
3
- "version": "0.3.10",
3
+ "version": "0.3.11",
4
4
  "type": "module",
5
5
  "description": "Claude Code and Codex leaderboard among friends for coding agent tokens and costs",
6
6
  "bin": {