cchubber 0.5.2 → 0.5.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cchubber",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "What you spent. Why you spent it. Is that normal. — Claude Code usage diagnosis with beautiful HTML reports.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1122,25 +1122,51 @@ ${cacheHealth.totalCacheBreaks > 0 ? `
1122
1122
  }
1123
1123
  });
1124
1124
 
1125
- // Leaderboard table — re-graded
1125
+ // Leaderboard table — re-graded, with user's position injected
1126
1126
  var tbody = document.getElementById('leaderboard-body');
1127
1127
  var sorted = recent.filter(function(r){return r.ratio}).sort(function(a,b){return (a.ratio||9999)-(b.ratio||9999)});
1128
1128
 
1129
+ // Find where the user would rank
1130
+ var myRank = sorted.findIndex(function(e){return (e.ratio||0) >= MY_RATIO});
1131
+ if(myRank < 0) myRank = sorted.length;
1132
+
1133
+ // Show top 10 + user's position (if not in top 10)
1134
+ var showIndices = [];
1135
+ for(var si=0;si<Math.min(10,sorted.length);si++) showIndices.push(si);
1136
+ var userInTop = myRank < 10;
1137
+ if(!userInTop && myRank < sorted.length){
1138
+ showIndices.push(-1); // separator
1139
+ if(myRank > 0) showIndices.push(myRank-1);
1140
+ showIndices.push(myRank);
1141
+ if(myRank+1 < sorted.length) showIndices.push(myRank+1);
1142
+ }
1143
+
1129
1144
  var html = '';
1130
- sorted.forEach(function(entry, i){
1145
+ for(var si2=0;si2<showIndices.length;si2++){
1146
+ var idx = showIndices[si2];
1147
+ if(idx === -1){
1148
+ html += '<tr><td colspan="6" class="px-8 py-1 text-center text-[10px] text-[#908fa0]">···</td></tr>';
1149
+ continue;
1150
+ }
1151
+ var entry = sorted[idx];
1152
+ if(!entry) continue;
1131
1153
  var g = getGrade(entry);
1132
- var isMe = Math.abs((entry.ratio||0) - MY_RATIO) < 50;
1133
- var rowStyle = isMe ? 'background:rgba(192,193,255,0.06);border-left:2px solid #c0c1ff;' : '';
1154
+ var isMe = idx === myRank;
1155
+ var rowStyle = isMe ? 'background:rgba(192,193,255,0.08);border-left:3px solid #c0c1ff;' : '';
1134
1156
  html += '<tr style="border-bottom:1px solid rgba(70,69,84,0.1);'+rowStyle+'">';
1135
- html += '<td class="px-8 py-3 text-sm font-mono text-[#908fa0]">#'+(i+1)+'</td>';
1157
+ html += '<td class="px-8 py-3 text-sm font-mono '+(isMe?'text-[#c0c1ff] font-bold':'text-[#908fa0]')+'">#'+(idx+1)+(isMe?' ← you':'')+'</td>';
1136
1158
  html += '<td class="px-4 py-3 text-sm font-bold text-center" style="color:'+gradeColors[g]+'">'+g+'</td>';
1137
1159
  html += '<td class="px-4 py-3 text-sm font-mono text-[#c7c4d7] text-right">'+(entry.ratio||'?')+':1</td>';
1138
1160
  html += '<td class="px-4 py-3 text-sm font-mono text-[#908fa0]">'+(entry.cost||'?')+'</td>';
1139
1161
  html += '<td class="px-4 py-3 text-sm font-mono text-[#c7c4d7] text-right">'+(entry.opus||'?')+'%</td>';
1140
1162
  html += '<td class="px-8 py-3 text-sm text-[#908fa0]">'+(entry.country||'?')+'</td>';
1141
1163
  html += '</tr>';
1142
- });
1164
+ }
1143
1165
  tbody.innerHTML = html;
1166
+
1167
+ // Update percentile text with rank
1168
+ document.getElementById('community-percentile').innerHTML =
1169
+ 'You\'re <strong style="color:#c0c1ff">#'+(myRank+1)+' of '+sorted.length+'</strong> users by cache efficiency. Better than <strong style="color:#c0c1ff">'+pctile+'%</strong>';
1144
1170
  })(stats);
1145
1171
  })();
1146
1172
  </script>