claude-usage-dashboard 1.3.3 → 1.3.5
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/bin/cli.js +23 -20
- package/package.json +40 -40
- package/public/css/style.css +265 -264
- package/public/index.html +108 -107
- package/public/js/api.js +16 -16
- package/public/js/app.js +273 -273
- 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/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 +147 -147
- package/server/index.js +33 -33
- package/server/parser.js +109 -109
- package/server/pricing.js +52 -52
- package/server/routes/api.js +127 -127
package/public/index.html
CHANGED
|
@@ -1,107 +1,108 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>Claude Usage Dashboard</title>
|
|
7
|
-
<link rel="
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
<div id="
|
|
16
|
-
<div class="
|
|
17
|
-
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
<div class="card-
|
|
30
|
-
<div class="card-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
<div class="card-
|
|
35
|
-
<div class="card-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
<div class="card-
|
|
40
|
-
<div class="card-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
<
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
<button data-yaxis="
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
<button data-granularity="
|
|
62
|
-
<button data-granularity="
|
|
63
|
-
<button data-granularity="
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
<
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
<
|
|
93
|
-
|
|
94
|
-
<
|
|
95
|
-
|
|
96
|
-
<option value="
|
|
97
|
-
<option value="
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
<div id="session-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
</
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Claude Usage Dashboard</title>
|
|
7
|
+
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z' fill='%23D97757'/></svg>">
|
|
8
|
+
<link rel="stylesheet" href="/css/style.css">
|
|
9
|
+
<script src="/lib/d3/d3.min.js"></script>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<header class="top-bar">
|
|
13
|
+
<h1 class="logo"><svg class="claude-icon" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m4.7144 15.9555 4.7174-2.6471.079-.2307-.079-.1275h-.2307l-.7893-.0486-2.6956-.0729-2.3375-.0971-2.2646-.1214-.5707-.1215-.5343-.7042.0546-.3522.4797-.3218.686.0608 1.5179.1032 2.2767.1578 1.6514.0972 2.4468.255h.3886l.0546-.1579-.1336-.0971-.1032-.0972L6.973 9.8356l-2.55-1.6879-1.3356-.9714-.7225-.4918-.3643-.4614-.1578-1.0078.6557-.7225.8803.0607.2246.0607.8925.686 1.9064 1.4754 2.4893 1.8336.3643.3035.1457-.1032.0182-.0728-.164-.2733-1.3539-2.4467-1.445-2.4893-.6435-1.032-.17-.6194c-.0607-.255-.1032-.4674-.1032-.7285L6.287.1335 6.6997 0l.9957.1336.419.3642.6192 1.4147 1.0018 2.2282 1.5543 3.0296.4553.8985.2429.8318.091.255h.1579v-.1457l.1275-1.706.2368-2.0947.2307-2.6957.0789-.7589.3764-.9107.7468-.4918.5828.2793.4797.686-.0668.4433-.2853 1.8517-.5586 2.9021-.3643 1.9429h.2125l.2429-.2429.9835-1.3053 1.6514-2.0643.7286-.8196.85-.9046.5464-.4311h1.0321l.759 1.1293-.34 1.1657-1.0625 1.3478-.8804 1.1414-1.2628 1.7-.7893 1.36.0729.1093.1882-.0183 2.8535-.607 1.5421-.2794 1.8396-.3157.8318.3886.091.3946-.3278.8075-1.967.4857-2.3072.4614-3.4364.8136-.0425.0304.0486.0607 1.5482.1457.6618.0364h1.621l3.0175.2247.7892.522.4736.6376-.079.4857-1.2142.6193-1.6393-.3886-3.825-.9107-1.3113-.3279h-.1822v.1093l1.0929 1.0686 2.0035 1.8092 2.5075 2.3314.1275.5768-.3218.4554-.34-.0486-2.2039-1.6575-.85-.7468-1.9246-1.621h-.1275v.17l.4432.6496 2.3436 3.5214.1214 1.0807-.17.3521-.6071.2125-.6679-.1214-1.3721-1.9246L14.38 17.959l-1.1414-1.9428-.1397.079-.674 7.2552-.3156.3703-.7286.2793-.6071-.4614-.3218-.7468.3218-1.4753.3886-1.9246.3157-1.53.2853-1.9004.17-.6314-.0121-.0425-.1397.0182-1.4328 1.9672-2.1796 2.9446-1.7243 1.8456-.4128.164-.7164-.3704.0667-.6618.4008-.5889 2.386-3.0357 1.4389-1.882.929-1.0868-.0062-.1579h-.0546l-6.3385 4.1164-1.1293.1457-.4857-.4554.0608-.7467.2307-.2429 1.9064-1.3114Z" fill="#D97757"/></svg> Claude Usage Dashboard</h1>
|
|
14
|
+
<div class="controls">
|
|
15
|
+
<div id="date-picker" class="date-picker"></div>
|
|
16
|
+
<div id="plan-selector" class="plan-selector"></div>
|
|
17
|
+
<div class="refresh-controls">
|
|
18
|
+
<button id="btn-refresh" class="btn-refresh" title="Refresh now">↻</button>
|
|
19
|
+
<label class="auto-refresh-label">
|
|
20
|
+
<input type="checkbox" id="auto-refresh-toggle" checked> Auto
|
|
21
|
+
</label>
|
|
22
|
+
<span id="last-updated" class="last-updated"></span>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
</header>
|
|
26
|
+
|
|
27
|
+
<section class="summary-cards" id="summary-cards">
|
|
28
|
+
<div class="card" id="card-total-tokens">
|
|
29
|
+
<div class="card-label">Total Tokens</div>
|
|
30
|
+
<div class="card-value" id="val-total-tokens">—</div>
|
|
31
|
+
<div class="card-sub" id="sub-total-tokens"></div>
|
|
32
|
+
</div>
|
|
33
|
+
<div class="card" id="card-api-cost">
|
|
34
|
+
<div class="card-label">API Cost Equivalent</div>
|
|
35
|
+
<div class="card-value" id="val-api-cost">—</div>
|
|
36
|
+
<div class="card-sub" id="sub-api-cost">at standard API pricing</div>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="card" id="card-cache">
|
|
39
|
+
<div class="card-label">Cache Hit Rate</div>
|
|
40
|
+
<div class="card-value" id="val-cache-rate">—</div>
|
|
41
|
+
<div class="card-sub" id="sub-cache-rate">cache_read / total input</div>
|
|
42
|
+
</div>
|
|
43
|
+
</section>
|
|
44
|
+
|
|
45
|
+
<section class="chart-section" id="quota-section">
|
|
46
|
+
<div class="chart-header">
|
|
47
|
+
<h2>Subscription Quota</h2>
|
|
48
|
+
<span id="quota-last-updated" class="last-updated"></span>
|
|
49
|
+
</div>
|
|
50
|
+
<div id="chart-quota" class="chart-container"></div>
|
|
51
|
+
</section>
|
|
52
|
+
|
|
53
|
+
<section class="chart-section">
|
|
54
|
+
<div class="chart-header">
|
|
55
|
+
<h2>Token Consumption Trend</h2>
|
|
56
|
+
<div class="granularity-toggle" id="yaxis-toggle">
|
|
57
|
+
<button data-yaxis="tokens">Tokens</button>
|
|
58
|
+
<button data-yaxis="dollars">$</button>
|
|
59
|
+
</div>
|
|
60
|
+
<div class="granularity-toggle" id="granularity-toggle">
|
|
61
|
+
<button data-granularity="hourly">Hourly</button>
|
|
62
|
+
<button data-granularity="daily">Daily</button>
|
|
63
|
+
<button data-granularity="weekly">Weekly</button>
|
|
64
|
+
<button data-granularity="monthly">Monthly</button>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
<div id="chart-token-trend" class="chart-container"></div>
|
|
68
|
+
</section>
|
|
69
|
+
|
|
70
|
+
<section class="chart-row-3">
|
|
71
|
+
<div class="chart-section">
|
|
72
|
+
<h2>Cost: Subscription vs API</h2>
|
|
73
|
+
<div id="chart-cost-comparison" class="chart-container"></div>
|
|
74
|
+
</div>
|
|
75
|
+
<div class="chart-section">
|
|
76
|
+
<h2>Model Distribution</h2>
|
|
77
|
+
<div id="chart-model-distribution" class="chart-container"></div>
|
|
78
|
+
</div>
|
|
79
|
+
<div class="chart-section">
|
|
80
|
+
<h2>Cache Efficiency</h2>
|
|
81
|
+
<div id="chart-cache-efficiency" class="chart-container"></div>
|
|
82
|
+
</div>
|
|
83
|
+
</section>
|
|
84
|
+
|
|
85
|
+
<section class="chart-section">
|
|
86
|
+
<h2>Project Distribution</h2>
|
|
87
|
+
<div id="chart-project-distribution" class="chart-container"></div>
|
|
88
|
+
</section>
|
|
89
|
+
|
|
90
|
+
<section class="chart-section">
|
|
91
|
+
<div class="chart-header">
|
|
92
|
+
<h2>Session Details</h2>
|
|
93
|
+
<div class="table-controls">
|
|
94
|
+
<input type="text" id="session-filter" placeholder="Filter by project..." class="filter-input">
|
|
95
|
+
<select id="session-sort" class="sort-select">
|
|
96
|
+
<option value="date">Sort by: Date</option>
|
|
97
|
+
<option value="cost">Sort by: Cost</option>
|
|
98
|
+
<option value="tokens">Sort by: Tokens</option>
|
|
99
|
+
</select>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
<div id="session-table" class="table-container"></div>
|
|
103
|
+
<div id="session-pagination" class="pagination"></div>
|
|
104
|
+
</section>
|
|
105
|
+
|
|
106
|
+
<script type="module" src="/js/app.js"></script>
|
|
107
|
+
</body>
|
|
108
|
+
</html>
|
package/public/js/api.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
const BASE = '/api';
|
|
2
|
-
|
|
3
|
-
function qs(params) {
|
|
4
|
-
const entries = Object.entries(params).filter(([, v]) => v != null && v !== '');
|
|
5
|
-
return entries.length ? '?' + new URLSearchParams(entries).toString() : '';
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export async function fetchUsage(params = {}) { return (await fetch(`${BASE}/usage${qs(params)}`)).json(); }
|
|
9
|
-
export async function fetchModels(params = {}) { return (await fetch(`${BASE}/models${qs(params)}`)).json(); }
|
|
10
|
-
export async function fetchProjects(params = {}) { return (await fetch(`${BASE}/projects${qs(params)}`)).json(); }
|
|
11
|
-
export async function fetchSessions(params = {}) { return (await fetch(`${BASE}/sessions${qs(params)}`)).json(); }
|
|
12
|
-
export async function fetchCost(params = {}) { return (await fetch(`${BASE}/cost${qs(params)}`)).json(); }
|
|
13
|
-
export async function fetchCache(params = {}) { return (await fetch(`${BASE}/cache${qs(params)}`)).json(); }
|
|
14
|
-
export async function fetchStatus() { return (await fetch(`${BASE}/status`)).json(); }
|
|
15
|
-
export async function fetchQuota() { return (await fetch(`${BASE}/quota`)).json(); }
|
|
16
|
-
export async function fetchSubscription() { return (await fetch(`${BASE}/subscription`)).json(); }
|
|
1
|
+
const BASE = '/api';
|
|
2
|
+
|
|
3
|
+
function qs(params) {
|
|
4
|
+
const entries = Object.entries(params).filter(([, v]) => v != null && v !== '');
|
|
5
|
+
return entries.length ? '?' + new URLSearchParams(entries).toString() : '';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export async function fetchUsage(params = {}) { return (await fetch(`${BASE}/usage${qs(params)}`)).json(); }
|
|
9
|
+
export async function fetchModels(params = {}) { return (await fetch(`${BASE}/models${qs(params)}`)).json(); }
|
|
10
|
+
export async function fetchProjects(params = {}) { return (await fetch(`${BASE}/projects${qs(params)}`)).json(); }
|
|
11
|
+
export async function fetchSessions(params = {}) { return (await fetch(`${BASE}/sessions${qs(params)}`)).json(); }
|
|
12
|
+
export async function fetchCost(params = {}) { return (await fetch(`${BASE}/cost${qs(params)}`)).json(); }
|
|
13
|
+
export async function fetchCache(params = {}) { return (await fetch(`${BASE}/cache${qs(params)}`)).json(); }
|
|
14
|
+
export async function fetchStatus() { return (await fetch(`${BASE}/status`)).json(); }
|
|
15
|
+
export async function fetchQuota() { return (await fetch(`${BASE}/quota`)).json(); }
|
|
16
|
+
export async function fetchSubscription() { return (await fetch(`${BASE}/subscription`)).json(); }
|