`rysh send`: drive your agents from any shell, no TUI attached
One command turns a rysh session into scriptable infrastructure: send shell commands or prompts to any pane from cron, CI, SSH — no screen required.
A terminal UI is a great place to watch agents. It's a terrible dependency for using them.
If the only way to talk to your agents is a full-screen TUI, they're an app. Apps need you present, focused, and attached. Infrastructure doesn't. And agents earn their keep precisely when you're not watching.
So rysh ships the escape hatch as a first-class command:
rysh send <session> <input> [--pane <pane-id>] [--mode shell|prompt]
One line, from any shell, into any pane of a running or detached session. No TUI attached, no attach required.
The shape of it
# run a shell command in the session's active pane
rysh send myproject "go test ./..." --mode shell
# send a prompt to the agent in a specific pane
rysh send myproject "summarize the last test run and list flaky tests" \
--pane worker-1 --mode prompt
Defaults do what you'd hope: omit --pane and input goes to the session's active pane; omit --mode and the pane's current mode is used — the same shell/prompt mode you'd toggle with Double-Escape inside the TUI. A pane you left in prompt mode is addressable as an agent; a pane in shell mode is addressable as a shell.
That symmetry is the point. rysh send isn't a side API — it's the same input path the TUI uses.
Why this works: the TUI was always just a client
Under the hood, a rysh session is a daemon with an embedded NATS message bus. Every actor — workspace, tabs, panes, agents — communicates over that bus. When you type in the TUI, your input is published as a typed message to the session's workspace inbox, routed to the pane's actor, and executed there.
rysh send publishes the same message to the same subject. The workspace actor can't tell the difference — routing, mode handling, ## system commands, agent addressing: all identical. Two hops, input to pane, whether a human or a script produced it.
This is why it works on detached sessions: the session process and its bus never stopped. The TUI was only ever a window onto it.
What you build with it
CI that talks to your reviewer agent.
rysh send review "new failing run: $BUILD_URL — diagnose and draft a fix" --mode prompt
Attach later; the diagnosis is waiting in the pane's transcript, and any file edits it proposed are sitting behind rysh's approval gates, not silently applied.
Cron with a colleague.
0 7 * * 1 rysh send ops "check disk usage and error rates; write findings to the project notes" --mode prompt
SSH one-liners. Session detached on your desk machine; you're on a laptop:
ssh desk 'rysh send myproject "status?" --mode prompt'
Shell-mode fan-out. Because --mode shell targets a real PTY, rysh send also works as a plain remote-exec into a stateful shell — the pane keeps its cwd, env, and history between sends. It's ssh-into-a-conversation.
Wiring rysh into anything. A git post-receive hook, a Makefile target, an alert webhook handler — anything that can run a binary can now brief an agent. The integration surface is "can execute a command," which is to say: everything.
The governance part doesn't switch off
The obvious worry: headless input sounds like uncontrolled input. It isn't, because control never lived in the TUI.
Approval gates are enforced pane-side, in the agentic loop itself. A prompt sent from cron that leads the agent toward a gated operation — a file write, a git commit, a non-allowlisted shell command — parks at the same approval a live prompt would. The tool call is executed-and-previewed or held-for-approval by policy, and the pane's transcript records everything for when you do attach. Headless doesn't mean ungoverned; it means unattended, with the audit trail accumulating where you'll read it.
And it's all local-first: rysh send talks to a daemon on your machine (or your server — rysh is self-hostable), which talks to Claude with your own API key. No third-party queue in the middle.
Attach when you care, send when you don't
The combined loop with sessions looks like this:
rysh myproject # morning: attach, set agents working
rysh detach myproject # leave; everything keeps running
rysh send myproject "…" # poke it from wherever, all day
rysh attach myproject # evening: read transcripts, answer approvals
The TUI becomes what it should be: the review surface. The session is the worker. rysh send is the wire between your life and it.
A multiplexer you can only use while staring at it is furniture. One you can script is infrastructure.
Rysh is early — we're recruiting design partners who'll wire agents into real pipelines and tell us what breaks. → rysh.ai/design-partner
Related: Sessions that survive · The ## command language