From 6bb266e234aae93ce9011e1580a1ac6d7de22f91 Mon Sep 17 00:00:00 2001 From: Caleb Allen Date: Fri, 6 Mar 2026 21:51:21 -0500 Subject: [PATCH] docs(09-02): complete keyboard shortcuts config & service plan - Create 09-02-SUMMARY.md with execution metrics and decisions - Update STATE.md: advance to plan 3, record metrics - Mark KEY-01, KEY-04, KEY-05 requirements complete --- .planning/REQUIREMENTS.md | 12 +- .planning/STATE.md | 19 +-- .../09-02-SUMMARY.md | 140 ++++++++++++++++++ 3 files changed, 156 insertions(+), 15 deletions(-) create mode 100644 .planning/phases/09-scan-cancellation-keyboard-shortcuts/09-02-SUMMARY.md diff --git a/.planning/REQUIREMENTS.md b/.planning/REQUIREMENTS.md index ea81211..61285bf 100644 --- a/.planning/REQUIREMENTS.md +++ b/.planning/REQUIREMENTS.md @@ -15,11 +15,11 @@ Requirements for v1.1 Features & Extensibility milestone. Each maps to roadmap p ### Keyboard Shortcuts -- [ ] **KEY-01**: Default keybindings work out of box (play/pause, next/prev, volume, search focus, queue toggle, shuffle, repeat) +- [x] **KEY-01**: Default keybindings work out of box (play/pause, next/prev, volume, search focus, queue toggle, shuffle, repeat) - [ ] **KEY-02**: User can customize all keyboard shortcuts via a visual settings UI - [ ] **KEY-03**: Shortcut conflicts are detected and warned about when rebinding -- [ ] **KEY-04**: Shortcuts are scoped — different bindings apply based on focused component (track list vs player vs global) -- [ ] **KEY-05**: Shortcuts are disabled when text input has focus (except Escape to blur) +- [x] **KEY-04**: Shortcuts are scoped — different bindings apply based on focused component (track list vs player vs global) +- [x] **KEY-05**: Shortcuts are disabled when text input has focus (except Escape to blur) ### Tag Editing @@ -140,11 +140,11 @@ Which phases cover which requirements. Updated during roadmap creation. | SCAN-01 | Phase 9 | Complete | | SCAN-02 | Phase 9 | Complete | | SCAN-03 | Phase 9 | Complete | -| KEY-01 | Phase 9 | Pending | +| KEY-01 | Phase 9 | Complete | | KEY-02 | Phase 9 | Pending | | KEY-03 | Phase 9 | Pending | -| KEY-04 | Phase 9 | Pending | -| KEY-05 | Phase 9 | Pending | +| KEY-04 | Phase 9 | Complete | +| KEY-05 | Phase 9 | Complete | | TAG-01 | Phase 10 | Pending | | TAG-02 | Phase 10 | Pending | | TAG-03 | Phase 10 | Pending | diff --git a/.planning/STATE.md b/.planning/STATE.md index deb5e15..c557ae2 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -8,7 +8,7 @@ progress: total_phases: 6 completed_phases: 0 total_plans: 5 - completed_plans: 1 + completed_plans: 2 --- # YellowJacket — Project State @@ -23,16 +23,16 @@ See: .planning/PROJECT.md (updated 2026-03-06) ## Current Position Phase: 9 — Scan Cancellation & Keyboard Shortcuts -Plan: 2 of 5 +Plan: 3 of 5 Status: In progress -Progress: █░░░░░░░░░░░░░░░░░░░ 1/5 plans (20%) -Last activity: 2026-03-07 — Completed 09-01 (scan control backend) +Progress: ████░░░░░░░░░░░░░░░░ 2/5 plans (40%) +Last activity: 2026-03-07 — Completed 09-02 (keyboard shortcuts config & service) ### Phase Overview | Phase | Status | |-------|--------| -| 9. Scan Cancellation & Keyboard Shortcuts | In Progress (1/5 plans) | +| 9. Scan Cancellation & Keyboard Shortcuts | In Progress (2/5 plans) | | 10. Tag Editing | Not started | | 11. Smart Playlists | Not started | | 12. Gapless Playback & Crossfade | Not started | @@ -47,6 +47,7 @@ Last activity: 2026-03-07 — Completed 09-01 (scan control backend) | Phase | Plan | Duration | Tasks | Files | |-------|------|----------|-------|-------| | 09-01 | scan control backend | 16 min | 2 | 5 | +| 09-02 | keyboard shortcuts config & service | 35 min | 2 | 12 | ## Accumulated Context @@ -94,11 +95,11 @@ Decisions from v1.0 are archived in PROJECT.md Key Decisions table. Key patterns ### Last Session **Date:** 2026-03-07 -**What happened:** Executed 09-01-PLAN.md — scan control backend. Added CancelScan/PauseScan/ResumeScan methods, per-scan cancellable context, pause checkpoints, and 3 new scan lifecycle events. -**Where we stopped:** Completed 09-01-PLAN.md -**Next action:** `/gsd-execute-phase 9` — Execute Plan 02 (keyboard shortcuts config) +**What happened:** Executed 09-02-PLAN.md — keyboard shortcuts config & service. Created Go shortcuts package, Wails bindings, frontend KeyboardShortcutService singleton, ShortcutsStore, and ShortcutsController. +**Where we stopped:** Completed 09-02-PLAN.md +**Next action:** `/gsd-execute-phase 9` — Execute Plan 03 (scan control UI) --- *State initialized: 2026-02-27* -Last activity: 2026-03-07 - Completed 09-01 scan control backend +Last activity: 2026-03-07 - Completed 09-02 keyboard shortcuts config & service *Last updated: 2026-03-07* diff --git a/.planning/phases/09-scan-cancellation-keyboard-shortcuts/09-02-SUMMARY.md b/.planning/phases/09-scan-cancellation-keyboard-shortcuts/09-02-SUMMARY.md new file mode 100644 index 0000000..b90cd9b --- /dev/null +++ b/.planning/phases/09-scan-cancellation-keyboard-shortcuts/09-02-SUMMARY.md @@ -0,0 +1,140 @@ +--- +phase: 09-scan-cancellation-keyboard-shortcuts +plan: 02 +subsystem: ui +tags: [keyboard-shortcuts, wails, lit, toml, config] + +# Dependency graph +requires: + - phase: 09-scan-cancellation-keyboard-shortcuts + provides: ShortcutsConfigChanged event (added in 09-01 codegen) +provides: + - Go shortcuts config package with defaults and validation + - Wails binding methods for shortcut CRUD (GetShortcuts, SetShortcuts, SetShortcut, ResetShortcuts) + - Frontend KeyboardShortcutService singleton with scope resolution + - ShortcutsStore with Wails persistence and event sync + - ShortcutsController for Lit component integration + - buildKeyString utility for shortcut capture widget +affects: [09-04-shortcuts-settings-ui, 09-05-shortcuts-integration] + +# Tech tracking +tech-stack: + added: [] + patterns: + - "Keyboard shortcut service singleton pattern (document keydown listener)" + - "Shadow DOM deep active element resolution for scope detection" + - "Canonical key string format: Ctrl+Alt+Shift+Key" + +key-files: + created: + - backend/shortcuts/config.go + - frontend/src/services/keyboard-shortcut-service.ts + - frontend/src/store/shortcuts-store.ts + - frontend/src/store/controllers/shortcuts-controller.ts + modified: + - backend/config/config.go + - backend/events/events.go + - frontend/src/events.ts + - frontend/src/store/index.ts + - frontend/index.ts + - frontend/wailsjs/go/config/Config.d.ts + - frontend/wailsjs/go/config/Config.js + - frontend/wailsjs/go/models.ts + +key-decisions: + - "Use ChangeVolume(delta) Wails binding for relative volume instead of reading state + SetVolume" + - "Use CurrentPositionSeconds + Seek for relative seek (no delta API available)" + - "Dispatch tracklist actions as CustomEvents on document for loose coupling" + - "Remove hardcoded Ctrl+F handler in index.ts — keyboard shortcut service now handles it" + +patterns-established: + - "services/ directory for singleton services (first usage)" + - "data-shortcut-scope attribute on elements for panel-specific shortcuts" + - "shortcut: event prefix for panel-specific shortcut dispatch" + +requirements-completed: [KEY-01, KEY-04, KEY-05] + +# Metrics +duration: 35min +completed: 2026-03-07 +--- + +# Phase 9 Plan 2: Keyboard Shortcuts Config & Service Summary + +**Go shortcuts config with TOML persistence, frontend KeyboardShortcutService singleton with scope resolution, shadow DOM active element walking, and text input suppression** + +## Performance + +- **Duration:** 35 min +- **Started:** 2026-03-07T02:14:19Z +- **Completed:** 2026-03-07T02:49:20Z +- **Tasks:** 2 +- **Files modified:** 12 + +## Accomplishments +- Go `shortcuts` package with 17 default bindings (player, nav, app, tracklist) +- Wails binding methods for shortcut CRUD: GetShortcuts, SetShortcuts, SetShortcut, ResetShortcuts +- Frontend KeyboardShortcutService with shadow DOM scope resolution and text input suppression +- ShortcutsStore syncs bindings via Wails events with queueMicrotask coalescing +- Replaced hardcoded Ctrl+F handler with service-based dispatch + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Create backend shortcuts config package and wire into main config** - `6285ca9` (feat) +2. **Task 2: Create frontend keyboard shortcut service, store, and controller** - `40d4815` (feat) + +## Files Created/Modified +- `backend/shortcuts/config.go` - Shortcuts config package with defaults, ApplyDefaults, Validate +- `backend/config/config.go` - Shortcuts field, getter/setter Wails bindings, event emission +- `backend/events/events.go` - ShortcutsConfigChanged event constant +- `frontend/src/events.ts` - Generated TypeScript event constant +- `frontend/src/services/keyboard-shortcut-service.ts` - Singleton keydown listener with scope resolution +- `frontend/src/store/shortcuts-store.ts` - Store with Wails persistence and event sync +- `frontend/src/store/controllers/shortcuts-controller.ts` - ReactiveController for Lit components +- `frontend/src/store/index.ts` - Added shortcuts store and controller exports +- `frontend/index.ts` - Removed hardcoded Ctrl+F, added service import +- `frontend/wailsjs/go/config/Config.d.ts` - Generated Wails TypeScript bindings +- `frontend/wailsjs/go/config/Config.js` - Generated Wails JavaScript stubs +- `frontend/wailsjs/go/models.ts` - Generated Wails model types + +## Decisions Made +- Used `ChangeVolume(delta)` Wails binding for relative volume adjustment (cleaner than state read + SetVolume) +- Used `CurrentPositionSeconds() + Seek(target)` for relative seeking (no delta seek API exists) +- Panel-specific actions (tracklist.play, tracklist.delete) dispatch as CustomEvents on document for loose coupling — track-list component can listen without import dependency +- Removed the hardcoded Ctrl+F keydown handler from index.ts — the keyboard shortcut service now handles `nav.searchAlt` → Ctrl+F + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 3 - Blocking] Fixed wsl lint error in library.go** +- **Found during:** Task 1 (pre-commit hook failure) +- **Issue:** `backend/library/library.go:593` had missing blank line before logger call (from Plan 01 commit) +- **Fix:** Added blank line before `l.logger.Info("scan cancelled, skipping orphan cleanup")` +- **Files modified:** backend/library/library.go +- **Verification:** golangci-lint passes with 0 issues +- **Committed in:** 6285ca9 (Task 1 commit) + +--- + +**Total deviations:** 1 auto-fixed (1 blocking) +**Impact on plan:** Trivial lint fix required to unblock pre-commit hook. No scope creep. + +## Issues Encountered +- Pre-commit hooks caused significant delays — `golangci-lint` runs on entire project and `codegen-check` verifies working tree cleanliness. Concurrent Plan 01 agent commits created race conditions with git staging. Resolved by stashing unrelated changes and ensuring clean working tree before commit. + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness +- Shortcuts foundation complete — default bindings work out of the box +- Ready for Plan 03 (scan control UI) and Plan 04 (shortcuts settings UI) +- `data-shortcut-scope` attribute ready for track-list and queue-panel components to adopt +- `buildKeyString` utility exported for the shortcut capture widget in Plan 04 + +--- +*Phase: 09-scan-cancellation-keyboard-shortcuts* +*Completed: 2026-03-07*