docs: ME-import places instrument on selected track

Update ingest surface (2) + instrument_drop_win entry points in CLAUDE.md
and the Ingest-through-the-bank spec in CONTEXT.md; createTrackWithInstrument
removed.
This commit is contained in:
2026-07-27 14:22:43 -04:00
parent 3b0c42fe52
commit fcca987454
2 changed files with 10 additions and 9 deletions
+2 -2
View File
@@ -141,8 +141,8 @@ There is no hot-reload. Copy the built binary into REAPER's `UserPlugins/` folde
- `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.
- `provenance_shell` — FX-chain identity queries via `TrackFX_*` / `TakeFX_*` APIs; collects source-item paths and parent-detection inputs to feed the pure `provenance` fingerprint builder. Stamps `Sample.provenance` on capture when every resolving source item maps by exact normalized path (case-folded on Windows) to exactly one bank sample; ambiguous/mixed cases record nothing conservatively.
- `drag_out_win` — M11 OS drag-out shell: Windows OLE `DoDragDrop` / `CF_HDROP`, copy-only structurally (`DROPEFFECT_MOVE` not offered, no source-deletion path); macOS/Linux via `SWELL_InitiateDragDropOfFileList` (copy-semantics caveat documented — SWELL does not expose a drop-effect query). Driven by the `drag_out` pure module.
- `ingest` — Phase S ingest-through-the-bank shell (S8) on the EXTENSION side: three surfaces — (1) arrange capture→bank→assign (bindable action), (2) Media-Explorer import→bank→new instrument on a new track (bindable action, single-file via `MediaExplorerGetLastPlayedFileInfo`; RS5k "load into a new sampler" parity — no `assignment_request` written; calls `createTrackWithInstrument`), (3) file drop onto the bank panel→bank only (multi-file, bank-fill; no `assignment_request` written, no effect on any live instance's selection — the bank-generation bump is retained so open instances' browsers refresh). Only surface (1) writes the `assignment_request` ext-state wire via `ingestAssignActiveInstance`. ingest NEVER inserts a timeline item.
- `instrument_drop_win` — Phase S FX-button drop shell (S17): (a) resolves a screen point to a track + its TCP FX-button hotspot via REAPER's hit-test API (`GetThingFromPoint`, `TrackFX_*`), and (b) on release adds a ReaSampler 9000 instance to that track and injects the dragged capture as its component state via `TrackFX_SetNamedConfigParm` "vst_chunk". Exposes three entry points: `loadInstrumentOntoTrack` (FX add+inject, no own undo block — the shared inner half used by callers that own the undo grouping), `performInstrumentDrop` (wraps `loadInstrumentOntoTrack` in its own undo block — the S17 drag-drop gesture path), and `createTrackWithInstrument` (appends a new track, names it, then calls `loadInstrumentOntoTrack`; rolls back via `DeleteTrack` on failure — the ME-import new-instrument path). Never captures, never writes the bank, never inserts a timeline item.
- `ingest` — Phase S ingest-through-the-bank shell (S8) on the EXTENSION side: three surfaces — (1) arrange capture→bank→assign (bindable action), (2) Media-Explorer import→bank→instrument on the SELECTED TRACK (bindable action, single-file via `MediaExplorerGetLastPlayedFileInfo`; adds RS9k to the user's currently selected track via `loadInstrumentOntoTrack` — no new track created, no routing changed; if no track is selected the sound still lands in the bank but no instrument is placed, with a console message; no `assignment_request` written), (3) file drop onto the bank panel→bank only (multi-file, bank-fill; no `assignment_request` written, no effect on any live instance's selection — the bank-generation bump is retained so open instances' browsers refresh). Only surface (1) writes the `assignment_request` ext-state wire via `ingestAssignActiveInstance`. ingest NEVER inserts a timeline item.
- `instrument_drop_win` — Phase S FX-button drop shell (S17): (a) resolves a screen point to a track + its TCP FX-button hotspot via REAPER's hit-test API (`GetThingFromPoint`, `TrackFX_*`), and (b) on release adds a ReaSampler 9000 instance to that track and injects the dragged capture as its component state via `TrackFX_SetNamedConfigParm` "vst_chunk". Exposes two entry points: `loadInstrumentOntoTrack` (FX add+inject, no own undo block — the shared inner half used by callers that own the undo grouping; also the ME-import placement path), `performInstrumentDrop` (wraps `loadInstrumentOntoTrack` in its own undo block — the S17 drag-drop gesture path). Never captures, never writes the bank, never inserts a timeline item.
- `draw_kit` — Phase L shared LICE draw shell (L1): `fillSurface` (micro-gradient + inner highlight/shadow), `drawButton`/`drawSlider`/`drawListRow`/`drawWaveform`, cached-font `text()` over four `LICE_CachedFont`s (kit-owned lifecycle), full interaction-state model, double-buffer preserved. Consumes `theme` + `component_geometry`. First consumer: `bank_panel` (GDI `DrawText` path retired in L1).
- `actions` — registers the capture/placement/slot action family, the Design View action family (toggle active mode, activate Arrange/Design, tag/untag selected tracks, show-both), the multi-bank action family (create/rename/reorder/delete bank, evacuate, activate, move/copy/remove selected samples), and the Phase R prune action (`BANK_PRUNE_FOLDER` — dry-run-first, confirm-with-manifest, then `pruneDeletePlan`-guarded deletion; **the ONLY file-deletion authority in the system**); routes each to the modules above via the `command_id`/`gaccel`/`hookcommand` contract. Every bank index verb wraps its mutation in a batched REAPER undo point (`Undo_BeginBlock2`/`EndBlock2`, `UNDO_STATE_MISCCFG`) so one bank operation is one Ctrl-Z. The prune action writes no ext state and opens no undo point (file deletion is not REAPER-undoable).
+8 -7
View File
@@ -1586,17 +1586,18 @@ headers):**
capture inputs) and assigns the resulting `Sample` id to the target instance. **It never
inserts a timeline item** — the capture/placement separation is load-bearing; assignment
is a bank-index + instance-selection act, not a placement.
- **Media Explorer import → bank → new instrument.** The Media-Explorer surface is **thin**:
- **Media Explorer import → bank → instrument on selected track.** The Media-Explorer surface is **thin**:
`OpenMediaExplorer` (open/select a file) and `MediaExplorerGetLastPlayedFileInfo` (read the
*one* last-played/selected file path + its selection range/pitch/vol/rate) are the whole
contract. There is **no** enumerate-selected-files and **no** register-a-drop-handler-on-
the-Media-Explorer API. So ME import is **single-file, pull-on-action** — an action fired
while a file is selected in the ME — not a push/drop from inside the ME. **Shipped behavior
(RS5k parity):** after importing the file into the active bank, the action stands up a NEW
ReaSampler 9000 instrument on a NEW track (named after the sound) pre-loaded with just that
sound (`createTrackWithInstrument` in `instrument_drop_win`). No `assignment_request` is
written; it never touches a live instance's selection. Undo-wrapped: track-create + persist +
FX-add + inject = one Ctrl-Z.
while a file is selected in the ME — not a push/drop from inside the ME. **Shipped behavior:**
after importing the file into the active bank, the action adds a ReaSampler 9000 instrument to
the user's **currently selected track** via `loadInstrumentOntoTrack` in `instrument_drop_win`
— no new track is created and no routing is changed ("new sound, existing track"). If no track
is selected the sound still lands in the bank but no instrument is placed and a console message
explains why. No `assignment_request` is written; it never touches a live instance's selection.
Undo-wrapped: persist + FX-add + inject = one Ctrl-Z.
- **Drag-and-drop onto ReaSampler surfaces.** REAPER exposes **no** drag-drop registration
API. Drop handling is on ReaSampler's *own* HWNDs via SWELL/Win32 (`WM_DROPFILES` /
`IDropTarget` on the docked `bank_panel` HWND — the surface the panel already owns) → ingest