# Commands, access, and limits

Admins configure shared command rules at **Admin → Command access**. Moderators
continue to create and edit custom replies at **Custom commands**.

The protected **All commands (defaults)** group applies implicitly to every
command and cannot be deleted. Administrators can leave each category on
**Keep command built-ins**, explicitly remove that category globally, or define
a new global value. Additional groups remain assignable to selected commands.

## Built-in stream commands

- `!clip [optional label]` requests a clip on the platform that delivered the
  command and saves the replay buffer through the first operational OBS
  connector. Twitch supports clip creation; platforms without a clip API report
  that part as unavailable without preventing the OBS replay save.
- `!raid <channel>` starts a supported platform raid. `!raid cancel` cancels a
  pending raid. Twitch shows its normal confirmation/countdown after Lumi starts
  the raid.

Twitch clip creation needs `clips:edit`; raids need
`channel:manage:raids`. Follower, subscriber-tier, and editor requirements need
`moderator:read:followers`, `channel:read:subscriptions`, and
`channel:read:editors` respectively. The configured user token must represent
the broadcaster, or an eligible moderator where Twitch permits it. Lumi reports
a verification problem instead of silently allowing a user when a required
scope is missing.

Twitch does not expose a clip-title field in Create Clip, and OBS replay-save
bindings do not accept a filename. Lumi therefore records and repeats the
optional label for operator context but does not claim that either provider used
it as the saved title.

The local OBS WebSocket connector calls `SaveReplayBuffer`. The OBS Browser
Bridge calls OBS Browser Source's `window.obsstudio.saveReplayBuffer()` and
requires **Basic access to OBS** (level 3) or higher. The replay buffer must
already be running. A platform or OBS failure is reported independently, so one
failure does not hide a successful action from the other system.

## Conditional custom replies

Choose **Conditional Reply** for a custom command, then add keyword/reply pairs.
For example, a `rules` command can answer `!rules backseating` and
`!rules spoilers` differently. The optional main response is shown for `!rules`
without an argument; if it is empty, Lumi lists the available keywords.

Separate keywords with commas when several aliases should return the same
reply. For example, `backseat, backseating, hints` can share one rules response.

Exact keyword matches always win. Optional fuzzy matching accepts only a clear,
close typo and refuses ambiguous or unrelated text. Reply templates use the
same shared placeholder validation and rendering as static custom commands.

## Groups and command overrides

A command can belong to several groups. Every assigned group rate limit and
role requirement applies. The highest group currency cost is used, so assigning
two priced groups does not charge twice. Group rate limits form a shared pool
across commands in that group.

Each command category has three choices:

- **Use group/default** inherits groups, or the command's conservative built-in
  default when no group supplies that category.
- **No limit / Everyone / Free** explicitly disables inherited values for that
  category.
- **Set** replaces inherited values for that category on this command.

When **Use groups/default** is selected, the editable child fields are hidden and
the effective inherited value is shown read-only. Changing assigned groups
updates that summary immediately. Command settings use one page-wide save action,
so edits to collapsed or filtered commands are submitted atomically instead of
being lost when another command is saved.

Group and command lists provide fuzzy search suggestions and live setting
filters. Non-matches are hidden while searching. Command sources use friendly
labels such as **Built-in command**, **Custom command**, or the plugin's display
name rather than internal registry identifiers.

Time-window limits support a shared global pool or one pool per Lumi user.
Per-stream limits also support global or per-user counting. Stream identities
are persisted, and a new provider stream that appears within two hours reuses
the previous session so a crash and troubleshooting restart cannot reset the
allowance.

Role requirements are evaluated from live platform roles first. Twitch performs
a scoped API check when follower status, subscriber tier, or editor status is
not available in chat metadata. YouTube uses owner, moderator, and member data
provided with live chat. Discord uses server ownership, permissions, and common
VIP/subscriber role names. A requirement that cannot be reliably verified is
denied with an actionable message.

Currency costs reuse the Economy Framework. A successful admission creates a
normal `spend` transaction with command metadata. If the command handler declines
or fails, Lumi releases the rate-limit reservation and writes a matching refund
transaction. If Economy is disabled, a priced command is denied rather than run
for free.
