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

95 lines
9.9 KiB
Markdown

# 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.md` and `openspec/specs/audio-transport/spec.md` for 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 `### Requirement` and `#### 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 mv` every file from `packages/audio/audio-plugins-fx/src/{base,chain,registry}/` into `packages/audio-fx/audio-fx-plugin-base/src/` preserving directory structure
- [ ] 2.3 `git mv` `packages/audio/audio-plugins-fx/src/error-codes.{ts,md,test.ts}` into `packages/audio-fx/audio-fx-plugin-base/src/error-codes/`. Rename to `error-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 from `packages/audio-ir/audio-ir-core/` and adjust names.
- [ ] 2.6 Author root barrel `src/index.ts` — explicit named re-exports (rule 10). Drop every `export *` 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 with `rg "\.\./" packages/audio-fx/audio-fx-plugin-base/src`)
- [ ] 2.8 Add `tests/dep-graph.test.ts`: reads own `package.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.md` for `audio-fx-plugin-eq`. Deps: `@suaveplan/audio-fx-plugin-base` (workspace:^) + whatever non-plugin `@suaveplan/*` packages the moved eq code imports (enumerate via `rg "@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 any `export *` 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 as `scripts/split-audio-fx-plugin/template/*.template` for 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 the `game/` → `game-audio` rename).
- [ ] 4.2 Script steps:
1. Validate slug matches `/^[a-z][a-z0-9-]*$/`. Refuse if a folder already exists at `packages/audio-fx/audio-fx-plugin-<slug>/`.
2. Create `packages/audio-fx/audio-fx-plugin-<slug>/src/`.
3. Copy every `scripts/split-audio-fx-plugin/template/*.template` to the new package root, replacing `{PLUGIN_NAME}` markers with `<slug>`. Strip the `.template` suffix.
4. `git mv packages/audio/audio-plugins-fx/src/plugins/<source-dir>/* packages/audio-fx/audio-fx-plugin-<slug>/src/`.
5. Walk every `.ts` / `.tsx` / `.md` file inside the new `src/` 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).
6. 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).
7. Author `src/index.ts` root barrel with explicit named re-exports of the plugin's public surface.
- [ ] 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 dir `game`), `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 in `openspec/archive/` are immutable history; ignore.
- [ ] 5.3 Update `scripts/folder-reorg/assignment.yml`: remove `audio-plugins-fx`; add 25 entries mapping every new `audio-fx-plugin-*` package to the `audio` plugin slot.
- [ ] 5.4 Update `CLAUDE.md` § Packages — replace `audio-plugins-fx` listing with `audio-fx-plugin-base` + 24 per-plugin entries (alphabetical).
- [ ] 5.5 Update `STATUS.md` — replace the `@suaveplan/audio-plugins-fx` row with 25 ✅ rows; update `## Counts` (`Migrated` +24).
- [ ] 5.6 `bun scripts/folder-reorg/generate-manifest.ts` — regenerate `MANIFEST.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-base` and `@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; `expectTypeOf` assertions 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.ts` thrown 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>` — never `git 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 under `packages/react/`, `openspec/changes/add-react-auth-core/`, `openspec/changes/extend-react-ui-runtime-theme-mutation/`, or `bun.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 the `game/` → `game-audio` rename; 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 package` note 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.