|
1 | | -# cc-token-usage |
| 1 | +# CLAUDE.md |
2 | 2 |
|
3 | | -Analyze Claude Code session token usage, costs, and efficiency. Reads local JSONL session files, calculates token consumption and API-equivalent costs, and generates terminal summaries and interactive HTML dashboards. |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
4 | 4 |
|
5 | | -- **GitHub:** https://github.com/LokiQ0713/cc-token-usage |
6 | | -- **npm:** https://www.npmjs.com/package/cc-token-usage |
7 | | - |
8 | | -## Tech Stack |
9 | | - |
10 | | -- **Language:** Rust (edition 2021) |
11 | | -- **Dependencies:** serde/serde_json (serialization), clap (CLI), chrono (dates), comfy-table (terminal tables), toml (config), dirs (paths), anyhow (errors) |
12 | | -- **Frontend:** Chart.js (embedded in HTML output) |
13 | | -- **Distribution:** cargo (crates.io) + npm (pre-built binaries) |
| 5 | +## Project Overview |
14 | 6 |
|
15 | | -## File Structure |
| 7 | +**cc-token-usage** — CLI tool that analyzes Claude Code session token usage, costs, and efficiency. Reads JSONL session files from `~/.claude/projects/`, calculates API-equivalent costs, and outputs terminal tables or interactive HTML dashboards. |
16 | 8 |
|
17 | | -``` |
18 | | -src/ |
19 | | -├── main.rs # Entry point, CLI dispatch |
20 | | -├── cli.rs # Clap CLI argument definitions |
21 | | -├── config.rs # Config file loading (pricing overrides) |
22 | | -├── lib.rs # Library root |
23 | | -├── data/ |
24 | | -│ ├── mod.rs |
25 | | -│ ├── scanner.rs # Discover JSONL session files |
26 | | -│ ├── parser.rs # 5-stage pipeline: parse → filter → validate → extract → dedup |
27 | | -│ ├── models.rs # Data types (JournalEntry, ValidatedTurn, SessionData, TokenUsage) |
28 | | -│ └── loader.rs # Load sessions + merge agent turns (cross-file dedup) |
29 | | -├── pricing/ |
30 | | -│ ├── mod.rs |
31 | | -│ └── calculator.rs # Token cost calculation with cache tiers |
32 | | -├── analysis/ |
33 | | -│ ├── mod.rs |
34 | | -│ ├── overview.rs # Aggregate statistics |
35 | | -│ ├── project.rs # Per-project breakdown |
36 | | -│ ├── session.rs # Per-session breakdown |
37 | | -│ ├── trend.rs # Daily/monthly trend analysis |
38 | | -│ └── validate.rs # Independent token verification (dual-path cross-validation) |
39 | | -└── output/ |
40 | | - ├── mod.rs |
41 | | - ├── text.rs # Terminal table output |
42 | | - └── html.rs # Interactive HTML dashboard |
43 | | -
|
44 | | -npm-package/ # npm wrapper for binary distribution |
45 | | -config.example.toml # Example config with pricing overrides |
46 | | -``` |
| 9 | +- **GitHub:** https://github.com/LokiQ0713/cc-token-usage |
| 10 | +- **npm:** https://www.npmjs.com/package/cc-token-usage |
47 | 11 |
|
48 | | -## Development |
| 12 | +## Commands |
49 | 13 |
|
50 | 14 | ```bash |
51 | | -# Build |
| 15 | +# Build & run |
52 | 16 | cargo build |
53 | | - |
54 | | -# Run |
55 | 17 | cargo run |
56 | 18 | cargo run -- --format html |
57 | | -cargo run -- project --top 5 |
58 | 19 | cargo run -- session --latest |
59 | | -cargo run -- trend --days 30 |
60 | | -cargo run -- validate # Verify token accuracy (3890+ checks) |
61 | 20 | cargo run -- validate --failures-only |
62 | 21 |
|
63 | | -# Test |
| 22 | +# Test (all tests, or a single test) |
64 | 23 | cargo test |
| 24 | +cargo test parse_valid_assistant_turn |
65 | 25 |
|
66 | | -# Lint |
| 26 | +# Lint & format |
67 | 27 | cargo clippy -- -D warnings |
68 | | - |
69 | | -# Format |
70 | 28 | cargo fmt |
71 | 29 | ``` |
72 | 30 |
|
| 31 | +## Architecture |
| 32 | + |
| 33 | +### Data Pipeline (src/data/) |
| 34 | + |
| 35 | +The core data flow is a 5-stage pipeline in `parser.rs`: |
| 36 | + |
| 37 | +``` |
| 38 | +JSONL line → JSON parse → type filter → validation → content extraction → request_id dedup |
| 39 | +``` |
| 40 | + |
| 41 | +Key design decisions: |
| 42 | +- **Sidechain filtering**: Main session files skip `isSidechain=true` entries (abandoned generations), but agent files keep them (agents always have `isSidechain=true`) |
| 43 | +- **Streaming dedup**: Same `requestId` appearing multiple times (streaming retries) keeps the last entry |
| 44 | +- **Cross-file dedup** (in `loader.rs`): Agent turns that already appear in the parent session (by `requestId`) are dropped to prevent double-counting |
| 45 | + |
| 46 | +Session files are discovered by `scanner.rs` which handles three file layouts: |
| 47 | +1. `<project>/<uuid>.jsonl` — main sessions |
| 48 | +2. `<project>/agent-<id>.jsonl` — legacy agents (parent resolved from first line's `sessionId`) |
| 49 | +3. `<project>/<uuid>/subagents/agent-<id>.jsonl` — new-style agents (parent from directory name) |
| 50 | + |
| 51 | +### Pricing (src/pricing/) |
| 52 | + |
| 53 | +`PricingCalculator` resolves model prices with a 4-step fallback: exact override → prefix override → exact builtin → prefix builtin. This handles versioned model IDs like `claude-opus-4-5-20251101` matching `claude-opus-4-5`. Cache write costs distinguish two TTL tiers (5-minute and 1-hour). Built-in prices have a staleness check (>90 days). |
| 54 | + |
| 55 | +### Analysis (src/analysis/) |
| 56 | + |
| 57 | +Each subcommand has its own analysis module (`overview.rs`, `project.rs`, `session.rs`, `trend.rs`). All consume `Vec<SessionData>` + `PricingCalculator` and return typed result structs defined in `mod.rs`. |
| 58 | + |
| 59 | +`validate.rs` implements **dual-path cross-validation**: an independent raw JSON counter (using `serde_json::Value`, no shared types with the main pipeline) re-counts tokens from JSONL files and compares against the pipeline's output. |
| 60 | + |
| 61 | +### Output (src/output/) |
| 62 | + |
| 63 | +- `text.rs` — terminal tables via `comfy-table` |
| 64 | +- `html.rs` — self-contained HTML with embedded Chart.js, supports light/dark theme and i18n (en/zh) |
| 65 | + |
73 | 66 | ## Release Workflow |
74 | 67 |
|
75 | | -1. Bump version in `Cargo.toml` and `npm-package/package.json` |
| 68 | +1. Bump version in both `Cargo.toml` and `npm-package/package.json` |
76 | 69 | 2. `npm version patch/minor/major` (creates git tag) |
77 | 70 | 3. `git push && git push --tags` |
78 | | -4. GitHub Actions `release.yml` auto-builds binaries for all platforms and publishes to npm |
| 71 | +4. GitHub Actions `release.yml` builds cross-platform binaries and publishes to npm |
| 72 | + |
| 73 | +**Important**: Always commit `Cargo.lock` in release commits — CI needs it for reproducible builds. Never delete and re-create release tags; always bump the version instead. |
79 | 74 |
|
80 | 75 | ## CI/CD |
81 | 76 |
|
82 | | -- **CI** (`ci.yml`): Runs `cargo check`, `cargo test`, `cargo clippy` on push/PR to master |
83 | | -- **Release** (`release.yml`): Triggered by version tags, builds cross-platform binaries, publishes to npm |
| 77 | +- **CI** (`ci.yml`): `cargo check` + `cargo test` + `cargo clippy` on push/PR to master |
| 78 | +- **Release** (`release.yml`): Triggered by `v*` tags, cross-compiles for Linux/macOS/Windows, publishes npm package |
0 commit comments