Skip to content

bircni/aitrack

Repository files navigation

aitrack

Track your AI coding-assistant usage across every machine β€” and own the data.

Each machine pushes a single JSON file to a git repo you control. Pull from anywhere to see a merged heatmap, stats table, and cost breakdown across Claude Code, Codex, and Cursor.

npm version CI node license


Why aitrack?

  • πŸ“Š One picture of everything β€” Claude Code + Codex + Cursor, merged across all your machines.
  • πŸ”’ You own the data β€” it lives in a git repo you create. No accounts, no telemetry, no third-party servers.
  • πŸ”‘ No API tokens for sync β€” uses your local git, so whatever auth already works in your terminal (SSH keys, credential manager) just works.
  • ⚑ Zero-setup preview β€” run npx aitrack show --tui and see your local usage before configuring anything.
  • πŸ’° Real cost estimates β€” per-model pricing applied to Claude Code token + cache usage.

Synced via git: Claude Code, Codex (OpenAI). Cursor is read locally on demand and never written to your repo (see Where data comes from).


See it

A live terminal table (aitrack show --tui) β€” same data also renders to a PNG heatmap via aitrack show:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Provider    β”‚ Days β”‚  Input β”‚ Output β”‚  Total β”‚ Est. cost β”‚  Streak β”‚ Peak month β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Claude Code β”‚   28 β”‚ 184.2M β”‚   1.4M β”‚ 185.6M β”‚   $142.80 β”‚ 12 / 12 β”‚ May 2026   β”‚
β”‚ Codex       β”‚   64 β”‚ 612.0M β”‚   3.1M β”‚ 615.1M β”‚   $318.40 β”‚   0 / 9 β”‚ Apr 2026   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ TOTAL       β”‚   92 β”‚ 796.2M β”‚   4.5M β”‚ 800.7M β”‚   $461.20 β”‚       β€” β”‚ β€”          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Today at a glance (aitrack usage today):

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Provider    β”‚ Tokens β”‚ Model             β”‚  Price β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ Claude Code β”‚  31.5M β”‚ claude-opus-4-8   β”‚ $25.38 β”‚
β”‚ Claude Code β”‚ 827.0K β”‚ claude-sonnet-4-6 β”‚  $0.47 β”‚
β”‚ Codex       β”‚  12.4M β”‚ gpt-5-codex       β”‚  $6.40 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚ TOTAL       β”‚  44.7M β”‚                   β”‚ $32.25 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Quick start

Preview instantly β€” no setup required:

npx aitrack show --tui     # stats table from local Claude/Codex (+ Cursor if available)
npx aitrack usage today    # today's usage, per provider + model
npx aitrack show           # heatmap PNG from the same local-first read

Your local data is staged at ~/.config/aitrack/pending/data/ so a later init/sync can adopt it into your repo.

Then, to sync across machines:

# 1. Create an EMPTY git repo (no README/license) β€” e.g. github.com/new β†’ "aitrack-data"
# 2. Configure + clone it locally:
npx aitrack init

# 3. Push this machine's data:
npx aitrack sync

# 4. View everything, from any machine:
npx aitrack show

init asks for your repo's remote URL (SSH or HTTPS β€” whatever you normally use) and clones it to ~/.config/aitrack/repo/. sync writes data/{your-hostname}.json and pushes it. show always reads fresh local Claude/Codex data, so you never need to sync first just to preview.

Multiple machines

Run aitrack init once per machine with the same repo URL, then aitrack sync on each. Every machine writes its own data/{hostname}.json, so there are no merge conflicts.


Commands

Command What it does
aitrack init Interactive setup β€” provide your repo URL and clone it locally
aitrack sync Read local data, write it to the cloned repo, and push
aitrack show Merge all sources and render a heatmap PNG (add --tui for a terminal table)
aitrack usage today Today's usage as a table: provider / tokens / model / price
aitrack usage week Rolling 7-day usage table
aitrack usage month Rolling 30-day usage table
aitrack usage year Current calendar-year usage table
aitrack usage all All-time usage table
aitrack recompute-costs Refresh costs: re-read local JSONL; reprice other machines from stored cache

show flags: --tui (terminal table instead of PNG), --all (single merged heatmap), --dark (dark mode), --no-cursor (skip Cursor), --no-open (don't auto-open the PNG), -o <path> (custom output path), --year <year> (filter to one calendar year). --no-cursor also works on every usage subcommand.


How it works

~/.config/aitrack/
β”œβ”€β”€ config.json          # repo URL + optional machineId
β”œβ”€β”€ pending/
β”‚   └── data/            # staged machine JSON before init/sync
β”‚       └── my-pc.json
└── repo/                # local clone of your data repo
    └── data/
        β”œβ”€β”€ my-pc.json
        └── work-laptop.json
  • Sync uses a local git clone at ~/.config/aitrack/repo/ with your existing git credentials β€” ordinary pulls and pushes.
  • show (PNG or --tui) always reads fresh local Claude/Codex JSONL on the current machine and merges in other machines' synced files. No sync needed to preview.
  • Before init, local usage is staged in ~/.config/aitrack/pending/data/ and adopted on the next init/sync.
  • Cursor is loaded only on the current machine: aitrack reads cursorAuth/accessToken from Cursor's local state.vscdb, then calls Cursor's own CSV usage export over HTTPS. The token is used solely for that request β€” it is never written to your repo or sent anywhere else. Use --no-cursor to skip it.
  • Heatmap intensity anchors on the 90th-percentile day rather than the absolute max, so one huge day doesn't flatten the rest of the year.

Cost handling

Claude Code cost is an API-equivalent estimate from per-model pricing and token/cache usage, keyed by Claude API model id with the date suffix stripped (see src/readers/claude.ts). Cursor and Codex local-session cost are left unknown because their local data doesn't expose a reliable all-history cost. If stored costs are missing or pricing changed, run aitrack recompute-costs.


Configuration

Stored at ~/.config/aitrack/config.json:

{
  "repoUrl": "git@github.com:your-username/aitrack-data.git",
  "machineId": "work-laptop"
}

machineId is optional β€” without it, sync uses your OS hostname as the filename. Set a stable name during init if your hostname might collide across machines or change after a reinstall. Existing hostname-based files keep working when read.


Where data comes from

Provider Source
Claude Code ~/.claude/projects/**/*.jsonl or $XDG_CONFIG_HOME/claude/projects/**/*.jsonl
Codex ~/.codex/sessions/*.jsonl or $CODEX_HOME/sessions/*.jsonl
Cursor (show only) local state.vscdb, then Cursor's HTTPS CSV export β€” never synced to your repo

Default state.vscdb locations (override with CURSOR_STATE_DB_PATH or CURSOR_CONFIG_DIR):

  • macOS: ~/Library/Application Support/Cursor/User/globalStorage/state.vscdb
  • Windows: %APPDATA%\Cursor\User\globalStorage\state.vscdb
  • Linux: ~/.config/Cursor/User/globalStorage/state.vscdb

Optional: CURSOR_WEB_BASE_URL (default https://cursor.com).


Data format

Each machine's file in the repo:

{
  "hostname": "my-pc",
  "lastUpdated": "2026-04-12T10:00:00.000Z",
  "days": {
    "2026-04-12": {
      "claude_code": {
        "byModel": {
          "claude-sonnet-4-6": { "inputTokens": 45000, "outputTokens": 3200, "costUSD": 0.183 }
        },
        "totals": { "inputTokens": 45000, "outputTokens": 3200, "costUSD": 0.183 }
      },
      "codex": {
        "byModel": { "codex-1": { "inputTokens": 12000, "outputTokens": 800 } },
        "totals": { "inputTokens": 12000, "outputTokens": 800 }
      }
    }
  }
}

Requirements

  • Node.js 22+
  • git installed and on your PATH
  • A git remote you can push to (GitHub or any host)

Native dependencies (better-sqlite3, @napi-rs/canvas) install automatically; on some systems you may need build tools if prebuilt binaries aren't available.


License

MIT

About

A small CLI tool to visualize your AI Usage

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Contributors