From 3483de871eb215745ebb0b343d5bc7fa16934c27 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 6 Apr 2026 23:56:25 +0000 Subject: [PATCH] =?UTF-8?q?docs(04-04):=20complete=20block=20inspector=20p?= =?UTF-8?q?lan=20=E2=80=94=20SUMMARY,=20STATE,=20ROADMAP=20updated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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%) --- .planning/REQUIREMENTS.md | 2 +- .planning/ROADMAP.md | 6 +- .planning/STATE.md | 19 +-- .../04-timeline-editor/04-04-SUMMARY.md | 133 ++++++++++++++++++ 4 files changed, 148 insertions(+), 12 deletions(-) create mode 100644 .planning/phases/04-timeline-editor/04-04-SUMMARY.md diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index b57da29..7b3e4d4 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -33,7 +33,7 @@ - [x] **TL-01**: Per-device horizontal tracks on a time axis - [x] **TL-02**: Drag-and-place animation blocks onto a track - [x] **TL-03**: Move, resize, and delete animation blocks -- [ ] **TL-04**: Color picker per animation block +- [x] **TL-04**: Color picker per animation block - [x] **TL-05**: Playback cursor (vertical line) tracking audio position in realtime - [x] **TL-06**: Undo/redo for all timeline mutations (min 20 steps, command pattern) - [x] **TL-07**: Beat detection marks overlaid on timeline (librosa beat_track) diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 0ad5c7f..f2f4607 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -15,7 +15,7 @@ Decimal phases appear between their surrounding integers in numeric order. - [x] **Phase 1: Foundation** - FastAPI skeleton, show file schema (Pydantic), device registry, terminal-aesthetic frontend shell (gap closure in progress) (completed 2026-04-05) - [x] **Phase 2: Audio Engine** - MPV IPC bridge, waveform rendering, playback controls, Windows timer fix (completed 2026-04-06) - [x] **Phase 3: Communication Protocol** - UDP packet spec, DRGB/DNRGB/DRGBW encoders, animation library, software simulator (completed 2026-04-06) -- [ ] **Phase 4: Timeline Editor** - DAW UI (tracks, drag-place blocks, resize, delete), undo/redo, beat detection, snap-to-beat +- [x] **Phase 4: Timeline Editor** - DAW UI (tracks, drag-place blocks, resize, delete), undo/redo, beat detection, snap-to-beat (completed 2026-04-06) - [ ] **Phase 5: Live Show Execution** - End-to-end show playback, seek-safe cue scheduling, show save/load, keyboard shortcuts, live preview - [ ] **Phase 6: AI Sync** - YouTube loading, AI-assisted show generation, beat calibration UI, structural segmentation - [ ] **Phase 7: Microcontroller Firmware** - MicroPython firmware for ESP32/Pico/RPi, animation command + frame receivers for SK6812 and WS2801 @@ -93,7 +93,7 @@ Plans: - [x] 04-01: Timeline canvas — per-device tracks, time axis, block rendering, playback cursor - [x] 04-02: Block interactions — drag-and-place, move, resize, delete; command pattern undo/redo (min 20 steps) - [x] 04-03: Beat detection + snap — librosa beat_track + plp + onset_detect in ProcessPoolExecutor, beat mark overlay, snap-to-beat, calibration offset UI -- [ ] 04-04: Block editor — animation library panel, color picker, parameter controls per block, changes reflected in show file +- [x] 04-04: Block editor — animation library panel, color picker, parameter controls per block, changes reflected in show file **UI hint**: yes ### Phase 5: Live Show Execution @@ -155,7 +155,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7 | 1. Foundation | 4/4 | Complete | 2026-04-05 | | 2. Audio Engine | 3/3 | Complete | 2026-04-06 | | 3. Communication Protocol | 3/3 | Complete | 2026-04-06 | -| 4. Timeline Editor | 3/4 | In Progress| | +| 4. Timeline Editor | 4/4 | Complete | 2026-04-06 | | 5. Live Show Execution | 0/3 | Not started | - | | 6. AI Sync | 0/3 | Not started | - | | 7. Microcontroller Firmware | 0/3 | Not started | - | diff --git a/.planning/STATE.md b/.planning/STATE.md index 40450cb..25f37a6 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -2,15 +2,15 @@ gsd_state_version: 1.0 milestone: v1.0 milestone_name: milestone -status: executing -stopped_at: Completed 04-timeline-editor/04-03-PLAN.md -last_updated: "2026-04-06T23:49:36.485Z" +status: verifying +stopped_at: Completed 04-timeline-editor/04-04-PLAN.md +last_updated: "2026-04-06T23:56:15.933Z" last_activity: 2026-04-06 progress: total_phases: 7 - completed_phases: 3 + completed_phases: 4 total_plans: 14 - completed_plans: 13 + completed_plans: 14 percent: 0 --- @@ -27,7 +27,7 @@ See: .planning/PROJECT.md (updated 2026-04-05) Phase: 04 (timeline-editor) — EXECUTING Plan: 4 of 4 -Status: Ready to execute +Status: Phase complete — ready for verification Last activity: 2026-04-06 Progress: [░░░░░░░░░░] 0% @@ -65,6 +65,7 @@ Progress: [░░░░░░░░░░] 0% | Phase 04-timeline-editor P01 | 4min | 2 tasks | 5 files | | Phase 04-timeline-editor P02 | 9 | 2 tasks | 6 files | | Phase 04-timeline-editor P03 | 2 | 1 tasks | 3 files | +| Phase 04-timeline-editor P04 | 4min | 2 tasks | 4 files | ## Accumulated Context @@ -107,6 +108,8 @@ Recent decisions affecting current work: - [Phase 04-timeline-editor]: setCurrentShowId() module-level function routes backend sync without coupling commands to app state - [Phase 04-timeline-editor]: BeatGrid stores raw beat_times unmodified — calibrationOffset subtracted only at getCalibratedBeats()/snap() time — offset slider works without corrupting base data - [Phase 04-timeline-editor]: BeatGrid.load() normalizes API field variants: beats/beat_times and tempo/tempo_bpm — actual API returns 'beats'/'tempo' not the plan's expected field names +- [Phase 04-timeline-editor]: UpdateParamsCommand uses currentShowId (module-level var) not this._showId — matches existing command pattern in commands.js +- [Phase 04-timeline-editor]: Color input fires 'change' not 'input' to create command — avoids flooding command history during native color picker drag ### Pending Todos @@ -120,8 +123,8 @@ None yet. ## Session Continuity -Last session: 2026-04-06T23:49:36.477Z -Stopped at: Completed 04-timeline-editor/04-03-PLAN.md +Last session: 2026-04-06T23:56:15.926Z +Stopped at: Completed 04-timeline-editor/04-04-PLAN.md Resume file: None Next action: `/gsd:plan-phase 1` diff --git a/.planning/phases/04-timeline-editor/04-04-SUMMARY.md b/.planning/phases/04-timeline-editor/04-04-SUMMARY.md new file mode 100644 index 0000000..5da1a92 --- /dev/null +++ b/.planning/phases/04-timeline-editor/04-04-SUMMARY.md @@ -0,0 +1,133 @@ +--- +phase: 04-timeline-editor +plan: 04 +subsystem: ui +tags: [canvas, timeline, inspector, color-picker, command-pattern, undo-redo] +dependency_graph: + requires: + - phase: 04-timeline-editor/04-02 + provides: CommandHistory, DeleteBlockCommand, syncBlock, selectedBlock, _onSelectBlock callback + provides: + - UpdateParamsCommand (undoable color/speed/direction/length changes) + - BlockInspector class rendering compact strip with all param controls + - Inspector show/hide wired to block selection via _onSelectBlock + - Block canvas fill uses params.color for visual distinction + - Undo/redo refreshes inspector values via re-triggered _onSelectBlock + affects: [] + +tech-stack: + added: [] + patterns: + - "BlockInspector wired via callback: timeline._onSelectBlock = (block) => inspector.show(block)" + - "Inspector delete wires via _onDelete callback to fire DeleteBlockCommand through timeline.history" + - "UpdateParamsCommand uses module-level currentShowId (same pattern as existing commands)" + - "Color change committed on 'change' event not 'input' — avoids command flood during color drag" + - "Block canvas fill uses blockColor + '1a' hex suffix for ~10% opacity color accent" + +key-files: + created: + - lightsync/frontend/timeline/inspector.js + modified: + - lightsync/frontend/timeline/commands.js + - lightsync/frontend/timeline/timeline.js + - lightsync/frontend/app.js + +key-decisions: + - "UpdateParamsCommand uses currentShowId (module-level var) not this._showId — matches existing command pattern in commands.js" + - "Color input fires 'change' (not 'input') to create command — avoids flooding command history during native color picker drag" + +patterns-established: + - "Inspector callbacks: _onSelectBlock and _onDelete on inspector — app.js wires both after creating inspector" + +requirements-completed: [TL-04] + +duration: 4min +completed: 2026-04-06 +--- + +# Phase 04 Plan 04: Block Inspector Panel Summary + +**Compact inspector strip between timeline and transport bar — shows animation label, color swatch, speed/direction/length controls — all param changes go through UpdateParamsCommand for full undo/redo support.** + +## Performance + +- **Duration:** ~4 min +- **Started:** 2026-04-06T23:51:12Z +- **Completed:** 2026-04-06T23:55:00Z +- **Tasks:** 2 +- **Files modified:** 4 (1 created, 3 modified) + +## Accomplishments + +- `UpdateParamsCommand` added to commands.js with execute/undo storing old/new params shallow copies +- `BlockInspector` class rendering inspector strip: animation label, color swatch → hidden color input, SPEED number, DIR select, LEN number, remove button +- Inspector show/hide wired to block selection via `timeline._onSelectBlock` callback in app.js +- Inspector delete wired via `_onDelete` → `DeleteBlockCommand` through `timeline.history` +- Block fill on canvas uses `params.color + '1a'` for subtle color accent — color changes visible immediately +- Undo/redo handlers re-trigger `_onSelectBlock(selectedBlock)` to refresh inspector values after command reversal +- Docker build: clean (no errors) + +## Task Commits + +1. **Task 1: UpdateParamsCommand + BlockInspector module** - `e82fc4a` (feat) +2. **Task 2: Wire inspector into timeline and app.js** - `8e084ca` (feat) + +## Files Created/Modified + +- `lightsync/frontend/timeline/inspector.js` — BlockInspector class with show/hide/_render/_wireEvents, imports UpdateParamsCommand +- `lightsync/frontend/timeline/commands.js` — UpdateParamsCommand added with currentShowId-based sync +- `lightsync/frontend/app.js` — imports BlockInspector + DeleteBlockCommand, wires inspector to timeline +- `lightsync/frontend/timeline/timeline.js` — block color accent from params.color, undo/redo re-triggers inspector refresh + +## Decisions Made + +| Decision | Rationale | +|----------|-----------| +| UpdateParamsCommand uses `currentShowId` not `this._showId` | The plan's code had `this._showId` which doesn't exist — commands.js uses module-level `currentShowId`, same as all other commands | +| Color change on `change` not `input` | Native color pickers fire `input` continuously during drag; committing on `change` prevents hundreds of undo steps for one color change | + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 1 - Bug] Fixed UpdateParamsCommand._showId → currentShowId** +- **Found during:** Task 1 (UpdateParamsCommand implementation) +- **Issue:** Plan's code used `this._showId` in syncBlock call, but commands.js uses module-level `currentShowId` — `this._showId` is undefined +- **Fix:** Used `currentShowId` (module-level variable) matching the exact pattern of PlaceBlockCommand, MoveBlockCommand etc. +- **Files modified:** `lightsync/frontend/timeline/commands.js` +- **Committed in:** e82fc4a + +--- + +**Total deviations:** 1 auto-fixed (Rule 1 - Bug) +**Impact on plan:** Essential fix — `this._showId` would be undefined at runtime, breaking backend sync for all param changes. + +## Issues Encountered + +None — all other implementation matched the plan exactly. + +## Known Stubs + +None — inspector is fully wired. All param changes route through UpdateParamsCommand. Color accent on canvas reflects actual block color. Remove button fires DeleteBlockCommand. Undo/redo refreshes inspector. + +## Self-Check: PASSED + +- `lightsync/frontend/timeline/inspector.js` exists: YES (e82fc4a) +- `inspector.js` exports `BlockInspector`: YES +- `commands.js` has `UpdateParamsCommand`: YES (e82fc4a) +- `app.js` imports `BlockInspector` and `DeleteBlockCommand`: YES (8e084ca) +- `app.js` wires `_onSelectBlock` and `_onDelete`: YES (8e084ca) +- `timeline.js` uses `blockColor + '1a'` for fill: YES (8e084ca) +- `timeline.js` undo/redo re-triggers `_onSelectBlock`: YES (8e084ca) +- Docker build: SUCCESS (clean) + +## Next Phase Readiness + +- Timeline editor is feature-complete: block place/move/resize/delete/params all undoable +- Inspector provides full visual feedback for selected block parameters +- Phase 04 is complete — all 4 plans done +- No blockers + +--- +*Phase: 04-timeline-editor* +*Completed: 2026-04-06*