tledger 0.2.1 → 0.3.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 CHANGED
@@ -1,171 +1,189 @@
1
1
  # Token Ledger
2
2
 
3
- Token Ledger is a small, local-only terminal dashboard for Codex usage. It
4
- shows ranked project bars, model mix, usage type, cache coverage, and reset
5
- cycle context without sending your data anywhere.
3
+ Token Ledger is a local-only Codex usage dashboard with two outputs:
6
4
 
7
- ## Install
5
+ - a generated PNG report for trends, model composition, and weekly-meter
6
+ context;
7
+ - a terminal dashboard for a fast project and token summary.
8
+
9
+ This README describes the local checkout. It does not assume a hosted report
10
+ or a published npm package.
8
11
 
9
- Requires Node.js 22.13 or newer.
12
+ ## Install
10
13
 
11
- Once published, install the CLI with:
14
+ Requires Node.js 22.13 or newer. From this checkout:
12
15
 
13
16
  ```bash
14
- npm install -g tledger
17
+ npm install
18
+ npm install -g .
15
19
  ```
16
20
 
17
- For a one-time run without a permanent global install:
21
+ The second command installs `tledger` on your PATH. From the checkout, you can
22
+ use `npx tledger` instead.
23
+
24
+ ## Basics
25
+
26
+ | What you need | Command |
27
+ | --- | --- |
28
+ | Quick guide | `tledger` |
29
+ | Last 24 hours | `tledger 1d` |
30
+ | Last 7 calendar days | `tledger week` |
31
+ | Rolling 30 days | `tledger 30d` |
32
+ | 7-day PNG report | `tledger report 7d` |
33
+ | Cache-only PNG report | `tledger report 7d --cache-rate` |
34
+
35
+ The main options are:
36
+
37
+ - `--static` prints once instead of opening the terminal dashboard.
38
+ - `--refresh` rebuilds the local usage cache.
39
+ - `--image-output <file>` chooses where to save a PNG.
40
+ - `--no-open` writes a PNG without opening it.
41
+ - `--help-all` shows the complete command and option reference.
42
+
43
+ `week` covers seven local calendar days ending on the selected day. `1d` is a
44
+ rolling 24-hour view ending when the command starts. In a TTY, the project
45
+ dashboard is interactive. `j`/`k` select a project; `q`, `Q`, `Esc`, or
46
+ `Ctrl-C` exits. Enter does not inspect a project, and `d` / `w` / `m` do not
47
+ change the range; choose the range in the command.
48
+
49
+ ## Cache and input controls
50
+
51
+ `tledger report [Nd|Nw] --cache-rate` writes a separate, purpose-built cache
52
+ report to `token-ledger-cache-report-<period>.png`. Its primary view is the
53
+ input-token-weighted cache rate (`cached input / measured input`), shown
54
+ across the selected period with input-volume context. A smaller model breakout
55
+ shows which models account for that input and their individual cache rates.
56
+ The cache report intentionally omits the general report's project, quota-meter,
57
+ runway, and output-token sections. Cached input is clamped to input per event,
58
+ and the report states how much token volume had a usable component breakdown.
59
+ Use `--image-output`, `--image-width`, `--date`, `--tz`, and `--no-open` the
60
+ same way as on the standard report.
61
+
62
+ The default privacy-reduced snapshot is
63
+ `~/.token-ledger/token-ledger-snapshot-v2.json.gz`. It is gzip-compressed,
64
+ written atomically with mode `0600`, targets 12 MiB, and has a hard 16 MiB
65
+ on-disk limit. Its expanded JSON representation also targets 48 MiB and has a
66
+ 64 MiB safety limit, so the old 93 MiB raw-cache behavior cannot recur on the
67
+ default production path. Reads check the compressed size before loading and
68
+ bound gzip expansion to the same 64 MiB JSON limit. The collector de-duplicates
69
+ through a private temporary SQLite spool, then keeps exact recent calls while
70
+ rolling older history into minute, hour, and day buckets. If a dense history
71
+ approaches the target, it increases the bucket resolution automatically while
72
+ preserving additive token, model, project, cache, tool-call, and thread totals.
73
+ When a compacted bucket crosses a requested range or chart boundary, Token
74
+ Ledger allocates its additive values proportionally across the overlap and
75
+ marks the terminal result as estimated; exact recent calls remain exact. The
76
+ temporary spool is removed when collection completes or exits with a handled
77
+ error.
78
+
79
+ If even the coarsest bounded representation exceeds the hard limit, Token
80
+ Ledger preserves the previous cache and asks you to reduce the source with
81
+ `--no-archived` or the collector's `--since` option. It never replaces the
82
+ production cache with an oversized or partial file. On a normal default-path
83
+ run, a snapshot whose mtime is in the past and less than one hour old skips the
84
+ source walk. An exact-hour or future mtime is not fresh; an older snapshot is
85
+ checked against local source mtimes before it is reused or rebuilt.
18
86
 
19
87
  ```bash
20
- npx tledger week
88
+ # Force a rebuild from CODEX_HOME or ~/.codex
89
+ tledger week --refresh
90
+
91
+ # Read the existing default snapshot without a source-freshness check
92
+ tledger week --no-refresh
93
+
94
+ # Read an explicit snapshot without automatic freshness checks
95
+ tledger week --input /path/to/token-ledger-snapshot-v2.json.gz
21
96
  ```
22
97
 
23
- Until the package is published, install it from this repository:
98
+ `--refresh` rebuilds the default snapshot and cannot be combined with
99
+ `--input` in this checkout. `--no-archived` excludes `archived_sessions` when a
100
+ refresh occurs. The collector can also be run directly:
24
101
 
25
102
  ```bash
26
- git clone <repository-url>
27
- cd token-ledger
28
- npm install -g .
103
+ node lib/token-ledger-importer.mjs --output /path/to/token-ledger-snapshot-v2.json.gz
29
104
  ```
30
105
 
31
- The package uses a small runtime image encoder for PNG report output, Node's
32
- built-in SQLite support, and reads Codex data directly from the local machine.
33
-
34
- ## Run
106
+ Explicit `.json` snapshots remain readable for fixtures and deliberate exports,
107
+ but `.json.gz` is the bounded production cache format. After an upgrade, the
108
+ new cache does not read or delete schema-v1 cache files; remove an old generated
109
+ cache separately once the v2 cache is proven.
35
110
 
36
- The shortest useful command is:
111
+ ## Report versus CLI
37
112
 
38
- ```bash
39
- tledger week
40
- ```
113
+ | | Generated report | Terminal dashboard |
114
+ | --- | --- | --- |
115
+ | Command | `tledger report 7d` or `tledger trend 7d --image` | `tledger week`, `tledger 1d`, or `tledger day <date>` |
116
+ | Output | One PNG with a stat quad, weekly-meter pace/runway, daily token columns, an aligned cache-rate strip, top projects, and per-model cache rates | Interactive or static project rows with totals, shares, thread counts, model mix, usage type, cache split, and reset-cycle context |
117
+ | Range | A selected local-calendar-day trend window, such as 7d or 2w | A calendar day/week or a rolling 24-hour/`Nd`/`Nw` window |
118
+ | Estimate surface | Meter-derived burn and runway are called out; cache coverage comes from measured token breakdowns | The sidebar can show derived `View burn`; project detail includes rate-card credit shares when available |
41
119
 
42
- It defaults to today's seven-day window, the computer's local timezone, the
43
- top 10 projects, and the local Codex data directory. The default terminal view
44
- is interactive; press `q` or `esc` to exit.
120
+ The report is the broader visual summary. The CLI does not open or generate a
121
+ report unless you request the `report`, `trend --image`, or `--image` form.
45
122
 
46
- Other common views:
123
+ ## Examples
47
124
 
48
- ```bash
49
- tledger 1d
50
- tledger 1d --static
51
- tledger day 2026-08-05
52
- tledger week --top 5
53
- tledger week --static
54
- tledger trend 7d --static
55
- tledger trend 7d --image --image-output artifacts/token-ledger-trend-7d.png
56
- tledger report 7d
57
- ```
125
+ ### Seven-day report
58
126
 
59
- `tledger 1d` shows the `TOKENS BY PROJECT` breakdown for the rolling 24 hours
60
- ending when the command starts. It is different from `tledger day today`, which
61
- covers the current calendar day from local midnight.
62
-
63
- `tledger report [7d|14d|30d]` is the one-step report output: it writes the
64
- dashboard PNG (identical to `trend --image`) to
65
- `token-ledger-report-<period>.png` in the current directory. It accepts the
66
- same flags as the trend view (`--drain`, `--date`, `--tz`, `--image-output`,
67
- `--image-width`) and prints progress while rendering and encoding the image.
68
-
69
- The terminal trend view is a compact approximation of the image view. For the
70
- full chart grammar, use `--image`: it writes a PNG with two aligned panels
71
- sharing one time axis — the observed weekly meter as a line on its own 0–100%
72
- panel on top, and calendar-day columns of local token volume stacked by model
73
- below, each annotated with the observed drop ("−18.1%" means the meter fell
74
- 18.1 points across that column's days). The drain numbers come straight from
75
- the meter — no pricing model involved — so token volume and actual limit
76
- consumption can be compared per day at a glance.
77
-
78
- Turns run in fast mode (service tier "priority") are drawn as a darker shade
79
- at the top of their model's segment, with each model's fast share in the
80
- legend; fast-mode turns are weighted 1.5× in the credit estimate because they
81
- debit the plan limit at a higher rate.
82
-
83
- Pass `--drain` to flip the columns into limit-drain units instead: each column
84
- becomes the weekly limit percentage the meter dropped, stacked by model using
85
- rate-card credit weights (an estimate — the official card is the best
86
- available proxy for per-model debit, but subscription limits are not billed
87
- per token), on the same percent scale as the meter line.
88
-
89
- Meter windows are keyed by their server-reported reset timestamp, so a fresh
90
- window that starts days early (a provider-initiated limit restart) is drawn as
91
- its own cycle and labeled `restart`, while a true weekly expiry is labeled
92
- `reset`.
93
- Stale readings from sessions still reporting a superseded window are dropped
94
- instead of being fused into the line as phantom drain. Drops observed after a
95
- sparse meter gap (over 36 hours) are spread across the covered days and marked
96
- with `≈`. When a range has no usable meter drain, columns fall back to raw
97
- local token counts and the chart says so.
98
-
99
- `--image` defaults to `token-ledger-trend-7d.png` in the current directory.
100
- Use `--image-output <file.png>` to choose the path and `--image-width <px>` to
101
- choose a width from 900 to 2400 pixels.
102
-
103
- Use `trend 14d` for daily columns across two weeks. At 30 days, the terminal
104
- uses readable multi-day bins: three-day bins at ordinary widths and two-day
105
- bins on wider terminals. The image view uses the same readable multi-day
106
- binning at 30 days. The image also reports the separate local rate-card credit
107
- estimate when token breakdowns are available; that estimate is an absolute
108
- credit count and never rescales the observed-drain columns.
109
-
110
- The CLI automatically checks the local Codex source files before rendering. If
111
- they are newer than the local cache, it rebuilds the privacy-reduced snapshot.
112
- The first refresh may scan historical rollout files; later runs use the cache
113
- for one hour before checking source freshness again. Use `--refresh` when you
114
- need to force an immediate rebuild.
115
-
116
- The `1d` project dashboard shows a compact snapshot-age line such as
117
- `SNAPSHOT · fresh · 12m old`. `fresh` means the snapshot is within the
118
- one-hour cache window, `stale` means it is older, and `age unknown` means the
119
- snapshot has no usable capture-time metadata. The indicator does not print a
120
- local path or trigger another source scan.
121
-
122
- Useful overrides:
127
+ ![Seven-day Token Ledger report example](docs/token-ledger-report-7-day.png)
123
128
 
124
- ```bash
125
- # Use another timezone instead of the computer's local timezone
126
- tledger week --tz America/New_York
129
+ ### Non-report CLI output
127
130
 
128
- # Force a complete local refresh
129
- tledger week --refresh
131
+ ![Anonymized Token Ledger terminal output](docs/token-ledger-cli-week.png)
130
132
 
131
- # Skip the freshness check and use the existing cache
132
- tledger week --no-refresh
133
+ The terminal capture was made from a local privacy-reduced snapshot after
134
+ replacing project and thread labels with neutral names. It contains no prompts,
135
+ responses, secrets, home paths, or project names.
133
136
 
134
- # Read a specific privacy-reduced snapshot
135
- tledger week --input /path/to/token-ledger-snapshot.json
136
- ```
137
+ ## What is observed
137
138
 
138
- `--static` prints once for pipes, logs, or terminals without interactive input.
139
- `--plain` or `NO_COLOR=1` disables ANSI color. `--youplot` is an optional
140
- legacy renderer and is not required for the default dashboard.
139
+ The collector reads local rollout JSONL under `sessions/` and, unless disabled,
140
+ `archived_sessions/`, plus `session_index.jsonl` and read-only `state_5.sqlite`
141
+ metadata. It retains positive `last_token_usage` model-call events and their
142
+ timestamps, turn IDs, model/source attribution, and token categories.
141
143
 
142
- ## Local data and privacy
144
+ Observed totals are the sum of globally de-duplicated retained events. Events
145
+ with turn IDs use the turn plus cumulative/last-usage/context signatures;
146
+ legacy events without turn IDs use a high-specificity usage signature and are
147
+ marked as heuristic. State database token counters are kept as non-additive
148
+ reference values because forks and subagents inherit cumulative history.
143
149
 
144
- The CLI reads from `CODEX_HOME` when set, otherwise `~/.codex`. It uses local
145
- Codex rollout JSONL files, the session index, and local state metadata. It
146
- writes its privacy-reduced cache to:
150
+ Input, cached-input, output, and reasoning are stored as separate categories:
151
+ cached input is a subset of input, and reasoning is a subset of output. Any
152
+ composition that presents them together subtracts those subsets to avoid
153
+ double counting. Models are attributed from turn context/settings and local
154
+ thread metadata, then normalized for display.
147
155
 
148
- ```text
149
- ~/.token-ledger/token-ledger-snapshot.json
150
- ```
156
+ The weekly meter uses local rate-limit observations for the account-wide
157
+ weekly window. Reset timestamps identify windows; stale readings and separate
158
+ named pools are not stitched into that meter. Remaining percentage,
159
+ observation time, and the selected window are local observations; the reset
160
+ type (weekly expiry versus restart) is derived by comparing the prior window's
161
+ reset timestamp with the first reading of the new window. None of this is an
162
+ official account-wide quota or billing record.
151
163
 
152
- The collector does not export message bodies, reasoning text, tool arguments or
153
- results, credentials, file contents, or full local paths. Display titles may
154
- contain user-written text. CLI errors and empty-state source labels show only a
155
- safe filename label, not an absolute input or source path. When a PNG or report
156
- is written, the explicit output path is reported so you can find the file. The
157
- CLI makes no network requests.
164
+ The exported snapshot contains token metadata, model/use-type labels, project
165
+ labels, and display titles. It omits message bodies, reasoning text, tool
166
+ arguments/results, credential fields, and full local paths. Display titles and
167
+ project labels are user-written or local metadata and should be reviewed before
168
+ sharing. Normal successful dashboard output is privacy-reduced, but diagnostics
169
+ or explicit PNG writes may echo configured snapshot, Codex, or output path
170
+ labels.
158
171
 
159
- ## Keyboard controls
172
+ ## What is estimated
160
173
 
161
- In the interactive dashboard:
174
+ Credit values use the hardcoded rate card dated **2026-08-17**. Cached input is
175
+ priced separately, priority/fast-mode events use the 1.5× multiplier, and
176
+ events without a detailed breakdown or known model rate are unrated. These are
177
+ rate-card estimates, not provider billing totals.
162
178
 
163
- - `↑` / `↓` or `j` / `k` moves between projects.
164
- - `q`, `Q`, `Esc`, or `Ctrl-C` exits.
165
- - Enter does not inspect a project, and `d` / `w` / `m` do not change the
166
- range; choose the desired range in the command instead.
179
+ When meter observations are available, report bars in `--drain` mode represent
180
+ observed meter drops; model attribution within a drop uses rate-card weights
181
+ when possible and token weights as a fallback. Long observation gaps are
182
+ spread across local calendar days as estimates. Tokens-per-meter-point,
183
+ model-split burn, runway, and CLI `View burn` are derived estimates. None is
184
+ official billing, quota, or account-completeness truth.
167
185
 
168
- ## Verify from source
186
+ ## Verify
169
187
 
170
188
  ```bash
171
189
  npm test
@@ -173,7 +191,3 @@ npm run lint
173
191
  npm run verify:release
174
192
  npm pack --dry-run --json
175
193
  ```
176
-
177
- `npm run verify:release` packs the allowlisted artifact, installs that tarball
178
- in a clean temporary directory with no network or Codex data access, and runs
179
- the installed `tledger --help` and synthetic `tledger 1d --static` smoke checks.