# Lumi Companion

Lumi Companion is the Windows streaming-computer client for Lumi. It provides a
single paired-device shell for Companion plugins, including server-hosted
transcription and Song Overlay capture. The app is single-instance, installs per
Windows user, closes to the notification area, and preserves pairing and settings
across updates.

## Install and pair

From Lumi, open **Admin > Companion** and choose **Download Companion**. The
private ZIP contains:

- the checksum-pinned per-user Windows installer;
- a one-time `.lumi-pairing.json` package;
- a Host Operator notice and start instructions.

Extract the ZIP and run `Lumi.Companion-Setup.exe`. Setup installs to
`%LocalAppData%\Programs\Lumi Companion`, displays the licence and privacy
notices, identifies the paired Lumi host, imports the adjacent pairing package,
and opens the installed copy. The extracted download can then be deleted.

Existing portable or installed builds retain the current Windows user's
DPAPI-protected device identity, so reinstalling does not create a duplicate
paired device. Pairing packages expire after 15 minutes, work once, and must not
be shared or committed.

## Security boundaries

- Companion plugins inherit the shell's paired-device authentication. Plugins do
  not store or request separate Lumi credentials.
- Production Companion traffic requires HTTPS. Plain HTTP/WebSocket traffic is
  accepted only when the device was paired from the exact matching loopback Lumi
  origin and the request remains on loopback.
- The OBS integration communicates with Companion through a same-user named pipe.
- Transcription audio is normalized to 16 kHz mono signed 16-bit PCM, kept in
  bounded memory, and sent to the paired Lumi host. Companion does not perform
  local speech recognition.
- Installing or repairing the OBS integration requests elevation only while OBS
  is closed and only to copy the verified managed component into OBS's shared
  ProgramData plugin directory.

## Updates

Companion checks after connecting and every six hours. Updates are
user-approved, size- and checksum-verified, and refused while OBS is streaming or
recording. Applying an update replaces the installed executable, bundled
components, and legal bundle, then restarts Companion. Pairing credentials,
settings, and plugin state remain in the per-user data directory.

Localhost development builds can also receive checksum-addressed same-version
updates without publishing a release. See
[Localhost development updates](../docs/local-development-updates.md).

## Build and verify

Requirements:

- Windows x64;
- a current .NET SDK with the .NET 8 targeting pack;
- CMake and Visual Studio C++ tools for the native OBS bridge;
- Inno Setup 6 for the installer.

Build the managed solution:

```powershell
dotnet build companion/Lumi.Companion.sln -c Release -p:EnableWindowsTargeting=true
```

Build the pinned OBS bridge, self-contained archive, legal bundle, and installer:

```powershell
companion/scripts/publish-companion.ps1
```

The publish script generates the shared application/tray icon, verifies the OBS
payload inside the published executable, collects NuGet notices, and packages the
corresponding source for the GPL-licensed OBS bridge.

Run Song Overlay's focused verification with:

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

Generated installers, pairing packages, credentials, build output, and logs must
not be committed.

## Distribution and legal notices

The release is currently unsigned, so Windows may show an unknown-publisher
warning. The installer and installed `legal` directory include the Companion
licence, default privacy notice, third-party notices, exact licence texts, and
the corresponding OBS bridge source bundle.

Self-hosters should set `LUMI_OPERATOR_NAME`, `LUMI_OPERATOR_CONTACT`, and
`LUMI_OPERATOR_PRIVACY_URL`. Those values identify the Host Operator responsible
for its hosted service and server-side processing; OokamiKunTV is the software
developer and is not automatically the operator of an independently hosted Lumi
installation.
