Skip to content

v2.9.1 — Cluster Health Chart Polish + Light Mode Fix

Choose a tag to compare

@Pr0zak Pr0zak released this 12 May 00:45
· 316 commits to main since this release

Nine commits of polish on top of v2.9.0. Three themes: a real light-mode regression fix, a much better Cluster Health chart, and a screenshots harness for the README/docs.

🔆 Light mode actually works on first paint

src/index.jsx had a leftover document.documentElement.classList.add('dark') in the initial useEffect that overrode whatever useDarkMode read from localStorage. Result: light-mode users got dark mode on every page load. Now the useDarkMode hook is the single source of truth and the theme is honored on mount.

📈 Cluster Health chart

Four improvements:

  • Tiered downsampling. /api/score-history accepts a ?bucket= parameter (minutes per bucket). Backend groups raw samples into time buckets and returns the average per bucket. No destructive retention — raw rows are preserved, aggregation happens at query time. Frontend picks bucket size based on selected period:

    Period Bucket Typical points
    1d raw (~15m) ~96
    7d raw (~15m) ~670
    30d hourly ~720
    90d 6-hour ~360
    180d 12-hour ~360
    1yr daily 365
  • New period selector. All is gone — never meant much once we had real periods. Replaced with 180d and 1yr.

  • Hover crosshair + value tooltip. Mouse-move over the chart drops a snapped vertical line on the nearest data point with a floating tooltip showing the value and timestamp. Tooltip flips to the left past the chart midpoint.

  • No more "vibration". fetchScoreHistory was being recreated on every render of useClusterData, so the chart's useEffect dep array fired on every parent re-render — a feedback loop that visibly jittered the chart for a few seconds after switching periods. Wrapped in useCallback; effect now fires only when period actually changes.

  • Full range fetched. useClusterData was requesting limit=168, which at the 15-min recommendations cadence covered only ~42 hours. Bumped to 10000 so 7d / 30d views actually have data.

📸 Tooling: screenshots harness

tools/screenshots.js and tools/dashboard-tabs.js use Puppeteer to capture README/docs screenshots at 1440×900 retina across every page × theme combo, with VM/CT names blurred from the live guest list. Set BLUR_NAMES=0 to disable. WSL prep is documented in the /screenshots skill.

README hero shots and gallery refreshed against the v2.9.x UI.

Full changelog

v2.9.0...v2.9.1