# reascript-builtin-fx Specification

Built-in REAPER plugin (ReaEQ, ReaComp, etc.) insertion and parameter configuration via ReaScript API, complementing RPPBuilder's VST3/MIDI/audio skeleton.

## Requirements

### Requirement: Insert Built-in FX via API
The ReaScript SHALL insert built-in REAPER plugins using `TrackFX_AddByName(fxname, instantiate=1)`, reading from command JSON's `plugins_to_add` list.

#### Scenario: Insert ReaEQ on target track
- GIVEN `plugins_to_add: [{"track_name": "Bass", "fx_name": "ReaEQ"}]`
- WHEN add_plugins action runs
- THEN `TrackFX_AddByName` is called on track "Bass" and the FX index is recorded in result

#### Scenario: Track not found
- GIVEN `plugins_to_add` references a non-existent track name
- WHEN insertion runs
- THEN an error with the track name is written to result; script continues to next plugin

### Requirement: Configure FX Parameters
The ReaScript SHALL call `TrackFX_SetParam(track, fx_idx, param_idx, value)` for each entry in a plugin's `params` dict.

#### Scenario: Set ReaEQ frequency and gain
- GIVEN ReaEQ at FX index 0 on "Bass" with `params: {"2": 200.0, "5": 3.0}`
- WHEN configure_fx_params runs
- THEN `SetParam(track, 0, 2, 200.0)` and `SetParam(track, 0, 5, 3.0)` are called

#### Scenario: Unknown param index
- GIVEN a params entry maps to a non-exposed index
- WHEN `TrackFX_SetParam` is called
- THEN the call proceeds (REAPER silently ignores invalid indices); no error raised

### Requirement: Post-Insertion Verification
After insertion, the ReaScript MUST verify the plugin loaded by calling `TrackFX_GetFXName`. A case-insensitive name match marks success; mismatch produces an error.

#### Scenario: Plugin loaded successfully
- GIVEN ReaEQ inserted at FX index 0
- WHEN verification runs
- THEN `GetFXName` returns "ReaEQ" (case-insensitive) and result marks it "ok"

#### Scenario: Plugin failed to load
- GIVEN insertion returned index -1 or name mismatch
- WHEN verification runs
- THEN result records `"failed to load ReaEQ on track Bass"`

### Requirement: Graceful API Degradation
The ReaScript SHALL check `TrackFX_AddByName`/`TrackFX_SetParam` availability at startup. If absent, it MUST exit with `{"status": "error"}` without attempting insertion.

#### Scenario: API functions missing
- GIVEN the REAPER version lacks `TrackFX_AddByName`
- WHEN `check_api()` runs
- THEN result is `{"status": "error", "message": "missing API: TrackFX_AddByName"}` and insertion is skipped

---
# Delta for reascript-generator

## ADDED Requirements

### Requirement: Multi-Action Dispatch
`ReaScriptCommand.action` SHALL accept an ordered string list. The generator MUST dispatch one script block per action in order. A string value like `"calibrate"` SHALL be treated as `["calibrate"]` for backward compat. Absent/empty SHALL default to `["calibrate"]`.

#### Scenario: Ordered pipeline
- GIVEN `action=["add_plugins", "verify_fx", "calibrate", "render"]`
- WHEN `_build_script()` runs
- THEN script contains insert → verify → calibrate → render blocks, each gated by its presence in the list

#### Scenario: String backward compat
- GIVEN `action="calibrate"`
- WHEN `_build_script()` runs
- THEN output matches current single-block behavior

### Requirement: Built-in FX Script Blocks
The generator SHALL produce code for `add_plugins` (iterates `plugins_to_add`, calls `TrackFX_AddByName`, verifies) and `configure_fx_params` (iterates same list, calls `TrackFX_SetParam`). Both SHALL be conditional on their action appearing in the list.

#### Scenario: Generate add_plugins + configure_fx_params
- GIVEN `plugins_to_add` with one ReaEQ entry + params, `action=["add_plugins", "configure_fx_params"]`
- WHEN script executes in REAPER
- THEN plugin is inserted then all specified params are configured

## MODIFIED Requirements

### Requirement: Extended Command/Result Schema
Command JSON SHALL include optional `plugins_to_add: [{"track_name": str, "fx_name": str, "params": {str: float}}]`. Result JSON SHALL include optional `added_plugins: [{"fx_name": str, "instance_id": int}]`.
(Previously: no plugin insertion fields.)

#### Scenario: plugins_to_add round-trip
- GIVEN command with `plugins_to_add=[{"track_name": "Bass", "fx_name": "ReaEQ", "params": {"2": 200.0}}]`
- WHEN script executes successfully
- THEN result includes `added_plugins: [{"fx_name": "ReaEQ", "instance_id": 0}]`

### Requirement: Adaptive API Check
`check_api()` SHALL require `TrackFX_AddByName`/`TrackFX_SetParam` when the action list includes `add_plugins` or `configure_fx_params`. For calibrate-only commands, the required set SHALL remain unchanged.
(Previously: required API set was static.)

#### Scenario: API check adapts
- GIVEN `action=["add_plugins"]`
- WHEN `check_api()` runs
- THEN `TrackFX_AddByName` and `TrackFX_SetParam` are required; absence produces error result
