# 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. ```bash 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/` excluding `static/`): Auto-restart the server. See [contexts/server-operations.md](contexts/server-operations.md) for the restart procedure. - **Frontend changes** (`static/js/`, `static/css/`): Run `cd server && npm run build` to rebuild the bundle. No server restart needed. ## Project Structure - `/server` — Python FastAPI backend (see [server/CLAUDE.md](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](contexts/frontend.md) | HTML, CSS, JS/TS, i18n, modals, icons, bundling | | [contexts/graph-editor.md](contexts/graph-editor.md) | Visual graph editor changes | | [contexts/server-operations.md](contexts/server-operations.md) | Server restart, startup modes, demo mode | | [contexts/chrome-tools.md](contexts/chrome-tools.md) | Chrome MCP tool usage for testing | | [contexts/ci-cd.md](contexts/ci-cd.md) | CI/CD pipelines, release workflow, build scripts | | [server/CLAUDE.md](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: 1. **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 2. **Log a clear warning** when migration happens so the user knows 3. **Keep the old file as a backup** after migration (rename to `.migrated` or similar) 4. **Test the migration** with both old-format and new-format data files 5. **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. ## Pre-Commit Checks (MANDATORY) Before every commit, run the relevant linters and fix any issues: - **Python changes**: `cd server && ruff check src/ tests/ --fix` - **TypeScript changes**: `cd server && npx tsc --noEmit && npm run build` - **Both**: Run both checks Do NOT commit code that fails linting. Fix the issues first. ## 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