Skip to main content

Race-condition-safe tmux wrapper for coding agents

Project description

twmux logo

Race-condition-safe tmux wrapper for coding agents.

Installation

uv pip install -e .

Usage

twmux [OPTIONS] COMMAND [ARGS]

Global Options

Option Description
--json Output as JSON (for programmatic use)
-L, --socket NAME Connect to specific tmux socket
-v, --verbose Verbose output

Commands

send - Send text safely

Send text to a pane with race-condition-safe Enter handling.

twmux send -t %5 "echo hello"
twmux send -t main:0.1 "make test" --delay 0.1
twmux send -t %5 "partial text" --no-enter

exec - Execute and capture

Execute a command and capture output with exit code.

twmux exec -t %5 "ls -la"
twmux --json exec -t main:0 "make test" --timeout 60

Returns:

  • output: Command stdout/stderr
  • exit_code: Command exit code (-1 if timeout)
  • timed_out: Whether command timed out

capture - Capture pane content

twmux capture -t %5
twmux capture -t %5 -n 50  # Last 50 lines
twmux --json capture -t main:0

wait-idle - Wait for output stabilization

Wait until pane output stops changing.

twmux wait-idle -t %5
twmux wait-idle -t %5 --timeout 10 --interval 0.1

interrupt - Send Ctrl+C

twmux interrupt -t %5

escape - Send Escape key

twmux escape -t %5

launch - Create new pane

Split current pane to create a new one.

twmux launch -t %5                      # Split below
twmux launch -t %5 -v                   # Split right (vertical)
twmux launch -t %5 -c "python3"         # Split and run command

kill - Kill pane

twmux kill -t %5

status - Show tmux state

twmux status
twmux --json status

Target Addressing

The -t option accepts tmux target syntax to identify panes.

Pane ID (Recommended)

Direct pane reference using tmux pane ID:

twmux send -t %5 "echo hello"      # Pane ID %5
twmux exec -t %12 "ls"             # Pane ID %12

Get pane IDs with twmux status or tmux list-panes -a.

Session:Window.Pane Format

Hierarchical addressing:

# Full path: session:window.pane
twmux send -t main:0.1 "echo hello"    # Session "main", window 0, pane 1
twmux send -t dev:2.0 "make test"      # Session "dev", window 2, pane 0

# Partial paths
twmux send -t main:0 "echo hello"      # Session "main", window 0, active pane
twmux send -t main: "echo hello"       # Session "main", active window/pane
twmux send -t :0.1 "echo hello"        # First session, window 0, pane 1

Target Resolution

Target Meaning
%5 Pane with ID %5 (absolute)
main:0.1 Session "main", window 0, pane 1
main:0 Session "main", window 0, active pane
main: Session "main", active window and pane
:0.1 First session, window 0, pane 1
:0 First session, window 0, active pane
(empty) First session, active window and pane

Examples

# Start a REPL in a new pane and interact with it
twmux launch -t %5 -c "python3"
# Returns: {"pane_id": "%12"}

# Send commands to the new pane
twmux send -t %12 "print('hello')"
twmux wait-idle -t %12

# Capture output
twmux capture -t %12 -n 10

# Execute and get result
twmux --json exec -t %12 "print(1+1)"
# Returns: {"output": "2", "exit_code": 0, "timed_out": false}

# Clean up
twmux kill -t %12

JSON Output

All commands support --json for programmatic use:

$ twmux --json exec -t %5 "echo hello"
{"output": "hello", "exit_code": 0, "timed_out": false}

$ twmux --json send -t %5 "test"
{"success": true, "attempts": 1}

$ twmux --json status
{
  "sessions": [
    {
      "session_id": "$0",
      "session_name": "main",
      "windows": [...]
    }
  ]
}

How It Works

Race-Condition-Safe Send

The send command:

  1. Sends text without Enter
  2. Waits (configurable delay)
  3. Captures pane content
  4. Sends Enter
  5. Verifies content changed
  6. Retries if needed

Marker-Based Execution

The exec command:

  1. Generates unique markers
  2. Wraps command: echo START; { cmd; } 2>&1; echo END:$?
  3. Polls pane with progressive expansion (100 → 500 → 2000 → all lines)
  4. Parses output between markers
  5. Extracts exit code

Output Stabilization

The wait-idle command:

  1. Hashes pane content (MD5)
  2. Polls at configurable interval
  3. Returns when N consecutive hashes match
  4. Times out if content keeps changing

Development

make install   # Install dependencies
make test      # Run tests
make lint      # Check code style
make format    # Auto-format code
make check     # Run lint + test

License

MIT

Prior Art, Inspiration

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

twmux-0.1.0.tar.gz (9.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

twmux-0.1.0-py3-none-any.whl (8.8 kB view details)

Uploaded Python 3

File details

Details for the file twmux-0.1.0.tar.gz.

File metadata

  • Download URL: twmux-0.1.0.tar.gz
  • Upload date:
  • Size: 9.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for twmux-0.1.0.tar.gz
Algorithm Hash digest
SHA256 0a876673ca4f0a35d236b8a2a35a87935a1e8a5e3bf8c07b6c048a4b448f8dcd
MD5 9ab39b8680d22562eb986dd54e4b64ea
BLAKE2b-256 764e3678d50d2c4896ca6d7e9c575dd2a0649ccff20fdb789d840e4c28cb2b8a

See more details on using hashes here.

File details

Details for the file twmux-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: twmux-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 8.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for twmux-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 013f7d1b4f4c5cfbca86d31e8bd4d6204e6710396a6fd5f6f12cfa05d145300d
MD5 a736241e524766a0b283627a66315f9e
BLAKE2b-256 b358b69e5a9e795b417b86498262f19c581fea5dbe84db2b0325cf35151b77df

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page