- 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.
4.4 KiB
Claude Instructions for WLED Screen Controller
Code Search
If ast-index is available, use it as the PRIMARY code search tool. It is significantly faster than grep and returns structured, accurate results. Fall back to grep/Glob only when ast-index is not installed, returns empty results, or when searching regex patterns/string literals/comments.
IMPORTANT for subagents: When spawning Agent subagents (Plan, Explore, general-purpose, etc.), always instruct them to use ast-index via Bash for code search instead of grep/Glob. Example: include "Use ast-index search, ast-index class, ast-index usages etc. via Bash for code search" in the agent prompt.
ast-index search "Query" # Universal search
ast-index class "ClassName" # Find class/struct/interface definitions
ast-index usages "SymbolName" # Find all usage sites
ast-index symbol "FunctionName" # Find any symbol
ast-index callers "FunctionName" # Find all call sites
ast-index outline "path/to/File.py" # Show all symbols in a file
ast-index changed --base master # Show symbols changed in current branch
Git Commit and Push Policy
NEVER commit or push without explicit user approval. Wait for the user to review changes and explicitly say "commit" or "push". Completing a task, "looks good", or "thanks" do NOT count as approval. See the system-level instructions for the full commit workflow.
Auto-Restart and Rebuild Policy
- Python code changes (
server/src/excludingstatic/): Auto-restart the server. See contexts/server-operations.md for the restart procedure. - Frontend changes (
static/js/,static/css/): Runcd server && npm run buildto rebuild the bundle. No server restart needed.
Project Structure
/server— Python FastAPI backend (see server/CLAUDE.md)/contexts— Context files for Claude (frontend conventions, graph editor, Chrome tools, server ops, demo mode)
Context Files
| File | When to read |
|---|---|
| contexts/frontend.md | HTML, CSS, JS/TS, i18n, modals, icons, bundling |
| contexts/graph-editor.md | Visual graph editor changes |
| contexts/server-operations.md | Server restart, startup modes, demo mode |
| contexts/chrome-tools.md | Chrome MCP tool usage for testing |
| server/CLAUDE.md | Backend architecture, API patterns, common tasks |
Task Tracking via TODO.md
Use TODO.md in the project root as the primary task tracker. Do NOT use the TodoWrite tool — all progress tracking goes through TODO.md.
Documentation Lookup
Use context7 MCP tools for library/framework documentation lookups (FastAPI, OpenCV, Pydantic, yt-dlp, etc.) instead of relying on potentially outdated training data.
Data Migration Policy (CRITICAL)
NEVER rename a storage file path, store key, entity ID prefix, or JSON field name without writing a migration. User data lives in JSON files under data/. If the code starts reading from a new filename while the old file still has user data, THAT DATA IS SILENTLY LOST.
When renaming any storage-related identifier:
- Add migration logic in
BaseJsonStore.__init__(or the specific store) that detects the old file/key and migrates data to the new name automatically on startup - Log a clear warning when migration happens so the user knows
- Keep the old file as a backup after migration (rename to
.migratedor similar) - Test the migration with both old-format and new-format data files
- Document the migration in the commit message
This applies to: file paths in StorageConfig, JSON root keys (e.g. picture_targets → output_targets), entity ID prefixes (e.g. pt_ → ot_), and any field renames in dataclass models.
Incident context: A past rename of picture_targets.json → output_targets.json was done without migration. The app created a new empty output_targets.json while the user's 7 targets sat unread in the old file. Data was silently lost.
General Guidelines
- Always test changes before marking as complete
- Follow existing code style and patterns
- Update documentation when changing behavior
- Never make commits or pushes without explicit user approval