Skip to content

feat(widgets): compact label presets for every labeled widget - #21

Merged
axisrow merged 2 commits into
mainfrom
feat/compact-labels-all
Sep 27, 2026
Merged

axisrow merged 2 commits into
mainfrom
feat/compact-labels-all

Conversation

@axisrow

@axisrow axisrow commented Sep 26, 2026

Copy link
Copy Markdown
Owner

Compact label presets for every labeled widget

Follow-up to the compact-labels feature: fills COMPACT_LABELS so the global Compact Labels toggle (Global Overrides → j) shortens every label routed through the shared helper, not just Model/Context/Cost. Per-widget j override in the item editor now appears for all of them automatically (the editor derives the keybind list from a render probe against this same map).

Examples: Session: → S: , Weekly: → W: , Weekly Sonnet: → WS: (also WO:/WF:), tokens In:/Out:/Total:/Cached:/Turn: → I:/O:/T:/C:/Tr:, cache Cache:/Cache Read:/Cache Write:/Cache Hit: → Ca:/CR:/CW:/CH:, timers Block:/Reset:/Weekly Reset: → B:/R:/WR: (bar/slider no-colon variants included), extra usage Ov:/OvU:/OvL:, context Ctx Used:/Ctx Left: → CU:/CL: (usable variants share the presets), Claude: → CC:. Empty presets still strip (Cost: → $2.46).

Upstream feature request: sirmalloc#610. Also fixes the 22 pre-existing ESLint errors left over from the merged theme/separator work (second commit, no behavior change).

Testing

  • New parameterized test covers every map entry through formatRawOrLabeledValue (compact on/off); capability-probe expectations updated in widgets.test.ts; helper test's no-preset cases now use an unmapped label.
  • Full suite: pre-existing flaky tests unrelated to this change (custom-command capture under load, several ink TUI timing tests, one network-dependent fetchUsageData test) fail on a clean tree as well; all deterministic tests pass.
  • bun tsc --noEmit clean, eslint clean, bun run build OK, live render verified.

🤖 Generated with Claude Code

axisrow and others added 2 commits September 27, 2026 01:50
Fill COMPACT_LABELS with short presets for all labels routed through
formatRawOrLabeledValue: usage widgets (S:, W:, WS:/WO:/WF:), tokens
(I:/O:/T:/C:/Tr:), cache widgets (Ca:/CR:/CW:/CH:), timers (B:/R:/WR:,
plus the bar/slider no-colon variants), extra usage (Ov:/OvU:/OvL:),
context percentage (CU:/CL: for both plain and usable variants), and
ClaudeStatus (CC:).

The ItemsEditor (j) keybind list is derived from a render probe against
this map, so every labeled widget picks the keybind up automatically.
Tests: parameterized preset coverage in renderer-compact-labels.test.ts;
capability probe expectations updated in widgets.test.ts; the shared
helper test now uses an unmapped label for its no-preset cases.

Upstream feature request: sirmalloc#610

Co-Authored-By: Claude Code <noreply@anthropic.com>
Arrow-parens, indent, import order, prefer-find and cached-font-status
nullish-assignment cleanups; no behavior change.

Co-Authored-By: Claude Code <noreply@anthropic.com>

@axisrow axisrow left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: compact label presets for every labeled widget

Verdict: Approve. No correctness issues found.

What was verified

Preset coverage is complete and exact. Every one of the 31 new keys in COMPACT_LABELS was cross-checked against the actual label prefixes passed to formatRawOrLabeledValue across src/widgets/: tokens (In:/Out:/Total:/Cached:/Turn:), cache (Cache:/Cache Read:/Cache Write:/Cache Hit:), timers (Block/Reset/Weekly Reset in both colon and bar/slider no-colon forms), extra usage (Overage/Overage Used/Overage Left), context (Ctx Used/Ctx Left plus both (u) variants), usage percents (Session/Weekly/Weekly Sonnet/Weekly Opus/Weekly Fable), plus Model/Context/Cost/Claude. Conversely, every helper callsite label in the tree is now covered by a preset — the PR claim that every labeled widget routed through the shared helper is covered holds in both directions.

No cross-firing between near-identical labels. The lookup in formatRawOrLabeledValue is an exact map match, so Reset: vs Reset (bar/slider mode), Cache: vs Cache Read: vs Cached:, and Weekly: vs Weekly Sonnet: cannot substitute for each other. The prefix predicate startsWithCompactLabel was also checked for shadowing: none of the near-prefixes mask a different key (e.g. Weekly: does not prefix-match Weekly Sonnet: 42%).

CU:/CL: duplication is deliberate. Ctx Used: and Ctx(u) Used: both map to CU: (and CL:), documented by a source comment noting the variants are rarely shown side by side. Acceptable as an intentional trade-off; worth revisiting only if someone stacks both usable and plain percentage widgets in one line.

No keybind collisions from the widened probe. Since startsWithCompactLabel now matches more preview outputs, more widget types get the j compact-label keybind in the item editor. A scan of all editor keybinds shows no widget defines j for anything else, so newly capable widgets (tokens-, cache-, timers, usage-*) acquire the toggle without conflicts. The updated capability assertions in widgets.test.ts (tokens-input, session-usage, weekly-usage) follow directly from the map plus the preview probe.

Second commit is purely mechanical. Arrow-paren removals, import reorder, ??= in getCachedPowerlineFontStatus (semantically identical to the null check), indentation realignment in PowerlineThemeSelector.tsx, .filter(...)[0] to .find(...), and replacing two toBeDefined() asserts with a narrowing throw in renderer-regular-theme.test.ts (same failure semantics, clearer message). No behavior change.

Test quality. The new parameterized test exercises every map entry through the real helper in both compact and plain modes — including the empty-preset strip case for Cost:. The retargeted no-preset case now uses Branch: , which no helper callsite emits, so it stays a valid unmapped-label probe.

Notes (non-blocking)

  • Exposing COMPACT_LABELS as an export widens the module surface slightly beyond what the tests strictly need, but it enables the parameterized test to stay exhaustive if entries are added later. Fine as is.
  • Widgets that render default labels without routing through the shared helper (e.g. plain clocks, git labels) remain outside compact coverage; that is the pre-existing helper-based design, not a regression of this PR.

@axisrow axisrow left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the full diff on the PR branch, traced every map key to its label-emission site, ran the suite, lint, and a live pipe render with three configs (global on / global off + per-widget true / global on + per-widget false). Approving; two non-blocking notes below.

Verified

  • Additive schema, no migration: the diff does not touch Settings schemas or migrations; WidgetItem.metadata is already an open z.record(z.string(), z.string()) (src/types/Widget.ts:26). No new metadata keys are introduced — the feature reuses the pre-existing compactLabel key and only fills the preset map. Configs without compactLabels/metadata render byte-identical to main (checked with a default-config render).
  • Precedence both ways: withGlobalCompactLabels (src/widgets/shared/raw-or-labeled.ts:109) injects 'true' only when compactLabels is on and metadata is unset, so an explicit per-widget 'false' blocks the global flag, and 'true' applies with the global flag off. Confirmed live: global-on + tokens-input{compactLabel:'false'} renders In: 0 while siblings render compact; global-off + session-cost{compactLabel:'true'} renders $2.46 (label stripped) while siblings keep full labels.
  • 87603-class double-glyph bug: not reproducible by construction — the map has no prefix-producing presets; Cost: maps to '' so the value's own $ is the only glyph. Live render with cost.total_cost_usd: 2.46 yields $2.46, not $$2.46. Render path uses exact-key lookup only (COMPACT_LABELS[labelPrefix]), no prefix matching, so partial-label misfires are impossible.
  • Map-key coverage: all 31 keys match their emission sites exactly, including the easy-to-miss ones: colon-less bar/slider variants Block /Reset /Weekly Reset (BlockTimer.ts:80, BlockResetTimer.ts:114, WeeklyResetTimer.ts:193), dynamic inverse labels Ctx Used: /Ctx Left: (ContextPercentage.ts:54) and Ctx(u) Used: /Ctx(u) Left: (ContextPercentageUsable.ts:58), and LABEL in ClaudeStatus.ts:22. Bonus: speed widgets share the In: /Out: /Total: labels, so they compact for free.
  • Upstream sirmalloc#601 metadata keys: no interaction risk — this PR adds no metadata keys, and compactLabel does not collide with existing keys (hide, zeroDisplay, ttl, speedWindow, metric, link keys).
  • Tests: full suite 2490 pass / 35 fail of 2525. The 35 failures are environment flakes in three untouched classes: custom-command subprocess capture (16), fetchUsageData probe timeouts at 5s (11), ink TUI timing (8). None touch the diff's files; the parameterized it.each(Object.entries(COMPACT_LABELS)) test and the capability-probe expectations all pass. bun run lint (tsc + eslint --max-warnings=0) exits 0.
  • Hygiene: no dependency changes (package.json/bun.lock untouched by the diff), no secrets, no lint suppressions added (second commit is purely mechanical formatting).

Non-blocking notes

  1. PR description understates the flake picture: "one network-dependent fetchUsageData test" — actually 11 fetchUsageData tests time out under full-suite load on this machine. Worth correcting in the description so future readers don't chase them as regressions.
  2. Ctx(u) Used: → CU: drops the usable marker, so context-percentage and context-percentage-usable render identically (CU: 5.0% vs CU: 5.3%) if shown side by side. The in-code comment acknowledges this ("rarely shown side by side"), so fine to keep — an alternative like CU(u): would preserve the distinction if it ever matters.

🤖 Generated with Claude Code

@axisrow
axisrow merged commit b35114c into main Sep 27, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant