refactor(ui): load the capabilities as ES modules (R3a) (#875)
ship-ci / ci (push) Waiting to run

The 12 capability <script> tags become type="module". No JS changes — the
capability scripts already self-register on the window.feedBack bus,
version-negotiate (`capabilities.version !== 1` → bail), and self-guard for
idempotency. They never import or call app.js; it is pure pub/sub.

Verified they export nothing by name: no top-level declaration in
capabilities.js or capabilities/*.js is read by any other script, so losing
global scope costs nothing.

This is the first REAL exercise of the ordering fix from #872. A module defers to
after HTML parse, so the capabilities now execute AFTER the document is parsed —
while app.js still calls `window.feedBack.on(...)` at its top level. That only
works because #872 put every classic script into the same deferred queue, where
document order IS execution order: capabilities.js (line 122) still runs before
app.js (line 1237). Had app.js stayed a plain classic script it would have run
during parse, hit a bare `{}`, and died on `.on is not a function`.

A/B against origin/main, 11 probes — capabilities.version, registered
participants (37), compatibility shims (14), the bus, workingTuning, theme,
setViz/showScreen/playSong, mounted plugin screens: IDENTICAL, zero console/page
errors on both. 12 module tags served and executed; pytest 2396, node 1032/1032,
ESLint 0, Codex 0.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Byron Gamatos
2026-07-11 17:15:38 +02:00
committed by GitHub
co-authored by Claude Opus 4.8
parent ff7e855e35
commit c223ace419
+12 -12
View File
@@ -119,19 +119,19 @@
script logs anything; load it as early as possible. See
docs/diagnostics-bundle-spec.md (feedBack#166). -->
<script defer src="/static/diagnostics.js"></script>
<script defer src="/static/capabilities.js"></script>
<script defer src="/static/capabilities/library.js"></script>
<script defer src="/static/capabilities/tuning.js"></script>
<script defer src="/static/capabilities/working-tuning.js"></script>
<script defer src="/static/capabilities/audio-session.js"></script>
<script defer src="/static/capabilities/audio-effects.js"></script>
<script defer src="/static/capabilities/playback.js"></script>
<script type="module" src="/static/capabilities.js"></script>
<script type="module" src="/static/capabilities/library.js"></script>
<script type="module" src="/static/capabilities/tuning.js"></script>
<script type="module" src="/static/capabilities/working-tuning.js"></script>
<script type="module" src="/static/capabilities/audio-session.js"></script>
<script type="module" src="/static/capabilities/audio-effects.js"></script>
<script type="module" src="/static/capabilities/playback.js"></script>
<!-- fee[dB]ack v0.3.0: ui.library-card-injection capability (plugin card actions). -->
<script defer src="/static/capabilities/library-card-actions.js"></script>
<script defer src="/static/capabilities/visualization.js"></script>
<script defer src="/static/capabilities/note-detection.js"></script>
<script defer src="/static/capabilities/midi-input.js"></script>
<script defer src="/static/capabilities/interface-scale.js"></script>
<script type="module" src="/static/capabilities/library-card-actions.js"></script>
<script type="module" src="/static/capabilities/visualization.js"></script>
<script type="module" src="/static/capabilities/note-detection.js"></script>
<script type="module" src="/static/capabilities/midi-input.js"></script>
<script type="module" src="/static/capabilities/interface-scale.js"></script>
</head>
<body class="h-screen flex overflow-hidden bg-fb-sidebar text-fb-text font-display">