ccgather 2.0.34 → 2.0.36

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 +56 -31
  2. package/package.json +55 -55
package/dist/index.js CHANGED
@@ -67,6 +67,31 @@ var init_config = __esm({
67
67
  function hyperlink(text, url) {
68
68
  return `\x1B]8;;${url}\x07${text}\x1B]8;;\x07`;
69
69
  }
70
+ function interpolateHex(t) {
71
+ const r = Math.round(218 + 29 * t);
72
+ const g = Math.round(119 + 28 * t);
73
+ const b = Math.round(86 - 56 * t);
74
+ return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
75
+ }
76
+ function renderChromeGradientLogo() {
77
+ const word = "CCGATHER";
78
+ const rows = [[], [], []];
79
+ for (let i = 0; i < word.length; i++) {
80
+ const ch = word[i];
81
+ const glyph = CHROME_FONT[ch];
82
+ if (!glyph) continue;
83
+ const color = import_chalk.default.hex(interpolateHex(i / (word.length - 1)));
84
+ for (let row = 0; row < 3; row++) {
85
+ if (rows[row].length > 0) rows[row].push(color(" "));
86
+ rows[row].push(color(glyph[row]));
87
+ }
88
+ }
89
+ return [rows[0].join(""), rows[1].join(""), rows[2].join("")];
90
+ }
91
+ function padLine(content) {
92
+ const w = getDisplayWidth(content);
93
+ return content + " ".repeat(Math.max(0, HEADER_WIDTH - w));
94
+ }
70
95
  function centerText(text, width) {
71
96
  const len = getDisplayWidth(text);
72
97
  const pad = width - len;
@@ -76,34 +101,33 @@ function createProfessionalHeader() {
76
101
  const lines = [];
77
102
  const v = boxRound.vertical;
78
103
  const h = boxRound.horizontal;
79
- lines.push(colors.dim(` ${boxRound.topLeft}${h.repeat(HEADER_WIDTH)}${boxRound.topRight}`));
80
- const logoLines = [
81
- `${colors.primary("\u2584\u2588\u2580\u2580 \u2584\u2588\u2580\u2580")} ${colors.secondary("\u2584\u2588\u2580\u2580 \u2584\u2588\u2580\u2588\u2584 \u2580\u2588\u2580 \u2588 \u2588 \u2588\u2580\u2580 \u2588\u2580\u2588")}`,
82
- `${colors.primary("\u2588 \u2588 ")} ${colors.secondary("\u2588 \u2580\u2588 \u2588\u2580\u2580\u2588\u2580 \u2588 \u2588\u2580\u2580\u2588 \u2588\u2580\u2580 \u2588\u2588\u2580")}`,
83
- `${colors.primary("\u2580\u2588\u2584\u2584 \u2580\u2588\u2584\u2584")} ${colors.secondary("\u2580\u2588\u2584\u2584\u2580 \u2588 \u2588 \u2588 \u2588 \u2588 \u2588\u2584\u2584 \u2588 \u2588")}`
84
- ];
85
- for (const l of logoLines) {
86
- lines.push(colors.dim(` ${v}`) + centerText(l, HEADER_WIDTH) + colors.dim(v));
104
+ const dim = colors.dim;
105
+ lines.push(dim(` ${boxRound.topLeft}${h.repeat(HEADER_WIDTH)}${boxRound.topRight}`));
106
+ lines.push(dim(` ${v}`) + padLine("") + dim(v));
107
+ const logoRows = renderChromeGradientLogo();
108
+ const logoPadLeft = 7;
109
+ const logoPadRight = HEADER_WIDTH - logoPadLeft - 31;
110
+ for (const row of logoRows) {
111
+ lines.push(dim(` ${v}`) + " ".repeat(logoPadLeft) + row + " ".repeat(logoPadRight) + dim(v));
87
112
  }
88
113
  const versionStr = `v${VERSION}`;
89
- const versionPad = HEADER_WIDTH - versionStr.length - 2;
114
+ const versionPad = HEADER_WIDTH - getDisplayWidth(versionStr) - 2;
115
+ lines.push(dim(` ${v}`) + " ".repeat(Math.max(0, versionPad)) + dim(versionStr) + " " + dim(v));
116
+ lines.push(dim(` ${boxRound.leftT}${h.repeat(HEADER_WIDTH)}${boxRound.rightT}`));
90
117
  lines.push(
91
- colors.dim(` ${v}`) + " ".repeat(versionPad) + colors.dim(versionStr) + " " + colors.dim(v)
118
+ dim(` ${v}`) + padLine(centerText(colors.muted("Proof of your Claude Code dedication"), HEADER_WIDTH)) + dim(v)
92
119
  );
93
- lines.push(colors.dim(` ${boxRound.leftT}${h.repeat(HEADER_WIDTH)}${boxRound.rightT}`));
94
120
  lines.push(
95
- colors.dim(` ${v}`) + centerText(colors.muted("Proof of your Claude Code dedication"), HEADER_WIDTH) + colors.dim(v)
121
+ dim(` ${v}`) + padLine(centerText(colors.dim("Track \xB7 Prove \xB7 Rise"), HEADER_WIDTH)) + dim(v)
96
122
  );
97
- lines.push(
98
- colors.dim(` ${v}`) + centerText(colors.dim("Track \xB7 Prove \xB7 Rise"), HEADER_WIDTH) + colors.dim(v)
99
- );
100
- lines.push(colors.dim(` ${v}`) + " ".repeat(HEADER_WIDTH) + colors.dim(v));
123
+ lines.push(dim(` ${v}`) + padLine("") + dim(v));
101
124
  const siteLabel = " \u{1F310} ccgather.com ";
102
125
  const siteLink = hyperlink(colors.secondary(siteLabel), "https://ccgather.com");
126
+ const siteLabelWidth = getDisplayWidth(siteLabel);
103
127
  const leftDashes = 13;
104
- const rightDashes = HEADER_WIDTH - leftDashes - siteLabel.length;
128
+ const rightDashes = HEADER_WIDTH - leftDashes - siteLabelWidth;
105
129
  lines.push(
106
- colors.dim(` ${boxRound.bottomLeft}${h.repeat(leftDashes)}`) + siteLink + colors.dim(`${h.repeat(rightDashes)}${boxRound.bottomRight}`)
130
+ dim(` ${boxRound.bottomLeft}${h.repeat(leftDashes)}`) + siteLink + dim(`${h.repeat(Math.max(0, rightDashes))}${boxRound.bottomRight}`)
107
131
  );
108
132
  return lines;
109
133
  }
@@ -118,7 +142,7 @@ function createBox(lines, width = 47) {
118
142
  return [top, ...paddedLines.map((l) => colors.dim(" ") + l), bottom].join("\n");
119
143
  }
120
144
  function _stripAnsi(str) {
121
- return str.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, "");
145
+ return str.replace(/\x1B\[[0-9;]*[a-zA-Z]|\x1B\]8;;[^\x07]*\x07/g, "");
122
146
  }
123
147
  function getDisplayWidth(str) {
124
148
  const stripped = _stripAnsi(str);
@@ -247,13 +271,13 @@ async function printAnimatedWelcomeBox(user) {
247
271
  console.log(` \u{1F44B} ${colors.white.bold(`Welcome back, ${user.username}!`)}`);
248
272
  await sleep(50);
249
273
  }
250
- var import_chalk, import_string_width, VERSION, colors, LOGO, LOGO_COMPACT, TAGLINE, SLOGAN, boxRound, box, HEADER_WIDTH, LEVELS;
274
+ var import_chalk, import_string_width, VERSION, colors, LOGO_COMPACT, TAGLINE, SLOGAN, boxRound, box, HEADER_WIDTH, CHROME_FONT, LEVELS;
251
275
  var init_ui = __esm({
252
276
  "src/lib/ui.ts"() {
253
277
  "use strict";
254
278
  import_chalk = __toESM(require("chalk"));
255
279
  import_string_width = __toESM(require("string-width"));
256
- VERSION = true ? "2.0.33" : "0.0.0";
280
+ VERSION = true ? "2.0.36" : "0.0.0";
257
281
  colors = {
258
282
  primary: import_chalk.default.hex("#DA7756"),
259
283
  // Claude coral
@@ -282,14 +306,6 @@ var init_ui = __esm({
282
306
  free: import_chalk.default.hex("#6B7280")
283
307
  // Gray
284
308
  };
285
- LOGO = `
286
- ${colors.primary("\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557")} ${colors.secondary("\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557")}
287
- ${colors.primary("\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D")}${colors.secondary("\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557")}
288
- ${colors.primary("\u2588\u2588\u2551 \u2588\u2588\u2551 ")}${colors.secondary("\u2588\u2588\u2551 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D")}
289
- ${colors.primary("\u2588\u2588\u2551 \u2588\u2588\u2551 ")}${colors.secondary("\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557")}
290
- ${colors.primary("\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557")}${colors.secondary("\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551")}
291
- ${colors.primary("\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D")} ${colors.secondary("\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D")}
292
- `;
293
309
  LOGO_COMPACT = `
294
310
  ${colors.primary("CC")}${colors.secondary("gather")} ${colors.muted("- Proof of your Claude Code dedication")}
295
311
  `;
@@ -316,6 +332,15 @@ var init_ui = __esm({
316
332
  rightT: "\u2524"
317
333
  };
318
334
  HEADER_WIDTH = 46;
335
+ CHROME_FONT = {
336
+ C: ["\u2554\u2550\u2557", "\u2551 ", "\u255A\u2550\u255D"],
337
+ G: ["\u2554\u2550\u2557", "\u2551 \u2566", "\u255A\u2550\u255D"],
338
+ A: ["\u2554\u2550\u2557", "\u2560\u2550\u2563", "\u2569 \u2569"],
339
+ T: ["\u2554\u2566\u2557", " \u2551 ", " \u2569 "],
340
+ H: ["\u2566 \u2566", "\u2560\u2550\u2563", "\u2569 \u2569"],
341
+ E: ["\u2554\u2550\u2557", "\u2551\u2563 ", "\u255A\u2550\u255D"],
342
+ R: ["\u2566\u2550\u2557", "\u2560\u2566\u255D", "\u2569\u255A\u2550"]
343
+ };
319
344
  LEVELS = [
320
345
  { min: 0, level: 1, name: "Novice", icon: "\u{1F331}", color: colors.dim },
321
346
  { min: 5e7, level: 2, name: "Apprentice", icon: "\u{1F4DA}", color: colors.muted },
@@ -1419,7 +1444,7 @@ async function submit(options) {
1419
1444
  return `${yy}${mm}${dd}`;
1420
1445
  };
1421
1446
  const dateRange = usageData.firstUsed && usageData.lastUsed ? `${formatDate(usageData.firstUsed)} ~ ${formatDate(usageData.lastUsed)}` : "";
1422
- const daysTrackedDisplay = dateRange ? `${usageData.daysTracked} days ${colors.dim(`(${dateRange})`)}` : usageData.daysTracked.toString();
1447
+ const daysTrackedDisplay = dateRange ? `${usageData.daysTracked}d ${colors.dim(`(${dateRange})`)}` : usageData.daysTracked.toString();
1423
1448
  const summaryLines = [
1424
1449
  `${colors.muted("Total Cost")} \u{1F4B0} ${colors.warning(formatCost(usageData.totalCost))}`,
1425
1450
  `${colors.muted("Total Tokens")} \u26A1 ${colors.primary(formatNumber(usageData.totalTokens))}`,
@@ -1450,7 +1475,7 @@ async function submit(options) {
1450
1475
  summaryLines.push(
1451
1476
  `${colors.muted("Level")} ${currentLevel.icon} ${currentLevel.color(`${currentLevel.name}`)}`
1452
1477
  );
1453
- console.log(createBox(summaryLines, 52));
1478
+ console.log(createBox(summaryLines, 46));
1454
1479
  console.log(
1455
1480
  ` ${colors.dim(`Scanned ${projectCount} project(s), ${usageData.dailyUsage.length} day(s) of data`)}`
1456
1481
  );
package/package.json CHANGED
@@ -1,55 +1,55 @@
1
- {
2
- "name": "ccgather",
3
- "version": "2.0.34",
4
- "description": "CLI tool for syncing Claude Code usage data to CCgather leaderboard",
5
- "bin": {
6
- "ccgather": "dist/index.js",
7
- "ccg": "dist/index.js"
8
- },
9
- "main": "./dist/index.js",
10
- "types": "./dist/index.d.ts",
11
- "scripts": {
12
- "build": "tsup",
13
- "dev": "tsup --watch",
14
- "start": "node dist/index.js",
15
- "typecheck": "tsc --noEmit",
16
- "test": "vitest run",
17
- "test:watch": "vitest"
18
- },
19
- "keywords": [
20
- "claude",
21
- "anthropic",
22
- "claude-code",
23
- "ccgather",
24
- "leaderboard",
25
- "cli"
26
- ],
27
- "author": "",
28
- "license": "Apache-2.0",
29
- "dependencies": {
30
- "chalk": "^5.3.0",
31
- "commander": "^12.1.0",
32
- "conf": "^13.0.1",
33
- "inquirer": "^9.2.23",
34
- "open": "^10.1.0",
35
- "ora": "^8.1.0",
36
- "string-width": "^7.2.0"
37
- },
38
- "devDependencies": {
39
- "@types/inquirer": "^9.0.7",
40
- "@types/node": "^22.10.2",
41
- "tsup": "^8.3.5",
42
- "typescript": "^5.7.2",
43
- "vitest": "^3.0.0"
44
- },
45
- "engines": {
46
- "node": ">=18"
47
- },
48
- "files": [
49
- "dist"
50
- ],
51
- "repository": {
52
- "type": "git",
53
- "url": "git+https://github.com/DHxWhy/CCgather.git"
54
- }
55
- }
1
+ {
2
+ "name": "ccgather",
3
+ "version": "2.0.36",
4
+ "description": "CLI tool for syncing Claude Code usage data to CCgather leaderboard",
5
+ "bin": {
6
+ "ccgather": "dist/index.js",
7
+ "ccg": "dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "scripts": {
12
+ "build": "tsup",
13
+ "dev": "tsup --watch",
14
+ "start": "node dist/index.js",
15
+ "typecheck": "tsc --noEmit",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest"
18
+ },
19
+ "keywords": [
20
+ "claude",
21
+ "anthropic",
22
+ "claude-code",
23
+ "ccgather",
24
+ "leaderboard",
25
+ "cli"
26
+ ],
27
+ "author": "",
28
+ "license": "Apache-2.0",
29
+ "dependencies": {
30
+ "chalk": "^5.3.0",
31
+ "commander": "^12.1.0",
32
+ "conf": "^13.0.1",
33
+ "inquirer": "^9.2.23",
34
+ "open": "^10.1.0",
35
+ "ora": "^8.1.0",
36
+ "string-width": "^7.2.0"
37
+ },
38
+ "devDependencies": {
39
+ "@types/inquirer": "^9.0.7",
40
+ "@types/node": "^22.10.2",
41
+ "tsup": "^8.3.5",
42
+ "typescript": "^5.7.2",
43
+ "vitest": "^3.0.0"
44
+ },
45
+ "engines": {
46
+ "node": ">=18"
47
+ },
48
+ "files": [
49
+ "dist"
50
+ ],
51
+ "repository": {
52
+ "type": "git",
53
+ "url": "git+https://github.com/DHxWhy/CCgather.git"
54
+ }
55
+ }