9.9 KiB
Tasks — Split audio-plugins-fx into audio-fx-plugin-* per-plugin packages
Every checkbox MUST reflect work actually done in this change. Strategy: build a real foundation + one canonical plugin, then a scaffold script replicates the per-plugin shape across the remaining 23.
1. Spec authoring
- 1.1 Read
openspec/AGENTS.md§§ 13, 14, 14a, 2c, 6a, 7, 193 - 1.2 Read
openspec/specs/audio-core/spec.mdandopenspec/specs/audio-transport/spec.mdfor surrounding capability shape - 1.3
proposal.md(this change) — 25 packages enumerated,audio-fx-plugin-*naming - 1.4
specs/audio-plugins-fx/spec.md— 5 ADDED + 1 REMOVED requirements, each with**Verified by:** - 1.5 Working-notes checklist of every
### Requirementand#### Scenario
2. Phase A — Build audio-fx-plugin-base
- 2.1
mkdir -p packages/audio-fx/audio-fx-plugin-base/{src,tests} - 2.2
git mvevery file frompackages/audio/audio-plugins-fx/src/{base,chain,registry}/intopackages/audio-fx/audio-fx-plugin-base/src/preserving directory structure - 2.3
git mvpackages/audio/audio-plugins-fx/src/error-codes.{ts,md,test.ts}intopackages/audio-fx/audio-fx-plugin-base/src/error-codes/. Rename toerror-codes/error-codes.{ts,md,test.ts}so the feature-folder convention holds. - 2.4 Author
packages/audio-fx/audio-fx-plugin-base/package.json—version: 0.1.0,sideEffects: false, deps@suaveplan/{audio-core, audio-transport, error, events, opentelemetry, schema-registry, types}+tslib+zod(all from catalog/workspace). Zero@suaveplan/audio-fx-plugin-*deps. Subpath exports:.,./base,./chain,./registry,./error-codes.files: ["dist", "README.md"]. - 2.5 Author
tsconfig.json,tsconfig.lib.json,vite.config.ts(multi-entry,preserveModules: true),vitest.config.ts,README.md. Copy frompackages/audio-ir/audio-ir-core/and adjust names. - 2.6 Author root barrel
src/index.ts— explicit named re-exports (rule 10). Drop everyexport *from sub-barrels in the moved code; convert to named re-exports. - 2.7 Rewrite internal imports inside moved files:
from "../base"→from "./base", etc. (verify withrg "\.\./" packages/audio-fx/audio-fx-plugin-base/src) - 2.8 Add
tests/dep-graph.test.ts: reads ownpackage.json, asserts zero@suaveplan/audio-fx-plugin-*deps (including self). - 2.9 Run
bun install && bunx turbo lint typecheck test build --filter=@suaveplan/audio-fx-plugin-base. Must reach 100/100/100/100.
3. Phase B — Build audio-fx-plugin-eq as the canonical template
- 3.1
mkdir -p packages/audio-fx/audio-fx-plugin-eq/src - 3.2
git mv packages/audio/audio-plugins-fx/src/plugins/eq/* packages/audio-fx/audio-fx-plugin-eq/src/ - 3.3 Author
package.json,tsconfig.json,tsconfig.lib.json,vite.config.ts,vitest.config.ts,README.mdforaudio-fx-plugin-eq. Deps:@suaveplan/audio-fx-plugin-base(workspace:^) + whatever non-plugin@suaveplan/*packages the moved eq code imports (enumerate viarg "@suaveplan/" packages/audio-fx/audio-fx-plugin-eq/src). - 3.4 Rewrite eq imports:
from "../../base"→from "@suaveplan/audio-fx-plugin-base/base",from "../../chain"→from "@suaveplan/audio-fx-plugin-base/chain", etc. - 3.5 Root barrel
src/index.ts— explicit named re-exports; convert anyexport *to named. - 3.6
bunx turbo lint typecheck test build --filter=@suaveplan/audio-fx-plugin-eq— green at 100/100/100/100. - 3.7 Designate
audio-fx-plugin-eq's config files (package.json,tsconfig.*,vite.config.ts,vitest.config.ts,README.md) as the canonical per-plugin template. Save the rendered versions with{PLUGIN_NAME}markers re-introduced asscripts/split-audio-fx-plugin/template/*.templatefor the scaffold script to consume.
4. Phase C — Scaffold script + replicate across 23 remaining plugins
- 4.1 Author
scripts/split-audio-fx-plugin/scaffold.ts(Bun-runnable TypeScript). Arguments:--name <slug>(e.g.compressor),--source-dir <name>(defaults to<slug>; used for thegame/→game-audiorename). - 4.2 Script steps:
- Validate slug matches
/^[a-z][a-z0-9-]*$/. Refuse if a folder already exists atpackages/audio-fx/audio-fx-plugin-<slug>/. - Create
packages/audio-fx/audio-fx-plugin-<slug>/src/. - Copy every
scripts/split-audio-fx-plugin/template/*.templateto the new package root, replacing{PLUGIN_NAME}markers with<slug>. Strip the.templatesuffix. git mv packages/audio/audio-plugins-fx/src/plugins/<source-dir>/* packages/audio-fx/audio-fx-plugin-<slug>/src/.- Walk every
.ts/.tsx/.mdfile inside the newsrc/and rewrite relative imports:../../base→@suaveplan/audio-fx-plugin-base/base,../../chain→@suaveplan/audio-fx-plugin-base/chain,../../registry→@suaveplan/audio-fx-plugin-base/registry,../../error-codes→@suaveplan/audio-fx-plugin-base/error-codes. Also rewrite cross-plugin imports if any (../<other-plugin>should not exist; abort with an error if found). - Convert every
export *in the new package's barrels to explicit named re-exports (read the source's actual exports via a minimal AST walk or fallback to grep + manual fix-list). - Author
src/index.tsroot barrel with explicit named re-exports of the plugin's public surface.
- Validate slug matches
- 4.3 Run the script for each of the 23 remaining plugins, in alphabetical order:
audio-analyzer,audio-player,auto-filter,chorus,compressor,delay,distortion,filter,flanger,game-audio(source dirgame),gate,glados,limiter,microphone,mixer,phaser,pitch-shifter,reverb,sampler,spatial,synthesizer,tremolo,widener. - 4.4 After every 5 plugins, run
bunx turbo lint typecheck test --filter='@suaveplan/audio-fx-plugin-*'to catch regressions early.
5. Phase D — Repo plumbing
- 5.1 Delete
packages/audio/audio-plugins-fx/(git rm -rf). - 5.2
rg "@suaveplan/audio-plugins-fx" packages/ apps/ scripts/ docs/ openspec/changes/ openspec/specs/— zero hits. Hits inopenspec/archive/are immutable history; ignore. - 5.3 Update
scripts/folder-reorg/assignment.yml: removeaudio-plugins-fx; add 25 entries mapping every newaudio-fx-plugin-*package to theaudioplugin slot. - 5.4 Update
CLAUDE.md§ Packages — replaceaudio-plugins-fxlisting withaudio-fx-plugin-base+ 24 per-plugin entries (alphabetical). - 5.5 Update
STATUS.md— replace the@suaveplan/audio-plugins-fxrow with 25 ✅ rows; update## Counts(Migrated+24). - 5.6
bun scripts/folder-reorg/generate-manifest.ts— regenerateMANIFEST.md.
6. Phase E — Final verification (5-gate triple across the family)
- 6.1
bun run check— Biome 0/0/0/0 monorepo-wide - 6.2
bunx turbo lint typecheck test --filter='@suaveplan/audio-fx-plugin-*'— green across all 25 - 6.3
bunx turbo test:coverage --filter='@suaveplan/audio-fx-plugin-*'— 100/100/100/100 on every package - 6.4
bunx turbo build --filter='@suaveplan/audio-fx-plugin-*'— green - 6.5
bun scripts/openspec-conformance.ts @suaveplan/audio-fx-plugin-baseand@suaveplan/audio-fx-plugin-eq— both PASS - 6.6
bunx turbo build(whole monorepo) — green; no downstream consumer breakage - 6.7
test ! -d packages/audio/audio-plugins-fx— exit 0 - 6.8
rg "@suaveplan/audio-plugins-fx" packages/ apps/ scripts/ docs/ openspec/changes/ openspec/specs/— zero hits
7. Phase F — 7-row checklist (AGENTS §13)
- 7.1 Generics threaded;
expectTypeOfassertions preserved on every literal-type claim - 7.2 Zod schemas wired at every declared boundary — preserved by move
- 7.3 Every error code in each
error-codes.tsthrown by at least one production path - 7.4 Strict-mode behaviors tested both on and off — preserved
- 7.5 OTel instruments asserted with a real in-memory
MeterProvider— preserved - 7.6 Lifecycle dedup tests preserved (in-flight Promise, idempotent set/load)
- 7.7 No retroactive tick — every box reflects work done in this change
8. Phase G — Archive + commit
Commit strategy: 3 commits scoped narrowly via explicit
git add <path>— nevergit add -A. Touch ONLY these path families:packages/audio-fx/audio-fx-plugin-*,packages/audio/audio-plugins-fx(deletion),scripts/split-audio-fx-plugin/,openspec/changes/split-audio-plugins-fx/,openspec/archive/2026-05-19-split-audio-plugins-fx/,openspec/specs/audio-plugins-fx/,STATUS.md,CLAUDE.md,scripts/folder-reorg/assignment.yml,MANIFEST.md. DO NOT touch any file underpackages/react/,openspec/changes/add-react-auth-core/,openspec/changes/extend-react-ui-runtime-theme-mutation/, orbun.lock— those belong to unrelated in-flight work.
- 8.1 Commit 1:
feat(audio-fx): extract audio-fx-plugin-base from audio-plugins-fx. Body: base package shipped; eq shipped as the canonical template; scaffold script committed. - 8.2 Commit 2:
feat(audio-fx): split 23 remaining FX plugins into audio-fx-plugin-* packages. Body: lists every new package; notes thegame/→game-audiorename; references Commit 1. - 8.3 Fold spec delta into NEW
openspec/specs/audio-plugins-fx/spec.md. The 5 ADDED requirements become the body; the REMOVED requirement is appended as a## Historical: bundled packagenote with a pointer to the archive. - 8.4
git mv openspec/changes/split-audio-plugins-fx openspec/archive/2026-05-19-split-audio-plugins-fx. - 8.5 Commit 3:
chore(audio-fx): delete audio-plugins-fx + archive split-audio-plugins-fx + refresh root docs. Body: cites the deletion of the old folder, the STATUS / CLAUDE / MANIFEST / assignment.yml updates, and the archive move. - 8.6 Every commit message ends with the standard trailer:
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> - 8.7 DO NOT push.