feat(hud): statusbar wow — 4 bug fixes + 5 wow features + refactor (Wave 0-3)#1485
Conversation
Infrastructure Wave: establish lib/ layout + re-export pattern, move 3 low-risk items (BUDDY_FACE, format_rate_limits, get_fresh_version) and reserve 6 skeleton paths for Wave 1-D and Wave 2-A-E with docstring contracts. - lib/hud_buddy.py re-exports canonical BUDDY_FACE from tiny_actor_presets - lib/hud_version.py renames _get_fresh_version -> get_fresh_version (public) - lib/hud_rate_limits.py moves format_rate_limits verbatim - 6 skeleton modules for future waves with API contracts in docstrings - codingbuddy-hud.py adds sys.path bootstrap + re-exports (no noqa) - 9 new test_hud_*.py with tmp_path fixture + re-export identity locks Golden Rule: 133 tests in test_hud.py/test_hud_state.py/test_mode_detect_hud.py remain 100% passing (behavior-preserving). Total 155/155 tests pass. Design decisions from 4-reviewer PLAN panel feedback: 1. BUDDY_FACE re-exported from canonical tiny_actor_presets (avoids 4-way dup) 2. sys.path bootstrap follows sibling hook convention (no noqa: E402) 3. Skeletons retained with explicit docstring contracts 4. costHistory field deferred to Wave 2-B owner 5. get_fresh_version public rename + _get_fresh_version backcompat alias 6. Optional dead import removed from hud_version.py 7. Framed as Infrastructure Wave (layout + re-export, not LOC reduction) Closes #1464
Resolves the stale version display bug ("shows v5.2.0 when actual is
v5.5.0") by adding a deterministic tier-2 fallback that reads
.claude-plugin/plugin.json via __file__-relative path.
- hud_version.get_fresh_version gains plugin_json_file parameter:
* None (default): tier-2 disabled, preserves backcompat
* "": enables dev-install default path (production)
* non-empty: test override
- _default_plugin_json_path() + _read_local_plugin_json() helpers
- format_status_line accepts plugin_json_file passthrough
- main() passes plugin_json_file="" to enable Wave 1-A in production
- 7 new tests for fallback ordering, malformed files, default path
- 162/162 tests pass (133 Golden Rule + 29 version/Wave 0)
Closes #1466
Part of #1464 (Wave 0 statusbar refactor)
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
2be8661 to
2810361
Compare
Combined Wave 0 polish items from the #1465/#1485 review cycle: 1. Narrow `except Exception` → `except ImportError` in the 3 lib fallback import blocks (qual-1465 HIGH-1). Real logic bugs (SyntaxError, NameError, AttributeError) inside lib modules now surface immediately instead of being silently swallowed by a catch-all. 2. Drop inline stub functions for `format_rate_limits` and `_get_fresh_version` (qual-1465 HIGH-2). Eliminates the signature drift between canonical lib definitions and in-file fallback stubs observed on the integrator branch (Wave 1-A `plugin_json_file` kwarg drift). The outer main() try/except still catches any runtime failure and emits the minimal "◕‿◕ CodingBuddy" safe output via the BUDDY_FACE constant. 3. Hoist `hud_velocity` + `hud_cache_savings` imports to module top as `_format_velocity_segment` / `_format_cache_savings` (perf-1485 H1). Eliminates ~0.47μs sys.modules lookup per render. Integrator branch only — no-op on refactor/wave branches where the inline imports don't exist yet. 4. Bump next to 16.2.3 for GHSA-q4gf-8mx6-v5v3 (landing-security-check). Aligns eslint-config-next and updates setup.test.ts assertion. Refs: qual-1465 HIGH-1/2, perf-1485 H1, GHSA-q4gf-8mx6-v5v3
Combined Wave 0 polish items from the #1465/#1485 review cycle: 1. Narrow `except Exception` to `except ImportError` in the 3 lib fallback import blocks (qual-1465 HIGH-1). Real logic bugs (SyntaxError, NameError, AttributeError) inside lib modules now surface immediately instead of being silently swallowed by a catch-all. 2. Drop inline stub functions for format_rate_limits and _get_fresh_version (qual-1465 HIGH-2). Eliminates the signature drift between canonical lib definitions and in-file fallback stubs observed on the integrator branch (Wave 1-A plugin_json_file kwarg drift). The outer main() try/except still catches any runtime failure and emits the minimal safe output via the BUDDY_FACE constant. 3. Hoist hud_velocity and hud_cache_savings imports to module top as _format_velocity_segment and _format_cache_savings (perf-1485 H1). Eliminates ~0.47us sys.modules lookup per render. Integrator branch only - no-op on refactor/wave branches where the inline imports don't exist yet. 4. Bump next to 16.2.3 for GHSA-q4gf-8mx6-v5v3 (landing-security-check). Aligns eslint-config-next and updates setup.test.ts assertion. Refs: qual-1465 HIGH-1/2, perf-1485 H1, GHSA-q4gf-8mx6-v5v3
Combined Wave 0 polish items from the #1465/#1485 review cycle: 1. Narrow `except Exception` to `except ImportError` in the 3 lib fallback import blocks (qual-1465 HIGH-1). Real logic bugs (SyntaxError, NameError, AttributeError) inside lib modules now surface immediately instead of being silently swallowed by a catch-all. 2. Drop inline stub functions for format_rate_limits and _get_fresh_version (qual-1465 HIGH-2). Eliminates the signature drift between canonical lib definitions and in-file fallback stubs observed on the integrator branch (Wave 1-A plugin_json_file kwarg drift). The outer main() try/except still catches any runtime failure and emits the minimal safe output via the BUDDY_FACE constant. 3. Hoist hud_velocity and hud_cache_savings imports to module top as _format_velocity_segment and _format_cache_savings (perf-1485 H1). Eliminates ~0.47us sys.modules lookup per render. Integrator branch only - no-op on refactor/wave branches where the inline imports don't exist yet. 4. Bump next to 16.2.3 for GHSA-q4gf-8mx6-v5v3 (landing-security-check). Aligns eslint-config-next and updates setup.test.ts assertion. Refs: qual-1465 HIGH-1/2, perf-1485 H1, GHSA-q4gf-8mx6-v5v3
Combined Wave 0 polish items from the #1465/#1485 review cycle: 1. Narrow `except Exception` to `except ImportError` in the 3 lib fallback import blocks (qual-1465 HIGH-1). Real logic bugs (SyntaxError, NameError, AttributeError) inside lib modules now surface immediately instead of being silently swallowed by a catch-all. 2. Drop inline stub functions for format_rate_limits and _get_fresh_version (qual-1465 HIGH-2). Eliminates the signature drift between canonical lib definitions and in-file fallback stubs observed on the integrator branch (Wave 1-A plugin_json_file kwarg drift). The outer main() try/except still catches any runtime failure and emits the minimal safe output via the BUDDY_FACE constant. 3. Hoist hud_velocity and hud_cache_savings imports to module top as _format_velocity_segment and _format_cache_savings (perf-1485 H1). Eliminates ~0.47us sys.modules lookup per render. Integrator branch only - no-op on refactor/wave branches where the inline imports don't exist yet. 4. Bump next to 16.2.3 for GHSA-q4gf-8mx6-v5v3 (landing-security-check). Aligns eslint-config-next and updates setup.test.ts assertion. Refs: qual-1465 HIGH-1/2, perf-1485 H1, GHSA-q4gf-8mx6-v5v3
Combined Wave 0 polish items from the #1465/#1485 review cycle: 1. Narrow `except Exception` to `except ImportError` in the 3 lib fallback import blocks (qual-1465 HIGH-1). Real logic bugs (SyntaxError, NameError, AttributeError) inside lib modules now surface immediately instead of being silently swallowed by a catch-all. 2. Drop inline stub functions for format_rate_limits and _get_fresh_version (qual-1465 HIGH-2). Eliminates the signature drift between canonical lib definitions and in-file fallback stubs observed on the integrator branch (Wave 1-A plugin_json_file kwarg drift). The outer main() try/except still catches any runtime failure and emits the minimal safe output via the BUDDY_FACE constant. 3. Hoist hud_velocity and hud_cache_savings imports to module top as _format_velocity_segment and _format_cache_savings (perf-1485 H1). Eliminates ~0.47us sys.modules lookup per render. Integrator branch only - no-op on refactor/wave branches where the inline imports don't exist yet. 4. Bump next to 16.2.3 for GHSA-q4gf-8mx6-v5v3 (landing-security-check). Aligns eslint-config-next and updates setup.test.ts assertion. Refs: qual-1465 HIGH-1/2, perf-1485 H1, GHSA-q4gf-8mx6-v5v3
Combined Wave 0 polish items from the #1465/#1485 review cycle: 1. Narrow `except Exception` to `except ImportError` in the 3 lib fallback import blocks (qual-1465 HIGH-1). Real logic bugs (SyntaxError, NameError, AttributeError) inside lib modules now surface immediately instead of being silently swallowed by a catch-all. 2. Drop inline stub functions for format_rate_limits and _get_fresh_version (qual-1465 HIGH-2). Eliminates the signature drift between canonical lib definitions and in-file fallback stubs observed on the integrator branch (Wave 1-A plugin_json_file kwarg drift). The outer main() try/except still catches any runtime failure and emits the minimal safe output via the BUDDY_FACE constant. 3. Hoist hud_velocity and hud_cache_savings imports to module top as _format_velocity_segment and _format_cache_savings (perf-1485 H1). Eliminates ~0.47us sys.modules lookup per render. Integrator branch only - no-op on refactor/wave branches where the inline imports don't exist yet. 4. Bump next to 16.2.3 for GHSA-q4gf-8mx6-v5v3 (landing-security-check). Aligns eslint-config-next and updates setup.test.ts assertion. Refs: qual-1465 HIGH-1/2, perf-1485 H1, GHSA-q4gf-8mx6-v5v3
Combined Wave 0 polish items from the #1465/#1485 review cycle: 1. Narrow `except Exception` to `except ImportError` in the 3 lib fallback import blocks (qual-1465 HIGH-1). Real logic bugs (SyntaxError, NameError, AttributeError) inside lib modules now surface immediately instead of being silently swallowed by a catch-all. 2. Drop inline stub functions for format_rate_limits and _get_fresh_version (qual-1465 HIGH-2). Eliminates the signature drift between canonical lib definitions and in-file fallback stubs observed on the integrator branch (Wave 1-A plugin_json_file kwarg drift). The outer main() try/except still catches any runtime failure and emits the minimal safe output via the BUDDY_FACE constant. 3. Hoist hud_velocity and hud_cache_savings imports to module top as _format_velocity_segment and _format_cache_savings (perf-1485 H1). Eliminates ~0.47us sys.modules lookup per render. Integrator branch only - no-op on refactor/wave branches where the inline imports don't exist yet. 4. Bump next to 16.2.3 for GHSA-q4gf-8mx6-v5v3 (landing-security-check). Aligns eslint-config-next and updates setup.test.ts assertion. Refs: qual-1465 HIGH-1/2, perf-1485 H1, GHSA-q4gf-8mx6-v5v3
Combined Wave 0 polish items from the #1465/#1485 review cycle: 1. Narrow `except Exception` to `except ImportError` in the 3 lib fallback import blocks (qual-1465 HIGH-1). Real logic bugs (SyntaxError, NameError, AttributeError) inside lib modules now surface immediately instead of being silently swallowed by a catch-all. 2. Drop inline stub functions for format_rate_limits and _get_fresh_version (qual-1465 HIGH-2). Eliminates the signature drift between canonical lib definitions and in-file fallback stubs observed on the integrator branch (Wave 1-A plugin_json_file kwarg drift). The outer main() try/except still catches any runtime failure and emits the minimal safe output via the BUDDY_FACE constant. 3. Hoist hud_velocity and hud_cache_savings imports to module top as _format_velocity_segment and _format_cache_savings (perf-1485 H1). Eliminates ~0.47us sys.modules lookup per render. Integrator branch only - no-op on refactor/wave branches where the inline imports don't exist yet. 4. Bump next to 16.2.3 for GHSA-q4gf-8mx6-v5v3 (landing-security-check). Aligns eslint-config-next and updates setup.test.ts assertion. Refs: qual-1465 HIGH-1/2, perf-1485 H1, GHSA-q4gf-8mx6-v5v3
Combined Wave 0 polish items from the #1465/#1485 review cycle: 1. Narrow `except Exception` to `except ImportError` in the 3 lib fallback import blocks (qual-1465 HIGH-1). Real logic bugs (SyntaxError, NameError, AttributeError) inside lib modules now surface immediately instead of being silently swallowed by a catch-all. 2. Drop inline stub functions for format_rate_limits and _get_fresh_version (qual-1465 HIGH-2). Eliminates the signature drift between canonical lib definitions and in-file fallback stubs observed on the integrator branch (Wave 1-A plugin_json_file kwarg drift). The outer main() try/except still catches any runtime failure and emits the minimal safe output via the BUDDY_FACE constant. 3. Hoist hud_velocity and hud_cache_savings imports to module top as _format_velocity_segment and _format_cache_savings (perf-1485 H1). Eliminates ~0.47us sys.modules lookup per render. Integrator branch only - no-op on refactor/wave branches where the inline imports don't exist yet. 4. Bump next to 16.2.3 for GHSA-q4gf-8mx6-v5v3 (landing-security-check). Aligns eslint-config-next and updates setup.test.ts assertion. Refs: qual-1465 HIGH-1/2, perf-1485 H1, GHSA-q4gf-8mx6-v5v3
Combined Wave 0 polish items from the #1465/#1485 review cycle: 1. Narrow `except Exception` to `except ImportError` in the 3 lib fallback import blocks (qual-1465 HIGH-1). Real logic bugs (SyntaxError, NameError, AttributeError) inside lib modules now surface immediately instead of being silently swallowed by a catch-all. 2. Drop inline stub functions for format_rate_limits and _get_fresh_version (qual-1465 HIGH-2). Eliminates the signature drift between canonical lib definitions and in-file fallback stubs observed on the integrator branch (Wave 1-A plugin_json_file kwarg drift). The outer main() try/except still catches any runtime failure and emits the minimal safe output via the BUDDY_FACE constant. 3. Hoist hud_velocity and hud_cache_savings imports to module top as _format_velocity_segment and _format_cache_savings (perf-1485 H1). Eliminates ~0.47us sys.modules lookup per render. Integrator branch only - no-op on refactor/wave branches where the inline imports don't exist yet. 4. Bump next to 16.2.3 for GHSA-q4gf-8mx6-v5v3 (landing-security-check). Aligns eslint-config-next and updates setup.test.ts assertion. Refs: qual-1465 HIGH-1/2, perf-1485 H1, GHSA-q4gf-8mx6-v5v3
Combined Wave 0 polish items from the #1465/#1485 review cycle: 1. Narrow `except Exception` to `except ImportError` in the 3 lib fallback import blocks (qual-1465 HIGH-1). Real logic bugs (SyntaxError, NameError, AttributeError) inside lib modules now surface immediately instead of being silently swallowed by a catch-all. 2. Drop inline stub functions for format_rate_limits and _get_fresh_version (qual-1465 HIGH-2). Eliminates the signature drift between canonical lib definitions and in-file fallback stubs observed on the integrator branch (Wave 1-A plugin_json_file kwarg drift). The outer main() try/except still catches any runtime failure and emits the minimal safe output via the BUDDY_FACE constant. 3. Hoist hud_velocity and hud_cache_savings imports to module top as _format_velocity_segment and _format_cache_savings (perf-1485 H1). Eliminates ~0.47us sys.modules lookup per render. Integrator branch only - no-op on refactor/wave branches where the inline imports don't exist yet. 4. Bump next to 16.2.3 for GHSA-q4gf-8mx6-v5v3 (landing-security-check). Aligns eslint-config-next and updates setup.test.ts assertion. Refs: qual-1465 HIGH-1/2, perf-1485 H1, GHSA-q4gf-8mx6-v5v3
2810361 to
6b05d00
Compare
EVAL Review Summary — Iteration 1 ConvergedReview panel: 4 independent reviewers dispatched via Claude native Teams (separate subagent context per reviewer). Round 1 Results
Performance Measurement
Status: 178× under target. Iteration 1 — Fix Applied (amend + force-with-lease)
Before: try:
from hud_velocity import format_velocity_segment
velocity_suffix = format_velocity_segment(stdin_data, hud_state) or ""
except Exception:
pass
try:
from hud_cache_savings import format_cache_savings
savings_suffix = format_cache_savings(stdin_data) or ""
except Exception:
passAfter: # Module top (outside format_status_line):
try:
from hud_velocity import format_velocity_segment as _format_velocity_segment
except ImportError:
def _format_velocity_segment(stdin_data, hud_state=None): return ""
try:
from hud_cache_savings import format_cache_savings as _format_cache_savings
except ImportError:
def _format_cache_savings(stdin_data): return ""
# Inside format_status_line (both helpers guaranteed to return ""):
velocity_suffix = _format_velocity_segment(stdin_data, hud_state)
savings_suffix = _format_cache_savings(stdin_data)Round 2 Verification
Deferred to Follow-up (Medium/Low, non-blocking)
Status✅ Critical = 0, High = 0 — Ready for merge pending full CI green.
|
Resolves the bug where statusLine renders leftover fields from a prior session (e.g. sessionId="manual-fix", currentMode="ACT" when user is in PLAN mode) instead of the current state. New lib/hud_session.py module: - detect_stale_session(): 4-signal staleness check (empty / repair marker / stdin mismatch / age > 4h) - heal_stale_state(): soft reset, returns copy, doesn't write disk - reset_stale_session(): durable variant for session-start boot - SESSION_STALE_SECONDS constant (4 hours) codingbuddy-hud.py::main() heals state before rendering so every statusLine render sees a valid snapshot. 24 new tests in test_hud_session.py cover all 4 staleness signals, heal semantics (clear / preserve / non-mutation / empty state), and reset_stale_session edge cases (fresh noop, marker healed, missing file silent, malformed silent). 179/179 tests pass (Golden Rule 133 + Wave 0 22 + Wave 1-B 24). Closes #1468 Part of #1464 (Wave 0 statusbar refactor)
Replaces `RL:5h:13%,7d:96%` with `RL:5h░13% 7d▓96%`: - Severity icons (░ ▒ ▓) visually distinguish low/medium/high usage - Space separator replaces comma - `RL:` prefix preserved for downstream anchors Also adds defensive float coercion to _coerce_percentage() so a non-numeric used_percentage (None, "N/A") is silently treated as 0.0 instead of crashing the statusLine hot path — addresses Wave 1-A security reviewer's A03 low-severity finding. 19 new tests in test_hud_rate_limits.py cover all 3 severity buckets, boundary values (60, 85, 85.01), both-tier mixed severity, defensive coercion (None, string, numeric string, empty tier), and re-export identity from codingbuddy-hud. 3 test_hud.py tests updated to new visual format. 162/162 tests pass. Part of #1464 (Wave 0 statusbar refactor)
Introduces width-aware segment rendering primitives so the status bar never spills out of narrow terminals. Wave 1-D ships the layout helpers; Wave 3 integrator wires them into format_status_line. New lib/hud_layout.py: - SEGMENT_PRIORITY canonical drop-order list (9 slots) - SACRED_PRIORITY=1 threshold (face_version, mode_health never dropped) - visible_len(s): East-Asian-aware column count - terminal_width(*, fallback): shutil-backed detection with fallback - shorten_model_label: "Opus 4.6 (1M context)" -> "Opus 4.6" / "Opus(1M)" - fit_segments: drop-until-fit with hard-truncate fallback (U+2026) 33 new tests in test_hud_layout.py cover all helpers, edge cases (empty, zero-width, sacred overflow, custom separator, CJK/emoji width), and SEGMENT_PRIORITY ordering invariants. 188/188 tests pass (Golden 133 + Wave 0 22 + Wave 1-D 33). Part of #1464 (Wave 0 statusbar refactor)
The Buddy face now reacts to HUD phase / blocker state so the status bar feels alive: Idle / Ready -> ◕‿◕ (FACE_IDLE) Thinking / Planning-> ◔‿◔ (FACE_THINKING) Active / Executing -> ◕◡◕ (FACE_ACTIVE) Error / Blocked -> ◕︵◕ (FACE_ERROR) Victory / Completed-> ◕ᴗ◕ (FACE_VICTORY) Priority resolution: 1. blocker_count > 0 always wins (error face) 2. recent_event == "victory" beats phase 3. Phase lookup (case-insensitive) 4. Fallback to FACE_IDLE hud_buddy.py extended: - FACE_* constants for each state - _PHASE_FACE_MAP for phase -> glyph lookup - get_buddy_face(phase, *, blocker_count, recent_event) pure function - select_face_from_state(hud_state) convenience dict wrapper - __all__ exports updated BUDDY_FACE is still canonically re-exported from tiny_actor_presets (identity lock preserved). 29 new tests in test_hud_buddy.py cover: - All 5 face constants distinct + non-empty - All 6 phase mappings (ready/planning/executing/evaluating/cycling/completed) - Case-insensitive phase, unknown phase, empty, None - Priority: blocker beats phase, blocker beats victory - Malformed blocker_count fall-through - Victory event recognition (case-insensitive) + unknown event - select_face_from_state (empty, None, planning, blocked, victory) - __all__ public API coverage 158/158 pass. Part of #1464 (Wave 0 statusbar refactor)
Shows session spend rate next to absolute cost so users can see whether they're on a slow planning pass or a hot refactor burn: $1.23↗$0.08/m Trend glyphs: - 🔥 rate >= $0.20/min (hot burn) - ↗ $0.01 <= rate < $0.20/min (normal/rising) - → 0 < rate < $0.01/min (steady, very low) - 💤 rate <= 0 (idle) Stateless implementation: rate = cost_usd / (duration_ms / 60k). Uses Claude Code stdin.cost.total_cost_usd and total_duration_ms directly, with hud_state.sessionStartTimestamp fallback for the elapsed-time component. Deliberately does NOT touch hud_state.py schema (costHistory was deferred per Wave 0 review). New lib/hud_velocity.py: - TREND_IDLE_MAX=0.01, TREND_HOT_MIN=0.20 constants - compute_spend_rate(cost_usd, duration_ms) -> float - trend_glyph(rate) -> str - format_velocity_segment(stdin_data, hud_state) -> str - format_cost_with_velocity(cost_usd, stdin, hud_state, *, is_exact) - _duration_ms_from_state helper for stdin fallback 33 new tests cover: - compute_spend_rate: zero/negative/non-numeric/numeric-string, known rates ($1/min, $0.50/30s, $6/10min) - trend_glyph: all 4 tiers + boundary values + non-numeric - format_velocity_segment: empty, missing cost, missing duration, zero rate, normal hot, rising tier, state fallback, no state - format_cost_with_velocity: exact/estimate prefix, no-velocity fallback, non-numeric cost, two decimals - Constant ordering 162/162 pass. Part of #1464 (Wave 0 statusbar refactor)
Claude API's prompt caching discounts cache_read_input_tokens by 90%. This module quantifies that saving so the HUD can surface "💰$4.56 saved" as a badge appended to the cost segment. New lib/hud_cache_savings.py: - compute_cache_savings(cache_read_tokens, model_id) -> float Pure arithmetic helper with defensive coercion for malformed input. - format_cache_savings(stdin_data) -> str End-to-end renderer that reads Claude Code stdin, extracts cache_read_input_tokens and model.id, returns "💰$N.NN saved" or "" below the $0.01 noise floor. - Known model families: haiku ($0.80/M), sonnet ($3/M), opus ($15/M). Unknown models fall back to sonnet-tier pricing (conservative). 26 new tests in test_hud_cache_savings.py cover: - All 3 model families + unknown + empty - Case-insensitive matching - Zero / negative / non-numeric / numeric-string inputs - Empty stdin / missing context_window / missing current_usage - Below $0.01 noise floor - display_name fallback when model.id is absent - Two-decimal formatting Part of #1464 (Wave 0 statusbar refactor)
Renders the statusLine mode label with per-mode ANSI truecolor gradients + tier-specific glyphs: PLAN -> ◇ blue (solid) ACT -> ◆ green (solid) EVAL -> ◈ purple (solid) AUTO -> ◊ rainbow (6-stop gradient: red->orange->yellow->green->blue->purple) NO_COLOR env var (https://no-color.org) honoured: any non-empty value disables color and returns plain text. New lib/hud_rainbow.py: - MODE_PALETTE: per-mode RGB anchor list - is_color_enabled(env): NO_COLOR check - mode_glyph(mode): per-mode Unicode glyph lookup - gradient_ansi(text, palette): character-by-character RGB wrap - render_mode_rainbow(mode, *, enabled, env): end-to-end renderer - strip_ansi(s): CSI escape removal helper (for tests + layout) 35 new tests cover: NO_COLOR parsing, glyph lookup (4 modes + unknown + case-insensitive), gradient (single/multi/empty), render (all 4 modes + enabled/disabled/env fallback + unknown mode + case-insensitive), strip_ansi (noop/escapes/empty/mixed), MODE_PALETTE schema. 164/164 pass. Part of #1464 (Wave 0 statusbar refactor)
Replaces the plain "Ctx:42%" text with a compact visual progress bar so users can see context-window usage at a glance: [████░░░░░░] 42% (safe, low usage) [███████░░░] 73% (approaching danger) [█████████▓] 92%⚠ (critical — full bar + warning glyph) Two visual signals distinguish the danger zones: 1. Dark glyph (▓) replaces the trailing full block at the danger threshold (85%) so "almost full" looks different from "full". 2. ⚠ suffix appended at the warning threshold (80%) — survives monochrome / greyscale renders. New lib/hud_context_bar.py: - CONTEXT_BAR_WIDTH = 10 cells (~10% resolution per cell) - CONTEXT_BAR_THRESHOLDS = (80, 85, 95) # warning, danger, critical - _clamp_percentage(pct): defensive float coercion with [0, 100] clamp - render_context_bar(used_pct, *, width): core renderer - format_context_bar_segment(stdin_data): Claude Code stdin extractor 29 new tests cover: - Basic shape (0/50/100 pct) - Rounding (banker's round-half-to-even for 5/15/95) - Warning/danger threshold boundaries (inclusive) - Clamping (negative, >100, None, non-numeric, numeric string) - Custom width (20, 0, 1) - Segment extractor (empty, missing context_window, missing used_percentage, normal render, zero) - Constants (width, threshold ordering) 158/158 pass. Part of #1464 (Wave 0 statusbar refactor)
Wave 3 integrator: - Merged all 9 parallel Wave sub-branches (Wave 0 + 1-A/B/C/D + 2-A/B/C/D/E) - Added Wave 2-B velocity suffix + Wave 2-C cache savings suffix to cost segment - 5 integration tests lock the Wave 3 assembly Cost segment output examples: "$1.23" (plain, no data) "$1.23↗$0.08/m" (velocity only) "$1.23💰$4.56 saved" (savings only) "$1.23↗$0.08/m💰$4.56 saved" (both) Defensive try/except imports ensure format_status_line still works when the optional modules are temporarily broken. Follow-up Wave 2 modules merged but not yet wired into format_status_line: - Wave 2-A: hud_buddy dynamic face per phase - Wave 2-D: hud_rainbow mode label coloring - Wave 2-E: hud_context_bar visual bar - Wave 1-D: hud_layout fit_segments adaptive truncation 381/381 tests pass (9 Wave-level test suites + Wave 3 integration). Closes the Wave 3 task. Part of #1464 (Wave 0 statusbar refactor effort).
Combined Wave 0 polish items from the #1465/#1485 review cycle: 1. Narrow `except Exception` to `except ImportError` in the 3 lib fallback import blocks (qual-1465 HIGH-1). Real logic bugs (SyntaxError, NameError, AttributeError) inside lib modules now surface immediately instead of being silently swallowed by a catch-all. 2. Drop inline stub functions for format_rate_limits and _get_fresh_version (qual-1465 HIGH-2). Eliminates the signature drift between canonical lib definitions and in-file fallback stubs observed on the integrator branch (Wave 1-A plugin_json_file kwarg drift). The outer main() try/except still catches any runtime failure and emits the minimal safe output via the BUDDY_FACE constant. 3. Hoist hud_velocity and hud_cache_savings imports to module top as _format_velocity_segment and _format_cache_savings (perf-1485 H1). Eliminates ~0.47us sys.modules lookup per render. Integrator branch only - no-op on refactor/wave branches where the inline imports don't exist yet. 4. Bump next to 16.2.3 for GHSA-q4gf-8mx6-v5v3 (landing-security-check). Aligns eslint-config-next and updates setup.test.ts assertion. Refs: qual-1465 HIGH-1/2, perf-1485 H1, GHSA-q4gf-8mx6-v5v3
6b05d00 to
b330528
Compare
Statusbar Wow — 4 bug fixes + 5 wow features + refactor
Single consolidated PR containing the entire statusbar wow upgrade work, rebased onto master with 12 linear commits (rebase & merge ready).
Supersedes the stacked sub-PRs: #1465, #1467, #1469, #1471, #1473, #1475, #1477, #1479, #1481, #1483.
Commit history (linear, 12 commits)
de622ccrefactor(hud): extract 9 modules for parallel statusbar workcdf0772fix(hud): version resolution fallback to plugin.json0606698fix(hud): session self-heal & stale state detection87b779afeat(hud): rate limit format with severity icons894f515feat(hud): adaptive layout engine5e8389dfeat(hud): breathing buddy face states78ec6c5feat(hud): cost velocity indicatora306920feat(hud): cache savings badge0fb3d5cfeat(hud): mode rainbow ANSI coloring8cd78b2feat(hud): smart context bar visualization295f5c4feat(hud): integrate Wave 2-B/2-C in format_status_lineb330528fix(hud,landing): narrow fallback imports + bump next to 16.2.3Scope
Bug fixes (user-reported):
RL:5h░13% 7d▓96%)Wow features (new):
$1.23↗$0.08/m)💰$4.56 saved)[████░░░░░░] 42%)Refactor:
lib/hud_*.pymodules extracted from monolithiccodingbuddy-hud.pySide fixes:
next@16.1.6 → 16.2.3for GHSA-q4gf-8mx6-v5v3 (landing-security-check)EVAL Review Results
8 independent reviewers dispatched via Claude native Teams (security, code, quality, performance × 2 PRs):
High findings addressed in
b330528:qual-1465HIGH-1: Narrowedexcept Exception→except ImportErrorqual-1465HIGH-2: Dropped inline fallback stubs (eliminated signature drift)perf-1485H1: Hoisted velocity/savings imports to module top (~0.47μs/render saved)Full review details in previous comments on #1465 and #1485.
Test results
No regressions after rebase.
Performance
Hot-path
format_status_lineavg: 0.028ms per render (178× under 5ms target).Deferred (follow-up PR)
hud_buddy.select_face_from_state) intoformat_status_linehud_rainbow.render_mode_rainbow) for mode label renderinghud_context_bar.format_context_bar_segment) replacing"Ctx:X%"hud_layout.fit_segments) for adaptive widthsec-1485MED-1:math.isfiniteguard inhud_velocity.compute_spend_ratesec-1485MED-2: nan handling inhud_context_bar._clamp_percentage(before wire-up)These require updating
test_hud.pyexpectations and are deferred to a follow-up PR to keep this one merge-ready.Merge strategy
Use Rebase and merge. The 12 linear commits will be appended to master as-is with no merge commit.
Closes #1464, #1466, #1468, #1470, #1472, #1474, #1476, #1478, #1480, #1482, #1484