Relay, voice & extras
Opt-in surfaces — answering X and Discord mentions (Relay), the spoken voice relay, the fleet ledger and the community RGB lamp, calm mode, mail, the captain's inbox, and self-evolution.
Everything on this page is off by default. VISION.md: "new capability ships as an option to enable, never as behavior that assumes consent."
Relay — talk to your fleet from X and Discord#
Relay connects your firstmate to public mentions. Kun's own instance is @myfirstmate.
- Enable: put
FMX_PAIRING_TOKENin the.envat the repo root. Kun confirmed it is the root, notconfig/.env. Relay ships inert without it. Relay needscurlandjq. Kun also noted tmux works best for the bot integration. - Who it listens to: direct mentions from the firstmate's own captain (owner-only routing).
- What it does: normal, reversible requests go through the same lifecycle as chat. Destructive, irreversible or security-sensitive asks are always flagged to you first.
- Replies are public-safe. No task ids, internal vocabulary, secrets or private plans.
- Follow-ups: spawned work gets an immediate acknowledgement, plus up to 3 follow-ups within 7 days for milestones and the final outcome (
FMX_FOLLOWUP_MAX_COUNT,FMX_FOLLOWUP_MAX_AGE_SECS). - Durable promises: a final reply promised in a thread is stored under
state/public-followup/and reconciled from disk. A restart or compaction can't lose it. - Dry run:
FMX_DRY_RUNrecords would-be replies and dismissals instate/x-outbox/without posting.
The skill is fmx-respond; the scripts are bin/fm-x-*.sh and bin/fm-public-followup.sh.
The demo that made this famous:
one-shot prompt from X -> firstmate worked for 3 hours straight -> modified and deployed itself -> replied with an image that was not supported at the time of my prompt. all that while i was watching house of the dragon. — @kunchenguid, 2026-06-30
Grok Bot variant
GROK_BOT.md is a copy-paste system prompt that recreates the first-mate pattern inside Grok's own bot platform. There, the "crewmates" are other bots and code goes to Cursor cloud agents. Kun published it as a one-click template (2026-09-07). It is a sibling of the CLI distro, not the same system.
Voice relay#
docs/voice-relay.md calls this "step one of three": a working spoken round trip.
laptop mic → fm-voice-client.py → SSH → fm-voice-relay.py (firstmate box) → AWS Bedrock Nova Sonic 2 → back
- It reads records: counts, or full titles and PR links with
config/voice-read-scope=full. It queues work throughbin/fm-inbox.sh note. "It has no tool that changes a project." - Push-to-talk only. Open-mic refuses to start, because there is no end-of-speech detection yet. It handles one turn per session.
- Measured: ~1.15–1.3s to first audio, ~$0.003 per exchange.
- Config:
FM_VOICE_REGION,FM_VOICE_MODEL,FM_VOICE_PROFILE,FM_VOICE_ID,FM_VOICE_RELAY.
The captain's inbox#
bin/fm-inbox.sh lets you add to the queue without interrupting a busy first mate:
bin/fm-inbox.sh note "look into the flaky e2e on xyz tomorrow" # durable, one wake
bin/fm-inbox.sh status # what's queued (no network)
bin/fm-inbox.sh ask "what's our default merge method?" # side question, touches nothing
bin/fm-inbox.sh say memo.wav # transcribe (Bedrock), then note
Fleet ledger (and the RGB lamp)#
Community member @jayparkcanada wired a Govee floor lamp to his fleet:
- 🟡 an agent is working,
- 🔴 a question or a failure,
- 🟢 a PR is ready.
It used no polling. macOS kqueue wakes on new status-log lines, Herdr's push events supply the "working" state, and colour goes to the lamp over the Govee LAN UDP API. (X Article, 2026-09-22.)
Kun's response was to ask @myfirstmate whether firstmate should expose a general ledger file for tools like this. It now does:
- Enable:
touch config/fleet-ledger. It is per home and not inherited. - Output:
state/fleet-ledger.jsonl, one JSON record per line, at-least-once delivery. - Records:
task.dispatched(kind, project, harness, model),task.status(state, key, text ≤2000 chars),task.pr_ready,task.merged(via pr or local),task.cleaned_up. - Deliberately excluded: live busy/idle transitions (subscribe to Herdr's
pane.agent_status_changedfor those), sequence numbers, rotation, backfill.
Example records, from docs/fleet-ledger.md:
{"v":1,"ts":1790132857,"event":"task.dispatched","task":"fix-login","kind":"ship","project":"webapp","harness":"claude","model":null}
{"v":1,"ts":1790133400,"event":"task.status","task":"fix-login","state":"done","key":null,"text":" PR https://github.com/acme/webapp/pull/7 checks green"}
{"v":1,"ts":1790133410,"event":"task.pr_ready","task":"fix-login","pr":"https://github.com/acme/webapp/pull/7"}
{"v":1,"ts":1790133900,"event":"task.merged","task":"fix-login","via":"pr","pr":"https://github.com/acme/webapp/pull/7"}
{"v":1,"ts":1790133960,"event":"task.cleaned_up","task":"fix-login"}
A lamp-style consumer is one line:
tail -F state/fleet-ledger.jsonl | jq -c 'select(.event=="task.pr_ready")'
Calm mode#
/calm hides firstmate's own operational rows (session-start digests, watcher wakes, guard nudges, launch briefs). It replaces the working spinner with a small animated sailboat.
- It is presentation only. Hidden content stays in model context, in storage, and in
/export. - It works on Pi. On Claude Code it needs
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1, which you set yourself; firstmate never sets it. - Supervision notes on Claude Code. With that flag set, the Claude Code mod also shows gray, display-only supervision notes, whether Calm is on or off: ⛵ for a routine outcome, ⚓
[seq N]for a captain outcome, and a note when the supervision host's latch trips. The model never sees them, and a resumed session shows each one only once. They come from the supervision outcome store, so you see them on homes that run the supervision host. - One preference file,
config/calm(on/off), applies to both.
Mail#
bin/fm-mail.sh read|send|poll|status is an IMAP/SMTP plane. poll turns unseen mail into check wakes, keyed by IMAP UID, and never marks mail read early. bin/fm-mail-check.sh arm runs it on the watcher's cadence. Credentials go in .env. Each surfaced email is a notification the first mate applies judgment to. It carries no authority.
Process-event sources and custom checks#
- Custom check: drop a script at
state/<id>.check.sh, then runbin/fm-check-register.sh <id>. That pins the script's SHA-256. The watcher runs it every cycle and surfaces its output as acheck:wake. - Process events (
process-event-sourcesskill): long-polling sources such as a Lavish board, quota thresholds,whencondition→action watches, and remote replies. They wake the first mate later instead of blocking a turn. Results are input, never authority. Each is acknowledged withbin/fm-procevent.sh handled <source> <seq>.docs/examples/process-event-extension/shows a complete minimal external extension.
Self-evolution#
The first mate can read and edit its own distro. That is why Kun says he got "500+ PRs coming from everyone using their firstmate to self evolve" (2026-08-10).
The rules:
- It changes shared tracked files (
AGENTS.md,bin/, skills) directly only when the fleet is empty. Otherwise it delegates to a crewmate. - The change ships through this repo's own no-mistakes pipeline and PR path.
- It loads
firstmate-coding-guidelinesfirst: one sentence per line, no agent co-authors, shellcheck-clean, colocated<subject>.test.shtests. AGENTS.mdstays under 9,000 words. Anything situational moves behind a skill trigger.
If you want your improvement upstream, just ask your first mate. CONTRIBUTING.md requires PRs to main to go through no-mistakes. CI checks a no-mistakes-pipeline-attestation bound to the exact PR head.