statusline-toolkit 1.0.0__py3-none-any.whl
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.
- statusline_toolkit-1.0.0.dist-info/METADATA +312 -0
- statusline_toolkit-1.0.0.dist-info/RECORD +7 -0
- statusline_toolkit-1.0.0.dist-info/WHEEL +5 -0
- statusline_toolkit-1.0.0.dist-info/entry_points.txt +2 -0
- statusline_toolkit-1.0.0.dist-info/licenses/LICENSE +21 -0
- statusline_toolkit-1.0.0.dist-info/top_level.txt +1 -0
- statusline_toolkit.py +1077 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: statusline-toolkit
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A small, dependency-free CLI for inspecting Claude Code's statusLine JSON payload, with currency conversion, cost tracking, and an HTML dashboard.
|
|
5
|
+
Author: gungunfebrianza
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/gungunfebrianza/statusline-toolkit
|
|
8
|
+
Project-URL: Changelog, https://github.com/gungunfebrianza/statusline-toolkit/blob/main/CHANGELOG.md
|
|
9
|
+
Keywords: claude-code,statusline,cli
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Topic :: Utilities
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# statusline-toolkit
|
|
22
|
+
|
|
23
|
+
[](https://github.com/gungunfebrianza/statusline-toolkit/actions/workflows/test.yml)
|
|
24
|
+
|
|
25
|
+
A small, dependency-free Python CLI for Claude Code's [`statusLine`](https://code.claude.com/docs/en/statusline)
|
|
26
|
+
JSON payload. Prints a color-coded one-line summary, with optional currency
|
|
27
|
+
conversion, cost tracking, and an HTML dashboard — all local, all plain
|
|
28
|
+
JSON files you own.
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
[Claude Sonnet 5] (my-project) [####------] 42% | $0.1234 (~Rp 2.011) | +156/-23 | 45s | $9.87/hr | 5h: 24% 7d: 41%
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Works identically on **Linux**, **macOS**, and **Windows**. [MIT licensed](LICENSE).
|
|
35
|
+
|
|
36
|
+
## Contents
|
|
37
|
+
|
|
38
|
+
- [Quick start](#quick-start)
|
|
39
|
+
- [Usage](#usage)
|
|
40
|
+
- [Reading the summary line](#reading-the-summary-line)
|
|
41
|
+
- [Installing as your Claude Code status line](#installing-as-your-claude-code-status-line)
|
|
42
|
+
- [Currency conversion](#currency-conversion)
|
|
43
|
+
- [Cost tracking: history, stats, and a dashboard](#cost-tracking-history-stats-and-a-dashboard)
|
|
44
|
+
- [Personal defaults file](#personal-defaults-file)
|
|
45
|
+
- [Plugin segments](#plugin-segments)
|
|
46
|
+
- [Project layout](#project-layout)
|
|
47
|
+
- [Tests](#tests)
|
|
48
|
+
- [Troubleshooting](#troubleshooting)
|
|
49
|
+
|
|
50
|
+
## Quick start
|
|
51
|
+
|
|
52
|
+
Requires Python 3.9+ (`python3` on Linux/macOS, `py` on Windows). Two ways to get it:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Option A: pip/pipx, no clone needed
|
|
56
|
+
pipx install git+https://github.com/gungunfebrianza/statusline-toolkit.git
|
|
57
|
+
statusline-toolkit --setup
|
|
58
|
+
|
|
59
|
+
# Option B: clone and run directly — no install step at all
|
|
60
|
+
git clone https://github.com/gungunfebrianza/statusline-toolkit.git
|
|
61
|
+
cd statusline-toolkit
|
|
62
|
+
python statusline_toolkit.py --input sample_statusline_data.json --idr
|
|
63
|
+
python statusline_toolkit.py --setup
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Both are equivalent — it's zero-dependency either way. The rest of this
|
|
67
|
+
README uses `python statusline_toolkit.py ...`; swap in `statusline-toolkit
|
|
68
|
+
...` if you installed via pip/pipx.
|
|
69
|
+
|
|
70
|
+
## Usage
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# Live: pipe whatever JSON Claude Code sends on stdin
|
|
74
|
+
some_producer_of_json | python statusline_toolkit.py
|
|
75
|
+
|
|
76
|
+
# Offline: inspect a saved payload
|
|
77
|
+
python statusline_toolkit.py --input sample_statusline_data.json --all # full JSON
|
|
78
|
+
python statusline_toolkit.py --input sample_statusline_data.json --list # just the field names
|
|
79
|
+
python statusline_toolkit.py --input sample_statusline_data.json --field cost.total_cost_usd
|
|
80
|
+
|
|
81
|
+
# Currency conversion (any ISO 4217 code)
|
|
82
|
+
python statusline_toolkit.py --input sample_statusline_data.json --currency EUR
|
|
83
|
+
|
|
84
|
+
# No colors (for logging, or a terminal that mangles ANSI)
|
|
85
|
+
python statusline_toolkit.py --input sample_statusline_data.json --no-color
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Flag reference
|
|
89
|
+
|
|
90
|
+
| Flag | Description |
|
|
91
|
+
|---|---|
|
|
92
|
+
| `-i, --input PATH` | Read the JSON payload from a file instead of stdin. |
|
|
93
|
+
| `-a, --all` | Print the entire payload as formatted JSON. |
|
|
94
|
+
| `-l, --list` | List every available field path, without values. |
|
|
95
|
+
| `-f, --field DOT.PATH` | Print just this field; repeatable. |
|
|
96
|
+
| `--currency CODE` | Show cost converted to `CODE` (e.g. `EUR`, `JPY`, `IDR`). |
|
|
97
|
+
| `--idr` | Shorthand for `--currency IDR` (backward compatible). |
|
|
98
|
+
| `--rate RATE` | Override the conversion rate for this run only. |
|
|
99
|
+
| `--rate-file PATH` | Use a different exchange-rate file. |
|
|
100
|
+
| `--no-color` | Disable ANSI colors (also honors `NO_COLOR`). |
|
|
101
|
+
| `--width N` | Override the detected terminal width for adaptive layout. |
|
|
102
|
+
| `--no-adapt` | Never drop segments to fit the width — always the full line. |
|
|
103
|
+
| `--setup` | Install as your Claude Code `statusLine`, then exit. |
|
|
104
|
+
| `-y, --yes` | With `--setup`, skip the overwrite confirmation. |
|
|
105
|
+
| `--settings-file PATH` | With `--setup`, target a different `settings.json`. |
|
|
106
|
+
| `--track` | Record this session's cost to history, for `--stats`/`--dashboard`. |
|
|
107
|
+
| `--stats` | Print a cost report from tracked history, then exit. |
|
|
108
|
+
| `--by-project` / `--by-model` | With `--stats`, group by project/model instead of day. |
|
|
109
|
+
| `--history-file PATH` | Use a different history file. |
|
|
110
|
+
| `--dashboard` | Render an HTML usage dashboard from tracked history, then exit. |
|
|
111
|
+
| `--dashboard-file PATH` | Where to write the dashboard (default: next to the history file). |
|
|
112
|
+
| `--open` | With `--dashboard`, open it in your browser. |
|
|
113
|
+
| `--config PATH` | Use a different [personal defaults file](#personal-defaults-file). |
|
|
114
|
+
| `--plugins-dir PATH` / `--no-plugins` | Custom [plugin](#plugin-segments) directory / skip loading plugins. |
|
|
115
|
+
| `--version` | Print the version and exit. |
|
|
116
|
+
|
|
117
|
+
Run `--help` any time for the same reference from the source.
|
|
118
|
+
|
|
119
|
+
## Reading the summary line
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
[Claude Sonnet 5] (my-project) [####------] 42% | $0.1234 (~Rp 2.011) | +156/-23 | 45s | $9.87/hr | 5h: 24% 7d: 41%
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
| Segment | Meaning |
|
|
126
|
+
|---|---|
|
|
127
|
+
| `[Claude Sonnet 5]` | Model name. |
|
|
128
|
+
| `(my-project)` | Current project folder — helps tell sessions apart. |
|
|
129
|
+
| `[####------] 42%` | Context window used, color-coded green→amber→red. |
|
|
130
|
+
| `$0.1234 (~Rp 2.011)` | USD cost, plus a converted estimate if `--currency`/`--idr` is passed. |
|
|
131
|
+
| `+156/-23` | Lines added/removed, colored git-style (green/red). |
|
|
132
|
+
| `45s` | Session duration. |
|
|
133
|
+
| `$9.87/hr` | **Burn rate** — cost extrapolated to an hourly pace (a derived number, not a raw field). |
|
|
134
|
+
| `5h: 24% 7d: 41%` | 5-hour / 7-day rate-limit usage. |
|
|
135
|
+
|
|
136
|
+
Any segment just disappears if the payload doesn't have that data — nothing errors.
|
|
137
|
+
|
|
138
|
+
**Colors** blend smoothly from green (low) to amber to red (high) on
|
|
139
|
+
terminals with 24-bit color support, and fall back to plain green/yellow/red
|
|
140
|
+
otherwise. `--no-color` or `NO_COLOR=1` turns all of it off.
|
|
141
|
+
|
|
142
|
+
**Adaptive width:** if the full line wouldn't fit your terminal, the least
|
|
143
|
+
essential segments drop first — rate limits, then burn rate, duration,
|
|
144
|
+
lines, project, currency — until it fits, or down to just
|
|
145
|
+
`[model] [bar] % | $cost` if space is very tight. Use `--width N` to set
|
|
146
|
+
the width explicitly (handy since Claude Code runs this headless, so
|
|
147
|
+
there's often nothing real to detect) or `--no-adapt` to always print the
|
|
148
|
+
full line.
|
|
149
|
+
|
|
150
|
+
## Installing as your Claude Code status line
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
python statusline_toolkit.py --setup # default: IDR
|
|
154
|
+
python statusline_toolkit.py --setup --currency EUR # a different currency
|
|
155
|
+
python statusline_toolkit.py --setup --currency EUR --track # also track cost history
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
This detects your OS and writes a `statusLine` entry into
|
|
159
|
+
`~/.claude/settings.json`, backing up any existing config first. It's
|
|
160
|
+
idempotent (safe to re-run) and asks before overwriting a different
|
|
161
|
+
`statusLine` (skip with `-y`). Restart Claude Code afterward to see it
|
|
162
|
+
take effect.
|
|
163
|
+
|
|
164
|
+
## Currency conversion
|
|
165
|
+
|
|
166
|
+
`exchange_rate.json` holds manually maintained rates you control — no
|
|
167
|
+
network calls, no API keys:
|
|
168
|
+
|
|
169
|
+
```json
|
|
170
|
+
{
|
|
171
|
+
"rates": { "IDR": 16300, "EUR": 0.92 },
|
|
172
|
+
"updated_at": "2026-07-06"
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Add a currency to `rates` and pass `--currency CODE`, or use
|
|
177
|
+
`--currency CODE --rate <value>` for a one-off conversion without
|
|
178
|
+
touching the file. If a currency isn't configured, the script tells you
|
|
179
|
+
exactly what to add rather than guessing. If `updated_at` is over 30 days
|
|
180
|
+
old, you'll get a one-line reminder to refresh it.
|
|
181
|
+
|
|
182
|
+
(Older single-currency files — `{"usd_to_idr": 16300, ...}` — still work unchanged.)
|
|
183
|
+
|
|
184
|
+
## Cost tracking: history, stats, and a dashboard
|
|
185
|
+
|
|
186
|
+
`--track` records each session's cost to `usage_history.json` (keyed by
|
|
187
|
+
session, so re-renders don't double-count). Then:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
python statusline_toolkit.py --input sample_statusline_data.json --track
|
|
191
|
+
python statusline_toolkit.py --stats # grouped by day
|
|
192
|
+
python statusline_toolkit.py --stats --by-project # or by project / --by-model
|
|
193
|
+
python statusline_toolkit.py --dashboard --open # visual HTML report
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
`--stats` prints a per-group cost/session breakdown with a grand total.
|
|
197
|
+
`--dashboard` renders the same data as a self-contained HTML file — summary
|
|
198
|
+
cards plus cost-by-day/project/model bar charts, no JS framework, no CDN,
|
|
199
|
+
light/dark aware — and only opens a browser if you pass `--open`.
|
|
200
|
+
|
|
201
|
+
Everything here is opt-in and local: nothing is tracked or rendered unless
|
|
202
|
+
you ask, and `usage_history.json` is plain JSON you can inspect or delete
|
|
203
|
+
anytime.
|
|
204
|
+
|
|
205
|
+
## Personal defaults file
|
|
206
|
+
|
|
207
|
+
Tired of retyping the same flags? Put them in
|
|
208
|
+
`~/.claude/statusline-toolkit.json`:
|
|
209
|
+
|
|
210
|
+
```json
|
|
211
|
+
{
|
|
212
|
+
"currency": "EUR",
|
|
213
|
+
"track": true,
|
|
214
|
+
"width": 100
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Every key is optional and mirrors a CLI flag (`no_color`, `by_project`,
|
|
219
|
+
`by_model`, `no_adapt`, `rate_file`, `history_file`, `plugins_dir`,
|
|
220
|
+
`no_plugins` are all supported too). **CLI flags always override the
|
|
221
|
+
file.** Use `--config PATH` for a different file (e.g. separate
|
|
222
|
+
personal/work profiles).
|
|
223
|
+
|
|
224
|
+
## Plugin segments
|
|
225
|
+
|
|
226
|
+
Add your own segment (git branch, whatever) without touching the script:
|
|
227
|
+
drop a `.py` file into `~/.claude/statusline-plugins/` defining one function.
|
|
228
|
+
|
|
229
|
+
```python
|
|
230
|
+
# ~/.claude/statusline-plugins/git_branch.py
|
|
231
|
+
import subprocess
|
|
232
|
+
|
|
233
|
+
def segment(data: dict, use_color: bool) -> str | None:
|
|
234
|
+
cwd = data.get("workspace", {}).get("current_dir") or data.get("cwd")
|
|
235
|
+
try:
|
|
236
|
+
branch = subprocess.run(
|
|
237
|
+
["git", "branch", "--show-current"], cwd=cwd, capture_output=True, text=True, timeout=1,
|
|
238
|
+
).stdout.strip()
|
|
239
|
+
except Exception:
|
|
240
|
+
return None
|
|
241
|
+
return f"({branch})" if branch else None
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
The filename becomes the segment's name; return `None`/`""` to hide it for
|
|
245
|
+
a render. An optional `PRIORITY: int` (default `0`) controls drop order
|
|
246
|
+
among plugins — but plugin segments always drop before any built-in one.
|
|
247
|
+
**A broken plugin (syntax error, exception, bad return type) is silently
|
|
248
|
+
skipped, never crashes the statusline.** Disable loading with
|
|
249
|
+
`--no-plugins`, or point elsewhere with `--plugins-dir`.
|
|
250
|
+
|
|
251
|
+
> **Security note:** a plugin is a regular Python file that runs with full
|
|
252
|
+
> permissions on every render — there's no sandboxing. Only put plugins in
|
|
253
|
+
> this folder that you wrote yourself or fully trust, the same way you'd
|
|
254
|
+
> treat any script before running it. Never copy a plugin from an untrusted
|
|
255
|
+
> source without reading it first.
|
|
256
|
+
|
|
257
|
+
## Project layout
|
|
258
|
+
|
|
259
|
+
| File | Purpose |
|
|
260
|
+
|---|---|
|
|
261
|
+
| `statusline_toolkit.py` | The CLI, including the `--setup` installer. |
|
|
262
|
+
| `exchange_rate.json` | Your USD→currency rates. |
|
|
263
|
+
| `sample_statusline_data.json` | Example payload for trying the tool offline. |
|
|
264
|
+
| `test_statusline_toolkit.py` | Unit tests. |
|
|
265
|
+
| `CHANGELOG.md` | What changed, release by release. |
|
|
266
|
+
| `LICENSE` | MIT license. |
|
|
267
|
+
| `pyproject.toml` | Packaging metadata, for `pip`/`pipx install`. |
|
|
268
|
+
| `.github/workflows/test.yml` | CI: runs the test suite on Linux/macOS/Windows for every push and PR. |
|
|
269
|
+
|
|
270
|
+
`usage_history.json`, `usage_dashboard.html`, `settings.json.bak`, and
|
|
271
|
+
`~/.claude/statusline-toolkit.json` are all generated on demand — not
|
|
272
|
+
part of a fresh checkout, safe to delete anytime.
|
|
273
|
+
|
|
274
|
+
## Tests
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
python -m unittest test_statusline_toolkit.py -v
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Standard library `unittest` only — no test runner to install.
|
|
281
|
+
|
|
282
|
+
## Troubleshooting
|
|
283
|
+
|
|
284
|
+
<details>
|
|
285
|
+
<summary><strong>"No input JSON received" / "Input is not valid JSON"</strong></summary>
|
|
286
|
+
|
|
287
|
+
Pass `--input sample_statusline_data.json` (or your own file), or pipe
|
|
288
|
+
valid JSON into stdin.
|
|
289
|
+
</details>
|
|
290
|
+
|
|
291
|
+
<details>
|
|
292
|
+
<summary><strong>Colors look garbled, or the gradient looks banded instead of smooth</strong></summary>
|
|
293
|
+
|
|
294
|
+
Your terminal doesn't support ANSI/truecolor — use `--no-color`, or run in
|
|
295
|
+
a modern terminal (Windows Terminal, a current PowerShell, most
|
|
296
|
+
Linux/macOS terminal apps).
|
|
297
|
+
</details>
|
|
298
|
+
|
|
299
|
+
<details>
|
|
300
|
+
<summary><strong>Windows: "python is not recognized..."</strong></summary>
|
|
301
|
+
|
|
302
|
+
Use the `py` launcher instead (`py statusline_toolkit.py ...`), or
|
|
303
|
+
reinstall Python with "Add python.exe to PATH" checked.
|
|
304
|
+
</details>
|
|
305
|
+
|
|
306
|
+
<details>
|
|
307
|
+
<summary><strong>`--setup` didn't seem to take effect</strong></summary>
|
|
308
|
+
|
|
309
|
+
Restart Claude Code — `statusLine` config is only read at session start.
|
|
310
|
+
Check `~/.claude/settings.json` for a `statusLine` block pointing at
|
|
311
|
+
`statusline_toolkit.py`.
|
|
312
|
+
</details>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
statusline_toolkit.py,sha256=GNT3WIHFY9BWS7wgS1-qa5PAJlk2_M5rBMwmPzr0EsI,44784
|
|
2
|
+
statusline_toolkit-1.0.0.dist-info/licenses/LICENSE,sha256=trdJLnU38r6Js0hKaZDTLE4pQdUM9rGpqHefMLXkFhU,1072
|
|
3
|
+
statusline_toolkit-1.0.0.dist-info/METADATA,sha256=g_S5LVoWrVrZY_peQylcBZZPvBDcuVxUUvxZvUHrPLE,13092
|
|
4
|
+
statusline_toolkit-1.0.0.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
5
|
+
statusline_toolkit-1.0.0.dist-info/entry_points.txt,sha256=Sb7uJBFjmkIdt7pBEdm-7zXH9lAJpB4ujsVhmQ7S50Q,63
|
|
6
|
+
statusline_toolkit-1.0.0.dist-info/top_level.txt,sha256=m0WGh14vs5N8s0gjVzQPd2CH9PVl3i8bBUQUcVMZdZM,19
|
|
7
|
+
statusline_toolkit-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 gungunfebrianza
|
|
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 all
|
|
13
|
+
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.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
statusline_toolkit
|