[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-73329":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":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":17,"stars7d":18,"stars30d":19,"stars90d":16,"forks30d":16,"starsTrendScore":20,"compositeScore":21,"rankGlobal":10,"rankLanguage":10,"license":22,"archived":23,"fork":23,"defaultBranch":24,"hasWiki":25,"hasPages":23,"topics":26,"createdAt":10,"pushedAt":10,"updatedAt":47,"readmeContent":48,"aiSummary":49,"trendingCount":16,"starSnapshotCount":16,"syncStatus":50,"lastSyncTime":51,"discoverSource":52},73329,"tokscale","junhoyeo\u002Ftokscale","junhoyeo","🛰️ A CLI tool for tracking token usage from OpenCode, Claude Code, 🦞OpenClaw (Clawdbot\u002FMoltbot), Pi, Codex, Gemini, Cursor, AmpCode, Factory Droid, Kimi, and more! • 🏅Global Leaderboard + 2D\u002F3D Contributions Graph","https:\u002F\u002Ftokscale.ai",null,"Rust",3631,236,15,69,0,98,247,801,294,109.12,"MIT License",false,"main",true,[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46],"ai","ai-agents","ampcode","claude","claude-code","clawdbot","codex","cursor","cursor-ide","droid","gemini","gemini-cli","gpt","hermes","moltbot","oh","openclaw","opencode","opentui","token-usage","2026-06-12 04:01:09","\u003C!-- \u003CCENTERED SECTION FOR GITHUB DISPLAY> -->\n\n\u003Cdiv align=\"center\">\n\n[![Tokscale](.\u002F.github\u002Fassets\u002Fhero-v2.png)](https:\u002F\u002Ftokscale.ai)\n\n\u003C\u002Fdiv>\n\n> A high-performance CLI tool and visualization dashboard for tracking token usage and costs across multiple AI coding agents.\n\n> [!TIP]\n>\n> v2 is here — native Rust TUI, cross-platform support, and more. \u003Cbr \u002F>\n> I drop new open-source work every week. Don't miss the next one.\n>\n> | [\u003Cimg alt=\"GitHub Follow\" src=\"https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Ffollowers\u002Fjunhoyeo?style=flat-square&logo=github&labelColor=black&color=24292f\" width=\"156px\" \u002F>](https:\u002F\u002Fgithub.com\u002Fjunhoyeo) | Follow [@junhoyeo](https:\u002F\u002Fgithub.com\u002Fjunhoyeo) on GitHub for more projects. Hacking on AI, infra, and everything in between. |\n> | :-----| :----- |\n> [\u003Cimg alt=\"Discord link\" src=\"https:\u002F\u002Fimg.shields.io\u002Fdiscord\u002F1480206352755458110?color=5865F2&label=discord&labelColor=black&logo=discord&logoColor=white&style=flat-square\" width=\"156px\" \u002F>](https:\u002F\u002Fdiscord.gg\u002Fh6DUGWdBbm) | Come hang out in our [Discord](https:\u002F\u002Fdiscord.gg\u002Fh6DUGWdBbm) — and surround yourself with the world's top-tier vibers. |\n\n\u003Cdiv align=\"center\">\n\n[![GitHub Release](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fv\u002Frelease\u002Fjunhoyeo\u002Ftokscale?color=0073FF&labelColor=black&logo=github&style=flat-square)](https:\u002F\u002Fgithub.com\u002Fjunhoyeo\u002Ftokscale\u002Freleases)\n[![npm Version](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fv\u002Ftokscale?color=0073FF&labelColor=black&style=flat-square&logo=npm)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Ftokscale)\n[![npm Downloads](https:\u002F\u002Fimg.shields.io\u002Fnpm\u002Fdt\u002Ftokscale?color=0073FF&labelColor=black&style=flat-square)](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Ftokscale)\n[![GitHub Contributors](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fcontributors\u002Fjunhoyeo\u002Ftokscale?color=0073FF&labelColor=black&style=flat-square)](https:\u002F\u002Fgithub.com\u002Fjunhoyeo\u002Ftokscale\u002Fgraphs\u002Fcontributors)\n[![GitHub Forks](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fforks\u002Fjunhoyeo\u002Ftokscale?color=0073FF&labelColor=black&style=flat-square)](https:\u002F\u002Fgithub.com\u002Fjunhoyeo\u002Ftokscale\u002Fnetwork\u002Fmembers)\n[![GitHub Stars](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fstars\u002Fjunhoyeo\u002Ftokscale?color=0073FF&labelColor=black&style=flat-square)](https:\u002F\u002Fgithub.com\u002Fjunhoyeo\u002Ftokscale\u002Fstargazers)\n[![GitHub Issues](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fissues\u002Fjunhoyeo\u002Ftokscale?color=0073FF&labelColor=black&style=flat-square)](https:\u002F\u002Fgithub.com\u002Fjunhoyeo\u002Ftokscale\u002Fissues)\n[![License](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Flicense-MIT-white?labelColor=black&style=flat-square)](https:\u002F\u002Fgithub.com\u002Fjunhoyeo\u002Ftokscale\u002Fblob\u002Fmaster\u002FLICENSE)\n[![Coverage](https:\u002F\u002Fraw.githubusercontent.com\u002Fjunhoyeo\u002Ftokscale\u002Frefs\u002Fheads\u002Fmain\u002F.github\u002Fbadges\u002Fcoverage.svg)](https:\u002F\u002Fgithub.com\u002Fjunhoyeo\u002Ftokscale\u002Fissues\u002F403)\n\n[🇺🇸 English](README.md) | [🇰🇷 한국어](README.ko.md) | [🇯🇵 日本語](README.ja.md) | [🇨🇳 简体中文](README.zh-cn.md)\n\n\u003C\u002Fdiv>\n\n\u003C!-- \u003C\u002FCENTERED SECTION FOR GITHUB DISPLAY> -->\n\n| Overview | Models |\n|:---:|:---:|\n| ![TUI Overview](.github\u002Fassets\u002Ftui-overview.png) | ![TUI Models](.github\u002Fassets\u002Ftui-models.png) | \n\n| Daily Summary | Stats |\n|:---:|:---:|\n| ![TUI Daily Summary](.github\u002Fassets\u002Ftui-daily.png) | ![TUI Stats](.github\u002Fassets\u002Ftui-stats.png) | \n\n| Frontend (3D Contributions Graph) | Wrapped 2025 |\n|:---:|:---:|\n| \u003Ca href=\"https:\u002F\u002Ftokscale.ai\">\u003Cimg alt=\"Frontend (3D Contributions Graph)\" src=\".github\u002Fassets\u002Ffrontend-contributions-graph.png\" width=\"700px\" \u002F>\u003C\u002Fa> | \u003Ca href=\"#wrapped-2025\">\u003Cimg alt=\"Wrapped 2025\" src=\".github\u002Fassets\u002Fwrapped-2025-agents.png\" width=\"700px\" \u002F>\u003C\u002Fa> |\n\n> **Run [`bunx tokscale@latest submit`](#social) to submit your usage data to the leaderboard and create your public profile!**\n\n## Overview\n\n**Tokscale** helps you monitor and analyze your token consumption from:\n\n| Logo | Client | Data Location | Supported |\n|------|----------|---------------|-----------|\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-opencode.png\" alt=\"OpenCode\" \u002F> | [OpenCode](https:\u002F\u002Fgithub.com\u002Fsst\u002Fopencode) | `~\u002F.local\u002Fshare\u002Fopencode\u002Fopencode.db` (1.2+, all channels including `opencode-stable.db`) or\u002Fand `~\u002F.local\u002Fshare\u002Fopencode\u002Fstorage\u002Fmessage\u002F` (legacy\u002Funmigrated) | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-claude.jpg\" alt=\"Claude\" \u002F> | [Claude Code](https:\u002F\u002Fdocs.anthropic.com\u002Fen\u002Fdocs\u002Fclaude-code) | `~\u002F.claude\u002Fprojects\u002F` and `~\u002F.claude\u002Ftranscripts\u002F` | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-openclaw.jpg\" alt=\"OpenClaw\" \u002F> | [OpenClaw](https:\u002F\u002Fopenclaw.ai\u002F) | `~\u002F.openclaw\u002Fagents\u002F` (+ legacy: `.clawdbot`, `.moltbot`, `.moldbot`) | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-openai.jpg\" alt=\"Codex\" \u002F> | [Codex CLI](https:\u002F\u002Fgithub.com\u002Fopenai\u002Fcodex) | `~\u002F.codex\u002Fsessions\u002F` | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-copilot.jpg\" alt=\"Copilot\" \u002F> | [GitHub Copilot CLI](https:\u002F\u002Fdocs.github.com\u002Fen\u002Fcopilot\u002Fhow-tos\u002Fuse-copilot-agents\u002Fuse-the-github-copilot-coding-agent-in-cli) | `~\u002F.copilot\u002Fotel\u002F*.jsonl` (+ `COPILOT_OTEL_FILE_EXPORTER_PATH`) | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-hermes.png\" alt=\"Hermes Agent\" \u002F> | [Hermes Agent](https:\u002F\u002Fgithub.com\u002FNousResearch\u002Fhermes-agent) | `$HERMES_HOME\u002Fstate.db` (fallback: `~\u002F.hermes\u002Fstate.db`) | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-gemini.png\" alt=\"Gemini\" \u002F> | [Gemini CLI](https:\u002F\u002Fgithub.com\u002Fgoogle-gemini\u002Fgemini-cli) | `~\u002F.gemini\u002Ftmp\u002F*\u002Fchats\u002F*.json` | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-cursor.jpg\" alt=\"Cursor\" \u002F> | [Cursor IDE](https:\u002F\u002Fcursor.com\u002F) | API sync via `~\u002F.config\u002Ftokscale\u002Fcursor-cache\u002F` | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-amp.png\" alt=\"Amp\" \u002F> | [Amp (AmpCode)](https:\u002F\u002Fampcode.com\u002F) | `~\u002F.local\u002Fshare\u002Famp\u002Fthreads\u002F` | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-codebuff.png\" alt=\"Codebuff\" \u002F> | [Codebuff](https:\u002F\u002Fcodebuff.com\u002F) | `~\u002F.config\u002Fmanicode\u002F` (+ `manicode-dev`, `manicode-staging`; override via `CODEBUFF_DATA_DIR`) | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-droid.png\" alt=\"Droid\" \u002F> | [Droid (Factory Droid)](https:\u002F\u002Ffactory.ai\u002F) | `~\u002F.factory\u002Fsessions\u002F` | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-pi.png\" alt=\"Pi\" \u002F> | [Pi](https:\u002F\u002Fgithub.com\u002Fbadlogic\u002Fpi-mono) | `~\u002F.pi\u002Fagent\u002Fsessions\u002F` and `~\u002F.omp\u002Fagent\u002Fsessions\u002F` ([Oh My Pi](https:\u002F\u002Fgithub.com\u002Fcan1357\u002Foh-my-pi)) | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-kimi.png\" alt=\"Kimi\" \u002F> | [Kimi CLI](https:\u002F\u002Fgithub.com\u002FMoonshotAI\u002Fkimi-cli) | `~\u002F.kimi\u002Fsessions\u002F` | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-qwen.png\" alt=\"Qwen\" \u002F> | [Qwen CLI](https:\u002F\u002Fgithub.com\u002FQwenLM\u002Fqwen-cli) | `~\u002F.qwen\u002Fprojects\u002F` | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-roocode.png\" alt=\"Roo Code\" \u002F> | [Roo Code](https:\u002F\u002Fgithub.com\u002FRooCodeInc\u002FRoo-Code) | `~\u002F.config\u002FCode\u002FUser\u002FglobalStorage\u002Frooveterinaryinc.roo-cline\u002Ftasks\u002F` (+ server: `~\u002F.vscode-server\u002Fdata\u002FUser\u002FglobalStorage\u002Frooveterinaryinc.roo-cline\u002Ftasks\u002F`) | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-kilocode.png\" alt=\"Kilo\" \u002F> | [Kilo](https:\u002F\u002Fgithub.com\u002FKilo-Org\u002Fkilocode) | `~\u002F.config\u002FCode\u002FUser\u002FglobalStorage\u002Fkilocode.kilo-code\u002Ftasks\u002F` (+ server: `~\u002F.vscode-server\u002Fdata\u002FUser\u002FglobalStorage\u002Fkilocode.kilo-code\u002Ftasks\u002F`) | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-kilocode.png\" alt=\"Kilo CLI\" \u002F> | [Kilo CLI](https:\u002F\u002Fgithub.com\u002Fnicepkg\u002Fkilo) | `~\u002F.local\u002Fshare\u002Fkilo\u002Fkilo.db` | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-mux.png\" alt=\"Mux\" \u002F> | [Mux](https:\u002F\u002Fgithub.com\u002Fcoder\u002Fmux) | `~\u002F.mux\u002Fsessions\u002F` | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-crush.png\" alt=\"Crush\" \u002F> | [Crush](https:\u002F\u002Fcrush.ai\u002F) | `$XDG_DATA_HOME\u002Fcrush\u002Fprojects.json` (project registry; fallback: `~\u002F.local\u002Fshare\u002Fcrush\u002Fprojects.json`) | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-goose.png\" alt=\"Goose\" \u002F> | [Goose](https:\u002F\u002Fgithub.com\u002Faaif-goose\u002Fgoose) | `~\u002F.local\u002Fshare\u002Fgoose\u002Fsessions\u002Fsessions.db` (+ macOS Application Support, legacy Block\u002Fgoose paths; override via `GOOSE_PATH_ROOT`) | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-antigravity.png\" alt=\"Antigravity\" \u002F> | [Google Antigravity](https:\u002F\u002Fantigravity.google\u002F) | Cached via `tokscale antigravity sync` to `~\u002F.config\u002Ftokscale\u002Fantigravity-cache\u002Fsessions\u002F*.jsonl` (live RPC against the local language server) | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-zed.webp\" alt=\"Zed Agent\" \u002F> | [Zed Agent](https:\u002F\u002Fzed.dev\u002Fdocs\u002Fai\u002Fagent-panel) | `~\u002F.local\u002Fshare\u002Fzed\u002Fthreads\u002Fthreads.db` (macOS: `~\u002FLibrary\u002FApplication Support\u002FZed\u002Fthreads\u002Fthreads.db`; Windows: `%LOCALAPPDATA%\u002FZed\u002Fthreads\u002Fthreads.db`; hosted Zed models only, not external ACP agents) | ✅ Yes |\n| \u003Cimg width=\"48px\" src=\".github\u002Fassets\u002Fclient-synthetic.png\" alt=\"Synthetic\" \u002F> | [Synthetic](https:\u002F\u002Fsynthetic.new\u002F) | Re-attributed from other sources via `hf:` model prefix or `synthetic` provider (+ [Octofriend](https:\u002F\u002Fgithub.com\u002Fsynthetic-lab\u002Foctofriend): `~\u002F.local\u002Fshare\u002Foctofriend\u002Fsqlite.db`) | ✅ Yes |\n\nGet real-time pricing calculations using [🚅 LiteLLM's pricing data](https:\u002F\u002Fgithub.com\u002FBerriAI\u002Flitellm), with support for tiered pricing models and cache token discounts.\n\n### Why \"Tokscale\"?\n\n[![Tokscale](.\u002F.github\u002Fassets\u002Fhero.png)](https:\u002F\u002Ftokscale.ai)\n\nThis project is inspired by the **[Kardashev scale](https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FKardashev_scale)**, a method proposed by astrophysicist Nikolai Kardashev to measure a civilization's level of technological advancement based on its energy consumption. A Type I civilization harnesses all energy available on its planet, Type II captures the entire output of its star, and Type III commands the energy of an entire galaxy.\n\nIn the age of AI-assisted development, **tokens are the new energy**. They power our reasoning, fuel our productivity, and drive our creative output. Just as the Kardashev scale tracks energy consumption at cosmic scales, Tokscale measures your token consumption as you scale the ranks of AI-augmented development. Whether you're a casual user or burning through millions of tokens daily, Tokscale helps you visualize your journey up the scale—from planetary developer to galactic code architect.\n\n## Contents\n\n- [Overview](#overview)\n  - [Why \"Tokscale\"?](#why-tokscale)\n- [Features](#features)\n- [Installation](#installation)\n  - [Quick Start](#quick-start)\n  - [Prerequisites](#prerequisites)\n  - [Development Setup](#development-setup)\n  - [Building the Native Module](#building-the-native-module)\n- [Usage](#usage)\n  - [Basic Commands](#basic-commands)\n  - [TUI Features](#tui-features)\n  - [Filtering by Platform](#filtering-by-platform)\n  - [Date Filtering](#date-filtering)\n  - [Pricing Lookup](#pricing-lookup)\n  - [Social](#social)\n  - [Cursor IDE Commands](#cursor-ide-commands)\n  - [Antigravity Commands](#antigravity-commands)\n  - [Example Output](#example-output---light-version)\n  - [Configuration](#configuration)\n  - [Environment Variables](#environment-variables)\n- [Frontend Visualization](#frontend-visualization)\n  - [Features](#features-1)\n  - [Running the Frontend](#running-the-frontend)\n- [Social Platform](#social-platform)\n  - [Features](#features-2)\n  - [Getting Started](#getting-started)\n  - [Data Validation](#data-validation)\n- [Wrapped 2025](#wrapped-2025)\n  - [Command](#command)\n  - [What's Included](#whats-included)\n- [Development](#development)\n  - [Prerequisites](#prerequisites-1)\n  - [How to Run](#how-to-run)\n- [Supported Platforms](#supported-platforms)\n  - [Native Module Targets](#native-module-targets)\n  - [Windows Support](#windows-support)\n- [Session Data Retention](#session-data-retention)\n- [Data Sources](#data-sources)\n- [Pricing](#pricing)\n- [Contributing](#contributing)\n  - [Development Guidelines](#development-guidelines)\n- [Acknowledgments](#acknowledgments)\n- [License](#license)\n\n## Features\n\n- **Interactive TUI Mode** - Beautiful terminal UI powered by Ratatui (default mode)\n  - 6 interactive views: Overview, Models, Daily, Hourly, Stats, Agents\n  - Keyboard & mouse navigation\n  - GitHub-style contribution graph with 9 color themes\n  - Real-time filtering and sorting\n  - Zero flicker rendering\n- **Multi-platform support** - Track usage across OpenCode, Claude Code, Codex CLI, Copilot CLI, Cursor IDE, Gemini CLI, Amp, Codebuff, Droid, OpenClaw, Hermes Agent, Pi, Kimi CLI, Qwen CLI, Roo Code, Kilo, Mux, Kilo CLI, Crush, Goose, Antigravity, and Synthetic\n- **Real-time pricing** - Fetches current pricing from LiteLLM with 1-hour disk cache; automatic OpenRouter fallback and Cursor model pricing for newly released models\n- **Detailed breakdowns** - Input, output, cache read\u002Fwrite, and reasoning token tracking\n- **Native Rust core** - All parsing and aggregation done in Rust for 10x faster processing\n- **Web visualization** - Interactive contribution graph with 2D and 3D views\n- **Flexible filtering** - Filter by platform, date range, or year\n- **Export to JSON** - Generate data for external visualization tools\n- **Social Platform** - Share your usage, compete on leaderboards, and view public profiles\n\n## Installation\n\n### Quick Start\n\n```bash\n# Run directly with npx\nnpx tokscale@latest\n\n# Or use bunx\nbunx tokscale@latest\n\n# Or use Deno without installing an alias\ndeno x npm:tokscale@latest\n\n# Light mode (table rendering only)\nnpx tokscale@latest --light\n```\n\nThat's it! This gives you the full interactive TUI experience with zero setup.\n\n> **Package Structure**: `tokscale` is an alias package (like [`swc`](https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Fswc)) that installs `@tokscale\u002Fcli`. Both install the same CLI with the native Rust core (`@tokscale\u002Fcore`) included.\n\n\n### Prerequisites\n\n- [Node.js](https:\u002F\u002Fnodejs.org\u002F) or [Bun](https:\u002F\u002Fbun.sh\u002F)\n- (Optional) Rust toolchain for building native module from source\n\n### Development Setup\n\nFor local development or building from source:\n\n```bash\n# Clone the repository\ngit clone https:\u002F\u002Fgithub.com\u002Fjunhoyeo\u002Ftokscale.git\ncd tokscale\n\n# Install Bun (if not already installed)\ncurl -fsSL https:\u002F\u002Fbun.sh\u002Finstall | bash\n\n# Install dependencies\nbun install\n\n# Run the CLI in development mode\nbun run cli\n```\n\n> **Note**: `bun run cli` is for local development. When installed via `bunx tokscale`, the command runs directly. The Usage section below shows the installed binary commands.\n\n### Building the Native Module\n\nThe native Rust module is **required** for CLI operation. It provides ~10x faster processing through parallel file scanning and SIMD JSON parsing:\n\n```bash\n# Build the native core (run from repository root)\nbun run build:core\n```\n\n> **Note**: Native binaries are pre-built and included when you install via `bunx tokscale@latest`. Building from source is only needed for local development.\n\n## Usage\n\n### Basic Commands\n\n```bash\n# Launch interactive TUI (default)\ntokscale\n\n# Launch TUI with specific tab\ntokscale models    # Models tab\ntokscale monthly   # Daily view (shows daily breakdown)\ntokscale hourly    # Hourly tab\n\n# Use legacy CLI table output\ntokscale --light\ntokscale models --light\n\n# Launch TUI explicitly\ntokscale tui\n\n# Export contribution graph data as JSON\ntokscale graph --output data.json\n\n# Output data as JSON (for scripting\u002Fautomation)\ntokscale --json                    # Default models view as JSON\ntokscale models --json             # Models breakdown as JSON\ntokscale monthly --json            # Monthly breakdown as JSON\ntokscale models --json > report.json   # Save to file\n```\n\n### TUI Features\n\nThe interactive TUI mode provides:\n\n- **6 Views**: Overview (chart + top models), Models, Daily, Hourly, Stats (contribution graph), Agents\n- **Keyboard Navigation**:\n  - `1-6` or `←\u002F→\u002FTab`: Switch views\n  - `↑\u002F↓`: Navigate lists\n  - `c\u002Fd\u002Ft`: Sort by cost\u002Fdate\u002Ftokens\n  - `s`: Open source picker dialog\n  - `g`: Open group-by picker dialog (model, client+model, client+provider+model)\n  - `p`: Cycle through 9 color themes\n  - `r`: Refresh data\n  - `e`: Export to JSON\n  - `q`: Quit\n- **Mouse Support**: Click tabs, buttons, and filters\n- **Themes**: Green, Halloween, Teal, Blue, Pink, Purple, Orange, Monochrome, YlGnBu\n- **Settings Persistence**: Preferences saved to `~\u002F.config\u002Ftokscale\u002Fsettings.json` (see [Configuration](#configuration))\n\n### Group-By Strategies\n\nPress `g` in the TUI or use `--group-by` in `--light`\u002F`--json` mode to control how model rows are aggregated:\n\n| Strategy | Flag | TUI Default | Effect |\n|----------|------|-------------|--------|\n| **Model** | `--group-by model` | ✅ | One row per model — merges all clients and providers |\n| **Client + Model** | `--group-by client,model` | | One row per client-model pair |\n| **Client + Provider + Model** | `--group-by client,provider,model` | | Most granular — no merging |\n\n**`--group-by model`** (most consolidated)\n\n| Clients | Providers | Model | Cost |\n|---------|-----------|-------|------|\n| OpenCode, Claude, Amp | github-copilot, anthropic | claude-opus-4-5 | $2,424 |\n| OpenCode, Claude | anthropic, github-copilot | claude-sonnet-4-5 | $1,332 |\n\n**`--group-by client,model`** (CLI default)\n\n| Client | Provider | Model | Cost |\n|--------|----------|-------|------|\n| OpenCode | github-copilot, anthropic | claude-opus-4-5 | $1,368 |\n| Claude | anthropic | claude-opus-4-5 | $970 |\n\n**`--group-by client,provider,model`** (most granular)\n\n| Client | Provider | Model | Cost |\n|--------|----------|-------|------|\n| OpenCode | github-copilot | claude-opus-4-5 | $1,200 |\n| OpenCode | anthropic | claude-opus-4-5 | $168 |\n| Claude | anthropic | claude-opus-4-5 | $970 |\n\n### Filtering by Platform\n\nUse `--client` (short `-c`) to scope reports to one or more clients. The flag is repeatable, accepts comma-separated values, and works with every report command:\n\n```bash\n# Show only OpenCode usage\ntokscale --client opencode\n\n# Comma-separated: combine multiple clients\ntokscale --client opencode,claude\n\n# Repeated: same effect, useful with shell aliases\ntokscale -c opencode -c claude\n\n# Cursor IDE requires `tokscale cursor login` first\ntokscale --client cursor\n\n# Synthetic (synthetic.new) is detected from other agent sessions\ntokscale --client synthetic\n\n# Combine with other filters\ntokscale --client opencode,claude --week --json\n```\n\nPossible values: `opencode`, `claude`, `codex`, `copilot`, `gemini`, `cursor`, `amp`, `codebuff`, `droid`, `openclaw`, `hermes`, `pi`, `kimi`, `qwen`, `roocode`, `kilocode`, `kilo`, `mux`, `crush`, `goose`, `antigravity`, `synthetic`.\n\n> **Deprecation notice**: The legacy single-client flags (`--opencode`, `--claude`, `--codex`, etc.) still work for backward compatibility but are hidden from `--help` and will be removed in the next major release. Migrate to `--client` whenever possible. Running tokscale in an interactive terminal will print a one-line warning when a legacy flag is used.\n\n### Date Filtering\n\nDate filters work across all commands that generate reports (`tokscale`, `tokscale models`, `tokscale monthly`, `tokscale graph`):\n\n```bash\n# Quick date shortcuts\ntokscale --today              # Today only\ntokscale --week               # Last 7 days\ntokscale --month              # Current calendar month\n\n# Custom date range (inclusive, local timezone)\ntokscale --since 2024-01-01 --until 2024-12-31\n\n# Filter by year\ntokscale --year 2024\n\n# Combine with other options\ntokscale models --week --client claude --json\ntokscale monthly --month --benchmark\n```\n\n> **Note**: Date filters use your local timezone. Both `--since` and `--until` are inclusive.\n\n### Pricing Lookup\n\nLook up real-time pricing for any model:\n\n```bash\n# Look up model pricing\ntokscale pricing \"claude-3-5-sonnet-20241022\"\ntokscale pricing \"gpt-4o\"\ntokscale pricing \"grok-code\"\n\n# Force specific provider source\ntokscale pricing \"grok-code\" --provider openrouter\ntokscale pricing \"claude-3-5-sonnet\" --provider litellm\n```\n\n**Lookup Strategy:**\n\nThe pricing lookup uses a multi-step resolution strategy:\n\n1. **Exact Match** - Direct lookup in LiteLLM\u002FOpenRouter databases\n2. **Alias Resolution** - Resolves friendly names (e.g., `big-pickle` → `glm-4.7`)\n3. **Tier Suffix Stripping** - Removes quality tiers (`gpt-5.2-xhigh` → `gpt-5.2`)\n4. **Version Normalization** - Handles version formats (`claude-3-5-sonnet` ↔ `claude-3.5-sonnet`)\n5. **Provider Prefix Matching** - Tries common prefixes (`anthropic\u002F`, `openai\u002F`, etc.)\n6. **Cursor Model Pricing** - Hardcoded pricing for models not yet in LiteLLM\u002FOpenRouter (e.g., `gpt-5.3-codex`)\n7. **Fuzzy Matching** - Word-boundary matching for partial model names\n\n**Provider Preference:**\n\nWhen multiple matches exist, original model creators are preferred over resellers:\n\n| Preferred (Original) | Deprioritized (Reseller) |\n|---------------------|-------------------------|\n| `xai\u002F` (Grok) | `azure_ai\u002F` |\n| `anthropic\u002F` (Claude) | `bedrock\u002F` |\n| `openai\u002F` (GPT) | `vertex_ai\u002F` |\n| `google\u002F` (Gemini) | `together_ai\u002F` |\n| `meta-llama\u002F` | `fireworks_ai\u002F` |\n\nExample: `grok-code` matches `xai\u002Fgrok-code-fast-1` ($0.20\u002F$1.50) instead of `azure_ai\u002Fgrok-code-fast-1` ($3.50\u002F$17.50).\n\n### Social\n\n```bash\n# Login to Tokscale (opens browser for GitHub auth)\ntokscale login\n\n# Save an existing Tokscale API token without browser auth\ntokscale login --token tt_xxx\n\n# Check who you're logged in as\ntokscale whoami\n\n# Submit your usage data to the leaderboard\ntokscale submit\n\n# Submit in CI\u002Fheadless environments without writing credentials\n# Precedence: TOKSCALE_API_TOKEN env > saved credentials file (~\u002F.config\u002Ftokscale\u002Fcredentials.json).\n# When the env var is set, the saved file is ignored for that invocation.\nTOKSCALE_API_TOKEN=tt_xxx tokscale submit\n\n# Revoke a token: visit Settings > API Tokens on the leaderboard site\n# (https:\u002F\u002Ftokscale.com\u002Fsettings) and click \"Revoke\" on the token row.\n# Revocation takes effect immediately — subsequent requests with that\n# token will get HTTP 401 \"Invalid API token\".\n\n# Submit with filters\ntokscale submit --client opencode,claude --since 2024-01-01\n\n# Preview what would be submitted (dry run)\ntokscale submit --dry-run\n\n# Logout\ntokscale logout\n```\n\n\u003Cimg alt=\"CLI Submit\" src=\".\u002F.github\u002Fassets\u002Fcli-submit.png\" \u002F>\n\n### Cursor IDE Commands\n\nCursor IDE requires separate authentication via session token (different from the social platform login):\n\n```bash\n# Login to Cursor (requires session token from browser)\n# --name is optional; it just helps you identify accounts later\ntokscale cursor login --name work\n\n# Check Cursor authentication status and session validity\ntokscale cursor status\n\n# List saved Cursor accounts\ntokscale cursor accounts\n\n# Manually refresh cached Cursor usage\ntokscale cursor sync\n\n# Switch active account (controls which account syncs to cursor-cache\u002Fusage.csv)\ntokscale cursor switch work\n\n# Logout from a specific account (keeps history; excludes it from aggregation)\ntokscale cursor logout --name work\n\n# Logout and delete cached usage for that account\ntokscale cursor logout --name work --purge-cache\n\n# Logout from all Cursor accounts (keeps history; excludes from aggregation)\ntokscale cursor logout --all\n\n# Logout from all accounts and delete cached usage\ntokscale cursor logout --all --purge-cache\n```\n\nBy default, tokscale **aggregates usage across all saved Cursor accounts** (all `cursor-cache\u002Fusage*.csv`).\n\nWhen you log out, tokscale keeps your cached usage history by moving it to `cursor-cache\u002Farchive\u002F` (so it won't be aggregated). Use `--purge-cache` if you want to delete the cached usage instead.\n\n**Credentials storage**: Cursor accounts are stored in `~\u002F.config\u002Ftokscale\u002Fcursor-credentials.json`. Usage data is cached at `~\u002F.config\u002Ftokscale\u002Fcursor-cache\u002F` (active account uses `usage.csv`, additional accounts use `usage.\u003Caccount>.csv`).\n\n**To get your Cursor session token:**\n1. Open https:\u002F\u002Fwww.cursor.com\u002Fsettings in your browser\n2. Open Developer Tools (F12)\n3. **Option A - Network tab**: Make any action on the page, find a request to `cursor.com\u002Fapi\u002F*`, look in the Request Headers for the `Cookie` header, and copy only the value after `WorkosCursorSessionToken=`\n4. **Option B - Application tab**: Go to Application → Cookies → `https:\u002F\u002Fwww.cursor.com`, find the `WorkosCursorSessionToken` cookie, and copy its value (not the cookie name)\n\n> ⚠️ **Security Warning**: Treat your session token like a password. Never share it publicly or commit it to version control. The token grants full access to your Cursor account.\n\n### Antigravity Commands\n\nAntigravity sync currently works on macOS and Linux only. The Antigravity-enabled editor must be running and its local language server available; tokscale reads usage from that local language server and caches normalized artifacts locally.\n\n```bash\n# Check whether tokscale can see running Antigravity language servers\ntokscale antigravity status\n\n# Sync usage from local Antigravity language servers into tokscale's cache\ntokscale antigravity sync\n\n# Delete the cached Antigravity artifacts\ntokscale antigravity purge-cache\n```\n\n**Cache location**: `~\u002F.config\u002Ftokscale\u002Fantigravity-cache\u002F`\n\n**How it works**: `tokscale antigravity sync` discovers local Antigravity session candidates, fetches confirmed usage data from the local language server RPC, and stores normalized JSONL artifacts for tokscale-core to parse later. Run sync before reports if you want the freshest Antigravity data.\n\n### Example Output (`--light` version)\n\n\u003Cimg alt=\"CLI Light\" src=\".\u002F.github\u002Fassets\u002Fcli-light.png\" \u002F>\n\n### Configuration\n\nTokscale stores settings in `~\u002F.config\u002Ftokscale\u002Fsettings.json`:\n\n```json\n{\n  \"colorPalette\": \"blue\",\n  \"includeUnusedModels\": false,\n  \"defaultClients\": [\"opencode\", \"claude\"],\n  \"scanner\": {\n    \"extraScanPaths\": {\n      \"codex\": [\n        \"\u002FUsers\u002Fme\u002Fworkspace\u002Fproject-a\u002F.codex\u002Fsessions\",\n        \"\u002FUsers\u002Fme\u002Fworkspace\u002Fproject-b\u002F.codex\u002Farchived_sessions\"\n      ]\n    }\n  }\n}\n```\n\n| Setting | Type | Default | Description |\n|---------|------|---------|-------------|\n| `colorPalette` | string | `\"blue\"` | TUI color theme (green, halloween, teal, blue, pink, purple, orange, monochrome, ylgnbu) |\n| `includeUnusedModels` | boolean | `false` | Show models with zero tokens in reports |\n| `autoRefreshEnabled` | boolean | `false` | Enable auto-refresh in TUI |\n| `autoRefreshMs` | number | `60000` | Auto-refresh interval (30000-3600000ms) |\n| `nativeTimeoutMs` | number | `300000` | Maximum time for native subprocess processing (5000-3600000ms) |\n| `defaultClients` | string[] | `[]` | Client filter applied when no `--client\u002F-c` flag is passed. Accepts the same ids as `--client` (e.g. `[\"opencode\", \"claude\", \"synthetic\"]`). Unknown ids are silently dropped. CLI flags always override this list completely — no merging. |\n| `light.writeCache` | boolean | `false` | When true, `tokscale --light` overwrites the TUI cache atomically after rendering. CLI flags `--write-cache` \u002F `--no-write-cache` override per-invocation. |\n| `scanner.extraScanPaths` | object | `{}` | Additional per-client scan roots for sessions outside Tokscale's default home-root locations |\n\nUse `scanner.extraScanPaths` for persistent extra roots such as project-level `.codex` directories or imported Gemini\u002FOpenClaw histories. Tokscale merges these paths with the default scan roots on every run and deduplicates overlapping roots by canonical path.\n\nUse `defaultClients` to pin a personal default — for example, set it to `[\"opencode\", \"claude\"]` if those are the only clients you use, and `tokscale` (with no flags) will scope every report to them automatically. Pass `--client` on the command line to override for a single run.\n\n#### Cache directory layout\n\nThe regenerable CLI\u002FTUI\u002Fpricing\u002FWrapped caches now live under `~\u002F.config\u002Ftokscale\u002Fcache\u002F` (or `${TOKSCALE_CONFIG_DIR}\u002Fcache\u002F` when overridden). Antigravity sync artifacts remain at `~\u002F.config\u002Ftokscale\u002Fantigravity-cache\u002F`: \n\n- `tui-data-cache.json` — TUI startup cache\n- `source-message-cache.bin` + `source-message-cache.lock` — source-message cache + lock file\n- `pricing-litellm.json` \u002F `pricing-openrouter.json` — pricing caches\n- `opencode-migration.json` — OpenCode migration record\n- `fonts\u002F` and `images\u002F` — Wrapped asset caches\n\nIt is safe to delete this directory. Tokscale will recreate and repopulate it on demand.\n\n### Environment Variables\n\nEnvironment variables override config file values. For CI\u002FCD or one-off use:\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `TOKSCALE_NATIVE_TIMEOUT_MS` | `300000` (5 min) | Overrides `nativeTimeoutMs` config |\n| `TOKSCALE_API_TOKEN` | unset | Tokscale personal API token for non-interactive `submit` and `delete-submitted-data` runs. Create one from Settings > API Tokens or save it locally with `tokscale login --token tt_xxx`. |\n| `TOKSCALE_EXTRA_DIRS` | unset | One-off extra session roots as `client:\u002Fabs\u002Fpath,client:\u002Fabs\u002Fpath` |\n| `TOKSCALE_CONFIG_DIR` | unset | Overrides the config directory root (where `settings.json`, `star-cache.json`, `cache\u002F`, and `antigravity-cache\u002F` live). Absolute path recommended; relative paths resolve against the process CWD. Useful for CI sandboxes or pinning a non-default location. When set, tokscale will not fall back to the legacy macOS `~\u002FLibrary\u002FApplication Support\u002Ftokscale\u002F` path. |\n\n```bash\n# Example: Increase timeout for very large datasets\nTOKSCALE_NATIVE_TIMEOUT_MS=600000 tokscale graph --output data.json\n\n# Example: one-off extra scan roots\nTOKSCALE_EXTRA_DIRS='codex:\u002FUsers\u002Fme\u002Fworkspace\u002Fproject-a\u002F.codex\u002Fsessions,gemini:\u002FUsers\u002Fme\u002Fimports\u002Fimac\u002Fgemini\u002Ftmp' tokscale\n\n# Example: submit from CI without an interactive browser login\nTOKSCALE_API_TOKEN=tt_xxx tokscale submit\n```\n\n> **Note**: For persistent extra roots, prefer `scanner.extraScanPaths` in `~\u002F.config\u002Ftokscale\u002Fsettings.json`. `TOKSCALE_EXTRA_DIRS` is best for one-off overrides or CI\u002FCD.\n\n### Headless Mode\n\nTokscale can aggregate token usage from **Codex CLI headless outputs** for automation, CI\u002FCD pipelines, and batch processing.\n\n**What is headless mode?**\n\nWhen you run Codex CLI with JSON output flags (e.g., `codex exec --json`), it outputs usage data to stdout instead of storing it in its regular session directories. Headless mode allows you to capture and track this usage.\n\n**Storage location:** `~\u002F.config\u002Ftokscale\u002Fheadless\u002F`\n\nOn macOS, Tokscale also scans `~\u002FLibrary\u002FApplication Support\u002Ftokscale\u002Fheadless\u002F` when `TOKSCALE_HEADLESS_DIR` is not set.\n\nTokscale automatically scans this directory structure:\n```\n~\u002F.config\u002Ftokscale\u002Fheadless\u002F\n└── codex\u002F       # Codex CLI JSONL outputs\n```\n\n**Environment variable:** Set `TOKSCALE_HEADLESS_DIR` to customize the headless log directory:\n```bash\nexport TOKSCALE_HEADLESS_DIR=\"$HOME\u002Fmy-custom-logs\"\n```\n\n**Recommended (automatic capture):**\n\n| Tool | Command Example |\n|------|-----------------|\n| **Codex CLI** | `tokscale headless codex exec -m gpt-5 \"implement feature\"` |\n\n**Manual redirect (optional):**\n\n| Tool | Command Example |\n|------|-----------------|\n| **Codex CLI** | `codex exec --json \"implement feature\" > ~\u002F.config\u002Ftokscale\u002Fheadless\u002Fcodex\u002Fci-run.jsonl` |\n\n**Diagnostics:**\n\n```bash\n# Show scan locations and headless counts\ntokscale sources\ntokscale sources --json\n```\n\n**CI\u002FCD integration example:**\n\n```bash\n# In your GitHub Actions workflow\n- name: Run AI automation\n  run: |\n    mkdir -p ~\u002F.config\u002Ftokscale\u002Fheadless\u002Fcodex\n    codex exec --json \"review code changes\" \\\n      > ~\u002F.config\u002Ftokscale\u002Fheadless\u002Fcodex\u002Fpr-${{ github.event.pull_request.number }}.jsonl\n\n# Later, track usage\n- name: Report token usage\n  run: tokscale --json\n```\n\n> **Note**: Headless capture is supported for Codex CLI only. If you run Codex directly, redirect stdout to the headless directory as shown above.\n\n## Frontend Visualization\n\nThe frontend provides a GitHub-style contribution graph visualization:\n\n### Features\n\n- **2D View**: Classic GitHub contribution calendar\n- **3D View**: Isometric 3D contribution graph with height based on token usage\n- **Multiple color palettes**: GitHub, GitLab, Halloween, Winter, and more\n- **3-way theme toggle**: Light \u002F Dark \u002F System (follows OS preference)\n- **GitHub Primer design**: Uses GitHub's official color system\n- **Interactive tooltips**: Hover for detailed daily breakdowns\n- **Day breakdown panel**: Click to see per-source and per-model details\n- **Year filtering**: Navigate between years\n- **Source filtering**: Filter by platform (OpenCode, Claude, Codex, Copilot, Cursor, Gemini, Amp, Codebuff, Droid, OpenClaw, Hermes Agent, Pi, Kimi, Qwen, Roo Code, Kilo, Mux, Kilo CLI, Crush, Goose, Antigravity, Synthetic)\n- **Stats panel**: Total cost, tokens, active days, streaks\n- **FOUC prevention**: Theme applied before React hydrates (no flash)\n\n### Running the Frontend\n\n```bash\ncd packages\u002Ffrontend\nbun install\nbun run dev\n```\n\nOpen [http:\u002F\u002Flocalhost:3000](http:\u002F\u002Flocalhost:3000) to access the social platform.\n\n## Social Platform\n\nTokscale includes a social platform where you can share your usage data and compete with other developers.\n\n### Features\n\n- **Leaderboard** - See who's using the most tokens across all platforms\n- **User Profiles** - Public profiles with contribution graphs and statistics\n- **Period Filtering** - View stats for all time, this month, or this week\n- **GitHub Integration** - Login with your GitHub account\n- **Local Viewer** - View your data privately without submitting\n\n### GitHub Profile Embed Widget\n\nYou can embed your public Tokscale stats directly in your GitHub profile README:\n\n```md\n[![Tokscale Stats](https:\u002F\u002Ftokscale.ai\u002Fapi\u002Fembed\u002F\u003Cusername>\u002Fsvg)](https:\u002F\u002Ftokscale.ai\u002Fu\u002F\u003Cusername>)\n```\n\n- Replace `\u003Cusername>` with your GitHub username\n- Optional query params:\n  - `theme=light` for a light theme\n  - `sort=tokens` (default) or `sort=cost` to control ranking basis\n  - `compact=1` to use compact layout + compact number notation (e.g., `1.2M`, `$3.4K`)\n- Example:\n  - `https:\u002F\u002Ftokscale.ai\u002Fapi\u002Fembed\u002F\u003Cusername>\u002Fsvg?theme=light&sort=cost&compact=1`\n\n### GitHub Profile Badge\n\nYou can also use a shields.io-style badge for a more compact display:\n\n```md\n![Tokscale Tokens](https:\u002F\u002Ftokscale.ai\u002Fapi\u002Fbadge\u002F\u003Cusername>\u002Fsvg)\n```\n\n- Replace `\u003Cusername>` with your GitHub username\n- Optional query params:\n  - `metric=tokens` (default), `metric=cost`, or `metric=rank`\n  - `style=flat` (default) or `style=flat-square`\n  - `sort=tokens` (default) or `sort=cost` to control ranking basis\n  - `compact=1` to use compact number notation (e.g., `1.2M`, `$3.4K`)\n  - `label=\u003Ctext>` to override the left-side label\n  - `color=\u003Chex>` to override the right-side color (e.g., `color=ff5733`)\n- Examples:\n  - `https:\u002F\u002Ftokscale.ai\u002Fapi\u002Fbadge\u002F\u003Cusername>\u002Fsvg?metric=cost&compact=1`\n  - `https:\u002F\u002Ftokscale.ai\u002Fapi\u002Fbadge\u002F\u003Cusername>\u002Fsvg?metric=rank&sort=cost&style=flat-square`\n\n### Getting Started\n\n1. **Login** - Run `tokscale login` to authenticate via GitHub, or create an API token in Settings for CI\u002Fheadless use\n2. **Submit** - Run `tokscale submit` to upload your usage data\n3. **View** - Visit the web platform to see your profile and the leaderboard\n\n### Data Validation\n\nSubmitted data goes through Level 1 validation:\n- Mathematical consistency (totals match, no negatives)\n- No future dates\n- Required fields present\n- Duplicate detection\n\n## Wrapped 2025\n\n![Wrapped 2025](.github\u002Fassets\u002Fhero-wrapped-2025.png)\n\nGenerate a beautiful year-in-review image summarizing your AI coding assistant usage—inspired by Spotify Wrapped.\n\n| `bunx tokscale@latest wrapped` | `bunx tokscale@latest wrapped --clients` | `bunx tokscale@latest wrapped --agents --disable-pinned` |\n|:---:|:---:|:---:|\n| ![Wrapped 2025 (Agents + Pin Sisyphus)](.github\u002Fassets\u002Fwrapped-2025-agents.png) | ![Wrapped 2025 (Clients)](.github\u002Fassets\u002Fwrapped-2025-clients.png) | ![Wrapped 2025 (Agents + Disable Pinned)](.github\u002Fassets\u002Fwrapped-2025-agents-disable-pinned.png) |\n\n### Command\n\n```bash\n# Generate wrapped image for current year\ntokscale wrapped\n\n# Generate for a specific year\ntokscale wrapped --year 2025\n```\n\n### What's Included\n\nThe generated image includes:\n\n- **Total Tokens** - Your total token consumption for the year\n- **Top Models** - Your 3 most-used AI models ranked by cost\n- **Top Clients** - Your 3 most-used platforms (OpenCode, Claude Code, Cursor, etc.)\n- **Messages** - Total number of AI interactions\n- **Active Days** - Days with at least one AI interaction\n- **Cost** - Estimated total cost based on LiteLLM pricing\n- **Streak** - Your longest consecutive streak of active days\n- **Contribution Graph** - A visual heatmap of your yearly activity\n\nThe generated PNG is optimized for sharing on social media. Share your coding journey with the community!\n\n## Development\n\n> **Quick setup**: If you just want to get started quickly, see [Development Setup](#development-setup) in the Installation section above.\n\n### Prerequisites\n\n```bash\n# Bun (required)\nbun --version\n\n# Rust (for native module)\nrustc --version\ncargo --version\n```\n\n### How to Run\n\nAfter following the [Development Setup](#development-setup), you can:\n\n```bash\n# Build native module (optional but recommended)\nbun run build:core\n\n# Run in development mode (launches TUI)\ncd packages\u002Fcli && bun src\u002Findex.ts\n\n# Or use legacy CLI mode\ncd packages\u002Fcli && bun src\u002Findex.ts --light\n```\n\n\u003Cdetails>\n\u003Csummary>Advanced Development\u003C\u002Fsummary>\n\n### Project Scripts\n\n| Script | Description |\n|--------|-------------|\n| `bun run cli` | Run CLI in development mode (TUI with Bun) |\n| `bun run build:core` | Build native Rust module (release) |\n| `bun run build:cli` | Build CLI TypeScript to dist\u002F |\n| `bun run build` | Build both core and CLI |\n| `bun run dev:frontend` | Run frontend development server |\n\n**Package-specific scripts** (from within package directories):\n- `packages\u002Fcli`: `bun run dev`, `bun run tui`\n- `packages\u002Fcore`: `bun run build:debug`, `bun run test`, `bun run bench`\n\n**Note**: This project uses **Bun** as the package manager for development.\n\n### Testing\n\n```bash\n# Test native module (Rust)\ncd packages\u002Fcore\nbun run test:rust      # Cargo tests\nbun run test           # Node.js integration tests\nbun run test:all       # Both\n```\n\n### Native Module Development\n\n```bash\ncd packages\u002Fcore\n\n# Build in debug mode (faster compilation)\nbun run build:debug\n\n# Build in release mode (optimized)\nbun run build\n\n# Run Rust benchmarks\nbun run bench\n```\n\n### Graph Command Options\n\n```bash\n# Export graph data to file\ntokscale graph --output usage-data.json\n\n# Date filtering (all shortcuts work)\ntokscale graph --today\ntokscale graph --week\ntokscale graph --since 2024-01-01 --until 2024-12-31\ntokscale graph --year 2024\n\n# Filter by platform\ntokscale graph --client opencode,claude\n\n# Show processing time benchmark\ntokscale graph --output data.json --benchmark\n```\n\n### Benchmark Flag\n\nShow processing time for performance analysis:\n\n```bash\ntokscale --benchmark           # Show processing time with default view\ntokscale models --benchmark    # Benchmark models report\ntokscale monthly --benchmark   # Benchmark monthly report\ntokscale graph --benchmark     # Benchmark graph generation\n```\n\n### Generating Data for Frontend\n\n```bash\n# Export data for visualization\ntokscale graph --output packages\u002Ffrontend\u002Fpublic\u002Fmy-data.json\n```\n\n### Performance\n\nThe native Rust module provides significant performance improvements:\n\n| Operation | TypeScript | Rust Native | Speedup |\n|-----------|------------|-------------|---------|\n| File Discovery | ~500ms | ~50ms | **10x** |\n| JSON Parsing | ~800ms | ~100ms | **8x** |\n| Aggregation | ~200ms | ~25ms | **8x** |\n| **Total** | **~1.5s** | **~175ms** | **~8.5x** |\n\n*Benchmarks for ~1000 session files, 100k messages*\n\n#### Memory Optimization\n\nThe native module also provides ~45% memory reduction through:\n\n- Streaming JSON parsing (no full file buffering)\n- Zero-copy string handling\n- Efficient parallel aggregation with map-reduce\n\n#### Running Benchmarks\n\n```bash\n# Generate synthetic data\ncd packages\u002Fbenchmarks && bun run generate\n\n# Run Rust benchmarks\ncd packages\u002Fcore && bun run bench\n```\n\n\u003C\u002Fdetails>\n\n## Supported Platforms\n\n### Native Module Targets\n\n| Platform | Architecture | Status |\n|----------|--------------|--------|\n| macOS | x86_64 | ✅ Supported |\n| macOS | aarch64 (Apple Silicon) | ✅ Supported |\n| Linux | x86_64 (glibc) | ✅ Supported |\n| Linux | aarch64 (glibc) | ✅ Supported |\n| Linux | x86_64 (musl) | ✅ Supported |\n| Linux | aarch64 (musl) | ✅ Supported |\n| Windows | x86_64 | ✅ Supported |\n| Windows | aarch64 | ✅ Supported |\n\n### Windows Support\n\nTokscale fully supports Windows. The TUI and CLI work the same as on macOS\u002FLinux.\n\n**Installation on Windows:**\n```powershell\n# Install Bun (PowerShell)\npowershell -c \"irm bun.sh\u002Finstall.ps1 | iex\"\n\n# Run tokscale\nbunx tokscale@latest\n```\n\n#### Data Locations on Windows\n\nAI coding tools store their session data in cross-platform locations. Most tools use the same relative paths on all platforms:\n\n| Tool | Unix Path | Windows Path | Source |\n|------|-----------|--------------|--------|\n| OpenCode | `~\u002F.local\u002Fshare\u002Fopencode\u002F` | `%USERPROFILE%\\.local\\share\\opencode\\` | Uses [`xdg-basedir`](https:\u002F\u002Fgithub.com\u002Fsindresorhus\u002Fxdg-basedir) for cross-platform consistency ([source](https:\u002F\u002Fgithub.com\u002Fsst\u002Fopencode\u002Fblob\u002Fmain\u002Fpackages\u002Fopencode\u002Fsrc\u002Fglobal\u002Findex.ts)) |\n| Claude Code | `~\u002F.claude\u002F` | `%USERPROFILE%\\.claude\\` | Same path on all platforms |\n| OpenClaw | `~\u002F.openclaw\u002F` (+ legacy: `.clawdbot`, `.moltbot`, `.moldbot`) | `%USERPROFILE%\\.openclaw\\` (+ legacy paths) | Same path on all platforms |\n| Codex CLI | `~\u002F.codex\u002F` | `%USERPROFILE%\\.codex\\` | Configurable via `CODEX_HOME` env var ([source](https:\u002F\u002Fgithub.com\u002Fopenai\u002Fcodex)) |\n| Copilot CLI | `~\u002F.copilot\u002Fotel\u002F` | `%USERPROFILE%\\.copilot\\otel\\` | Requires OTEL file export; also auto-ingests `COPILOT_OTEL_FILE_EXPORTER_PATH` |\n| Hermes Agent | `~\u002F.hermes\u002F` | `%USERPROFILE%\\.hermes\\` | Configurable via `HERMES_HOME` env var ([source](https:\u002F\u002Fgithub.com\u002FNousResearch\u002Fhermes-agent\u002Fblob\u002Fmain\u002Fwebsite\u002Fdocs\u002Fdeveloper-guide\u002Fsession-storage.md)) |\n| Gemini CLI | `~\u002F.gemini\u002F` | `%USERPROFILE%\\.gemini\\` | Same path on all platforms |\n| Amp | `~\u002F.local\u002Fshare\u002Famp\u002F` | `%USERPROFILE%\\.local\\share\\amp\\` | Uses `xdg-basedir` like OpenCode |\n| Cursor | API sync | API sync | Data fetched via API, cached in `%USERPROFILE%\\.config\\tokscale\\cursor-cache\\` |\n| Droid | `~\u002F.factory\u002F` | `%USERPROFILE%\\.factory\\` | Same path on all platforms |\n| Pi | `~\u002F.pi\u002F` and `~\u002F.omp\u002F` | `%USERPROFILE%\\.pi\\` and `%USERPROFILE%\\.omp\\` | Same path on all platforms (supports both Pi and [Oh My Pi](https:\u002F\u002Fgithub.com\u002Fcan1357\u002Foh-my-pi)) |\n| Kimi CLI | `~\u002F.kimi\u002F` | `%USERPROFILE%\\.kimi\\` | Same path on all platforms |\n| Qwen CLI | `~\u002F.qwen\u002F` | `%USERPROFILE%\\.qwen\\` | Same path on all platforms |\n| Roo Code | `~\u002F.config\u002FCode\u002FUser\u002FglobalStorage\u002Frooveterinaryinc.roo-cline\u002Ftasks\u002F` | `%USERPROFILE%\\.config\\Code\\User\\globalStorage\\rooveterinaryinc.roo-cline\\tasks\\` | VS Code globalStorage task logs |\n| Kilo | `~\u002F.config\u002FCode\u002FUser\u002FglobalStorage\u002Fkilocode.kilo-code\u002Ftasks\u002F` | `%USERPROFILE%\\.config\\Code\\User\\globalStorage\\kilocode.kilo-code\\tasks\\` | VS Code globalStorage task logs |\n| Mux | `~\u002F.mux\u002Fsessions\u002F` | `%USERPROFILE%\\.mux\\sessions\\` | Same path on all platforms |\n| Codebuff | `~\u002F.config\u002Fmanicode\u002Fprojects\u002F` (+ `manicode-dev`, `manicode-staging`) | `%USERPROFILE%\\.config\\manicode\\projects\\` | Override via `CODEBUFF_DATA_DIR` env var |\n| Kilo CLI | `~\u002F.local\u002Fshare\u002Fkilo\u002F` | `%USERPROFILE%\\.local\\share\\kilo\\` | Uses `xdg-basedir` like OpenCode |\n| Crush | `$XDG_DATA_HOME\u002Fcrush\u002F` (fallback: `~\u002F.local\u002Fshare\u002Fcrush\u002F`) | `%USERPROFILE%\\.local\\share\\crush\\` (or `%XDG_DATA_HOME%\\crush\\` if set) | Uses XDG data directory with fallback |\n| Goose | `~\u002F.local\u002Fshare\u002Fgoose\u002Fsessions\u002F` (+ macOS Application Support, legacy Block paths) | `%USERPROFILE%\\.local\\share\\goose\\sessions\\` | Configurable via `GOOSE_PATH_ROOT` env var |\n| Antigravity | `~\u002F.config\u002Ftokscale\u002Fantigravity-cache\u002Fsessions\u002F` | — | `tokscale antigravity sync` is currently supported on macOS\u002FLinux only |\n| Synthetic | Re-attributed from other sources | Re-attributed from other sources | Detects `hf:` model prefix + `synthetic` provider |\n\n> **Note**: On Windows, `~` expands to `%USERPROFILE%` (e.g., `C:\\Users\\YourName`). These tools intentionally use Unix-style paths (like `.local\u002Fshare`) even on Windows for cross-platform consistency, rather than Windows-native paths like `%APPDATA%`.\n\n#### Windows-Specific Configuration\n\nTokscale stores its configuration in:\n- **TUI settings**: `%APPDATA%\\tokscale\\settings.json` (platform default; override with `TOKSCALE_CONFIG_DIR`)\n- **Cache**: `%APPDATA%\\tokscale\\cache\\` (consolidated cache root)\n- **Legacy cache paths**: `%USERPROFILE%\\.cache\\tokscale\\` and `%LOCALAPPDATA%\\tokscale\\cache\\` equivalents from older releases may still exist until regenerated data is written to the new path\n- **Cursor credentials**: `%USERPROFILE%\\.config\\tokscale\\cursor-credentials.json`\n- **Tokscale account credentials**: `%USERPROFILE%\\.config\\tokscale\\credentials.json`\n\n## Session Data Retention\n\nBy default, some AI coding assistants automatically delete old session files. To preserve your usage history for accurate tracking, disable or extend the cleanup period.\n\n| Platform | Default | Config File | Setting to Disable | Source |\n|----------|---------|-------------|-------------------|--------|\n| Claude Code | **⚠️ 30 days** | `~\u002F.claude\u002Fsettings.json` | `\"cleanupPeriodDays\": 9999999999` | [Docs](https:\u002F\u002Fdocs.anthropic.com\u002Fen\u002Fdocs\u002Fclaude-code\u002Fsettings) |\n| Gemini CLI | Disabled | `~\u002F.gemini\u002Fsettings.json` | `\"general.sessionRetention.enabled\": false` | [Docs](https:\u002F\u002Fgithub.com\u002Fgoogle-gemini\u002Fgemini-cli\u002Fblob\u002Fmain\u002Fdocs\u002Fcli\u002Fsession-management.md) |\n| Codex CLI | Disabled | N\u002FA | No cleanup feature | [#6015](https:\u002F\u002Fgithub.com\u002Fopenai\u002Fcodex\u002Fissues\u002F6015) |\n| OpenCode | Disabled | N\u002FA | No cleanup feature | [#4980](https:\u002F\u002Fgithub.com\u002Fsst\u002Fopencode\u002Fissues\u002F4980) |\n\n### Claude Code\n\n**Default**: 30 days cleanup period\n\nAdd to `~\u002F.claude\u002Fsettings.json`:\n```json\n{\n  \"cleanupPeriodDays\": 9999999999\n}\n```\n\n> Setting an extremely large value (e.g., `9999999999` days ≈ 27 million years) effectively disables cleanup.\n\n### Gemini CLI\n\n**Default**: Cleanup disabled (sessions persist forever)\n\nIf you've enabled cleanup and want to disable it, remove or set `enabled: false` in `~\u002F.gemini\u002Fsettings.json`:\n```json\n{\n  \"general\": {\n    \"sessionRetention\": {\n      \"enabled\": false\n    }\n  }\n}\n```\n\nOr set an extremely long retention period:\n```json\n{\n  \"general\": {\n    \"sessionRetention\": {\n      \"enabled\": true,\n      \"maxAge\": \"9999999d\"\n    }\n  }\n}\n```\n\n### Codex CLI\n\n**Default**: No automatic cleanup (sessions persist forever)\n\nCodex CLI does not have built-in session cleanup. Sessions in `~\u002F.codex\u002Fsessions\u002F` persist indefinitely.\n\n> **Note**: There's an open feature request for this: [#6015](https:\u002F\u002Fgithub.com\u002Fopenai\u002Fcodex\u002Fissues\u002F6015)\n\n### OpenCode\n\n**Default**: No automatic cleanup (sessions persist forever)\n\nOpenCode does not have built-in session cleanup. Sessions in `~\u002F.local\u002Fshare\u002Fopencode\u002Fstorage\u002F` persist indefinitely.\n\n> **Note**: See [#4980](https:\u002F\u002Fgithub.com\u002Fsst\u002Fopencode\u002Fissues\u002F4980)\n\n---\n\n## Data Sources\n\n### OpenCode\n\nLocation: `~\u002F.local\u002Fshare\u002Fopencode\u002Fopencode.db` (v1.2+) or `storage\u002Fmessage\u002F{sessionId}\u002F*.json` (legacy)\n\nOpenCode 1.2+ stores sessions in SQLite. Tokscale reads from SQLite first and falls back to legacy JSON files for older versions.\n\nOpenCode picks the db filename from the release channel the binary was built against: the `latest` and `beta` channels use `opencode.db`, while other channels use `opencode-\u003Cchannel>.db` (e.g. `opencode-stable.db`, `opencode-nightly.db`). Tokscale scans all of them, so users running multiple channels side by side get a unified view.\n\nIf you launched opencode with `OPENCODE_DB` pointing at a file outside `~\u002F.local\u002Fshare\u002Fopencode`, add the absolute path to `~\u002F.config\u002Ftokscale\u002Fsettings.json` so tokscale can find it on every run:\n\n```json\n{\n  \"scanner\": {\n    \"opencodeDbPaths\": [\n      \"\u002Fcustom\u002Flocation\u002Fopencode.db\",\n      \"\u002Fanother\u002Flocation\u002Fopencode-stable.db\"\n    ]\n  }\n}\n```\n\nPaths are merged with auto-discovery, deduped by canonical path, and non-existent entries are silently skipped (so stale config never breaks a scan). `opencode.db-wal`, `opencode.db-shm`, and other SQLite sidecars are rejected.\n\nIf you keep sessions outside Tokscale's default home-root locations, you can also persist extra scan roots per client:\n\n```json\n{\n  \"scanner\": {\n    \"extraScanPaths\": {\n      \"codex\": [\n        \"\u002FUsers\u002Fme\u002Fworkspace\u002Fproject-a\u002F.codex\u002Fsessions\",\n        \"\u002FUsers\u002Fme\u002Fworkspace\u002Fproject-b\u002F.codex\u002Farchived_sessions\"\n      ],\n      \"gemini\": [\"\u002FUsers\u002Fme\u002Fimports\u002Fimac\u002Fgemini\u002Ftmp\"],\n      \"openclaw\": [\"\u002FUsers\u002Fme\u002Fimports\u002Fimac\u002Fopenclaw\u002Fagents\"]\n    }\n  }\n}\n```\n\nThis is useful for project-level `.codex` directories and imported histories. Tokscale still scans its default roots, then merges `scanner.extraScanPaths` and `TOKSCALE_EXTRA_DIRS` on top with canonical-path deduplication. It does not auto-discover your whole workspace.\n\nEach message contains:\n```json\n{\n  \"id\": \"msg_xxx\",\n  \"role\": \"assistant\",\n  \"modelID\": \"claude-sonnet-4-20250514\",\n  \"providerID\": \"anthropic\",\n  \"tokens\": {\n    \"input\": 1234,\n    \"output\": 567,\n    \"reasoning\": 0,\n    \"cache\": { \"read\": 890, \"write\": 123 }\n  },\n  \"time\": { \"created\": 1699999999999 }\n}\n```\n\n### Claude Code\n\nLocation: `~\u002F.claude\u002Fprojects\u002F{projectPath}\u002F*.jsonl` and `~\u002F.claude\u002Ftranscripts\u002F*.jsonl`\n\nJSONL format with assistant messages containing usage data:\n```json\n{\"type\": \"assistant\", \"message\": {\"model\": \"claude-sonnet-4-20250514\", \"usage\": {\"input_tokens\": 1234, \"output_tokens\": 567, \"cache_read_input_tokens\": 890}}, \"timestamp\": \"2024-01-01T00:00:00Z\"}\n```\n\nWrapper transcript files under `~\u002F.claude\u002Ftranscripts\u002F` are counted only when they contain real Claude usage metadata. Files with user\u002Ftool events but no `usage` block are skipped rather than estimated.\n\n### Codex CLI\n\nLocation: `~\u002F.codex\u002Fsessions\u002F*.jsonl`\n\nEvent-based format with `token_count` events:\n```json\n{\"type\": \"event_msg\", \"payload\": {\"type\": \"token_count\", \"info\": {\"last_token_usage\": {\"input_tokens\": 1234, \"output_tokens\": 567}}}}\n```\n\n### Copilot CLI\n\nLocation: `~\u002F.copilot\u002Fotel\u002F*.jsonl` or the explicit path in `COPILOT_OTEL_FILE_EXPORTER_PATH`\n\nCopilot support reads file-exported OpenTelemetry JSONL. Enable it before running Copilot:\n\n```bash\nexport COPILOT_OTEL_ENABLED=true\nexport COPILOT_OTEL_EXPORTER_TYPE=file\nmkdir -p \"$HOME\u002F.copilot\u002Fotel\"\nexport COPILOT_OTEL_FILE_EXPORTER_PATH=\"$HOME\u002F.copilot\u002Fotel\u002Fcopilot-otel-$(date +%Y%m%d-%H%M%S).jsonl\"\n```\n\nPowerShell:\n\n```powershell\n$otelDir = \"$HOME\u002F.copilot\u002Fotel\"\nNew-Item -ItemType Directory -Force -Path $otelDir | Out-Null\n$env:COPILOT_OTEL_ENABLED = \"true\"\n$env:COPILOT_OTEL_EXPORTER_TYPE = \"file\"\n$env:COPILOT_OTEL_FILE_EXPORTER_PATH = Join-Path $otelDir (\"copilot-otel-{0}.jsonl\" -f (Get-Date -Format \"yyyyMMdd-HHmmss\"))\n```\n\nUsing a timestamped filename is recommended so each Copilot session writes to a fresh file instead of accumulating into one huge OTEL log.\n\nTokscale treats `chat` spans as the source of truth for token accounting and ignores tool spans plus cumulative metrics in phase 1:\n\n```json\n{\"type\":\"span\",\"name\":\"chat gpt-5.4-mini\",\"attributes\":{\"gen_ai.operation.name\":\"chat\",\"gen_ai.response.model\":\"gpt-5.4-mini\",\"gen_ai.conversation.id\":\"session-id\",\"gen_ai.usage.input_tokens\":1234,\"gen_ai.usage.output_tokens\":567,\"gen_ai.usage.cache_read.input_tokens\":890,\"gen_ai.usage.reasoning.output_tokens\":123}}\n```\n\n> Copilot's OTEL payloads currently do not expose stable workspace metadata, so Copilot rows may appear without workspace attribution. Tokscale prices these rows from the reported model when possible and does not trust `github.copilot.cost` directly.\n\n### Gemini CLI\n\nLocation: `~\u002F.gemini\u002Ftmp\u002F{projectHash}\u002Fchats\u002F*.json`\n\nSession files containing message arrays:\n```json\n{\n  \"sessionId\": \"xxx\",\n  \"messages\": [\n    {\"type\": \"gemini\", \"model\": \"gemini-2.5-pro\", \"tokens\": {\"input\": 1234, \"output\": 567, \"cached\": 890, \"thoughts\": 123}}\n  ]\n}\n```\n\n### Cursor IDE\n\nLocation: `~\u002F.config\u002Ftokscale\u002Fcursor-cache\u002F` (synced via Cursor API)\n\nCursor data is fetched from the Cursor API using your session token and cached locally. Run `tokscale cursor login` to authenticate. See [Cursor IDE Commands](#cursor-ide-commands) for setup instructions.\n\n### Antigravity\n\nLocation: `~\u002F.config\u002Ftokscale\u002Fantigravity-cache\u002Fsessions\u002F*.jsonl` (synced via local Antigravity language server RPC)\n\nAntigravity data is not fetched automatically by the root command. Run `tokscale antigravity sync` while the Antigravity-enabled editor is open to refresh the local cache, then use normal tokscale reports and filters against the cached JSONL artifacts.\n\n### OpenClaw\n\nLocation: `~\u002F.openclaw\u002Fagents\u002F*\u002Fsessions\u002Fsessions.json` (also scans legacy paths: `~\u002F.clawdbot\u002F`, `~\u002F.moltbot\u002F`, `~\u002F.moldbot\u002F`)\n\nIndex file pointing to JSONL session files:\n```json\n{\n  \"agent:main:main\": {\n    \"sessionId\": \"uuid\",\n    \"sessionFile\": \"\u002Fpath\u002Fto\u002Fsession.jsonl\"\n  }\n}\n```\n\nSession JSONL format with model_change events and assistant messages:\n```json\n{\"type\":\"model_change\",\"provider\":\"openai-codex\",\"modelId\":\"gpt-5.2\"}\n{\"type\":\"message\",\"message\":{\"role\":\"assistant\",\"usage\":{\"input\":1660,\"output\":55,\"cacheRead\":108928,\"cost\":{\"total\":0.02}},\"timestamp\":1769753935279}}\n```\n\n### Hermes Agent\n\nLocation: `$HERMES_HOME\u002Fstate.db` (fallback: `~\u002F.hermes\u002Fstate.db`)\n\nHermes stores session-level usage in a SQLite `sessions` table. Tokscale imports rows where `model` is present and token or cost totals are non-zero, uses `started_at` as the timestamp, preserves `message_count`, and prefers `actual_cost_usd` over `estimated_cost_usd`.\n\n### Pi\n\nLocation: `~\u002F.pi\u002Fagent\u002Fsessions\u002F\u003Cencoded-cwd>\u002F*.jsonl` and `~\u002F.omp\u002Fagent\u002Fsessions\u002F\u003Cencoded-cwd>\u002F*.jsonl` ([Oh My Pi](https:\u002F\u002Fgithub.com\u002Fcan1357\u002Foh-my-pi))\n\nJSONL format with session header and message entries:\n```json\n{\"type\":\"session\",\"id\":\"pi_ses_001\",\"timestamp\":\"2026-01-01T00:00:00.000Z\",\"cwd\":\"\u002Ftmp\"}\n{\"type\":\"message\",\"id\":\"msg_001\",\"timestamp\":\"2026-01-01T00:00:01.000Z\",\"message\":{\"role\":\"assistant\",\"model\":\"claude-3-5-sonnet\",\"provider\":\"anthropic\",\"usage\":{\"input\":100,\"output\":50,\"cacheRead\":10,\"cacheWrite\":5,\"totalTokens\":165}}}\n```\n\n### Kimi CLI\n\nLocation: `~\u002F.kimi\u002Fsessions\u002F{GROUP_ID}\u002F{SESSION_UUID}\u002Fwire.jsonl`\n\nwire.jsonl format with StatusUpdate messages:\n```json\n{\"type\": \"metadata\", \"protocol_version\": \"1.3\"}\n{\"timestamp\": 1770983426.420942, \"message\": {\"type\": \"StatusUpdate\", \"payload\": {\"token_usage\": {\"input_other\": 1562, \"output\": 2463, \"input_cache_read\": 0, \"input_cache_creation\": 0}, \"message_id\": \"chatcmpl-xxx\"}}}\n```\n\n### Qwen CLI\n\nLocation: `~\u002F.qwen\u002Fprojects\u002F{PROJECT_PATH}\u002Fchats\u002F{CHAT_ID}.jsonl`\n\nFormat: JSONL — one JSON object per line, each with `type`, `model`, `timestamp`, `sessionId`, and `usageMetadata` fields.\n\nToken fields (from `usageMetadata`):\n- `promptTokenCount` → input tokens\n- `candidatesTokenCount` → output tokens\n- `thoughtsTokenCount` → reasoning\u002Fthinking tokens\n- `cachedContentTokenCount` → cached input tokens\n\n### Roo Code\n\nLocation:\n- Local: `~\u002F.config\u002FCode\u002FUser\u002FglobalStorage\u002Frooveterinaryinc.roo-cline\u002Ftasks\u002F{TASK_ID}\u002Fui_messages.json`\n- Server (best-effort): `~\u002F.vscode-server\u002Fdata\u002FUser\u002FglobalStorage\u002Frooveterinaryinc.roo-cline\u002Ftasks\u002F{TASK_ID}\u002Fui_messages.json`\n\nEach task directory may also include `api_conversation_history.json` with `\u003Cenvironment_details>` blocks used for model\u002Fagent metadata.\n\n`ui_messages.json` is an array of UI events. Tokscale counts only:\n- `type == \"say\"`\n- `say == \"api_req_started\"`\n\nThe `text` field is JSON containing token\u002Fcost metadata:\n```json\n{\n  \"type\": \"say\",\n  \"say\": \"api_req_started\",\n  \"ts\": \"2026-02-18T12:00:00Z\",\n  \"text\": \"{\\\"cost\\\":0.12,\\\"tokensIn\\\":100,\\\"tokensOut\\\":50,\\\"cacheReads\\\":20,\\\"cacheWrites\\\":5,\\\"apiProtocol\\\":\\\"anthropic\\\"}\"\n}\n```\n\n### Kilo\n\nLocation:\n- Local: `~\u002F.config\u002FCode\u002FUser\u002FglobalStorage\u002Fkilocode.kilo-code\u002Ftasks\u002F{TASK_ID}\u002Fui_messages.json`\n- Server (best-effort): `~\u002F.vscode-server\u002Fdata\u002FUser\u002FglobalStorage\u002Fkilocode.kilo-code\u002Ftasks\u002F{TASK_ID}\u002Fui_messages.json`\n\nKilo uses the same task log shape as Roo Code. Tokscale applies the same rules:\n- count only `say\u002Fapi_req_started` events from `ui_messages.json`\n- parse `tokensIn`, `tokensOut`, `cacheReads`, `cacheWrites`, `cost`, and `apiProtocol` from `text` JSON\n- enrich model\u002Fagent metadata from sibling `api_conversation_history.json` when available\n\n### Mux\n\nLocation:\n- `~\u002F.mux\u002Fsessions\u002F{WORKSPACE_ID}\u002Fsession-usage.json`\n\nMux stores cumulative per-session token usage in `session-usage.json` files. Each file contains a `byModel` map with per-model token breakdowns:\n- `input`, `cached` (cache reads), `cacheCreate` (cache writes), `output`, `reasoning`\n- Model names use `provider:model` format (e.g., `anthropic:claude-opus-4-6`) — tokscale strips the provider prefix for model identification\n- Sub-agent usage is automatically rolled up into parent sessions by Mux, so there is no double-counting\n\n### Kilo CLI\n\nLocation: `~\u002F.local\u002Fshare\u002Fkilo\u002Fkilo.db`\n\nKilo CLI stores session data in a SQLite database similar to OpenCode. Each message row contains per-message token breakdowns (input, output, cache read\u002Fwrite, reasoning) with model and provider attribution.\n\n### Crush\n\nLocation: Project-level SQLite databases discovered via `$XDG_DATA_HOME\u002Fcrush\u002Fprojects.json` (fallback: `~\u002F.local\u002Fshare\u002Fcrush\u002Fprojects.json`)\n\nCrush stores usage in per-project SQLite databases (`crush.db`). Tokscale imports session-level cost totals from root sessions only, because Crush does not expose reliable per-message or per-model token accounting. Records appear as `model=session-total` with zero token breakdown.\n\n### Goose\n\nLocation: `~\u002F.local\u002Fshare\u002Fgoose\u002Fsessions\u002Fsessions.db` (also scans `~\u002FLibrary\u002FApplication Support\u002Fgoose\u002F`, `~\u002FLibrary\u002FApplication Support\u002FBlock\u002Fgoose\u002F`, `~\u002F.local\u002Fshare\u002FBlock\u002Fgoose\u002F`; override via `GOOSE_PATH_ROOT`)\n\nGoose stores per-session usage in a SQLite `sessions.db`. Tokscale extracts the model from `model_config_json`, the provider from `provider_name`, and accumulated input\u002Foutput token totals per session. Reasoning tokens are inferred when the column is populated.\n\n### Codebuff\n\nLocation: `~\u002F.config\u002Fmanicode\u002Fprojects\u002F\u003Cproject>\u002Fchats\u002F\u003CchatId>\u002Fchat-messages.json` (also scans `manicode-dev` and `manicode-staging` channels; override via `CODEBUFF_DATA_DIR`)\n\nCodebuff (formerly Manicode) writes per-chat JSON files. Tokscale parses token usage from `metadata.usage`, `metadata.codebuff.usage`, and the run-state `messageHistory[*].providerOptions` fallback, walking the history in reverse so partial newer entries don't shadow earlier entries that carry the actual token counts. Per-message timestamps fall back to the chat-id directory name and finally to file mtime when missing.\n\n### Synthetic (synthetic.new)\n\nSynthetic usage is detected via post-processing of existing agent session files. Messages are re-attributed to `synthetic` when they use `hf:` model IDs or synthetic providers (`synthetic`, `glhf`, `octofriend`).\n\nTokscale also checks Octofriend SQLite at `~\u002F.local\u002Fshare\u002Foctofriend\u002Fsqlite.db` and parses token-bearing records when available.\n\n## Pricing\n\nTokscale fetches real-time pricing from [LiteLLM's pricing database](https:\u002F\u002Fgithub.com\u002FBerriAI\u002Flitellm\u002Fblob\u002Fmain\u002Fmodel_prices_and_context_window.json).\n\n**Dynamic Fallback**: For models not yet available in LiteLLM (e.g., recently released models), Tokscale automatically fetches pricing from [OpenRouter's endpoints API](https:\u002F\u002Fopenrouter.ai\u002Fdocs\u002Fapi\u002Fapi-reference\u002Fendpoints\u002Flist-endpoints). This ensures you get accurate pricing from the model's author provider (e.g., Z.AI for glm-4.7) without waiting for LiteLLM updates.\n\n**Cursor Model Pricing**: For very recently released models not yet in either LiteLLM or OpenRouter (e.g., `gpt-5.3-codex`), Tokscale includes hardcoded pricing sourced from [Cursor's model docs](https:\u002F\u002Fcursor.com\u002Fen-US\u002Fdocs\u002Fmodels). These overrides are checked after all upstream sources but before fuzzy matching, so they automatically yield once real upstream pricing becomes available.\n\n**Caching**: Pricing data is cached to disk with 1-hour TTL for fast startup:\n- LiteLLM cache: `~\u002F.config\u002Ftokscale\u002Fcache\u002Fpricing-litellm.json`\n- OpenRouter cache: `~\u002F.config\u002Ftokscale\u002Fcache\u002Fpricing-openrouter.json` (caches author pricing for models from supported providers)\n\nPricing includes:\n- Input tokens\n- Output tokens\n- Cache read tokens (discounted)\n- Cache write tokens\n- Reasoning tokens (for models like o1)\n- Model-specific tiered pricing (for example, above 200k or 272k tokens)\n\n## Contributing\n\nContributions are welcome! Please follow these steps:\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature\u002Famazing-feature`)\n3. Make your changes\n4. Run tests (`cd packages\u002Fcore && bun run test:all`)\n5. Commit your changes (`git commit -m 'Add amazing feature'`)\n6. Push to the branch (`git push origin feature\u002Famazing-feature`)\n7. Open a Pull Request\n\n### Development Guidelines\n\n- Follow existing code style\n- Add tests for new functionality\n- Update documentation as needed\n- Keep commits focused and atomic\n\n## Acknowledgments\n\n- [ccusage](https:\u002F\u002Fgithub.com\u002Fryoppippi\u002Fccusage), [viberank](https:\u002F\u002Fgithub.com\u002Fsculptdotfun\u002Fviberank), and [Isometric Contributions](https:\u002F\u002Fgithub.com\u002Fjasonlong\u002Fisometric-contributions) for inspiration\n- [Ratatui](https:\u002F\u002Fgithub.com\u002Fratatui\u002Fratatui) for terminal UI framework\n- [Solid.js](https:\u002F\u002Fwww.solidjs.com\u002F) for reactive rendering\n- [LiteLLM](https:\u002F\u002Fgithub.com\u002FBerriAI\u002Flitellm) for pricing data\n- [napi-rs](https:\u002F\u002Fnapi.rs\u002F) for Rust\u002FNode.js bindings\n- [github-contributions-canvas](https:\u002F\u002Fgithub.com\u002Fsallar\u002Fgithub-contributions-canvas) for 2D graph reference\n\n## License\n\n\u003Cp align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fjunhoyeo\">\n    \u003Cimg src=\".github\u002Fassets\u002Flabtocat-on-spaceship.png\" width=\"540\">\n  \u003C\u002Fa>\n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  \u003Cstrong>MIT © \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fjunhoyeo\">Junho Yeo\u003C\u002Fa>\u003C\u002Fstrong>\n\u003C\u002Fp>\n\nIf you find this project intriguing, **please consider starring it ⭐** or [follow me on GitHub](https:\u002F\u002Fgithub.com\u002Fjunhoyeo) and join the ride (1.1k+ already aboard). I code around the clock and ship mind-blowing things on a regular basis—your support won't go to waste.\n","Tokscale 是一个用于跟踪多个AI编码代理（如OpenCode、Claude Code、OpenClaw等）的令牌使用情况和成本的高性能命令行工具及可视化仪表板。它采用Rust语言开发，提供原生TUI界面支持，并具备跨平台特性。用户可以通过Tokscale直观地查看令牌消耗量及其相关费用，同时享受2D\u002F3D贡献图表与全球排行榜功能。此工具特别适用于需要管理或优化AI服务资源使用的开发者和个人，帮助他们更好地控制成本并提高效率。",2,"2026-06-11 03:45:02","high_star"]