ccusage-ui 0.1.0 → 0.1.2
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 +49 -0
- package/package.json +10 -2
- package/public/index.html +8 -6
- package/screenshot.png +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# ccusage-ui
|
|
2
|
+
|
|
3
|
+
Web UI dashboard for [Claude Code](https://claude.ai/code) usage statistics.
|
|
4
|
+
|
|
5
|
+
[](screenshot.png)
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+
|
|
10
|
+
## Quick Start
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npx ccusage-ui
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Or install globally:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g ccusage-ui
|
|
20
|
+
ccusage-ui
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
- Daily/Monthly usage trend charts
|
|
26
|
+
- Model breakdown visualization
|
|
27
|
+
- Token usage and cost tracking
|
|
28
|
+
- User level tier display
|
|
29
|
+
|
|
30
|
+
## Requirements
|
|
31
|
+
|
|
32
|
+
- Node.js >= 20
|
|
33
|
+
- [Claude Code](https://claude.ai/code) usage data
|
|
34
|
+
|
|
35
|
+
## Related
|
|
36
|
+
|
|
37
|
+
- [ccusage](https://github.com/ryoppippi/ccusage) - CLI tool for Claude Code usage
|
|
38
|
+
|
|
39
|
+
## Author
|
|
40
|
+
|
|
41
|
+
**Doha Park** - [sowonlabs.com](https://www.sowonlabs.com)
|
|
42
|
+
|
|
43
|
+
[](https://x.com/dohapark81)
|
|
44
|
+
[](https://www.threads.com/@dohapark81)
|
|
45
|
+
[](https://www.linkedin.com/in/dohapark81/)
|
|
46
|
+
|
|
47
|
+
## License
|
|
48
|
+
|
|
49
|
+
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ccusage-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"main": "server.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"ccusage-ui": "server.js"
|
|
@@ -10,9 +10,17 @@
|
|
|
10
10
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
11
|
},
|
|
12
12
|
"keywords": [],
|
|
13
|
-
"author": "",
|
|
13
|
+
"author": "Doha Park",
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"description": "Web UI for Claude Code usage statistics",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/sowonlabs/ccusage-ui.git"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/sowonlabs/ccusage-ui",
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/sowonlabs/ccusage-ui/issues"
|
|
23
|
+
},
|
|
16
24
|
"dependencies": {
|
|
17
25
|
"ccusage": "^18.0.0"
|
|
18
26
|
}
|
package/public/index.html
CHANGED
|
@@ -226,7 +226,7 @@
|
|
|
226
226
|
<div id="loading">
|
|
227
227
|
<div class="spinner"></div>
|
|
228
228
|
<div class="loading-text">Analyzing Usage Data...</div>
|
|
229
|
-
<div class="loading-sub">
|
|
229
|
+
<div class="loading-sub">This may take a few minutes on first load</div>
|
|
230
230
|
</div>
|
|
231
231
|
|
|
232
232
|
<div class="container" id="dashboard" style="display: none; opacity: 0; transition: opacity 0.5s;">
|
|
@@ -344,8 +344,8 @@
|
|
|
344
344
|
dashboard.style.opacity = '0'; // Fade out dashboard while reloading
|
|
345
345
|
|
|
346
346
|
try {
|
|
347
|
-
statusText.textContent = force ? "Refreshing Data..." : "
|
|
348
|
-
subText.textContent = force ? "
|
|
347
|
+
statusText.textContent = force ? "Refreshing Data..." : "Analyzing Usage Data...";
|
|
348
|
+
subText.textContent = force ? "This may take a few minutes..." : "This may take a few minutes on first load";
|
|
349
349
|
|
|
350
350
|
const query = force ? '?force=true' : '';
|
|
351
351
|
|
|
@@ -429,7 +429,9 @@
|
|
|
429
429
|
const ctx = document.getElementById('trendChart').getContext('2d');
|
|
430
430
|
if (trendChart) trendChart.destroy();
|
|
431
431
|
|
|
432
|
-
const dataSrc = currentView === 'daily'
|
|
432
|
+
const dataSrc = currentView === 'daily'
|
|
433
|
+
? [...dailyData].sort((a, b) => a.date.localeCompare(b.date)).slice(-30)
|
|
434
|
+
: [...monthlyData].sort((a, b) => a.month.localeCompare(b.month));
|
|
433
435
|
const labels = dataSrc.map(d => currentView === 'daily' ? d.date : d.month);
|
|
434
436
|
|
|
435
437
|
let datasetData;
|
|
@@ -480,7 +482,7 @@
|
|
|
480
482
|
Current: <b style="color:#0071e3">${getLevelName(lastVal)}</b> <span style="color:#86868b; margin-left: 5px;">(${lastVal.toFixed(0)}M)</span>
|
|
481
483
|
</div>
|
|
482
484
|
<div style="font-size: 14px; color: #1d1d1f;">
|
|
483
|
-
|
|
485
|
+
Pace: <b style="color:#5856d6">${getLevelName(projection)}</b> <span style="color:#86868b">(${projection.toFixed(0)}M)</span>
|
|
484
486
|
</div>
|
|
485
487
|
</div>
|
|
486
488
|
`;
|
|
@@ -583,7 +585,7 @@
|
|
|
583
585
|
stack: 'stack1'
|
|
584
586
|
},
|
|
585
587
|
{
|
|
586
|
-
label: '
|
|
588
|
+
label: 'Pace',
|
|
587
589
|
data: projectionData,
|
|
588
590
|
backgroundColor: 'rgba(52, 199, 89, 0.1)', // Very light green
|
|
589
591
|
borderColor: '#34c759',
|
package/screenshot.png
ADDED
|
Binary file
|