cmd-usage 0.6.3

Live Command Code (commandcode.ai) usage dashboard: credits, 5-hour and weekly windows, plan limits. Watch mode or one-shot.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
.TH CMDUSE 1 "2026-09" "cmd-usage 0.6.3" "User Commands"
.SH NAME
cmduse \- live Command Code (commandcode.ai) usage dashboard and reporter
.SH SYNOPSIS
.B cmduse
[\fIOPTIONS\fR]
.br
.B cmduse \-1
[\fIOPTIONS\fR]
.br
.B cmduse daily
[\fB\-\-days\fR \fIn\fR] [\fB\-\-json\fR] [\fB\-\-local\fR]
.br
.B cmduse hourly
[\fB\-\-hours\fR \fIn\fR] [\fB\-\-json\fR] [\fB\-\-local\fR]
.br
.B cmduse model
[\fB\-\-json\fR]
.br
.B cmduse session
[\fB\-\-json\fR]
.br
.B cmduse models
[\fB\-\-json\fR] [\fB\-\-gated\fR]
.br
.B cmduse plans
[\fB\-\-json\fR]
.br
.B cmduse statusline
[\fB\-\-json\fR]
.br
.B cmduse config set
\fIkey\fR=\fIvalue\fR [\fIkey\fR=\fIvalue\fR ...]
.br
.B cmduse \-V
.br
.B cmduse \-h
.SH DESCRIPTION
.B cmduse
is a terminal client for the Command Code (commandcode.ai) metered AI API.  It
fetches the account's plan, remaining monthly credits, and the 5\-hour and
weekly rolling spending windows, and renders them as a live in\-place
dashboard.  It also produces account\-wide usage reports (all harnesses, via
the usage API), offline reports from local CLI logs, a template\-driven
statusline for prompts, and a listing of live models.
.PP
Authentication is read from
.IR ~/.commandcode/auth.json ,
the login state written by the official Command Code CLI (\fBcmd login\fR).
The file is a JSON object containing an \fBapiKey\fR field.  There is no
separate cmduse login; without that file every network command fails with an
error naming the missing key.
.SH EXIT STATUS
.TP
0
Success.
.TP
1
Runtime failure (network, auth, config write, report fetch).
.TP
2
Argument parse error; a message was printed to stderr.
.SH SUBCOMMANDS
With no subcommand, \fBcmduse\fR runs the live dashboard in watch mode.  With
\fB\-1\fR it fetches once and prints.
.TP
.B daily
Account usage by UTC day for the last \fI\-\-days\fR N days (default 7, max
365, today included).  Account\-wide means all harnesses (CLI, IDE, web,
API) that spent against the same account.  Days are derived by fetching the
cumulative summary at each UTC midnight and differencing adjacent
boundaries; requests are pooled 8 at a time in parallel.  With
\fB\-\-local\fR it instead reads only this machine's CLI sessions from
.IR ~/.commandcode/projects
(offline, no API key required, misses other harnesses).  \fB\-\-json\fR
emits one JSON object per day on its own line, then a totals object on a
line with key "total".
.TP
.B hourly
Same cumulative\-differencing method as \fBdaily\fR but over UTC hour
boundaries for the last \fI\-\-hours\fR N hours (default 24, max 168).
\fB\-\-local\fR reads CLI\-log hour buckets offline.  \fB\-\-json\fR emits
rows then a totals line.
.TP
.B model
Local usage grouped by model, read from
.IR ~/.commandcode/projects
(offline; the usage API exposes no per\-model split).  \fB\-\-json\fR
supported.
.TP
.B session
Local usage grouped by project/session directory, same offline file.
\fB\-\-json\fR supported.
.TP
.B models
Live model list from the provider endpoint
.I GET https://api.commandcode.ai/provider/v1/models
\-\- the same source the account plan gating uses.  Unfiltered by plan
unless \fB\-\-gated\fR is given, in which case only the current plan's
allowed models are shown (see the OPTIONS entry for \fB\-\-gated\fR).
Text rows are sorted by display name as
.IR "NAME  CONTEXT  ID" ,
where CONTEXT is a human K/M count or "\-" when the API omits it.
\fB\-\-json\fR prints one JSON object per model per line with keys id, name,
context_length, owned_by.
.TP
.B plans
Print the plan comparison table (name, price, monthly credits, 5\-hour and
weekly caps), marking the current plan with a leading "*" matched by exact
display name, so "individual\-goat" does not mark the Go row.  The current
plan is fetched best\-effort; with no key or network no row is marked.
For the JSON form, see \fB\-\-json\fR under OPTIONS.
.TP
.B statusline
Fetch once and print a single compact line (no trailing newline) built from
the configured statusline template.  Suitable for shell prompts, tmux
status, and headless scripts.  On any API error prints
.I "cmduse: <error>"
to stdout and exits 1.  \fB\-\-json\fR prints one JSON object:
plan, monthlyRemaining, monthlyCap, fiveHourUsed, fiveHourCap, weeklyUsed,
weeklyCap (all dollars as JSON numbers; plan is the human name such as
"GOAT").
.TP
.B config set \fIkey\fR=\fIvalue\fR ...
Merge the given settings into
.I ~/.config/cmd\-usage/config.json
(or
.IR $XDG_CONFIG_HOME/cmd\-usage/config.json )
and print the resulting values.  Keys and valid ranges:
.RS
.TP
interval=\fIs\fR
refresh seconds, 1\(en86400.
.TP
width=\fIn\fR
bar width, 5\(en200.
.TP
burst_on=\fIbool\fR
show the spend\-burst sparkline row in watch mode (default true).
.TP
burst=\fIn\fR
sparkline sample count, 5\(en240 (default 40).
.TP
sl=\fIstring\fR
statusline template, see STATUSLINE.
.TP
sl_colors=\fIbool\fR
ANSI colors in the statusline (default true).
.TP
sl_ascii=\fIbool\fR
use "#\-" bars instead of the "\[ha]"/dash glyphs in the statusline (default
false).
.RE
Unknown keys, non\-numeric values, and out\-of\-range values abort with a
message and exit 2; nothing is written.
.SH OPTIONS
.TP
.B \-1, \-\-once
Fetch once, print, exit.  Without this, watch mode runs forever until
Ctrl\-C.  With \fB\-\-json\fR it prints one JSON object (plan, status,
periodEnd, monthlyCredits, monthlyCap, purchasedCredits, freeCredits,
fiveHour, weekly, summary, error) instead of the text dashboard.
.TP
.B \-p, \-\-plain
No ANSI colors and no live redraw (used with \fB\-1\fR for scripts/pipes).
In watch mode it keeps the plain text render but still redraws in place.
.TP
.B \-i, \-\-interval \fIdur\fR
Refresh interval (1\(en86400 seconds).  Accepts a unit suffix:
.I 30s ", " 5m ", " 1h ", " 2d
(bare number = seconds).  Overrides config \fBinterval_secs\fR.
.TP
.B \-w, \-\-bar\-width \fIn\fR
Progress bar width (5\(en200).  Overrides config \fBbar_width\fR.
.TP
.B \-b, \-\-bursts \fIn\fR
Show the spend\-burst sparkline for this run with N samples (5\(en240);
implies it on regardless of config.
.TP
.B \-\-tz \fI\(+-HH:MM\fR
.BR daily " / " hourly :
bucket by this fixed UTC offset instead of UTC.  Accepts
.I +05:30 ", " -08:00 ", " +0530 ", " -8 .
.TP
.B \-\-days \fIn\fR
.BR daily : number of days back (1\(en365).
.TP
.B \-\-hours \fIn\fR
.BR hourly : number of hours back (1\(en168).
.TP
.B \-\-json
Machine\-readable output where the subcommand supports it.
.TP
.B \-\-gated
.BR models :
keep only models the current plan may use.  Uses the plan id plus purchased
and free credits; purchased/free credits unlock everything, an unknown plan
shows everything.  The gate is a close approximation of the API's (the
server enforces the real limit), so a misclassification could show or hide
one model.  With \fB\-\-json\fR it does not filter: every model is emitted
with additional \fBallowed\fR (bool) and \fBreason\fR (string) fields.
.TP
.B \-W, \-\-watch
Force watch mode (the default).  Conflicts with
.BR \-1 ;
supplying both exits 2.
.TP
.B watch
Bare\-word alias for
.BR \-W .
.TP
.B \-\-local
.BR daily " / " hourly :
read only this machine's CLI logs; no network.
.TP
.B \-V, \-\-version
Print \fBcmduse <version>\fR and exit 0.
.TP
.B \-h, \-\-help
Print usage and exit 0.  Accepts "help" as a bare word too.
.TP
.B config
Config subcommand; see SUBCOMMANDS.
.SH THE LIVE DASHBOARD
With no subcommand, \fBcmduse\fR renders a frame and rewrites it in place
every interval.  All line content is clipped to the terminal width and the
frame never exceeds what the window holds, so it cannot wrap or scroll
during normal operation.
.SS Layout (full mode)
The frame is, top to bottom:
.RS
.nf
Command Code Usage . GOAT . active
Period ends 2026-09-27

Credits $44.15 / $70.00 monthly . $0.00 purchased . $0.00 free

Usage windows
 Monthly   36.9% <bar> $25.85 / $70.00 . resets in 18d 0h . window 42% elapsed
 5-hour    11.1% <bar> $1.55  / $14.00 . resets in 2h 22m . window 59% elapsed
 Weekly    55.7% <bar> $19.61 / $35.00 . resets in 1d 18h . window 75% elapsed

This billing period
 Requests 2.7K . Cost $26.63 . Tokens 402.1M in / 721.2K out . Success 100%
.fi
.RE
When enabled and there was nonzero spend in the last samples, an extra
spend\-burst row precedes the last (status) line.
.PP
Line semantics:
.TP
Header
Plan display name (see below) and subscription status.
.TP
Period ends
The UTC billing cycle end date, from the subscription's
\fBcurrentPeriodEnd\fR.  Exactly the first 10 characters (YYYY\-MM\-DD).
.TP
Credits
Remaining monthly credits, purchased credits, and free credits.  The cap
shown is from the local plan table (see PLAN TABLE), not from the API.
.TP
Usage windows
Three rows.  Bar fill is used/cap; the percentage is used/cap; "used / cap"
is in dollars; "resets in" is wall time until the window rolls;
"window N% elapsed" is time since the window start divided by its length.
Monthly's used is derived: monthly cap minus remaining credits.  Its cap and
period come from the plan table and the subscription period.  5\-hour and
weekly data (used, cap, resetAt) come verbatim from the API
\fBwindowLimits\fR response and are never derived.
.TP
On pace warning
When a window is at least 10% elapsed AND the current spend rate
(used since window start, divided by seconds since window start) projects
hitting the cap before the window resets, the row gains
\fI. on pace to hit cap in <Xh Ym>\fR.  Under 10% elapsed no projection is
shown (a flat extrapolation from minutes of data is noise).  The projection
assumes a flat spend rate; bursty sessions shift it.
.TP
This billing period
Cumulative request count, cost, input/output tokens (human K/M compact) and
success rate, from the usage summary endpoint.
.SS Window math (exact)
A window of length L seconds ends at instant R (epoch ms, from the API or,
for monthly, the subscription period end parsed as ISO 8601 UTC).  Its start
is R \- L.  Elapsed percent is
.IR "(now \- start) / L ",
clamped to 0\(en100, rounded to a whole percent.  "Resets in" is R \- now,
rendered as "Nd Nh" when a day or more, "Nh Nm" when an hour or more, "Nm"
when a minute or more, else "<1m".  When now >= R it renders "resetting..."
(the next fetch carries the fresh window).  Pace ETA is
.IR "used / (now \- start) ",
giving a dollars\-per\-second rate; seconds\-to\-cap is
.IR "(cap \- used) / rate";
it is shown only when that lands before R and the 10% gate passes.  ISO
dates parse as UTC when suffixed with Z or lacking a suffix, and honor an
explicit +HH:MM or \-HH:MM (or basic +HHMM) offset by shifting the civil
reading; a time with no offset is read as UTC.
.SS Compact mode
The terminal size is re\-queried every refresh.  When the window is smaller
than 40 columns by 16 rows the full frame is replaced by a single content
line:
.RS
.nf
GOAT $44.15/$70.00 . 5h $1.55
.fi
.RE
followed by the status line.  When the window is resized back over the
threshold the full frame returns, in place.  Even a very small window (a few
columns) keeps redrawing the clipped compact line stably; there is no exit
and no shredding.
.SS Status line and countdown
The final frame line is the status line:
.I "refreshing every <N>s . ctrl-c to quit"
Between refreshes, each second the line rewrites in place as
.I "refreshing every <N>s . next refresh in <K>s . ctrl-c to quit"
.IR "K" " = N\-1 .. 1".
Both lines are clipped to the terminal width if needed; a line exactly at
the width is legal (no wrap), longer content is truncated at the width.
.SS Spend\-burst sparkline
On by default; disabled with
.BR "config set burst_on=false" .
It is one row, labeled
.I "spend bursts (<N>s samples) "
followed by the history rendered as an 8\-level bar chart.  Each bar is the
dollar delta of the 5\-hour window's cumulative used between two consecutive
refreshes, so a tall bar means spend during that interval and a flat line
means idle.  Sample count is config \fBburst_samples\fR (default 40) or
\fB\-b\fR on the command line; at a 5s interval 40 samples is about 3
minutes.  The row is hidden while every retained delta is zero, so idle
screens stay quiet.  History is session\-only: it starts empty each run and
never shows spend from earlier sessions.  Zero scale renders an all\-low
row.
.SH PLAN TABLE
Plan detection lowercases the API plan id and matches substrings in this
order: "enterprise" -> Enterprise, "provider" -> Provider,
"team" -> Team Pro, "max" with "20" -> Max 20x, "max" without
-> Max 10x, "goat" -> GOAT, "pro" -> Pro, "go" -> Go,
anything else -> Free.
.PP
Monthly credit pool by plan (single shared pool, verified empirically; the
docs' per\-model allowances are not what the API meters):
.IP Go
$10
.IP GOAT
$70
.IP Pro
$80
.IP Max 10x
$150
.IP Max 20x
$300
.IP Team Pro
$40
.IP Enterprise / Provider
none (pay\-as\-you\-go; no monthly cap row)
.PP
The 5\-hour and weekly caps (e.g. $14 / $35 on GOAT) are NOT in this table;
they come from the API
.B windowLimits
response and must not be derived client\-side.
.SH STATUSLINE
The statusline template supports the placeholders
.I {plan} {credits} {cap} {credits_bar} {5h_bar} {5h_pct} {5h_used} {5h_cap} {5h_eta}
.I {wk_bar} {wk_pct} {wk_used} {wk_cap} {wk_eta}
. Unknown placeholders are dropped; an unclosed brace passes through;
multi\-line templates are allowed.  \fBsl_colors=false\fR strips ANSI after
rendering; \fBsl_ascii=true\fR renders bars with "#" and "\-" instead of the
box glyphs.  {credits} is remaining monthly credits, {cap} the plan monthly
cap.  {5h_eta} and {wk_eta} render the pace warning text ("on pace to hit cap
in 2h 3m") or an empty string when no warning applies.  The same template
engine renders both the statusline subcommand and any statusline template in
a shell prompt.
.SH API ENDPOINTS
All requests go to
.IR https://api.commandcode.ai ,
with header
.I Authorization: Bearer <apiKey>
and Accept: application/json.  Endpoints:
.IP "GET /alpha/billing/subscriptions"
plan id, status, current period start/end.
.IP "GET /alpha/billing/credits"
credits object (monthly/purchased/free) and windowLimits (fiveHour, weekly;
each with used, cap, resetAt in ms).
.IP "GET /alpha/usage/summary"
cumulative totals: count, cost, tokens in/out, success rate.
.IP "GET /alpha/usage/summary?since=<ISO>"
same shape, cumulative since the ISO instant (used by daily/hourly
differencing).
.IP "GET /provider/v1/models"
live model list; each entry has id, and may have name, context_length,
owned_by.
.PP
Transient failures (TLS handshake drops, timeouts, EOF, 429, and any 5xx)
are retried up to 5 times with an exponential backoff (1s base, 8s cap,
jitter); a hard 15s per\-attempt timeout applies.  A watch\-mode fetch that
still fails renders a minimal error frame:
.RS
.nf
Command Code Usage . fetch failed
error: <joined per-endpoint errors>
retrying on next refresh
.fi
.RE
and the next interval retries; no fake zero data is shown.
.SH FILES
.TP
.I ~/.commandcode/auth.json
Read; API key.  Written by the Command Code CLI.
.TP
.I ~/.commandcode/projects
Read; per\-project CLI usage logs used by \fBdaily\fR/\fBhourly\fR
\fB\-\-local\fR, \fBmodel\fR, \fBsession\fR.  JSON lines.
.TP
.I ~/.config/cmd\-usage/config.json
Config, or
.I $XDG_CONFIG_HOME/cmd\-usage/config.json
when XDG_CONFIG_HOME is set.  Missing/corrupt files silently fall back to
defaults (a corrupt file prints a warning to stderr).  Keys:
.RS
.TP
interval_secs
integer 1\(en86400, default 5.
.TP
bar_width
integer 5\(en200, default 20.
.TP
burst_enabled
boolean, default true.
.TP
burst_samples
integer 5\(en240, default 40.
.TP
notify_on_cap
boolean, default true.  In watch mode fire a desktop notification once when a
window crosses into overflow.
.TP
statusline_template
string, default "{plan} {credits}/{cap} . 5h {5h_bar} . wk {wk_bar}".
.TP
statusline_colors
boolean, default true.
.TP
statusline_ascii
boolean, default false.
.RE
Unknown keys are preserved on config set (the file is rewritten from the
merged struct, so unknown keys are actually dropped on the next
.I "config set"
write; hand\-editing extra keys is tolerated until a config set rewrites the
file).
.SH ENVIRONMENT
.TP
.B XDG_CONFIG_HOME
Base for the config file when set.
.TP
.B HOME
Base for auth, projects, config (fallback), and cache paths when
XDG_CONFIG_HOME is unset.
.SH EXAMPLES
.nf
cmduse                     # live dashboard, 5s refresh
cmduse -1                  # one shot
cmduse -1 -p               # plain one shot (scripts)
cmduse -i 30 -w 40         # slower refresh, wider bars
cmduse -b 120              # sparkline with 120 samples
cmduse daily --days 14     # account usage, two weeks
cmduse daily --local       # this machine only
cmduse hourly --hours 6
cmduse models
cmduse statusline
cmduse config set interval=10 burst_on=false
.fi
.SH BUGS / NOTES
Rendering edge cases were observed against real terminals:
.IP \(bu
A frame taller than the terminal scrolls on refresh; that is why watch mode
switches to compact mode under 40x16 and clips every line to the width.
.IP \(bu
Never add a trailing newline after the frame's last line and never write a
bare newline at the very bottom row of the window; both desync the in\-place
redraw in real terminals.
.IP \(bu
Account dailies and hourlies are UTC; a session near a midnight boundary
splits across two day rows.
.SH SEE ALSO
.BR cmd (1),
the Command Code CLI for login and authentication.