diff --git a/.planning/phases/04-timeline-editor/04-CONTEXT.md b/.planning/phases/04-timeline-editor/04-CONTEXT.md new file mode 100644 index 0000000..179600c --- /dev/null +++ b/.planning/phases/04-timeline-editor/04-CONTEXT.md @@ -0,0 +1,108 @@ +# Phase 4: Timeline Editor - Context + +**Gathered:** 2026-04-06 +**Status:** Ready for planning + + +## Phase Boundary + +The main area becomes a live DAW timeline — per-device horizontal tracks on a time axis, animation blocks that can be placed, moved, resized, and deleted, a real-time playback cursor, undo/redo stack (min 20 steps), beat detection overlay from librosa, snap-to-beat, beat calibration offset, and a block editor for per-block color/param editing. No live UDP firing (Phase 5), no AI sync (Phase 6). + + + + +## Implementation Decisions + +### Block editor placement +- **D-01:** Fixed inspector panel between the timeline and the transport bar — always visible when a block is selected, hidden/collapsed when nothing is selected +- **D-02:** Inspector shows block label (animation type), color picker, and animation params (speed, direction, length, etc.) in a single horizontal row — compact strip style matching the terminal aesthetic +- **D-03:** Layout from top to bottom: TIMELINE → BLOCK INSPECTOR (conditional) → TRANSPORT BAR + +### Claude's Discretion +- **Block data model**: Add `duration: float = 4.0` to existing `CueModel` — backward-compatible, `timestamp` stays as start time. Schema_version stays at 1 (duration defaults gracefully for old files). Renaming `timestamp` to `start_time` would be cleaner but requires migration — defer to v2. +- **Timeline canvas technology**: Choose based on what's best for the interaction model. HTML5 Canvas is recommended (custom hit-testing, DAW-like perf, consistent with waveform rendering approach). DOM divs are acceptable if the planner has strong reasons. Mixed (canvas background + DOM blocks) is also valid. +- **State ownership for undo/redo**: Frontend-owned state recommended — all timeline mutations live in a JS command history stack, backend updated on explicit save or after each mutation via async API call. This matches how the audio clock already lives in the browser. The command pattern must support at least 20 undo steps. +- **Beat detection UI placement**: Beat marks overlaid directly on the timeline (same horizontal axis as blocks). Calibration offset control can live in a settings/toolbar area or inline near the beat mark display — planner decides. +- **Waveform canvas**: Phase 2 backend (`/api/audio/waveform`, `lightsync/audio/waveform.py`) and frontend beat analysis are implemented, but there's currently no `` element in `index.html`. Phase 4 must add the waveform canvas to the timeline panel and wire it up. + + + + +## Specific Ideas + +- Terminal aesthetic carries forward from Phase 1: flat, sharp edges, cyan/teal on near-black, monospace. No rounded corners, no drop shadows, no gradients. The inspector panel should look like a terminal status bar, not a floating dialog. +- The full app layout from Phase 1 (DEVICES sidebar | main area | transport bar) is the permanent shell. Phase 4 fills `main-area` with the actual timeline. The inspector sits between the timeline canvas and the existing `.transport-bar` footer. + + + + +## Canonical References + +**Downstream agents MUST read these before planning or implementing.** + +### Requirements +- `.planning/REQUIREMENTS.md` — TL-01 through TL-08, SYNC-01, SYNC-02 (this phase's acceptance criteria) +- `.planning/ROADMAP.md` §Phase 4 — Success criteria (6 items), plan breakdown (04-01 through 04-04) + +### Data models and protocol +- `lightsync/models/show.py` — CueModel, TrackModel, ShowModel (add `duration` field here; all blocks live in tracks.cues) +- `lightsync/models/device.py` — DeviceConfig (track labels come from device name/strip_type) + +### Audio and beat analysis (Phase 2 output — Phase 4 consumes) +- `lightsync/audio/beats.py` — Beat detection logic (librosa beat_track + plp + onset_detect) +- `lightsync/api/audio.py` — GET /api/audio/beats endpoint, GET /api/audio/waveform endpoint +- `lightsync/audio/waveform.py` — extract_peaks() function for waveform canvas data + +### Animation library (Phase 3 output — Phase 4 library panel) +- `lightsync/animations/` — All 7 animation types (chase, pulse, rainbow, strobe, color_wipe, fire, solid) + +### Existing frontend +- `lightsync/frontend/index.html` — Current layout (sidebar, main-area, transport-bar); Phase 4 replaces the animation tile grid in main-area with the actual timeline canvas +- `lightsync/frontend/app.js` — Existing WebSocket client, audio tick loop, device CRUD — new timeline code integrates here +- `lightsync/frontend/style.css` — CSS variables (--accent cyan, dark theme conventions from Phase 1 D-11 through D-15) + +### Prior context +- `.planning/phases/01-foundation/01-CONTEXT.md` — Visual aesthetic decisions (D-11 through D-15): flat, sharp, cyan/teal, monospace, uppercase headers + + + + +## Existing Code Insights + +### Reusable Assets +- `lightsync/audio/waveform.py` — extract_peaks() returns amplitude samples for canvas rendering +- `lightsync/api/audio.py` — GET /api/audio/beats?path= returns {beat_times, onset_times, tempo_bpm}; cached after first analysis +- `lightsync/animations/` — Animation registry with all 7 types; factory function create_animation(name, params) +- `lightsync/frontend/app.js` — LightSyncClient WebSocket class, 10Hz tick loop (audio.currentTime → server), apiPost/apiDelete helpers +- `lightsync/api/` — Router structure (devices.py, shows.py, audio.py, ws.py) — add timeline/block REST endpoints here + +### Established Patterns +- Frontend is ES module (`type="module"`) — import/export pattern required for new JS files +- Transport state is browser-driven: HTML5 ` + + +## Deferred Ideas + +- Live UDP firing while timeline plays — Phase 5 +- AI-assisted block placement — Phase 6 +- Structural segmentation overlay (verse/chorus/bridge regions) — Phase 6 / v2 +- Keyboard shortcuts for all primary operations — Phase 5 (UI-03) +- Show save/load persistence across sessions — Phase 5 + + + +--- + +*Phase: 04-timeline-editor* +*Context gathered: 2026-04-06*