eve agent on boxd — freeq IRC/AV bridge, stream.place watch/publish, voice + slide modes
JavaScript 46%
TypeScript 40%
Python 8%
Shell 6%
Nix <1%
<1%

README.md

eve-agent #

eve.dev agent deployed on eve.boxd.sh.

  • Model: OpenCode Zen deepseek-v4-flash-free (OpenAI-compatible Chat Completions)
  • Channels: built-in eve channel + IRC via irc-bridge (POST /irc/inbound + SSE /irc/out)
  • AV (optional): av-bridge (Rust) — freeq MoQ media planes + internet radio (av-bridge/, freeq eve-av-bridge); stream.place watch (:8792) and publish (RTMP egress)
  • Tools: cowsay, ATProto, rook/thermals, Anna, Linear (eve project), guess_emotion, play_radio / stop_radio / stop_media (stream to freeq AV; stop_media = all planes), enter_voice_mode / exit_voice_mode / voice_status (Grok Voice duplex, default Eve timbre), enter_slide_mode / exit_slide_mode / slide_status (AV caption card: speech/text → tile only, no TTS), watch_stream / publish_stream (stream.place in/out), memory_bank_add / memory_bank_list (durable song/note list)
  • Skills: vit, vit-request-watch, anna, linear, freeq-irc, irc-backlog, embody-emotion, freeq-radio, freeq-voice, freeq-slide
  • Schedules: vit-request-caps every 10m → explore kind:request on controlled beacons → IRC #test
  • Secrets: API keys pulled live from OpenBao (openbao.boxd.sh) via scripts/fetch-keys.sh — never committed

Layout #

agent/
  agent.ts           # model + agent definition
  instructions.md
  channels/          # eve.ts, irc.ts (HTTP+SSE only — no IRC socket)
  lib/ tools/ skills/ schedules/
irc-bridge/
  server.mjs         # freeq IRC → POST /irc/inbound ; SSE /irc/out → PRIVMSG
systemd/user/        # user unit templates (eve, irc-bridge, optional av-bridge + streamplace plane (:8792))
scripts/
  prep.sh, start.sh, install-systemd.sh, fetch-keys.sh, sync-freeq-session.mjs
flake.nix

rook.host tools #

Public (no identity):

Tool Purpose
thermals_stats Board totals
thermals_requests / thermals_request Open work requests
thermals_rook Profile + track record by did/handle
thermals_leaderboard Ranked rooks

Local CLI (@solpbc/rook):

Tool Purpose
rook_whoami / rook_doctor Identity + readiness
rook_enroll Enroll with human invite URL + handle
rook_profile Show / publish / remove thermals profile
rook_submit fork → push → pr → ship from a local clone

Optional env: ROOK_IDENTITY_FILE, THERMALS_URL (default https://thermals.cloud).

Agent-facing docs: https://rook.host/llms.txt · https://thermals.cloud/llms.txt

Anna's Archive tools #

Tool Purpose
anna_search Books by ISBN/title via annas-mcp → MD5s
anna_download Member API → save file under ~/archive (or ANNA_DOWNLOAD_DIR)
anna_article_search Papers by DOI/keywords (annas-mcp)
openlibrary_isbn Open Library bibliography
anna_record Unified AA metadata for one MD5
anna_fast_download Member API → URL only (ANNA_API_KEY)
anna_torrents Bulk torrent catalog (large dumps)

Single-book flow: anna_search → pick md5 → anna_download (or anna_fast_download for URL only).

Variable Notes
ANNA_API_KEY OpenBao membership key for JSON download API
ANNA_DOWNLOAD_DIR Default $HOME/archive
ANNAS_MCP_BIN Optional path to annas-mcp
ANNA_ARCHIVE_BASE Default https://annas-archive.gl
bash scripts/install-annas-mcp.sh   # → ~/.local/bin/annas-mcp

Skill: load_skill → anna.

Linear tools (eve project) #

All Linear tools are scoped to the Linear project named eve (override with LINEAR_PROJECT_NAME or LINEAR_PROJECT_ID). Issues outside that project are rejected.

Tool Purpose
linear_status Project progress + counts by state + sample open issues
linear_issues List/filter issues (query, state, assignee); default open only
linear_issue Full detail for one identifier/UUID
linear_create_issue Create issue always on the eve project
linear_update_issue Update title/description/priority/state/assignee (eve only)
Variable Notes
LINEAR_API_KEY OpenBao ai-api-keys personal API key
LINEAR_PROJECT_NAME Default eve
LINEAR_PROJECT_ID Optional UUID (skips name lookup)

Skill: load_skill → linear.

Slide mode (freeform AV caption card) #

You say something → Eve shows it on the freeq AV slide only. No TTS speak-back (avoids mic feedback loops). Repeats until exit.

Trigger Action
eve: enter slide mode Start listening
type anything / speak in call Slide shows it (display only)
eve: exit slide mode Stop

Tools: enter_slide_mode, exit_slide_mode, slide_status. Skill: freeq-slide. Join freeq AV to see the tile.

Voice / conversation mode (Grok Voice) #

Duplex speech in freeq AV via Cloudflare Workers AI xai/grok-voice (default spoken voice eve).

Trigger Action
eve: enter voice mode / enter conversation mode Start duplex + short spoken greeting
eve: exit voice mode Stop Grok session
eve: voice status Live/off probe

Tools: enter_voice_mode, exit_voice_mode, voice_status. Skill: freeq-voice.

Variable Notes
CLOUDFLARE_ACCOUNT_ID Workers AI account (config / runtime.env)
CLOUDFLARE_API_TOKEN From OpenBao ai-api-keys
GROK_VOICE Default eve

Users must join the freeq voice call in the channel. stop_media also ends voice mode.

Memory bank (saved songs / notes) #

Host file (not the sandbox). IRC: “add song to memory bank”, “read the memory bank”.

Tool Purpose
memory_bank_add Append one entry (usually current now playing / radio_title)
memory_bank_list List saved entries
Variable Default
MEMORY_BANK_PATH $HOME/memory-bank.txt

Never claim a save without a tool result. Skill: freeq-radio.

freeq IRC nick / SASL #

If the bot appears as Guest… or logs SASL failed (904), the freeq OAuth session expired.

# on the eve VM
npx --yes @solpbc/rook login
node scripts/sync-freeq-session.mjs   # or /home/boxd/my-agent/scripts/…
# restart agent (start.sh)

Skill: load_skill → freeq-irc. Target nick: eve / handle eve.boxd.sh (PDS https://pds.eve.boxd.sh).

Local dev #

nix develop          # or: direnv allow
npm install
export OPENCODE_API_KEY=…   # or other provider keys
npm run dev

Boxd (eve.boxd.sh) #

On the VM, secrets come from OpenBao. Production path uses systemd user units (eve, eve-irc-bridge, optional eve-av-bridge) — see systemd/README.md.

export OPENBAO_ADDR=https://openbao.boxd.sh
export OPENBAO_TOKEN=…      # boxd secret / service token
npm install
bash scripts/install-systemd.sh   # once (writes units + ~/.config/eve/)
# put OPENBAO_* in ~/.config/eve/openbao.env (mode 0600)
loginctl enable-linger "$USER"    # once, if units should survive logout
npm run boxd:start                # systemctl --user start eve.target

Legacy (no units): bash scripts/start.sh --legacy (prep + nohup bridge + foreground eve).

Optional IRC env (defaults match freeq; set in ~/.config/eve/config.env for units):

Variable Default
IRC_HOST irc.freeq.at
IRC_PORT 6697
IRC_TLS 1
IRC_NICK eve
IRC_CHANNEL #test
IRC_PASSWORD (unset)
IRC_OWNERS (unset)

vit request-cap schedule #

Variable Default
VIT_CONTROLLED_BEACONS codegod100 repo beacons (comma-separated overrides)
VIT_CONTROLLED_BEACON_OWNERS codegod100 (substring match on beacon)
VIT_REQUEST_REPORT_EMPTY unset = quiet when no matches; 1 = always report
VIT_EXPLORE_URL https://explore.v-it.org

npm run boxd:start runs eve build && eve start so the cron fires. Locally with eve dev, fire once:

curl -X POST http://127.0.0.1:8000/eve/v1/dev/schedules/vit-request-caps

Framework docs #

See node_modules/eve/docs/ or https://eve.dev/docs.