# Song Overlay Companion integration

This integration adds a provider-neutral media event source to Lumi Companion. Spotify is the only available provider in this release, but the Companion protocol and runtime isolate provider-specific behavior behind `IMediaProvider`.

## Navigation contract

Every Companion plugin implements `ICompanionPluginContribution` and receives one nested root in both navigation surfaces:

- Tray menu: core actions, `Plugins`, one submenu per plugin, then health/update/log/settings controls and Quit.
- App sidebar: Overview, `PLUGINS`, one expandable root per plugin, then Connection, Logs, and Settings at the bottom.

Plugin actions are caught at the shell boundary so a routine plugin exception does not terminate Companion. The Song Overlay runtime also catches provider callbacks, transport failures, heartbeats, and initialization failures and reports an actionable plugin status.

## Song Overlay flow

1. Windows Global System Media Transport Controls exposes Spotify playback state.
2. The provider raises media, playback, timeline, and session-availability events.
3. The runtime sends only meaningful deltas to Lumi: track change, inferred next/previous, play, resume, pause, stop, seek, metadata enrichment, or a sparse recovery heartbeat.
4. Playback progress is projected from the last event. Continuous progress messages are not sent.
5. Cover art is resized and sent only with track metadata.
6. The existing Lumi `plugins/now_playing` endpoint updates the Song Overlay source and optional chat announcement.

## Build and verification

From the repository root on Windows:

```powershell
dotnet build companion/Lumi.Companion.sln -c Release -p:EnableWindowsTargeting=true
node plugins/now_playing/tests/verify.js
```

Or run:

```powershell
companion/scripts/verify-song-overlay.ps1
```

The optional Spotify Web API connection is used only for metadata enrichment such as exact links and release year. Core playback detection works through Windows without Spotify authorization.
