cchubber 0.5.3 → 0.5.4

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/README.md CHANGED
@@ -9,9 +9,7 @@ Your Claude Code usage, diagnosed. One command.
9
9
  npx cchubber
10
10
  ```
11
11
 
12
- Reads your local data, generates an HTML report. No API keys, no accounts, runs entirely offline.
13
-
14
- Sends anonymous aggregate stats (grade, cache ratio, model split) once per day to help build community benchmarks. No tokens, no file contents, no project names. Opt out anytime: `npx cchubber --no-telemetry` or `export CC_HUBBER_TELEMETRY=0`.
12
+ Reads your local data, generates an HTML report. No API keys, no accounts. Sends anonymous stats for community benchmarks ([details](#telemetry)). Opt out: `--no-telemetry`.
15
13
 
16
14
  Built during the March 2026 cache crisis because nobody could tell if they'd been hit. Thousands of users burning through limits 10-20x faster than normal, and Anthropic's only answer was "we're investigating." We wanted receipts.
17
15
 
@@ -103,6 +101,35 @@ Everything is local. CC Hubber reads files that already exist on your machine.
103
101
 
104
102
  CC Hubber tells you why, and whether it's normal. Inflection detection, cache break estimation, model routing savings, session intelligence, trend-weighted grading. Different tools for different questions.
105
103
 
104
+ ## Telemetry
105
+
106
+ CC Hubber sends anonymous usage stats once per day to power community benchmarks. This is what makes the leaderboard rank, grade calibration, and community comparisons in your recommendations work. Without it, every user gets the same generic thresholds instead of real benchmarks.
107
+
108
+ **What's collected:**
109
+ - Cache health: grade, ratio, hit rate, break count
110
+ - Cost: bucketed range (e.g. "$500-1K"), not exact amounts
111
+ - Models: opus/sonnet/haiku split percentages
112
+ - Sessions: count, average duration, tool usage counts
113
+ - Config: CLAUDE.md token count, hook count, MCP server names, skill count
114
+ - Environment: OS, architecture, Node version, Claude Code version
115
+ - Tech stack: boolean flags (uses React, TypeScript, Tailwind, etc.)
116
+ - Anonymous machine ID (random hash, not tied to any account)
117
+
118
+ **What's NOT collected:**
119
+ - No file contents, project names, or directory paths
120
+ - No API keys, tokens, or credentials
121
+ - No conversation text or prompts
122
+ - No personal information (name, email, IP address)
123
+
124
+ **Opt out anytime:**
125
+ ```bash
126
+ npx cchubber --no-telemetry
127
+ # or permanently:
128
+ export CC_HUBBER_TELEMETRY=0
129
+ ```
130
+
131
+ Full source: [`src/telemetry.js`](src/telemetry.js)
132
+
106
133
  ## License
107
134
 
108
135
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cchubber",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
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": {
@@ -748,7 +748,9 @@ ${cacheHealth.totalCacheBreaks > 0 ? `
748
748
 
749
749
  function chart(d){
750
750
  if(!svg)return;
751
- if(!d.length){svg.innerHTML='<text x="450" y="100" text-anchor="middle" fill="#908fa0" font-size="13" font-family="Inter,sans-serif">No data</text>';return}
751
+ if(!d.length){svg.innerHTML='<text x="450" y="100" text-anchor="middle" fill="#908fa0" font-size="13" font-family="Inter,sans-serif">No data for this period</text>';return}
752
+ var total=d.reduce(function(s,x){return s+x.cost},0);
753
+ if(total<0.01){svg.innerHTML='<text x="450" y="100" text-anchor="middle" fill="#908fa0" font-size="13" font-family="Inter,sans-serif">No cost data — costs are only calculated from token counts, not the costUSD field</text>';return}
752
754
  var mx=Math.max.apply(null,d.map(function(x){return x.cost}))*1.1;if(mx<0.01)mx=1;
753
755
  var s='';
754
756
  // grid lines
@@ -1166,7 +1168,7 @@ ${cacheHealth.totalCacheBreaks > 0 ? `
1166
1168
 
1167
1169
  // Update percentile text with rank
1168
1170
  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>';
1171
+ "You are <strong style=\\"color:#c0c1ff\\">#"+(myRank+1)+" of "+sorted.length+"</strong> users by cache efficiency. Better than <strong style=\\"color:#c0c1ff\\">"+pctile+"%</strong>";
1170
1172
  })(stats);
1171
1173
  })();
1172
1174
  </script>