tokmeter 0.1.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.
- tokmeter-0.1.0/.gitignore +13 -0
- tokmeter-0.1.0/LICENSE +21 -0
- tokmeter-0.1.0/PKG-INFO +170 -0
- tokmeter-0.1.0/README.md +145 -0
- tokmeter-0.1.0/dashboard.html +1996 -0
- tokmeter-0.1.0/pyproject.toml +51 -0
- tokmeter-0.1.0/tokmeter.py +885 -0
tokmeter-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 lich99
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
tokmeter-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tokmeter
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Local dashboard for Claude Code & Codex CLI token cost
|
|
5
|
+
Project-URL: Homepage, https://github.com/lich99/tokmeter
|
|
6
|
+
Project-URL: Repository, https://github.com/lich99/tokmeter
|
|
7
|
+
Project-URL: Issues, https://github.com/lich99/tokmeter/issues
|
|
8
|
+
Author: lich99
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: anthropic,claude-code,codex,cost,dashboard,openai,tokens
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Environment :: Web Environment
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
20
|
+
Classifier: Topic :: Software Development
|
|
21
|
+
Classifier: Topic :: Utilities
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: polars>=1.0
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# tokmeter
|
|
27
|
+
|
|
28
|
+
Local dashboard for what Claude Code and Codex CLI are actually costing you.
|
|
29
|
+
|
|
30
|
+
Reads `~/.claude/projects/**/*.jsonl` and `~/.codex/sessions/**/*.jsonl`
|
|
31
|
+
directly off your disk, aggregates with polars, serves a single-file HTML on
|
|
32
|
+
`localhost:8765`. No auth, no upload, no telemetry.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
uvx tokmeter
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
That's it. Opens the browser. `Ctrl-C` to exit.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
| | command |
|
|
45
|
+
|---|---|
|
|
46
|
+
| **uv (recommended)** | `uvx tokmeter` |
|
|
47
|
+
| **uv, persistent** | `uv tool install tokmeter` |
|
|
48
|
+
| **single-file mode** | `curl -O https://raw.githubusercontent.com/lich99/tokmeter/main/tokmeter.py && uv run tokmeter.py` |
|
|
49
|
+
| pipx | `pipx install tokmeter` |
|
|
50
|
+
| pip | `pip install tokmeter` |
|
|
51
|
+
|
|
52
|
+
`uv run tokmeter.py` works without a venv — the script declares its
|
|
53
|
+
dependency inline via [PEP 723](https://peps.python.org/pep-0723/).
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
tokmeter --port 8866 # change port
|
|
57
|
+
tokmeter --host 0.0.0.0 # bind to LAN
|
|
58
|
+
tokmeter --no-open # don't auto-open browser
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`TOKMETER_PORT` env var is equivalent to `--port`.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## What it shows
|
|
66
|
+
|
|
67
|
+
- **Both Claude Code and Codex CLI** in one chart, switchable per source.
|
|
68
|
+
- **Real-time**: a 30 s background rescan picks up new sessions
|
|
69
|
+
(mtime + size delta only — minimal I/O); the browser polls every 60 s.
|
|
70
|
+
- **Arbitrary range**: From / To picker plus presets `1H / 5H / 24H / 7D / 30D / All`.
|
|
71
|
+
- **Adaptive bucketing**: `Auto` picks `1m / 5m / 15m / 30m / 1h / 6h / 1d`
|
|
72
|
+
based on window width; can be forced.
|
|
73
|
+
- **Three timezones**: `America/New_York (ET)` / Local / UTC.
|
|
74
|
+
- **Cost-over-time** stack: by role (main vs subagent) or by token tier.
|
|
75
|
+
- **Cost split** donut: input / output / cache-write 5m / cache-write 1h /
|
|
76
|
+
cache-read for Claude; cached / output text / reasoning / input for Codex.
|
|
77
|
+
- **By project / by model** breakdowns.
|
|
78
|
+
- **Buckets table**: 100k+ rows scrolled virtually, jump-to-time supported.
|
|
79
|
+
- **Gaps toggle**: `Fill` (zero-pads empty buckets) / `Skip` (sparse only).
|
|
80
|
+
- **Path de-mangling**: `-Users-nek0-Code-Claw-proxy` → `~/Code/Claw_proxy`
|
|
81
|
+
by walking the filesystem to disambiguate the `_` → `-` collision.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Pricing rules
|
|
86
|
+
|
|
87
|
+
Anthropic published list prices (USD / MTok):
|
|
88
|
+
|
|
89
|
+
| family | input | output | cache w 5m | cache w 1h | cache read |
|
|
90
|
+
|---|---:|---:|---:|---:|---:|
|
|
91
|
+
| Opus 4.5 / 4.6 / 4.7 | 5.00 | 25.00 | 6.25 | 10.00 | 0.50 |
|
|
92
|
+
| Opus 4 / 4.1 | 15.00 | 75.00 | 18.75 | 30.00 | 1.50 |
|
|
93
|
+
| Sonnet 4 / 4.5 / 4.6 | 3.00 | 15.00 | 3.75 | 6.00 | 0.30 |
|
|
94
|
+
| Haiku 4.5 | 1.00 | 5.00 | 1.25 | 2.00 | 0.10 |
|
|
95
|
+
| Haiku 3.5 | 0.80 | 4.00 | 1.00 | 1.60 | 0.08 |
|
|
96
|
+
|
|
97
|
+
Token figures come from
|
|
98
|
+
`usage.cache_creation.ephemeral_5m_input_tokens` and `ephemeral_1h_input_tokens`
|
|
99
|
+
— the real billing buckets that `ccusage` and friends drop, leading them to
|
|
100
|
+
under-count by 10–30 % on heavy cache-write workloads.
|
|
101
|
+
|
|
102
|
+
OpenAI published list prices for Codex's GPT-5.x family are bundled too,
|
|
103
|
+
including the **>272 K long-context tier** (2× input/cached, 1.5× output)
|
|
104
|
+
and the **Priority Processing** multipliers when Codex Fast is on. The
|
|
105
|
+
service tier for each call is read from `~/.codex/logs_2.sqlite` because
|
|
106
|
+
`config.toml` only sets the default and many users toggle it mid-thread.
|
|
107
|
+
|
|
108
|
+
> If you're on the Anthropic Max plan or an OpenAI ChatGPT plan, your real
|
|
109
|
+
> bill is the flat subscription. The dollars here are the **equivalent
|
|
110
|
+
> standard-API cost** of the same workload — useful for comparing intensity
|
|
111
|
+
> across days, projects, or the two CLIs. Not your actual invoice.
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## API
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
GET / dashboard HTML
|
|
119
|
+
GET /api/refresh force rescan, returns {scanned,changed,removed}
|
|
120
|
+
GET /api/aggregate?from=<ms>&to=<ms>&granularity=<g>&tz=<tz>&gaps=<gaps>&source=<src>
|
|
121
|
+
aggregated buckets for the window
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
- `granularity`: `1m | 5m | 15m | 30m | 1h | 6h | 1d`
|
|
125
|
+
- `tz`: `ET | UTC | LOCAL` (LOCAL is normalized client-side; server treats it as UTC)
|
|
126
|
+
- `gaps`: `fill` (zero-pad empty buckets, default) | `skip` (omit empties)
|
|
127
|
+
- `source`: `cc` | `codex` | `all`
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
curl http://127.0.0.1:8765/api/refresh
|
|
131
|
+
curl "http://127.0.0.1:8765/api/aggregate?from=$(($(date +%s)*1000-18000000))&to=$(($(date +%s)*1000))&granularity=15m&tz=ET&source=all"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Files
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
tokmeter/
|
|
140
|
+
├── tokmeter.py HTTP server + scanner + polars aggregation
|
|
141
|
+
├── dashboard.html single-file frontend
|
|
142
|
+
├── pyproject.toml
|
|
143
|
+
├── LICENSE (MIT)
|
|
144
|
+
└── README.md
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`dashboard.html` is re-read from disk on every `GET /` — **edit CSS, refresh
|
|
148
|
+
the browser, no restart needed** during development.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Known limits
|
|
153
|
+
|
|
154
|
+
- **`<synthetic>` rows are skipped.** Claude Code emits these as
|
|
155
|
+
zero-token placeholders when you interrupt mid-stream or a hook short-
|
|
156
|
+
circuits. Filtered at parse time, not counted.
|
|
157
|
+
- **Agent SDK / OpenClaw / NanoClaw with `CLAUDE_CODE_OAUTH_TOKEN`** don't
|
|
158
|
+
write to `~/.claude/projects/` — invisible to tokmeter, visible only in
|
|
159
|
+
the Anthropic Console.
|
|
160
|
+
- **`claude -p` with `ANTHROPIC_API_KEY` set or `--bare`** logs locally but
|
|
161
|
+
bills through the API account, not your Max plan.
|
|
162
|
+
- 1 M context windows on Opus 4.7 / 4.6 / Sonnet 4.6 are billed at standard
|
|
163
|
+
rates (no long-context surcharge); Codex GPT-5.x crossing 272 K tokens
|
|
164
|
+
triggers the long-context tier and is priced accordingly.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## License
|
|
169
|
+
|
|
170
|
+
MIT. See [LICENSE](./LICENSE).
|
tokmeter-0.1.0/README.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# tokmeter
|
|
2
|
+
|
|
3
|
+
Local dashboard for what Claude Code and Codex CLI are actually costing you.
|
|
4
|
+
|
|
5
|
+
Reads `~/.claude/projects/**/*.jsonl` and `~/.codex/sessions/**/*.jsonl`
|
|
6
|
+
directly off your disk, aggregates with polars, serves a single-file HTML on
|
|
7
|
+
`localhost:8765`. No auth, no upload, no telemetry.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
uvx tokmeter
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
That's it. Opens the browser. `Ctrl-C` to exit.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Install
|
|
18
|
+
|
|
19
|
+
| | command |
|
|
20
|
+
|---|---|
|
|
21
|
+
| **uv (recommended)** | `uvx tokmeter` |
|
|
22
|
+
| **uv, persistent** | `uv tool install tokmeter` |
|
|
23
|
+
| **single-file mode** | `curl -O https://raw.githubusercontent.com/lich99/tokmeter/main/tokmeter.py && uv run tokmeter.py` |
|
|
24
|
+
| pipx | `pipx install tokmeter` |
|
|
25
|
+
| pip | `pip install tokmeter` |
|
|
26
|
+
|
|
27
|
+
`uv run tokmeter.py` works without a venv — the script declares its
|
|
28
|
+
dependency inline via [PEP 723](https://peps.python.org/pep-0723/).
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
tokmeter --port 8866 # change port
|
|
32
|
+
tokmeter --host 0.0.0.0 # bind to LAN
|
|
33
|
+
tokmeter --no-open # don't auto-open browser
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`TOKMETER_PORT` env var is equivalent to `--port`.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## What it shows
|
|
41
|
+
|
|
42
|
+
- **Both Claude Code and Codex CLI** in one chart, switchable per source.
|
|
43
|
+
- **Real-time**: a 30 s background rescan picks up new sessions
|
|
44
|
+
(mtime + size delta only — minimal I/O); the browser polls every 60 s.
|
|
45
|
+
- **Arbitrary range**: From / To picker plus presets `1H / 5H / 24H / 7D / 30D / All`.
|
|
46
|
+
- **Adaptive bucketing**: `Auto` picks `1m / 5m / 15m / 30m / 1h / 6h / 1d`
|
|
47
|
+
based on window width; can be forced.
|
|
48
|
+
- **Three timezones**: `America/New_York (ET)` / Local / UTC.
|
|
49
|
+
- **Cost-over-time** stack: by role (main vs subagent) or by token tier.
|
|
50
|
+
- **Cost split** donut: input / output / cache-write 5m / cache-write 1h /
|
|
51
|
+
cache-read for Claude; cached / output text / reasoning / input for Codex.
|
|
52
|
+
- **By project / by model** breakdowns.
|
|
53
|
+
- **Buckets table**: 100k+ rows scrolled virtually, jump-to-time supported.
|
|
54
|
+
- **Gaps toggle**: `Fill` (zero-pads empty buckets) / `Skip` (sparse only).
|
|
55
|
+
- **Path de-mangling**: `-Users-nek0-Code-Claw-proxy` → `~/Code/Claw_proxy`
|
|
56
|
+
by walking the filesystem to disambiguate the `_` → `-` collision.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Pricing rules
|
|
61
|
+
|
|
62
|
+
Anthropic published list prices (USD / MTok):
|
|
63
|
+
|
|
64
|
+
| family | input | output | cache w 5m | cache w 1h | cache read |
|
|
65
|
+
|---|---:|---:|---:|---:|---:|
|
|
66
|
+
| Opus 4.5 / 4.6 / 4.7 | 5.00 | 25.00 | 6.25 | 10.00 | 0.50 |
|
|
67
|
+
| Opus 4 / 4.1 | 15.00 | 75.00 | 18.75 | 30.00 | 1.50 |
|
|
68
|
+
| Sonnet 4 / 4.5 / 4.6 | 3.00 | 15.00 | 3.75 | 6.00 | 0.30 |
|
|
69
|
+
| Haiku 4.5 | 1.00 | 5.00 | 1.25 | 2.00 | 0.10 |
|
|
70
|
+
| Haiku 3.5 | 0.80 | 4.00 | 1.00 | 1.60 | 0.08 |
|
|
71
|
+
|
|
72
|
+
Token figures come from
|
|
73
|
+
`usage.cache_creation.ephemeral_5m_input_tokens` and `ephemeral_1h_input_tokens`
|
|
74
|
+
— the real billing buckets that `ccusage` and friends drop, leading them to
|
|
75
|
+
under-count by 10–30 % on heavy cache-write workloads.
|
|
76
|
+
|
|
77
|
+
OpenAI published list prices for Codex's GPT-5.x family are bundled too,
|
|
78
|
+
including the **>272 K long-context tier** (2× input/cached, 1.5× output)
|
|
79
|
+
and the **Priority Processing** multipliers when Codex Fast is on. The
|
|
80
|
+
service tier for each call is read from `~/.codex/logs_2.sqlite` because
|
|
81
|
+
`config.toml` only sets the default and many users toggle it mid-thread.
|
|
82
|
+
|
|
83
|
+
> If you're on the Anthropic Max plan or an OpenAI ChatGPT plan, your real
|
|
84
|
+
> bill is the flat subscription. The dollars here are the **equivalent
|
|
85
|
+
> standard-API cost** of the same workload — useful for comparing intensity
|
|
86
|
+
> across days, projects, or the two CLIs. Not your actual invoice.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## API
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
GET / dashboard HTML
|
|
94
|
+
GET /api/refresh force rescan, returns {scanned,changed,removed}
|
|
95
|
+
GET /api/aggregate?from=<ms>&to=<ms>&granularity=<g>&tz=<tz>&gaps=<gaps>&source=<src>
|
|
96
|
+
aggregated buckets for the window
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
- `granularity`: `1m | 5m | 15m | 30m | 1h | 6h | 1d`
|
|
100
|
+
- `tz`: `ET | UTC | LOCAL` (LOCAL is normalized client-side; server treats it as UTC)
|
|
101
|
+
- `gaps`: `fill` (zero-pad empty buckets, default) | `skip` (omit empties)
|
|
102
|
+
- `source`: `cc` | `codex` | `all`
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
curl http://127.0.0.1:8765/api/refresh
|
|
106
|
+
curl "http://127.0.0.1:8765/api/aggregate?from=$(($(date +%s)*1000-18000000))&to=$(($(date +%s)*1000))&granularity=15m&tz=ET&source=all"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Files
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
tokmeter/
|
|
115
|
+
├── tokmeter.py HTTP server + scanner + polars aggregation
|
|
116
|
+
├── dashboard.html single-file frontend
|
|
117
|
+
├── pyproject.toml
|
|
118
|
+
├── LICENSE (MIT)
|
|
119
|
+
└── README.md
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
`dashboard.html` is re-read from disk on every `GET /` — **edit CSS, refresh
|
|
123
|
+
the browser, no restart needed** during development.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Known limits
|
|
128
|
+
|
|
129
|
+
- **`<synthetic>` rows are skipped.** Claude Code emits these as
|
|
130
|
+
zero-token placeholders when you interrupt mid-stream or a hook short-
|
|
131
|
+
circuits. Filtered at parse time, not counted.
|
|
132
|
+
- **Agent SDK / OpenClaw / NanoClaw with `CLAUDE_CODE_OAUTH_TOKEN`** don't
|
|
133
|
+
write to `~/.claude/projects/` — invisible to tokmeter, visible only in
|
|
134
|
+
the Anthropic Console.
|
|
135
|
+
- **`claude -p` with `ANTHROPIC_API_KEY` set or `--bare`** logs locally but
|
|
136
|
+
bills through the API account, not your Max plan.
|
|
137
|
+
- 1 M context windows on Opus 4.7 / 4.6 / Sonnet 4.6 are billed at standard
|
|
138
|
+
rates (no long-context surcharge); Codex GPT-5.x crossing 272 K tokens
|
|
139
|
+
triggers the long-context tier and is priced accordingly.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## License
|
|
144
|
+
|
|
145
|
+
MIT. See [LICENSE](./LICENSE).
|