diff --git a/CLAUDE.md b/CLAUDE.md index 4cc6e8b..b557aa0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Repo identity and current state -The CMake project and binary are now named `reaper_reasampler`. This is **ReaSampler** — a per-project audio sample-bank capture tool that now builds TWO artifacts: the REAPER extension (`reaper_reasampler`) AND **ReaSampler 9000**, a Windows-only VST3 sampler instrument (`reasampler_9000.vst3`, `src/vst/`, second CMake target `reasampler_vst`, gated on the vendored `vendor/vst3sdk` submodule slice). The MPE modules (`mpe_model`, `mpe_view`) have been removed. M0–M8 are complete (bank_model, peaks, capture offline+realtime, persist, bank_panel, insert, capture action family, RealtimeRecordBackend, tail T1+T2+T1-followons). Phase B multi-bank (B1–B5, B-cap), Phase D1/D2 Design View (D1–D5, D2-W1–W3-B), Phase V versioning/beta-channel (V1/V3, V4), M10 provenance + re-capture from source, Phase R Reclaim (R1–R3: prune-reconcile core, dry-run shell, guarded deletion + action + panel button), M11 in full (batch capture, action-button strip + keybinding labels, conform-on-insert verified-extant, native OS drag-out), Phase L L1 (shared LICE drawing kit: `theme`/palette module, `component_geometry` geometry helpers, `draw_kit` shell, GDI DrawText retired in `bank_panel`), Phase L L2 (dock-panel layout redesign: `action_bar` pure task-grouped layout module, full M11-aware button inventory placed by task cluster, `bank_panel` redesigned through the L1 kit), Phase L L4 (dock-panel button layout enhancement: three-zone layout — top capture/placement/maintenance toolbar, bottom Design-View tagging/switching toolbar, footer narrow-toggle + Tail-button + Prune; `footer_bar` pure module + `footer_bar_tests`; `ActionCluster::Tagging`/`Switching` in `action_bar`), Phase L L5 (dock-panel button refinements: top-bar overflow menu for Batch Items/Batch Razor/Capture RT via `overflow_menu` pure module; custom LICE-kit hover-delay tooltips via `tooltip` pure module; four opposite-mode Item/Track tag buttons + Show Both on the bottom toolbar; Toggle + Activate-Arrange/Design buttons removed; grouping spacing widened — `mode_enable` pure opposite-mode enablement predicate), Phase L L6 (toolbar polish: single-row short-label button faces — keybinding micro sub-row removed from `ActionBarSlot`, keybinding now shown in hover tooltip as "`phrase — binding`"; Cancel RT moved from visible bar into the overflow menu — More (⋯) now lists Batch Items / Batch Razor / Capture RT / Cancel RT; visible top-bar cluster order Capture → Maintenance → Placement; toolbar height 40→28 px), Phase L L7 (capture ordering, card metadata, and selection styling: per-bank `SlotMap` (id→slot) in `bank_book` — gap-preserving persisted display order, `reorderSample`/`replaceSample`/`orderedSampleIds`/`reconcileSlots` mutators; `captureTimeSigNum`/`captureTimeSigDenom` stamped on `Sample` at capture via `TimeMap_GetTimeSigAtTime`; `card_drag` pure module — gesture precedence + SWELL stock cursor cues; `card_meta` pure module — bars.beats.subdivisions + s.ms formatters; `bank_panel` sparse-grid rendering with gap cells, drop dispatch + cursor cues, metadata overlay, tertiary-border selection), and Phase S (S1–S18 complete; S13 cross-artifact relay deferred): VST3 sampler instrument `reasampler_9000.vst3` — voice engine (`sampler_core`), zone payload (`sample_map`), pitch-preserve OLA (`pitch_shift`), bank change-detection (`bank_sync`), IPC bridge (`bridge_marshal`), editor UI modules (`editor_geometry`, `keyboard_strip`, `waveform_view`, `capture_browser`, `browser_scroll`, `note_entry`, `param_slider`, `embed_strip`), VST3 shells (`reasampler_processor`, `reasampler_editor`, `reasampler_embed`, `reaper_bridge` READ-ONLY bank consumer, `vst_entry`); extension additions: `instrument_drop` pure FX-button blob builder (S17), `assignment_request` pure ingest-assign wire (S8), `ingest` shell (S8: docked-panel drop → capture/import + assign), `instrument_drop_win` shell (S17: `TrackFX_AddByName` + vst_chunk inject, rollback on fail); `drag_out` extended with `InstrumentDrop` third gesture; S18 channel isolation forks VST3 binary to `reasampler_9000_beta.vst3` alongside the beta extension have all landed. M9 slots deferred indefinitely. The *discipline* — pure REAPER-free testable core split from REAPER-facing shells — is **preserved** throughout. +The CMake project and binary are now named `reaper_reasampler`. This is **ReaSampler** — a per-project audio sample-bank capture tool that now builds TWO artifacts: the REAPER extension (`reaper_reasampler`) AND **ReaSampler 9000**, a Windows-only VST3 sampler instrument (`reasampler_9000.vst3`, `src/vst/`, second CMake target `reasampler_vst`, gated on the vendored `vendor/vst3sdk` submodule slice). The MPE modules (`mpe_model`, `mpe_view`) have been removed. M0–M8 are complete (bank_model, peaks, capture offline+realtime, persist, bank_panel, insert, capture action family, RealtimeRecordBackend, tail T1+T2+T1-followons). Phase B multi-bank (B1–B5, B-cap), Phase D1/D2 Design View (D1–D5, D2-W1–W3-B), Phase V versioning/beta-channel (V1/V3, V4), M10 provenance + re-capture from source, Phase R Reclaim (R1–R3: prune-reconcile core, dry-run shell, guarded deletion + action + panel button), M11 in full (batch capture, action-button strip + keybinding labels, conform-on-insert verified-extant, native OS drag-out), Phase L L1 (shared LICE drawing kit: `theme`/palette module, `component_geometry` geometry helpers, `draw_kit` shell, GDI DrawText retired in `bank_panel`), Phase L L2 (dock-panel layout redesign: `action_bar` pure task-grouped layout module, full M11-aware button inventory placed by task cluster, `bank_panel` redesigned through the L1 kit), Phase L L4 (dock-panel button layout enhancement: three-zone layout — top capture/placement/maintenance toolbar, bottom Design-View tagging/switching toolbar, footer narrow-toggle + Tail-button + Prune; `footer_bar` pure module + `footer_bar_tests`; `ActionCluster::Tagging`/`Switching` in `action_bar`), Phase L L5 (dock-panel button refinements: top-bar overflow menu for Batch Items/Batch Razor/Capture RT via `overflow_menu` pure module; custom LICE-kit hover-delay tooltips via `tooltip` pure module; four opposite-mode Item/Track tag buttons + Show Both on the bottom toolbar; Toggle + Activate-Arrange/Design buttons removed; grouping spacing widened — `mode_enable` pure opposite-mode enablement predicate), Phase L L6 (toolbar polish: single-row short-label button faces — keybinding micro sub-row removed from `ActionBarSlot`, keybinding now shown in hover tooltip as "`phrase — binding`"; Cancel RT moved from visible bar into the overflow menu — More (⋯) now lists Batch Items / Batch Razor / Capture RT / Cancel RT; visible top-bar cluster order Capture → Maintenance → Placement; toolbar height 40→28 px), Phase L L7 (capture ordering, card metadata, and selection styling: per-bank `SlotMap` (id→slot) in `bank_book` — gap-preserving persisted display order, `reorderSample`/`replaceSample`/`orderedSampleIds`/`reconcileSlots` mutators; `captureTimeSigNum`/`captureTimeSigDenom` stamped on `Sample` at capture via `TimeMap_GetTimeSigAtTime`; `card_drag` pure module — gesture precedence + SWELL stock cursor cues; `card_meta` pure module — bars.beats.subdivisions + s.ms formatters; `bank_panel` sparse-grid rendering with gap cells, drop dispatch + cursor cues, metadata overlay, tertiary-border selection), Phase L L3 (VST editor + embed-strip restyle: `reasampler_editor.cpp` + `reasampler_embed.cpp` restyled through the L1 kit — REAPER-grey neutrals + three pastel accents, pastel spectral keyboard strip + zone bars as the signature surface with active zone lifting to `accent/primary` + static glow, hover/pressed/drag states throughout; local `kCol*` forest-green palette retired; GDI `DrawTextA` path retired in both VST shells; VST3 class UID unchanged; Phase L now complete), and Phase S (S1–S18 complete; S13 cross-artifact relay deferred): VST3 sampler instrument `reasampler_9000.vst3` — voice engine (`sampler_core`), zone payload (`sample_map`), pitch-preserve OLA (`pitch_shift`), bank change-detection (`bank_sync`), IPC bridge (`bridge_marshal`), editor UI modules (`editor_geometry`, `keyboard_strip`, `waveform_view`, `capture_browser`, `browser_scroll`, `note_entry`, `param_slider`, `embed_strip`), VST3 shells (`reasampler_processor`, `reasampler_editor`, `reasampler_embed`, `reaper_bridge` READ-ONLY bank consumer, `vst_entry`); extension additions: `instrument_drop` pure FX-button blob builder (S17), `assignment_request` pure ingest-assign wire (S8), `ingest` shell (S8: docked-panel drop → capture/import + assign), `instrument_drop_win` shell (S17: `TrackFX_AddByName` + vst_chunk inject, rollback on fail); `drag_out` extended with `InstrumentDrop` third gesture; S18 channel isolation forks VST3 binary to `reasampler_9000_beta.vst3` alongside the beta extension have all landed. M9 slots abandoned (Daniel, 2026-07-27). The *discipline* — pure REAPER-free testable core split from REAPER-facing shells — is **preserved** throughout. CONTEXT.md is the authoritative spec and build roadmap. Read it first for any non-trivial task. Every REAPER API name cited there is correct-by-intent; verify argument order, types, and flag values against `vendor/reaper-sdk/sdk/reaper_plugin_functions.h` before use. @@ -38,6 +38,8 @@ Key targets (see CMakeLists.txt for the full list): | `view_mode_model_tests` | executable | Pure unit tests for `view_mode_model` — no REAPER, no DAW. | | `view_tree_tests` | executable | Pure unit tests for `view_tree` — no REAPER, no DAW. | | `mode_switch_tests` | executable | Pure unit tests for `mode_switch` — no REAPER, no DAW. | +| `bank_grid_tests` | executable | Pure unit tests for `bank_grid` — no REAPER, no DAW. | +| `tab_strip_tests` | executable | Pure unit tests for `tab_strip` — no REAPER, no DAW. | | `bank_book_tests` | executable | Pure unit tests for `bank_book` — no REAPER, no DAW. | | `wav_trim_tests` | executable | Pure unit tests for `wav_trim` — no REAPER, no DAW. | | `owned_manifest_tests` | executable | Pure unit tests for `owned_manifest` — no REAPER, no DAW. | @@ -105,6 +107,8 @@ There is no hot-reload. Copy the built binary into REAPER's `UserPlugins/` folde - `peaks` — waveform min/max bin computation from raw PCM. Fed a known signal, asserts envelope. Does not depend on REAPER's peak API. - `view_mode_model` — Design View mode system: mode registry, GUID-keyed membership, folder-tree-aware visibility derivation, snapshot-based park/restore planner, JSON round-trip. Mirror of `bank_model` for the Design View phase. - `view_tree` — pure `I_FOLDERDEPTH`→FolderTree helper for the Design View shell; no REAPER types at the boundary. +- `bank_grid` — REAPER-free grid layout, selection, keyboard-nav, and thumbnail-cache-key logic for the docked bank panel: `computeCellRects` (N cells tiled left-to-right/top-to-bottom), `hitTestCell`, `Selection` mutators (`applyClick`, `navigate`), `ThumbnailKey`/`thumbnailKeyString`, and `compressAmplitudeForDisplay`. The originating geometry module that later pure modules mirror. +- `tab_strip` — REAPER-free scrollable tab-strip layout + hit-test for the named-banks strip (Phase B): `computeTabStripLayout` (overflow + chevron geometry), `computeTabRects` (clipped, scroll-offset-shifted tab rects), `hitTestTabStrip` (Tab / ScrollLeft / ScrollRight / None). Mirror of `bank_grid`. - `mode_switch` — REAPER-free segment layout + hit-test math for the bank_panel's Design View mode switch; divides a header rectangle into N equal segments and hit-tests a point to a segment. Mirror of `bank_grid`. - `bank_book` — multi-bank registry (Phase B): an ordered set of banks (pool seeded as bank-zero + named banks), each wrapping a `BankIndex`. Owns create/rename/reorder/delete of named banks, pool privileges (un-deletable/un-renamable/un-evacuable, never zero banks) enforced in-model, active-bank id, index-only move/copy/remove of a sample between or from banks, `hashReferencedElsewhere` cross-bank reference query, JSON round-trip + legacy-`bank_index`→pool migration. Wraps `BankIndex` (bank_model untouched; no `bankId` on `Sample`). L7 adds: per-`Bank` gap-preserving **`SlotMap`** (id→slot) for deterministic display order — persisted inside the existing `"banks"` blob; `reorderSample` (insert-before-shift; same-slot = no-op), `replaceSample` (occupant index-removal via standard remove path + pool-guard inheritance; no-op on reject), `orderedSampleIds`, `reconcileSlots` (pre-L7 migration seeds dense insertion order on load). - `owned_manifest` — owned-file manifest seam (Phase B B-cap): the set of project-relative files the capture path itself created, persisted under the `"owned_files"` ext-state key, so Phase R prune can distinguish the bank system's own orphans from hand-dropped files. Deliberately decoupled from `bank_book` — tracks files created, not index membership. Phase R (R1/R2) consumes it; no prune logic here. diff --git a/docs/product/code-organization.md b/docs/product/code-organization.md index 7cdb8f8..e303cf4 100644 --- a/docs/product/code-organization.md +++ b/docs/product/code-organization.md @@ -49,7 +49,7 @@ audit** (§2b) — both staff-engineer-rigor analyses of the actual `src/` tree. the *old* layout. As of 2026-07-27 the outstanding work is **Phase S** (merged to dev) and **Phase L L3** (the VST restyle, itself gated on Phase S) — Daniel's plain target: *"when Phase S and L3 are finished."* (L1/L2/L4–L7 have already landed; D2 is functionally complete; - M9 is deferred.) Stated prominently because getting the gate wrong is the one way this phase + M9 is abandoned.) Stated prominently because getting the gate wrong is the one way this phase does real damage. - **Beyond SOLID, Phase Q also fixes naming.** The reorg gives every symbol a *directory + namespace home* (Q-3/Q-4); §2b's grep-verified naming audit adds the orthogonal dimension of @@ -344,9 +344,9 @@ namespace of every header, splitting the four largest TUs). Meanwhile: `COMPLETED.md`; the once-listed "L2 pending" is stale and has been corrected here.) - **D2** is **functionally complete** (D2-W1..W3-B landed; the only open item — a per-track lane-split panel indicator — is *explicitly deferred*, not a blocking residual). **M9** (slots) - is *explicitly deferred* (Daniel, 2026-07-26), not scheduled work. Neither blocks the gate on - its own; both are named in the gate only so a future reactivation of either re-arms the "tree - must be quiescent" condition. + is **abandoned** (Daniel, 2026-07-27) — will not be built. D2 is named in the gate only so a + future reactivation of its deferred panel indicator re-arms the "tree must be quiescent" + condition; M9 is out and cannot re-arm it. A structural reorg landing while any of these is mid-flight would force every in-flight branch through a **rename-and-relocate-everything** merge — the worst possible conflict @@ -364,24 +364,14 @@ does not begin until the tree is **quiescent**, with no large branch outstanding 3. **D2** — confirmed complete or its deferred indicator explicitly re-deferred. It is functionally complete today; this line stays only so that if the deferred panel indicator is picked up as active work, it re-arms the quiescence condition. -4. **M9** — landed **or** confirmed-abandoned. It is *deferred* today (Daniel, 2026-07-26); the - distinction between "deferred" and "abandoned" is a Daniel call (see the disposition note - below), but either disposition satisfies the gate as long as M9 is not *active in-flight work* - when Q-W1 opens. +4. **M9** — **abandoned** (Daniel, 2026-07-27). This gate condition is permanently satisfied; + M9 will not be reactivated. Restated as the plain readiness target Daniel named: **"when Phase S and L3 are finished."** Phase Q is the *last* structural pillar precisely because it reshapes the ground every other pillar stands on. Landing it early would tax every subsequent phase; landing it last taxes nothing. -> **Daniel-decision note (M9 disposition).** M9 (MPC-style slots) is recorded as "deferred -> indefinitely / can be picked up later" — which is *not* the same as "abandoned." For the gate -> this is immaterial (deferred and abandoned both clear it). It matters only if M9 is ever -> reactivated as scheduled work: doing so *before* Phase Q means M9 lands on the flat layout and -> is cheap; doing so *after* means M9 is authored against the reorganized `core/`/`shell/` tree. -> No action needed unless Daniel wants M9 scheduled — flagged so the "deferred vs abandoned" -> ambiguity is surfaced, not silently resolved. - *(Sequencing corollary: because the gate is "everything else first," Phase Q's own internal sequencing —§5— is about risk-ordering the reorg, not about racing other phases.)*