# Proposal: ReaScript-First Built-in Plugin Configuration ## Intent RPPBuilder writes `.rpp` text that REAPER loads, but **built-in plugins** (ReaEQ, ReaComp, ReaVerb, etc.) need the REAPER API (`TrackFX_AddByName`, `TrackFX_SetParam`) to configure parameters correctly. Text-mode `VST "ReaEQ" "reaeq.dll"` loads the plugin but leaves all 19 param slots at zero — no EQ curve, no compression threshold. ReaScript already handles verify/render; it must also handle **built-in plugin insertion and parameter configuration** while RPPBuilder keeps generating VST3/MIDI/audio structure. ## Scope ### In Scope - New ReaScript actions: `add_track`, `add_fx`, `add_midi_item`, `configure_fx_params` - `ReaScriptCommand` dataclass extended with `plugins_to_add: list[PluginDef]`, `fx_params: list[dict]` - `ReaScriptGenerator` generates script blocks for `InsertTrackAtIndex`, `TrackFX_AddByName`, `CreateNewMIDIItemInProj`, `MIDI_InsertNote`, `TrackFX_SetParam` - `scripts/run_in_reaper.py` supports multi-action pipeline: skeleton → inject plugins → verify → render - `commands.py` decoupled: action dispatch mapping, `ReaScriptResult` gains `added_plugins: list[tuple[str, int]]` - RPPBuilder marks built-in plugins with `params` field; ReaScript reads these and applies via API ### Out of Scope - VST3 plugin insertion via ReaScript (RPPBuilder handles these) - ReaScript-based arrangement/track ordering (RPPBuilder remains source of truth) - OSC/HTTP-based REAPER control - Multi-DAW support ## Capabilities ### New Capabilities - `reascript-builtin-fx`: ReaScript generates code to insert built-in REAPER plugins with configured parameters via the native API, reading a `plugins_to_add` section from the command JSON. ### Modified Capabilities - `reascript-generator`: (existing) expands beyond verify/calibrate/render to support add_track, add_fx, add_midi_item, configure_fx_params actions with action dispatch. ## Approach **Hybrid pipeline**: RPPBuilder writes a skeleton `.rpp` with VST3 plugs + MIDI + audio. ReaScript then executes: 1. Open skeleton `.rpp` 2. Add tracks reserved for built-in plugins (`InsertTrackAtIndex`) 3. Insert FX by name (`TrackFX_AddByName("ReaEQ")`) 4. Configure params (`TrackFX_SetParam(track, fx_idx, param_idx, value)`) 5. Add MIDI items/notes for ReaScript-generated MIDI (if needed) 6. Verify all FX → calibrate volumes → render → measure LUFS `ReaScriptCommand.action` becomes an ordered list: `["add_plugins", "verify_fx", "calibrate", "render"]`. `ReaScriptGenerator._build_script()` dispatches per-action code blocks. ## Affected Areas | Area | Impact | Description | |------|--------|-------------| | `src/reaper_scripting/commands.py` | Modified | New action types + `plugins_to_add` field | | `src/reaper_scripting/__init__.py` | Modified | New script generation blocks for built-in FX | | `scripts/run_in_reaper.py` | Modified | Multi-action pipeline orchestration | | `src/reaper_builder/__init__.py` | Modified | Mark built-in plugins in RPP with params dict | | `tests/test_reaper_scripting.py` | Modified | New tests for add_fx/configure_fx_params | ## Risks | Risk | Likelihood | Mitigation | |------|------------|------------| | Built-in plugin API missing in REAPER version | Low | API check in generated script; fallback to text-only | | Param indices differ across REAPER versions | Medium | Pin known indices; version-detect at script startup | | Multi-action execution breaks existing tests | Medium | Extensible action dispatch; existing `"calibrate"` action preserved | ## Rollback Plan 1. Revert `commands.py` to single-action model (backward compat: `action: "calibrate"` still works) 2. Revert `_build_script()` to single-block generation 3. RPPBuilder changes are additive (new `params` field); no rollback needed 4. Existing 298 tests must remain green throughout ## Dependencies - REAPER v7+ with Python ReaScript - No new Python packages ## Success Criteria - [ ] `ReaScriptCommand(action="add_plugins")` generates valid Python that calls `TrackFX_AddByName` and `TrackFX_SetParam` - [ ] Built-in plugin (ReaEQ) loaded with correct params in generated `.rpp` verified by REAPER - [ ] Existing 298 tests pass unchanged - [ ] `scripts/run_in_reaper.py` runs multi-action pipeline end-to-end - [ ] Generated ReaScript handles missing API gracefully with `check_api()` guard