forked from unom/punktfunk
M4 of design/library-scanner-plugins-implementation-plan.md, plus WP6.2. WP4.1 — SourceToggles and ProvidersCard merge into Library/Sources.tsx. They were two cards because they were two different things: scanners were compiled into the host, plugins were an afterthought. After the extraction they are the same thing — the host reports ONE list of sources whose ids match whether they came from a built-in scanner or the plugin replacing it — so one surface is both simpler and the only honest presentation. Each row carries its toggle, a running/stopped badge for plugin sources, an entry count, filter, settings and an uninstall that offers to remove the games too. An "Add a source" rail lists uncatalogued library plugins with a "Detected" badge; `detected` is deliberately tri-state, so only a POSITIVE probe badges — an entry with no probes for this platform is unknown, and calling that "not installed" would be a lie. The settings drawer (SourceSettings.tsx) renders a generic form from the plugin's own JSON Schema over GET/PUT /__config, through the existing session-gated /plugin-ui/<id>/ proxy — zero new host surface, and the browser never learns the plugin's port or secret. It flattens allOf branches (effect nests a checked schema's annotations there, so a form reading only the top level silently loses every title and default) and falls back to a JSON editor when any field is a shape it cannot express — partial rendering would be worse than none, because a field missing from the form is a setting the operator cannot change. WP4.2 — uiPlugins() now excludes category "library", which covers both the sidebar and the mobile overflow since they share the selector. The /plugins/$pluginId/$ route still resolves, so existing deep links keep working; library plugins are just not advertised. WP4.3 — LibraryGrid groups role:"launcher" entries into a rail above the grid, and the empty state points at the sources surface rather than leaving a bare grid (after extraction, "no games" is the expected first-run state). WP6.2 — a migration banner offering one install per still-built-in scanner whose plugin is catalogued. One button per scanner, never a single "migrate everything" and never a silent auto-install: installing code stays an explicit operator act, and per-scanner is what makes it safe to repeat (the claim suppresses the built-in idempotently, so a half-finished migration is a valid state). WP4.4 — i18n en+de (kept under the existing "Game sources" label rather than minting a third "Plugins"), Storybook stories for the sources card in three states, the launcher rail and the banner. Gates: orval regen, tsc clean, vite build clean, check-i18n green at 595 messages for both locales. Still owed: the browser click-through (the store's Tabs-theme bug shipped through green types and lint), and an AppShell nav story — that one needs the plugins query mocked, which does not exist in this Storybook setup yet.