Skip to content

aaditagrawal/slopmeter

 
 

Repository files navigation

slopmeter

CLI tool that generates usage heatmaps for Amp, Claude Code, Codex, Crush, Cursor, Gemini CLI, Google Antigravity, Open Code, and Pi Coding Agent for the rolling past year (ending today).

Monorepo layout

packages/
  cli/
  registry/
tooling/
  typescript-config/

Setup

bun install
bun run check

Usage

# Build once
bun run build

# Run from built output
node packages/cli/dist/cli.js

# Run the CLI package directly in dev mode
bun run --cwd packages/cli dev

# Or if installed as a package binary
slopmeter

Options

# Output file (default: `./heatmap-last-year.png`; explicit provider flags add suffixes like `./heatmap-last-year_cursor.png`, and `--all` uses `./heatmap-last-year_all.png`)
slopmeter --output ./out/heatmap.svg
slopmeter -o ./out/heatmap.svg

# Output format
slopmeter --format png
slopmeter --format svg
slopmeter --format json
slopmeter -f svg

# Dark theme
slopmeter --dark
slopmeter --dark --format svg

# Merge all providers into one graph
slopmeter --all

# Provider filters (optional)
slopmeter --amp
slopmeter --antigravity
slopmeter --claude
slopmeter --codex
slopmeter --cursor
slopmeter --gemini
slopmeter --opencode
slopmeter --crush
slopmeter --pi

What the image shows

  • Monday-first contribution-style heatmap for the last year.
  • Top metrics per provider:
    • LAST 30 DAYS
    • INPUT TOKENS
    • OUTPUT TOKENS
    • TOTAL TOKENS (includes cache tokens)
  • Bottom metrics per provider:
    • MOST USED MODEL (with total tokens)
    • RECENT USE (LAST 30 DAYS) (with total tokens)
    • LONGEST STREAK
    • CURRENT STREAK

Model names are normalized to remove a trailing date suffix like -20251101.

Format behavior

  • Default format is PNG.
  • If --output is omitted, the default filename is ./heatmap-last-year.<ext>, ./heatmap-last-year_<providers>.<ext> for explicit provider flags, or ./heatmap-last-year_all.<ext> for --all.
  • If --format is omitted, format is inferred from --output extension (.png, .svg, or .json).
  • If neither provides a format, PNG is used.

JSON export

  • Use --format json (or an .json output filename) to export data for interactive rendering.
  • Export includes fixed version: "2026-03-11".
  • Each provider includes:
    • title and colors
    • daily rows with date, input, output, cache, total
    • daily[].breakdown per-model usage for that day, sorted by tokens.total (includes input and output)
    • insights (mostUsedModel, recentMostUsedModel) when available

Provider/data behavior

  • If no provider flags are passed, the CLI renders all providers with available data.
  • If --all is passed, the CLI renders one merged graph across all providers with consolidated totals, streaks, and model rankings.
  • Pi Coding Agent usage is derived from assistant messages in Pi session logs, grouped by the model that handled each turn.
  • Google Antigravity usage is aggregated from local Antigravity request logs, synced trajectorySummaries state, browser recording metadata, annotation view timestamps, and Antigravity-managed conversation/implicit file mtimes.
  • Google Antigravity currently reports activity, streaks, and best-effort model counts. It does not expose real input/output token totals from local state, so activity-only graphs show N/A for token counters.
  • If provider flags are passed, slopmeter only loads those providers and only prints availability for those providers.
  • If no provider flags are passed, the CLI loads all providers and prints availability for all providers.
  • If explicit provider flags are passed and any requested provider has no data, the command exits with an error.
  • If no provider flags are passed and no provider has data, the command exits with an error.

Environment knobs

  • SLOPMETER_FILE_PROCESS_CONCURRENCY: positive integer file-processing limit for Claude Code and Codex JSONL files. Default: 16.
  • SLOPMETER_MAX_JSONL_RECORD_BYTES: byte cap for Claude Code and Codex JSONL records, Gemini CLI session files, OpenCode JSON documents, and OpenCode SQLite message.data payloads. Default: 67108864 (64 MB).
  • ANTIGRAVITY_LOGS_DIR: overrides the Antigravity extension logs directory.
  • ANTIGRAVITY_STATE_DB: overrides the Antigravity state.vscdb path used for synced trajectory summaries.
  • ANTIGRAVITY_DATA_DIR: overrides the Antigravity local data dir used for browser recordings, annotations, conversations, and implicit state. Default: ~/.gemini/antigravity.

JSONL oversized-record behavior

  • Claude Code and Codex now share the same bounded JSONL record splitter and do not materialize whole files in memory.
  • Oversized Claude Code JSONL records fail the affected file with a clear error that names the file, line number, byte cap, and SLOPMETER_MAX_JSONL_RECORD_BYTES.
  • OpenCode legacy JSON message files use a bounded JSON document reader before JSON.parse.
  • OpenCode SQLite message.data payloads use the same byte cap before JSON.parse.
  • Oversized OpenCode JSON documents and SQLite message payloads fail clearly with the source path or row label, byte cap, and SLOPMETER_MAX_JSONL_RECORD_BYTES.
  • Codex now streams JSONL records and only parses records that affect usage aggregation.
  • Oversized irrelevant Codex records are skipped and summarized with a warning after processing.
  • Oversized relevant Codex records fail the affected file with a clear error that names the file, line number, byte cap, and SLOPMETER_MAX_JSONL_RECORD_BYTES.
  • Pi Coding Agent session logs are streamed and only assistant messages are parsed for usage aggregation.

Data locations

  • Claude Code: $CLAUDE_CONFIG_DIR/*/projects (comma-separated dirs) or defaults ~/.config/claude/projects and ~/.claude/projects
  • Codex: $CODEX_HOME/sessions or ~/.codex/sessions
  • Cursor: reads cursorAuth/accessToken and cursorAuth/refreshToken from $CURSOR_STATE_DB_PATH, $CURSOR_CONFIG_DIR/User/globalStorage/state.vscdb, ~/Library/Application Support/Cursor/User/globalStorage/state.vscdb (macOS), %APPDATA%/Cursor/User/globalStorage/state.vscdb (Windows), or ~/.config/Cursor/User/globalStorage/state.vscdb (Linux), then loads usage from Cursor's CSV export endpoint
  • Amp: $AMP_DATA_DIR or $XDG_DATA_HOME/amp or ~/.local/share/amp
  • Gemini CLI: $GEMINI_CONFIG_DIR/tmp/**/chats/session-*.json or ~/.gemini/tmp/**/chats/session-*.json
  • Open Code: prefers $OPENCODE_DATA_DIR/opencode.db or ~/.local/share/opencode/opencode.db, and falls back to $OPENCODE_DATA_DIR/storage/message or ~/.local/share/opencode/storage/message
  • Crush: reads crush.db from the current workspace ./.crush, ~/.crush, tracked Crush project data dirs listed in global projects.json, the global data dir itself, and project-local .crush/crush.db files discovered under HOME when Crush has not tracked them yet. The global metadata dir is discovered from $CRUSH_GLOBAL_DATA, $XDG_DATA_HOME/crush, %LOCALAPPDATA%\\crush, or ~/.local/share/crush
  • Pi Coding Agent: $PI_CODING_AGENT_DIR/sessions or ~/.pi/agent/sessions
  • Google Antigravity logs: $ANTIGRAVITY_LOGS_DIR or ~/Library/Application Support/Antigravity/logs (macOS), %APPDATA%\\Antigravity\\logs (Windows), or $XDG_CONFIG_HOME/Antigravity/logs / ~/.config/Antigravity/logs (Linux)
  • Google Antigravity synced state: $ANTIGRAVITY_STATE_DB or ~/Library/Application Support/Antigravity/User/globalStorage/state.vscdb (macOS), %APPDATA%\\Antigravity\\User\\globalStorage\\state.vscdb (Windows), or $XDG_CONFIG_HOME/Antigravity/User/globalStorage/state.vscdb / ~/.config/Antigravity/User/globalStorage/state.vscdb (Linux)
  • Google Antigravity local data: $ANTIGRAVITY_DATA_DIR or ~/.gemini/antigravity

About

CLI tool to show off how many tokens you use

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 99.2%
  • JavaScript 0.8%