[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-81324":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":13,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":16,"stars30d":17,"stars90d":15,"forks30d":15,"starsTrendScore":18,"compositeScore":19,"rankGlobal":10,"rankLanguage":10,"license":20,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":21,"hasPages":21,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":40,"readmeContent":41,"aiSummary":42,"trendingCount":15,"starSnapshotCount":15,"syncStatus":43,"lastSyncTime":44,"discoverSource":45},81324,"aiusage","juliantanx\u002Faiusage","juliantanx","Open-source AI usage tracker — tokens, cost, and sessions across Claude Code, Codex, Hermes, Qoder, and more","https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@juliantanx\u002Faiusage",null,"TypeScript",80,6,44,0,7,36,4,49.64,"MIT License",false,"main",[24,25,26,27,5,28,29,30,31,32,33,34,35,36,37,38,39],"ai","ai-analytics","ai-coding-assistant","ai-usage","better-sqlite3","claude","claude-code","cli","codex","cost-tracking","dashboard","developer-tools","react","token-tracker","token-usage","typescript","2026-06-12 04:01:32","# aiusage — AI Coding Assistant Usage Tracker\n\n**Website: [aiusage.jtanx.com](https:\u002F\u002Faiusage.jtanx.com)**\n\nTrack token usage, cost, and sessions across **7 AI coding tools** — local-first, no accounts required.\n\n[![npm version](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fv\u002F@juliantanx\u002Faiusage)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@juliantanx\u002Faiusage)\n[![CI](https:\u002F\u002Fgithub.com\u002Fjuliantanx\u002Faiusage\u002Factions\u002Fworkflows\u002Ftest.yml\u002Fbadge.svg)](https:\u002F\u002Fgithub.com\u002Fjuliantanx\u002Faiusage\u002Factions\u002Fworkflows\u002Ftest.yml)\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-blue.svg)](https:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT)\n[![Node.js](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FNode.js-20%2B-green.svg)](https:\u002F\u002Fnodejs.org\u002F)\n[![Website](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FWebsite-aiusage.jtanx.com-blue.svg)](https:\u002F\u002Faiusage.jtanx.com)\n\nEnglish | [中文](https:\u002F\u002Fgithub.com\u002Fjuliantanx\u002Faiusage\u002Fblob\u002Fmain\u002FREADME_zh.md)\n\n## Quick Start\n\n**Prerequisites:** Node.js 20 or later\n\n```bash\nnpm install -g @juliantanx\u002Faiusage\naiusage parse\naiusage serve\n```\n\nOpen `http:\u002F\u002Flocalhost:3847` to explore the dashboard.\n\n\u003Cp align=\"center\">\n  \u003Cimg src=\"https:\u002F\u002Fraw.githubusercontent.com\u002Fjuliantanx\u002Faiusage\u002Fa527444cf87a9c1e92f1440282ed4e94f744b910\u002Fpackages\u002Fsite\u002Fstatic\u002Fscreenshots\u002Fdashboard-home.png\" alt=\"aiusage dashboard home\" width=\"32%\" \u002F>\n  \u003Cimg src=\"https:\u002F\u002Fraw.githubusercontent.com\u002Fjuliantanx\u002Faiusage\u002Fa527444cf87a9c1e92f1440282ed4e94f744b910\u002Fpackages\u002Fsite\u002Fstatic\u002Fscreenshots\u002Foverview.png\" alt=\"aiusage overview dashboard\" width=\"32%\" \u002F>\n  \u003Cimg src=\"https:\u002F\u002Fraw.githubusercontent.com\u002Fjuliantanx\u002Faiusage\u002Fa527444cf87a9c1e92f1440282ed4e94f744b910\u002Fpackages\u002Fsite\u002Fstatic\u002Fscreenshots\u002Fsessions.png\" alt=\"aiusage sessions dashboard\" width=\"32%\" \u002F>\n\u003C\u002Fp>\n\n> If aiusage is useful, **[star this repo](https:\u002F\u002Fgithub.com\u002Fjuliantanx\u002Faiusage)** to help more developers discover it.\n\n`aiusage` does not run a built-in background parser. If you want automatic imports, schedule `aiusage parse` with cron or Task Scheduler.\n\n### Running in Background (PM2)\n\n`aiusage serve` runs in the foreground and stops when you close the terminal. To keep it running in the background on **Windows, macOS, and Linux**, use [PM2](https:\u002F\u002Fpm2.keymetrics.io\u002F):\n\n```bash\n# Install PM2 (one-time)\nnpm install -g pm2\n\n# Start aiusage as background services (generates config + starts PM2)\naiusage pm2-start\n\n# Set auto-start on boot (Linux \u002F macOS: run directly; Windows: run the output command as Administrator)\npm2 startup\n\n# Common commands\npm2 list            # View running status\npm2 logs            # View logs\npm2 stop all        # Stop all services\npm2 restart all     # Restart all services\npm2 delete all      # Remove all services\n```\n\n\u003Cdetails>\n\u003Csummary>Build from source\u003C\u002Fsummary>\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fjuliantanx\u002Faiusage.git\ncd aiusage\npnpm install\npnpm build\ncd packages\u002Fcli\nnpm link\n```\n\nAfter pulling updates, rebuild to pick up changes:\n\n```bash\npnpm build\n```\n\nIf you switch Node.js versions locally, recompile the `better-sqlite3` native module for the new version:\n\n```bash\npnpm rebuild:sqlite\n```\n\n> This is only needed when developing from source. Users who install via `npm install -g` do not need to do this — the module is compiled automatically during installation.\n\n\u003C\u002Fdetails>\n\n## Why aiusage\n\nYour AI coding tools each log usage separately — different formats, different machines, no shared view. aiusage pulls it all into one local dashboard with no accounts, no telemetry, and no cloud required.\n\n- **One dashboard** for tokens, cost, model mix, and tool-call activity\n- **Multi-machine sync** via GitHub, S3, or R2 — entirely optional\n- **Your data stays local** by default\n\n## Supported tools\n\n| Tool | Status |\n|------|--------|\n| Claude Code | ✅ |\n| Codex | ✅ |\n| OpenCode | ✅ |\n| Cursor | ✅ |\n| Hermes | ✅ |\n| Qoder | ✅ |\n| OpenClaw | ✅ |\n\n\n## CLI Reference\n\n### `aiusage` (default)\n\nPrint a usage summary to the terminal (same as `aiusage summary`).\n\n### `aiusage parse`\n\nImport newly appended local session data from discovered source paths.\n\n| Option | Description |\n|--------|-------------|\n| `--tool \u003Ctool>` | Only parse a specific tool: `claude-code`, `codex`, `openclaw`, `opencode`, `hermes`, `qoder`, `cursor` |\n| `--progress` | Show real-time progress bar on stderr (TTY only, silent in pipes\u002FCI) |\n\n```bash\naiusage parse                        # Parse all tools\naiusage parse --tool claude-code     # Only parse Claude Code logs\naiusage parse --progress             # Show progress bar while parsing\n```\n\n### `aiusage serve`\n\nStart the local web dashboard and runtime settings controller.\n\n| Option | Description | Default |\n|--------|-------------|---------|\n| `-p, --port \u003Cport>` | Port number | `3847` |\n\n```bash\naiusage serve             # Start on port 3847\naiusage serve -p 8080     # Start on port 8080\n```\n\n### `aiusage summary`\n\nPrint a usage summary in the terminal.\n\n| Option | Description |\n|--------|-------------|\n| `--device \u003Cid>` | Filter by device instance ID |\n| `--tool \u003Ctool>` | Filter by tool type (`claude-code`, `codex`, `openclaw`, `opencode`, `hermes`, `qoder`, `cursor`) |\n\n```bash\naiusage summary                        # All-time summary\naiusage summary --tool claude-code     # Single tool\n```\n\n### `aiusage status`\n\nShow version, device name, DB path, schema version, table\u002Fview counts, record count, DB size, and sync status.\n\n### `aiusage export`\n\nExport records as CSV, JSON, or NDJSON.\n\n| Option | Description | Required |\n|--------|-------------|----------|\n| `--format \u003Cformat>` | Output format: `csv`, `json`, `ndjson` | Yes |\n| `-o, --output \u003Cfile>` | Output file path (default: stdout) | No |\n\n```bash\naiusage export --format csv                 # CSV to stdout\naiusage export --format json -o report.json # JSON to file\naiusage export --format ndjson              # NDJSON to stdout\n```\n\n### `aiusage clean`\n\nRemove old records from the local database based on age.\n\n| Option | Description | Default |\n|--------|-------------|---------|\n| `--before \u003Cduration>` | Delete data older than this duration (e.g. `30d`, `180d`) | `180d` |\n\n```bash\naiusage clean                    # Delete records older than 180 days\naiusage clean --before 30d       # Delete records older than 30 days\naiusage clean --before 90d --yes # Delete records older than 90 days, skip confirm\n```\n\n### `aiusage reset`\n\nDelete all parsed records, tool calls, synced data, and the parse watermark. Source log files (`~\u002F.claude`, `~\u002F.codex`, etc.) are **not** affected. Use this to re-import everything from scratch.\n\n| Option | Description |\n|--------|-------------|\n| `--yes` | Skip confirmation prompt (required to execute) |\n\n```bash\naiusage reset --yes    # Wipe all data, then run `aiusage parse` to re-import\n```\n\n### `aiusage recalc`\n\nRecalculate costs using the latest pricing data.\n\n```bash\naiusage recalc\n```\n\n### `aiusage init`\n\nConfigure a sync backend for multi-machine data aggregation.\n\n| Option | Description |\n|--------|-------------|\n| `--backend \u003Cbackend>` | Sync backend: `github`, `s3`, `skip` |\n| `--repo \u003Crepo>` | GitHub repository (format: `username\u002Frepo-name`) |\n| `--token \u003Ctoken>` | GitHub Personal Access Token |\n| `--bucket \u003Cbucket>` | S3 bucket name |\n| `--prefix \u003Cprefix>` | S3 object prefix (default: `aiusage\u002F`) |\n| `--endpoint \u003Cendpoint>` | S3 endpoint URL |\n| `--region \u003Cregion>` | S3 region (default: `auto`) |\n| `--access-key-id \u003Cid>` | S3 access key ID |\n| `--secret-access-key \u003Ckey>` | S3 secret access key |\n| `--device \u003Calias>` | Device alias |\n\n```bash\naiusage init --backend github --repo user\u002Faiusage-data --token ghp_xxx\naiusage init --backend s3 --bucket my-bucket --endpoint https:\u002F\u002Fxxx.r2.cloudflarestorage.com --access-key-id AKIAxxx --secret-access-key xxx\n```\n\n### `aiusage sync`\n\nPush and pull data with the configured remote backend.\n\n```bash\naiusage sync\n```\n\n## Web Dashboard\n\n```bash\naiusage serve\n# Open http:\u002F\u002Flocalhost:3847\n```\n\n`aiusage serve` hosts the following dashboard pages:\n\n- **Home (`\u002F`)** — live counter homepage. On first load it calls `\u002Fapi\u002Frefresh`, runs one incremental local parse, then loads summary data. After that, it refreshes on the configured dashboard poll interval.\n- **Overview (`\u002Foverview`)** — totals, cost, active days, and per-tool breakdowns for Today, This Week, This Month, Last 30d, or All Time.\n- **Tokens** — token usage trends over time, with breakdown-by-type or combined total view.\n- **Cost** — cost trends with by-tool and by-model breakdowns.\n- **Models** — model share and distribution.\n- **Tool Calls** — tool call frequency and ranking.\n- **Projects** — project-level usage rollups.\n- **Sessions** — session browsing with filters and pagination.\n- **Pricing** — active model pricing reference.\n- **Settings** — configure device name, week start day, dashboard poll interval, auto-parse interval, source paths, sync backend, credentials, and local data retention without editing config files manually.\n- **Docs** — in-app documentation with CLI reference and feature guides.\n\n**Settings behavior**\n\n- **Dashboard Poll Interval** is in milliseconds and only controls the homepage refresh cycle after the initial load.\n- **Auto-Parse Interval** is in milliseconds and schedules background `aiusage parse` runs only while `aiusage serve` is running. Set `0` or leave it blank to disable it.\n- **Local Data Retention** runs periodic cleanup only while `aiusage serve` is running. Set `0` or leave it blank to keep data forever.\n- **Source path** changes take effect on the next parse.\n- **Sync backend and credential** changes take effect on the next sync.\n\n---\n\n## Deployment\n\nNeed multi-machine aggregation or cloud access? Choose your scenario:\n\n| Scenario | Method | Description |\n|----------|--------|-------------|\n| Multiple machines, aggregate data | [Multi-Machine Sync](#multi-machine-sync) | Sync via GitHub\u002FS3\u002FR2 |\n| Multiple machines + unified dashboard | [Docker Deployment](#docker-deployment) | Run a 24\u002F7 dashboard from synced data |\n\nFor single-machine usage, Quick Start is enough.\n\n### Multi-Machine Sync\n\nUse this to aggregate token usage from multiple machines into one dashboard. Works with Claude Code, Codex, OpenClaw, OpenCode, Hermes, and Qoder.\n\n**Architecture:**\n\n```\nMachine A ──┐\nMachine B ──┼──▶ GitHub \u002F S3 \u002F R2 (shared storage) ──▶ Any machine: aiusage summary \u002F serve\nMachine C ──┘\n```\n\n**Step 1 — Choose a sync backend**\n\n**Option A: GitHub (recommended)**\n\n1. Create a **private** repository on GitHub (for example `aiusage-data`)\n2. Generate a [Personal Access Token](https:\u002F\u002Fgithub.com\u002Fsettings\u002Ftokens) with `repo` scope\n\n**Option B: AWS S3 \u002F Cloudflare R2**\n\n1. Create an S3 or R2 bucket\n2. Create an IAM user or role with read\u002Fwrite permissions\n3. Note the access key ID, secret access key, and endpoint\n\n**Step 2 — Install and configure on each machine**\n\nOn every machine that uses Claude Code, Codex, OpenClaw, OpenCode, Hermes, or Qoder:\n\n```bash\n# Install aiusage CLI\nnpm install -g @juliantanx\u002Faiusage\n\n# Configure sync backend — GitHub\naiusage init --backend github \\\n  --repo \u003Cuser>\u002Faiusage-data \\\n  --token ghp_xxxxxxxxxxxxxxxxxxxx\n\n# OR configure sync backend — S3 \u002F R2\naiusage init --backend s3 \\\n  --bucket my-aiusage-bucket \\\n  --prefix aiusage\u002F \\\n  --endpoint https:\u002F\u002F\u003Caccount-id>.r2.cloudflarestorage.com \\\n  --region auto \\\n  --access-key-id AKIAxxxxxxxxxxxx \\\n  --secret-access-key xxxxxxxxxxxxxxxxxxxxxxxxxx\n```\n\n**Step 3 — Parse and sync on each machine**\n\n```bash\naiusage parse\naiusage sync\n```\n\n**Step 4 — View aggregated data on any machine**\n\n```bash\naiusage sync\naiusage summary\naiusage serve\n```\n\n**Automate (recommended)**\n\n```bash\n# Linux\u002FmacOS\ncrontab -e\n# Add:\n*\u002F30 * * * * \u002Fusr\u002Flocal\u002Fbin\u002Faiusage parse && \u002Fusr\u002Flocal\u002Fbin\u002Faiusage sync >> ~\u002F.aiusage\u002Fcron.log 2>&1\n\n# Windows\nschtasks \u002Fcreate \u002Ftn \"AiusageSync\" \u002Ftr \"aiusage parse && aiusage sync\" \u002Fsc minute \u002Fmo 30\n```\n\n**How sync works**\n\n- Each machine has a unique `deviceInstanceId` generated on first run.\n- Each device writes to its own daily file (`{deviceInstanceId}\u002FYYYY\u002FMM\u002FDD.ndjson`) in the remote backend.\n- Pull reads other devices' files into the local `synced_records` table; upload writes only this device's files.\n- Device-partitioned files avoid write conflicts, so no locking is needed.\n- Sync frequency comes from your external scheduler or manual runs; aiusage does not include a built-in sync daemon.\n- Session IDs are anonymized via `sha256(device + sessionId)`.\n\n---\n\n### Docker Deployment\n\nRun the pre-built image on a server for a 24\u002F7 dashboard. The container does **not** run any AI coding tools itself — it serves the web dashboard, can run the same runtime settings controller as `aiusage serve`, and can pull synced data from GitHub, S3, or R2.\n\n**Architecture:**\n\n```\nMachine A ──┐                           ┌── Browser: https:\u002F\u002Faiusage.your-domain.com\nMachine B ──┼──▶ GitHub \u002F S3 \u002F R2 ──▶ Cloud Server (Docker)\nMachine C ──┘                           └── port 3847\n```\n\n**How data flows**\n\n1. Each dev machine runs `aiusage parse && aiusage sync` to upload local usage data.\n2. The Docker container runs `aiusage sync` to pull that data into its local SQLite database.\n3. The web dashboard reads from the local database and displays aggregated stats.\n\n**Data storage in Docker**\n\n| Item | Container path | Description |\n|------|---------------|-------------|\n| Database | `\u002Froot\u002F.aiusage\u002Fcache.db` | SQLite database with aggregated usage data |\n| Config | `\u002Froot\u002F.aiusage\u002Fconfig.json` | Sync backend config, runtime settings, and credentials |\n| State | `\u002Froot\u002F.aiusage\u002Fstate.json` | Consent and sync runtime state |\n| Watermarks | `\u002Froot\u002F.aiusage\u002Fwatermark.json` | Incremental parse cursors |\n\nAll data lives under `\u002Froot\u002F.aiusage`, which is declared as a `VOLUME`. You **must** mount this volume to persist data across container restarts.\n\n**Step 1 — Pull image and run**\n\n```bash\n# Pull image\ndocker pull juliantanx\u002Faiusage\n\n# Run container (mount volume for data persistence)\ndocker run -d \\\n  --name aiusage \\\n  -p 3847:3847 \\\n  -v aiusage-data:\u002Froot\u002F.aiusage \\\n  juliantanx\u002Faiusage\n\n# Configure sync backend\ndocker exec -it aiusage aiusage init \\\n  --backend github \\\n  --repo \u003Cuser>\u002Faiusage-data \\\n  --token ghp_xxxxxxxxxxxxxxxxxxxx\n\n# Initial data pull\ndocker exec -it aiusage aiusage sync\n```\n\n> Without the `-v` flag, data is lost when the container is removed.\n\n**Step 2 — Scheduled sync**\n\n```bash\n# Install cron in container and create scheduled task\ndocker exec -it aiusage bash -c \"apt-get update && apt-get install -y cron\"\ndocker exec -it aiusage bash -c \\\n  'echo \"*\u002F30 * * * * aiusage sync >> \u002Froot\u002F.aiusage\u002Fcron.log 2>&1\" | crontab -'\ndocker restart aiusage\n```\n\n> Note: `parse` is not needed here unless you also mount local AI session logs into the container. In the standard deployment, only `sync` is needed to pull data from the remote backend.\n\n**Step 3 — Access**\n\nOpen `http:\u002F\u002F\u003Cserver-ip>:3847`.\n\nFor HTTPS with a custom domain:\n\n```bash\n# Caddy (auto HTTPS, recommended)\ncaddy reverse-proxy --from aiusage.your-domain.com --to localhost:3847\n\n# Or Nginx\nserver {\n    listen 80;\n    server_name aiusage.your-domain.com;\n    location \u002F {\n        proxy_pass http:\u002F\u002F127.0.0.1:3847;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n    }\n}\n```\n\n**Build image yourself (optional)**\n\nA `Dockerfile` is included in the project root:\n\n```bash\ndocker build -t aiusage .\n```\n\n---\n\n## Data Storage\n\n| Item | Path |\n|------|------|\n| Local database | `~\u002F.aiusage\u002Fcache.db` |\n| Config | `~\u002F.aiusage\u002Fconfig.json` |\n| Sync state | `~\u002F.aiusage\u002Fstate.json` |\n| Parse watermarks | `~\u002F.aiusage\u002Fwatermark.json` |\n\n### Default Source Paths\n\n`aiusage parse` auto-discovers session logs from the following default locations:\n\n| Tool | macOS | Linux | Windows |\n|------|-------|-------|---------|\n| Claude Code | `~\u002F.claude\u002Fprojects\u002F` | `~\u002F.claude\u002Fprojects\u002F` | `%USERPROFILE%\\.claude\\projects\\` |\n| Codex | `~\u002F.codex\u002Fsessions\u002F` | `~\u002F.codex\u002Fsessions\u002F` | `%USERPROFILE%\\.codex\\sessions\\` |\n| OpenClaw | `~\u002F.openclaw\u002Fagents\u002F*\u002Fsessions\u002F` | `~\u002F.openclaw\u002Fagents\u002F*\u002Fsessions\u002F` | `%USERPROFILE%\\.openclaw\\agents\\*\\sessions\\` |\n| OpenCode | `~\u002FLibrary\u002FApplication Support\u002Fopencode\u002Fopencode.db` | `~\u002F.local\u002Fshare\u002Fopencode\u002Fopencode.db` | `%APPDATA%\\opencode\\opencode.db` |\n| Hermes | `~\u002F.hermes\u002Fstate.db` | `~\u002F.hermes\u002Fstate.db` | `%USERPROFILE%\\.hermes\\state.db` |\n| Qoder (sessions) | `~\u002F.qoder\u002Flogs\u002Fsessions\u002F` | `~\u002F.qoder\u002Flogs\u002Fsessions\u002F` plus WSL-mounted Windows user homes | `%USERPROFILE%\\.qoder\\logs\\sessions\\` |\n| Qoder (SQLite) | `~\u002FLibrary\u002FApplication Support\u002FQoder\u002FSharedClientCache\u002Fcache\u002Fdb\u002Flocal.db` | `~\u002F.local\u002Fshare\u002FQoder\u002FSharedClientCache\u002Fcache\u002Fdb\u002Flocal.db` | `%LOCALAPPDATA%\\Qoder\\SharedClientCache\\cache\\db\\local.db` |\n| Cursor | `~\u002FLibrary\u002FApplication Support\u002FCursor\u002FUser\u002FglobalStorage\u002Fstate.vscdb` | `~\u002F.config\u002FCursor\u002FUser\u002FglobalStorage\u002Fstate.vscdb` | `%APPDATA%\\Cursor\\User\\globalStorage\\state.vscdb` |\n\nDiscovery behavior:\n\n- **Claude Code** — recursively scans `~\u002F.claude\u002Fprojects\u002F**` for `.jsonl` files, including nested subagent logs.\n- **Codex** — recursively scans `~\u002F.codex\u002Fsessions\u002F**` for `.jsonl` files.\n- **OpenClaw** — scans each agent's `sessions\u002F` directory under `~\u002F.openclaw\u002Fagents\u002F*\u002Fsessions\u002F` and skips checkpoint files.\n- **OpenCode** — reads the SQLite database file directly instead of `.jsonl` logs.\n- **Hermes** — reads the SQLite database file (`state.db`) directly. Sessions without a recorded end time are still imported if they have token data (e.g. sessions from a force-quit).\n- **Qoder (sessions)** — recursively scans structured session segment logs (`logs\u002Fsessions\u002F**\u002Fsegments\u002F*.jsonl`) and imports `model.response.completed` token events. On WSL, aiusage also checks mounted Windows user homes such as `\u002Fmnt\u002Fc\u002FUsers\u002F\u003Cuser>`, `\u002Fmnt\u002Fd\u002FUsers\u002F\u003Cuser>`, and `\u002Fmnt\u002Fe\u002FUsers\u002F\u003Cuser>` for the same Qoder session-log layout.\n- **Qoder (SQLite)** — reads the `local.db` SQLite database directly (`SharedClientCache\u002Fcache\u002Fdb\u002Flocal.db`) and imports assistant messages from the `chat_message` table, joined with `chat_record` for model information. This is the primary source on macOS and is tried alongside the sessions directory.\n- **Cursor** — reads Cursor's `state.vscdb` SQLite database directly and imports composer conversations with token usage data.\n\n> On Linux, OpenCode respects `$XDG_DATA_HOME` if set.\n\nQoder Desktop also creates installation files under `Program Files`, UI\u002Fcache data under `AppData\u002FRoaming\u002FQoder` and `AppData\u002FLocal\u002F.qoder`, and transcripts under `%USERPROFILE%\\.qoder\\projects` or `%USERPROFILE%\\.qoder\\cache`. These are not imported as token records: desktop `Context usage update` log lines are repeated context-window snapshots, and transcripts\u002Fconversation-history files do not contain per-request token usage.\n\n### Custom Source Paths\n\nIf you installed a tool to a non-default location, override the paths in the **Settings** page of the web dashboard (`http:\u002F\u002Flocalhost:3847\u002Fsettings` → Sources section), or edit `~\u002F.aiusage\u002Fconfig.json` directly:\n\n```json\n{\n  \"sources\": {\n    \"claude-code\": \"\u002Fcustom\u002Fpath\u002F.claude\u002Fprojects\",\n    \"codex\": \"\u002Fcustom\u002Fpath\u002F.codex\u002Fsessions\",\n    \"openclaw\": \"\u002Fcustom\u002Fsessions-dir\",\n    \"opencode\": \"\u002Fcustom\u002Fpath\u002Fopencode.db\",\n    \"hermes\": \"\u002Fcustom\u002Fpath\u002F.hermes\u002Fstate.db\",\n    \"qoder\": \"\u002Fcustom\u002Fpath\u002F.qoder\u002Flogs\u002Fsessions\",\n    \"qoder-db\": \"\u002Fcustom\u002Fpath\u002Flocal.db\",\n    \"cursor\": \"\u002Fcustom\u002Fpath\u002Fstate.vscdb\"\n  }\n}\n```\n\nOnly the paths you specify are overridden; unspecified tools fall back to their defaults. `qoder` points to the session logs directory; `qoder-db` points directly to the `local.db` SQLite file.\n\n## Database Visualization\n\nThe local database is a standard SQLite file, so you can open it directly in DBeaver, TablePlus, DataGrip, DB Browser for SQLite, or any similar tool.\n\n```bash\naiusage status\n# Shows the exact DB Path, schema version, and object counts\n```\n\n- Open `~\u002F.aiusage\u002Fcache.db` as a SQLite database.\n- Prefer read-only mode in your database tool. `aiusage` writes to the same file and uses WAL mode.\n- If your tool asks about sidecar files, keep `cache.db-wal` and `cache.db-shm` alongside the main database file.\n- Start with the read-only views:\n  - `v_usage_records`: one row per usage record with normalized timestamp and token totals\n  - `v_tool_calls`: tool call rows joined with their parent usage record\n  - `v_sessions`: session-level aggregates for pivoting and charting\n- Raw internal tables remain available for advanced inspection:\n  - `records`\n  - `tool_calls`\n  - `synced_records`\n  - `sync_tombstones`\n\n## Tech Stack\n\n- **Runtime:** Node.js, TypeScript\n- **Database:** better-sqlite3 (local, WAL mode)\n- **CLI:** Commander.js\n- **Web:** SvelteKit + adapter-static\n- **Build:** tsup (core\u002Fcli), Vite (web)\n- **Sync:** GitHub API, AWS S3 \u002F Cloudflare R2\n\n## Project Structure\n\n```text\npackages\u002F\n  core\u002F     - Shared types, database schema, pricing data\n  cli\u002F      - CLI tool for parsing logs, querying data, cloud sync\n  web\u002F      - SvelteKit web dashboard (SPA)\n```\n\n## FAQ\n\n### Does aiusage upload my data?\n\nNo. aiusage is local-first. Your usage data stays on your machine unless you explicitly configure a sync backend.\n\n### Can I use aiusage across multiple machines?\n\nYes. You can sync usage data through GitHub, S3, or R2 and then view the combined result from any configured machine or Docker deployment.\n\n### Does aiusage run a background parser automatically?\n\nNo. By default, you run `aiusage parse` manually. You can automate parsing and syncing with cron, Task Scheduler, or your own scheduler.\n\n### Which assistants are supported?\n\naiusage currently supports Claude Code, Codex, OpenClaw, OpenCode, Hermes, and Qoder.\n\n### Can I inspect the raw database myself?\n\nYes. aiusage stores data in a local SQLite database, and the README already documents how to open it in tools like DBeaver, TablePlus, DataGrip, or DB Browser for SQLite.\n\n## Friends\n\n[**linux.do**](https:\u002F\u002Flinux.do\u002F) — Thanks to the linux.do community for their support and inspiration during the development of this project.\n\n## Star History\n\n\u003Ca href=\"https:\u002F\u002Fwww.star-history.com\u002F?repos=juliantanx%2Faiusage&type=date&logscale=&legend=top-left\">\n \u003Cpicture>\n   \u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"https:\u002F\u002Fapi.star-history.com\u002Fchart?repos=juliantanx\u002Faiusage&type=date&theme=dark&legend=top-left&t=20260530\" \u002F>\n   \u003Csource media=\"(prefers-color-scheme: light)\" srcset=\"https:\u002F\u002Fapi.star-history.com\u002Fchart?repos=juliantanx\u002Faiusage&type=date&legend=top-left&t=20260530\" \u002F>\n   \u003Cimg alt=\"Star History Chart\" src=\"https:\u002F\u002Fapi.star-history.com\u002Fchart?repos=juliantanx\u002Faiusage&type=date&legend=top-left&t=20260530\" \u002F>\n \u003C\u002Fpicture>\n\u003C\u002Fa>\n\n## Contributing\n\nContributions are welcome! See [CONTRIBUTING.md](.\u002FCONTRIBUTING.md) for how to get started.\n\n## License\n\n[MIT](.\u002FLICENSE)\n","`aiusage` 是一个开源的AI编码助手使用情况跟踪工具，支持Claude Code、Codex等7种AI编码工具。它能够追踪并记录这些工具在使用过程中的令牌消耗、成本和会话情况。项目采用TypeScript编写，并利用了React构建前端界面以及better-sqlite3作为本地数据库解决方案，确保数据处理高效且易于管理。该工具以本地优先的方式运行，无需注册账户即可开始使用，非常适合开发者或团队用来监控和优化AI辅助编程的成本与效率。通过简单的命令行操作即可完成安装及启动，同时提供了详细的仪表盘来展示各项指标，帮助用户更直观地理解资源使用状况。",2,"2026-06-11 04:04:36","CREATED_QUERY"]