From 05be9ebdbe5f77310178772089655dab8f415246 Mon Sep 17 00:00:00 2001 From: Joe Hallahan Date: Sun, 19 Jul 2026 05:27:52 -0400 Subject: [PATCH] Add new chart-transform plugin capability (#1000) * Chart-transform plugin capability * PR comments * Cleanup * Fix markdown * CodeRabbit feedback Signed-off-by: Joe --------- Signed-off-by: Joe Co-authored-by: Byron Gamatos --- CHANGELOG.md | 8 + CLAUDE.md | 8 + docs/capability-domains.md | 15 +- docs/capability-recipes.md | 51 +++ docs/capability-roadmap.md | 4 + docs/capability-safety-matrix.md | 2 +- plugins/capability_inspector/screen.js | 5 +- plugins/highway_3d/CLAUDE.md | 2 +- plugins/highway_3d/plugin.json | 2 +- plugins/highway_3d/screen.js | 26 +- static/capabilities.js | 3 +- static/capabilities/chart-transform.js | 336 ++++++++++++++++++ static/highway.js | 209 ++++++++++-- static/js/highway-draw.js | 31 +- static/v3/index.html | 1 + tests/js/chart_transform_domain.test.js | 335 ++++++++++++++++++ tests/js/highway_chart_transform.test.js | 355 ++++++++++++++++++++ tests/js/highway_chord_render_cache.test.js | 6 +- 18 files changed, 1345 insertions(+), 54 deletions(-) create mode 100644 static/capabilities/chart-transform.js create mode 100644 tests/js/chart_transform_domain.test.js create mode 100644 tests/js/highway_chart_transform.test.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f8ccfb..84e8771 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added +- **`chart-transform` capability domain (#952)** — plugins can now remap the + chart before rendering and scoring through a core-owned provider + coordinator. Synchronous transforms run after difficulty filtering; host + data is isolated from providers, accepted timelines are time-sorted, and + failures fall back to the original chart with a fixed public reason. + Effective chart arrays and metadata are available to 2D/custom renderers + and highway getters, while `getSongInfo()` retains the original metadata. + Provider selection persists and applies to primary and splitscreen highways. - **Library filter: one-click "Not split" + a piano stem pill.** The v3 Filters drawer's stems section gains a **Not split** shortcut that selects "lacks every instrument stem" in one tap — the same query Stem Splitter's missing-stems view runs — instead of diff --git a/CLAUDE.md b/CLAUDE.md index 0cf042e..1084f4e 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -400,6 +400,14 @@ highway.setNoteStateProvider((note, chartTime) => { - The built-in 2D highway consults it in `drawNote` / `drawSustains` / the chord-frame path: 'hit'/'active' → bright string colour + additive halo + a contained "sizzle" (crackling sparks, throbbing core, a shockwave ring on a fresh strike) on the gem and a bright (vs dim) sustain trail; 'miss' → faint red wash. The bundled **3D highway** reads the same data via `bundle.getNoteState` (bright string-tinted outline + bright body + glowing sustain + a contained sparkle hugging the note rect on hit/active; red outline + suppressed body on miss). Custom renderers that want it call `bundle.getNoteState(note, chartTime)` — it null-guards and returns the normalized `{ state, alpha, color }` (or null). - This is orthogonal to the overlay contract: note_detect remains an overlay (HUD, diagnostic miss markers, the "currently detected" indicator) *and* a scorer that feeds this provider. A renderer that ignores `getNoteState` simply doesn't light gems — nothing breaks. +#### 4. Chart-transform provider — remap the chart before rendering AND scoring (feedBack#952) + +The core-owned `chart-transform` provider coordinator applies synchronous chart substitutions after difficulty filtering. Register and select providers through the capability domain; it owns persistence, refresh, splitscreen propagation, failure attribution, and diagnostics. + +Provider inputs and staged outputs are isolated copies. Async returns or provider errors fail back to the original chart and expose only a fixed public failure reason. `getSongInfo()` remains the original chart contract; transform-aware consumers use the renderer bundle or `getStringCount()`, `getTuning()`, `getCapo()`, and `getCentOffset()`. + +See [docs/capability-recipes.md](docs/capability-recipes.md#chart-transform-provider) for the manifest and registration example. + ### Audio mixer fader registration (feedBack#87) Plugins that produce audio outside the song's `