Repository navigation
v0.8.17
Patch release that lets Relayer see the prompts Claude Code asks before it runs a shell command or creates a file (2.1.285 and 2.1.286) or edits one (2.1.285), which an agent waited at unseen until now, and that makes a panic while reading one agent's output end that agent's session instead of the whole process. A person answers those prompts: Allow and Deny are not offered for Claude, since no answer to them has been checked against a real Claude Code, and the rules rest on 2.1.285 cases of unconfirmed provenance and on 2.1.286 test strings. The desktop application and the gateway also flag an agent whose version they were not verified against; the probe that finds the version runs only the agent's own binary, inside its deadline and outside the gateway's state lock.
Added
-
The Claude adapter recognizes the prompts Claude Code asks before it runs a shell command, creates a file and edits a file. The adapter knew only the workspace-trust and environment-key prompts of 2.1.59, so an agent stopped at any of these waited for an answer nobody was asked for. The shell-command and create-file prompts of 2.1.285 and 2.1.286 and the edit-file prompt of 2.1.285 are now raised as events: the shell command as a high-risk
permissioncarrying a best-effort reading of the command Claude Code displays, the other two asconfirmations of unknown risk. A person answers all three at the terminal. The desktop and web decision modal take a typed answer too, but for the shell command it shows the title "Confidential input required", the agent, adapter, risk and rule, and a masked field, but not the command, the terminal output or the options, so read the command in the terminal. Create and edit are unknown risk, not low, so no policy allows them by itself: what Claude Code is asked to write decides what runs next (.github/workflows,.claude/settings.json, apackage.jsonscript), and the guardrails only partly cover that. A deny a policy would give is handed back to a person, since the adapter has no verified deny byte. Allow and Deny buttons are not offered in the modal; the TUI still lists F2 and F3, which write nothing and bring the prompt back. No answer to these prompts is backed by a stored capture of its effect: Enter is expected to take the highlighted option, which Relayer does not read, so answer at the terminal. The 2.1.285 cases have unconfirmed provenance and the 2.1.286 layouts are test strings, not fixtures; the 2.1.59 workspace-trust and API-key rules also recognize the unnumbered menu Claude Code draws in 2.1.286, from test strings only. Other prompts Claude Code asks (overwriting an existing file, a PowerShell command, a web fetch, an MCP tool) have no rule and no stored capture: one is raised only if its text happens to match one of the five rules or an intercept_pattern, and otherwise the agent waits unseen. -
The desktop application and the gateway flag an agent whose version they were not verified against. When a run starts, each vendor agent's own binary is run as
--version, and an agent whose version is not one its adapter's patterns were captured against is marked "unverified version" on its card and in the decision modal, since its prompts and the answers it expects may differ from what the adapter knows. It is informational and stays that way deliberately: it changes no policy, an unverified version does not refuse an automatic decision, and nothing is written to the audit journal. The TUI andrelayer doctordo not run it. See the security model. -
RELAYER_NO_VERSION_CHECK=1turns the version probe off for every user of a machine, asRELAYER_NO_UPDATE_CHECKturns off the desktop's release check: nothing is executed and no badge is shown. It is an environment variable rather than a configuration key because the probe runs a child process on the host — a machine-level concern, an endpoint agent that flags process spawns or a network home directory — whileconfig.yamlis per-project, strict-schema and travels through version control. A probe's answer is now cached per executable path until that file's modification time or size changes, so restarting a run does not run every vendor tool again; an upgrade changes the file and asks the new binary.
Fixed
-
A panic in the goroutine that reads an agent's output ends that agent's session, not Relayer. Nothing recovered a panic there, so a bug in an adapter, or output an agent chose to make it trip, ended the whole process and with it the supervision of every other agent, in the TUI, the desktop application and the gateway. The reader now returns the panic as the error that ends that session, like any other processing failure, with the runtime error's message (numbers and type names, never text from the agent) or, for any other panic value, only its type, and the place it came from. A PTY agent's terminal is closed with its reader, as after any reader failure; with tmux the pane keeps running with nobody reading it, so stop it from the interface. A panic in the same adapter code reached when a policy answers a prompt, or when a gateway call delivers an answer, is still not recovered and ends the whole process. In the TUI, Bubble Tea catches such a panic (a policy answer, a tmux re-synchronization), prints it, restores the terminal and ends the TUI, and with it the supervision of every agent.
-
A very small browser terminal could blank a Windows agent's screen. A terminal pane that had not been laid out yet, or a phone-sized one, sent a resize of a few columns, and the Windows pseudo-console could blank the screen it kept. The gateway now raises any resize to at least 40 columns by 15 rows, the browser terminal reports no size under 20 by 8, and the terminal pane has a minimum height of 250 px, so a narrow pane gets a wider PTY than it shows. The desktop application's own resize call is not clamped.
-
The version probe replayed the command line it was told to run. Starting a run executes each vendor agent's own binary as
--version, to compare its version with the ones its adapter's patterns were captured against. Forsh -candcmd /cit rejoined the configured arguments, appended--versionand ran the whole script again, so a configured command's side effects happened twice per start — a marker file the script wrote was written once by the probe and once by the agent. A launcher (npx,node,python,docker) reported its own version as the agent's, and an agent configured withshell:and no argv probed whateverclaudethePATHhappened to resolve. The probe now runsargv[0]alone, with none of the configured arguments, and only when its base name — without a Windows.exesuffix — is exactly the adapter's own executable (claude,codex,aider,goose,interpreter); anything else is not probed, and shows no version and no badge. On Windows,sh.exeandcmd.exefail that test by name. -
The probe's 2.5s timeout did not bound the probe. Killing the process left the wait for its output pipes, which a grandchild that inherited stdout — a daemon the tool spawned, a pager, a hung child — held open for as long as it lived. Every agent was probed in turn, and on
relayer servethat ran under the gateway's state lock, so one such tool stalledgetStatefor every connected operator and viewer. The wait is now bounded 500ms past the process, a run's probes run in parallel within a 4s budget, and the gateway runs them before taking its state lock. What a probe reads is bounded at 64 KiB, and is stdout alone, on the line that names the product: a banner or a launcher's own version no longer becomes "the agent's version" that every client saw. -
A viewer received the host's tool version.
installedVersionand the reason text that quotes it crossed to viewers with the rest of the state, as the startup notices carrying the same reason did not. A viewer now receives the unverified flag alone — that an agent's version is not one this build was verified against is supervision information, and a viewer watching a prompt should have it — and neither the version nor the reason: which build of a tool a machine runs is host tooling state, like the notices and the journal's path thatgetStatealready hid. -
An agent whose adapter the configuration left empty was never warned. The probe tested the configured adapter, so
command: [claude]with noadapter:— which the run resolves to the Claude adapter — showed nothing whatever its version, while an adapter the registry resolved away to generic was probed on the configured name alone. The check now uses the adapter the run resolved. -
The version warnings were in French, while every other string a run shows an operator is English: the reason a version is unverified, the startup log's
Avertissement, and the desktop badge'sversion non vérifiée.
Full commit list: v0.8.16...v0.8.17