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>
8.9 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.
# Check if available:
ast-index version
# Rebuild index (first time or after major changes):
ast-index rebuild
# Common commands:
ast-index search "Query" # Universal search across files, symbols, modules
ast-index class "ClassName" # Find class/struct/interface definitions
ast-index usages "SymbolName" # Find all places a symbol is used
ast-index implementations "BaseClass" # Find all subclasses/implementations
ast-index symbol "FunctionName" # Find any symbol (class, function, property)
ast-index outline "path/to/File.cpp" # Show all symbols in a file
ast-index hierarchy "ClassName" # Show inheritance tree
ast-index callers "FunctionName" # Find all call sites
ast-index changed --base master # Show symbols changed in current branch
ast-index update # Incremental update after file changes
CRITICAL: Git Commit and Push Policy
🚨 NEVER CREATE COMMITS WITHOUT EXPLICIT USER APPROVAL 🚨
🚨 NEVER PUSH TO REMOTE WITHOUT EXPLICIT USER APPROVAL 🚨
Strict Rules
- DO NOT create commits automatically after making changes
- DO NOT commit without being explicitly instructed by the user
- DO NOT push to remote repository without explicit instruction
- ALWAYS WAIT for the user to review changes and ask you to commit
- ALWAYS ASK if you're unsure whether to commit
Workflow
- Make code changes as requested
- STOP - Inform user that changes are complete
- WAIT - User reviews the changes
- ONLY IF user explicitly says "commit" or "create a commit":
- Stage the files with
git add - Create the commit with a descriptive message
- STOP - Do NOT push
- Stage the files with
- ONLY IF user explicitly says "push" or "commit and push":
- Push to remote repository
What Counts as Explicit Approval
✅ YES - These mean you can commit:
- "commit"
- "create a commit"
- "commit these changes"
- "git commit"
✅ YES - These mean you can push:
- "push"
- "commit and push"
- "push to remote"
- "git push"
❌ NO - These do NOT mean you should commit:
- "that looks good"
- "thanks"
- "perfect"
- User silence after you make changes
- Completing a feature/fix
Example Bad Behavior (DON'T DO THIS)
❌ User: "Fix the MSS engine test issue"
❌ Claude: [fixes the issue]
❌ Claude: [automatically commits without asking] <-- WRONG!
Example Good Behavior (DO THIS)
✅ User: "Fix the MSS engine test issue"
✅ Claude: [fixes the issue]
✅ Claude: "I've fixed the MSS engine test issue by adding auto-initialization..."
✅ [WAITS FOR USER]
✅ User: "Looks good, commit it"
✅ Claude: [now creates the commit]
IMPORTANT: Auto-Restart Server on Code Changes
Whenever server-side Python code is modified (any file under /server/src/ excluding /server/src/wled_controller/static/), automatically restart the server so the changes take effect immediately. Do NOT wait for the user to ask for a restart.
No restart needed for frontend-only changes — but you MUST rebuild the bundle. The browser loads the esbuild bundle (static/dist/app.bundle.js, static/dist/app.bundle.css), NOT the source files. After ANY change to frontend files (JS, CSS under /server/src/wled_controller/static/), run:
cd server && npm run build
Without this step, changes will NOT take effect. No server restart is needed — just rebuild and refresh the browser.
Restart procedure
Use the PowerShell restart script — it reliably stops only the server process and starts a new detached instance:
powershell -ExecutionPolicy Bypass -File "c:\Users\Alexei\Documents\wled-screen-controller\server\restart.ps1"
Do NOT use Stop-Process -Name python (kills unrelated Python processes like VS Code extensions) or bash background & jobs (get killed when the shell session ends).
IMPORTANT: Server Startup Commands
There are two server modes with separate configs, ports, and data directories:
| Mode | Command | Config | Port | API Key | Data |
|---|---|---|---|---|---|
| Real | python -m wled_controller.main |
config/default_config.yaml |
8080 | development-key-change-in-production |
data/ |
| Demo | python -m wled_controller.demo |
config/demo_config.yaml |
8081 | demo |
data/demo/ |
Both can run simultaneously on different ports.
Restarting after code changes
-
Real server: Use the PowerShell restart script (it only targets the real server process):
powershell -ExecutionPolicy Bypass -File "c:\Users\Alexei\Documents\wled-screen-controller\server\restart.ps1" -
Demo server: Find and kill the process on port 8081, then restart:
# Find PID powershell -Command "netstat -ano | Select-String ':8081.*LISTEN'" # Kill it powershell -Command "Stop-Process -Id <PID> -Force" # Restart cd server && python -m wled_controller.demo
Do NOT use Stop-Process -Name python — it kills unrelated Python processes (VS Code extensions, etc.).
Project Structure
This is a monorepo containing:
/server- Python FastAPI backend (seeserver/CLAUDE.mdfor detailed instructions)/client- Future frontend client (if applicable)
Working with Server
For detailed server-specific instructions (restart policy, testing, etc.), see:
server/CLAUDE.md
Frontend (HTML, CSS, JS, i18n)
For all frontend conventions (CSS variables, UI patterns, modals, localization, tutorials), see contexts/frontend.md.
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.
- When starting a multi-step task: add sub-steps as
- [ ]items under the relevant section - When completing a step: mark it
- [x]immediately — don't batch updates - When a task is fully done: mark it
- [x]and leave it for the user to clean up - When the user requests a new feature/fix: add it to the appropriate section with a priority tag
Documentation Lookup
Use context7 MCP tools for library/framework documentation lookups. When you need to check API signatures, usage patterns, or current behavior of external libraries (e.g., FastAPI, OpenCV, Pydantic, yt-dlp), use mcp__plugin_context7_context7__resolve-library-id to find the library, then mcp__plugin_context7_context7__query-docs to fetch up-to-date docs. This avoids relying on potentially outdated training data.
IMPORTANT: Demo Mode Awareness
When adding new entity types, engines, device providers, or stores — keep demo mode in sync:
- New entity stores: Add the store's file path to
StorageConfiginconfig.py— themodel_post_init()auto-rewritesdata/→data/demo/paths when demo is active. - New capture engines: If a new engine is added, verify demo mode filtering still works (demo engines use
is_demo_mode()gate inis_available()). - New audio engines: Same as capture engines —
is_available()must respectis_demo_mode(). - New device providers: If discovery is added, gate it with
is_demo_mode()likeDemoDeviceProvider.discover(). - New seed data: When adding new entity types that should appear in demo mode, update
server/src/wled_controller/core/demo_seed.pyto include sample entities. - Frontend indicators: Demo mode state is exposed via
GET /api/v1/version→demo_mode: bool. Frontend stores it asdemoModein app state and setsdocument.body.dataset.demo = 'true'. - Backup/Restore: If new stores are added to
STORE_MAPinsystem.py, they automatically work in demo mode since the data directory is already isolated.
Key files:
- Config flag:
server/src/wled_controller/config.py→Config.demo,is_demo_mode() - Demo engines:
core/capture_engines/demo_engine.py,core/audio/demo_engine.py - Demo devices:
core/devices/demo_provider.py - Seed data:
core/demo_seed.py
General Guidelines
- Always test changes before marking as complete
- Follow existing code style and patterns
- Update documentation when changing behavior
- Write clear, descriptive commit messages when explicitly instructed
- Never make commits or pushes without explicit user approval