diff options
| author | auric <auric@japegames.com> | 2026-02-22 21:36:39 -0600 |
|---|---|---|
| committer | auric <auric@japegames.com> | 2026-02-22 21:36:39 -0600 |
| commit | 551c8aece8f30f7495b8340e36fbabd5f49e4705 (patch) | |
| tree | 782a91b2a7820f1ff7b75ee18db05dff0ae5e7ca /AGENTS.md | |
| parent | 509019b2a95a4b768da31ba7990bb2dd3759ad4f (diff) | |
docs: document umbrella-bot in README and AGENTS
README gets a Matrix bot section covering setup, commands, config paths,
and dependencies. AGENTS gets the bot added to the file map and a full
Matrix bot section covering the formatting rules (markdown->HTML via the
markdown library, no emojis, no em dashes), power level requirements,
command/socket message mapping, tail data flow, and config layout.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'AGENTS.md')
| -rw-r--r-- | AGENTS.md | 82 |
1 files changed, 80 insertions, 2 deletions
@@ -63,8 +63,11 @@ src/ a2s.c/h Valve A2S_INFO UDP health probe with challenge handling. clients/ - umbrella-cli/main.c CLI client. JSON over Unix socket. Interactive - attach mode (epoll on socket + stdin). + umbrella-cli/main.c CLI client. JSON over Unix socket. Interactive + attach mode (epoll on socket + stdin). + umbrella-bot/umbrella-bot.py Matrix bot. Bridges a Matrix room to umbrella + units via the Unix socket. asyncio, matrix-nio + with E2E encryption. See "Matrix bot" section. filters/ source.py Source engine filter (TF2, GMod): strips server_cvar, @@ -130,6 +133,81 @@ Daemon → client responses: {"type":"status", "name":"tf2", "state":"running", "players":4, "max":24, "map":"cp_badlands"} ``` +## Matrix bot + +### Dependencies + +``` +matrix-nio[e2e] aiofiles markdown +``` + +### Response formatting rules — never break these + +Matrix messages are sent with `format: org.matrix.custom.html`. The +`body` field is plain text (client fallback). The `formatted_body` +field must be valid HTML — not raw Markdown. + +Always convert via: +```python +md_lib.markdown(reply, extensions=["fenced_code", "nl2br"]) +``` + +- `fenced_code` — renders triple-backtick code blocks as `<pre><code>` +- `nl2br` — converts `\n` to `<br>` so multi-line responses don't + collapse into one paragraph + +Never use `reply.replace("\n", "<br>")` or pass raw Markdown to +`formatted_body` — clients will display literal `**` and backticks. + +### Style rules for response strings + +- **No emojis** — use plain text (`Error:`, `Sent:`, etc.) +- **No em dashes** — use a hyphen-minus (`-`) + +This applies to all strings the bot sends to Matrix: command responses, +HELP_TEXT, error messages. + +### Power level + +Commands require power level >= 50 in the configured room. The check +runs in `get_user_power_level()` before dispatching any command. Users +below 50 get a plain error string and the command is not executed. + +### Commands and data flow + +| Command | Umbrella socket msg | Notes | +|---------|--------------------|----| +| `!units` | `{"cmd":"list"}` | Returns name, display, state, players, max_players per unit | +| `!status <unit>` | `{"cmd":"status","unit":"..."}` | Returns state, players, max_players, map | +| `!tail <unit>` | `{"cmd":"tail","unit":"..."}` | Returns full ring buffer (up to 500 lines); bot trims to last 30 | +| `!cmd <unit> <cmd>` | `{"cmd":"input","unit":"...","data":"...\n"}` | Logged to `/var/log/umbrella/bot-audit.log` | +| `!broadcast <msg>` | `{"cmd":"broadcast","message":"..."}` | Returns sent/failed counts | +| `!restart <unit>` | `{"cmd":"action","unit":"...","action":"restart"}` | | +| `!update <unit>` | `{"cmd":"action","unit":"...","action":"update"}` | | +| `!action <unit> <action>` | `{"cmd":"action","unit":"...","action":"..."}` | | + +### Tail flow (bot side) + +``` +!tail tf2 + -> umbrella.tail(unit) -> {"cmd":"tail","unit":"tf2"} over Unix socket + -> daemon responds {"type":"output","data":"line1\nline2\n...","history":true} + -> bot splits data into lines, trims to last TAIL_MAX_LINES (30) + -> wraps in triple-backtick block + -> sends with formatted_body via markdown conversion +``` + +### Config + +`/etc/umbrella/bot.conf` — homeserver, user_id, password, room_id, +device_id, store_path, socket_path. `chmod 600` required (contains +password). See `clients/umbrella-bot/bot.conf.example`. + +Encryption keys stored in SQLite at `store_path` +(default `/etc/umbrella/bot-store`). + +First-run: `umbrella-bot.py --setup` to login and obtain device ID. + ## YAML parser gotcha `unit.c` uses libyaml's event API with a hand-rolled state machine. |
