cctrack 0.4.1__tar.gz → 0.6.0__tar.gz
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.
- cctrack-0.6.0/CLAUDE.md +54 -0
- {cctrack-0.4.1 → cctrack-0.6.0}/PKG-INFO +32 -11
- {cctrack-0.4.1 → cctrack-0.6.0}/README.md +33 -12
- {cctrack-0.4.1 → cctrack-0.6.0}/pyproject.toml +1 -1
- {cctrack-0.4.1 → cctrack-0.6.0}/src/cctrack/__init__.py +573 -274
- {cctrack-0.4.1 → cctrack-0.6.0}/tests/test_cctrack.py +143 -5
- {cctrack-0.4.1 → cctrack-0.6.0}/tests/test_hook_reporting.py +510 -136
- cctrack-0.4.1/CLAUDE.md +0 -48
- {cctrack-0.4.1 → cctrack-0.6.0}/.github/workflows/ci.yml +0 -0
- {cctrack-0.4.1 → cctrack-0.6.0}/.github/workflows/publish.yml +0 -0
- {cctrack-0.4.1 → cctrack-0.6.0}/.gitignore +0 -0
- {cctrack-0.4.1 → cctrack-0.6.0}/LICENSE +0 -0
- {cctrack-0.4.1 → cctrack-0.6.0}/src/cctrack/__main__.py +0 -0
- {cctrack-0.4.1 → cctrack-0.6.0}/tests/test_hook.py +0 -0
cctrack-0.6.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
cctrack-py is a zero-dependency Python CLI that scans Claude Code JSONL log files and reports token usage and estimated cost. It's a Python port of the Go-based [cctrack dashboard](https://github.com/ksred/cctrack), stripped down to a single command that parses logs and prints a cost report.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Install in development mode
|
|
13
|
+
uv pip install -e .
|
|
14
|
+
|
|
15
|
+
# Run the tool
|
|
16
|
+
python -m cctrack
|
|
17
|
+
# or after install:
|
|
18
|
+
cctrack
|
|
19
|
+
|
|
20
|
+
# Run all tests
|
|
21
|
+
python -m pytest tests/
|
|
22
|
+
|
|
23
|
+
# Run a single test
|
|
24
|
+
python -m pytest tests/test_cctrack.py::test_name
|
|
25
|
+
|
|
26
|
+
# Build distribution
|
|
27
|
+
uv build
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Architecture
|
|
31
|
+
|
|
32
|
+
This is a single-module CLI tool. All logic lives in `src/cctrack/__init__.py`:
|
|
33
|
+
|
|
34
|
+
1. **Rate card** (`RATES`, `get_rates`, `calculate_cost`, `is_known_model`) - Model-to-price mapping using prefix matching. Order matters: longer/more-specific prefixes must come first (the legacy `claude-opus-4` 15/75 entry must stay below every `claude-opus-4-x`). Unknown models fall back to Sonnet rates and are flagged with `?` in the report. `get_rates`/`calculate_cost` take the usage date so time-limited `intro` pricing (e.g. Sonnet 5 through 2026-08-31) applies to past usage correctly.
|
|
35
|
+
1a. **Energy model** (`ENERGY_WH_PER_MTOK`, `estimate_energy_wh`) - Opt-in (`--energy`) order-of-magnitude estimate keyed off each rate entry's `tier`. Deliberately NOT a function of price: both cache-write TTLs use one figure because a 1h write costs more money but the same compute.
|
|
36
|
+
2. **File discovery** (`default_dirs`, `discover_files`) - Walks `~/.claude/projects/` and `~/.sandy/sandboxes/` for `.jsonl` files.
|
|
37
|
+
3. **Remote aggregation** (`fetch_remote_jsonl`, `parse_remote_events`, `fetch_remote_hook_data`, `parse_remote_hook_data`) - SSHs to hosts, cats all JSONL logs plus statusline hook data (statusline files, monthly summaries, session baselines) with file separators, parses locally.
|
|
38
|
+
3a. **Hook parsing** (`parse_hook_rows`, `compute_hook_deltas`, `_cost_increment`) - The hook is authoritative for **cost only**. Its `input_tokens`/`output_tokens`/`cache_*` fields are context-window SNAPSHOTS (`input_tokens` ≈ `cache_read + cache_write`; `output_tokens` is just the last message's), not cumulative — never use them for token counts. `cost_usd` is a per-session running total, but it RESTARTS on resume/compaction and a render can report 0, so deltas walk every row chronologically and treat a meaningful drop as a restart.
|
|
39
|
+
4. **JSONL parsing** (`parse_lines`, `parse_events`, `dedup_events`) - Extracts `assistant` events with token usage. Deduplicates by `requestId` across all of a host's files (last event wins) — resumed sessions (`--resume`/`--continue`) repeat events with the same `requestId` in new files. Events without `requestId` are never deduped.
|
|
40
|
+
5. **Aggregation** (`aggregate`) - Buckets events into daily and monthly summaries with token counts and costs.
|
|
41
|
+
6. **Output** (`print_report`) - Prints current month-to-date summary with projections, daily breakdown, and previous month summaries. Cost is composed **per source** (one source per machine): hook cost where a source has statusline coverage, accuracy-factor-adjusted JSONL cost otherwise, summed per date. The accuracy factor is measured per source over dates strictly after that source's hook install day.
|
|
42
|
+
|
|
43
|
+
Entry point: `cctrack:main` (registered in `pyproject.toml` as a console script).
|
|
44
|
+
|
|
45
|
+
## Key Design Decisions
|
|
46
|
+
|
|
47
|
+
- Zero external dependencies - stdlib only (json, argparse, subprocess, etc.)
|
|
48
|
+
- Deduplication is global per host by `requestId` (last wins) - resumed sessions replay history into new files and must not double count. Cross-host `requestId` collisions can't occur (distinct API calls).
|
|
49
|
+
- Hook data is authoritative for **cost only**; every token count comes from the JSONL logs. Never mix the two in one figure - the hook's token fields are snapshots and would double count against JSONL cache columns.
|
|
50
|
+
- Never let one machine's hook coverage suppress another machine's JSONL cost - compose per source.
|
|
51
|
+
- Cumulative counters from the hook are not monotonic. Any code differencing `cost_usd` must handle restarts (resume/compaction) and zero-valued renders, or whole days silently vanish.
|
|
52
|
+
- `session-baselines.json` carries each session's rolled-up cumulative across the 90-day retention boundary so straddling sessions aren't re-counted from zero.
|
|
53
|
+
- Build system is Hatch (`hatchling`)
|
|
54
|
+
- Requires Python 3.10+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cctrack
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: Claude Code cost tracker — scans JSONL logs and reports token usage + estimated cost
|
|
5
5
|
Project-URL: Homepage, https://github.com/rappdw/cctrack
|
|
6
6
|
Project-URL: Repository, https://github.com/rappdw/cctrack
|
|
@@ -98,18 +98,39 @@ cctrack --install-hook --remote dgx macbook-air
|
|
|
98
98
|
|
|
99
99
|
## Rate card
|
|
100
100
|
|
|
101
|
-
Prices per million tokens, from [Anthropic's pricing page](https://
|
|
101
|
+
Prices per million tokens, from [Anthropic's pricing page](https://platform.claude.com/docs/en/about-claude/pricing). Cache writes are priced per TTL: 5-minute at 1.25× input, 1-hour at 2× input.
|
|
102
102
|
|
|
103
|
-
| Model | Input | Output | Cache Read | Cache Write |
|
|
104
|
-
|
|
105
|
-
|
|
|
106
|
-
| Opus 4 / 4.
|
|
107
|
-
|
|
|
108
|
-
|
|
|
109
|
-
|
|
|
110
|
-
| Haiku
|
|
103
|
+
| Model | Input | Output | Cache Read | Cache Write 5m | Cache Write 1h |
|
|
104
|
+
|---|---|---|---|---|---|
|
|
105
|
+
| Fable 5 / Mythos 5 | $10.00 | $50.00 | $1.00 | $12.50 | $20.00 |
|
|
106
|
+
| Opus 5 / 4.8 / 4.7 / 4.6 / 4.5 | $5.00 | $25.00 | $0.50 | $6.25 | $10.00 |
|
|
107
|
+
| Opus 4 / 4.1 | $15.00 | $75.00 | $1.50 | $18.75 | $30.00 |
|
|
108
|
+
| Sonnet 5 (through 2026-08-31) | $2.00 | $10.00 | $0.20 | $2.50 | $4.00 |
|
|
109
|
+
| Sonnet 5 (from 2026-09-01) / 4.x / 3.7 | $3.00 | $15.00 | $0.30 | $3.75 | $6.00 |
|
|
110
|
+
| Haiku 4.x | $1.00 | $5.00 | $0.10 | $1.25 | $2.00 |
|
|
111
|
+
| Haiku 3.5 | $0.80 | $4.00 | $0.08 | $1.00 | $1.60 |
|
|
112
|
+
| Haiku 3 | $0.25 | $1.25 | $0.03 | $0.30 | $0.50 |
|
|
111
113
|
|
|
112
|
-
|
|
114
|
+
Usage is priced with the rates in effect on the day it happened, so time-limited introductory pricing is applied correctly to past usage.
|
|
115
|
+
|
|
116
|
+
Unknown models fall back to Sonnet rates and are flagged with `?` in the report's Model column — a prompt to update the rate card rather than a silent guess.
|
|
117
|
+
|
|
118
|
+
## Energy estimate
|
|
119
|
+
|
|
120
|
+
`cctrack --energy` adds an estimated inference energy column (Wh/kWh):
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
cctrack --energy
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
This is a **rough estimate, not a measurement** — Anthropic does not publish per-token energy figures or model sizes. It is modelled from logged tokens using the published full-stack per-prompt figures the major labs have disclosed (Google: 0.24 Wh median Gemini text prompt; OpenAI: ~0.34 Wh average ChatGPT query — both include accelerator, host, cooling and idle capacity), apportioned across token classes by relative compute cost and scaled by model tier:
|
|
127
|
+
|
|
128
|
+
- **output tokens dominate** — decode is sequential and memory-bandwidth bound
|
|
129
|
+
- **input and cache writes** are prefill: parallel, far cheaper per token
|
|
130
|
+
- **cache reads** skip prefill entirely (~0.1× input)
|
|
131
|
+
- both cache-write TTLs use the same figure — a 1-hour write costs more money but the same compute
|
|
132
|
+
|
|
133
|
+
Treat results as ±1 order of magnitude. It covers datacenter inference only: not model training, and not your own machine. Scale the whole model with `CCTRACK_ENERGY_SCALE=1.5` if you have better numbers for your workload.
|
|
113
134
|
|
|
114
135
|
## Origins
|
|
115
136
|
|
|
@@ -73,18 +73,39 @@ cctrack --install-hook --remote dgx macbook-air
|
|
|
73
73
|
|
|
74
74
|
## Rate card
|
|
75
75
|
|
|
76
|
-
Prices per million tokens, from [Anthropic's pricing page](https://
|
|
77
|
-
|
|
78
|
-
| Model | Input | Output | Cache Read | Cache Write |
|
|
79
|
-
|
|
80
|
-
|
|
|
81
|
-
| Opus 4 / 4.
|
|
82
|
-
|
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
| Haiku
|
|
86
|
-
|
|
87
|
-
|
|
76
|
+
Prices per million tokens, from [Anthropic's pricing page](https://platform.claude.com/docs/en/about-claude/pricing). Cache writes are priced per TTL: 5-minute at 1.25× input, 1-hour at 2× input.
|
|
77
|
+
|
|
78
|
+
| Model | Input | Output | Cache Read | Cache Write 5m | Cache Write 1h |
|
|
79
|
+
|---|---|---|---|---|---|
|
|
80
|
+
| Fable 5 / Mythos 5 | $10.00 | $50.00 | $1.00 | $12.50 | $20.00 |
|
|
81
|
+
| Opus 5 / 4.8 / 4.7 / 4.6 / 4.5 | $5.00 | $25.00 | $0.50 | $6.25 | $10.00 |
|
|
82
|
+
| Opus 4 / 4.1 | $15.00 | $75.00 | $1.50 | $18.75 | $30.00 |
|
|
83
|
+
| Sonnet 5 (through 2026-08-31) | $2.00 | $10.00 | $0.20 | $2.50 | $4.00 |
|
|
84
|
+
| Sonnet 5 (from 2026-09-01) / 4.x / 3.7 | $3.00 | $15.00 | $0.30 | $3.75 | $6.00 |
|
|
85
|
+
| Haiku 4.x | $1.00 | $5.00 | $0.10 | $1.25 | $2.00 |
|
|
86
|
+
| Haiku 3.5 | $0.80 | $4.00 | $0.08 | $1.00 | $1.60 |
|
|
87
|
+
| Haiku 3 | $0.25 | $1.25 | $0.03 | $0.30 | $0.50 |
|
|
88
|
+
|
|
89
|
+
Usage is priced with the rates in effect on the day it happened, so time-limited introductory pricing is applied correctly to past usage.
|
|
90
|
+
|
|
91
|
+
Unknown models fall back to Sonnet rates and are flagged with `?` in the report's Model column — a prompt to update the rate card rather than a silent guess.
|
|
92
|
+
|
|
93
|
+
## Energy estimate
|
|
94
|
+
|
|
95
|
+
`cctrack --energy` adds an estimated inference energy column (Wh/kWh):
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
cctrack --energy
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
This is a **rough estimate, not a measurement** — Anthropic does not publish per-token energy figures or model sizes. It is modelled from logged tokens using the published full-stack per-prompt figures the major labs have disclosed (Google: 0.24 Wh median Gemini text prompt; OpenAI: ~0.34 Wh average ChatGPT query — both include accelerator, host, cooling and idle capacity), apportioned across token classes by relative compute cost and scaled by model tier:
|
|
102
|
+
|
|
103
|
+
- **output tokens dominate** — decode is sequential and memory-bandwidth bound
|
|
104
|
+
- **input and cache writes** are prefill: parallel, far cheaper per token
|
|
105
|
+
- **cache reads** skip prefill entirely (~0.1× input)
|
|
106
|
+
- both cache-write TTLs use the same figure — a 1-hour write costs more money but the same compute
|
|
107
|
+
|
|
108
|
+
Treat results as ±1 order of magnitude. It covers datacenter inference only: not model training, and not your own machine. Scale the whole model with `CCTRACK_ENERGY_SCALE=1.5` if you have better numbers for your workload.
|
|
88
109
|
|
|
89
110
|
## Origins
|
|
90
111
|
|