ccclub 0.2.38 → 0.2.40

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 +27 -14
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -18,8 +18,8 @@ import { randomBytes } from "crypto";
18
18
  import { execSync } from "child_process";
19
19
 
20
20
  // ../shared/dist/constants.js
21
- var BLOCK_DURATION_HOURS = 1;
22
- var BLOCK_DURATION_MS = BLOCK_DURATION_HOURS * 60 * 60 * 1e3;
21
+ var BLOCK_DURATION_MIN = 30;
22
+ var BLOCK_DURATION_MS = BLOCK_DURATION_MIN * 60 * 1e3;
23
23
  var DEFAULT_API_URL = "https://ccclub.dev";
24
24
  var CLAUDE_PROJECTS_DIR = ".claude/projects";
25
25
  var CCCLUB_CONFIG_DIR = ".ccclub";
@@ -282,16 +282,17 @@ async function collectUsageEntries() {
282
282
  }
283
283
 
284
284
  // src/aggregator.ts
285
- function floorToHour(date) {
285
+ function floorToBlock(date) {
286
286
  const floored = new Date(date);
287
- floored.setUTCMinutes(0, 0, 0);
287
+ const min = floored.getUTCMinutes();
288
+ floored.setUTCMinutes(min - min % 30, 0, 0);
288
289
  return floored;
289
290
  }
290
291
  function aggregateToBlocks(entries, humanTurns = []) {
291
292
  if (entries.length === 0) return [];
292
293
  const humanTurnMs = humanTurns.map((t) => new Date(t).getTime());
293
294
  const blocks = [];
294
- let blockStart = floorToHour(new Date(entries[0].timestamp));
295
+ let blockStart = floorToBlock(new Date(entries[0].timestamp));
295
296
  let blockEnd = new Date(blockStart.getTime() + BLOCK_DURATION_MS);
296
297
  let currentBlock = [];
297
298
  let humanIdx = 0;
@@ -364,7 +365,7 @@ function aggregateToBlocks(entries, humanTurns = []) {
364
365
  }
365
366
 
366
367
  // src/commands/sync.ts
367
- var SYNC_FORMAT_VERSION = "5";
368
+ var SYNC_FORMAT_VERSION = "6";
368
369
  function getSyncVersionPath() {
369
370
  return join4(homedir4(), CCCLUB_CONFIG_DIR, "sync-version");
370
371
  }
@@ -380,8 +381,8 @@ function needsFullSync() {
380
381
  }
381
382
  var THROTTLE_MS = 5 * 60 * 1e3;
382
383
  async function syncCommand(options) {
384
+ const timePath = getLastSyncTimePath();
383
385
  if (options.silent && !options.full) {
384
- const timePath = getLastSyncTimePath();
385
386
  if (existsSync3(timePath)) {
386
387
  try {
387
388
  const ts = parseInt(readFileSync2(timePath, "utf-8").trim(), 10);
@@ -394,10 +395,20 @@ async function syncCommand(options) {
394
395
  } catch {
395
396
  }
396
397
  }
397
- await doSync(options.full || false, options.silent);
398
+ try {
399
+ await doSync(options.full || false, options.silent);
400
+ } catch {
401
+ if (options.silent) {
402
+ try {
403
+ writeFileSync(timePath, "0");
404
+ } catch {
405
+ }
406
+ }
407
+ }
398
408
  }
399
409
  async function doSync(firstSync = false, silent = false) {
400
- const config = await requireConfig();
410
+ const config = silent ? await loadConfig() : await requireConfig();
411
+ if (!config) return;
401
412
  if (!firstSync && needsFullSync()) {
402
413
  firstSync = true;
403
414
  }
@@ -440,8 +451,9 @@ async function doSync(firstSync = false, silent = false) {
440
451
  signal: AbortSignal.timeout(3e4)
441
452
  });
442
453
  if (!res.ok) {
443
- const err = await res.json().catch(() => ({ error: res.statusText }));
444
- if (spinner) spinner.fail(`Sync failed: ${err.error}`);
454
+ const errBody = await res.json().catch(() => ({ error: res.statusText }));
455
+ if (spinner) spinner.fail(`Sync failed: ${errBody.error}`);
456
+ if (silent) throw new Error(`sync failed: ${res.status}`);
445
457
  return;
446
458
  }
447
459
  const data = await res.json();
@@ -457,6 +469,7 @@ async function doSync(firstSync = false, silent = false) {
457
469
  }
458
470
  } catch (err) {
459
471
  if (spinner) spinner.fail(`Sync error: ${err instanceof Error ? err.message : err}`);
472
+ if (silent) throw err;
460
473
  }
461
474
  }
462
475
 
@@ -842,7 +855,7 @@ async function printActivity(apiUrl, code, range) {
842
855
  if (active.length === 0) return;
843
856
  const startMs = new Date(data.start).getTime();
844
857
  const endMs = new Date(data.end).getTime();
845
- const bucketCount = range === "24h" ? 24 : range === "7d" ? 28 : 30;
858
+ const bucketCount = range === "24h" ? 48 : range === "7d" ? 28 : 30;
846
859
  const bucketMs = (endMs - startMs) / bucketCount;
847
860
  const allBuckets = [];
848
861
  for (const user of active) {
@@ -974,7 +987,7 @@ async function profileCommand(options) {
974
987
  import chalk7 from "chalk";
975
988
  async function showDataCommand() {
976
989
  console.log(chalk7.bold("\n What CCClub uploads:\n"));
977
- console.log(chalk7.dim(" Only aggregated 1-hour block summaries. No conversation content,"));
990
+ console.log(chalk7.dim(" Only aggregated 30-minute block summaries. No conversation content,"));
978
991
  console.log(chalk7.dim(" no file paths, no project names, no session details.\n"));
979
992
  const { entries, humanTurns } = await collectUsageEntries();
980
993
  const blocks = aggregateToBlocks(entries, humanTurns);
@@ -1069,7 +1082,7 @@ async function hookCommand() {
1069
1082
  }
1070
1083
 
1071
1084
  // src/index.ts
1072
- var VERSION = "0.2.38";
1085
+ var VERSION = "0.2.40";
1073
1086
  startUpdateCheck(VERSION);
1074
1087
  var program = new Command();
1075
1088
  program.name("ccclub").description("CCClub - Compare Claude Code usage with friends").version(VERSION);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccclub",
3
- "version": "0.2.38",
3
+ "version": "0.2.40",
4
4
  "type": "module",
5
5
  "description": "See how much Claude Code you and your friends are using",
6
6
  "bin": {