Changelog
Release notes for Agent Relay. Format follows Keep a Changelog and the project follows Semantic Versioning. Downloadable artifacts live on the GitHub Releases page.
v0.7.7
View release →- **
relay handoff armalso reports agents whose window has reset.** It is the call that already runs after every turn, so recovery is heard without waiting for a second handoff to happen to be needed. - **
relay handoff plan/relay handoff arm.** The rate-limit handoff decision (who continues, and why not everyone else) is now a command rather than something only the interactive REPL could reach.plananswers offline and immediately from the shared rate-limit ledger, the installed CLIs, and any successor already parked;armis the predictive half that asks the running agent while it still has quota to answer. - Rate-limit records now carry the provider's real reset time when a quota reading is cached, instead of always expiring after a flat hour. The ledger always promised this; nothing had been supplying it.
- **
v0.7.6
View release →- Relay picks your next agent before you run out. When the running agent crosses 90% of a usage window, Relay asks it, while it still has the quota to answer, what remains to finish the job and which of the *installed, authenticated, not-already-limited* agents should continue. The answer is parked on disk. When the limit actually hits, the handoff is immediate: no model call at the worst possible moment, just a decision that was already made. The remaining-scope half becomes the successor's
Next action, so it picks up the whole job rather than the slice that happened to be in flight. - Relay offers your preferred agent back. When a rate-limited agent's window resets, Relay says so once. It is an offer, not an automatic switch.
- **
relay limits//limits.** Real subscription usage for the agent CLIs (Claude Code's 5-hour and weekly windows, and Codex's quota), read from each CLI's own authoritative source rather than estimated. Agents that expose no quota surface report that explicitly instead of being omitted, so "we cannot see it" is never mistaken for "it has room". - Automatic handoff could return to the agent that just ran out. Fallback selection took the first agent in the configured order that differed from the current one, with no memory and no availability check, so with an order of
codex, claude, a rate-limited claude went to codex, and a rate-limited codex went straight back to claude. Relay now remembers which agents are rate-limited (account-scoped, so it survives a restart and applies across repos) and skips agents whose CLI is not installed. When no agent can take over, the message names the actual obstacle (gemini is not installed,claude is rate-limited) instead of the old catch-all, and the checkpoint is preserved forrelay resume. Explicit/useis unaffected: asking for a specific agent still switches to it. - Handoff packets told the next agent to hand off. The packet's
Next actionline, the most directive thing the successor reads, was filled with Relay's own bookkeeping (Hand off to Codex), and new sessions recordedContinue work in <the agent that just stopped>. Both now carry the work itself: the task, or the session objective. Affects every handoff, including manual/useandrelay <agent>.
- Relay picks your next agent before you run out. When the running agent crosses 90% of a usage window, Relay asks it, while it still has the quota to answer, what remains to finish the job and which of the *installed, authenticated, not-already-limited* agents should continue. The answer is parked on disk. When the limit actually hits, the handoff is immediate: no model call at the worst possible moment, just a decision that was already made. The remaining-scope half becomes the successor's
v0.7.5
View release →- **Account-specific models in
/model.** The REPL picker now lists the models your signed-in account can actually use, asking each agent's own tooling where it can (Codex's model cache,agy models,opencode models) and falling back to Relay's curated suggestions otherwise. This brings the CLI level with the desktop model menu, and makes OpenCode model selection possible at all. Its models are account-specific, so the curated-only picker could offer nothing but "default". Detection is cached for a few minutes;/model --refreshre-detects. An unrecognised name is still accepted, now with a warning and close-match suggestions. - Readable provider failures. A turn that fails at the provider (an unavailable model, an expired login, a context overflow) now reports one actionable sentence instead of the agent's raw protocol JSON. Checked independently of the exit code, because some agent CLIs report the failure in-band and still exit zero. Rate limits are untouched and still drive automatic handoffs.
- **
relay discoverreports models.**--jsonnow includes each agent'smodelsandmodel_flag(already on the underlying result, but dropped by the command), the table shows a model count, and--modelslists them. There was previously no way to enumerate models without opening the picker. - **
relay run --modelwarns on an unrecognised name.** Same wording and close-match suggestions as/model, since--modelis sticky and a typo otherwise persists as the repo default. Advisory only: the model is still applied. Warnings go to stderr, so--jsonstdout stays parseable, and are repeated in the payload asmodel_warnings. - OpenCode adapter support. Relay now includes OpenCode in agent discovery, aliases (
o), REPL handoff routing, fallback-order inference, dashboard badges, and managed run/handoff flows. - OpenCode install and daemon plugin integration.
relay installnow writes a Relay-owned OpenCode plugin when OpenCode is detected, routes selected OpenCode events throughrelay hook opencode-event, and removes only the Relay-owned plugin on uninstall. - OpenCode session export capture. Relay-managed OpenCode sessions attach sanitized
opencode exportoutput to handoff packets when the native OpenCode session id is known; missing ids or export failures remain non-fatal and fall back to Relay's observable turn artifacts. - Gemini hook-based rate-limit ingestion.
relay installnow wires a Gemini CLINotificationhook into~/.gemini/settings.jsonand routes quota/rate-limit notifications throughrelay hook gemini-notification. - **
!runs shell commands without leaving the session.**!git statusat the prompt (or typed mid-turn, running between turns) executes in the repo root and streams its output into the transcript, so what it showed feeds handoffs. Each!is a fresh shell, so no state carries between commands. Non-zero exits are reported, andCtrl+Ckills the whole pipeline. - Queue messages while an agent is working. Typing during a turn used to go nowhere: the input panel is closed for the duration so agent output can stream into real terminal scrollback, which left no input surface at all. The REPL now reads keystrokes during a turn, shows a standing
› type to queue a follow-upinput line with what you are typing, lists what is already waiting, and runs queued messages in order when the turn ends, the way Claude Code and Codex do.↑on an empty line pulls the newest queued message back into the input to edit before it is sent; it goes back on the end when you press Enter. Enter is the contract: only submitted lines run. A line still half-typed when the turn ends pre-fills the next prompt instead of being sent, a multi-line paste stays one message rather than becoming one turn per line, and pasted code keeps its indentation. A failed or interrupted turn discards the queue and prints what was dropped, rather than running follow-ups against a state you did not expect. POSIX terminals only; Windows and piped stdin behave exactly as before. - Agent reasoning is shown but never persisted. Thinking text used to be written into the session transcript, which lands on disk and feeds the handoff packet the next agent receives. Reasoning is unbounded agent text: it quotes system prompts, files it just read, whatever it happened to see, and none of that belongs in a durable artifact handed onward. It still renders live;
/thinking offhides it on screen too. - Claude model labels no longer pin a version. The picker read
Opus 4.8while theopusalias had already moved toclaude-opus-5, so it advertised the wrong model. Labels are now bare tier names (Fable,Opus,Sonnet,Haiku), which cannot go stale, because Anthropic repoints the aliases at each release and the ids follow automatically. - Edit previews render as a diff, not a raw patch. An agent's edit now shows as
Update(README.md)with a plain-language count (Added 4 lines, removed 2 lines), real file line numbers, surrounding context, and colour carrying the add/remove distinction. A⋯marks regions the diff skipped, so a jump in the line numbers cannot be misread as a deletion. Previously the raw unified diff was dumped into a markdown fence, where four of six lines were machinery (--- a/…,+++ b/…,@@) and the paths came out doubly-slashed (a//Users/you/repo/README.md). - Escape sequences in agent output can no longer restyle the UI. File content shown in a diff, reasoning text, and spinner labels are now stripped of ANSI escapes and control characters before rendering. A file whose bytes contain
ESC[31mwas being passed through to the terminal, recolouring Relay's own UI and, because escapes are not zero-width, pushing rows past the console edge. (Streamed agent output is unchanged: the existing sanitizer still allows an agent to colour its own text.) - Agent reasoning renders as dimmed prose. It was a Markdown blockquote, which Rich draws with a full-height
▌bar and renders as Markdown, so the least important thing on screen also got boxed code blocks and highlighted spans. It is now quiet text that reads as secondary to the answer. - The turn transcript repeats itself less, and breathes. An edit printed two lines naming the same file (
Editing /long/absolute/pathand then the diff's own header), so the tool line is gone and the diff header carries it. Reasoning that only restates the reply it precedes ("Done! The README header has been updated…", immediately followed by the agent saying exactly that) is no longer shown. And a blank line now separates reasoning, tool calls, diffs and the reply, instead of running them together. - The per-turn latency breakdown is no longer printed after each reply. It was a development instrument that shipped in 0.7.0 by accident. The timings are still recorded in the session's
metadata.latency_ms, so anything reading them off disk is unaffected. - **Every slash command answers
--help.** None of them did before: session commands fed the flag to their own argument parsing (/use --helpfailed with "unknown agent: --help") and registry commands rejected it as an unknown flag. Handled centrally in the dispatcher, so it covers both families and their aliases (/c -h), and prints the command's arguments and flags, or its example for a session command. - **
/helplists every command the shell answers to, with examples.** Seven working commands were missing,/useamong them, because the listing was hand-maintained in two places that had drifted from the dispatcher and from each other. Session commands now come from one source shared by/help, the slash menu, anddocs/repl.md, each with an example (e.g. /use claude), and a test pins that source to the dispatcher. - A provider error no longer crashes a run. Claude and Codex stream normalization assumed every JSON line was an object with an object-valued
message; a provider error puts a string there, which raised anAttributeErrorand took down the whole session with a traceback.
- **Account-specific models in
v0.7.0
View release →- Interactive REPL (
relaywith no subcommand). Persistent slash shell modeled on Claude Code / Codex: every existing CLI command is also a/-prefixed slash command, bare text is forwarded to the active agent's PTY, and the inline Textual panel redraws on every keystroke. Driven by a singleSlashRegistryso/help, the slash menu, anddocs/repl.mdnever drift. - Tmux integration.
relay --tmuxwraps the REPL inrelay-<sha256(cwd)[:8]>for crash-safety;relay --attachreattaches./tmux status|detach|split <agent>from inside the REPL. First-run prompt persists the choice totmux_autoinconfig.toml. - Structured JSONL logging at
~/.config/relay/repl.log(rotating 5×1 MB). Captures session lifecycle, slash dispatch (cmd / duration_ms / ok / error), agent spawn/exit, signal events.RELAY_LOG_LEVELhonored. - **
/diagnose**: shareable bundle (version + redacted log tail) for bug reports. - Crash recovery: pidfile reaper at startup. PID files live in
~/.config/relay/agents/; on next launch we cross-check the live command line against the recorded agent and only signal genuine orphans. Reused PIDs are skipped silently. - Onboarding wizard on first run (config file missing). Detects agents, picks a default, asks about tmux, persists to
config.toml. Re-runnable via/setup.--no-onboardingskips it for CI/scripts. - **
[repl.env]config section** for opting in additional env forwards to spawned agents. Keys validated as proper env-variable names; values still scrubbed by the deny-list unless on the per-agent provider allowlist. - Performance budgets + gated micro-benches in
tests/bench_repl.py(RELAY_BENCH=1). 16 ms p99 keystroke-to-render target documented indocs/performance.md. - Auto-generated slash-command reference (
docs/repl.md) plus a CI gate (tests/test_repl_docs.py) that fails the build if the registry and the doc drift. - New docs:
docs/repl.md,docs/architecture.md,docs/performance.md,docs/security.md(env contract + redaction pipeline + validation rules). scripts/release.sh X.Y.Z: one-command release prep. Bumps__version__, the extensionpackage.json, regenerates the lockfile, rewritesCHANGELOG.md's[Unreleased]header to a dated[X.Y.Z], regenerates the docs-site changelog + search-index JSON, and stages everything for a PR. It doesn't commit/push/tag, leaving that to the user's branch workflow.- Hook-based automatic rate-limit handoff.
relay installnow wires Claude CodeNotificationand CodexStophooks, normalizes hook payloads into daemonrate_limitedevents, and lets live REPL sessions execute a matching automatic handoff through the configured fallback order. - Install-time fallback-order setup.
relay installinfers[handoff].orderfrom detected Claude, Codex, and Gemini CLIs when no order exists. Userelay install --handoff-order ...to override or--no-handoff-orderto skip. - Per-agent env allowlist.
build_agent_envnow takes anagent=parameter and only forwards a provider key (e.g.ANTHROPIC_API_KEY) when launching that agent. All other forwarded keys whose values match a known-secret prefix (sk-,AKIA,ghp_,xox, …) are replaced with[REDACTED]before reaching the child. - Slash parser hardening. Every string / list-of-string argument passes through
validate_string(rejects null bytes and control chars outside\t\n\r);ArgSpec.choicesis now enforced; paths go throughresolve_safe_path(rejects..traversal, absolute,~, and symlink escapes unless--allow-outside-cwd). - **Docs now treat
relayas the primary workflow.** README, web docs, public concept pages, and examples were updated around the interactive shell, repo-local session lineage, automatic handoff triggers, and the current command surfaces. - **
logger.exception(...)no longer leaks secrets to disk.**_JsonlFormatter.formatnow runsredact()overexc_info, pre-cachedexc_text, andstack_info, the last hop before the JSONL file. Previously the redaction filter only touched the message and structured extras, so a traceback containingkey=sk-…survived to disk. - **
/diagnose --jsonno longer leaks the working directory path.** The JSON payload'scwdfield now goes through the sameredact()call the text path uses, so output is safe to paste into a bug report from any project. - Docs-site changelog page now renders
**bold**markdown properly (was showing literal**characters in the v0.6.x entries).
- Interactive REPL (
v0.6.3
View release →- Homebrew bump PR:
git pushfrom the rendered formula failed becausegh repo cloneauthenticates viaGH_TOKENbutgit pushfalls back to the git credential helper which has no credentials in CI. Now we rewrite the tap remote URL to embed the PAT (https://x-access-token:$GH_TOKEN@github.com/…) right after clone so subsequent pushes succeed without any extra credential helper setup.
- Homebrew bump PR:
v0.6.2
View release →- VS Code extension publish is no longer automated. The Marketplace publisher Members / Azure DevOps identity dance proved brittle in CI; publishing the
.vsixby hand from a laptop is a five-minute step per release and avoids surprises. The recipe lives as a comment inrelease.yml. The extension'spackage.jsonnow tracks the main package version (0.6.2here) so manual publishes stay in step. - Homebrew bump PR. The release workflow tried to
cpthe rendered formula intotap/Formula/agent-relay.rb, but a freshly-created tap repo doesn't have aFormula/directory yet. Addedmkdir -p tap/Formulabefore the copy.
- VS Code extension publish is no longer automated. The Marketplace publisher Members / Azure DevOps identity dance proved brittle in CI; publishing the
v0.6.1
View release →- Intel macOS native binary (
relay-darwin-x64). GitHub deprecated themacos-13runner in 2026 and capacity collapsed, so jobs targeting that label routinely queue for hours without starting. Intel-Mac users now fall through automatically toinstall.sh'suv tool installfallback; the curl one-liner still works on Intel Macs, it just takes the source path instead of a binary download. Apple Silicon, Linux x64, Linux arm64, and Windows x64 binaries are unaffected. Revisit when (if) we need cross-compile-from-arm64 to bring back the native binary. - The v0.6.0 release shipped without the Homebrew bump PR (the
bump-homebrewjob depended on the cancelled darwin-x64 matrix entry). With darwin-x64 dropped from the matrix, v0.6.1 produces a clean Homebrew bump PR automatically, sobrew install bethvourc/tap/agent-relaynow works.
- Intel macOS native binary (
v0.6.0
View release →- Always-on layer: a small local daemon plus four adapters captures context from every AI coding agent on the machine and hands off automatically when one rate-limits. Drive it from the CLI, or let it run in the background. See the always-on guide.
relay install/uninstall/doctor: detects installed agents (Claude Code, Cursor, Antigravity, Windsurf, VS Code, Codex CLI, aider, Gemini CLI, Warp), wires hooks/extensions/configs, and registers the daemon for auto-start via launchd / systemd user units / Windows Startup folder.doctorruns six health checks.relay daemon start|stop|status|tail: manages the background process;tailstreams live events from every adapter.relay wrap <cmd>: PTY-wraps any CLI agent (codex, aider, gemini-cli, sgpt, llm) so its rate-limits and lifecycle are captured without disturbing colours, prompts, or^C.relay resume <snapshot-id>+relay snapshots: list and reopen handoff snapshots produced by the daemon.relay dashboard: local web UI showing live sessions, snapshots, and a handoff trigger. Built into the binary; no external service.relay proxy start|status|cert: opt-in HTTPS proxy (requirespip install agent-relay-tool[proxy]) for lossless rate-limit capture from Anthropic / OpenAI / Google response headers.relay mcp serve: MCP server that lets Warp's native agent (or any MCP-aware client) feed events into the relay log.relay self-update: pulls the latest binary release and replaces the running executable atomically.relayshort command, declared alongsideagent-relayin the PyPI package, so the canonical short name works regardless of install method.--version/-Vflag on the root parser.- VS Code-family extension: one extension published to Open VSX and the VS Code Marketplace covers Cursor, Antigravity, VS Code, Windsurf, Trae, Void, and any future VS Code fork. Includes a
Relay: Hand off this sessioncommand onCmd+Shift+R. - Native binary distribution: PyInstaller bundles for macOS arm64 / macOS x64 / Linux x64 / Linux arm64 / Windows x64, published on every release via GitHub Actions. The curl one-liner at agent-relay.dev now detects platform and pulls the right binary, with a
uv toolfallback. - Homebrew tap at
bethvourc/homebrew-tap:brew install bethvourc/tap/agent-relayinstalls the native binary. - Docs site: new pages at
/always-on,/architecture,/privacy,/adapters/{claude-code,cursor,warp,cli}. pyproject.tomlcleaned up:[project.optional-dependencies]was previously nested inside[project], which silently droppedauthors/keywords/classifiersunder the wrong section.- Release pipeline split:
publish.ymlkeeps PyPI ownership;release.ymlowns platform binaries (uploaded to the public mirror via a scoped PAT), VS Code extension publishing, and the Homebrew bump PR. Source code stays on the private origin; only compiled artifacts surface publicly.
v0.5.6
View release →deactivatecommand (aliascomplete) for marking a session as finished or inactive, giving you explicit control over session lifecycle instead of relying on implicit timeouts.- Console feedback when a session is deactivated, so it's clear which session closed and what its final state was.
- Public community mirror at github.com/bethvourc/agent--relay for README, issues, discussions, and releases. Source remains private.
- Project metadata (
pyproject.tomlHomepage/Source/Issues) now points at the public mirror, so PyPI sidebar links resolve for anonymous visitors. - Docs site (
agent-relay.dev) GitHub/issue links route to the public mirror. - Installation scripts (
install.sh,install.ps1) refined for clearer platform-specific guidance.
v0.5.5
View release →- Improved cost estimation and model handling in metrics + CLI; cost labels in the dashboard and alerts now read as "est. cost" to make clear that values are estimates rather than billed amounts.
- Last release before the public-mirror split.
v0.5.0
View release →alertscommand for inspecting threshold breaches across sessions, with matching dashboard panel that integrates alerts into the session detail view.- Live-update controls for the dashboard: opt-in soft-refresh with JSON payloads so the page can update in place without a full reload.
MetricsFilterfor scoped metric queries: filter dashboard views by session, agent, time window, and more.- HTML dashboard surface for the Prometheus exporter so operators get a browsable view alongside the scrape endpoint.
- Chart features on the dashboard for session metrics (token, cost, and latency over turns).
- PyPI download badge on the README for visibility into install volume.
- Standardised metric labels and heading styles across the UI for a more consistent look.
- Refactored UI colour themes to use a token-based styling system; surface rule applied consistently to metrics panels and other surfaces.
- Help command structure reworked for clearer navigation and grouping.
- Turn-status aliases introduced so metrics and watch output read more naturally.
- Deprecated CLI and integration test files cleaned out as part of the metrics refactor.
v0.4.0
View release →watchcommand: live session monitoring that follows an in-progress session and auto-picks the latest active session when none is given. Includes a--metricspanel that refreshes per turn.metricscommand for token / cost / latency rollups per session.metrics-tailcommand streams metric events as JSONL for ingestion into external pipelines.metrics-servecommand exposes Prometheus and OTLP exporters from the local daemon, with alert evaluation hooks emitted into the JSONL stream.- Fallback logic in
watchimproved so the command picks the latest session when no id is supplied, instead of erroring out.
v0.3.0
View release →- Gemini agent adapter. Agent Relay now drives Gemini alongside Claude and Codex.
- Turn prompt logic refined to conditionally display the preamble, improving conversation flow when context is already loaded.
- Session snapshot rendering in
handoffscleaned up for a tighter output.
v0.2.0
View release →conversecommand for agent-to-agent turn-based interaction.discovercommand for detecting available agent CLIs on the host.cleancommand for removing all relay sessions.resolvecommand for resolving conflicts in concurrent agent runs, including capture-hook specifications and claim handling.- Concurrent execution support with tmux session management and pane capture; phase management and control status reporting for multi-agent workflows.
- Agent aliases and tmux integration so existing tmux users can plug Agent Relay into their workflow.
- Verbose output option on the
claudecommand. - Renamed PyPI package from
agent-relaytoagent-relay-toolto clear up naming conflicts; installation instructions updated to match. - Codex output normalisation: trailing "done" markers stripped so handoff payloads don't carry noise.
- Conversation rendering in the CLI extended to include agent output inline.
- Workstream kind defaults to
mixedin concurrent execution; schema validation added.
v0.1.0
View release →- Initial release. Agent Relay ships as a local-first CLI for handing off coding sessions between AI agents.
agent-relay <agent>: the one command that captures the current session state, generates a handoff packet, and launches the next agent with context preserved.- v2 session model: per-repo storage at
<repo>/.agent-relay/with manifests, journals, checkpoints, and content-addressed objects. repaircommand for fixing inconsistencies in v2 sessions, plus integrity checks on session load.- Lifecycle management (active / completed / archived) with safety checks on launch commands and agent profiles.
- Status / dashboard rendering for inspecting sessions from the CLI.
- Migration path from legacy session files into v2 sessions.