# 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
