claude-usage-dashboard 1.4.1 → 1.5.0
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 +122 -77
- package/bin/cli.cjs +20 -20
- package/bin/cli.js +16 -16
- package/bin/cli.sh +11 -11
- package/package.json +43 -43
- package/public/css/style.css +287 -265
- package/public/index.html +123 -108
- package/public/js/api.js +17 -16
- package/public/js/app.js +326 -304
- package/public/js/charts/cache-efficiency.js +29 -29
- package/public/js/charts/cost-comparison.js +39 -39
- package/public/js/charts/model-distribution.js +56 -56
- package/public/js/charts/project-distribution.js +103 -103
- package/public/js/charts/quota-cycles.js +209 -0
- package/public/js/charts/session-stats.js +117 -117
- package/public/js/charts/token-trend.js +357 -357
- package/public/js/components/date-picker.js +35 -35
- package/public/js/components/plan-selector.js +57 -57
- package/server/aggregator.js +151 -151
- package/server/credentials.js +112 -112
- package/server/index.js +45 -45
- package/server/parser.js +129 -129
- package/server/pricing.js +52 -52
- package/server/quota-cycles.js +274 -0
- package/server/routes/api.js +175 -141
- package/server/sync.js +69 -69
package/README.md
CHANGED
|
@@ -1,77 +1,122 @@
|
|
|
1
|
-
# Claude Usage Dashboard
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/claude-usage-dashboard)
|
|
4
|
-
[](https://www.npmjs.com/package/claude-usage-dashboard)
|
|
5
|
-
|
|
6
|
-
> Find out what your Claude Code subscription is actually worth in API costs.
|
|
7
|
-
|
|
8
|
-
Your $200/month Max plan might be consuming **$15,000+/month** in API-equivalent value. This dashboard shows you exactly how much — per project, per session, per model. One command to start. Completely local.
|
|
9
|
-
|
|
10
|
-
```bash
|
|
11
|
-
npx claude-usage-dashboard
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-

|
|
15
|
-
|
|
16
|
-
## What You'll See
|
|
17
|
-
|
|
18
|
-
###
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
###
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
1
|
+
# Claude Usage Dashboard
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/claude-usage-dashboard)
|
|
4
|
+
[](https://www.npmjs.com/package/claude-usage-dashboard)
|
|
5
|
+
|
|
6
|
+
> Find out what your Claude Code subscription is actually worth in API costs — and whether your quota is shrinking — across every machine you own.
|
|
7
|
+
|
|
8
|
+
Your $200/month Max plan might be consuming **$15,000+/month** in API-equivalent value. This dashboard shows you exactly how much — per project, per session, per model, and across all your machines in one unified view. It also tracks your 7-day quota cycles, projects token usage at full utilization, and keeps history so you can spot if your effective quota quietly changed. One command to start. Completely local.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npx claude-usage-dashboard
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
## What You'll See
|
|
17
|
+
|
|
18
|
+
### See Every Machine in One Place
|
|
19
|
+
|
|
20
|
+
Use Claude on a laptop, a desktop, and a work machine? Most dashboards only see the one they're running on. This one syncs across all of them.
|
|
21
|
+
|
|
22
|
+
Point it at any shared folder — Google Drive, Dropbox, OneDrive, a NAS, an rsync target — and every machine's logs roll up into one unified view. No server. No account. Just a folder you already have.
|
|
23
|
+
|
|
24
|
+
### Know What You're Spending
|
|
25
|
+
|
|
26
|
+
Real-time projected API cost at your current usage rate — weekly and monthly. At 5% quota utilization, you might be burning through **$3,600/week** equivalent. The dashboard calculates this from your actual quota window, not estimates.
|
|
27
|
+
|
|
28
|
+
### Track Your Quota in Real Time
|
|
29
|
+
|
|
30
|
+
Live utilization gauges for 5-hour, 7-day, and per-model quotas pulled directly from the Anthropic API. Auto-detects your plan tier (Pro / Max 5x / Max 20x). Never get throttled by surprise again.
|
|
31
|
+
|
|
32
|
+
### Track Your Quota Across Cycles
|
|
33
|
+
|
|
34
|
+
Anthropic doesn't publish exact token limits, and those limits can change without notice. The Quota Cycle History section gives you a running record of each 7-day cycle so you can see exactly how much you got and whether it stayed consistent.
|
|
35
|
+
|
|
36
|
+
For each cycle, the dashboard projects what your full token quota would be at 100% utilization — broken down by Input, Output, Cache Read, Cache Write, and Total. A horizontal bar chart overlays actual vs. projected per cycle, and the history table highlights projected tokens and cost with a delta column showing the change versus the previous cycle.
|
|
37
|
+
|
|
38
|
+
That delta is the key signal: if your projected quota drops from one cycle to the next without you changing how you work, something changed on the platform side. Track your actual consumption week-over-week so you have real numbers when something feels off — not just a gut feeling. Up to 10 past cycles are retained across all your machines.
|
|
39
|
+
|
|
40
|
+
### Find What's Eating Your Tokens
|
|
41
|
+
|
|
42
|
+
Per-project and per-session cost breakdowns show exactly where your usage goes. Sortable session table with cost, duration, and full token breakdown. Spot the expensive sessions instantly.
|
|
43
|
+
|
|
44
|
+
### Understand Your Cache Efficiency
|
|
45
|
+
|
|
46
|
+
You'll probably discover that ~95% of your tokens are cache reads at 1/10th the cost. The dashboard visualizes cache read vs. cache write vs. uncached requests so you can see how efficiently Claude is using context.
|
|
47
|
+
|
|
48
|
+
### Everything Else
|
|
49
|
+
|
|
50
|
+
**Multi-machine sync** — aggregate usage across all your devices via a shared folder · **Quota cycle tracking** — monitors each 7-day reset window, projects usage at 100% utilization, logs history to detect quota changes · Hourly/daily/weekly/monthly token trends · Dollar and token toggle · Model distribution across Opus/Sonnet/Haiku · Active hours heatmap · Auto-refresh (30s) · Persistent filters via localStorage · Dark theme
|
|
51
|
+
|
|
52
|
+
## Quick Start
|
|
53
|
+
|
|
54
|
+
Run directly — no install, no config, no API keys needed:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
npx claude-usage-dashboard
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Open [localhost:3000](http://localhost:3000). That's it.
|
|
61
|
+
|
|
62
|
+
### From Source
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
git clone https://github.com/ludengz/claude-usage-dashboard.git
|
|
66
|
+
cd claude-usage-dashboard
|
|
67
|
+
npm install
|
|
68
|
+
npm start
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Custom Port
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
PORT=8080 npx claude-usage-dashboard
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Multi-Machine Sync
|
|
78
|
+
|
|
79
|
+
If you use Claude Code on more than one machine — a desktop and a laptop, a work Mac and a home PC — each one only sees its own logs. Sync solves this.
|
|
80
|
+
|
|
81
|
+
Set two environment variables on each machine, then start the dashboard normally:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# Add to your shell profile (~/.bashrc, ~/.zshrc, etc.) on each machine:
|
|
85
|
+
export CLAUDE_DASH_SYNC_DIR="$HOME/Google Drive/claude-sync"
|
|
86
|
+
export CLAUDE_DASH_MACHINE_NAME="MacBook" # optional — defaults to hostname
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
On Windows, set them as user environment variables:
|
|
90
|
+
|
|
91
|
+
```powershell
|
|
92
|
+
[Environment]::SetEnvironmentVariable('CLAUDE_DASH_SYNC_DIR', 'C:\Users\you\Google Drive\claude-sync', 'User')
|
|
93
|
+
[Environment]::SetEnvironmentVariable('CLAUDE_DASH_MACHINE_NAME', 'Desktop', 'User')
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Or pass them inline:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
CLAUDE_DASH_SYNC_DIR="/path/to/shared" CLAUDE_DASH_MACHINE_NAME="MacBook" npx claude-usage-dashboard
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
On startup, local logs from `~/.claude/projects/` are copied into `<sync_dir>/<machine_name>/`. The dashboard then reads **all machine folders** in the sync directory, giving you a single aggregated view across every device. Usage re-syncs every 5 seconds.
|
|
103
|
+
|
|
104
|
+
**Works with any shared folder.** Google Drive, Dropbox, OneDrive, iCloud Drive, Syncthing, a NAS, or a plain rsync cronjob. No server, no account, no API key — just a folder that syncs between your machines.
|
|
105
|
+
|
|
106
|
+
## How It Works
|
|
107
|
+
|
|
108
|
+
Reads the JSONL session logs that Claude Code already writes to `~/.claude/projects/` on your machine. If you use Claude Code, the data is already there. Logs are re-read every 5 seconds — new usage appears without restarting.
|
|
109
|
+
|
|
110
|
+
When `CLAUDE_DASH_SYNC_DIR` is set, the dashboard copies local logs into `<sync_dir>/<machine_name>/` on startup and on every refresh. It then reads all machine subfolders in that directory — so any machine running the dashboard with the same sync folder contributes to the aggregate view.
|
|
111
|
+
|
|
112
|
+
Subscription quota data is fetched from the Anthropic API using your existing local OAuth credentials. Your plan tier is auto-detected.
|
|
113
|
+
|
|
114
|
+
## Running Tests
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npm test
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## License
|
|
121
|
+
|
|
122
|
+
ISC
|
package/bin/cli.cjs
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
const { join, resolve } = require('path');
|
|
4
|
-
const { spawnSync } = require('child_process');
|
|
5
|
-
|
|
6
|
-
// Parse CLI args before spawning server
|
|
7
|
-
const args = process.argv.slice(2);
|
|
8
|
-
for (let i = 0; i < args.length; i++) {
|
|
9
|
-
if (args[i] === '--sync-dir' && args[i + 1]) {
|
|
10
|
-
process.env.CLAUDE_DASH_SYNC_DIR = resolve(args[i + 1]);
|
|
11
|
-
i++;
|
|
12
|
-
} else if (args[i] === '--machine-name' && args[i + 1]) {
|
|
13
|
-
process.env.CLAUDE_DASH_MACHINE_NAME = args[i + 1];
|
|
14
|
-
i++;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const serverPath = join(__dirname, '..', 'server', 'index.js');
|
|
19
|
-
const result = spawnSync(process.execPath, [serverPath], { stdio: 'inherit' });
|
|
20
|
-
process.exit(result.status || 0);
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
const { join, resolve } = require('path');
|
|
4
|
+
const { spawnSync } = require('child_process');
|
|
5
|
+
|
|
6
|
+
// Parse CLI args before spawning server
|
|
7
|
+
const args = process.argv.slice(2);
|
|
8
|
+
for (let i = 0; i < args.length; i++) {
|
|
9
|
+
if (args[i] === '--sync-dir' && args[i + 1]) {
|
|
10
|
+
process.env.CLAUDE_DASH_SYNC_DIR = resolve(args[i + 1]);
|
|
11
|
+
i++;
|
|
12
|
+
} else if (args[i] === '--machine-name' && args[i + 1]) {
|
|
13
|
+
process.env.CLAUDE_DASH_MACHINE_NAME = args[i + 1];
|
|
14
|
+
i++;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const serverPath = join(__dirname, '..', 'server', 'index.js');
|
|
19
|
+
const result = spawnSync(process.execPath, [serverPath], { stdio: 'inherit' });
|
|
20
|
+
process.exit(result.status || 0);
|
package/bin/cli.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import path from 'path';
|
|
3
|
-
|
|
4
|
-
// Parse CLI args before importing server
|
|
5
|
-
const args = process.argv.slice(2);
|
|
6
|
-
for (let i = 0; i < args.length; i++) {
|
|
7
|
-
if (args[i] === '--sync-dir' && args[i + 1]) {
|
|
8
|
-
process.env.CLAUDE_DASH_SYNC_DIR = path.resolve(args[i + 1]);
|
|
9
|
-
i++;
|
|
10
|
-
} else if (args[i] === '--machine-name' && args[i + 1]) {
|
|
11
|
-
process.env.CLAUDE_DASH_MACHINE_NAME = args[i + 1];
|
|
12
|
-
i++;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
await import('../server/index.js');
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
4
|
+
// Parse CLI args before importing server
|
|
5
|
+
const args = process.argv.slice(2);
|
|
6
|
+
for (let i = 0; i < args.length; i++) {
|
|
7
|
+
if (args[i] === '--sync-dir' && args[i + 1]) {
|
|
8
|
+
process.env.CLAUDE_DASH_SYNC_DIR = path.resolve(args[i + 1]);
|
|
9
|
+
i++;
|
|
10
|
+
} else if (args[i] === '--machine-name' && args[i + 1]) {
|
|
11
|
+
process.env.CLAUDE_DASH_MACHINE_NAME = args[i + 1];
|
|
12
|
+
i++;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
await import('../server/index.js');
|
package/bin/cli.sh
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
# Resolve symlinks to find the real script location
|
|
3
|
-
SCRIPT="$0"
|
|
4
|
-
while [ -L "$SCRIPT" ]; do
|
|
5
|
-
DIR="$(cd -P "$(dirname "$SCRIPT")" && pwd)"
|
|
6
|
-
SCRIPT="$(readlink "$SCRIPT")"
|
|
7
|
-
case "$SCRIPT" in /*) ;; *) SCRIPT="$DIR/$SCRIPT" ;; esac
|
|
8
|
-
done
|
|
9
|
-
DIR="$(cd -P "$(dirname "$SCRIPT")" && pwd)"
|
|
10
|
-
|
|
11
|
-
exec node "$DIR/../server/index.js" "$@"
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Resolve symlinks to find the real script location
|
|
3
|
+
SCRIPT="$0"
|
|
4
|
+
while [ -L "$SCRIPT" ]; do
|
|
5
|
+
DIR="$(cd -P "$(dirname "$SCRIPT")" && pwd)"
|
|
6
|
+
SCRIPT="$(readlink "$SCRIPT")"
|
|
7
|
+
case "$SCRIPT" in /*) ;; *) SCRIPT="$DIR/$SCRIPT" ;; esac
|
|
8
|
+
done
|
|
9
|
+
DIR="$(cd -P "$(dirname "$SCRIPT")" && pwd)"
|
|
10
|
+
|
|
11
|
+
exec node "$DIR/../server/index.js" "$@"
|
package/package.json
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "claude-usage-dashboard",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
5
|
-
"main": "server/index.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"claude-usage-dashboard": "bin/cli.cjs"
|
|
8
|
-
},
|
|
9
|
-
"files": [
|
|
10
|
-
"bin/",
|
|
11
|
-
"server/",
|
|
12
|
-
"public/"
|
|
13
|
-
],
|
|
14
|
-
"scripts": {
|
|
15
|
-
"start": "node server/index.js",
|
|
16
|
-
"test": "mocha test/**/*.test.js --timeout 5000"
|
|
17
|
-
},
|
|
18
|
-
"keywords": [
|
|
19
|
-
"claude",
|
|
20
|
-
"usage",
|
|
21
|
-
"dashboard",
|
|
22
|
-
"token",
|
|
23
|
-
"cost"
|
|
24
|
-
],
|
|
25
|
-
"author": "",
|
|
26
|
-
"license": "ISC",
|
|
27
|
-
"repository": {
|
|
28
|
-
"type": "git",
|
|
29
|
-
"url": "https://github.com/ludengz/claude-usage-dashboard.git"
|
|
30
|
-
},
|
|
31
|
-
"type": "module",
|
|
32
|
-
"engines": {
|
|
33
|
-
"node": ">=18.0.0"
|
|
34
|
-
},
|
|
35
|
-
"dependencies": {
|
|
36
|
-
"d3": "^7.9.0",
|
|
37
|
-
"express": "^5.2.1"
|
|
38
|
-
},
|
|
39
|
-
"devDependencies": {
|
|
40
|
-
"chai": "^6.2.2",
|
|
41
|
-
"mocha": "^11.7.5"
|
|
42
|
-
}
|
|
43
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "claude-usage-dashboard",
|
|
3
|
+
"version": "1.5.0",
|
|
4
|
+
"description": "Claude Code usage dashboard — token costs, quota cycle tracking, cache efficiency, multi-machine sync across all your devices",
|
|
5
|
+
"main": "server/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"claude-usage-dashboard": "bin/cli.cjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin/",
|
|
11
|
+
"server/",
|
|
12
|
+
"public/"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"start": "node server/index.js",
|
|
16
|
+
"test": "mocha test/**/*.test.js --timeout 5000"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"claude",
|
|
20
|
+
"usage",
|
|
21
|
+
"dashboard",
|
|
22
|
+
"token",
|
|
23
|
+
"cost"
|
|
24
|
+
],
|
|
25
|
+
"author": "",
|
|
26
|
+
"license": "ISC",
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/ludengz/claude-usage-dashboard.git"
|
|
30
|
+
},
|
|
31
|
+
"type": "module",
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18.0.0"
|
|
34
|
+
},
|
|
35
|
+
"dependencies": {
|
|
36
|
+
"d3": "^7.9.0",
|
|
37
|
+
"express": "^5.2.1"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"chai": "^6.2.2",
|
|
41
|
+
"mocha": "^11.7.5"
|
|
42
|
+
}
|
|
43
|
+
}
|