ccgather 1.3.47 → 1.3.49
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 +40 -66
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -40,13 +40,6 @@ function getConfig() {
|
|
|
40
40
|
}
|
|
41
41
|
return configInstance;
|
|
42
42
|
}
|
|
43
|
-
function resetConfig() {
|
|
44
|
-
const config = getConfig();
|
|
45
|
-
config.clear();
|
|
46
|
-
Object.entries(defaults).forEach(([key, value]) => {
|
|
47
|
-
config.set(key, value);
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
43
|
function isAuthenticated() {
|
|
51
44
|
const config = getConfig();
|
|
52
45
|
return !!config.get("apiToken");
|
|
@@ -75,7 +68,7 @@ function hyperlink(text, url) {
|
|
|
75
68
|
return `\x1B]8;;${url}\x07${text}\x1B]8;;\x07`;
|
|
76
69
|
}
|
|
77
70
|
function centerText(text, width) {
|
|
78
|
-
const len =
|
|
71
|
+
const len = getDisplayWidth(text);
|
|
79
72
|
const pad = width - len;
|
|
80
73
|
return " ".repeat(Math.max(0, Math.floor(pad / 2))) + text + " ".repeat(Math.max(0, pad - Math.floor(pad / 2)));
|
|
81
74
|
}
|
|
@@ -85,13 +78,13 @@ function createProfessionalHeader() {
|
|
|
85
78
|
const h = boxRound.horizontal;
|
|
86
79
|
lines.push(colors.dim(` ${boxRound.topLeft}${h.repeat(HEADER_WIDTH)}${boxRound.topRight}`));
|
|
87
80
|
const logoLines = [
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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")}`
|
|
91
84
|
];
|
|
92
85
|
for (const l of logoLines) {
|
|
93
86
|
lines.push(
|
|
94
|
-
colors.dim(` ${v}`) + l
|
|
87
|
+
colors.dim(` ${v}`) + centerText(l, HEADER_WIDTH) + colors.dim(v)
|
|
95
88
|
);
|
|
96
89
|
}
|
|
97
90
|
const versionStr = `v${VERSION}`;
|
|
@@ -118,7 +111,7 @@ function createProfessionalHeader() {
|
|
|
118
111
|
}
|
|
119
112
|
function createBox(lines, width = 47) {
|
|
120
113
|
const paddedLines = lines.map((line) => {
|
|
121
|
-
const visibleLength =
|
|
114
|
+
const visibleLength = getDisplayWidth(line);
|
|
122
115
|
const padding = width - 2 - visibleLength;
|
|
123
116
|
return `${box.vertical} ${line}${" ".repeat(Math.max(0, padding))} ${box.vertical}`;
|
|
124
117
|
});
|
|
@@ -126,8 +119,14 @@ function createBox(lines, width = 47) {
|
|
|
126
119
|
const bottom = colors.dim(` ${box.bottomLeft}${box.horizontal.repeat(width)}${box.bottomRight}`);
|
|
127
120
|
return [top, ...paddedLines.map((l) => colors.dim(" ") + l), bottom].join("\n");
|
|
128
121
|
}
|
|
129
|
-
function
|
|
130
|
-
|
|
122
|
+
function getDisplayWidth(str) {
|
|
123
|
+
let width = (0, import_string_width.default)(str);
|
|
124
|
+
const flagRegex = /[🇦-🇿][🇦-🇿]/gu;
|
|
125
|
+
const flags = str.match(flagRegex);
|
|
126
|
+
if (flags) {
|
|
127
|
+
width += flags.length * 2 * 2;
|
|
128
|
+
}
|
|
129
|
+
return width;
|
|
131
130
|
}
|
|
132
131
|
function header(title, icon = "") {
|
|
133
132
|
const iconPart = icon ? `${icon} ` : "";
|
|
@@ -203,8 +202,7 @@ function getLevelProgress(tokens) {
|
|
|
203
202
|
}
|
|
204
203
|
function countryCodeToFlag(countryCode) {
|
|
205
204
|
if (!countryCode || countryCode.length !== 2) return "\u{1F310}";
|
|
206
|
-
|
|
207
|
-
return String.fromCodePoint(...codePoints);
|
|
205
|
+
return countryCode.toUpperCase();
|
|
208
206
|
}
|
|
209
207
|
function success(message) {
|
|
210
208
|
return `${colors.success("\u2713")} ${message}`;
|
|
@@ -361,7 +359,7 @@ async function printAnimatedWelcomeBox(user) {
|
|
|
361
359
|
const flag = countryCodeToFlag(user.countryCode);
|
|
362
360
|
lines.push(`${flag} Country Rank: ${colors.primary(`#${user.countryRank}`)}`);
|
|
363
361
|
}
|
|
364
|
-
const maxVisibleLength = Math.max(...lines.map((l) =>
|
|
362
|
+
const maxVisibleLength = Math.max(...lines.map((l) => getDisplayWidth(l)));
|
|
365
363
|
const boxWidth = Math.max(maxVisibleLength + 4, 47);
|
|
366
364
|
const top = colors.dim(` ${box.topLeft}${box.horizontal.repeat(boxWidth)}${box.topRight}`);
|
|
367
365
|
const bottom = colors.dim(
|
|
@@ -370,7 +368,7 @@ async function printAnimatedWelcomeBox(user) {
|
|
|
370
368
|
console.log(top);
|
|
371
369
|
await sleep(20);
|
|
372
370
|
for (const line of lines) {
|
|
373
|
-
const visibleLength =
|
|
371
|
+
const visibleLength = getDisplayWidth(line);
|
|
374
372
|
const padding = boxWidth - 2 - visibleLength;
|
|
375
373
|
const paddedLine = `${box.vertical} ${line}${" ".repeat(Math.max(0, padding))} ${box.vertical}`;
|
|
376
374
|
console.log(colors.dim(" ") + paddedLine);
|
|
@@ -378,12 +376,13 @@ async function printAnimatedWelcomeBox(user) {
|
|
|
378
376
|
}
|
|
379
377
|
console.log(bottom);
|
|
380
378
|
}
|
|
381
|
-
var import_chalk, VERSION, colors, LOGO, LOGO_COMPACT, TAGLINE, SLOGAN, boxRound, box, HEADER_WIDTH, LEVELS;
|
|
379
|
+
var import_chalk, import_string_width, VERSION, colors, LOGO, LOGO_COMPACT, TAGLINE, SLOGAN, boxRound, box, HEADER_WIDTH, LEVELS;
|
|
382
380
|
var init_ui = __esm({
|
|
383
381
|
"src/lib/ui.ts"() {
|
|
384
382
|
"use strict";
|
|
385
383
|
import_chalk = __toESM(require("chalk"));
|
|
386
|
-
|
|
384
|
+
import_string_width = __toESM(require("string-width"));
|
|
385
|
+
VERSION = true ? "1.3.48" : "0.0.0";
|
|
387
386
|
colors = {
|
|
388
387
|
primary: import_chalk.default.hex("#DA7756"),
|
|
389
388
|
// Claude coral
|
|
@@ -1137,7 +1136,10 @@ async function submitToServer(data) {
|
|
|
1137
1136
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1138
1137
|
dailyUsage: data.dailyUsage,
|
|
1139
1138
|
// Session fingerprint for duplicate prevention
|
|
1140
|
-
sessionFingerprint: data.sessionFingerprint
|
|
1139
|
+
sessionFingerprint: data.sessionFingerprint,
|
|
1140
|
+
// League placement audit trail
|
|
1141
|
+
leagueReason: data.leagueReason,
|
|
1142
|
+
leagueReasonDetails: data.leagueReasonDetails
|
|
1141
1143
|
})
|
|
1142
1144
|
});
|
|
1143
1145
|
if (!response.ok) {
|
|
@@ -1259,12 +1261,8 @@ async function submit(options) {
|
|
|
1259
1261
|
}
|
|
1260
1262
|
return;
|
|
1261
1263
|
}
|
|
1262
|
-
verifySpinner.succeed(colors.success("Authenticated"));
|
|
1263
1264
|
const username = tokenCheck.username || config.get("username");
|
|
1264
|
-
|
|
1265
|
-
console.log(`
|
|
1266
|
-
${colors.muted("Logged in as:")} ${colors.white(username)}`);
|
|
1267
|
-
}
|
|
1265
|
+
verifySpinner.succeed(colors.success(`Authenticated as ${colors.white(username || "unknown")}`));
|
|
1268
1266
|
const projectName = getCurrentProjectName();
|
|
1269
1267
|
if (!hasProjectSessions()) {
|
|
1270
1268
|
console.log(`
|
|
@@ -1364,6 +1362,9 @@ async function submit(options) {
|
|
|
1364
1362
|
console.log(` ${success(`Selected: ${finalPlan.toUpperCase()}`)}`);
|
|
1365
1363
|
} else {
|
|
1366
1364
|
planDetectionReason = "current";
|
|
1365
|
+
console.log(
|
|
1366
|
+
` ${colors.dim("\u{1F4CB} League: reading plan info only (subscriptionType, rateLimitTier)")}`
|
|
1367
|
+
);
|
|
1367
1368
|
if (usageData.ccplan) {
|
|
1368
1369
|
for (const line of currentPlanMessage(usageData.ccplan)) {
|
|
1369
1370
|
console.log(line);
|
|
@@ -1371,6 +1372,14 @@ async function submit(options) {
|
|
|
1371
1372
|
}
|
|
1372
1373
|
}
|
|
1373
1374
|
usageData.ccplan = finalPlan;
|
|
1375
|
+
usageData.leagueReason = planDetectionReason === "opus" ? "opus" : planDetectionReason === "user_choice" ? "user_choice" : "credential";
|
|
1376
|
+
if (planDetectionReason === "opus") {
|
|
1377
|
+
usageData.leagueReasonDetails = `Opus verified: ${opusCheck.opusModels.join(", ")}`;
|
|
1378
|
+
} else if (planDetectionReason === "user_choice") {
|
|
1379
|
+
usageData.leagueReasonDetails = `User selected: ${finalPlan} (data >${oldDataCheck.daysSinceOldest}d old)`;
|
|
1380
|
+
} else {
|
|
1381
|
+
usageData.leagueReasonDetails = `Credential: ${usageData.ccplan || "free"}`;
|
|
1382
|
+
}
|
|
1374
1383
|
usageData.dailyUsage = usageData.dailyUsage.map((daily) => ({
|
|
1375
1384
|
...daily,
|
|
1376
1385
|
ccplan: finalPlan
|
|
@@ -1677,8 +1686,10 @@ async function showSettingsMenu() {
|
|
|
1677
1686
|
name: "settingsAction",
|
|
1678
1687
|
message: "Settings:",
|
|
1679
1688
|
choices: [
|
|
1680
|
-
{
|
|
1681
|
-
|
|
1689
|
+
{
|
|
1690
|
+
name: `\u{1F510} ${colors.white("Re-authenticate")} ${colors.dim("\u2013 switch account or fix login issues")}`,
|
|
1691
|
+
value: "auth"
|
|
1692
|
+
},
|
|
1682
1693
|
{ name: `\u2B05\uFE0F ${import_chalk3.default.gray("Back")}`, value: "back" }
|
|
1683
1694
|
],
|
|
1684
1695
|
loop: false
|
|
@@ -1690,48 +1701,11 @@ async function showSettingsMenu() {
|
|
|
1690
1701
|
await auth2({});
|
|
1691
1702
|
break;
|
|
1692
1703
|
}
|
|
1693
|
-
case "disconnect": {
|
|
1694
|
-
await handleDisconnect();
|
|
1695
|
-
break;
|
|
1696
|
-
}
|
|
1697
1704
|
case "back":
|
|
1698
1705
|
await showMenuOnly();
|
|
1699
1706
|
break;
|
|
1700
1707
|
}
|
|
1701
1708
|
}
|
|
1702
|
-
async function handleDisconnect() {
|
|
1703
|
-
const { confirmFirst } = await import_inquirer3.default.prompt([
|
|
1704
|
-
{
|
|
1705
|
-
type: "confirm",
|
|
1706
|
-
name: "confirmFirst",
|
|
1707
|
-
message: import_chalk3.default.yellow("Are you sure you want to disconnect from CCgather?"),
|
|
1708
|
-
default: false
|
|
1709
|
-
}
|
|
1710
|
-
]);
|
|
1711
|
-
if (!confirmFirst) {
|
|
1712
|
-
console.log(colors.dim("\n Cancelled.\n"));
|
|
1713
|
-
await showSettingsMenu();
|
|
1714
|
-
return;
|
|
1715
|
-
}
|
|
1716
|
-
const { confirmSecond } = await import_inquirer3.default.prompt([
|
|
1717
|
-
{
|
|
1718
|
-
type: "confirm",
|
|
1719
|
-
name: "confirmSecond",
|
|
1720
|
-
message: import_chalk3.default.red("This will remove all local settings. Are you really sure?"),
|
|
1721
|
-
default: false
|
|
1722
|
-
}
|
|
1723
|
-
]);
|
|
1724
|
-
if (!confirmSecond) {
|
|
1725
|
-
console.log(colors.dim("\n Cancelled.\n"));
|
|
1726
|
-
await showSettingsMenu();
|
|
1727
|
-
return;
|
|
1728
|
-
}
|
|
1729
|
-
resetConfig();
|
|
1730
|
-
console.log();
|
|
1731
|
-
console.log(colors.success(" \u2713 Disconnected from CCgather"));
|
|
1732
|
-
console.log(colors.dim(" Your CCgather settings have been removed."));
|
|
1733
|
-
console.log(colors.dim(" Run npx ccgather to set up again.\n"));
|
|
1734
|
-
}
|
|
1735
1709
|
program.action(async () => {
|
|
1736
1710
|
await showMainMenu();
|
|
1737
1711
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccgather",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.49",
|
|
4
4
|
"description": "CLI tool for syncing Claude Code usage data to CCgather leaderboard",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ccgather": "dist/index.js",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"inquirer": "^9.2.23",
|
|
32
32
|
"open": "^10.1.0",
|
|
33
33
|
"ora": "^8.1.0",
|
|
34
|
+
"string-width": "^7.2.0",
|
|
34
35
|
"update-notifier": "^7.3.1"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|