Files
2026-05-27 23:29:53 +01:00

8.6 KiB
Raw Permalink Blame History

Split audio-plugins-fx into audio-fx-plugin-* per-plugin packages

Package: @suaveplan/audio-fx-plugin-* (new), @suaveplan/audio-fx-plugin-base (new), @suaveplan/audio-plugins-fx (removed) Status: PROPOSED Type: refactor

Why

audio-plugins-fx currently bundles the contract, PluginChain, PluginRegistry, ChainSnapshot, and 24 concrete plugins into a single package. Subpath exports give bundlers tree-shaking, but consumers still pay the full peer-dep surface, every plugin advances on the same version, and the dep graph in MANIFEST.md cannot distinguish a chain consumer from a reverb consumer.

Every other plugin family in the repo is split per-plugin: network-plugin-*, drive-plugin-chunks, i18n-formatter-*, i18n-backend-*, the recently-shipped audio-ir-{family}-plugin-<name>. Audio FX is the outlier. Splitting now — while still at 0.1.0 and before downstream consumers (audio-engine-browser, react-audio) wire against it — avoids a much larger rename later and matches the established convention.

Naming

The new family uses the audio-fx-plugin-* prefix (fx is the family marker, distinguishing this from future audio-ir-*, audio-synth-*, etc. plugin families):

  • @suaveplan/audio-fx-plugin-base — foundation (contract + chain + registry + error codes).
  • @suaveplan/audio-fx-plugin-<name> — one package per concrete FX plugin.

What changes

Foundation (1 package)

  • ADDED: @suaveplan/audio-fx-plugin-base — AudioFxPlugin contract, AbstractAudioFxPlugin, PluginChain, ChainContext, AmbientState, BusRegistry, PluginRegistry, ChainSnapshot, ChainEventBus, ParameterSchedule, PresetSnapshot, shared AUDIO_PLUGIN.* error-code registry. Universal-tier; consumes @suaveplan/{audio-core, audio-transport, error, events, opentelemetry, schema-registry, types} but has zero @suaveplan/audio-fx-plugin-* deps. Owns every file in the current audio-plugins-fx/src/{base,chain,registry}/ trees plus the root error-codes.ts.

Per-plugin packages (24 packages)

Each new package owns one folder from audio-plugins-fx/src/plugins/<source-dir>/ verbatim — no DSP, parameter, or error-code changes.

New package Source dir One-line description
audio-fx-plugin-audio-analyzer audio-analyzer/ tap-point FFT analyser
audio-fx-plugin-audio-player audio-player/ playback source plugin
audio-fx-plugin-auto-filter auto-filter/ LFO-driven filter
audio-fx-plugin-chorus chorus/ modulated comb / multi-voice chorus
audio-fx-plugin-compressor compressor/ feed-forward compressor with sidechain input
audio-fx-plugin-delay delay/ stereo delay with ping-pong + BPM sync
audio-fx-plugin-distortion distortion/ waveshaping + soft/hard clip
audio-fx-plugin-eq eq/ parametric / shelving / high-pass / low-pass EQ
audio-fx-plugin-filter filter/ biquad / IIR / state-variable
audio-fx-plugin-flanger flanger/ short-delay modulated comb
audio-fx-plugin-game-audio game/ game-audio orchestration plugin (impl filename is game-audio.ts)
audio-fx-plugin-gate gate/ noise gate with hold + linked envelope
audio-fx-plugin-glados glados/ pitch-tracked vocal-style effect
audio-fx-plugin-limiter limiter/ look-ahead brick-wall limiter
audio-fx-plugin-microphone microphone/ source plugin simulating mic colour
audio-fx-plugin-mixer mixer/ bus mixer with per-channel sends
audio-fx-plugin-phaser phaser/ all-pass-bank phaser
audio-fx-plugin-pitch-shifter pitch-shifter/ phase-vocoder pitch shift
audio-fx-plugin-reverb reverb/ engine-pluggable reverb (FDN, Schroeder, convolution)
audio-fx-plugin-sampler sampler/ sample-playback source
audio-fx-plugin-spatial spatial/ HRTF-based spatial panner
audio-fx-plugin-synthesizer synthesizer/ polyphonic subtractive synth
audio-fx-plugin-tremolo tremolo/ amplitude-modulated tremolo
audio-fx-plugin-widener widener/ stereo width / mid-side processor

Scaffold script (one new tooling file)

  • ADDED: scripts/split-audio-fx-plugin/scaffold.ts — reusable helper that takes a plugin slug (eq, reverb, …) plus the source dir name, copies a per-plugin template (config files), git mvs the source folder, and rewrites imports. The script is committed alongside the split so the same scaffold can be reused for future audio-fx-plugin-* additions.

Removals + repo plumbing

  • REMOVED: @suaveplan/audio-plugins-fx — superseded. Package is at 0.1.0, never published to Verdaccio. Folder packages/audio/audio-plugins-fx/ is deleted after the moves.
  • MODIFIED: MANIFEST.md — refreshed via bun scripts/folder-reorg/generate-manifest.ts.
  • MODIFIED: STATUS.md — replace the single audio-plugins-fx ✅ row with 25 new ✅ rows (1 base + 24 per-plugin). Net Migrated count delta: +24.
  • MODIFIED: CLAUDE.md § Packages (audio family subsection) — replace the bundled listing with the per-plugin enumeration.
  • MODIFIED: scripts/folder-reorg/assignment.yml — every new audio-fx-plugin-* package maps to the audio plugin slot; remove the audio-plugins-fx entry.

Out of scope

  • New plugins beyond what audio-plugins-fx already ships — additions land as their own packages directly under the new layout.
  • React / R3F bindings for plugins — remain in react-audio-* packages, untouched.
  • Engine-pluggable backends (e.g. a future audio-fx-plugin-reverb-convolution) — possible future split, not in this change.
  • Changing any plugin's runtime behavior, DSP, parameter surface, or error codes. This is a pure relocation + dep-graph refactor.

Source mapping

Genesis-original — no enterprise/audio-plugins-fx.md exists. Section retained as a pointer to the in-tree source.

Requirement Source path Notes
base contract + chain + registry surface packages/audio/audio-plugins-fx/src/{base,chain,registry}/ Moves verbatim into audio-fx-plugin-base
each concrete plugin packages/audio/audio-plugins-fx/src/plugins/<source-dir>/ Moves verbatim into audio-fx-plugin-<slug> per the table above
shared error codes packages/audio/audio-plugins-fx/src/error-codes.ts Moves into audio-fx-plugin-base/src/error-codes/; concrete plugins import codes from @suaveplan/audio-fx-plugin-base/error-codes

Requirements with no source line

Requirement Justification
per-package independent versioning New constraint introduced by the split; each plugin can graduate to 1.0.0 on its own cadence
audio-fx-plugin-base cannot depend on any audio-fx-plugin-<name> Prevents cycles in the dep graph that the bundled package masked
scaffold script committed to scripts/split-audio-fx-plugin/ Future additions to the FX family use the same template — keeps shape consistent across plugins

Verification approach

  • Per-plugin: each new package keeps its existing test suite intact under the new path. bunx turbo test --filter=@suaveplan/audio-fx-plugin-<name> green at 100/100/100/100 for every plugin.
  • audio-fx-plugin-base/tests/dep-graph.test.ts — asserts the package has zero @suaveplan/audio-fx-plugin-* deps (other than its own name, which would be a self-dep and is also rejected).
  • scripts/folder-reorg/generate-manifest.ts after the split — MANIFEST.md diff shows 25 new packages and no orphaned audio-plugins-fx entry.
  • rg "@suaveplan/audio-plugins-fx" packages/ apps/ scripts/ docs/ openspec/changes/ openspec/specs/ — zero hits after the migration commit (archive is allowed).
  • bunx turbo build whole monorepo — green; catches any missed import rewrite.

Migration impact

  • In-monorepo consumers: rg "@suaveplan/audio-plugins-fx" packages/ apps/ returns hits only inside the package itself (no downstream package has wired it up yet — audio-engine-browser and react-audio are still – in STATUS.md). The split lands before first consumer.
  • External consumers: none — package is 0.1.0 and was never published to Verdaccio.

Impact

Affected dependents

Run bunx turbo ls --filter=...@suaveplan/audio-plugins-fx to enumerate. At proposal time, the only dependent is audio-plugins-fx's own test suite — no other live package imports it. The placeholder audio-engine-browser is still status – (not yet ported) and will compose against audio-fx-plugin-* directly when it lands.

  • No live dependents (verified by bunx turbo ls --filter=...@suaveplan/audio-plugins-fx).