Usage Dashboard
Reads every ~/.claude*/projects/**/*.jsonl transcript, sums input/output/cache
tokens + estimated cost, groups by instance, model, and day, then opens an HTML
dashboard. Each ~/.claude* config dir is treated as one instance (label =
dir suffix; ~/.claude → personal, ~/.claude-myfinancial → myfinancial).
Run
python3 ~/.claude/skills/usage-dashboard/dashboard.py
Writes claude_usage.html to the temp dir and opens it in the browser.
Daily Obsidian ledger
daily_obsidian.py reuses the same collector to write the usage into the
Obsidian vault ($VAULT_DIR, default ~/Documents/wiki):
python3 ~/.claude/skills/usage-dashboard/daily_obsidian.py
- One note per day at
wiki/usage/<YYYY-MM-DD>.md— frontmatter (cost/tokens/turns, Dataview-queryable) + tables: by instance, by project, by model, token composition. wiki/usage/index.md— rolling master table (newest day first) + all-time totals.- Idempotent: regenerates every run, self-heals missed days.
- Scheduled daily at 22:05 by
com.rohit.usage-ledger.plist(installed in~/Library/LaunchAgents/), just after theclaude-to-obsidianchat sync (22:00). - Self-check:
python3 daily_obsidian.py --selfcheck.
Scheduled-run attribution
Both the HTML dashboard and the Obsidian note split usage by what triggered
the run: Interactive (you typed it) vs each scheduled launchd job by name
(daily-financial-blog-post, daily-code-feature-add, daily-self-improve, …).
- HTML: the Schedule grouping button (next to Project/Model/Instance); click a row to drill into its tokens/models/turns.
- Obsidian: a top-level By schedule table + a per-account one in each note.
- Detection (in
dashboard.collect()): a launchd job runs headless with itsSKILL.mdas the prompt, so the session's first user message starts with that skill's YAML frontmatter (---\nname: <task>).TASK_REextracts the name; anything else isinteractive. No plist parsing, no API calls.
Notes
- Prices are list-rate estimates in the
PRICINGdict at the top ofdashboard.py. They drift — edit them to match your actual plan. - Self-check:
python3 dashboard.py --selfcheck(verifies cost math). - Adds a new instance automatically when a new
~/.claude*dir appears. - Instance label map (
personal→rohitgupta) lives inNAMESindaily_obsidian.pyandNAMEindashboard.py— edit to taste. - Lazy alternative for a single instance:
npx ccusage.