Theme

Theteia

The Discord ocbot

Remote-control a local opencode coding agent from Discord. Send a prompt from your phone, get one report, then press Accept, Follow up, or Park & redo.

Theteia (ocbot) is a Rust Discord bot that puts a local opencode coding agent behind chat buttons. You work on your machine; the agent runs in a directory you choose; every run comes back to you as one report with an outcome — Completed, Errored, Aborted, or Empty — and a decision to make. The bot is built for a single operator: one allowlisted user per surface, a guard in front of every interaction, and no multi-tenant anything.

Under the hood it is deliberately boring machinery: at most one active action per directory (a per-directory lock), every state change is a compare-and-swap transition so duplicate button presses lose, and Accept, Park & redo, and Reset survive a SIGKILL at any point — boot reconcile recovers from database facts, not memory. Discord and Signal are both supported as surfaces.

# Install

Build from source — Linux host, Rust 1.98.1 (pinned via rust-toolchain.toml, fetched automatically), and an opencode server v2 on loopback:

Clone and build

git clone https://github.com/lexbity/theteia-discord-ocbot.git
cd theteia-discord-ocbot
cargo build --release

Then follow the full setup guide (bot token, opencode server, first run) or the production install (systemd units, secrets, backups).

# Try it

  1. Create the Discord bot

    Create an application in the Discord developer portal, copy the token (DISCORD_TOKEN), enable the Message Content intent, and invite it to a private server you own. Copy your own user ID — that is ALLOWED_USER_ID.
  2. Start the opencode server

    opencode serve on loopback with a password — the bot refuses v1 servers and probes the pin at startup.
  3. Configure and run

    cp config/config.toml.example config/config.toml, point it at your working directory, export DISCORD_TOKEN and ALLOWED_USER_ID, then run from the repository root: cargo run --release. DM the bot a prompt and wait for the report.

The full walkthrough, including the Signal surface and troubleshooting, is in Getting started .

# What it offers

Drive the agent from Discord

Run prompts, read reports, and make decisions from a DM; the guard rejects every other user before a handler runs.

Decisions safe to double-tap

Every state change is a compare-and-swap transition: duplicate button presses lose, exactly one commit lands.

Crash-safe git operations

Accept, Park & redo, and Reset survive a SIGKILL at any point; boot reconcile recovers from database facts, not memory.

Two surfaces, one core

Discord buttons and a Signal emoji-legend flow stand in front of the same core; a fan-out implements the ChatPort for both.

Honest signals

JSON logs with secret scrubbing, a loopback metrics endpoint, and a stall watchdog that pings once when nothing happens.

Restore drills

The SQLite diary is backed up nightly, and restoring it is a documented, rehearsed procedure — not an improvisation.

# Read the docs

System diagram, crates, data model, and the load-bearing decisions.
systemd install, secrets, backups, and upgrades.
Metrics, logs, degraded mode, and the incident runbook.
Dev setup, the lint floor, commit and PR conventions, CI gates.
Code

GitHub

Browse the source, read the contributing guide, and open issues.

Contribute

Dev setup, the quality floor, commit and PR conventions, and the CI gates are documented in CONTRIBUTING . Theteia is Apache-2.0 licensed.