nomnomtokens 0.3.0 → 0.5.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 +48 -24
- package/dist/index.js +1198 -107
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/web/nitro.json +1 -1
- package/web/public/_nuxt/AuWqCQTg.js +1 -0
- package/web/public/_nuxt/{W3KL_OjU.js → B1SHP0x7.js} +1 -1
- package/web/public/_nuxt/{DQEnwY-5.js → B4lg_KdO.js} +1 -1
- package/web/public/_nuxt/B8pNcdCn.js +1 -0
- package/web/public/_nuxt/{COwSpxrx.js → BL80uXr2.js} +1 -1
- package/web/public/_nuxt/{B2aHje2L.js → BOu13FsZ.js} +1 -1
- package/web/public/_nuxt/{CvIugsJe2.js → BYf03To42.js} +1 -1
- package/web/public/_nuxt/{CkRZsevx.js → B_fydnl_.js} +1 -1
- package/web/public/_nuxt/{DnTwjl0_2.js → BboXpc0v2.js} +2 -2
- package/web/public/_nuxt/{CfBMjq8x.js → Bg-w_mbM.js} +1 -1
- package/web/public/_nuxt/{B1jhn8zK.js → BsIJiDwC.js} +1 -1
- package/web/public/_nuxt/BsfWsX6E.js +1 -0
- package/web/public/_nuxt/{C9MiT_Wm.js → BuKW47N9.js} +2 -2
- package/web/public/_nuxt/{4C_a23zt.js → BvB3OU0z.js} +1 -1
- package/web/public/_nuxt/CLdT3CQk.js +1 -0
- package/web/public/_nuxt/{D9j6aFUy.js → Car0xtsn.js} +1 -1
- package/web/public/_nuxt/Ch1ysvEi.js +1 -0
- package/web/public/_nuxt/{BOKlFKrX.js → Ck5ddq-9.js} +1 -1
- package/web/public/_nuxt/{Cq1Sq3Go.js → CsVo4EXo.js} +1 -1
- package/web/public/_nuxt/CzaLG4_B2.js +1 -0
- package/web/public/_nuxt/{C51OzH6V.js → D9MZNmok.js} +1 -1
- package/web/public/_nuxt/{D9Mxq5ER.js → DQ6vgNw-.js} +1 -1
- package/web/public/_nuxt/{D49wVVwm2.js → DZ0oUjlX2.js} +1 -1
- package/web/public/_nuxt/DbTv-m36.js +1 -0
- package/web/public/_nuxt/{D4C6J8YV.js → DdHo_MGy.js} +1 -1
- package/web/public/_nuxt/{m3-Vaz25.js → DmteO8Ul.js} +1 -1
- package/web/public/_nuxt/DyoXCutE.js +1 -0
- package/web/public/_nuxt/{DPnm6zS2.js → DyvBBld_2.js} +1 -1
- package/web/public/_nuxt/{CIKwfDBl.js → PaV2v2OF.js} +1 -1
- package/web/public/_nuxt/{BMSLzLlT.js → RjmsMzM7.js} +1 -1
- package/web/public/_nuxt/builds/latest.json +1 -1
- package/web/public/_nuxt/builds/meta/2bf417d4-fc60-4108-8624-e631e05f5a46.json +1 -0
- package/web/public/_nuxt/entry.CE8-9Sal.css +2 -0
- package/web/public/_nuxt/{Dy30RUCD2.js → hPGLTkZo2.js} +1 -1
- package/web/public/_nuxt/{Bprokln-.js → jeqgGzjf.js} +1 -1
- package/web/public/_nuxt/n29w62AT.js +1 -0
- package/web/public/_nuxt/{CDzUujek.js → tShBBc0S.js} +2 -2
- package/web/server/chunks/_/filters.mjs +1 -0
- package/web/server/chunks/_/filters.mjs.map +1 -1
- package/web/server/chunks/build/AuditCard-CgGiEb_r.mjs +290 -0
- package/web/server/chunks/build/AuditCard-CgGiEb_r.mjs.map +1 -0
- package/web/server/chunks/build/{CardContent-C_IMqI8K.mjs → CardDescription-Bi5t5iXj.mjs} +30 -30
- package/web/server/chunks/build/CardDescription-Bi5t5iXj.mjs.map +1 -0
- package/web/server/chunks/build/{FilterBar-BlEsJ5dy.mjs → FilterBar-BYBOdTrl.mjs} +2 -2
- package/web/server/chunks/build/{FilterBar-BlEsJ5dy.mjs.map → FilterBar-BYBOdTrl.mjs.map} +1 -1
- package/web/server/chunks/build/{Sparkline-CaCRq45J.mjs → Sparkline-B3kazZhU.mjs} +2 -2
- package/web/server/chunks/build/{Sparkline-CaCRq45J.mjs.map → Sparkline-B3kazZhU.mjs.map} +1 -1
- package/web/server/chunks/build/{_id_-BvccBwzH.mjs → _id_-DPUt6OzN.mjs} +4 -4
- package/web/server/chunks/build/{_id_-BvccBwzH.mjs.map → _id_-DPUt6OzN.mjs.map} +1 -1
- package/web/server/chunks/build/asyncData-CMa0z9Yw.mjs +2 -2
- package/web/server/chunks/build/audit-BPAlwhzn.mjs +1180 -0
- package/web/server/chunks/build/audit-BPAlwhzn.mjs.map +1 -0
- package/web/server/chunks/build/{default-BokiYQNv.mjs → default-CvQF0-O_.mjs} +46 -22
- package/web/server/chunks/build/default-CvQF0-O_.mjs.map +1 -0
- package/web/server/chunks/build/export-CwC19yOz.mjs +232 -0
- package/web/server/chunks/build/export-CwC19yOz.mjs.map +1 -0
- package/web/server/chunks/build/fetch-DJ9NNbFP.mjs +1 -1
- package/web/server/chunks/build/{import-CO3NEu0P.mjs → import-BmoVtcGR.mjs} +31 -15
- package/web/server/chunks/build/import-BmoVtcGR.mjs.map +1 -0
- package/web/server/chunks/build/{limits-CX9zBSqw.mjs → limits-C21_a18j.mjs} +5 -5
- package/web/server/chunks/build/{limits-CX9zBSqw.mjs.map → limits-C21_a18j.mjs.map} +1 -1
- package/web/server/chunks/build/nuxt-link-mYiLFsJs.mjs +2 -2
- package/web/server/chunks/build/{pages-DyXqJyPq.mjs → pages-CJpczmoA.mjs} +81 -11
- package/web/server/chunks/build/pages-CJpczmoA.mjs.map +1 -0
- package/web/server/chunks/build/{providers-Ca7keu2G.mjs → providers-BBVw9CDb.mjs} +4 -4
- package/web/server/chunks/build/{providers-Ca7keu2G.mjs.map → providers-BBVw9CDb.mjs.map} +1 -1
- package/web/server/chunks/build/{scopes-E5z80S19.mjs → scopes-DpYnOAM9.mjs} +203 -62
- package/web/server/chunks/build/scopes-DpYnOAM9.mjs.map +1 -0
- package/web/server/chunks/build/{sessions-CESRiCOS.mjs → sessions-B-Y_ifp1.mjs} +5 -5
- package/web/server/chunks/build/{sessions-CESRiCOS.mjs.map → sessions-B-Y_ifp1.mjs.map} +1 -1
- package/web/server/chunks/build/{timeline-d27OlbZN.mjs → timeline-8kK28WQB.mjs} +5 -5
- package/web/server/chunks/build/{timeline-d27OlbZN.mjs.map → timeline-8kK28WQB.mjs.map} +1 -1
- package/web/server/chunks/build/useFormat-NkyUqeik.mjs +1 -1
- package/web/server/chunks/build/{useStats-CmYzpdbE.mjs → useStats-BQQJIKQO.mjs} +7 -5
- package/web/server/chunks/build/{useStats-CmYzpdbE.mjs.map → useStats-BQQJIKQO.mjs.map} +1 -1
- package/web/server/chunks/nitro/nitro.mjs +692 -214
- package/web/server/chunks/nitro/nitro.mjs.map +1 -1
- package/web/server/chunks/routes/api/export.get.mjs +22 -3
- package/web/server/chunks/routes/api/export.get.mjs.map +1 -1
- package/web/server/chunks/routes/api/import/csv.post.mjs +20 -6
- package/web/server/chunks/routes/api/import/csv.post.mjs.map +1 -1
- package/web/server/chunks/routes/api/ingest.post.mjs +1 -1
- package/web/server/chunks/routes/api/meta.get.mjs +1 -1
- package/web/server/chunks/routes/api/scopes/_hash_.patch.mjs +35 -0
- package/web/server/chunks/routes/api/scopes/_hash_.patch.mjs.map +1 -0
- package/web/server/chunks/routes/api/stats/audit.get.mjs +60 -0
- package/web/server/chunks/routes/api/stats/audit.get.mjs.map +1 -0
- package/web/server/chunks/routes/api/stats/limits.get.mjs +1 -1
- package/web/server/chunks/routes/api/stats/providers.get.mjs +1 -1
- package/web/server/chunks/routes/api/stats/scopes.get.mjs +1 -1
- package/web/server/chunks/routes/api/stats/session/_id_.get.mjs +1 -1
- package/web/server/chunks/routes/api/stats/summary.get.mjs +1 -1
- package/web/server/chunks/routes/api/stats/verdict.get.mjs +35 -0
- package/web/server/chunks/routes/api/stats/verdict.get.mjs.map +1 -0
- package/web/server/chunks/routes/renderer.mjs +2 -2
- package/web/server/chunks/virtual/entry.mjs +17 -12
- package/web/server/chunks/virtual/precomputed.mjs +1 -1
- package/web/server/chunks/virtual/precomputed.mjs.map +1 -1
- package/web/server/index.mjs +1 -1
- package/web/public/_nuxt/Bia8fJFj.js +0 -1
- package/web/public/_nuxt/CIHIOSzn.js +0 -1
- package/web/public/_nuxt/CZSbzIi-.js +0 -1
- package/web/public/_nuxt/DMgad8mU.js +0 -1
- package/web/public/_nuxt/DhJW7zb9.js +0 -1
- package/web/public/_nuxt/OU1MVgXQ.js +0 -1
- package/web/public/_nuxt/builds/meta/e90c8a2d-9e50-4b58-8019-6b1bf4c8fc6d.json +0 -1
- package/web/public/_nuxt/cbxnBwm6.js +0 -1
- package/web/public/_nuxt/entry.MbqNBIeH.css +0 -2
- package/web/server/chunks/build/CardContent-C_IMqI8K.mjs.map +0 -1
- package/web/server/chunks/build/default-BokiYQNv.mjs.map +0 -1
- package/web/server/chunks/build/export-BhfwmSMl.mjs +0 -184
- package/web/server/chunks/build/export-BhfwmSMl.mjs.map +0 -1
- package/web/server/chunks/build/import-CO3NEu0P.mjs.map +0 -1
- package/web/server/chunks/build/pages-DyXqJyPq.mjs.map +0 -1
- package/web/server/chunks/build/scopes-E5z80S19.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# nomnomtokens
|
|
2
2
|
|
|
3
|
-
> nom nom nom — your
|
|
3
|
+
> nom nom nom — your agents are eating tokens. One local store shows where.
|
|
4
4
|
|
|
5
|
-
A local-first dashboard for AI coding agent spend
|
|
6
|
-
dashboard opens in your browser: how much
|
|
7
|
-
|
|
5
|
+
A local-first dashboard for AI coding agent spend across Claude Code, Codex,
|
|
6
|
+
and Cursor. Run one command and a dashboard opens in your browser: how much
|
|
7
|
+
went today, on which projects and models, how much of that was cache or
|
|
8
|
+
subagents, and when you'll hit your limit.
|
|
8
9
|
|
|
9
10
|
```sh
|
|
10
11
|
npx nomnomtokens
|
|
@@ -14,21 +15,27 @@ npx nomnomtokens
|
|
|
14
15
|
|
|
15
16
|

|
|
16
17
|
|
|
17
|
-
Claude Code,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
One store for Claude Code, Codex CLI/IDE session rollouts, and Cursor (when its
|
|
19
|
+
local IDE database has token fields). The point is not another total — it is
|
|
20
|
+
history you can filter and audit: model mix, cache vs fresh tokens, and
|
|
21
|
+
subagent share where the transcript marks it. The event contract is deliberately
|
|
22
|
+
not AI-shaped, so other agents — and eventually CI minutes and cloud bills —
|
|
23
|
+
plug in as adapters without touching the core.
|
|
21
24
|
|
|
22
25
|
## What you get
|
|
23
26
|
|
|
24
|
-
- **Overview** — eaten today / this week / this month,
|
|
25
|
-
projects when you'll hit the cap
|
|
27
|
+
- **Overview** — eaten today / this week / this month, a limits widget that
|
|
28
|
+
projects when you'll hit the cap, a **Where it went** card (cache hit,
|
|
29
|
+
subagent share, model mix, tips), and a **Verdict** when weekly limit
|
|
30
|
+
snapshots exist.
|
|
31
|
+
- **Audit** — the full report: models, top sessions, cold resumes, tips. Same
|
|
32
|
+
numbers as `nnt audit`.
|
|
26
33
|
- **Timeline** — spend over time stacked by model, plus an hour×weekday heatmap
|
|
27
34
|
of when you actually work.
|
|
28
35
|
- **Projects** — per-project cost with trend against the preceding period. Click
|
|
29
|
-
a row to filter every screen
|
|
30
|
-
|
|
31
|
-
|
|
36
|
+
a row to filter every screen; expand a row to tag a client for invoices.
|
|
37
|
+
- **Providers** — per-agent and per-model breakdown: cache hit rate and cost per
|
|
38
|
+
1,000 changed lines.
|
|
32
39
|
- **Sessions** — every conversation, drilling into how the bill accumulated.
|
|
33
40
|
- **Limits** — window-fill history with a burn-rate projection and markers for
|
|
34
41
|
the moments you actually hit the cap.
|
|
@@ -54,9 +61,16 @@ live updates.
|
|
|
54
61
|
The hook doubles as a real status line:
|
|
55
62
|
|
|
56
63
|
```
|
|
57
|
-
(^u^) $4.20 ctx 37% 5h 73%
|
|
64
|
+
(^u^) $4.20 ctx 37% 7d 81% ·4d3h 5h 73% ·1h47m 138 lines
|
|
58
65
|
```
|
|
59
66
|
|
|
67
|
+
The countdown after each window is the time left until it resets: the
|
|
68
|
+
percentage tells you whether to slow down, the countdown tells you what slowing
|
|
69
|
+
down would cost. It is omitted when Claude Code sends no `resets_at`. The
|
|
70
|
+
weekly window is shown first when it is the tighter of the two. If Claude's
|
|
71
|
+
week is nearly full and a recent Codex snapshot in the store still has
|
|
72
|
+
headroom, a `codex 7d N%` suffix is appended.
|
|
73
|
+
|
|
60
74
|
## Commands
|
|
61
75
|
|
|
62
76
|
| Command | Does |
|
|
@@ -66,16 +80,22 @@ The hook doubles as a real status line:
|
|
|
66
80
|
| `nnt serve [--port]` | open the dashboard |
|
|
67
81
|
| `nnt init [--force]` | wire up the status line hook |
|
|
68
82
|
| `nnt statusline` | ingest a session payload and print a status line |
|
|
69
|
-
| `nnt doctor` | why is it empty? checks sources, hook, and
|
|
70
|
-
| `nnt import <file
|
|
71
|
-
| `nnt export` | dump filtered events as CSV/JSON |
|
|
83
|
+
| `nnt doctor` | why is it empty? checks sources, hook, store, and transcript wipe |
|
|
84
|
+
| `nnt import <file>` | billing CSV or nnt archive JSON into the local store |
|
|
85
|
+
| `nnt export` | dump filtered events as CSV/JSON, or `--format nnt` for a portable store |
|
|
72
86
|
| `nnt prices [show\|refresh]` | local model price table (`~/.nomnomtokens/prices.json`) |
|
|
73
87
|
| `nnt alerts [show\|check]` | limit % / daily $ thresholds (`~/.nomnomtokens/alerts.json`) |
|
|
88
|
+
| `nnt audit [--days] [--json]` | where spend went: cache, subagents, models, cold resumes, tips |
|
|
89
|
+
| `nnt verdict [--json]` | which Claude plan weekly fill actually needs (dated estimates) |
|
|
90
|
+
| `nnt weigh [--json]` | weekly limit points per list-price dollar, when one model owns the gap |
|
|
91
|
+
| `nnt otel --endpoint <url>` | opt-in OTLP/HTTP JSON export of numbers and hashes |
|
|
74
92
|
|
|
75
93
|
## Privacy
|
|
76
94
|
|
|
77
|
-
Your data never leaves your machine. No account, no telemetry
|
|
78
|
-
|
|
95
|
+
Your data never leaves your machine unless you opt in. No account, no telemetry.
|
|
96
|
+
The dashboard makes no outbound calls — not even a font or a CDN script. The
|
|
97
|
+
only network is explicit: `nnt prices refresh --from`, alert webhooks, and
|
|
98
|
+
`nnt otel --endpoint`.
|
|
79
99
|
|
|
80
100
|
The event type has nowhere to put a prompt, a diff, or a path:
|
|
81
101
|
|
|
@@ -141,9 +161,11 @@ the core, the contract is wrong and that's a bug worth reporting.
|
|
|
141
161
|
|
|
142
162
|
## Roadmap
|
|
143
163
|
|
|
144
|
-
Shipped: Claude Code / Cursor / Codex adapters, CSV import &
|
|
145
|
-
grouped by name, local `prices.json`
|
|
146
|
-
|
|
164
|
+
Shipped: Claude Code / Cursor / Codex adapters, CSV and nnt-archive import &
|
|
165
|
+
export, Projects grouped by name with optional client tags, local `prices.json`
|
|
166
|
+
refresh, limit/daily alerts, all dashboard screens including `/audit`, limits
|
|
167
|
+
with forecasting, live updates, Overview audit + verdict, `nnt audit` /
|
|
168
|
+
`nnt verdict`, and opt-in `nnt otel`.
|
|
147
169
|
|
|
148
170
|
Cursor caveat: the IDE often stores zero token counts in local bubbles. We only
|
|
149
171
|
emit events when numbers are present (exact `tokenCount`, or
|
|
@@ -151,8 +173,10 @@ emit events when numbers are present (exact `tokenCount`, or
|
|
|
151
173
|
local counts will not appear until Cursor writes them — or until you import a
|
|
152
174
|
billing CSV.
|
|
153
175
|
|
|
154
|
-
Next:
|
|
155
|
-
a rewrite, and never in
|
|
176
|
+
Next: a desktop window and menu bar around the same local store. Cloud mode
|
|
177
|
+
stays a later second sink for the same events, never a rewrite, and never in
|
|
178
|
+
the critical path. An OTLP *receiver* is not on the roadmap — `nnt otel`
|
|
179
|
+
exports into Grafana/Datadog you already run.
|
|
156
180
|
|
|
157
181
|
## License
|
|
158
182
|
|