feat(widgets): compact label presets with global and per-widget toggles - #10
Conversation
Add abbreviated label presets for labeled widgets, complementary to the free-form label editing proposed upstream (sirmalloc#601): - New `compactLabels` settings flag (default off). Additive v4 key: old configs parse unchanged and render identically, no version bump needed. - Presets live in one map (`Model:` -> `M:`, `Context:` -> `Ctx:`, `Cost:` -> `` — the value's own `$` is the glyph) inside `formatRawOrLabeledValue`, so every widget routed through the helper picks them up with no per-widget changes. Model, Session Cost, and Context Bar moved onto the helper. - One-click global toggle in Global Overrides `(j)`; per-widget override via `(j) compact label` in the items editor (metadata `compactLabel`), which wins over the global setting in both directions. Capability for the editor keybind is derived from a cached preview probe of the widget registry. - Extend the Git Branch width-cap pattern to Current Working Dir and Session Name (`w` max-width keybind). - Document per-widget padding/separator/label width overhead in docs/USAGE.md; defaults unchanged. Tests: preset resolution, toggle metadata, global injection precedence, migration parity (v1->v4 and schema-less v4 parse), registry-wide `j` keybind reservation, capable-type probe sanity, Global Overrides `(j)` keystroke test. bun test 2400 pass; bun run lint clean. Co-Authored-By: Claude Code <noreply@anthropic.com>
axisrow
left a comment
There was a problem hiding this comment.
Вердикт: requesting changes — одно функциональное расхождение с задокументированным поведением + док-нитка, остальное чисто.
Главное — пер-виджетный (j) не даёт форсить метки ВЫКЛ при включённом глобальном Compact Labels. toggleCompactLabel переключает только undefined ↔ true; значение false не пишется никогда. Доки этого же PR обещают «force it on/off regardless of the global setting», и модель данных opt-out поддерживает (тест рендерера с compactLabel: false проходит), но из TUI это состояние недостижимо: при compactLabels: true виджет уже рендерится компактно (withGlobalCompactLabels инжектит true на рендере), поэтому (j) пишет true — без видимых изменений, а второй раз нажатие удаляет ключ — глобальный флаг возвращается. Кейбинд превращается в визуальный no-op, причём в списке виджетов нет маркера: getCompactLabelModifierText смотрит только на сохранённые метаданные. Фикс: трёхстадийный цикл по эффективному состоянию (рендерится компактно → false; false → убрать ключ/наследовать; иначе → true) плюс эффективное состояние в тексте модификатора.
Нитка — docs/USAGE.md:122: Model: (7 колонок) → M: (3) = −4, а не −5; Context: (9) → Ctx: (5) = −4, а не −3 (Cost: → −6 верно).
Что хорошо: аддитивный ключ compactLabels с дефолтом false без бампа версии схемы — старые конфиги рендерятся идентично (покрыто тестами parse v4 и миграции v1); кешированный probe getCompactLabelCapableTypes с try/catch безопасен — виджеты без isPreview-гарда (SessionUsage и т.п.) не запускают сабпроцессов на preview; тест резервации клавиши (j) по всем виджетам; внятный приоритет rawValue > пер-виджет > глобальный в formatRawOrLabeledValue.
The per-widget (j) toggle only wrote/removed 'true', so with the global Compact Labels setting on it became a visual no-op: the render-time injection re-compactified the widget after the key was removed, and no row marker showed the effective state. - toggleCompactLabel now takes the settings and cycles the EFFECTIVE state: compact (saved 'true' or inherited global on) -> write 'false'; forced off -> drop the key and inherit; otherwise -> write 'true'. - getCompactLabelModifierText reports the effective state: '(compact label)' / '(compact label: on)' / '(compact label: off)'. - ItemsEditor/input-handlers pass settings through to both. - docs/USAGE.md: fix preset savings arithmetic (Model -4, Context -4). Co-Authored-By: Claude Code <noreply@anthropic.com>
…act is on Co-Authored-By: Claude Code <noreply@anthropic.com>
axisrow
left a comment
There was a problem hiding this comment.
Вердикт: approve. Фиксы f41c8d3 + 87a21ca закрывают оба пункта ревью 5324047980, перепроверено по диффу: toggleCompactLabel(item, settings) циклит по эффективному состоянию (inherit → on → forced-off → inherit; при глобали on стартует с inherited-compact → forced-off), getCompactLabelModifierText показывает on/off/явный on, settings прокинуты из ItemsEditor в оба продакшн-коллера, рендер-тест доказывает сценарий «(j) при глобали on выключает метку» end-to-end (Model: Opus 4.6 | $2.46), арифметика в docs/USAGE.md исправлена (−4/−4/−6). Обратная совместимость сохранена: settings? optional, старые коллеры получают прежнее поведение. Замечаний нет.
Co-Authored-By: Claude Code <noreply@anthropic.com>
Summary
Compact display modes for labeled widgets — a settings-driven way to shorten the standard
Model:/Context:/Cost:prefixes and cap wide widgets, without touching defaults for existing configurations.What landed
Model:→M:,Context:→Ctx:,Cost:→ renders the bare value with its own dollar glyph (a naive$-prefixed preset produced$$2.46— caught by the acceptance render and fixed).Settings.compactLabels(key(j)in Global Overrides) and per-widgetmetadata.compactLabel(key(j)in the item editor, probe-gated); per-widget wins over global in both directions.compactLabelskey (defaultfalse), no version bump; migration tests assert v1→v4 and bare-v4 parses leave old configs rendering identically.(w)added toCurrent Working DirandSession Name, following the existing Git Branch / Git Root Dir pattern.docs/USAGE.md; rendering defaults unchanged.Before / after (piped render)
Per-widget override off →
Context:keeps its full label while the rest stays compact.Tests
bun test: 2400 pass / 0 fail (single final run, this exact tree); migration + key-reservation tests includedbun run lint: clean, no suppressionsKnown risks / notes
(j)visibility uses a preview-probe heuristic — flagged for review.🤖 Generated with Claude Code