Files
wled-screen-controller-mixed/server/CLAUDE.md
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

8.0 KiB
Raw Blame History

Claude Instructions for WLED Screen Controller Server

Development Workflow

Server Restart Policy

IMPORTANT: When making changes to server code (Python files in src/wled_controller/), you MUST restart the server if it's currently running to ensure the changes take effect.

NOTE: Auto-reload is currently disabled (reload=False in main.py) due to watchfiles causing an infinite reload loop. Changes to server code will NOT be automatically picked up - manual server restart is required.

When to restart:

  • After modifying API routes (api/routes.py, api/schemas.py)
  • After updating core logic (core/*.py)
  • After changing configuration (config.py)
  • After modifying utilities (utils/*.py)
  • After updating data models or database schemas

How to check if server is running:

# Look for running Python processes with wled_controller
ps aux | grep wled_controller
# Or check for processes listening on port 8080
netstat -an | grep 8080

How to restart:

  1. Find the task ID of the running server (look for background bash tasks in conversation)
  2. Stop the server using TaskStop with the task ID
  3. Check for port conflicts (port 8080 may still be in use):
    netstat -ano | findstr :8080
    
    If a process is still using port 8080, kill it:
    powershell -Command "Stop-Process -Id <PID> -Force"
    
  4. Start a new server instance in the background:
    cd server && python -m wled_controller.main
    
    Use run_in_background: true parameter in Bash tool
  5. Wait 3 seconds for server to initialize:
    sleep 3
    
  6. Verify startup by reading the output file:
    • Look for "Uvicorn running on http://0.0.0.0:8080"
    • Check for any errors in stderr
    • Verify "Application startup complete" message

Common Issues:

  • Port 8080 in use: Old process didn't terminate cleanly - kill it manually
  • Module import errors: Check that all Python files are syntactically correct
  • Permission errors: Ensure file permissions allow Python to execute

Files that DON'T require restart:

  • Static files (static/*.html, static/*.css, static/*.js) - but you MUST rebuild the bundle after changes: cd server && npm run build
  • Locale files (static/locales/*.json) - loaded by frontend
  • Documentation files (*.md)
  • Configuration files in config/ if server supports hot-reload (check implementation)

Git Commit and Push Policy

CRITICAL: NEVER commit OR push code changes without explicit user approval.

Rules

  • You MUST NOT create commits without explicit user instruction
  • You MUST NOT push commits unless explicitly instructed by the user
  • Wait for the user to review changes and ask you to commit
  • If the user says "commit", create a commit but DO NOT push
  • If the user says "commit and push", you may push after committing
  • Always wait for explicit permission before any commit or push operation

Workflow

  1. Make changes to code
  2. STOP and WAIT - inform the user of changes and wait for instruction
  3. Only create commit when user explicitly requests it (e.g., "commit", "create a commit")
  4. STOP and WAIT - do not push
  5. Only push when user explicitly requests it (e.g., "push", "commit and push", "push to remote")

Testing Changes

After restarting the server with new code:

  1. Test the modified endpoints/functionality
  2. Check browser console for any JavaScript errors
  3. Verify API responses match updated schemas
  4. Test with different locales if i18n was modified

Project Structure Notes

  • src/wled_controller/main.py - FastAPI application entry point
  • src/wled_controller/api/ - REST API endpoints and schemas
  • src/wled_controller/core/ - Core business logic (screen capture, WLED client, processing)
  • src/wled_controller/utils/ - Utility functions (logging, monitor detection)
  • src/wled_controller/static/ - Frontend files (HTML, CSS, JS, locales)
  • config/ - Configuration files (YAML)
  • data/ - Runtime data (devices.json, persistence)

Common Tasks

Adding a new API endpoint:

  1. Add route to api/routes.py
  2. Define request/response schemas in api/schemas.py
  3. Restart the server
  4. Test the endpoint via /docs (Swagger UI)

Adding a new field to existing API:

  1. Update Pydantic schema in api/schemas.py
  2. Update corresponding dataclass (if applicable)
  3. Update backend logic to populate the field
  4. Restart the server
  5. Update frontend to display the new field

Modifying display/monitor detection:

  1. Update functions in utils/monitor_names.py or core/screen_capture.py
  2. Restart the server
  3. Test with GET /api/v1/config/displays

Modifying server login:

  1. Update the logic.
  2. Restart the server

Adding translations:

  1. Add keys to static/locales/en.json and static/locales/ru.json
  2. Add data-i18n attributes to HTML elements in static/index.html
  3. Use t('key') function in static/app.js for dynamic content
  4. No server restart needed (frontend only)

Frontend UI Patterns

Entity Cards

All entity cards (devices, targets, CSS sources, streams, scenes, automations, etc.) must support clone functionality. Clone buttons use the ICON_CLONE (📋) icon in .card-actions.

Clone pattern: Clone must open the entity's add/create modal with fields prefilled from the cloned item. It must never silently create a duplicate — the user should review and confirm.

Implementation:

  1. Export a cloneMyEntity(id) function that fetches (or finds in cache) the entity data
  2. Call the add/create modal function, passing the entity data as cloneData
  3. In the modal opener, detect clone mode (no ID + cloneData present) and prefill all fields
  4. Append ' (Copy)' to the name
  5. Set the modal title to the "add" variant (not "edit")
  6. The save action creates a new entity (POST), not an update (PUT)
export async function cloneMyEntity(id) {
    const entity = myCache.data.find(e => e.id === id);
    if (!entity) return;
    showMyEditor(null, entity);  // null id = create mode, entity = cloneData
}

Register the clone function in app.js window exports so inline onclick handlers can call it.

Modal Dialogs

IMPORTANT: All modal dialogs must follow these standards for consistent UX:

Backdrop Click Behavior

All modals MUST close when the user clicks outside the dialog (on the backdrop). Implement this by adding a click handler that checks if the clicked element is the modal backdrop itself:

// Show modal
const modal = document.getElementById('my-modal');
modal.style.display = 'flex';

// Add backdrop click handler to close modal
modal.onclick = function(event) {
    if (event.target === modal) {
        closeMyModal();
    }
};

Where to add: In every function that shows a modal (e.g., showAddTemplateModal(), editTemplate(), showTestTemplateModal()).

Close Button Requirement

Each modal dialog that has a "Cancel" button MUST also have a cross (×) close button at the top-right corner of the dialog. This provides users with multiple intuitive ways to dismiss the dialog:

  1. Click the backdrop (outside the dialog)
  2. Click the × button (top-right corner)
  3. Click the Cancel button (bottom of dialog)
  4. Press Escape key (if implemented)

HTML Structure:

<div class="modal-content">
    <button class="close-btn" onclick="closeMyModal()">&times;</button>
    <h2>Dialog Title</h2>
    <!-- dialog content -->
    <div class="modal-actions">
        <button onclick="closeMyModal()">Cancel</button>
        <button onclick="submitAction()">Submit</button>
    </div>
</div>

CSS Requirements:

  • Close button should be positioned absolutely at top-right
  • Should be easily clickable (min 24px × 24px hit area)
  • Should have clear hover state

Authentication

Server uses API key authentication. Keys are configured in:

  • config/default_config.yaml under auth.api_keys
  • Or via environment variables: WLED_AUTH__API_KEYS

For development, ensure at least one API key is configured or the server won't start.