`##pane listen`: when one pane watches another work
One command subscribes a pane to another pane's redacted output stream. It's tail -f for conversations — and the primitive agent teamwork is built on.
Unix got composition right once, forty years ago: small programs, connected by streams. build | tee | grep. The pipe made processes composable.
Then we built terminal multiplexers and forgot the lesson. Panes sit side by side for decades, perfectly isolated, sharing nothing but your attention. tmux's best offer is pipe-pane dumping raw bytes to a file — a fire hose and a bucket.
Rysh panes aren't just shells; they're conversations with agents in them. So rysh gives them the pipe they deserve:
##pane listen <id|alias> # subscribe this pane to another pane's output
##pane unlisten # stop
Type it in any pane, name any other pane (panes have given-names — Ctrl+P r or ##pane name — so it's ##pane listen builder, not a UUID hunt). From then on, the target's output flows into your pane, live.
tail -f, but for a colleague's work. Including when the colleague is an AI.
What actually flows: the redacted stream
Here's the design decision that makes listen more than a gimmick. The listening pane does not tap the source's raw output.
Every rysh pane has a shared-output actor: it subscribes to its own pane's output stream, applies secret redaction, and republishes to a separate .sharedOutput topic. When you run ##pane listen, a listener actor is spawned under your pane and subscribed to the target's .sharedOutput — the sanitized stream, never the raw one.
Consequences worth spelling out:
- Credentials don't travel. The API key that flashed through the builder pane's environment output gets redacted at the source, before the stream ever leaves the pane's boundary. Listeners see structure, not secrets.
- Privacy has a switch. Output the source pane marks with
##privatelands in a private buffer that never reaches the shared stream at all.##publicflips back. Observability is granted by the observed, not taken by the observer. - It's the same trust boundary everywhere. A local listening pane and a remote collaborator subscribed via
##shareconsume the same redacted stream. One seam, one policy, audited in one place.
This is the difference between piping and governed observation. tmux never needed the distinction. Agents that handle your .env files absolutely do.
The morning this becomes indispensable
Watching a long-running agent without babysitting it. Your deploy pane runs a slow, chatty rollout. In your main working pane: ##pane listen deploy. Keep coding; the rollout narrates in your margin. ##pane unlisten when it's boring again. No pane-hopping, no split you'll forget to close.
A reviewer agent that watches the builder. This is where it gets interesting: the listener can be an agent's pane. A pane whose agent is instructed to review runs ##pane listen builder. Everything the builder agent does — commands, diffs, test output — streams into the reviewer's context as it happens. The reviewer doesn't need the builder to hand off a summary; it watched the work.
That's a genuinely different collaboration shape than "agent finishes, human pastes result into second agent." Observation is the handoff.
One ops pane aggregating a stack. A pane listening to three service panes becomes a poor man's log aggregator — except the sources are conversations, and redaction already happened.
Events ride the same stream
listen has a second life: it's the transport for rysh's pipeline events. Lines beginning with ##> bypass the PTY entirely and are published as clean event lines on the source's output.
The listener actor treats them specially instead of just displaying them:
##>event:print:<payload>— forwards the payload into the listening pane, clean.##>event:ai:softdev:<language>:<phase>— triggers the listening pane's agent with a contextual prompt for that phase.##>event:sh:softdev:<language>:<phase>— runs the phase's mapped shell command in the listening pane (for Go'sunit_testingphase:go test -v ./...).
And the detail that makes triggered agents competent rather than clueless: the listener maintains a rolling context buffer (capped at 50KB) of the source's recent non-event output. When an event fires an AI prompt, that accumulated context rides along. The downstream agent doesn't just hear "tests, go" — it has seen the preceding work.
Subscribe to a colleague, and their milestones can become your triggers. That's an assembly line, built from two panes and one command — the full version of that story is the pipeline events article.
Composition, rediscovered
The actor plumbing is invisible but worth one sentence: listening is a subscription on the session's message bus, not a UI hack — which is why it survives detach/reattach, works between panes in different tabs, and costs nothing when idle.
Panes that can watch panes turn a multiplexer from a grid of isolated screens into a graph of connected workers. Unix composed processes with pipes. Rysh composes conversations with subscriptions — redacted, revocable, and one command long.
Rysh is early. If "a reviewer agent that watches the builder" sounds like your team's next workflow, become a design partner: rysh.ai/design-partner
Related: Pipeline events: an assembly line out of panes · Four output streams per pane