Skip to main content

pairmux

Let AI agents drive interactive terminal programs — and hand off to a human when they can't.

Documentation · CLI reference · Changelog · Source

pairmux is a small Agent-Computer Interface layer over tmux with no separate service to supervise. Agents get a real PTY with persistent shell state and actionable command outcomes; humans keep normal access to the same live terminal — watch, take over, hand back.

Why pairmux

  • A real PTY. Exec-style agent shell tools run commands without a terminal, so REPLs, psql, ssh password prompts, docker exec -it, git rebase -i, pagers, and TUIs are impossible there. pairmux makes them drivable.
  • Human handoff on credentials and judgment calls. A recognized secret prompt never suggests an answer; wait --human --notify, attach, and note turn a blocked credential prompt into a resumable checkpoint — and the wait ends as soon as the human answers, note or no note.
  • Persistent shell state. source venv/bin/activate, export, and nvm use happen once in a live shell instead of being re-composed into every command.
  • Actionable waits and captured history. run blocks until completion, a recognized prompt, or timeout (never killing the command); journals retain full output with exit codes, and --json emits a versioned pairmux.v1 envelope with ordered next steps.

Install

uv tool install pairmux
# or
pipx install pairmux
# or, inside a dedicated environment
python -m pip install pairmux

The wheel contains a prebuilt native Go binary, so installation needs no Go toolchain or source build. Wheel installers must select Python 3.9 or newer; the installed pairmux executable itself contains no Python code.

PyPI package requirements and wheel targets:

  • tmux 3.2 or newer
  • macOS 12+ or manylinux_2_17 (glibc 2.17+)
  • x86-64 or ARM64 (aarch64)
  • no native Windows wheel; use a compatible Linux distribution inside WSL

Check the local environment after installation:

pairmux doctor

60-second quickstart

Create one managed terminal, then run commands in it:

pairmux --json new --name demo
pairmux --json run demo "echo hello from pairmux"

# A timeout returns status=running; it does not kill the command.
pairmux --json run demo "sleep 2; echo finished" --timeout 1s

# When status is running, keep waiting without sleep-and-guess polling.
pairmux --json wait demo --idle 800
pairmux --json peek demo

wait --idle refreshes terminal state after output becomes quiet; silence alone is not treated as completion. peek and log are read-only, so other agents can inspect the same terminal without taking its writer lock.

Teach your agent

pairmux embeds its Agent Skill, including the new → run → wait/send/log loop and safe human handoff guidance:

pairmux skill install --target codex --dry-run
pairmux skill install --target codex

Use --target all to update only the supported agent configuration directories that already exist. See the Agent Skills guide for all targets and install locations.

MCP clients can launch the built-in stdio server and use the core terminal operations as typed tools:

{
  "command": "pairmux",
  "args": ["mcp", "serve"]
}

Interactive work and human handoff

After 800 ms of output quiet, pairmux recognizes supported prompt patterns: confirmations, password/passphrase/passcode prompts, pager markers, press-key messages, and Python's >>>. It reports awaiting-input and never auto-answers. Replace the uppercase placeholders below before sending ordinary input:

pairmux send NAME --text VALUE --enter

For a secret-shaped prompt, the response recommends pairmux wait NAME --human --notify. A human can enter the same live pane with pairmux attach NAME, provide the input, and detach with the configured tmux binding (default Ctrl-b d). Running pairmux note NAME "ready" afterward records a message and releases an agent waiting with --human; it does not itself detach or enforce control ownership. This avoids routing the input through the agent-facing send command. Prompt recognition is heuristic, desktop notification is best-effort, and whether an application echoes or records input remains application-dependent.

How it works

pairmux does not implement another PTY or add a background service of its own. tmux remains the terminal-state engine; short-lived pairmux commands add completion detection, captured output, model-friendly shaping, and coordination around the live pane. pairmux attach starts a native tmux client against the correct managed session whenever a human needs to observe or take over.

pairmux is open source under the MIT License.

Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

pairmux-0.5.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.4 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

pairmux-0.5.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.3 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

pairmux-0.5.2-py3-none-macosx_12_0_x86_64.whl (1.4 MB view details)

Uploaded Python 3macOS 12.0+ x86-64

pairmux-0.5.2-py3-none-macosx_12_0_arm64.whl (1.3 MB view details)

Uploaded Python 3macOS 12.0+ ARM64

File details

Details for the file pairmux-0.5.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

  • Download URL: pairmux-0.5.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: Python 3, manylinux: glibc 2.17+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pairmux-0.5.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 61a2f540b5d82c9b7ce2479017e2c4488aea45c07b42ebcd08dab6d6b4dba35f
MD5 46dd2788c115d14da244afc9ada25ec1
BLAKE2b-256 92f17105a359a08309c42f5188e128b84cae7446a3ed661d42dd613638501fe4

See more details on using hashes here.

File details

Details for the file pairmux-0.5.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

  • Download URL: pairmux-0.5.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: Python 3, manylinux: glibc 2.17+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pairmux-0.5.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 5a838260f112e3c968a5b5f2d2a3e7a7d90260d8c42bc87c21e06925adbd71d7
MD5 5ae939e282dba8604f8ba1571b5a59c6
BLAKE2b-256 249006ade5e634a7fd19252b0a03e64d613930582b83041e7e68165cb819e1be

See more details on using hashes here.

File details

Details for the file pairmux-0.5.2-py3-none-macosx_12_0_x86_64.whl.

File metadata

  • Download URL: pairmux-0.5.2-py3-none-macosx_12_0_x86_64.whl
  • Upload date:
  • Size: 1.4 MB
  • Tags: Python 3, macOS 12.0+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pairmux-0.5.2-py3-none-macosx_12_0_x86_64.whl
Algorithm Hash digest
SHA256 3dde2dcbac47f4061335ce2bd359253bca03506e295cbf179468f94cdc2dade1
MD5 a5aa54c1783f59e0c20a4fca82a404dc
BLAKE2b-256 a6bb722913650f32ea96b9f2dd606f38383ad2c115a21e5cea9977815d8b3a26

See more details on using hashes here.

File details

Details for the file pairmux-0.5.2-py3-none-macosx_12_0_arm64.whl.

File metadata

  • Download URL: pairmux-0.5.2-py3-none-macosx_12_0_arm64.whl
  • Upload date:
  • Size: 1.3 MB
  • Tags: Python 3, macOS 12.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.16 {"installer":{"name":"uv","version":"0.11.16","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pairmux-0.5.2-py3-none-macosx_12_0_arm64.whl
Algorithm Hash digest
SHA256 3d28744a6c17ff4a05e76e5226a151aed75ba9621d3afb2ce186824abf801930
MD5 17fd46ec15c53d25e1ad2e3e3b9a7e9a
BLAKE2b-256 3ba5d6f7fc2e5dd8130f57d2baf0ba88f2e6066633604b795595b403bd45c2e8

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.5.2 This release

4 files

0.5.1

4 files

0.5.0

4 files

0.4.0

4 files

0.3.0

4 files

0.2.0

4 files

0.1.1

4 files

0.1.0

4 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page