Tracks local query usage and token-rate estimates across Claude Code, Cline, and Codex / ChatGPT. Reads session files written by each tool, deduplicates against a local ledger, and reports token and price breakdowns across multiple providers (Anthropic, OpenAI, Amazon Bedrock, Google, Meta, Mistral).
- Python 3.9+
- At least one supported source:
- Claude Code (CLI)
- Cline (VS Code extension)
- Codex / ChatGPT (VS Code extension or CLI)
For the interactive dashboard:
Works best with a Nerd Font for full glyph coverage.
git clone https://github.com/brfid/lcost.git
cd lcost
pip install -e .After cloning, install the pre-commit hook to block accidental commits of runtime data:
./scripts/install-hooks.shTo include dashboard dependencies:
pip install -e '.[tui]'The package was renamed from claudit to lcost. On first run, lcost automatically renames legacy data/cache dirs:
~/.local/share/claudit/→~/.local/share/lcost/~/.cache/claudit/→~/.cache/lcost/
No manual migration needed. The old claudit CLI is gone — use lcost.
Run with no arguments to launch the interactive dashboard:
lcostPrint a text report instead:
lcost --reportlcost --report --days 7 # Last 7 active days
lcost --report --all # All days with activity
lcost --report --from 2026-04-01 --to 2026-04-30 # Specific range--from / --to are inclusive ISO dates. When either is set, it overrides --days.
lcost --source cline # Cline only
lcost --source claude-code # Claude Code only
lcost --source codex # Codex / ChatGPT onlyCase-insensitive substring match against the project path stored per entry:
lcost --project techdocs-tools
lcost --project dotfiles --days 60lcost --statsPrints file size, entry counts by source, date range, top projects, backup count, and per-source scan health (last success, records seen, and records added).
By default each run scans live data incrementally (unchanged files skipped, growing JSONL files resumed from the last byte offset). You can override:
lcost --cached # Skip scanning, report from stored data only
lcost --rescan # Ignore stored state, rescan all files from byte 0
lcost --deep # Re-parse every session file; keeps ledger entries, deduplicates
lcost --max-gap-hours 12 # Auto-promote to deep rescan if last ingest was >12h ago (default: 24)Use --deep when you suspect missed sessions. Use --rescan after recovering from a corrupt or missing ingest state.
If a provider updates rates, recalculate stored costs against the current pricing table:
lcost --recalc --dry-run # Preview changes without writing
lcost --recalc # Rewrite costs in the ledgerEntries with no configured rates are skipped and their stored cost is preserved. --recalc prints a skipped count alongside changed.
| Flag | Description |
|---|---|
--verbose, -v |
Show source discovery and error details |
--quiet, -q |
Suppress status messages |
--ledger-path PATH |
Use a different ledger file location |
Launch with lcost (the default mode).
The dashboard is a single dense board (btop-style): a KPI strip, a daily
price-or-token trend chart beside an hour × weekday heatmap, a 24-hour
activity bar, ranking panels, and the call log — all at once. Number keys
expand one panel to fullscreen; Esc (or 0) returns to the board.
| Key | Expands | Contents |
|---|---|---|
1 |
TREND | Daily time-series. m cycles cost / tokens I-O / cache tokens / savings |
2 |
HEATMAP | Hour × weekday heatmap. m cycles cost / requests / tokens |
3 |
LOG | Full call log: 100 most recent calls. j/k to move, enter for detail |
4 |
CALLS | Per-call cost distribution histogram |
On the board, m switches both the trend and heatmap between token price and
tokens. The all-source strip directly below the KPIs shows today's Codex,
Claude Code, and Cline values plus the most recent scan freshness. h cycles
the hourly bar (cost / tokens / requests). ] / [ cycle between the
fullscreen panels.
The board always shows today's session activity:
- Session stats — calls, cost, $/hr rate, cache efficiency, token totals
- Per-call distribution — median, P95, max call cost
- Hourly heat strip — 24-character braille sparkline of cost by hour
- Active projects — top 6 with cost bars
- Model mix — per-family color coding (Opus, Sonnet, Haiku, GPT-5, Nova, …)
- Stop reasons — counts of
end_turn,tool_use,max_tokens, etc. - Call log — 100 most recent calls with time, model, tokens, cache, cost bar, project, prompt preview
New entries from auto-refresh are flagged with ★ and shown in bold. Subagent calls are marked with ↳.
| Key | Action |
|---|---|
q |
Quit |
r |
Toggle auto-refresh (default: on, 30s) |
? |
Show help |
j / k |
Scroll down / up one line |
J / K |
Scroll ten lines |
ctrl+d / ctrl+u |
Page down / up |
g / G |
Jump to top / bottom |
1–4 |
Expand a panel fullscreen (TREND / HEATMAP / LOG / CALLS) |
0 / esc |
Return to the board |
] / [ |
Next / previous fullscreen panel |
enter |
Expand selected call (modal with full details) |
m |
Switch board price / tokens; fullscreen: cycle that panel's metric |
h |
Cycle hourly-bar metric: cost / tokens / requests |
ctrl+c |
Quit |
The status bar shows entry count, active days, refresh state, and a +N new badge when auto-refresh finds new entries.
On each run, lcost:
- Scans session data from Cline, Claude Code, and Codex / ChatGPT.
- Deduplicates entries against a local
ledger.jsonby entry ID. - Back-fills missing fields on existing entries (handles schema evolution).
- Reports cost and token breakdowns from the ledger.
Scanning is incremental — unchanged files are skipped and growing JSONL files resume from the last byte offset. State is stored in ingest_state.json.
If more than --max-gap-hours have elapsed since the last ingest (default: 24h), lcost auto-promotes to a deep rescan, re-parsing every session file from byte zero. Dedup by entry ID keeps the result consistent. This is the safety net against Claude Code's session cleanup window — as long as you run lcost at least once per that window, no data is lost.
The ledger is backed up daily to backups/ledger-YYYY-MM-DD.json (7 copies retained). To roll back, copy a backup over ledger.json.
Cline reports model IDs with provider prefixes when routing through AWS Bedrock or other gateways (e.g. us.anthropic.claude-opus-4-7, us.openai.gpt-5-5, us.amazon.nova-pro-v1). The collector strips recognized prefixes (anthropic, openai, amazon, meta, mistral, cohere, ai21, google, deepseek) so the same entry matches regardless of the gateway.
Model family detection is substring-based with more-specific families listed first: gpt-5-nano matches before bare gpt-5. New families are added by appending to the FAMILIES list in pricing.py.
Each ingested Claude Code call stores:
source,ts,model— provenance and timestampproject— decoded filesystem path (greedy resolver handles dashes in real directory names)session— JSONL filename stemisSubagent—trueif the session file is under*/subagents/*stopReason—end_turn,tool_use,max_tokens, etc.promptPreview— first 80 chars of the preceding user message (tool results excluded)- Token/cost fields:
tokensIn,tokensOut,cacheWrites,cacheReads,cost,cacheSavings
Codex reads rollout JSONL from $CODEX_HOME/sessions and
$CODEX_HOME/archived_sessions (default: ~/.codex/). This includes the
Codex VS Code extension's rollouts. It stores token-count observations and
minimal session metadata only—never prompts, responses, tool payloads, or
credentials.
For each query, tokensIn excludes cache reads and cache writes; those
numbers are recorded separately. Reasoning tokens are retained as metadata,
but are not added again because they are already included in output tokens.
Pricing is per model family, keyed off a single FAMILIES registry in lcost/pricing.py. Rates are USD per million tokens.
| Family | Input | Output | Cache write | Cache read | Source |
|---|---|---|---|---|---|
| Opus | 5.00 | 25.00 | 6.25 | 0.50 | anthropic.com/pricing |
| Sonnet | 3.00 | 15.00 | 3.75 | 0.30 | anthropic.com/pricing |
| Haiku | 1.00 | 5.00 | 1.25 | 0.10 | anthropic.com/pricing |
| GPT-5 | 1.25 | 10.00 | 1.25 | 0.125 | openai.com/pricing |
| GPT-5 mini | 0.25 | 2.00 | 0.25 | 0.025 | openai.com/pricing |
| GPT-5 nano | 0.05 | 0.40 | 0.05 | 0.005 | openai.com/pricing |
| GPT-5.6 Luna | 0.20 | 1.20 | 0.25 | 0.02 | Configured Codex Bedrock rate |
| GPT-5.6 Terra | 2.00 | 12.00 | 2.50 | 0.20 | Configured Codex Bedrock rate |
| GPT-5.6 Sol | 4.00 | 20.00 | 5.00 | 0.40 | Configured Codex Bedrock rate |
Cline costs come from the provider's inline per-call data and are stored
as-is. Claude Code and Codex costs are computed from the table above. Codex
uses the active Bedrock model's token rate for a per-query estimate—lcost does
not allocate ChatGPT or Codex subscription fees. Each new rate-card estimate
retains a versioned pricingRef in the ledger. Use --recalc to recompute
stored costs after a rate change; entries with no configured rates are
skipped. Verify rates against each provider's pricing page if you suspect
drift.
- Survives session cleanup — once ingested, entries persist in the ledger indefinitely.
- No double-counting — re-scanning the same data is safe; dedup is by entry ID.
- Non-destructive — lcost never modifies source data.
All files are stored in ~/.local/share/lcost/ by default ($XDG_DATA_HOME/lcost/ if set).
| File | Description |
|---|---|
ledger.json |
All ingested API call records, keyed by unique entry ID |
ingest_state.json |
Per-file byte offsets plus source scan health (safe to delete) |
backups/ledger-YYYY-MM-DD.json |
Daily ledger snapshots, last 7 retained |
Pidfile and caches live in ~/.cache/lcost/ ($XDG_CACHE_HOME/lcost/ if set).
cd lcost
pytest tests/ -vCovers: incremental ingest, file-state tracking, date/project/source filtering, model pricing fallback, prompt-preview extraction, schema-evolution back-fill, project-path resolution, subagent detection, gap-triggered deep rescan, backup rotation, orphan ingest-state cleanup, cross-provider model normalization, None-as-unpriced recalc semantics.
macOS, Windows, and Linux. Auto-detects OS-appropriate data directories for each source.