Race-condition-safe tmux wrapper for coding agents
Project description
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/stderrexit_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:
- Sends text without Enter
- Waits (configurable delay)
- Captures pane content
- Sends Enter
- Verifies content changed
- Retries if needed
Marker-Based Execution
The exec command:
- Generates unique markers
- Wraps command:
echo START; { cmd; } 2>&1; echo END:$? - Polls pane with progressive expansion (100 → 500 → 2000 → all lines)
- Parses output between markers
- Extracts exit code
Output Stabilization
The wait-idle command:
- Hashes pane content (MD5)
- Polls at configurable interval
- Returns when N consecutive hashes match
- 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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0a876673ca4f0a35d236b8a2a35a87935a1e8a5e3bf8c07b6c048a4b448f8dcd
|
|
| MD5 |
9ab39b8680d22562eb986dd54e4b64ea
|
|
| BLAKE2b-256 |
764e3678d50d2c4896ca6d7e9c575dd2a0649ccff20fdb789d840e4c28cb2b8a
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
013f7d1b4f4c5cfbca86d31e8bd4d6204e6710396a6fd5f6f12cfa05d145300d
|
|
| MD5 |
a736241e524766a0b283627a66315f9e
|
|
| BLAKE2b-256 |
b358b69e5a9e795b417b86498262f19c581fea5dbe84db2b0325cf35151b77df
|