# Lumi Bot

Discord bot + WebUI with role-based access, plugin management, and self-update support.

## Quick start

Requires Node.js 18+ on Windows or Linux.

1. Install dependencies:
   ```
   npm install
   ```
   Do not use `--ignore-scripts`: Lumi uses the native `better-sqlite3` module,
   which must download or build a binary for your Node.js version. If Node was
   upgraded after installation, run `npm rebuild better-sqlite3` or remove
   `node_modules` and run `npm install` again. Linux source builds may also need
   Python and a C/C++ compiler toolchain.
2. Run with auto-restart:
   ```
   npm run run
   ```
3. Open `http://localhost:3000/setup` and enter your Discord app + bot settings.

Before starting Lumi, you can check the runtime and native dependency with
`npm run verify:preflight`. Run the complete syntax and focused test suite with
`npm run verify:all`; it stops at the first failure and prints the failing check.

## Logs

Administrators can review structured Core, plugin, platform, command, WebUI,
security, and integration activity under **Admin → Logs**. Logs support live
updates, component/activity filters, server-side search, redacted details,
request IDs, retention limits, and text or JSON Lines downloads. Plugin and
core logging conventions are documented in [`docs/logging.md`](docs/logging.md).

You can also seed local configuration with a `.env` file. Use `.env.example`
as the template; `.env` is ignored by git.

## Discord app setup

- OAuth2 redirect URI: `http://localhost:3000/auth/discord/callback`
- OAuth2 scopes: `identify`, `guilds`, `guilds.members.read`
- Add the bot to your server and copy the Guild ID.

## WebUI roles

The WebUI maps Discord roles to access levels:
- `DISCORD_ADMIN_ROLE_ID`
- `DISCORD_MOD_ROLE_ID`

You can set these in `.env` or change role IDs in **Admin → Settings**.

## Plugins

Use **Admin → Plugins** to install, enable, update, or uninstall plugins.
You can also create a local plugin from the WebUI.

Lumi Companion provides the streaming-computer boundary for transcription,
media capture, and private stream testing. Its trust boundaries and setup are documented in
[`docs/lumi-companion-transcription.md`](docs/lumi-companion-transcription.md).
Private OBS output testing, Lumi-managed MediaMTX setup, recovery behavior, and
network safety are documented in
[`docs/stream-testing.md`](docs/stream-testing.md).

## Updates and recovery

Use **Admin → Updates** for version-aware core and plugin updates. Lumi reads
repo metadata from `main` by default, can explicitly target the newest
`experimental-*` branch, creates snapshots before updates, blocks unsafe major
jumps without compatibility bridge metadata, and keeps advanced ZIP updates
hidden behind manual reveal controls. Snapshots store compressed rollback code
and a compressed database backup without duplicating AI models or other
preserved local data; age and per-target retention are configurable on the
Updates page.

Admins may also install or repair a specific core or plugin release. These
choices use immutable version tags and verify the selected version before files
are replaced. `npm start` and `npm run run` launch the update-aware wrapper,
which repairs required packages from the lockfile after a core update while
allowing unavailable optional integrations to remain disabled. On Windows the
wrapper invokes npm through the active Node installation, including Node.js 24,
so dependency repair does not rely on spawning a command script directly.

Recovery mode can be started with `LUMI_SAFE_MODE=1 npm run run`,
`node run.js --safe-mode`, or `data/recovery/safe-mode.flag`. See
[`docs/updates.md`](docs/updates.md) and
[`docs/recovery-mode.md`](docs/recovery-mode.md). Production can also be moved
between `main` and an exact `experimental-*` branch from **Admin > Updates**
with a verified pre-deployment snapshot, graceful restart, one-click return to
`main`, and emergency restore. See
[`docs/branch-deployments.md`](docs/branch-deployments.md).

## Twitch bot

Configure Twitch chat settings in **Admin → Settings**:

- `twitch_bot_username`
- `twitch_bot_oauth` (OAuth token)
- `twitch_channels` (comma-separated)

Custom commands can target any enabled chat platform from **Admin → Commands**.
Static commands send one template. Random Reply commands choose among weighted
messages and can optionally roll a number for conditions such as `<20` or
`>=10`; insert that roll with `{{core.command.rng}}`. Admin-only Dynamic commands
accept JavaScript or Python snippets that return a reply. Lumi wraps simple
snippets automatically while preserving explicit `run(ctx)` and module exports.
Previews use deterministic mock data and never send external network requests;
network calls, if intentionally used by an admin-authored command, occur only in
the real command runtime.

Admins can create reusable permission-aware `{{custom.*}}` text values under
**Admin → Settings → Reusable text values**.

## Users and linking

Users have an internal UUID and username. Link Twitch accounts in **Profile** and manage usernames in **Profile** or **Admin → Users**.

## Theming

Use **Admin → Theming** to select one of six read-only Lumi themes. Duplicate a
built-in or custom theme to edit colors, surfaces, controls, status colors,
focus states, radius, shadows, and spacing with a live light/dark preview.
Custom themes can be applied, renamed, duplicated, and deleted. Invalid or
incomplete values fall back safely to the selected built-in base theme.

Developer and modding conventions are documented in
[`docs/lumi-ui.md`](docs/lumi-ui.md).

## OBS overlays

Admins can create live, token-protected OBS Browser Sources under **Admin → OBS
overlays**, with server-controlled or fixed scenes and optional local OBS
WebSocket or zero-credential OBS Browser Bridge synchronization. Native sources
include a configurable combined Twitch, YouTube, and Discord chat overlay. See
[`docs/obs-overlays.md`](docs/obs-overlays.md).

## Notes

- Auto-update uses `git pull` from the configured remote + branch.
- Auto-restart uses `run.js` to respawn the process after updates or crashes.
