Key Colors test:
- New WS endpoint for live KC target test streaming (replaces REST polling)
- Auto-connect on lightbox open, auto-disconnect on close
- Uses same FPS/preview_width as CSS source test (no separate controls)
- Removed FPS selector, start/stop toggle, and updateAutoRefreshButton
Device cards:
- Fix full re-render on every poll caused by relative "Last seen" time in HTML
- Last seen label now patched in-place via data attribute (like FPS metrics)
- Remove overlay visualization button from LED target cards
Sync clocks:
- Fix card not updating start/stop icon: invalidate cache before reload
Other:
- Tab indicator respects bg-anim toggle (hidden when dynamic background off)
- Camera backend icon grid uses SVG icons instead of emoji
- Frontend context rule: no emoji in IconSelect items
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
UI fixes:
- Automation card badge moved to flex layout — title truncates, badge stays visible
- Automation condition pills max-width increased to 280px
- Dashboard crosslinks fixed: pass correct sub-tab key (led-targets not led)
- navigateToCard only skips data load when tab already has cards in DOM
- Badge gets white-space:nowrap + flex-shrink:0 to prevent wrapping
New features:
- formatCompact() for large frame/error counters (1.2M, 45.2K) with hover title
- Log filter and log level selects replaced with IconSelect grids
- OpenRGB devices now support software brightness control
OpenRGB improvements:
- Added brightness_control capability (uses software brightness fallback)
- Change-threshold dedup compares raw pixels before brightness scaling
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Performance: cache getBoundingClientRect in card-glare and drag-drop,
build adjacency Maps for O(1) graph BFS, batch WebGL uniform uploads,
cache matchMedia/search text in card-sections, use Map in graph-layout.
Code quality: extract shared FPS chart factory (chart-utils.js) and
FilterListManager (filter-list.js), replace 14-way CSS editor dispatch
with type handler registry, move state to state.js, fix layer violation
in api.js, add i18n for hardcoded strings, sync 53 missing locale keys,
add HTTP error logging in DataCache.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Split Sources tab: raw/raw_templates, processed/proc_templates each get own panel
- Split Targets tab: led-devices, led-targets, kc-targets, kc-patterns each get own panel
- Remove graph local search — search button and / key open global command palette
- Add graphNavigateToNode for command palette → graph node navigation
- Add tree group expand/collapse animation (max-height + opacity transition)
- Make tree group headers visually distinct (smaller, uppercase, left border on children)
- Make CardSection collapse opt-in via collapsible flag (disabled by default)
- Move filter textbox next to section title (remove margin-left: auto)
- Fix notification bell button vertical centering in test preview
- Fix clipboard copy on non-HTTPS with execCommand fallback
- Add overlay toggle button on picture-based CSS cards
- Add CSPT to graph add-entity picker and global search
- Update all cross-link navigation paths for new panel keys
- Add i18n keys for new tree groups and search groups (en/ru/zh)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove csColorStrips CardSection from targets.js, add to streams.js
- Add color_strip sub-tab with tree nav entry between Picture and Audio
- Update navigateToCard refs in target cards and command palette
- Update tutorial steps: remove led-css from targets, add color_strip to sources
- Add i18n keys for streams.group.color_strip and tour.src.color_strip
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Unify minimap/toolbar/legend drag+dock into shared _makeDraggable() helper
- Persist legend visibility and position, add active state to toggle buttons
- Show custom colors only on graph cards (entity defaults remain in legend)
- Replace emoji overlay buttons with SVG path icons
- Fix stale is_running blocking target start (auto-clear if task is done)
- Resolve device/target IDs to names in conflict error messages
- Hot-switch LED device on running target via async stop-swap-start cycle
- Compact automation dashboard cards and fix time_of_day localization
- Inline CSS source pill on target cards to save vertical space
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace flex-wrap with overflow ellipsis on .card-title and .template-name
- Reduce card title font size from 1.2rem/18px to 1.05rem
- Add title attribute (hover tooltip) on all card types for full name
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Stream live JPEG frames from picture sources into the test preview rectangle
- Add composite layer brightness display via value source streaming
- Fix missing id on css-test-rect-screen element that prevented frame display
- Preload images before swapping to eliminate flicker on frame updates
- Increase preview resolution to 480x360 and add subtle outline
- Prevent auto-focus on name field in modals on touch devices (desktopFocus)
- Fix performance chart padding, color picker clipping, and subtitle offset
- Add calibration-style ticks and source name/LED count to rectangle preview
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace plain dropdowns with visual icon grids:
- Animation type (static/gradient CSS sources): icons for each effect
- WLED target protocol: DDP vs HTTP with descriptions
Add i18n keys for protocol options in all 3 locales.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Animated conic gradient spins around the card edge using CSS Houdini
@property for smooth angle interpolation. Skips the left edge when
a custom card color stripe is assigned (data-has-color attribute).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When a target uses a composite CSS source, the LED preview now shows
individual layer strips below the blended composite result. Backend
stores per-layer color snapshots and sends an extended binary wire
format; frontend renders separate canvases with hover labels.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Move tab bar into header (centered between title and toolbar)
- Make entire header sticky with border-bottom separator
- Remove container max-width for full-width layout
- Add scroll-spy: tree sidebar tracks visible section on scroll
- Remember scroll position per tab when switching
- Remove sticky section headers, use scroll-margin-top instead
- Update sticky offsets to use --sticky-top CSS variable
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add TreeNav component that groups related entity types into a
collapsible hierarchy for Targets and Sources tabs. Targets tree
shows section-level leaves (Devices, Color Strips, LED Targets,
KC Targets, Pattern Templates) with scroll-to-section on click.
Sources tree groups into Picture, Audio, and Utility categories.
Also fixes missing csAudioTemplates in stream section expand/collapse.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add `tags: List[str]` field to all 13 entity types (devices, output targets,
CSS sources, picture sources, audio sources, value sources, sync clocks,
automations, scene presets, capture/audio/PP/pattern templates)
- Update all stores, schemas, and route handlers for tag CRUD
- Add GET /api/v1/tags endpoint aggregating unique tags across all stores
- Create TagInput component with chip display, autocomplete dropdown,
keyboard navigation, and API-backed suggestions
- Display tag chips on all entity cards (searchable via existing text filter)
- Add tag input to all 14 editor modals with dirty check support
- Add CSS styles and i18n keys (en/ru/zh) for tag UI
- Also includes code review fixes: thread safety, perf, store dedup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rename all Python modules, classes, API endpoints, config keys, frontend
fetch URLs, and Home Assistant integration URLs from picture-targets to
output-targets. Store loads both new and legacy JSON keys for backward
compatibility with existing data files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Autorestore fixes:
- Snapshot WLED state before connect() mutates it (lor, AudioReactive)
- Gate restore on auto_shutdown setting (was unconditional)
- Remove misleading auto_restore capability from serial provider
- Default auto_shutdown to false for all new devices
Protocol badge fixes:
- Show correct protocol per device type (OpenRGB SDK, MQTT, WebSocket)
- Was showing "Serial" for all non-WLED devices
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
FPS chart stays always visible; timing, frames, keepalive, errors, and
uptime are collapsed behind an animated toggle. Error warning icon
appears next to target name when errors_count > 0. Uses CSS grid
0fr→1fr transition for smooth expand/collapse animation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace plain <select> dropdowns with a searchable command palette modal
for 16 entity selectors across 6 editors (targets, streams, CSS sources,
value sources, audio sources, pattern templates). Unified EntityPalette
singleton + EntitySelect wrapper in core/entity-palette.js.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add `startup` automation condition type that activates on server boot,
replacing the per-target `auto_start` flag
- Remove `auto_start` field from targets, scene snapshots, and all API layers
- Remove auto-start UI section and star buttons from dashboard and target cards
- Remove `color` field from scene presets (backend, API, modal, frontend)
- Add card color support to scene preset cards (color picker + border style)
- Show localStorage-backed card colors on all dashboard cards (targets,
automations, sync clocks, scene presets)
- Fix card color picker updating wrong card when duplicate data attributes
exist by using closest() from picker wrapper instead of global querySelector
- Add sync clocks step to Sources tab tutorial
- Bump SW cache v9 → v10
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces Synchronization Clocks — shared, controllable time bases
that CSS sources can optionally reference for synchronized animation.
Backend:
- New SyncClock dataclass, JSON store, Pydantic schemas, REST API
- Runtime clock with thread-safe pause/resume/reset and speed control
- Ref-counted runtime pool with eager creation for API control
- clock_id field on all ColorStripSource types
- Stream integration: clock time/speed replaces source-local values
- Paused clock skips rendering (saves CPU + stops frame pushes)
- Included in backup/restore via STORE_MAP
Frontend:
- Sync Clocks tab in Streams section with cards and controls
- Clock dropdown in CSS editor (hidden speed slider when clock set)
- Clock crosslink badge on CSS source cards (replaces speed badge)
- Targets tab uses DataCache for picture/audio sources and sync clocks
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Zone picker UI in device add/settings modals with per-zone checkbox selection
- Combined mode: pixels distributed sequentially across zones
- Separate mode: full effect resampled independently to each zone via linear interpolation
- Per-zone LED preview in target cards: one canvas strip per zone with hover overlay labels
- Zone badges on device cards enriched with actual LED counts from OpenRGB API
- Fix stale led_count by using device_led_count discovered at connect time
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Color picker popover now uses fixed positioning on small screens to
escape the header toolbar overflow container. Section titles, sub-tab
labels, and filter placeholders use data-i18n attributes so they update
automatically on language change. Display picker title switches to
"Select a Device" for engine-owned display lists.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add stop-all buttons to LED targets and KC targets section headers
(visible only when targets are running, uses headerExtra on CardSection)
- Add reset ability to performance chart color pickers (removes custom
color from localStorage and reverts to default)
- Remove CODEBASE_REVIEW.md
- Add prioritized TODO.md with P1/P2/P3 feature roadmap
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- CardSection._animateEntrance: skip after first render to prevent
card fade-in replaying on every data refresh
- automations: use reconcile() on subsequent renders instead of full
innerHTML replacement that destroyed and recreated all cards
- streams: same reconcile() approach for all 9 CardSections
- targets/dashboard/streams: only show setTabRefreshing loading bar
on first render when the tab is empty
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use error.detail from API responses instead of generic i18n messages
so users see specific reasons for failures (e.g. "Device is referenced
by target(s): ...").
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce localStorage-backed card color assignment for all card types
with a reusable wrapCard() helper that provides consistent card shell
structure (top actions, bottom actions with color picker). Move color
picker from top-right to bottom-right action bar. Add color reset
button to clear card color back to default.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- New WS device type: broadcaster singleton + LEDClient that sends binary
frames to connected WebSocket clients during processing
- FastAPI WS endpoint at /api/v1/devices/{device_id}/ws with token auth
- Frontend: add/edit WS devices, connection URL with copy button in settings
- Add health_check and auto_restore capabilities to WLED and Serial providers;
hide health interval and auto-restore toggle for devices without them
- Skip health check loop for virtual devices (Mock, MQTT, WS) — set always-online
- Copy buttons and labels for API CSS push endpoints (REST POST / WebSocket)
- Hide mock:// and ws:// URLs in target device dropdown
- Hide filter textbox when card section is collapsed (cs-collapsed CSS class)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Stability:
- Fix race condition: set _is_running before create_task in target processors
- Await probe task after cancel in wled_target_processor
- Replace raw fetch() with fetchWithAuth() across devices, kc-targets, pattern-templates
- Add try/catch to showTestTemplateModal in streams.js
- Wrap blocking I/O in asyncio.to_thread (picture_targets, system restore)
- Fix dashboardStopAll to filter only running targets with ok guard
Performance:
- Vectorize fire effect spark loop with numpy in effect_stream
- Vectorize FFT band binning with cumulative sum in analysis.py
- Rewrite pixel_processor with vectorized numpy (accept ndarray or list)
- Add httpx.AsyncClient connection pooling with lock in wled_provider
- Optimize _send_pixels_http to avoid np.hstack allocation in wled_client
- Mutate chart arrays in-place in dashboard, perf-charts, targets
- Merge dashboard 2-batch fetch into single Promise.all
- Hoist frame_time outside loop in mapped_stream
Usability:
- Fix health check interval load/save in device settings
- Swap confirm modal button classes (No=secondary, Yes=danger)
- Add aria-modal to audio/value source editors, fix close button aria-labels
- Add modal footer close button to settings modal
- Add dedicated calibration LED count validation error keys
i18n:
- Replace ~50 hardcoded English strings with t() calls across 12 JS files
- Add 50 new keys to en.json, ru.json, zh.json
- Localize inline toasts in index.html with window.t fallback
- Add data-i18n to command palette footer
- Add localization policy to CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Replace all emoji characters across WebUI with inline Lucide SVG icons
for cross-platform consistency (icon paths in icon-paths.js)
- Add accent color picker popover with 9 preset colors + custom picker,
persisted to localStorage, updates all CSS custom properties
- Remove subtab separator line for cleaner look
- Color badge icons with accent color for visual pop
- Remove processing badge from target cards
- Fix hardcoded #4CAF50 in FPS labels and active badges to use CSS vars
- Replace CSS content emoji (▶) with pure CSS triangle
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add sub-tutorials for Dashboard, Targets, Sources, and Profiles tabs
with ? trigger buttons, en/ru/zh translations, and hidden-ancestor
skip via offsetParent check
- Add expand/collapse all buttons to Profiles tab toolbar
- Move dashboard poll slider from section header to toolbar
- Fix cardEnter animation forcing opacity:1 on disabled profile cards
- Use data-card-section selectors instead of data-cs-toggle to avoid
z-index misalignment during tutorial spotlight
- Add tutorial sync convention to CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dashboard cards (targets, auto-start, profiles) are now clickable,
navigating to the full entity card on the appropriate tab. Card
sections support drag-and-drop reordering via grip handles with
localStorage persistence. Fix crosslink navigation scoping to avoid
matching dashboard cards, and fix highlight race on rapid clicks.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add protocol field (ddp/http) to storage, API schemas, routes, processor
- WledTargetProcessor passes protocol to create_led_client(use_ddp=...)
- Target editor: protocol dropdown + keepalive in collapsible Specific Settings
- FPS, brightness threshold, adaptive FPS moved to main form area
- Hide Specific Settings section for serial devices (protocol is WLED-only)
- Card badge: show DDP/HTTP for WLED devices, Serial for serial devices
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DDP uses fire-and-forget UDP, so when a WiFi device becomes overwhelmed
by sustained traffic, sends appear successful while the device is
actually unreachable. This adds:
- HTTP liveness probe (GET /json/info, 2s timeout) every 10s during
streaming, exposed as device_streaming_reachable in target state
- Adaptive FPS (opt-in): exponential backoff when device is unreachable,
gradual recovery when it stabilizes — finds sustainable send rate
- Honest health checks: removed the lie that forced device_online=true
during streaming; now runs actual health checks regardless
- Target editor toggle, FPS display shows effective rate when throttled,
health dot reflects streaming reachability, red highlight when
unreachable
- Auto-backup scheduling support in settings modal
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Stability: Add outer try/except/finally with _running=False cleanup to all 6
processing loop methods (live, color_strip, effect, audio, composite, mapped).
Add exponential backoff on consecutive capture errors in live_stream. Move
audio stream.stop() outside lock scope.
Performance: Replace per-pixel Python loop with np.array().tobytes() in
ddp_client. Vectorize pixelate filter with cv2.resize down+up. Vectorize
gradient rendering with np.searchsorted.
Frontend: Add lockBody/unlockBody re-entrancy counter. Add {once:true} to
fetchWithAuth abort listener. Null ws.onclose before ws.close() in LED preview.
Backend: Remove auth token prefix from log messages. Add atomic_write_json
helper (tempfile + os.replace) and update all 10 stores. Add name uniqueness
checks to all update methods. Fix DELETE status codes to 204 in audio_sources
and value_sources. Fix get_source() silent bug in color_strip_sources.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add real-time value source test: WebSocket endpoint streams get_value() at
~20Hz, frontend renders scrolling time-series chart with min/max/current stats
- Add auto-gain for audio value sources: rolling peak normalization with slow
decay, sensitivity range increased to 0.1-20.0
- Always show brightness overlay on LED preview when brightness source is set
- Refactor ValueStreamManager to shared ref-counted streams (value streams
produce scalars, not LED-count-dependent, so sharing is correct)
- Simplify acquire/release API: remove consumer_id parameter since streams
are no longer consumer-dependent
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New per-target property: when effective output brightness
(max pixel value × device/source brightness) falls below
the threshold, LEDs turn off completely. Useful for cutting
dim flicker in audio-reactive and ambient setups.
Threshold slider (0–254) in target editor, badge on card,
hot-swap to running processors, persisted in storage.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show effective brightness percentage on the LED preview when a
value source dims below 100%. Prepend a brightness byte to the
preview WebSocket wire format. Increase preview height to 32px.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The dashboard panel appears before the targets panel in the DOM and both
use data-target-id. document.querySelector was finding the dashboard
element (which has no data-tm children) instead of the target card.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Charts: blue filled area for fps_actual (rolling avg), green line for
fps_current (real-time sends/sec)
- Labels: fps_current/fps_target as primary, avg fps_actual as secondary
- Track fps_current in metrics history for dashboard chart preload
- Applied to both LED targets page and dashboard
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix inverted gamma formula: use (i/255)^gamma instead of (i/255)^(1/gamma)
so gamma>1 correctly darkens midtones (standard LED gamma correction)
- Fix frame interpolation flicker: move interp buffer update after temporal
smoothing so idle-tick output is consistent with new-frame output
- Fix target card hover/animation reset: use stable placeholder values in
card HTML for volatile metrics (data-tm attributes), patch real values
in-place after reconcile instead of replacing entire card DOM element
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add tab refresh loading bar animation for all 4 tab loaders
- Add profiles loading guard to prevent concurrent fetches
- Centralize theme colors into CSS variables (--text-secondary, --text-muted,
--bg-secondary, --success-color, --shadow-color) for both dark/light themes
- Replace hardcoded gray values across 10 CSS files with variables
- Fix duplicate .btn-sm definition in modal.css
- Fix z-index: toast 2001→2500 to safely clear modals at 2000
- Add :focus-visible keyboard navigation indicators for all interactive elements
- Add responsive breakpoints for tab bar and header on narrow screens
- Prevent background page scroll when command palette is open
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add loading guard to loadPictureSources to prevent concurrent fetches
- Pause perf chart polling and uptime timer when browser tab is hidden
- Disconnect KC and LED preview WebSockets when leaving targets tab
- Add error toasts to loadCaptureTemplates and saveKCBrightness
- Skip auto-refresh polling when document is hidden
- Widen auto-start dashboard cards for better text display
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add auto_start boolean field to PictureTarget model (persisted per-target)
- Wire auto_start through API schemas, routes, and store
- Auto-start targets on server boot in main.py lifespan
- Add star toggle button on target cards (next to delete button)
- Add auto-start section on dashboard between performance and profiles
- Remove auto-start section from profiles tab
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Keyboard shortcuts: Ctrl+1-4 for tab switching
- URL hash routing: #tab/subtab format with browser back/forward support
- Tab count badges: running targets and active profiles counts
- Cross-entity quick links: clickable references navigate to related cards
- Command palette (Ctrl+K): global search across all entities with keyboard navigation
- Expand/collapse all sections: buttons in sub-tab bars
- Sticky section headers: headers pin while scrolling long card grids
- Improved section filter: better styling with reset button
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>