skills/claude-usage-dashboard/SKILL.md
```markdown --- name: claude-usage-dashboard description: Local dashboard for tracking Claude Code token usage, costs, and session history from JSONL logs triggers: - track claude code usage - show claude token usage - claude code cost dashboard - how much am I spending on claude - visualize claude sessions - claude usage statistics - monitor claude code tokens - set up claude usage tracking --- # Claude Code Usage Dashboard > Skill by [ara.so](https://ara.so) — Daily 2026 Skil
npx skillsauth add aradotso/trending-skills skills/claude-usage-dashboardInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
---
name: claude-usage-dashboard
description: Local dashboard for tracking Claude Code token usage, costs, and session history from JSONL logs
triggers:
- track claude code usage
- show claude token usage
- claude code cost dashboard
- how much am I spending on claude
- visualize claude sessions
- claude usage statistics
- monitor claude code tokens
- set up claude usage tracking
---
# Claude Code Usage Dashboard
> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.
A zero-dependency local dashboard that reads Claude Code's JSONL session logs and turns them into charts, cost estimates, and usage summaries. Works on API, Pro, and Max plans.
---
## What it does
Claude Code writes detailed usage logs to `~/.claude/projects/` regardless of subscription type. This tool:
- **Parses** those JSONL files into a local SQLite database at `~/.claude/usage.db`
- **Estimates costs** using Anthropic API pricing (April 2026)
- **Serves a browser dashboard** at `http://localhost:8080` with Chart.js charts
- **Tracks** input tokens, output tokens, cache creation tokens, cache read tokens, model used, and session/project metadata
Captures usage from Claude Code CLI, VS Code extension, and Dispatched Code sessions. Does **not** capture Cowork sessions (server-side, no local transcripts).
---
## Installation
No pip, no venv, no build step. Requires Python 3.8+ (standard library only).
```bash
git clone https://github.com/phuryn/claude-usage
cd claude-usage
# macOS/Linux
python3 cli.py dashboard # scan + open browser dashboard at http://localhost:8080
python3 cli.py scan # parse JSONL files, populate ~/.claude/usage.db
python3 cli.py today # print today's usage summary by model
python3 cli.py stats # print all-time statistics
# Windows
python cli.py dashboard
python cli.py scan
python cli.py today
python cli.py stats
The scanner is incremental — it tracks each file's path and modification time, so re-running scan is fast (only processes new or changed files).
| File | Purpose |
|------|---------|
| scanner.py | Parses ~/.claude/projects/**/*.jsonl, writes to SQLite |
| dashboard.py | Serves single-page HTML/JS dashboard on localhost:8080 |
| cli.py | Entry point for scan, today, stats, dashboard commands |
Each session creates one JSONL file in ~/.claude/projects/. Each line is a JSON record. The scanner looks for assistant-type records:
{
"type": "assistant",
"message": {
"model": "claude-sonnet-4-6",
"usage": {
"input_tokens": 1234,
"output_tokens": 567,
"cache_creation_input_tokens": 890,
"cache_read_input_tokens": 4321
}
}
}
| Model | Input | Output | Cache Write | Cache Read | |-------|-------|--------|------------|-----------| | claude-opus-4-6 | $6.15/MTok | $30.75/MTok | $7.69/MTok | $0.61/MTok | | claude-sonnet-4-6 | $3.69/MTok | $18.45/MTok | $4.61/MTok | $0.37/MTok | | claude-haiku-4-5 | $1.23/MTok | $6.15/MTok | $1.54/MTok | $0.12/MTok |
Only models whose name contains opus, sonnet, or haiku are costed. Others show n/a.
Note: These are API prices. Max/Pro subscribers pay subscription rates, not per-token.
from scanner import Scanner
# Scan all Claude Code JSONL logs into ~/.claude/usage.db
scanner = Scanner()
scanner.scan()
# Access the SQLite database directly
import sqlite3
from pathlib import Path
db_path = Path.home() / ".claude" / "usage.db"
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Get total tokens by model
cursor.execute("""
SELECT model,
SUM(input_tokens) as total_input,
SUM(output_tokens) as total_output,
SUM(cache_read_input_tokens) as total_cache_read
FROM usage
GROUP BY model
ORDER BY total_input DESC
""")
rows = cursor.fetchall()
for row in rows:
print(row)
conn.close()
from dashboard import DashboardServer
# Start the dashboard on a custom port
server = DashboardServer(port=9090)
server.serve()
# Opens http://localhost:9090 in browser
import sqlite3
from pathlib import Path
from datetime import date, timedelta
db_path = Path.home() / ".claude" / "usage.db"
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Today's usage
today = date.today().isoformat()
cursor.execute("""
SELECT model,
SUM(input_tokens),
SUM(output_tokens),
SUM(cache_creation_input_tokens),
SUM(cache_read_input_tokens)
FROM usage
WHERE DATE(timestamp) = ?
GROUP BY model
""", (today,))
print("Today's usage:", cursor.fetchall())
# Last 7 days cost estimate (sonnet only)
week_ago = (date.today() - timedelta(days=7)).isoformat()
cursor.execute("""
SELECT
SUM(input_tokens) / 1_000_000.0 * 3.69 +
SUM(output_tokens) / 1_000_000.0 * 18.45 +
SUM(cache_creation_input_tokens) / 1_000_000.0 * 4.61 +
SUM(cache_read_input_tokens) / 1_000_000.0 * 0.37 AS estimated_cost
FROM usage
WHERE model LIKE '%sonnet%'
AND DATE(timestamp) >= ?
""", (week_ago,))
cost = cursor.fetchone()[0]
print(f"Estimated sonnet cost last 7 days: ${cost:.4f}")
# Sessions with most tokens
cursor.execute("""
SELECT session_id, SUM(input_tokens + output_tokens) as total_tokens
FROM usage
GROUP BY session_id
ORDER BY total_tokens DESC
LIMIT 10
""")
print("Top sessions:", cursor.fetchall())
conn.close()
# Run scan every hour, log output
crontab -e
# Add:
0 * * * * cd /path/to/claude-usage && python3 cli.py scan >> ~/claude-usage-scan.log 2>&1
import sqlite3
from pathlib import Path
db_path = Path.home() / ".claude" / "usage.db"
if not db_path.exists():
print("Database not found — run: python3 cli.py scan")
else:
conn = sqlite3.connect(db_path)
count = conn.execute("SELECT COUNT(*) FROM usage").fetchone()[0]
print(f"Database has {count} usage records")
conn.close()
The dashboard supports bookmarkable model filter URLs:
http://localhost:8080/?model=sonnet
http://localhost:8080/?model=opus
http://localhost:8080/?model=haiku
import sqlite3
from pathlib import Path
conn = sqlite3.connect(Path.home() / ".claude" / "usage.db")
cursor = conn.cursor()
cursor.execute("""
SELECT project,
COUNT(DISTINCT session_id) as sessions,
SUM(input_tokens + output_tokens) as total_tokens
FROM usage
GROUP BY project
ORDER BY total_tokens DESC
""")
for project, sessions, tokens in cursor.fetchall():
print(f"{project}: {sessions} sessions, {tokens:,} tokens")
conn.close()
# Check that Claude Code logs exist
ls ~/.claude/projects/
# Verify the database was created
ls ~/.claude/usage.db
# Run scan with verbose output
python3 cli.py scan
python3 cli.py scan first to populate the databasepython3 --version # needs 3.8+
# If below 3.8, upgrade Python via pyenv, homebrew, or system package manager
# Edit dashboard.py or start server on a different port
from dashboard import DashboardServer
DashboardServer(port=8081).serve()
Confirm you're using the Claude Code VS Code extension (not Claude.ai web). The extension writes to the same ~/.claude/projects/ directory. Re-run python3 cli.py scan after using VS Code.
Cowork sessions run server-side and do not write local JSONL transcripts — this is a platform limitation, not a bug in the tool.
-- Main usage table (created by scanner.py)
CREATE TABLE IF NOT EXISTS usage (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TEXT,
session_id TEXT,
project TEXT,
model TEXT,
input_tokens INTEGER,
output_tokens INTEGER,
cache_creation_input_tokens INTEGER,
cache_read_input_tokens INTEGER
);
-- File tracking table (incremental scan state)
CREATE TABLE IF NOT EXISTS scanned_files (
path TEXT PRIMARY KEY,
mtime REAL,
last_scanned TEXT
);
development
```markdown --- name: compose-performance-skills description: Install and use the skydoves/compose-performance-skills agent skill library to diagnose and fix Jetpack Compose performance issues including stability, recomposition, lazy layouts, modifiers, side effects, and build configuration. triggers: - "my composable recomposes too often" - "LazyColumn drops frames during scroll" - "diagnose Compose stability issues" - "fix unnecessary recomposition in Jetpack Compose" - "optimize Com
development
Headless iOS Simulator manager with host-side HID input injection, 60fps streaming, and device farm web UI for iOS 26
development
```markdown --- name: claude-code-game-studios description: Turn Claude Code into a full 49-agent game dev studio with 72 workflow skills, automated hooks, and a real studio hierarchy for Godot, Unity, and Unreal projects. triggers: - "set up claude code game studios" - "use ai agents for game development" - "set up game dev studio with claude" - "add game studio agents to my project" - "how do I use claude code for game dev" - "set up godot unity unreal ai workflow" - "49 agents g
development
```markdown --- name: xq-py-quantum-vm description: Python implementation of the Quip Network's quantum virtual machine (xqvm) triggers: - quantum virtual machine python - xqvm quip network - quantum circuit simulation python - xq-py quantum vm - quip network quantum python - simulate quantum gates python - quantum vm xqvm - xqvm-py quantum circuit --- # xq-py Quantum Virtual Machine > Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection. `xqvm-py` is a Python impl