Commit Graph

107 Commits

Author SHA1 Message Date
Claude
165cdb6f23 feat(06-01): add yt-dlp and anthropic dependencies
- Add yt-dlp>=2025.0.0 and anthropic>=0.40.0 to pyproject.toml
- Wire ANTHROPIC_API_KEY env var in docker-compose.prod.yml (empty default)
- Rebuilt Docker image, both packages importable in container
2026-04-07 11:35:33 +00:00
Claude
57bd91d4e7 docs(06-ai-sync): create phase plan 2026-04-07 11:31:04 +00:00
Claude
b88bd98c40 docs(06): research phase AI sync domain 2026-04-07 11:17:32 +00:00
Claude
b0e13bfab8 docs(06): capture phase context 2026-04-07 10:57:18 +00:00
Claude
c715369a65 docs(phase-05): evolve PROJECT.md after phase completion 2026-04-07 10:42:22 +00:00
Claude
c706d4c8dd docs(phase-05): complete phase execution 2026-04-07 10:41:54 +00:00
Claude
a6b8a2d591 docs(05-04): complete mouse play/pause WS fix plan — SUMMARY, STATE, ROADMAP updated
- 05-04-SUMMARY.md: gap closure complete, UDP cues fire for mouse playback
- STATE.md: plan advanced to 2/4, progress 100%, decision logged
- ROADMAP.md: Phase 05 marked Complete (4/4 plans)
2026-04-07 10:38:24 +00:00
Claude
ac0f3d52db feat(05-04): add WebSocket play/pause messages to wireAudio() event listeners
- audio 'play' listener now sends client.send({ type: 'play', position }) to server
- audio 'pause' listener now sends client.send({ type: 'pause', position }) to server
- Server is_playing flag now set correctly on mouse-initiated playback
- UDP cue scheduler fires for both mouse and keyboard playback
2026-04-07 10:37:18 +00:00
Claude
11cd0fce7b docs(05): add phase 5 verification report (9/11 truths, gaps identified)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 10:31:43 +00:00
Claude
4543f9b38d docs(05): add gap closure plan 05-04 for mouse play/pause WS fix 2026-04-07 10:31:12 +00:00
Claude
448bd34eb2 docs(05-03): complete keyboard shortcuts plan — SUMMARY, STATE, ROADMAP updated 2026-04-07 10:19:12 +00:00
Claude
3562652f2b feat(05-03): add wireKeyboard() with all 7 keyboard shortcuts
- Space toggles play/pause, sends play/pause msg to server
- ArrowLeft/ArrowRight seek +/-5s, send seek msg, clear preview strips
- Ctrl+Z calls timeline.history.undo()
- Ctrl+Shift+Z and Ctrl+Y both call timeline.history.redo()
- Ctrl+S prevents browser dialog, fetches show and POSTs to save
- All shortcuts suppressed when focus is on input/select/textarea
- Space skips when active element is a button (prevents double-toggle)
- wireKeyboard() called at init after wireAudio()
2026-04-07 10:18:19 +00:00
Claude
1499736fde docs(05-02): complete live preview panel plan — SUMMARY, STATE, ROADMAP updated 2026-04-07 10:16:48 +00:00
Claude
e064954b28 feat(05-02): wire preview_update handler, show selector, and preview strip builder
- Import setCurrentShowId from commands.js
- Add preview_update WebSocket message handler that calls updatePreviewStrip
- Add updatePreviewStrip() function to update device strip color and animation
- Add buildPreviewStrips() function to populate #live-preview from device list
- Call buildPreviewStrips() inside device fetch callback in initTimeline
- Add async refreshShows() to populate show-select dropdown from /api/shows
- Add btn-load-show click handler: loads show, populates tracks, sends WebSocket load msg
- Clear preview strips on seek (remove active class, reset color and anim label)
2026-04-07 10:15:34 +00:00
Claude
e0e412fcd1 feat(05-02): add live preview panel HTML and CSS styles
- Add #live-preview div between timeline-canvas and block-inspector
- Add show selector (show-select + btn-load-show) to transport bar
- Add keyboard-hint span at far right of transport bar
- Append .live-preview, .device-strip, .strip-label, .strip-color, .strip-anim, .keyboard-hint CSS styles
2026-04-07 10:14:16 +00:00
Claude
7809402d54 docs(05-01): complete cue scheduler plan — SUMMARY, STATE, ROADMAP updated
- 05-01-SUMMARY.md created with task commits, decisions, next-phase readiness
- STATE.md advanced to plan 2/3, progress 88%, decisions logged
- ROADMAP.md updated: phase 5 in progress (1/3 summaries)
- REQUIREMENTS.md: SHW-03 marked complete
2026-04-07 10:12:09 +00:00
Claude
64c49c9e64 feat(05-01): add cue scheduling loop and preview_update broadcast to tick handler
- LOOKAHEAD = 0.060 (60ms window per D-02)
- Scheduler iterates show.tracks/cues on each tick, gated on is_playing and show
- Cues within lookahead window fire UDP via encode_animation_cmd + UDPSender.send
- Past cues (>100ms behind) silently marked fired without UDP dispatch
- active_cue tracking per track enables preview state for already-fired blocks
- preview_update messages broadcast to all clients on each tick (D-07)
- Clear preview_update (animation: null) sent when no active cue on a device
2026-04-07 10:11:03 +00:00
Claude
3d36cc5754 feat(05-01): add per-connection show state and load handler to ws.py
- Import encode_animation_cmd and ShowModel at module level
- Add show, fired_ids, is_playing per-connection state variables
- Extend load handler to load show from show_store by show_id (D-04)
- play handler sets is_playing=True
- pause handler sets is_playing=False without touching fired_ids
- seek handler rebuilds fired_ids from show cues before seek position (D-03)
2026-04-07 10:10:23 +00:00
Claude
3c9575f915 docs(05): phase 5 execution plans — cue scheduler, live preview, keyboard shortcuts 2026-04-07 09:16:45 +00:00
Claude
6a1ec4e3b6 docs(05): create phase plan — 3 plans across 3 waves 2026-04-07 09:16:17 +00:00
Claude
02826b2c89 docs(05): fix UI-SPEC checker blocks — typography, spacing 2026-04-07 09:05:57 +00:00
Claude
f739c8fe19 docs(05): UI design contract
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-07 09:02:33 +00:00
Claude
2ac23c3297 docs(05): research phase domain 2026-04-07 08:59:07 +00:00
Claude
7b37f014d0 docs(state): record phase 5 context session 2026-04-07 08:48:39 +00:00
Claude
4ce9759055 docs(05): capture phase context 2026-04-07 08:48:34 +00:00
Claude
34077018a9 docs(phase-04): evolve PROJECT.md after phase completion 2026-04-07 00:00:51 +00:00
Claude
399b7a1e05 docs(phase-04): complete phase execution 2026-04-07 00:00:33 +00:00
Claude
3483de871e docs(04-04): complete block inspector plan — SUMMARY, STATE, ROADMAP updated
- BlockInspector with color/speed/direction/length param controls
- UpdateParamsCommand for full undo/redo param editing
- Phase 04 complete (4/4 plans), TL-04 requirement marked done
- Progress: 14/14 plans (100%)
2026-04-06 23:56:25 +00:00
Claude
8e084ca8dc feat(04-04): wire BlockInspector into timeline and app.js
- app.js imports BlockInspector and DeleteBlockCommand
- Inspector created with #block-inspector element and timeline.history
- timeline._onSelectBlock callback shows/hides inspector on block select
- inspector._onDelete fires DeleteBlockCommand and hides inspector
- inspector.tracks kept in sync after loadTracks() resolves
- timeline.js block rendering uses blockColor + '1a' for color accent fill
- undo/redo handlers re-trigger _onSelectBlock to refresh inspector values
2026-04-06 23:54:22 +00:00
Claude
e82fc4a775 feat(04-04): add UpdateParamsCommand + BlockInspector module
- UpdateParamsCommand with execute/undo for color/speed/direction/length
- Uses module-level currentShowId (not this._showId) matching existing pattern
- BlockInspector renders compact strip with animation label, color swatch,
  speed input, direction select, length input, and remove button
- Color change committed on 'change' event (not 'input') to avoid command flood
- _onDelete callback wired to remove button for app.js to handle
2026-04-06 23:51:48 +00:00
Claude
d1965dcefc docs(04-03): complete BeatGrid plan summary and update state 2026-04-06 23:49:44 +00:00
Claude
287fe16a56 feat(04-03): BeatGrid module + enhanced beat rendering + loading states
- Create beats.js with BeatGrid class: load(), getCalibratedBeats(), getCalibratedOnsets(), snap(), hasBeats getter
- BeatGrid manages calibrationOffset and snapEnabled state
- snap() uses 100ms threshold against calibrated beat positions
- Handles API field variants: beats/beat_times, tempo/tempo_bpm
- Refactor timeline.js: replace beatTimes/calibrationOffset/snapEnabled with this.beatGrid
- Add getters/setters for calibrationOffset and snapEnabled (backward compat with app.js)
- render() now shows DETECTING BEATS... loading indicator and error state
- render() draws beat marks via getCalibratedBeats(), onset ticks via getCalibratedOnsets()
- snapToBeat() delegates to beatGrid.snap()
- app.js chains BPM label update after loadBeats() resolves
2026-04-06 23:48:27 +00:00
Claude
c37fa6d1f6 docs(04-02): complete block interactions plan — SUMMARY, STATE, ROADMAP updated
- CommandHistory + 4 command classes + backend CRUD endpoints
- Full mouse interactions: drag-place, move, resize, delete, undo/redo
- Requirements TL-02, TL-03, TL-06 marked complete
- Progress: 86% (12/14 plans)
2026-04-06 23:46:05 +00:00
Claude
7e18ac6c84 feat(04-02): wire block interactions into TimelineCanvas
- Import CommandHistory and all 4 command classes from new modules
- hitTest() with 8px EDGE for resize-left/resize-right/move zones
- _hasOverlap() check for time range collision on same track
- snapToBeat() with 0.1s threshold and calibrationOffset
- _setupInteractions() with mousedown/mousemove/keydown listeners
- _startMove(): live drag preview, snap on mouseup, overlap rejection
- _startResize(): left/right edge handles, 0.5s min duration, snap
- handleDrop(): place block from palette with crypto.randomUUID()
- Keyboard: Delete, Ctrl+Z (undo), Ctrl+Shift+Z / Ctrl+Y (redo)
- app.js: dragstart on palette, dragover/dragleave/drop on canvas
- Ghost block rendered during dragover for visual feedback
- Resize handle indicators drawn on selected block
2026-04-06 23:44:45 +00:00
Claude
658c92f94d feat(04-02): command pattern + CommandHistory + block CRUD backend
- CommandHistory class with execute/undo/redo, 50-step max, redo-clear on new action
- PlaceBlockCommand, MoveBlockCommand, ResizeBlockCommand, DeleteBlockCommand
- setCurrentShowId() module-level function for backend sync routing
- syncBlock() fire-and-forget fetch helper for backend sync
- POST/PATCH/DELETE /api/shows/{show_id}/tracks/{device_id}/blocks endpoints
- timeline router registered in main.py with prefix=/api
2026-04-06 23:37:29 +00:00
Claude
96d7825c34 docs(04-01): complete timeline canvas foundation plan — SUMMARY, STATE, ROADMAP updated
- SUMMARY: timeline canvas with per-device tracks, waveform, beat marks, playback cursor
- STATE: plan advanced to 2/4, progress 79%, decisions and metrics recorded
- ROADMAP: Phase 4 progress updated (1/4 plans complete, In Progress)
- Requirements TL-01, TL-05 marked complete
2026-04-06 23:35:29 +00:00
Claude
efa612380c feat(04-01): TimelineCanvas class + CSS + app.js wiring
- Create lightsync/frontend/timeline/timeline.js with TimelineCanvas class
  - Per-device horizontal tracks with track headers and time axis
  - HiDPI canvas rendering with devicePixelRatio handling
  - Waveform peaks background layer, beat marks overlay, cue block rendering
  - Playback cursor synced to audio.currentTime via requestAnimationFrame
  - Auto-scroll when cursor approaches right edge
  - Mouse wheel scrolling on timeline canvas
  - loadTracks(), loadWaveform(), loadBeats() data loading methods
  - Empty state messages when no devices or audio loaded
- Add timeline CSS to style.css (toolbar, canvas, inspector strip, snap button)
- Wire timeline into app.js: import, initTimeline(), zoom/beat-offset/snap controls
- Remove old animation-grid click listener (element no longer exists in main-area)
- Populate animation palette dynamically in sidebar with 7 animation types
2026-04-06 23:34:32 +00:00
Claude
454fddc35e feat(04-01): data model changes + HTML layout restructure
- Add CueModel.duration field (float = 4.0) for block length in seconds
- Add AnalysisBlock.calibration_offset field (float = 0.03) for librosa bias
- Replace main-area animation grid with timeline canvas layout (toolbar, canvas, inspector)
- Move ANIMATIONS panel into sidebar below DEVICES panel
- Add timeline-toolbar with zoom slider, beat offset input, snap toggle
2026-04-06 23:30:55 +00:00
Claude
22f31cdad0 docs(phase-04): mark planning complete 2026-04-06 23:25:04 +00:00
Claude
78c5d6256d docs(phase-04): add phase plans (4 plans, 3 waves) 2026-04-06 23:24:46 +00:00
Claude
e8e0532972 docs(04): create phase plan 2026-04-06 23:24:11 +00:00
Claude
5f46f6f8a1 docs(04): UI design contract 2026-04-06 23:11:02 +00:00
Claude
f2abc04dcc docs(04): UI design contract for timeline editor phase
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 23:09:42 +00:00
Claude
9d9cd935b6 docs(phase-04): capture context for timeline editor phase
Inspector panel below timeline (above transport) confirmed.
Block data model, canvas tech, and undo/redo architecture left to Claude's discretion with recommendations noted.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 22:14:06 +00:00
Claude
5a84e55059 docs(phase-03): evolve PROJECT.md after phase completion 2026-04-06 21:56:19 +00:00
Claude
73d50d04a8 docs(phase-03): complete phase execution 2026-04-06 21:55:48 +00:00
Claude
299612589b docs(03-03): complete UDP simulator and FastAPI integration plan
- Create 03-03-SUMMARY.md: simulator, e2e tests, lifespan integration
- Update STATE.md: advance plan, 100% progress, record decisions
- Update ROADMAP.md: phase 03 marked Complete (3/3 plans)
- Mark UDP-04 requirement complete in REQUIREMENTS.md
2026-04-06 21:52:37 +00:00
Claude
509911f5c5 feat(03-03): integrate UDPSender into FastAPI lifespan
- Import UDPSender in main.py
- Start UDPSender on app boot, assign to app.state.udp_sender
- Stop UDPSender cleanly on shutdown (before registry.save)
- All existing lifespan behavior unchanged (beats, registry, show_store)
2026-04-06 21:51:40 +00:00
Claude
f3f0baff51 feat(03-03): implement UDP simulator with packet logging — GREEN
- SimulatorProtocol parses DRGB, DRGBW, DNRGB, ANIM_CMD packets
- PacketLog dataclass stores led_count, start_index, decoded cmd
- run_simulator() async factory for test and standalone use
- Runnable as __main__ standalone server on WLED_PORT
- All 7 e2e tests pass
2026-04-06 21:51:16 +00:00
Claude
3829f81a5f test(03-03): add failing e2e protocol tests — RED
- 7 e2e tests covering DRGB, DRGBW, DNRGB, ANIM_CMD, full pipeline, SK6812, standalone import
- Uses asyncio.run() pattern (no pytest-asyncio dependency)
- All tests fail with ModuleNotFoundError: simulator not yet implemented
2026-04-06 21:50:40 +00:00