ccusage 0.1.12 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -51
- package/dist/index.js +66 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,10 +41,12 @@ This tool helps you understand the value you're getting from your subscription b
|
|
|
41
41
|
- 🎨 **Beautiful Output**: Colorful table-formatted display
|
|
42
42
|
- 📄 **JSON Output**: Export data in structured JSON format with `--json`
|
|
43
43
|
- 💰 **Cost Tracking**: Shows costs in USD for each day/session
|
|
44
|
+
- 🔄 **Cache Token Support**: Tracks and displays cache creation and cache read tokens separately
|
|
44
45
|
|
|
45
46
|
## Limitations
|
|
46
47
|
|
|
47
48
|
- This tool only reads local JSONL files generated by Claude Code. If you use Claude Code with multiple devices, you need to ensure the JSONL files are synchronized across devices.
|
|
49
|
+
- API usage for tools like Web Search, Code Execution, and Image Analysis are not included in the token usage reports. The tool only tracks language model token usage.
|
|
48
50
|
|
|
49
51
|
## Installation
|
|
50
52
|
|
|
@@ -151,15 +153,15 @@ All commands support the following options:
|
|
|
151
153
|
│ │
|
|
152
154
|
╰──────────────────────────────────────────╯
|
|
153
155
|
|
|
154
|
-
|
|
155
|
-
│ Date
|
|
156
|
-
|
|
157
|
-
│ 2025-05-30
|
|
158
|
-
│ 2025-05-29
|
|
159
|
-
│ 2025-05-28
|
|
160
|
-
|
|
161
|
-
│ Total
|
|
162
|
-
|
|
156
|
+
┌──────────────┬────────┬─────────┬──────────────┬────────────┬──────────────┬────────────┐
|
|
157
|
+
│ Date │ Input │ Output │ Cache Create │ Cache Read │ Total Tokens │ Cost (USD) │
|
|
158
|
+
├──────────────┼────────┼─────────┼──────────────┼────────────┼──────────────┼────────────┤
|
|
159
|
+
│ 2025-05-30 │ 277 │ 31,456 │ 512 │ 1,024 │ 33,269 │ $17.58 │
|
|
160
|
+
│ 2025-05-29 │ 959 │ 39,662 │ 256 │ 768 │ 41,645 │ $16.42 │
|
|
161
|
+
│ 2025-05-28 │ 155 │ 21,693 │ 128 │ 512 │ 22,488 │ $8.36 │
|
|
162
|
+
├──────────────┼────────┼─────────┼──────────────┼────────────┼──────────────┼────────────┤
|
|
163
|
+
│ Total │ 11,174 │ 720,366 │ 896 │ 2,304 │ 734,740 │ $336.47 │
|
|
164
|
+
└──────────────┴────────┴─────────┴──────────────┴────────────┴──────────────┴────────────┘
|
|
163
165
|
```
|
|
164
166
|
|
|
165
167
|
### Session Report
|
|
@@ -170,53 +172,20 @@ All commands support the following options:
|
|
|
170
172
|
│ │
|
|
171
173
|
╰───────────────────────────────────────────────╯
|
|
172
174
|
|
|
173
|
-
|
|
174
|
-
│ Project
|
|
175
|
-
|
|
176
|
-
│
|
|
177
|
-
|
|
178
|
-
│
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
└──────────────────────────────┴──────────────┴───────────────┴──────────────┴────────────┴───────────────┘
|
|
175
|
+
┌─────────────┬────────────┬────────┬─────────┬──────────────┬────────────┬──────────────┬────────────┬───────────────┐
|
|
176
|
+
│ Project │ Session │ Input │ Output │ Cache Create │ Cache Read │ Total Tokens │ Cost (USD) │ Last Activity │
|
|
177
|
+
├─────────────┼────────────┼────────┼─────────┼──────────────┼────────────┼──────────────┼────────────┼───────────────┤
|
|
178
|
+
│ myproject │ session-1 │ 4,512 │ 350,846 │ 512 │ 1,024 │ 356,894 │ $156.40 │ 2025-05-24 │
|
|
179
|
+
├─────────────┼────────────┼────────┼─────────┼──────────────┼────────────┼──────────────┼────────────┼───────────────┤
|
|
180
|
+
│ myproject │ session-2 │ 2,775 │ 186,645 │ 256 │ 768 │ 190,444 │ $98.45 │ 2025-05-25 │
|
|
181
|
+
├─────────────┼────────────┼────────┼─────────┼──────────────┼────────────┼──────────────┼────────────┼───────────────┤
|
|
182
|
+
│ Total │ │ 11,174 │ 720,445 │ 768 │ 1,792 │ 734,179 │ $336.68 │ │
|
|
183
|
+
└─────────────┴────────────┴────────┴─────────┴──────────────┴────────────┴──────────────┴────────────┴───────────────┘
|
|
183
184
|
```
|
|
184
185
|
|
|
185
186
|
## Requirements
|
|
186
|
-
|
|
187
|
-
- [Bun](https://bun.sh) runtime
|
|
188
187
|
- Claude Code usage history files (`~/.claude/projects/**/*.jsonl`)
|
|
189
188
|
|
|
190
|
-
## Development
|
|
191
|
-
|
|
192
|
-
```bash
|
|
193
|
-
# Run tests
|
|
194
|
-
bun test
|
|
195
|
-
|
|
196
|
-
# Type check
|
|
197
|
-
bun run typecheck
|
|
198
|
-
|
|
199
|
-
# Lint
|
|
200
|
-
bun run lint
|
|
201
|
-
|
|
202
|
-
# Format code
|
|
203
|
-
bun run format
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
## Project Structure
|
|
207
|
-
|
|
208
|
-
```
|
|
209
|
-
ccusage/
|
|
210
|
-
├── commands/
|
|
211
|
-
│ ├── daily.ts # Daily report command
|
|
212
|
-
│ └── session.ts # Session report command
|
|
213
|
-
├── data-loader.ts # JSONL data loading logic
|
|
214
|
-
├── index.ts # CLI entry point
|
|
215
|
-
├── logger.ts # Logger configuration
|
|
216
|
-
├── utils.ts # Shared utilities
|
|
217
|
-
└── package.json
|
|
218
|
-
```
|
|
219
|
-
|
|
220
189
|
## License
|
|
221
190
|
|
|
222
191
|
MIT
|
package/dist/index.js
CHANGED
|
@@ -5939,7 +5939,9 @@ const UsageDataSchema = object({
|
|
|
5939
5939
|
timestamp: string(),
|
|
5940
5940
|
message: object({ usage: object({
|
|
5941
5941
|
input_tokens: number(),
|
|
5942
|
-
output_tokens: number()
|
|
5942
|
+
output_tokens: number(),
|
|
5943
|
+
cache_creation_input_tokens: optional(number()),
|
|
5944
|
+
cache_read_input_tokens: optional(number())
|
|
5943
5945
|
}) }),
|
|
5944
5946
|
costUSD: number()
|
|
5945
5947
|
});
|
|
@@ -5947,6 +5949,8 @@ const DailyUsageSchema = object({
|
|
|
5947
5949
|
date: string(),
|
|
5948
5950
|
inputTokens: number(),
|
|
5949
5951
|
outputTokens: number(),
|
|
5952
|
+
cacheCreationTokens: number(),
|
|
5953
|
+
cacheReadTokens: number(),
|
|
5950
5954
|
totalCost: number()
|
|
5951
5955
|
});
|
|
5952
5956
|
const SessionUsageSchema = object({
|
|
@@ -5954,6 +5958,8 @@ const SessionUsageSchema = object({
|
|
|
5954
5958
|
projectPath: string(),
|
|
5955
5959
|
inputTokens: number(),
|
|
5956
5960
|
outputTokens: number(),
|
|
5961
|
+
cacheCreationTokens: number(),
|
|
5962
|
+
cacheReadTokens: number(),
|
|
5957
5963
|
totalCost: number(),
|
|
5958
5964
|
lastActivity: string()
|
|
5959
5965
|
});
|
|
@@ -5986,10 +5992,14 @@ async function loadUsageData(options) {
|
|
|
5986
5992
|
date,
|
|
5987
5993
|
inputTokens: 0,
|
|
5988
5994
|
outputTokens: 0,
|
|
5995
|
+
cacheCreationTokens: 0,
|
|
5996
|
+
cacheReadTokens: 0,
|
|
5989
5997
|
totalCost: 0
|
|
5990
5998
|
};
|
|
5991
5999
|
existing.inputTokens += data.message.usage.input_tokens || 0;
|
|
5992
6000
|
existing.outputTokens += data.message.usage.output_tokens || 0;
|
|
6001
|
+
existing.cacheCreationTokens += data.message.usage.cache_creation_input_tokens || 0;
|
|
6002
|
+
existing.cacheReadTokens += data.message.usage.cache_read_input_tokens || 0;
|
|
5993
6003
|
existing.totalCost += data.costUSD || 0;
|
|
5994
6004
|
dailyMap.set(date, existing);
|
|
5995
6005
|
} catch (e) {}
|
|
@@ -6035,11 +6045,15 @@ async function loadSessionData(options) {
|
|
|
6035
6045
|
projectPath: projectPath || "Unknown Project",
|
|
6036
6046
|
inputTokens: 0,
|
|
6037
6047
|
outputTokens: 0,
|
|
6048
|
+
cacheCreationTokens: 0,
|
|
6049
|
+
cacheReadTokens: 0,
|
|
6038
6050
|
totalCost: 0,
|
|
6039
6051
|
lastActivity: ""
|
|
6040
6052
|
};
|
|
6041
6053
|
existing.inputTokens += data.message.usage.input_tokens || 0;
|
|
6042
6054
|
existing.outputTokens += data.message.usage.output_tokens || 0;
|
|
6055
|
+
existing.cacheCreationTokens += data.message.usage.cache_creation_input_tokens || 0;
|
|
6056
|
+
existing.cacheReadTokens += data.message.usage.cache_read_input_tokens || 0;
|
|
6043
6057
|
existing.totalCost += data.costUSD || 0;
|
|
6044
6058
|
if (data.timestamp > lastTimestamp) {
|
|
6045
6059
|
lastTimestamp = data.timestamp;
|
|
@@ -7023,7 +7037,7 @@ const consola = createConsola();
|
|
|
7023
7037
|
//#endregion
|
|
7024
7038
|
//#region package.json
|
|
7025
7039
|
var name = "ccusage";
|
|
7026
|
-
var version = "0.
|
|
7040
|
+
var version = "0.2.0";
|
|
7027
7041
|
var description = "Usage analysis tool for Claude Code";
|
|
7028
7042
|
|
|
7029
7043
|
//#endregion
|
|
@@ -7040,6 +7054,8 @@ const ModelSpecSchema = object({
|
|
|
7040
7054
|
input_cost_per_token: optional(number()),
|
|
7041
7055
|
output_cost_per_token: optional(number()),
|
|
7042
7056
|
output_cost_per_reasoning_token: optional(number()),
|
|
7057
|
+
cache_creation_input_token_cost: optional(number()),
|
|
7058
|
+
cache_read_input_token_cost: optional(number()),
|
|
7043
7059
|
litellm_provider: optional(string()),
|
|
7044
7060
|
mode: optional(string()),
|
|
7045
7061
|
supports_function_calling: optional(boolean()),
|
|
@@ -7128,10 +7144,14 @@ const dailyCommand = define({
|
|
|
7128
7144
|
const totals = dailyData.reduce((acc, data) => ({
|
|
7129
7145
|
inputTokens: acc.inputTokens + data.inputTokens,
|
|
7130
7146
|
outputTokens: acc.outputTokens + data.outputTokens,
|
|
7147
|
+
cacheCreationTokens: acc.cacheCreationTokens + data.cacheCreationTokens,
|
|
7148
|
+
cacheReadTokens: acc.cacheReadTokens + data.cacheReadTokens,
|
|
7131
7149
|
totalCost: acc.totalCost + data.totalCost
|
|
7132
7150
|
}), {
|
|
7133
7151
|
inputTokens: 0,
|
|
7134
7152
|
outputTokens: 0,
|
|
7153
|
+
cacheCreationTokens: 0,
|
|
7154
|
+
cacheReadTokens: 0,
|
|
7135
7155
|
totalCost: 0
|
|
7136
7156
|
});
|
|
7137
7157
|
if (ctx.values.json) {
|
|
@@ -7140,13 +7160,17 @@ const dailyCommand = define({
|
|
|
7140
7160
|
date: data.date,
|
|
7141
7161
|
inputTokens: data.inputTokens,
|
|
7142
7162
|
outputTokens: data.outputTokens,
|
|
7143
|
-
|
|
7163
|
+
cacheCreationTokens: data.cacheCreationTokens,
|
|
7164
|
+
cacheReadTokens: data.cacheReadTokens,
|
|
7165
|
+
totalTokens: data.inputTokens + data.outputTokens + data.cacheCreationTokens + data.cacheReadTokens,
|
|
7144
7166
|
totalCost: data.totalCost
|
|
7145
7167
|
})),
|
|
7146
7168
|
totals: {
|
|
7147
7169
|
inputTokens: totals.inputTokens,
|
|
7148
7170
|
outputTokens: totals.outputTokens,
|
|
7149
|
-
|
|
7171
|
+
cacheCreationTokens: totals.cacheCreationTokens,
|
|
7172
|
+
cacheReadTokens: totals.cacheReadTokens,
|
|
7173
|
+
totalTokens: totals.inputTokens + totals.outputTokens + totals.cacheCreationTokens + totals.cacheReadTokens,
|
|
7150
7174
|
totalCost: totals.totalCost
|
|
7151
7175
|
}
|
|
7152
7176
|
};
|
|
@@ -7156,8 +7180,10 @@ const dailyCommand = define({
|
|
|
7156
7180
|
const table = new import_cli_table3$1.default({
|
|
7157
7181
|
head: [
|
|
7158
7182
|
"Date",
|
|
7159
|
-
"Input
|
|
7160
|
-
"Output
|
|
7183
|
+
"Input",
|
|
7184
|
+
"Output",
|
|
7185
|
+
"Cache Create",
|
|
7186
|
+
"Cache Read",
|
|
7161
7187
|
"Total Tokens",
|
|
7162
7188
|
"Cost (USD)"
|
|
7163
7189
|
],
|
|
@@ -7167,6 +7193,8 @@ const dailyCommand = define({
|
|
|
7167
7193
|
"right",
|
|
7168
7194
|
"right",
|
|
7169
7195
|
"right",
|
|
7196
|
+
"right",
|
|
7197
|
+
"right",
|
|
7170
7198
|
"right"
|
|
7171
7199
|
]
|
|
7172
7200
|
});
|
|
@@ -7174,7 +7202,9 @@ const dailyCommand = define({
|
|
|
7174
7202
|
data.date,
|
|
7175
7203
|
formatNumber(data.inputTokens),
|
|
7176
7204
|
formatNumber(data.outputTokens),
|
|
7177
|
-
formatNumber(data.
|
|
7205
|
+
formatNumber(data.cacheCreationTokens),
|
|
7206
|
+
formatNumber(data.cacheReadTokens),
|
|
7207
|
+
formatNumber(data.inputTokens + data.outputTokens + data.cacheCreationTokens + data.cacheReadTokens),
|
|
7178
7208
|
formatCurrency(data.totalCost)
|
|
7179
7209
|
]);
|
|
7180
7210
|
table.push([
|
|
@@ -7182,13 +7212,17 @@ const dailyCommand = define({
|
|
|
7182
7212
|
"─".repeat(12),
|
|
7183
7213
|
"─".repeat(12),
|
|
7184
7214
|
"─".repeat(12),
|
|
7215
|
+
"─".repeat(12),
|
|
7216
|
+
"─".repeat(12),
|
|
7185
7217
|
"─".repeat(10)
|
|
7186
7218
|
]);
|
|
7187
7219
|
table.push([
|
|
7188
7220
|
import_picocolors$1.default.yellow("Total"),
|
|
7189
7221
|
import_picocolors$1.default.yellow(formatNumber(totals.inputTokens)),
|
|
7190
7222
|
import_picocolors$1.default.yellow(formatNumber(totals.outputTokens)),
|
|
7191
|
-
import_picocolors$1.default.yellow(formatNumber(totals.
|
|
7223
|
+
import_picocolors$1.default.yellow(formatNumber(totals.cacheCreationTokens)),
|
|
7224
|
+
import_picocolors$1.default.yellow(formatNumber(totals.cacheReadTokens)),
|
|
7225
|
+
import_picocolors$1.default.yellow(formatNumber(totals.inputTokens + totals.outputTokens + totals.cacheCreationTokens + totals.cacheReadTokens)),
|
|
7192
7226
|
import_picocolors$1.default.yellow(formatCurrency(totals.totalCost))
|
|
7193
7227
|
]);
|
|
7194
7228
|
console.log(table.toString());
|
|
@@ -7219,10 +7253,14 @@ const sessionCommand = define({
|
|
|
7219
7253
|
const totals = sessionData.reduce((acc, data) => ({
|
|
7220
7254
|
inputTokens: acc.inputTokens + data.inputTokens,
|
|
7221
7255
|
outputTokens: acc.outputTokens + data.outputTokens,
|
|
7256
|
+
cacheCreationTokens: acc.cacheCreationTokens + data.cacheCreationTokens,
|
|
7257
|
+
cacheReadTokens: acc.cacheReadTokens + data.cacheReadTokens,
|
|
7222
7258
|
totalCost: acc.totalCost + data.totalCost
|
|
7223
7259
|
}), {
|
|
7224
7260
|
inputTokens: 0,
|
|
7225
7261
|
outputTokens: 0,
|
|
7262
|
+
cacheCreationTokens: 0,
|
|
7263
|
+
cacheReadTokens: 0,
|
|
7226
7264
|
totalCost: 0
|
|
7227
7265
|
});
|
|
7228
7266
|
if (ctx.values.json) {
|
|
@@ -7232,14 +7270,18 @@ const sessionCommand = define({
|
|
|
7232
7270
|
sessionId: data.sessionId,
|
|
7233
7271
|
inputTokens: data.inputTokens,
|
|
7234
7272
|
outputTokens: data.outputTokens,
|
|
7235
|
-
|
|
7273
|
+
cacheCreationTokens: data.cacheCreationTokens,
|
|
7274
|
+
cacheReadTokens: data.cacheReadTokens,
|
|
7275
|
+
totalTokens: data.inputTokens + data.outputTokens + data.cacheCreationTokens + data.cacheReadTokens,
|
|
7236
7276
|
totalCost: data.totalCost,
|
|
7237
7277
|
lastActivity: data.lastActivity
|
|
7238
7278
|
})),
|
|
7239
7279
|
totals: {
|
|
7240
7280
|
inputTokens: totals.inputTokens,
|
|
7241
7281
|
outputTokens: totals.outputTokens,
|
|
7242
|
-
|
|
7282
|
+
cacheCreationTokens: totals.cacheCreationTokens,
|
|
7283
|
+
cacheReadTokens: totals.cacheReadTokens,
|
|
7284
|
+
totalTokens: totals.inputTokens + totals.outputTokens + totals.cacheCreationTokens + totals.cacheReadTokens,
|
|
7243
7285
|
totalCost: totals.totalCost
|
|
7244
7286
|
}
|
|
7245
7287
|
};
|
|
@@ -7250,8 +7292,10 @@ const sessionCommand = define({
|
|
|
7250
7292
|
head: [
|
|
7251
7293
|
"Project",
|
|
7252
7294
|
"Session",
|
|
7253
|
-
"Input
|
|
7254
|
-
"Output
|
|
7295
|
+
"Input",
|
|
7296
|
+
"Output",
|
|
7297
|
+
"Cache Create",
|
|
7298
|
+
"Cache Read",
|
|
7255
7299
|
"Total Tokens",
|
|
7256
7300
|
"Cost (USD)",
|
|
7257
7301
|
"Last Activity"
|
|
@@ -7264,6 +7308,8 @@ const sessionCommand = define({
|
|
|
7264
7308
|
"right",
|
|
7265
7309
|
"right",
|
|
7266
7310
|
"right",
|
|
7311
|
+
"right",
|
|
7312
|
+
"right",
|
|
7267
7313
|
"left"
|
|
7268
7314
|
]
|
|
7269
7315
|
});
|
|
@@ -7279,7 +7325,9 @@ const sessionCommand = define({
|
|
|
7279
7325
|
sessionDisplay,
|
|
7280
7326
|
formatNumber(data.inputTokens),
|
|
7281
7327
|
formatNumber(data.outputTokens),
|
|
7282
|
-
formatNumber(data.
|
|
7328
|
+
formatNumber(data.cacheCreationTokens),
|
|
7329
|
+
formatNumber(data.cacheReadTokens),
|
|
7330
|
+
formatNumber(data.inputTokens + data.outputTokens + data.cacheCreationTokens + data.cacheReadTokens),
|
|
7283
7331
|
formatCurrency(data.totalCost),
|
|
7284
7332
|
data.lastActivity
|
|
7285
7333
|
]);
|
|
@@ -7290,6 +7338,8 @@ const sessionCommand = define({
|
|
|
7290
7338
|
"─".repeat(12),
|
|
7291
7339
|
"─".repeat(12),
|
|
7292
7340
|
"─".repeat(12),
|
|
7341
|
+
"─".repeat(12),
|
|
7342
|
+
"─".repeat(12),
|
|
7293
7343
|
"─".repeat(10),
|
|
7294
7344
|
"─".repeat(12)
|
|
7295
7345
|
]);
|
|
@@ -7298,7 +7348,9 @@ const sessionCommand = define({
|
|
|
7298
7348
|
"",
|
|
7299
7349
|
import_picocolors.default.yellow(formatNumber(totals.inputTokens)),
|
|
7300
7350
|
import_picocolors.default.yellow(formatNumber(totals.outputTokens)),
|
|
7301
|
-
import_picocolors.default.yellow(formatNumber(totals.
|
|
7351
|
+
import_picocolors.default.yellow(formatNumber(totals.cacheCreationTokens)),
|
|
7352
|
+
import_picocolors.default.yellow(formatNumber(totals.cacheReadTokens)),
|
|
7353
|
+
import_picocolors.default.yellow(formatNumber(totals.inputTokens + totals.outputTokens + totals.cacheCreationTokens + totals.cacheReadTokens)),
|
|
7302
7354
|
import_picocolors.default.yellow(formatCurrency(totals.totalCost)),
|
|
7303
7355
|
""
|
|
7304
7356
|
]);
|