Skip to content

Automations

An automation is any executable. Configure it in Settings › Automations or in config.toml:

[[automation]]
name = "Summarize"
command = "~/bin/summarize.sh"      # ~ is expanded; relative names are looked up on PATH
args = []
triggers = ["transcript-ready"]     # recording-started | recording-stopped | transcript-ready | error; [] = by hand only
enabled = true
timeoutSec = 600
env = { REX_SUMMARIZER = "claude -p" }

Contract

Rex runs /usr/bin/env <command> <args…> <meeting-folder> with:

  • working directory = the meeting folder
  • meeting.json on stdin
  • environment: REX_EVENT, REX_MEETING_DIR, REX_MEETING_ID, REX_MEETING_JSON (path), REX_TRANSCRIPT_JSON (path, when it exists), REX_RESULT_JSON (path rex automation-result writes to, see below), REX_APP_VERSION, plus the automation's env table. PATH gains ~/.local/bin, ~/bin, /opt/homebrew/bin, /usr/local/bin so user tools are found even when Rex was launched from Finder.
  • stdout + stderr → automations/<name>-<yyyyMMdd-HHmmss>.log in the meeting folder (readable from the meeting detail view's Logs button and from Settings › Automations › Test Run).

Writing summary.md into the meeting folder makes Rex show it in the meeting detail.

Reporting results

By default Rex only knows an automation's exit code, so the app falls back to showing the last non-empty line of output as the run's result. To say what actually happened — essential for agent-driven automations that can "succeed" without doing the work — call rex automation-result before exiting:

rex automation-result --status ok \
  --message "Routed transcript to Clients/Acme" \
  --link "obsidian://open?vault=Notes&file=Clients%2FAcme%2F2026-08-31%20Kickoff"
  • --status is ok, warning (finished, but a human should look — e.g. "couldn't identify the customer, left it in the inbox"), or failed. failed counts as an automation failure even when the process exits 0.
  • --message is one sentence for a human (max 500 characters). It appears on the meeting, in the chip tooltip, and in the macOS notification.
  • --link (repeatable) is a file path or URL to what was produced. File paths get a reveal-in-Finder button; URLs (obsidian://…, https://…) open in their handler.
  • The result is tied to the meeting via REX_MEETING_ID from the environment; pass --meeting <id> only to double-check — a mismatch is an error. Outside an automation run the command refuses to write anywhere.

The report lands in automations/<name>-<ts>.result.json next to the run's log (schemaVersion: 1 — status, message, links, meetingID). Runs that never call rex automation-result get a synthesized result file (exit code + last output line), so every past run's outcome stays visible on the meeting. Reporting more than once is fine; the last report wins.

For agents (Claude Code, opencode, …), add an instruction like: "When you are done, run rex automation-result --status <ok|warning|failed> --message '<what you did>' --link '<path or URL to the result>'. Use warning if you finished but a human should double-check something."

Automations window

Window › Automations (⇧⌘A, also in the menu-bar menu and the main window's toolbar) lists every meeting with the last result of each enabled automation — one column per automation, the status icon and message in each cell. Double-click a row to open the meeting; the context menu runs an automation on the selected meetings, opens any links the results reported, and reveals the folder.

The filter at the bottom shows All meetings, With results, Without results, Failed, or Warnings; with more than one automation configured, a second picker narrows the test to one of them (so "Without results · Summarize" is exactly the backlog for that automation).

Tick the checkbox on each meeting you want (or Select all shown in the footer), then Run… in the toolbar queues an automation on those meetings — or on every meeting shown when nothing is ticked. A meeting where that automation is already running or queued is skipped, whether it was started here, from the meeting's own button, or from the sidebar. Queued runs execute one at a time, oldest meeting first, so an AI-backed automation started on thirty meetings never trips a rate limit; the footer shows what is running and how far along the batch is, and Stop Queue cancels the current run and drops the rest. The queue keeps going when the window is closed; failures are reported the same way as any other run.

Rules

  • Automations run any time, including while a recording is in progress — they are separate processes and cannot affect the capture. A recording-started run sees an incomplete folder: no transcript yet, audio still being written.
  • Runs against the same meeting are serialised; different meetings run in parallel.
  • timeoutSec kills a hung run (SIGTERM, then SIGKILL). Cancel in the UI does the same.
  • A non-zero exit — or an explicit --status failed report — is reported in the app (and as a macOS notification) and fires the error trigger once - never from an error run itself, never for a cancellation. A reported ok/warning outcome also posts a notification saying what the automation did.
  • Every enabled automation shows up as a button on every meeting (and in the sidebar's context menu); a run started that way sees REX_EVENT=manual. triggers only adds automatic runs, so triggers = [] is a by-hand-only automation. Any enabled automation can also be run from a terminal: rex automation-run <name> <meeting-folder>.

Examples

Examples/automations/summarize.sh pipes transcript.md through $REX_SUMMARIZER (default claude -p) and writes summary.md; copy-to-obsidian.sh writes a note into $OBSIDIAN_VAULT/$OBSIDIAN_FOLDER. Both read every secret and path from environment variables and ship disabled - see Examples/automations/README.md.