ccgather 1.3.24 → 1.3.25

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 +82 -33
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -656,23 +656,61 @@ function getCCplanBadge(ccplan) {
656
656
  };
657
657
  return badges[ccplan.toLowerCase()] || "";
658
658
  }
659
+ var LEVELS = [
660
+ { min: 0, level: 1, name: "Novice", icon: "\u{1F331}", color: colors.dim },
661
+ { min: 1e5, level: 2, name: "Apprentice", icon: "\u{1F4DA}", color: colors.muted },
662
+ { min: 5e5, level: 3, name: "Journeyman", icon: "\u26A1", color: colors.cyan },
663
+ { min: 1e6, level: 4, name: "Expert", icon: "\u{1F48E}", color: colors.pro },
664
+ { min: 5e6, level: 5, name: "Master", icon: "\u{1F525}", color: colors.warning },
665
+ { min: 1e7, level: 6, name: "Grandmaster", icon: "\u{1F451}", color: colors.max },
666
+ { min: 5e7, level: 7, name: "Legend", icon: "\u{1F31F}", color: colors.primary },
667
+ { min: 1e8, level: 8, name: "Mythic", icon: "\u{1F3C6}", color: colors.secondary }
668
+ ];
659
669
  function getLevelInfo(tokens) {
660
- const levels = [
661
- { min: 0, level: 1, name: "Novice", icon: "\u{1F331}", color: colors.dim },
662
- { min: 1e5, level: 2, name: "Apprentice", icon: "\u{1F4DA}", color: colors.muted },
663
- { min: 5e5, level: 3, name: "Journeyman", icon: "\u26A1", color: colors.cyan },
664
- { min: 1e6, level: 4, name: "Expert", icon: "\u{1F48E}", color: colors.pro },
665
- { min: 5e6, level: 5, name: "Master", icon: "\u{1F525}", color: colors.warning },
666
- { min: 1e7, level: 6, name: "Grandmaster", icon: "\u{1F451}", color: colors.max },
667
- { min: 5e7, level: 7, name: "Legend", icon: "\u{1F31F}", color: colors.primary },
668
- { min: 1e8, level: 8, name: "Mythic", icon: "\u{1F3C6}", color: colors.secondary }
669
- ];
670
- for (let i = levels.length - 1; i >= 0; i--) {
671
- if (tokens >= levels[i].min) {
672
- return levels[i];
670
+ for (let i = LEVELS.length - 1; i >= 0; i--) {
671
+ if (tokens >= LEVELS[i].min) {
672
+ return LEVELS[i];
673
673
  }
674
674
  }
675
- return levels[0];
675
+ return LEVELS[0];
676
+ }
677
+ function getLevelProgress(tokens) {
678
+ let currentIndex = 0;
679
+ for (let i = LEVELS.length - 1; i >= 0; i--) {
680
+ if (tokens >= LEVELS[i].min) {
681
+ currentIndex = i;
682
+ break;
683
+ }
684
+ }
685
+ const current = LEVELS[currentIndex];
686
+ const isMaxLevel = currentIndex === LEVELS.length - 1;
687
+ if (isMaxLevel) {
688
+ return {
689
+ current,
690
+ next: null,
691
+ progress: 100,
692
+ tokensToNext: 0,
693
+ isMaxLevel: true
694
+ };
695
+ }
696
+ const nextLevel = LEVELS[currentIndex + 1];
697
+ const currentMin = current.min;
698
+ const nextMin = nextLevel.min;
699
+ const progressInLevel = tokens - currentMin;
700
+ const levelRange = nextMin - currentMin;
701
+ const progress = Math.min(100, Math.round(progressInLevel / levelRange * 100));
702
+ return {
703
+ current,
704
+ next: {
705
+ level: nextLevel.level,
706
+ name: nextLevel.name,
707
+ icon: nextLevel.icon,
708
+ threshold: nextLevel.min
709
+ },
710
+ progress,
711
+ tokensToNext: nextMin - tokens,
712
+ isMaxLevel: false
713
+ };
676
714
  }
677
715
  function countryCodeToFlag(countryCode) {
678
716
  if (!countryCode || countryCode.length !== 2) return "\u{1F310}";
@@ -932,32 +970,43 @@ async function submit(options) {
932
970
  if (result.success) {
933
971
  submitSpinner.succeed(colors.success("Successfully submitted!"));
934
972
  console.log();
973
+ if (result.rank || result.countryRank) {
974
+ console.log(` ${colors.white.bold("Your Ranking")}`);
975
+ console.log();
976
+ if (result.rank) {
977
+ const medal = result.rank === 1 ? "\u{1F947}" : result.rank === 2 ? "\u{1F948}" : result.rank === 3 ? "\u{1F949}" : result.rank <= 10 ? "\u{1F3C5}" : "\u{1F30D}";
978
+ console.log(` ${medal} ${colors.muted("Global:")} ${colors.primary.bold(`#${result.rank}`)}`);
979
+ }
980
+ if (result.countryRank) {
981
+ const countryMedal = result.countryRank === 1 ? "\u{1F947}" : result.countryRank <= 3 ? "\u{1F3C6}" : "\u{1F3E0}";
982
+ console.log(` ${countryMedal} ${colors.muted("Country:")} ${colors.primary.bold(`#${result.countryRank}`)}`);
983
+ }
984
+ console.log();
985
+ }
986
+ const levelProgress = getLevelProgress(usageData.totalTokens);
987
+ const currentLevel = levelProgress.current;
988
+ console.log(` ${colors.white.bold("Level Progress")}`);
989
+ console.log();
990
+ console.log(` ${currentLevel.icon} ${currentLevel.color(`Level ${currentLevel.level}`)} ${colors.muted("\u2022")} ${colors.white(currentLevel.name)}`);
991
+ if (!levelProgress.isMaxLevel && levelProgress.next) {
992
+ const barWidth = 24;
993
+ const filled = Math.round(levelProgress.progress / 100 * barWidth);
994
+ const empty = barWidth - filled;
995
+ const bar = colors.primary("\u2588".repeat(filled)) + colors.dim("\u2591".repeat(empty));
996
+ console.log(` [${bar}] ${colors.white(`${levelProgress.progress}%`)}`);
997
+ console.log(` ${colors.muted("Next:")} ${levelProgress.next.icon} ${colors.white(levelProgress.next.name)} ${colors.dim("\u2022")} ${colors.primary(formatNumber(levelProgress.tokensToNext))} ${colors.muted("to go")}`);
998
+ } else {
999
+ console.log(` ${colors.max("\u2605")} ${colors.max("MAX LEVEL ACHIEVED!")}`);
1000
+ }
1001
+ console.log();
935
1002
  if (result.newBadges && result.newBadges.length > 0) {
936
1003
  displayNewBadges(result.newBadges);
937
1004
  }
938
1005
  if (result.badgeProgress && result.badgeProgress.length > 0) {
939
1006
  displayBadgeProgress(result.badgeProgress, result.totalBadges || 0);
940
1007
  }
941
- const levelInfo = getLevelInfo(usageData.totalTokens);
942
1008
  const leaderboardUrl = `https://ccgather.com/leaderboard?u=${username}`;
943
- const successLines = [
944
- `${colors.success("\u2713")} ${colors.white.bold("Submission Complete!")}`,
945
- "",
946
- `${levelInfo.icon} ${levelInfo.color(`Level ${levelInfo.level}`)} ${colors.muted("\u2022")} ${colors.white(levelInfo.name)}`,
947
- ""
948
- ];
949
- if (result.rank) {
950
- successLines.push(`${colors.muted("Global Rank:")} ${colors.primary(`#${result.rank}`)}`);
951
- }
952
- if (result.countryRank) {
953
- successLines.push(`${colors.muted("Country Rank:")} ${colors.primary(`#${result.countryRank}`)}`);
954
- }
955
- if (result.rank || result.countryRank) {
956
- successLines.push("");
957
- }
958
- successLines.push(`${colors.muted("Check your rank on the leaderboard:")}`);
959
- successLines.push(`${link(leaderboardUrl)}`);
960
- console.log(createBox(successLines));
1009
+ console.log(` ${colors.muted("View full stats:")} ${link(leaderboardUrl)}`);
961
1010
  console.log();
962
1011
  } else {
963
1012
  submitSpinner.fail(colors.error("Failed to submit"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccgather",
3
- "version": "1.3.24",
3
+ "version": "1.3.25",
4
4
  "description": "CLI tool for syncing Claude Code usage data to CCgather leaderboard",
5
5
  "bin": {
6
6
  "ccgather": "dist/index.js",