Problem
The numeric formatters render a fixed decimal count, so whole values carry a
trailing .0: 1.0M, 512.0k, 100.0%, 50.0 t/s. Blanket-stripping it
(the original #456) was rejected: the fixed width stops the field from snapping
as a value crosses a whole unit (1M -> 1.1M -> ...), which Claude Code
itself preserves (6.0k). The fix is to make precision configurable, not to
change the default.
Proposal
A per-widget number-format setting, type-aware, with an optional global.
Default output is unchanged.
Format: numberFormat = { style?, decimals? }
style: precise (keep trailing zeros, today: 1.0M) | compact (drop
trailing zeros, keep real fractions: 1M, 1.1M) | whole (no decimals: 1M)
decimals: max places before style applies (precise + 2 -> 1.00M)
Type-aware defaults
Each numeric widget has a number kind with its own default, so one setting
does the right thing per type:
| kind |
widgets |
default |
| token |
tokens in/out/cached/total, context length, context-bar count, compaction reclaimed, cache read/write |
precise, 1 (1.0M) |
| speed |
input/output/total speed |
precise, 1 (50.0 t/s) |
| percent |
context %, cache hit %, usage/utilization/reset sliders |
precise, 1 (84.5%) |
| memory |
free memory |
current (G: 1, M/K: 0) |
| cost |
session cost |
precise, 2 ($1.20) |
So tokens can be xxx.x while money stays xxx.xx: cost defaults to 2 and a
token-oriented change won't pull it to 1.
Precedence
effective = global[kind] (if set) -> widget.numberFormat (if set) -> kind default
Per-widget is the primary control. The global is optional and off by default;
when set it wins, the same way overrideForegroundColor / globalBold already
do. With nothing set, every widget renders exactly as today.
Scope
formatTokens + consumers, formatSpeed, FreeMemory, the toFixed(1)%
percentage sites, SessionCost.
Implementation notes
numberFormat is an optional top-level WidgetItem field (parallel to
dim/bold); global is an optional per-kind Settings field. Optional, so
no settings-version migration; absent = current behavior.
- One
resolveNumberFormat(kind, item, settings) choke point; pure formatters
take the resolved { style, decimals }; shared helpers take it as a param.
Precision is resolved at render time (it can't be a post-render pass like
color/bold).
- TUI: per-widget affordance in the editor (like
(d) for dim) + a global
entry in the overrides menu.
Non-goals
- No change to default output. Cost stays 2-decimal by default.
Problem
The numeric formatters render a fixed decimal count, so whole values carry a
trailing
.0:1.0M,512.0k,100.0%,50.0 t/s. Blanket-stripping it(the original #456) was rejected: the fixed width stops the field from snapping
as a value crosses a whole unit (
1M->1.1M-> ...), which Claude Codeitself preserves (
6.0k). The fix is to make precision configurable, not tochange the default.
Proposal
A per-widget number-format setting, type-aware, with an optional global.
Default output is unchanged.
Format:
numberFormat = { style?, decimals? }style:precise(keep trailing zeros, today:1.0M) |compact(droptrailing zeros, keep real fractions:
1M,1.1M) |whole(no decimals:1M)decimals: max places beforestyleapplies (precise+ 2 ->1.00M)Type-aware defaults
Each numeric widget has a number kind with its own default, so one setting
does the right thing per type:
1.0M)50.0 t/s)84.5%)$1.20)So tokens can be
xxx.xwhile money staysxxx.xx: cost defaults to 2 and atoken-oriented change won't pull it to 1.
Precedence
effective = global[kind] (if set) -> widget.numberFormat (if set) -> kind defaultPer-widget is the primary control. The global is optional and off by default;
when set it wins, the same way
overrideForegroundColor/globalBoldalreadydo. With nothing set, every widget renders exactly as today.
Scope
formatTokens+ consumers,formatSpeed,FreeMemory, thetoFixed(1)%percentage sites,
SessionCost.Implementation notes
numberFormatis an optional top-levelWidgetItemfield (parallel todim/bold); global is an optional per-kindSettingsfield. Optional, sono settings-version migration; absent = current behavior.
resolveNumberFormat(kind, item, settings)choke point; pure formatterstake the resolved
{ style, decimals }; shared helpers take it as a param.Precision is resolved at render time (it can't be a post-render pass like
color/bold).
(d)for dim) + a globalentry in the overrides menu.
Non-goals