cmd-usage 0.7.27

Live Command Code (commandcode.ai) usage dashboard: credits, 5-hour and weekly windows, plan limits. Watch mode or one-shot.
Documentation
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
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
.TH CMDUSE 1 "2026-10" "cmd-usage 0.7.8" "User Commands"
.SH NAME
cmduse \- live Command Code (commandcode.ai) usage dashboard and reporter
.br
ocuse \- OpenCode Go/Zen usage (Go's usage endpoint plus local opencode data)
.br
arkuse \- Volcengine ARK Agent Plan usage in AFP (control\-plane meters plus local opencode data)
.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\-\-csv\fR] [\fB\-\-local\fR]
.br
.B cmduse hourly
[\fB\-\-hours\fR \fIn\fR] [\fB\-\-json\fR] [\fB\-\-csv\fR] [\fB\-\-local\fR]
.br
.B cmduse model
[\fB\-\-days\fR \fIn\fR | \fB\-\-since\fR \fIISO\fR]
[\fB\-\-json\fR] [\fB\-\-csv\fR]
.br
.B cmduse session
[\fB\-\-days\fR \fIn\fR | \fB\-\-since\fR \fIISO\fR]
[\fB\-\-json\fR] [\fB\-\-csv\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 mcp
.br
.B cmduse config set
\fIkey\fR=\fIvalue\fR [\fIkey\fR=\fIvalue\fR ...]
.br
.B cmduse \-V
.br
.B cmduse \-h
.br
.B ocuse
[\fIOPTIONS\fR]
.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.  The same crate also
ships a second binary,
.BR ocuse ,
which tracks OpenCode Go and OpenCode Zen; it shares this manual's
presentation and is documented under
.BR OCUSE .
A third binary,
.BR arkuse ,
tracks a Volcengine ARK Agent Plan in the plan's own unit (AFP) and is
documented under
.BR ARKUSE .
.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).  Days are bucketed
in UTC unless \fB\-\-tz\fR is given, which applies to both the API and the
local path.  \fB\-\-json\fR emits one object
\fI{"scope","total","days"}\fR where \fIdays\fR maps each date to its totals.
\fB\-\-csv\fR emits
\fIday,requests,tokens_in,tokens_out,cache_read,cache_write,cost_usd\fR
with a final \fItotal\fR row.
.TP
.B hourly
Same cumulative\-differencing method as \fBdaily\fR but over hour
boundaries (UTC unless \fB\-\-tz\fR) for the last \fI\-\-hours\fR N hours
(default 24, max 168).  \fB\-\-local\fR reads CLI\-log hour buckets offline
and honors \fB\-\-tz\fR.  \fB\-\-json\fR emits one object
\fI{"scope","source","hours"}\fR; \fB\-\-csv\fR emits
\fIhour,requests,tokens_in,tokens_out,cost_usd\fR.
.TP
.B model
Local usage grouped by model, read from
.IR ~/.commandcode/projects
(offline; the usage API exposes no per\-model split).  All\-time by default:
\fB\-\-days\fR \fIn\fR or \fB\-\-since\fR \fIISO\fR bounds the window, and
\fB\-\-json\fR reports \fIsource\fR + \fIsince\fR alongside \fImodels\fR.
Passing a model id instead (.B model \fIid\fR) prints that one model's
requests, tokens, cost and share of the window, as \fBocuse\fR and
\fBarkuse\fR do.
\fB\-\-json\fR and \fB\-\-csv\fR supported; the \fITokens\fR column sums
input, output, cache read, and cache write.
.TP
.B session
Local usage grouped by project/session directory, same offline file.
\fB\-\-json\fR and \fB\-\-csv\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 mcp
Run an MCP (Model Context Protocol) stdio server: newline\-delimited
JSON\-RPC on stdin/stdout, diagnostics on stderr.  Exposes seven tools \(
usage, plans, models, daily, hourly, session, model \) whose output is the same
text the corresponding subcommands print.  The seven tools and their
arguments are identical across \fBcmduse\fR, \fBocuse\fR and \fBarkuse\fR
(each adds \fBplan\fR, the plan its source needs): \fBmodels\fR takes
\fIgated\fR, \fBdaily\fR/\fBhourly\fR take \fItz\fR, and
\fBsession\fR/\fBmodel\fR take \fIsince\fR, \fIdays\fR and \fIrows\fR.
Tool execution errors are returned as
results with isError true, not JSON\-RPC errors.  Intended for MCP hosts
such as Zed's context_servers ("command": "cmduse", "args": ["mcp"]).
.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
Options accept \fB\-\-name value\fR, \fB\-\-name=value\fR, and an attached short
value (\fB\-i30\fR, \fB\-w40\fR).
.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.
Colors are also dropped automatically on a non\-terminal stdout or when
\fBNO_COLOR\fR is set.
The plain render carries the same fields as the colored dashboard: period end,
monthly quota (remaining / cap), a Monthly allowance row with its
"$X by now" pro\-rata figure, "window N% elapsed" on every window row, and the
"on pace to hit cap in ..." burn\-rate warning when the current rate reaches
the cap before the window resets.
.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.  Applies to the account API
path and the \fB\-\-local\fR log path alike.  Accepts
.I +05:30 ", " -08:00 ", " +0530 ", " -8 .
.TP
.B \-\-days, \-\-last, \-l \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 \-\-rows \fIn\fR
Table rows to print for \fBmodels\fR, \fBmodel\fR and \fBsession\fR.
\fI0\fR means every row.  Without the flag the reports print every row
(\fBsession\fR prints 20) and the live frame keeps its 15 row panel.  A trimmed
table ends with \fI\[u2026] N more\fR; \fB\-\-json\fR and \fB\-\-csv\fR always
carry every row, because a report is data and a short one would read as the
whole period.
.TP
.B \-\-json
Machine\-readable output where the subcommand supports it.  Conflicts with
\fB\-\-csv\fR (supplying both exits 2).
.TP
.B \-\-csv
CSV output for \fBdaily\fR, \fBhourly\fR, \fBmodel\fR, and \fBsession\fR.
Fields containing a comma, quote, or newline are quoted per RFC 4180.
.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.  If the
bundled gating snapshot is older than 30 days a warning is printed to stderr.
.TP
.B \-\-dismiss\-update
Acknowledge the current update notice: records the newest crates.io version
(same as
.BR "config set dismissed_update=<ver>" )
and exits.  The notice stays hidden until an even newer version appears.
.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 . $29.40 by now
 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 also carries "$X by now": the monthly cap pro\-rated to that elapsed
share (cap x elapsed%), i.e. what an even burn would have consumed by this
point \- compare it against the actual used figure.  It is Monthly\-only: the
5\-hour and weekly caps are throttles rather than budgets, so a pro\-rata
figure there would read as a spend target.
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 429's numeric
\fBRetry\-After\fR is honored (capped at 60s) in place of the computed backoff.  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 ~/.cache/cmd\-usage/last\-check
Written; JSON recording the last update\-check time and newest known version.
Deleting it forces a fresh check on the next run.
.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.
.TP
check_updates
boolean, default true.  When false, never contact crates.io to check for a
newer \fBcmd\-usage\fR.
.TP
dismissed_update
version string or null.  Suppresses the update notice for exactly this
version; a newer release shows again.
.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.
.TP
.B NO_COLOR
When set to a non\-empty value, ANSI colors are suppressed (no\-color.org).
Colors are also suppressed automatically when stdout is not a terminal, so
piping a report or `cmduse \-1` never leaks SGR escapes.
.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 and local dailies/hourlies bucket in UTC by default; pass
\fB\-\-tz\fR to bucket by a fixed offset.  Without it, a session near a UTC
midnight boundary splits across two day rows.
.IP \(bu
If the API returns a plan id not in the local plan table, the dashboard labels
it "Free" with no monthly cap and prints a one\-time warning to stderr; update
\fIcore/plans.json\fR to teach it the new plan.
.SH OCUSE
The same crate also ships a second binary,
.BR ocuse ,
which tracks OpenCode Go (the Go subscription) and OpenCode Zen
(pay\-as\-you\-go) with the same CLI shape as \fBcmduse\fR.  OpenCode Go
exposes the console's own usage endpoint,
.IR GET\ /zen/go/v1/usage ,
which reports the three account meters \(em
.I rolling
(5\-hour),
.IR weekly ,
and
.I monthly
\(em each a percent of its limit and a reset instant, so
.B ocuse
reads those for its window rows (the credential from
.IR $OCUSE_API_KEY ", " $OPENCODE_API_KEY ,
else the live credential opencode itself is using \(em
.B credential
in opencode's store, where v2 and
.B /connect
write it \(em with the legacy
.I auth.json
as the fallback for a v1 install).
It reports what actually ran on this machine from opencode's own store for
everything the endpoint does not carry \(em the per\-model table,
\fBdaily\fR/\fBhourly\fR, tokens \(em priced by opencode itself, against the
token rates and per\-model limits the OpenCode docs publish (the generated
catalogue
.IR core/zen.json ).
The endpoint's figures win wherever both exist: the server's 5\-hour window is
a block with its own reset, its week is anchored to Monday 00:00 UTC, its month
is the subscription anniversary, and it meters with its own price basis, none
of which is reproducible from the store.  With no key, no network, or
\fB\-\-no\-api\fR, the windows fall back to a local estimate and the dashboard
labels them as such \(em and names the reason under the \fBGO\fR heading when
there is one (\fIusage API: HTTP 401 api_key_expired\fR), because the estimate
alone cannot tell a missing key from an expired one.  The same line rides in
\fB\-\-json\fR as \fIaccountError\fR (\fBnull\fR when the endpoint answered, and
for \fB\-\-no\-api\fR, which is a choice rather than a fault).  An expired Go
key is not renewed by signing in again: it has to be replaced in the OpenCode
console.
.PP
Go meters per model: each model has a monthly dollar limit, and its 5\-hour,
weekly, and monthly windows are fixed shares of that limit (20%, 50%, and
100%).  Go ships as two plans that share one token price list but grant
different per\-model limits: Go and Go Plus.  Neither the store nor the usage
endpoint names the plan the account is on, so the plan is explicit
(\fB\-\-plan\fR) and defaults to
.BR go .
.SS ocuse synopsis
.B ocuse
[\fIOPTIONS\fR]
.br
.B ocuse \-1
[\fB\-\-json\fR] [\fIOPTIONS\fR]
.br
.B ocuse model
[\fIid\fR] [\fB\-\-since\fR \fIISO\fR] [\fB\-\-json\fR | \fB\-\-csv\fR] [\fIOPTIONS\fR]
.br
.B ocuse daily
[\fB\-\-days\fR \fIn\fR] [\fB\-\-json\fR | \fB\-\-csv\fR] [\fIOPTIONS\fR]
.br
.B ocuse hourly
[\fB\-\-hours\fR \fIn\fR] [\fB\-\-json\fR | \fB\-\-csv\fR] [\fIOPTIONS\fR]
.br
.B ocuse session
[\fB\-\-since\fR \fIISO\fR] [\fB\-\-json\fR | \fB\-\-csv\fR]
.br
.B ocuse models
[\fB\-\-gated\fR] [\fB\-\-json\fR]
.br
.B ocuse plans
[\fB\-\-json\fR]
.br
.B ocuse statusline
[\fB\-\-json\fR] [\fIOPTIONS\fR]
.br
.B ocuse mcp
.br
.B ocuse \-V
.br
.B ocuse \-h
.SS ocuse commands
.TP
.B (no command)
Run the live dashboard in watch mode: a frame redrawn in place every 10
seconds (colour, severity gauges, and the spend\-burst sparkline) until
Ctrl\-C.  The frame and countdown reuse \fBcmduse\fR's in\-place redraw
contract, so a shrinking frame never scrolls.
.TP
.B \-1, \-\-once
Fetch once, print, exit.  With \fB\-\-json\fR it prints the JSON projection
instead of the text dashboard.
.TP
.B \-\-json
Machine\-readable projection (one object): \fIsource\fR, \fIgeneratedAt\fR,
\fIperiodStart\fR (and its alias \fIperiodStartAt\fR, both epoch ms),
\fIperiodEndAt\fR (the resolved end of the period in epoch ms, \fBnull\fR for
\fB\-\-window all\fR, whose range has no boundary), \fIperiodInferred\fR,
\fIaccount\fR (the three account meters from Go's usage endpoint \(em
\fIrolling\fR, \fIweekly\fR, \fImonthly\fR, each \fI{status, percent,
resetsAt}\fR with \fIresetsAt\fR in epoch ms \(em or \fBnull\fR when the
endpoint was not reached), \fItotals\fR (each of month, fiveHour,
weekly carrying cost, requests, and tokens), and the per\-model breakdown
\fImodels\fR.  A bare \fB\-\-json\fR also leaves the watch loop, so it prints
and exits rather than redrawing.
.TP
.B model [\fIid\fR]
Local usage grouped by model.  With no \fIid\fR, the full model table; with an
\fIid\fR, that model's limit, its month/5\-hour/weekly spend, and its share of
period spend.  An unused model prints that it has no usage in the period.
\fB\-\-since\fR \fIISO\fR pins the window start (an exact instant, outranking
\fB\-\-window\fR and \fB\-\-period\-start\fR).  \fB\-\-json\fR emits one object
\fI{"scope","source","sinceMs","models"}\fR whose \fImodels\fR map each id to
requests, tokensIn, tokensOut, cacheRead, costUsd and its limit; \fB\-\-csv\fR
emits \fImodel,requests,tokens_in,tokens_out,cache_read,cost_usd\fR.
.TP
.B daily
Spend per day (oldest first) over the read window (\fB\-\-days\fR), bucketed in
the display timezone (\fB\-\-tz\fR).  \fB\-\-json\fR emits
\fI{"scope","source","total","days"}\fR; \fB\-\-csv\fR emits
\fIday,requests,tokens_in,tokens_out,cache_read,cost_usd\fR with a final
\fItotal\fR row.
.TP
.B hourly
Spend per hour, same bucketing as \fBdaily\fR but over the last \fB\-\-hours\fR
N hours (default 24, max 168).  \fB\-\-json\fR emits
\fI{"scope","source","total","hours"}\fR; \fB\-\-csv\fR emits
\fIhour,requests,tokens_in,tokens_out,cache_read,cost_usd\fR with a final
\fItotal\fR row.
.TP
.B session
Spend per session, newest first (top 20).  \fB\-\-since\fR \fIISO\fR pins the
window start.  \fB\-\-json\fR emits \fI{"scope","source","sessions"}\fR (each
entry adding the last\-used instant and the distinct\-model count);
\fB\-\-csv\fR emits
\fIsession,requests,tokens_in,tokens_out,cache_read,cost_usd\fR.
.TP
.B models
The Go catalogue for the selected plan: each model's name, id, \fB$\fR/1M
in/out/cache\-read rates, the plan's monthly limit, and a \fIGRANTED\fR column.
Without \fB\-\-gated\fR every catalogued model is listed and marked;
\fB\-\-gated\fR keeps only the models the plan grants (present in the plan's
allowance map).  \fB\-\-json\fR prints one JSON object per line with keys id,
name, input, output, cacheRead, limit (null when not granted) and granted.
Needs no database; works offline.
.TP
.B plans
Print the Go/Zen catalogue: both Go plans (label, price, and each model's
monthly limit) beside the shared token rates, then a line for the Zen
pay\-as\-you\-go models.  \fB\-\-json\fR emits one object with
\fIextractedAt\fR, \fIwindows\fR (the 5\-hour/weekly/monthly shares),
\fIplans\fR (id, label, priceUsd, allowanceByModel), and the Go and Zen rate
tables.  Needs no database; works offline.
.TP
.B statusline
Print one compact line: month spend, 5\-hour spend, and the top model.
\fB\-\-json\fR prints one object: plan, period, monthSpent, monthCap,
fiveHourSpent, fiveHourCap, weeklySpent, weeklyCap, model.
.TP
.B mcp
Run an MCP stdio server; see \fBocuse mcp server\fR below.
.TP
.B \-V, \-\-version
Print \fBocuse <version>\fR and exit 0.
.TP
.B \-h, \-\-help
Print usage and exit 0.
.SS ocuse options
.TP
.B \-\-db \fIpath\fR
opencode store path.  Default \fBOPENCODE_DB\fR, else
.IR ~/.local/share/opencode/opencode.db .
Opened read\-only, so a running opencode is unaffected; a missing or
unreadable store exits 1 with a hint.
.TP
.B \-\-plan \fIid\fR
Which Go plan to measure against: \fBgo\fR (default) or \fBgo-plus\fR.  There
is deliberately no auto\-detection: the usage endpoint reports percentages
rather than a plan id, and the local store records no subscription, so the plan
must be given.  An unknown id exits 2 and lists the known ids.
.TP
.B \-\-no\-api
Do not call OpenCode Go's usage endpoint: report the local estimate only.
Useful offline, or to compare the local windows against the account's.
.TP
.B \-\-days \fIn\fR
Days of history to read (default 120).  Bounds the
\fBdaily\fR window and the range the MCP tools scan.
.TP
.B \-\-hours \fIn\fR
Hours of history for \fBhourly\fR (default 24, max 168).
.TP
.B \-\-gated
models: keep only the models the selected plan grants.
.TP
.B \-\-window \fIw\fR
Reporting window for the dashboard and statusline: \fBmonth\fR (default, the
calendar month in UTC), \fBall\fR, or \fI<n>d\fR.  Anything else exits 2.
.TP
.B \-\-period-start \fIYYYY\-MM\-DD\fR
Pin the period start (midnight UTC) instead of deriving it from
\fB\-\-window\fR.
.TP
.B \-\-infer\-anniversary
Infer the period start from the first Go request ever seen, instead of the
calendar month.  Opt\-in, because sparse history infers badly; ignored when
\fB\-\-period-start\fR or \fB\-\-since\fR is given.  The JSON's
\fIperiodInferred\fR reports which
was used.
.TP
.B \-\-since \fIISO\fR
Window start for \fBmodel\fR/\fBsession\fR as an exact ISO\-8601 instant
(\fI2026\-08\-27T00:00:00Z\fR).  Outranks \fB\-\-window\fR and
\fB\-\-period\-start\fR; an unparseable value exits 2.
.TP
.B \-\-json
Machine\-readable output for every subcommand that has one: the dashboard
(\fB\-1\fR), \fBdaily\fR, \fBhourly\fR, \fBmodel\fR, \fBsession\fR,
\fBmodels\fR, \fBplans\fR, \fBstatusline\fR.  Never coloured.
.TP
.B \-\-csv
CSV output for \fBdaily\fR, \fBhourly\fR, \fBmodel\fR and \fBsession\fR
(the columns carry the store's fields; there is no cache\-write column).
Never coloured.  Supplying both \fB\-\-json\fR and \fB\-\-csv\fR exits 2.
.TP
.B \-\-rows \fIn\fR
Table rows to print (default 15).
.TP
.B \-\-plain
No colour and no gauges.  Colour is also dropped automatically on a
non\-terminal stdout or when \fBNO_COLOR\fR is set.
.TP
.B \-\-tz \fI\(+-HH:MM\fR
Display timezone for the \fBdaily\fR/\fBhourly\fR buckets.  Accepts
.IR +05:30 ", " -08:00 ", " +0530 .
Anything else exits 2.
.SS ocuse data and windows
When Go's usage endpoint answers, the header's three window lines are the
account's own meters (the shares and resets \fBopencode.ai/console\fR shows),
each with this store's own spend beside the server's share of the
limit \(em priced on the documented peak/off\-peak schedule, because opencode
records the off\-peak sheet for every turn and would read about 40% under the
console on a peak\-heavy day \(em the two need not agree, so the share carries its own \fIof limit\fR label
\(em and the billing period comes from the endpoint's monthly reset instant \(em
the subscription anniversary, which is why the period line reads
\fIGo billing month\fR.  No dollar denominator is printed: any ceiling
derived from one side contradicts the other \(em \fIspend / share\fR offered
\fI$40\fR against a documented \fI$80\fR monthly allowance, and the summed
per\-model limits were the old \fI$215\fR.  The burn still gets an \fIon pace
to hit cap in\fR ETA, and the monthly row \(em the one budget \(em its
\fI$X by now\fR pro\-rata figure.
Each model's table row still compares its own spend
against its monthly limit; the table's \fI5H\fR/\fIWK\fR columns are local
rolling windows (this model's spend over the last 5 hours / 7 days), and the
dashboard says so rather than letting them read as a second opinion.
.TP
Without the endpoint \(em no Go key, no network, or \fB\-\-no\-api\fR \(em the
window lines are a local estimate and are labelled as one: the rows carry
spend alone, since limits are per model and no account\-wide pool exists to
divide by.  Only the monthly period has a real end, so that row alone gains
a reset countdown and its \fIwindow N% elapsed\fR share; the rolling 5\-hour
and weekly rows show no countdown.  The period defaults to the calendar month, with
\fB\-\-period\-start\fR pinning the real anniversary and
\fB\-\-infer\-anniversary\fR guessing it from history.  The header splits period tokens
\fIin / out\fR and names the resolved end date.  A model whose spend
crosses its limit is flagged \fILIMIT EXCEEDED\fR.  There is no
\fISuccess N%\fR figure \(em opencode's store records no per\-request success
or error signal.  Limits and rates come from
.IR core/zen.json ,
regenerated from OpenCode's own docs sources with
.BR "bun scripts/extract\-zen.ts" .
.SS ocuse mcp server
\fBocuse mcp\fR runs an MCP stdio server (newline\-delimited JSON\-RPC on
stdin/stdout, diagnostics on stderr) exposing seven tools \(em \fIusage\fR,
\fIplans\fR, \fImodels\fR, \fIdaily\fR, \fIhourly\fR, \fIsession\fR,
\fImodel\fR \) whose output matches the corresponding subcommands.  Tool
execution errors are returned as results with \fIisError\fR true, never as
JSON\-RPC errors.  stdout carries protocol traffic only.
.SS ocuse files
.TP
.I ~/.local/share/opencode/opencode.db
Read\-only; opencode's own message store (v1 \fBmessage\fR, or v2
\fBsession_message\fR after the migration), the only per\-model cost source.
.TP
.I $OPENCODE_DB
Overrides the store path (equivalently, \fB\-\-db\fR).
.TP
.I ~/.local/share/opencode/auth.json
Read (never written) as the fallback Go key \(em the legacy v1 location of the
credential \fB/connect\fR stores; on v2 the live one is the \fBcredential\fR row
of opencode's store, which is read first.  \fB$OCUSE_API_KEY\fR and
\fB$OPENCODE_API_KEY\fR override both.
.SS arkuse
.B arkuse
tracks a Volcengine ARK Agent Plan and reports in
.BR AFP ,
the plan's own unit, never in dollars or yuan: one AFP is ¥0.002 at every
tier and a model's coefficient converts tokens into it \(em
\fIAFP = (input + cache_read + output) \(mu coef / 10,000\fR.  Cache reads are
billed; \fIreasoning\fR is not added again because it already sits inside
the output count.  Coefficients, tier gates, promo dates and the plan table
are hand\-maintained in
.IR core/ark.json ,
because the publisher documents them as prose.
.SS arkuse synopsis
.B arkuse
[\fIOPTIONS\fR]
.br
.B arkuse \-1
[\fB\-\-json\fR] [\fIOPTIONS\fR]
.br
.B arkuse model
[\fIid\fR] [\fB\-\-since\fR \fIISO\fR] [\fB\-\-json\fR | \fB\-\-csv\fR] [\fIOPTIONS\fR]
.br
.B arkuse daily
[\fB\-\-days\fR \fIn\fR] [\fB\-\-json\fR | \fB\-\-csv\fR] [\fIOPTIONS\fR]
.br
.B arkuse hourly
[\fB\-\-hours\fR \fIn\fR] [\fB\-\-json\fR | \fB\-\-csv\fR] [\fIOPTIONS\fR]
.br
.B arkuse session
[\fB\-\-since\fR \fIISO\fR] [\fB\-\-json\fR | \fB\-\-csv\fR]
.br
.B arkuse models
[\fB\-\-gated\fR] [\fB\-\-json\fR]
.br
.B arkuse plans
[\fB\-\-json\fR]
.br
.B arkuse statusline
[\fB\-\-json\fR] [\fIOPTIONS\fR]
.br
.B arkuse mcp
.br
.B arkuse \-V
.br
.B arkuse \-h
.SS arkuse commands
Every subcommand, machine format, watch frame, config key, update check and
cap notification mirrors
.BR cmduse 's,
with AFP standing where the other binaries put money.
.TP
.B (no command), \fB\-1\fR
Live watch, or one frame with \fB\-1\fR.  The dashboard shows the plan's own
5\-hour / daily / weekly / monthly meter rows, each with the server's share of
the limit and this store's AFP beside it labelled \fIlocal\fR, then a model
block with each model's coefficient, AFP, requests and share of period AFP.
No per\-model allowance is invented: ARK limits the plan.
.TP
.B daily, hourly, session, model
The same reports as
.BR cmduse .
\fB\-\-csv\fR columns are
\fIday|hour|session|model,requests,tokens_in,tokens_out,cache_read,afp\fR
(no cache\-write column, and AFP replaces cost).  \fBmodel\fR with no id prints
the period's per\-model table.
.TP
.B models
The ARK catalogue with the coefficient in force today (a promo halves it until
its date), the derived ¥/1M tokens, the minimum tier and whether the selected
plan grants the model.  \fB\-\-gated\fR keeps only what the plan grants;
\fB\-\-json\fR is one object per line.  Needs no store.
.TP
.B plans
The personal tiers (price, monthly AFP quota, and the 5\-hour / daily / weekly
quotas), the active promos, the flat AFP rate, and the enterprise seat price
list.  Enterprise AFP is metered per seat and the personal usage API does not
expose it, so only prices appear.  Needs no store.
.TP
.B statusline
One compact line: period AFP, 5\-hour AFP, weekly AFP and the top model.
\fB\-\-json\fR mirrors cmduse's keys (\fImonthSpent\fR,
\fIfiveHourSpent\fR, \fIweeklySpent\fR, the caps \fBnull\fR, \fImodel\fR)
with an extra \fIafp\fR block carrying the monthly yuan figure and the
control plane's \fIaccount\fR object.
.TP
.B mcp
Run an MCP stdio server exposing the same seven tools \(em \fIusage\fR,
\fIplans\fR, \fImodels\fR, \fIdaily\fR, \fIhourly\fR, \fIsession\fR,
\fImodel\fR \) whose output matches the subcommands.
.SS arkuse options
The shared options are those under
.BR "ocuse options" ,
with these differences.
.TP
.B \-\-plan \fItier\fR
The ARK tier: \fIsmall\fR, \fImedium\fR, \fIlarge\fR or \fImax\fR.  Default:
the profile's own \fIplan_tier\fR, else \fImedium\fR.  An unknown tier exits 2
and lists the known ones.
.TP
.B \-\-profile \fIname\fR
The \fBarkcli\fR control\-plane profile to query.  Default
\fB$ARKUSE_PROFILE\fR, else the first profile whose type is
\fIagent\-plan\fR.  An unknown name degrades to the local estimate with the
control plane's own reason on the dashboard.
.TP
.B \-\-no\-api
Skip \fBarkcli\fR entirely and report the local estimate only.  The tier then
comes from \fB\-\-plan\fR or the catalogue default, and no profile is
resolved.
.SS arkuse data and windows
Two sources.  \fBarkcli usage plan\fR returns the plan's own meters with their
reset instants \(em the only figures that see every machine and harness on the
subscription \(em and this store (\fIopencode.db\fR, provider
\fIagent\-plan\fR only) supplies the per\-model attribution and the local
estimate.  The server's windows are not reproducible locally: the 5\-hour
window is a block with its own reset, the week is anchored to Monday 00:00, and
the month is the subscription anniversary, so rows are cut at
\fIreset \(mi window\fR and period dates print in the server's own offset.
A text\-only workload has no daily window; only media and Harness items do.
When no meter answers the rows fall back to a rolling cut and the block is
labelled \fIestimated locally\fR with the reason beside it \(em still as
\fIused / quota\fR against the plan's published split (5\-hour 10%, daily 50%,
weekly 35%, monthly 100% of its AFP), with a percentage and a countdown, so a
window never degrades to AFP alone.  A meter served without figures (a
just\-reset block carries only \fItotal\fR and \fIpercent\fR) is derived rather
than rejected, and its countdown comes from the oldest row still inside the
cut.
.PP
The plan's semantics are surfaced rather than assumed: no downgrade; on an
upgrade the monthly quota is pro\-rated while the 5\-hour and weekly windows
reset to the new tier immediately; plain API calls against the plan base URL
are forbidden (ban risk); the quota is shared across every harness; and
postpaid overflow is opt\-in.  Because ARK limits the plan rather than a model,
\fInotify_on_cap\fR fires per window meter.
.SS arkuse files
.TP
.I ~/.config/arkuse/config.json
The same keys as cmduse's config, set with \fBarkuse config set\fR.
.TP
.I $OPENCODE_DB, \-\-db
The store path; opened read\-only.
.SH SEE ALSO
.BR cmd (1),
the Command Code CLI for login and authentication.
.br
.BR ocuse ,
this crate's OpenCode Go/Zen twin, documented above under
.BR OCUSE .
.br
.BR arkuse ,
this crate's ARK Agent Plan twin, documented above under
.BR ARKUSE .