#panes #tmux #routing #editor #layout #logging

bin+lib tmux-router

Declarative tmux pane routing — sync editor layouts to tmux

25 releases

Uses new Rust 2024

0.3.10 Apr 9, 2026
0.3.9 Apr 4, 2026
0.3.6 Mar 30, 2026
0.2.9 Mar 24, 2026
0.1.3 Mar 6, 2026

#92 in Text editors

Download history 24/week @ 2026-03-07 15/week @ 2026-03-14 16/week @ 2026-03-21 212/week @ 2026-03-28 238/week @ 2026-04-04 63/week @ 2026-04-11 98/week @ 2026-04-18 28/week @ 2026-04-25

210 downloads per month
Used in agent-doc

MIT license

245KB
4.5K SLoC

tmux-router

Alpha Software — API may change between minor versions.

Declarative tmux pane routing — bind files to tmux panes and manage layouts programmatically.

Install

cargo install tmux-router

CLI

Layout Management

# Sync editor layout to tmux panes (2 columns)
tmux-router sync --col src/main.rs,src/lib.rs --col tests/test_main.rs

# Register a file to an existing pane
tmux-router register src/main.rs %5

# Unregister a file
tmux-router unregister src/main.rs

# Show all bindings and pane health
tmux-router status

# Prune dead panes from registry
tmux-router resync

# Focus (select) the pane bound to a file
tmux-router focus src/main.rs

Pane Interaction

# Send a command to a pane (by file name or pane ID)
tmux-router send src/main.rs "cargo test"
tmux-router send %5 "cargo test"

# Send text without pressing Enter
tmux-router send %5 "partial input" --no-enter

# Send raw tmux keys (C-c, Escape, Enter, etc.)
tmux-router send %5 "C-c" --raw

# Capture pane screen content
tmux-router capture src/main.rs
tmux-router capture %5 --lines 50

Use Cases

Test Runner

Bind a pane to your source file. The pane runs cargo watch — every save triggers a test rerun.

tmux-router sync --col src/main.rs --col tests/
tmux-router send tests/ "cargo watch -x test"
# Later, check results:
tmux-router capture tests/ --lines 20 | grep "test result"

REPL-Driven Development

Edit a Python file in your editor, send code blocks to an IPython REPL in a bound pane.

tmux-router register scratch.py %5
# In pane %5: ipython is running
tmux-router send scratch.py "exec(open('scratch.py').read())"
tmux-router capture scratch.py --lines 10

Log Watcher

Bind a log file to a pane running tail -f or lnav.

tmux-router register app.log %7
# In pane %7: tail -f app.log
# From any script:
tmux-router capture app.log --lines 5

Database Console

Bind a SQL file to a pane running psql. Send queries from your editor.

tmux-router register queries.sql %8
# In pane %8: psql mydb
tmux-router send queries.sql "SELECT count(*) FROM users;"
tmux-router capture queries.sql --lines 5

Multi-Agent Orchestration

Run multiple Claude Code instances, each bound to a different task file.

tmux-router sync --col task-a.md --col task-b.md --col task-c.md
tmux-router send task-a.md "fix the auth bug"
tmux-router send task-b.md "add unit tests for the parser"
# Check progress:
tmux-router capture task-a.md --lines 30

Scripted Workflows

Combine send and capture for automated pipelines.

#!/bin/bash
tmux-router send server.rs "cargo run"
sleep 2
tmux-router send client.rs "curl localhost:8080/health"
sleep 1
result=$(tmux-router capture client.rs --lines 1)
if echo "$result" | grep -q "ok"; then
    echo "Server healthy"
fi

Library Usage

use tmux_router::{Tmux, sync, FileResolution};
use std::path::Path;

let tmux = Tmux::default_server();
let cols = vec!["a.md,b.md".into(), "c.md".into()];
sync(
    &cols,
    Some("@1"),
    Some("a.md"),
    &tmux,
    Path::new(".tmux-router/registry.json"),
    &|path| {
        Some(FileResolution::Registered {
            key: path.to_string_lossy().to_string(),
            tmux_session: None,
        })
    },
)?;

// Send text to a pane
tmux.send_keys("%5", "hello world")?;

// Capture pane content
let output = tmux.capture_pane("%5", Some(20))?;

// Send raw tmux keys
tmux.send_keys_raw("%5", "C-c")?;

Architecture

  • Registry (.tmux-router/registry.json) — maps file paths to pane IDs
  • Layout reconciliation — attach-first algorithm (ATTACH → SELECT → DETACH → REORDER → VERIFY)
  • Stash window — evicted panes collected in one place, not scattered; early-exit paths stash excess panes to prevent leftovers from previous layouts
  • Health management — dead panes pruned, stale bindings cleaned up

License

MIT

Dependencies

~1.3–2.6MB
~46K SLoC