refactor: comprehensive code quality, security, and release readiness improvements
Some checks failed
Lint & Test / test (push) Failing after 48s
Some checks failed
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.
This commit is contained in:
186
CLAUDE.md
186
CLAUDE.md
@@ -7,196 +7,50 @@
|
||||
**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
|
||||
# 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 search "Query" # Universal search
|
||||
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 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
|
||||
ast-index update # Incremental update after file changes
|
||||
```
|
||||
|
||||
## CRITICAL: Git Commit and Push Policy
|
||||
## Git Commit and Push Policy
|
||||
|
||||
**🚨 NEVER CREATE COMMITS WITHOUT EXPLICIT USER APPROVAL 🚨**
|
||||
**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.
|
||||
|
||||
**🚨 NEVER PUSH TO REMOTE WITHOUT EXPLICIT USER APPROVAL 🚨**
|
||||
## Auto-Restart and Rebuild Policy
|
||||
|
||||
### Strict Rules
|
||||
|
||||
1. **DO NOT** create commits automatically after making changes
|
||||
2. **DO NOT** commit without being explicitly instructed by the user
|
||||
3. **DO NOT** push to remote repository without explicit instruction
|
||||
4. **ALWAYS WAIT** for the user to review changes and ask you to commit
|
||||
5. **ALWAYS ASK** if you're unsure whether to commit
|
||||
|
||||
### Workflow
|
||||
|
||||
1. Make code changes as requested
|
||||
2. **STOP** - Inform user that changes are complete
|
||||
3. **WAIT** - User reviews the changes
|
||||
4. **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
|
||||
5. **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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
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):
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
# 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.).
|
||||
- **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
|
||||
|
||||
This is a monorepo containing:
|
||||
- `/server` - Python FastAPI backend (see `server/CLAUDE.md` for detailed instructions)
|
||||
- `/client` - Future frontend client (if applicable)
|
||||
- `/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)
|
||||
|
||||
## Working with Server
|
||||
## Context Files
|
||||
|
||||
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`](contexts/frontend.md).
|
||||
| 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 |
|
||||
| [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`.
|
||||
|
||||
- **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:**
|
||||
|
||||
1. **New entity stores**: Add the store's file path to `StorageConfig` in `config.py` — the `model_post_init()` auto-rewrites `data/` → `data/demo/` paths when demo is active.
|
||||
2. **New capture engines**: If a new engine is added, verify demo mode filtering still works (demo engines use `is_demo_mode()` gate in `is_available()`).
|
||||
3. **New audio engines**: Same as capture engines — `is_available()` must respect `is_demo_mode()`.
|
||||
4. **New device providers**: If discovery is added, gate it with `is_demo_mode()` like `DemoDeviceProvider.discover()`.
|
||||
5. **New seed data**: When adding new entity types that should appear in demo mode, update `server/src/wled_controller/core/demo_seed.py` to include sample entities.
|
||||
6. **Frontend indicators**: Demo mode state is exposed via `GET /api/v1/version` → `demo_mode: bool`. Frontend stores it as `demoMode` in app state and sets `document.body.dataset.demo = 'true'`.
|
||||
7. **Backup/Restore**: If new stores are added to `STORE_MAP` in `system.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`
|
||||
**Use context7 MCP tools for library/framework documentation lookups** (FastAPI, OpenCV, Pydantic, yt-dlp, etc.) instead of relying on potentially outdated training data.
|
||||
|
||||
## 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
|
||||
|
||||
Reference in New Issue
Block a user