feat: SDD workflow — test sync, song generation + validation, ReaScript hybrid pipeline

- compose-test-sync: fix 3 failing tests (NOTE_TO_MIDI, DrumLoopAnalyzer mock, section name)
- generate-song: CLI wrapper + RPP validator (6 structural checks) + 4 e2e tests
- reascript-hybrid: ReaScriptGenerator + command protocol + CLI + 16 unit tests
- 110/110 tests passing
- Full SDD cycle (propose→spec→design→tasks→apply→verify) for all 3 changes
This commit is contained in:
renato97
2026-05-03 22:00:26 -03:00
parent 7729d5f12f
commit 48bc271afc
25 changed files with 2842 additions and 343 deletions

View File

@@ -0,0 +1,36 @@
# Tasks: reascript-hybrid
## Phase 1: Foundation — Protocol Layer
- [x] 1.1 Create `src/reaper_scripting/commands.py` with `ReaScriptCommand` and `ReaScriptResult` dataclasses matching the JSON schemas in the spec
- [x] 1.2 Implement `write_command(path: Path, cmd: ReaScriptCommand) -> None` — serializes to JSON with `version: 1`
- [x] 1.3 Implement `read_result(path: Path) -> ReaScriptResult` — deserializes JSON; raises `ProtocolVersionError` if `version != 1`
- [x] 1.4 Add `ProtocolVersionError` exception class
## Phase 2: Core — ReaScript Generator
- [x] 2.1 Create `src/reaper_scripting/__init__.py` with `ReaScriptGenerator` class
- [x] 2.2 Implement `generate(path: Path, command: ReaScriptCommand) -> None` — writes a self-contained Python ReaScript
- [x] 2.3 The generated script must include hand-rolled JSON parser (~20 lines of string splitting) — no `import json`
- [x] 2.4 The generated script must call `GetFunctionMetadata` to verify API availability on startup
- [x] 2.5 The generated script must implement the full Phase 2 pipeline: open project → verify FX → calibrate tracks → render → measure LUFS → write result
- [x] 2.6 The generated script must handle errors and write `{"status": "error", "message": "..."}` on failure
- [x] 2.7 Write `tests/test_commands.py` — test JSON round-trip, version mismatch raises `ProtocolVersionError`
- [x] 2.8 Write `tests/test_reagenerator.py` — parse generated script with `ast.parse`, verify it contains required API calls (`Main_openProject`, `TrackFX_GetCount`, `TrackFX_GetFXName`, `SetMediaTrackInfo_Value`, `CreateTrackSend`, `Main_RenderFile`, `CalcMediaSrcLoudness`)
## Phase 3: Integration — CLI Orchestration
- [x] 3.1 Create `scripts/run_in_reaper.py` CLI entry point
- [x] 3.2 CLI must accept `python scripts/run_in_reaper.py <rpp_path> [--output <wav_path>] [--timeout <seconds>]`
- [x] 3.3 CLI generates ReaScript file to `REAPER ResourcePath()/scripts/fl_control_phase2.py`
- [x] 3.4 CLI writes command JSON to `REAPER ResourcePath()/scripts/fl_control_command.json`
- [x] 3.5 CLI polls for `fl_control_result.json` until it exists or timeout reached
- [x] 3.6 CLI parses result and prints LUFS metrics; exits 0 on success, 2 on timeout, 1 on error
- [x] 3.7 CLI writes `output/song_lufs.json` and `output/song_fx_errors.json` on success
## Phase 4: Integration Test (Manual)
- [ ] 4.1 Run `pytest tests/test_phase2.py -k integration` against live REAPER with registered custom Action — skipped in CI
- [ ] 4.2 Verify full pipeline: .rpp opens, FX verified, tracks calibrated, render completes, LUFS measured
- [ ] 4.3 Verify `fx_errors` correctly identifies a missing plugin slot (empty string from `TrackFX_GetFXName`)
- [ ] 4.4 Verify timeout exits with code 2 when REAPER is not running