docs: archive M11 wave 1 to COMPLETED; reconcile CLAUDE.md
Batch capture + panel action buttons/labels landed; conform-on-insert verified already shipped; resample-and-mute-source cut by Daniel (Design View park/hide supersedes it). Drag-out remains in PLAN.
This commit is contained in:
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|||||||
|
|
||||||
## Repo identity and current state
|
## 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. 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, and Phase R Reclaim (R1–R3: prune-reconcile core, dry-run shell, guarded deletion + action + panel button) have all landed. M9 slots and M11 polish remain. 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. 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), and M11 wave 1 (batch capture, action-button strip + keybinding labels, conform-on-insert verified-extant) have all landed. M9 slots and M11 native-OS-drag-out remain. 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.
|
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.
|
||||||
|
|
||||||
@@ -39,6 +39,8 @@ Key targets (see CMakeLists.txt for the full list):
|
|||||||
| `provenance_tests` | executable | Pure unit tests for `provenance` — no REAPER, no DAW. |
|
| `provenance_tests` | executable | Pure unit tests for `provenance` — no REAPER, no DAW. |
|
||||||
| `prune_reconcile_tests` | executable | Pure unit tests for `prune_reconcile` — no REAPER, no DAW. |
|
| `prune_reconcile_tests` | executable | Pure unit tests for `prune_reconcile` — no REAPER, no DAW. |
|
||||||
| `prune_button_tests` | executable | Pure unit tests for `prune_button` — no REAPER, no DAW. |
|
| `prune_button_tests` | executable | Pure unit tests for `prune_button` — no REAPER, no DAW. |
|
||||||
|
| `batch_capture_tests` | executable | Pure unit tests for `batch_capture` — no REAPER, no DAW. |
|
||||||
|
| `action_buttons_tests` | executable | Pure unit tests for `action_buttons` — no REAPER, no DAW. |
|
||||||
| `reaper_reasampler` | loadable module | The actual extension binary (`.dll` / `.dylib` / `.so`). |
|
| `reaper_reasampler` | loadable module | The actual extension binary (`.dll` / `.dylib` / `.so`). |
|
||||||
|
|
||||||
### Beta channel build (Phase V, V4)
|
### Beta channel build (Phase V, V4)
|
||||||
@@ -77,11 +79,13 @@ There is no hot-reload. Copy the built binary into REAPER's `UserPlugins/` folde
|
|||||||
- `provenance` — capture-recipe fingerprint (M10): build/encode/compare a `rsprov1` length-prefixed fingerprint of scope, exact range, tail, rate/channels, track GUIDs, and order-sensitive FX-chain identity; parse/compare for drift detection on re-capture. A thin reproducibility fingerprint — NOT a serialized chain to restore. Drives `BankIndex::updateInPlace` / `BankBook::updateSampleInPlace` (order-preserving, id-stable) on re-capture.
|
- `provenance` — capture-recipe fingerprint (M10): build/encode/compare a `rsprov1` length-prefixed fingerprint of scope, exact range, tail, rate/channels, track GUIDs, and order-sensitive FX-chain identity; parse/compare for drift detection on re-capture. A thin reproducibility fingerprint — NOT a serialized chain to restore. Drives `BankIndex::updateInPlace` / `BankBook::updateSampleInPlace` (order-preserving, id-stable) on re-capture.
|
||||||
- `prune_reconcile` — Phase R pure prune core: `pruneOrphans(present, referenced, owned)` computes `(owned ∩ present) − referenced` (exact-string path match); `buildPruneReport` tallies count/bytes/display-capped file list; `pruneDeletePlan` produces the confirm-time staleness intersection (`confirmed ∩ freshOrphans`). REAPER-free, filesystem-free. The safety-critical "which files are orphans" decision — hard-tested here before any I/O exists. Also: `BankBook::referencedPaths()` additive const union query (all banks incl. pool, de-duped) added to `bank_book`.
|
- `prune_reconcile` — Phase R pure prune core: `pruneOrphans(present, referenced, owned)` computes `(owned ∩ present) − referenced` (exact-string path match); `buildPruneReport` tallies count/bytes/display-capped file list; `pruneDeletePlan` produces the confirm-time staleness intersection (`confirmed ∩ freshOrphans`). REAPER-free, filesystem-free. The safety-critical "which files are orphans" decision — hard-tested here before any I/O exists. Also: `BankBook::referencedPaths()` additive const union query (all banks incl. pool, de-duped) added to `bank_book`.
|
||||||
- `prune_button` — Phase R pure layout/hit-test for the `bank_panel` footer Prune button: `computePruneButton` (right-anchored, suppressed gracefully when footer is too narrow) + `hitTestPruneButton`. Mirror of `mode_switch` / `tab_strip`.
|
- `prune_button` — Phase R pure layout/hit-test for the `bank_panel` footer Prune button: `computePruneButton` (right-anchored, suppressed gracefully when footer is too narrow) + `hitTestPruneButton`. Mirror of `mode_switch` / `tab_strip`.
|
||||||
|
- `batch_capture` — M11 pure batch-capture planner: maps a list of source ranges to ordinal capture units, drives per-unit capture via a shared `captureAndIndexOne` helper, and aggregates mixed results. No REAPER types at the boundary.
|
||||||
|
- `action_buttons` — M11 pure action-button strip layout/hit-test: divides a strip rect into N action buttons, min-width overflow-hiding, label formatting with "(unbound)" fallback, `ActionButtonRect` struct. Mirror of `mode_switch` / `bank_grid`.
|
||||||
|
|
||||||
**REAPER-facing shells:**
|
**REAPER-facing shells:**
|
||||||
- `capture` — `ICaptureBackend` interface; `OfflineRenderBackend` (deterministic default) and `RealtimeRecordBackend`. Input: `CaptureRequest`. Output: finished file + populated `Sample` handed to `bank_model`.
|
- `capture` — `ICaptureBackend` interface; `OfflineRenderBackend` (deterministic default) and `RealtimeRecordBackend`. Input: `CaptureRequest`. Output: finished file + populated `Sample` handed to `bank_model`.
|
||||||
- `insert` — placement via `InsertMedia`; conform-to-project-tempo is an explicit opt-in flag, never silent stretching.
|
- `insert` — placement via `InsertMedia`; conform-to-project-tempo is an explicit opt-in flag, never silent stretching.
|
||||||
- `bank_panel` — docked LICE-drawn grid: thumbnails, audition, multi-select, keyboard navigation.
|
- `bank_panel` — docked LICE-drawn grid: thumbnails, audition, multi-select, keyboard navigation; a 28px action-button strip (M11) between the split body and tail footer that fires capture/insert/re-capture actions via `NamedCommandLookup` + `Main_OnCommand` and shows live keybinding labels via `kbd_getTextFromCmd`.
|
||||||
- `persist` — project ext state (`SetProjExtState` / `GetProjExtState`, namespace `"reasampler"`) ↔ `BankBook` JSON (`"banks"` key) + `ViewModeModel` JSON (`"view_state"` key) + `TailSetting` JSON (`"tail_setting"` key) + `OwnedManifest` JSON (`"owned_files"` key) + writing-version stamp (`"version"` key, written via `stampVersion()` on every `saveToActiveProject()`); project-relative path resolution. A `projectconfig` hook (`BeginLoadProjectState(isUndo)`) triggers a deferred session reload on undo/redo so Ctrl-Z/redo visibly restores book/view/tail/manifest in-session. Hosts `ReaSamplerSession::pruneDryRun()` (read-only orphan enumeration via M4 project-relative resolution) and `pruneOrphanSet()` (full-set query for the R3 delete path); supplies `referencedPaths()` + `owned().paths()` to the `prune_reconcile` pure core.
|
- `persist` — project ext state (`SetProjExtState` / `GetProjExtState`, namespace `"reasampler"`) ↔ `BankBook` JSON (`"banks"` key) + `ViewModeModel` JSON (`"view_state"` key) + `TailSetting` JSON (`"tail_setting"` key) + `OwnedManifest` JSON (`"owned_files"` key) + writing-version stamp (`"version"` key, written via `stampVersion()` on every `saveToActiveProject()`); project-relative path resolution. A `projectconfig` hook (`BeginLoadProjectState(isUndo)`) triggers a deferred session reload on undo/redo so Ctrl-Z/redo visibly restores book/view/tail/manifest in-session. Hosts `ReaSamplerSession::pruneDryRun()` (read-only orphan enumeration via M4 project-relative resolution) and `pruneOrphanSet()` (full-set query for the R3 delete path); supplies `referencedPaths()` + `owned().paths()` to the `prune_reconcile` pure core.
|
||||||
- `view` — Design View shell: reads the folder tree via `view_tree`, snapshots flag values before parking, drives hide + CPU-park on inactive-mode leaves (`B_SHOWINTCP`/`B_SHOWINMIXER`/`B_MAINSEND`/`I_FXEN` + per-FX offline) and derived visibility on parents; restores from snapshot. Never touches master or `B_MUTE`/`I_SOLO`.
|
- `view` — Design View shell: reads the folder tree via `view_tree`, snapshots flag values before parking, drives hide + CPU-park on inactive-mode leaves (`B_SHOWINTCP`/`B_SHOWINMIXER`/`B_MAINSEND`/`I_FXEN` + per-FX offline) and derived visibility on parents; restores from snapshot. Never touches master or `B_MUTE`/`I_SOLO`.
|
||||||
- `track_guid` — shared `MediaTrack*` → canonical GUID-string formatter; single source of truth for membership keys used by both the view shell and the actions layer.
|
- `track_guid` — shared `MediaTrack*` → canonical GUID-string formatter; single source of truth for membership keys used by both the view shell and the actions layer.
|
||||||
|
|||||||
@@ -1164,6 +1164,40 @@ untouched.
|
|||||||
through the registered command id (the same action as the bindable menu entry —
|
through the registered command id (the same action as the bindable menu entry —
|
||||||
no duplicate logic).
|
no duplicate logic).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Milestone 11 — polish (wave 1)
|
||||||
|
**Goal:** Batch capture (per selected item / per razor area), action trigger buttons
|
||||||
|
+ keybinding help labels, conform-on-insert. CONTEXT.md Build order 11.
|
||||||
|
**Verify (gates 23/23 both configs):** CTest green on new pure targets; each
|
||||||
|
in-panel action fires through the command-id contract without regressing precision
|
||||||
|
invariants.
|
||||||
|
|
||||||
|
- [x] **Batch capture** (`batch_capture` pure module + `CAPTURE_BATCH_ITEMS` /
|
||||||
|
`CAPTURE_BATCH_RAZOR` actions): plan source ranges → ordinal units; mixed-result
|
||||||
|
aggregation; actions fire one bank sample per selected item / per razor area;
|
||||||
|
transient per-unit selection with RAII restore; per-unit invariants + provenance;
|
||||||
|
single persist per batch; one summary line. `RunCapture` internals extracted to a
|
||||||
|
shared `captureAndIndexOne` helper (behavior identical). New CTest target
|
||||||
|
`batch_capture_tests`.
|
||||||
|
- [x] **Action trigger buttons + keybinding help labels** (`action_buttons` pure
|
||||||
|
module + bank_panel strip): strip layout/hit-test with min-width overflow-hiding
|
||||||
|
and label formatting with "(unbound)" fallback; struct `ActionButtonRect`; a 28px
|
||||||
|
LICE button strip in bank_panel between the split body and tail footer fires
|
||||||
|
capture item/track, realtime start/cancel, insert native/conform, re-capture-from-
|
||||||
|
source via `NamedCommandLookup` + `Main_OnCommand`; labels show live bindings via
|
||||||
|
`kbd_getTextFromCmd`. Coexists with Phase R's prune button (footer). New CTest
|
||||||
|
target `action_buttons_tests`.
|
||||||
|
- [x] **Conform-on-insert** — verified already shipped (both insert variants were
|
||||||
|
registered actions since the insert milestone); no new code. Closes as
|
||||||
|
verified-extant.
|
||||||
|
- ~~[ ] **Resample-and-mute-source** — Cut (fixed by Daniel, 2026-07-26).~~ Rationale:
|
||||||
|
the Design View mode projection (park/hide inactive-mode content) supersedes the
|
||||||
|
mute-after-capture workflow; a mute action would be redundant with the dual-canvas
|
||||||
|
architecture. Mirror of the null-test cut precedent ("Cut (fixed by Daniel)").
|
||||||
|
|
||||||
|
**Remaining in M11:** Native OS drag-out (not built in wave 1 — still in PLAN.md).
|
||||||
|
|
||||||
## Phase R forks — settled 2026-07-24
|
## Phase R forks — settled 2026-07-24
|
||||||
- **Fork R-C — deletion mechanism.** Settled: **trash-preferred, unlink fallback.**
|
- **Fork R-C — deletion mechanism.** Settled: **trash-preferred, unlink fallback.**
|
||||||
Route to OS trash where a portable move-to-trash is available (recoverable), else
|
Route to OS trash where a portable move-to-trash is available (recoverable), else
|
||||||
|
|||||||
@@ -24,30 +24,12 @@ state persists via the index.
|
|||||||
- [ ] "Capture to slot N" / "insert slot N" actions, MIDI-bindable.
|
- [ ] "Capture to slot N" / "insert slot N" actions, MIDI-bindable.
|
||||||
|
|
||||||
## Milestone 11 — polish
|
## Milestone 11 — polish
|
||||||
**Goal:** Batch capture (per selected item / per razor area),
|
**Goal:** Native OS drag-out (remaining polish item). CONTEXT.md Build order 11,
|
||||||
resample-and-mute-source, conform-on-insert, native OS drag-out. CONTEXT.md
|
§Non-goals (drag-out deferred to last).
|
||||||
Build order 11, §Non-goals (drag-out deferred to last).
|
**Verify (in DAW):** Drag-out places a valid file in the OS target without
|
||||||
**Verify (in DAW):** Each polish action works without regressing the precision
|
regressing the precision invariants.
|
||||||
invariants; drag-out places a valid file in the OS target.
|
|
||||||
|
|
||||||
- [ ] Batch capture: per selected item / per razor area.
|
|
||||||
- [ ] Resample-and-mute-source.
|
|
||||||
- [ ] Conform-on-insert (explicit).
|
|
||||||
- [ ] Native OS drag-out (deferred final; `InsertMedia` path must already work).
|
- [ ] Native OS drag-out (deferred final; `InsertMedia` path must already work).
|
||||||
- [ ] Keybinding help labels: in the docked bank_panel, surface the current key
|
|
||||||
binding for each capture/provenance action (e.g. "Capture Item → <key>") by
|
|
||||||
querying the SDK for the key bound to the action's command id
|
|
||||||
(`kbd_getTextFromCmd(cmd, SectionFromUniqueID(0))` — main section) and formatting
|
|
||||||
a reminder label. Unbound case degrades to the action name with a clear
|
|
||||||
"unbound"/"—" marker (empty/blank return handled explicitly). Split: label-text
|
|
||||||
formatting (binding string + fallback → label) is **pure/testable**; the SDK
|
|
||||||
binding query + label draw is bank_panel shell.
|
|
||||||
- [ ] Action trigger buttons: clickable bank_panel buttons that fire the capture and
|
|
||||||
provenance actions directly, routing through the **existing** command-id contract
|
|
||||||
(`Main_OnCommand`/`KBD_OnMainActionEx` with the registered command id — the same id
|
|
||||||
minted at `registerAction`), never re-implementing capture. Split: button
|
|
||||||
hit-testing/layout math is **pure/testable** (mirror of `mode_switch`/`bank_grid`);
|
|
||||||
draw + command dispatch is bank_panel shell.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user