app_mouse_test.go:
- TestTabAtXMatchesTabWidths: Verifies that tabAtX() correctly maps
X coordinates to tab indices for all active tab states
- Uses tabWidthForTest() helper that mirrors TabVisualWidth() logic
- Catches regressions where tab hit detection drifts from rendering
card_fix_test.go:
- TestCardRowBackgroundFill: Verifies that CardRow() properly equalizes
card heights and fills backgrounds on shorter cards
- Forces TrueColor profile in init() to ensure ANSI codes generate
- Validates that padding lines contain ANSI escape sequences,
confirming background styling isn't stripped
These tests guard against visual regressions that are hard to catch
in manual testing, particularly the subtle issue where short cards
in a row would have "punched out" gaps where their backgrounds
didn't extend to match taller neighbors.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Comprehensive visual refresh of all TUI components:
card.go:
- Add semantic icons based on metric type (tokens=◈, sessions=◉,
cost=◆, cache=◇)
- Color-code metric values using new theme colors (Cyan, Magenta,
Green, Blue) for visual variety
- Add CardRow() helper that properly height-equalizes cards and
fills background on shorter cards to prevent "punched out" gaps
- Set explicit background on all style components
chart.go:
- Add background styling to sparkline renderer
- Ensure bar chart respects theme.Active.Surface background
progress.go:
- Add color gradient based on progress (Cyan→Accent→AccentBright)
- Style percentage text with bold and matching color
- Fix background fill on empty bar segments
statusbar.go:
- Complete redesign with SurfaceHover background
- Style keyboard hints: dim brackets, bright keys, muted labels
- Proper spacing and background continuity across sections
- Styled refresh indicator with AccentBright
tabbar.go:
- Add TabVisualWidth() for accurate mouse hit detection
- Modern underline-style active indicator using ━ characters
- AccentBright for active tab, proper dim styling for inactive
- Consistent Surface background across all tab elements
These changes create a cohesive visual language where every element
respects the dark background, icons add visual interest without
clutter, and color coding provides semantic meaning.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Change module path from 'cburn' to 'github.com/theirongolddev/cburn'
to enable standard Go remote installation:
go install github.com/theirongolddev/cburn@latest
This is a BREAKING CHANGE for any external code importing this module
(though as a CLI tool, this is unlikely to affect anyone).
All internal imports updated to use the new module path.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduce background data refresh so the dashboard stays current without
restarting. This touches four layers:
Config (config.go):
- New TUIConfig struct with AutoRefresh (bool) and RefreshIntervalSec
(int) fields, defaulting to enabled at 30-second intervals.
- Minimum interval floor of 10 seconds enforced at load time.
App core (app.go):
- RefreshDataMsg type for background refresh completion signaling.
- Auto-refresh state: interval timer, refreshing flag, lastRefresh
timestamp. Checked on every tick; fires refreshDataCmd when elapsed.
- refreshDataCmd: background goroutine that loads session data via cache
(with uncached fallback) and posts RefreshDataMsg on completion.
- Manual refresh keybind: 'r' triggers immediate refresh.
- Auto-refresh toggle keybind: 'R' toggles auto-refresh and persists
the preference to config.toml.
- Help text updated with r/R keybind documentation.
Status bar (statusbar.go):
- Shows spinning refresh indicator during active refresh.
- Shows auto-refresh icon when auto-refresh is enabled.
Settings tab (tab_settings.go):
- Two new editable fields: Auto Refresh (bool) and Refresh Interval
(seconds with 10s minimum).
- Settings display reads live App state to stay consistent with the
R toggle keybind (avoids stale config-file reads).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Theme simplification (theme/theme.go):
- Remove Purple and BorderHover fields from Theme struct — neither was
referenced in the new tab renderers, reducing per-theme boilerplate
from 14 to 12 color definitions
Component extraction (components/):
- Move Sparkline() and BarChart() from card.go to new chart.go, giving
visualization components their own file as complexity grows
- card.go retains MetricCard, ContentCard, LayoutRow, and CardInnerWidth
which are layout-focused
- New chart.go: Sparkline (unicode block chars) and BarChart (multi-row
with anchored Y-axis, optional X-axis labels, dynamic height/width)
- New progress.go: ProgressBar component with customizable width, color,
and percentage display — used by rate-limit and budget views
Status bar and tab bar updates:
- statusbar.go: adapt to simplified theme struct
- tabbar.go: adapt to simplified theme struct
Add BarChart component that renders multi-row Unicode bar charts with
anchored Y-axis labels, automatic tick-step computation, sub-sampling
for narrow terminals, and optional X-axis date labels. The chart
gracefully degrades to a sparkline when width/height is too small.
Add ContentCard, CardRow, and CardInnerWidth utilities for consistent
bordered card layout across all dashboard tabs. ContentCard renders
a lipgloss-bordered card with optional bold title; CardRow joins
pre-rendered cards horizontally; CardInnerWidth computes the usable
text width after accounting for border and padding.
Add LayoutRow helper that distributes a total width into n integer
widths that sum exactly, absorbing the integer-division remainder
into the first items -- eliminates off-by-one pixel drift in multi-
column layouts.
Refactor MetricCard to accept an outerWidth parameter and derive the
content width internally by subtracting border, replacing the old
raw-width parameter that required callers to do the subtraction.
MetricCardRow now uses LayoutRow for exact width distribution.
Refine TabBar to render all tabs on a single row when they fit within
the terminal width, falling back to the two-row layout only when
they overflow.
Simplify StatusBar by removing the unused filterInfo append that was
cluttering the left section.
Implement shared UI components used across the dashboard tabs:
- tui/components/card.go: Three components:
* MetricCard: bordered card with label (muted), value (bold), and
optional delta (dim) — used for the dashboard's top-level KPIs.
* MetricCardRow: renders N cards side-by-side using lipgloss
horizontal join, auto-calculating card width from available space.
* Sparkline: theme-colored Unicode block sparkline (8-level,
auto-scaled to series max). Used in Dashboard and Trends tabs.
* ProgressBar: filled/empty bar (accent + dim) with percentage
label. Used in the Budget tab for plan-relative spend.
- tui/components/statusbar.go: Bottom status bar with left-aligned
keybinding hints ([f]ilter [?]help [q]uit), current filter info,
and right-aligned data age indicator. Padding auto-fills to
terminal width.
- tui/components/tabbar.go: 10-tab navigation bar split across two
rows (Dashboard/Costs/Sessions/Models/Projects on row 1,
Trends/Efficiency/Activity/Budget/Settings on row 2). Each
inactive tab highlights its keyboard shortcut letter with [bracket]
notation. Active tab renders in accent color. Settings uses 'x'
as its shortcut (not present in the name, so appended). TabIdxByKey
maps key presses to tab indices.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>