1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use clap::{Parser, Subcommand, ValueEnum};
use std::path::PathBuf;
#[derive(Debug, Clone, ValueEnum)]
pub enum OutputFormat {
Text,
Html,
Json,
}
#[derive(Debug, Clone, ValueEnum)]
pub enum GroupBy {
Day,
Month,
}
#[derive(Parser, Debug)]
#[command(
name = "cc-token-usage",
version,
about = "Analyze Claude Code session token usage, costs, and efficiency"
)]
pub struct Cli {
/// Output format (default: both text + html)
#[arg(long, value_enum, global = true)]
pub format: Option<OutputFormat>,
/// Write output to a file instead of stdout
#[arg(long, global = true)]
pub output: Option<PathBuf>,
/// Path to Claude home directory (default: ~/.claude)
#[arg(long, global = true)]
pub claude_home: Option<PathBuf>,
/// Monthly subscription price in USD for cost calculations
#[arg(long, global = true)]
pub subscription_price: Option<f64>,
/// Path to config file
#[arg(long, global = true)]
pub config: Option<PathBuf>,
#[command(subcommand)]
pub command: Option<Command>,
}
#[derive(Subcommand, Debug)]
pub enum Command {
/// Show overall usage overview across all projects
Overview,
/// Analyze token usage for a specific project
Project {
/// Project name to analyze
#[arg(long, allow_hyphen_values = true)]
name: Option<String>,
/// Show top N sessions by token usage
#[arg(long, default_value_t = 10)]
top: usize,
},
/// Analyze a specific session
Session {
/// Session ID to analyze
id: Option<String>,
/// Analyze the latest session instead of specifying an ID
#[arg(long)]
latest: bool,
},
/// Validate token counting accuracy against raw JSONL data
Validate {
/// Validate a specific session ID (optional, validates all if omitted)
id: Option<String>,
/// Show only failed checks
#[arg(long)]
failures_only: bool,
},
/// Check for updates and self-update the binary
Update {
/// Only check for a new version, don't download
#[arg(long)]
check: bool,
},
/// Show usage trends over time
Trend {
/// Number of days to include (0 = all history)
#[arg(long, default_value_t = 0)]
days: u32,
/// Group by: day or month
#[arg(long, value_enum, default_value_t = GroupBy::Day)]
group_by: GroupBy,
},
/// Generate a "Wrapped" annual summary of your Claude Code usage
Wrapped {
/// Year to summarize (default: current year)
#[arg(long)]
year: Option<i32>,
},
/// Show a GitHub-style activity heatmap in the terminal
Heatmap {
/// Number of days to show (0 = all history, default 365)
#[arg(long, default_value_t = 365)]
days: u32,
},
}