Commit Graph

29 Commits

Author SHA1 Message Date
alexei.dolgolyov fd46c51dba docs: TODO + CLAUDE.md notes + locale keys for new features
TODO.md grows the device-support follow-up roadmap. CLAUDE.md trims a
stale section. en/ru/zh locales add the strings used by the new
HTTP-endpoint editor, MiniSelect labels, automations expansion, and
value-source kinds. Ru/zh parity for the older keys is tracked
separately in REVIEW_TODO.md.
2026-05-23 00:50:31 +03:00
alexei.dolgolyov 9d4a534ec6 feat(ui): release notes overlay v2 + settings/streams/dashboard polish
Release Notes overlay redesign (scoped via .release-notes-shell)
- Backend exposes release.assets (name/size/download_url) through
  UpdateReleaseInfo so the frontend can render real download links.
- New masthead: eyebrow + display-font title + tag/published/pre-release
  chip strip + close/external action buttons; opts out of layout.css's
  global `header { height: 60px }` and `header::before` accent bar that
  were leaking into the overlay's <header>.
- Markdown body: <code> filenames are wrapped in clickable <a> via fuzzy
  asset match (exact basename, then same-extension token-overlap), with
  per-asset description tooltip and a small download glyph.
- Per-asset description derived from filename pattern (Windows installer
  /portable/msi, Linux tarball/AppImage/deb/rpm, macOS dmg/pkg, Android
  apk/aab, iOS ipa, generic archives) with i18n keys in en/ru/zh.
- Hide checksum / signature side-files (.sha256/.sha512/.sig/.asc/...).

Settings modal & dashboard polish
- ds-section refresh, rail-channel routing, notif matrix updates.
- Dashboard customize panel + per-account layout updates.
- New docs/settings-modal-redesign.html design reference.

Streams / targets / color-strip
- Stream cards rewrite (cards.css, streams.css, streams.ts).
- Composite stream + metrics history adjustments.
- WLED target processor + color-strip pipeline refinements.
- Color-strip WS source streamer touch-ups.

Misc
- Perf charts overhaul; tabular game-integration / HA / MQTT / weather
  source cards; donation/sync-clocks/scene-presets minor polish.
- New i18n keys across en/ru/zh.

Test infrastructure
- conftest pre-creates the test DB so main.py's legacy-data migration
  doesn't shovel the user's production DB into the test temp dir.
- test_preferences_notifications wipes its own setting at the start of
  the defaults test (was relying on isolation it never enforced).

Pre-commit gates: ruff clean, tsc clean, npm run build clean,
pytest 899/899 passing.
2026-04-29 17:14:05 +03:00
alexei.dolgolyov 8574424fb7 feat: Android TV app embedding Python server via Chaquopy
Lint & Test / test (push) Successful in 2m10s
Adds a native Android TV application that runs the full LedGrab Python
server in-process via Chaquopy. Captures the TV box screen using the
MediaProjection API and exposes the existing web UI on the device's
local network — users configure via phone/tablet browser.

Android (new /android/ module):
- Kotlin shell: MainActivity, CaptureService (foreground service),
  ScreenCapture (MediaProjection + ImageReader), PythonBridge (Chaquopy).
- Polished Leanback-themed UI with QR code for easy web UI access.
- AGP 8.9 + Chaquopy 17 + Gradle 8.11 (avoids the AGP 8.7 thread-lock bug).
- Pre-built pydantic-core wheels for arm64-v8a, x86_64, x86 cross-compiled
  with maturin + Android NDK, linked against Chaquopy's libpython3.11.so.

Python server platform guards:
- New utils/platform.py with is_android()/is_windows()/is_linux() helpers.
- Guard every top-level import of desktop-only packages (mss, psutil,
  sounddevice, pyserial, PyAudioWPatch, etc.) with try/except ImportError.
- Android-incompatible calls gated with None-checks so the server runs on
  reduced capabilities on Android (no CPU/RAM metrics, no mss displays).
- utils/image_codec.py gains a Pillow fallback for resize + JPEG encode
  when cv2 is unavailable; all internal cv2.resize callers migrated.
- New android_entry.py start_server/stop_server invoked from Kotlin.
- get_displays API falls back to best available engine when mss fails.

New capture engines:
- MediaProjectionEngine: receives RGBA frames pushed from Kotlin through
  a thread-safe queue; caches last frame for static-screen previews.
- ScrcpyClientEngine: optional H.264 streaming via scrcpy-client library
  (priority 10, overrides the ADB-screencap engine when installed).

Frontend:
- Tab loaders previously required an apiKey; now correctly treat
  "auth disabled" as authenticated (Android has no auth by default).
- Re-trigger the active tab's loader after loadServerInfo resolves
  authRequired, since initTabs runs earlier.
- Add i18n keys for the demo / mediaprojection / scrcpy_client engines.

Docs:
- TODO.md: follow-ups for multi-ABI wheel rebuilds, CI pipeline, USB
  serial LED controllers, root-only capture, perf metrics abstraction.
- CLAUDE.md: Android dependency sync policy (pip --exclude doesn't exist).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 03:11:43 +03:00
alexei.dolgolyov 02cd9d519c refactor: rename project to LedGrab, split HA integration into separate repo
Lint & Test / test (push) Successful in 1m56s
- Rename Python package: wled_controller -> ledgrab
- Rename env var prefix: WLED_ -> LEDGRAB_ (with auto-migration for old vars)
- Rename localStorage key: wled_api_key -> ledgrab_api_key (with migration)
- Rename HA integration domain: wled_screen_controller -> ledgrab
- Update all imports, build scripts, Docker, installer, config, docs
- Remove HA integration (moved to ledgrab-haos-integration repo)
- Remove hacs.json (belongs in HA repo now)
- Add startup warning for users with old WLED_ env vars
- All tests pass (715/715), ruff clean, tsc clean, frontend builds
2026-04-12 22:45:28 +03:00
alexei.dolgolyov 29fb944494 fix: resolve test pollution from freeze_saves and fix os_listener toggle
Lint & Test / test (push) Successful in 27s
- Add unfreeze_saves() to base_store.py and call it in e2e cleanup.
  The backup restore flow calls freeze_saves() which sets a module-level
  flag that silently disables all store _save() calls. Without reset,
  this poisoned all subsequent persistence tests (9 failures).
- Fix os_listener toggle to use toggle-switch/toggle-slider CSS classes
  instead of nonexistent switch/slider classes (was showing plain checkbox).
- Add mandatory test run to CLAUDE.md pre-commit checks.

All 341 tests now pass.
2026-03-24 22:26:57 +03:00
alexei.dolgolyov 9b80076b5b feat: expand color strip sources with new effects, gradient improvements, and daylight/candlelight enhancements
Lint & Test / test (push) Failing after 29s
Effects: add 7 new procedural effects (rain, comet, bouncing ball, fireworks,
sparkle rain, lava lamp, wave interference) and custom palette support via
user-defined [[pos,R,G,B],...] stops.

Gradient: add easing functions (linear, ease_in_out, step, cubic) for stop
interpolation, plus noise_perturb and hue_rotate animation types.

Daylight: add longitude field and NOAA solar equations for accurate
sunrise/sunset based on latitude, longitude, and day of year.

Candlelight: add wind simulation (correlated gusts), candle type presets
(taper/votive/bonfire), and wax drip effect with localized brightness dips.

Also fixes editor preview to include all new fields for inline LED test.
2026-03-23 22:40:55 +03:00
alexei.dolgolyov e391346b4b docs: reference Gitea CI/CD guide from claude-code-facts repo
Lint & Test / test (push) Successful in 29s
2026-03-23 01:17:34 +03:00
alexei.dolgolyov 0716d602e2 docs: add CI/CD context file and pre-commit lint rule
Lint & Test / test (push) Failing after 13s
Create contexts/ci-cd.md documenting release pipeline, build scripts,
CI runners, and versioning. Reference it from CLAUDE.md context table.
Add mandatory pre-commit lint check rule to CLAUDE.md.
2026-03-22 13:52:47 +03:00
alexei.dolgolyov 42bc05c968 fix: update release description to match current build artifacts
Lint & Test / test (push) Failing after 14s
Add Windows installer, Docker volume mount, and first-time setup
instructions to the Gitea release body. Fix Docker registry URL.
Add CI/Release sync rule to CLAUDE.md.
2026-03-22 13:50:46 +03:00
alexei.dolgolyov 6a6c8b2c52 perf: reduce portable build size ~40MB — replace winsdk/wmi, migrate cv2 to Pillow
Lint & Test / test (push) Failing after 19s
- Replace winsdk (~35MB) with winrt packages (~2.5MB) for OS notification
  listener. API is identical, 93% size reduction.
- Replace wmi (~3-5MB) with ctypes for monitor names (EnumDisplayDevicesW)
  and camera names (SetupAPI). Zero external dependency.
- Migrate cv2.resize/imencode/LUT to Pillow/numpy in 5 files (filters,
  preview helpers, kc_target_processor). OpenCV only needed for camera
  and video stream now.
- Fix DefWindowProcW ctypes overflow on 64-bit Python (pre-existing bug
  in platform_detector display power listener).
- Fix openLightbox import in streams-capture-templates.ts (was using
  broken window cast instead of direct import).
- Add mandatory data migration policy to CLAUDE.md after silent data
  loss incident from storage file rename without migration.
2026-03-22 13:35:01 +03:00
alexei.dolgolyov f2871319cb refactor: comprehensive code quality, security, and release readiness improvements
Lint & Test / test (push) Failing after 48s
Security: tighten CORS defaults, add webhook rate limiting, fix XSS in
automations, guard WebSocket JSON.parse, validate ADB address input,
seal debug exception leak, URL-encode WS tokens, CSS.escape in selectors.

Code quality: add Pydantic models for brightness/power endpoints, fix
thread safety and name uniqueness in DeviceStore, immutable update
pattern, split 6 oversized files into 16 focused modules, enable
TypeScript strictNullChecks (741→102 errors), type state variables,
add dom-utils helper, migrate 3 modules from inline onclick to event
delegation, ProcessorDependencies dataclass.

Performance: async store saves, health endpoint log level, command
palette debounce, optimized entity-events comparison, fix service
worker precache list.

Testing: expand from 45 to 293 passing tests — add store tests (141),
route tests (25), core logic tests (42), E2E flow tests (33), organize
into tests/api/, tests/storage/, tests/core/, tests/e2e/.

DevOps: CI test pipeline, pre-commit config, Dockerfile multi-stage
build with non-root user and health check, docker-compose improvements,
version bump to 0.2.0.

Docs: rewrite CLAUDE.md (202→56 lines), server/CLAUDE.md (212→76),
create contexts/server-operations.md, fix .js→.ts references, fix env
var prefix in README, rewrite INSTALLATION.md, add CONTRIBUTING.md and
.env.example.
2026-03-22 00:38:28 +03:00
alexei.dolgolyov 2240471b67 Add demo mode: virtual hardware sandbox for testing without real devices
Demo mode provides a complete sandbox environment with:
- Virtual capture engine (radial rainbow test pattern on 3 displays)
- Virtual audio engine (synthetic music-like audio on 2 devices)
- Virtual LED device provider (strip/60, matrix/256, ring/24 LEDs)
- Isolated data directory (data/demo/) with auto-seeded sample entities
- Dedicated config (config/demo_config.yaml) with pre-configured API key
- Frontend indicator (DEMO badge + dismissible banner)
- Engine filtering (only demo engines visible in demo mode)
- Separate entry point: python -m wled_controller.demo (port 8081)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 16:17:14 +03:00
alexei.dolgolyov bbe42ee0a2 Graph editor: unified card colors, keyboard focus, color picker button
- Unified graph node colors with card color system (shared localStorage)
- Added color picker palette button to node overlay toolbar
- Auto-focus graph container for keyboard shortcuts to work immediately
- Trap Tab key to prevent focus escaping to footer
- Added mandatory bundle rebuild note to CLAUDE.md files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 17:34:07 +03:00
alexei.dolgolyov e912019873 Improve CSS test preview: HD resolution, screen-only border, and refactor frontend docs
- Bump capture preview resolution from 480×360 to 960×540 (HD)
- Increase preview FPS from 2 to ~12 FPS (AUX_INTERVAL 0.5→0.08)
- Add accent-color border on screen rect only (not LED edges) via ::after
- Use dynamic aspect-ratio from decoded JPEG frames instead of fixed height
- Widen modal to 900px for picture sources
- Move frontend conventions from CLAUDE.md to contexts/frontend.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 01:50:23 +03:00
alexei.dolgolyov f6f428515a Update TODO.md and add task tracking rule to CLAUDE.md
Remove completed/deferred items from TODO.md and add instruction
to use TODO.md as the primary task tracker instead of TodoWrite.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 17:40:16 +03:00
alexei.dolgolyov 155bbdbc24 Update ast-index instructions in CLAUDE.md
Add subagent guidance, version check, and additional commands
(hierarchy, changed, update).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:38:12 +03:00
alexei.dolgolyov ac10b53064 Add ast-index as primary code search tool in CLAUDE.md
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 14:15:26 +03:00
alexei.dolgolyov 2712c6682e Add EntitySelect/IconSelect UI improvements across modals
- Portal IconSelect popups to document.body with position:fixed to prevent
  clipping by modal overflow-y:auto
- Replace custom scene selectors in automation editor with EntitySelect
  command-palette pickers (main scene + fallback scene)
- Add IconSelect grid for automation deactivation mode (none/revert/fallback)
- Add IconSelect grid for automation condition type and match type
- Replace mapped zone source dropdowns with EntitySelect pickers
- Replace scene target selector with EntityPalette.pick() pattern
- Remove effect palette preview bar from CSS editor
- Remove sensitivity badge from audio color strip source cards
- Clean up unused scene-selector CSS and scene-target-add-row CSS
- Add locale keys for all new UI elements across en/ru/zh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 16:00:30 +03:00
alexei.dolgolyov bd8d7a019f Codebase review: stability, performance, usability, and i18n fixes
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>
2026-02-28 12:12:37 +03:00
alexei.dolgolyov efb6cf7ce6 Add per-tab tutorials, profile expand/collapse, and fix card animation
- 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>
2026-02-27 14:15:41 +03:00
alexei.dolgolyov bafd8b4130 Add value source card crosslinks and fix scene initial value bias
- Audio value source cards link to the referenced audio source
- Adaptive scene cards link to the referenced picture source
- Fix SceneValueStream starting at 0.5 regardless of actual scene;
  first frame now skips smoothing to avoid artificial bias
- Add crosslinks guidance to CLAUDE.md card appearance section

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 16:56:26 +03:00
alexei.dolgolyov 466527bd4a Add clone buttons, fix card navigation highlight, UI polish
- Add clone buttons to Audio Source and Value Source cards
- Fix command palette navigation destroying card highlight by skipping
  redundant data reload (skipLoad option on switchTab)
- Convert value source modal sliders to value-in-label pattern
- Change audio/value source modal footers to icon-only buttons
- Remove separator lines between card sections
- Add UI conventions to CLAUDE.md (card appearance, modal footer, sliders)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 03:10:36 +03:00
alexei.dolgolyov e4c4301a7b Add dirty check to all remaining editor modals
Subclass Modal with snapshotValues() for: value source editor, audio
source editor, add device, profile editor, capture template, stream
editor, and PP template modals. Close/cancel now triggers discard
confirmation when form has unsaved changes. Document the convention
in CLAUDE.md.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 18:12:30 +03:00
alexei.dolgolyov 808037775f Remove target segments, use single color strip source per target
Segments are redundant now that the "mapped" CSS type handles spatial
multiplexing internally. Each target now references one color_strip_source_id
instead of an array of segments with start/end/reverse ranges.

Backward compat: existing targets with old segments format are migrated
on load by extracting the first segment's CSS source ID.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 00:00:26 +03:00
alexei.dolgolyov bef28ece5c Add static color support, HAOS light entity, and real-time profile updates
- Add static_color capability to WLED and serial providers with native
  set_color() dispatch (WLED uses JSON API, serial uses idle client)
- Encapsulate device-specific logic in providers instead of device_type
  checks in ProcessorManager and API routes
- Add HAOS light entity for devices with brightness_control + static_color
  (Adalight/AmbiLED get light entity, WLED keeps number entity)
- Fix serial device brightness and turn-off: pass software_brightness
  through provider chain, clear device on color=null, re-send static
  color after brightness change
- Add global events WebSocket (events-ws.js) replacing per-tab WS,
  enabling real-time profile state updates on both dashboard and profiles tabs
- Fix profile activation: mark active when all targets already running,
  add asyncio.Lock to prevent concurrent evaluation races, skip process
  enumeration when no profile has conditions, trigger immediate evaluation
  on enable/create/update for instant target startup
- Add reliable server restart script (restart.ps1)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 14:23:47 +03:00
alexei.dolgolyov 8d4dbbcc7f Polish Pattern Template UI: dialog sizing, KC editor layout, and conventions
- Fix dialog/canvas sizing: fit-content dialog follows canvas width, canvas
  max-width: 100% prevents overflow, horizontal resize supported
- Move pattern template dropdown above FPS/mode/smoothing in KC editor
- Remove emoji from pattern template dropdown options and auto-generated names
- Remove placeholder option from pattern template select, default to first
- Rename default pattern template from "Default" to "Full Screen"
- Add UI conventions to CLAUDE.md (hint pattern, select dropdown rules)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 18:46:08 +03:00
alexei.dolgolyov 58df163ded Rename WLED Grab to LED Grab, merge Devices into Targets tab with WLED sub-tab, and UI polish
- Rename "WLED Grab" to "LED Grab" across all files (title, logs, locales)
- Merge Devices and Targets into a single Targets tab with WLED sub-tab
  containing Devices and Targets sections (like Sources tab pattern)
- Make target card source name label full-width
- Render engine template config as two-column key-value grid
- Update CLAUDE.md: no server restart needed for frontend-only changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 15:44:11 +03:00
alexei.dolgolyov 3db7ba4b0e Fix DXcam engine and improve UI: loading spinners, template card gap
DXcam engine overhaul:
- Remove all user-facing config (device_idx, output_idx, output_color)
  since these are auto-resolved or hardcoded to RGB
- Use one-shot grab() mode with retry for reliability
- Lazily create camera per display via _ensure_camera()
- Clear dxcam global factory cache to prevent stale DXGI state

UI improvements:
- Replace "Loading..." text with CSS spinner animations
- Fix template card header gap on default cards (scope padding-right
  to cards with remove button only via :has selector)
- Add auto-restart server rule to CLAUDE.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 17:26:38 +03:00
alexei.dolgolyov 5370d80466 Add capture template system with in-memory defaults and split device settings UI
Validate / validate (push) Failing after 8s
- Generate default templates (MSS, DXcam, WGC) in memory from EngineRegistry at startup
- Only persist user-created templates to JSON, skip defaults on load/save
- Add capture_template_id to Device model and DeviceCreate schema
- Remember last used template in localStorage, use it for new devices with fallback
- Split Device Settings dialog into General Settings and Capture Settings
- Add capture settings button (🎬) to device card
- Separate default and custom templates with visual separator in Templates tab
- Add capture engine integration to ProcessorManager
- Add CLAUDE.md with git commit/push policy and server restart instructions
- Add en/ru localization for all new UI elements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 02:43:49 +03:00