Replacing tmux send-keys for agent coordination? stdin FIFO is the right answer, not an alternative

tmux send-keys became the backbone of multi-agent relay systems for one reason: it could inject input into a running AI agent process at any moment, simulating a human interrupt. It worked. But it was always a hack — it targets a terminal pane, not a process, and carries all of tmux's fragility on Windows Git Bash with it.

The cleaner architecture separates the two things tmux was doing simultaneously:

1. Process lifecycle: supervisor loop

Instead of an external process injecting /next-run <path> into a live agent's stdin, the agent writes its own handoff file before exiting:

# supervisor wrapper
handoff="/tmp/next-run-${session_id}.md"
printf 'poll\n' > "$handoff"
while [[ -f "$handoff" ]]; do
    claude-code "/next-run $handoff"
done

The agent finishes a cycle, writes the next handoff, and exits cleanly. The supervisor reads the file and restarts. No injection, no timing race, no tmux session required. The agent writes its last will before dying — context stays clean across restarts because each cycle starts fresh.

2. Async wake / interrupt: stdin FIFO + registration file

For the "prod is on fire, wake up the polling agent" case, give each agent a named pipe as its stdin:

fifo="/tmp/mux-agent-${slug}-${backend}-${mode}.fifo"
mkfifo "$fifo"
claude-code "/next-run $handoff" < "$fifo" &
printf '%s\t%s\n' "$$" "$fifo" > "/tmp/mux-agent-${slug}-${backend}-${mode}.reg"

Any process that wants to wake the agent writes to the FIFO — same semantics as send-keys, but at the OS level, no tmux required.

3. Discovery: the registration file is the registry

mux agents no longer needs to walk tmux list-panes -a. It scans /tmp/mux-agent-*.reg, checks kill -0 $pid for each entry, and lists the live ones. The FIFO path in the registration file is both the agent's address and its communication channel — one mechanism solves discovery and messaging.

What this unlocks

With display decoupled from communication, agents can run entirely in the background. Output goes to a log file; mux log <agent> tails it when you want to watch. Closing a terminal window no longer kills the agent. On locked-down Windows hosts without WSL2, the whole stack runs in Git Bash with no tmux dependency at all.

The tmux send-keys approach worked because it exploited the one interface AI coding agents expose: their terminal stdin. The FIFO approach exploits the same interface at the OS level — it's not a workaround, it's the same idea done properly.

The one thing tmux still does better is real-time pane-peeking across agents in team mode. For multi-agent workflows where one agent needs to interrupt another mid-execution, stdin FIFO is the right replacement. For single-agent lifecycle management, the supervisor loop makes the interrupt unnecessary in the first place.

Comments

  1. Markdown is allowed. HTML tags allowed: <strong>, <em>, <blockquote>, <code>, <pre>, <a>.