
cmux-terminal-multiplexer
AI-native terminal multiplexer with programmable socket API, full Playwright-equivalent browser automation, and agent team coordination — built for Claude Code and autonomous agent workflows
- Installs
- 1.4K
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/reason-machines/trending-skills --skill cmux-terminal-multiplexer- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads cmux-terminal-multiplexer automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
cmux — AI-Native Terminal Multiplexer
Skill by ara.so — Daily 2026 Skills collection
cmux is a terminal multiplexer with a programmable socket API designed for AI coding agents. It provides full Playwright-equivalent browser automation, real-time terminal split management, sidebar status reporting, and agent team coordination — all via a simple CLI.
What cmux Does
- Terminal splits — create side-by-side or stacked panes, send commands, capture output
- Browser automation — full headless Chromium with snapshot-based element refs (no CSS selectors)
- Status sidebar — live progress bars, log messages, and icon badges visible to the user
- Notifications — native OS notifications from agent workflows
- Agent teams — coordinate parallel subagents, each with their own visible split
Orient Yourself
cmux identify --json # current window/workspace/pane/surface context
cmux list-panes # all panes in current workspace
cmux list-pane-surfaces --pane pane:1 # surfaces within a pane
cmux list-workspaces # all workspaces (tabs) in current window
Environment variables set automatically:
$CMUX_SURFACE_ID— your current surface ref$CMUX_WORKSPACE_ID— your current workspace ref
Handles use short refs: surface:N, pane:N, workspace:N, window:N.
Terminal Splits
Create splits
cmux --json new-split right # side-by-side (preferred for parallel work)
cmux --json new-split down # stacked (good for logs)
Always capture the returned surface_ref:
WORKER=$(cmux --json new-split right | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
Send commands and read output
cmux send-surface --surface surface:22 "npm run build\n"
cmux capture-pane --surface surface:22 # current screen
cmux capture-pane --surface surface:22 --scrollback # with full history
cmux send-key-surface --surface surface:22 ctrl-c # send key
cmux send-key-surface --surface surface:22 enter
Golden rule: never steal focus. Always use --surface targeting.
Worker split pattern
WORKER=$(cmux --json new-split right | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux send-surface --surface "$WORKER" "make test 2>&1; echo EXIT_CODE=\$?\n"
sleep 3
cmux capture-pane --surface "$WORKER"
cmux close-surface --surface "$WORKER" # clean up when done
Pane management
cmux focus-pane --pane pane:2
cmux close-surface --surface surface:22
cmux swap-pane --pane pane:1 --target-pane pane:2
cmux move-surface --surface surface:7 --pane pane:2 --focus true
cmux reorder-surface --surface surface:7 --before surface:3
Browser Automation
cmux embeds a full headless Chromium engine with a Playwright-style API. No external Chrome required. Every command targets a browser surface by ref.
Workflow pattern
navigate → wait for load → snapshot --interactive → act with refs → re-snapshot
Open and navigate
cmux --json browser open https://example.com # opens browser split, returns surface ref
cmux browser surface:23 goto https://other.com
cmux browser surface:23 back
cmux browser surface:23 forward
cmux browser surface:23 reload
cmux browser surface:23 get url
cmux browser surface:23 get title
Capture the surface ref:
BROWSER=$(cmux --json browser open https://docs.example.com | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
Snapshot and element refs
Instead of CSS selectors, snapshot to get stable element refs (e1, e2, ...):
cmux browser surface:23 snapshot --interactive # full interactive snapshot
cmux browser surface:23 snapshot --interactive --compact # compact output
cmux browser surface:23 snapshot --selector "form#login" --interactive # scoped
Refs are invalidated after DOM mutations — always re-snapshot after navigation or clicks. Use --snapshot-after to auto-get a fresh snapshot:
cmux --json browser surface:23 click e1 --snapshot-after
Interact with elements
# Click and hover
cmux browser surface:23 click e1
cmux browser surface:23 dblclick e2
cmux browser surface:23 hover e3
cmux browser surface:23 focus e4
# Text input
cmux browser surface:23 fill e5 "hello@example.com" # clear + type
cmux browser surface:23 fill e5 "" # clear input
cmux browser surface:23 type e6 "search query" # type without clearing
# Keys
cmux browser surface:23 press Enter
cmux browser surface:23 press Tab
cmux browser surface:23 keydown Shift
# Forms
cmux browser surface:23 check e7 # checkbox
cmux browser surface:23 uncheck e7
cmux browser surface:23 select e8 "option-value"
# Scroll
cmux browser surface:23 scroll --dy 500
cmux browser surface:23 scroll --selector ".container" --dy 300
cmux browser surface:23 scroll-into-view e9
Wait for state
cmux browser surface:23 wait --load-state complete --timeout-ms 15000
cmux browser surface:23 wait --selector "#ready" --timeout-ms 10000
cmux browser surface:23 wait --text "Success" --timeout-ms 10000
cmux browser surface:23 wait --url-contains "/dashboard" --timeout-ms 10000
cmux browser surface:23 wait --function "document.readyState === 'complete'" --timeout-ms 10000
Read page content
cmux browser surface:23 get text body # visible text
cmux browser surface:23 get html body # raw HTML
cmux browser surface:23 get value "#email" # input value
cmux browser surface:23 get attr "#link" --attr href
cmux browser surface:23 get count ".items" # element count
cmux browser surface:23 get box "#button" # bounding box
cmux browser surface:23 get styles "#el" --property color
# State checks
cmux browser surface:23 is visible "#modal"
cmux browser surface:23 is enabled "#submit"
cmux browser surface:23 is checked "#agree"
Locators (Playwright-style)
cmux browser surface:23 find role button
cmux browser surface:23 find text "Sign In"
cmux browser surface:23 find label "Email"
cmux browser surface:23 find placeholder "Enter email"
cmux browser surface:23 find testid "submit-btn"
cmux browser surface:23 find first ".item"
cmux browser surface:23 find last ".item"
cmux browser surface:23 find nth ".item" 3
JavaScript evaluation
cmux browser surface:23 eval "document.title"
cmux browser surface:23 eval "document.querySelectorAll('.item').length"
cmux browser surface:23 eval "window.scrollTo(0, document.body.scrollHeight)"
Frames and dialogs
cmux browser surface:23 frame "#iframe-selector" # switch to iframe
cmux browser surface:23 frame main # back to main frame
cmux browser surface:23 dialog accept
cmux browser surface:23 dialog dismiss
cmux browser surface:23 dialog accept "prompt text"
Cookies, storage, and state
# Cookies
cmux browser surface:23 cookies get
cmux browser surface:23 cookies set session_token "abc123"
cmux browser surface:23 cookies clear
# Local/session storage
cmux browser surface:23 storage local get
cmux browser surface:23 storage local set myKey "myValue"
cmux browser surface:23 storage session clear
# Save/restore full browser state (cookies + storage + tabs)
cmux browser surface:23 state save ./auth-state.json
cmux browser surface:23 state load ./auth-state.json
Authentication flow
BROWSER=$(cmux --json browser open https://app.example.com/login | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux browser $BROWSER wait --load-state complete --timeout-ms 15000
cmux browser $BROWSER snapshot --interactive
cmux browser $BROWSER fill e1 "user@example.com"
cmux browser $BROWSER fill e2 "my-password"
cmux browser $BROWSER click e3
cmux browser $BROWSER wait --url-contains "/dashboard" --timeout-ms 20000
# Save auth for reuse
cmux browser $BROWSER state save ./auth-state.json
# Reuse in a new surface
BROWSER2=$(cmux --json browser open https://app.example.com | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux browser $BROWSER2 state load ./auth-state.json
cmux browser $BROWSER2 goto https://app.example.com/dashboard
Diagnostics
cmux browser surface:23 console list # JS console output
cmux browser surface:23 console clear
cmux browser surface:23 errors list # JS errors
cmux browser surface:23 errors clear
cmux browser surface:23 highlight "#el" # visual highlight
cmux browser surface:23 screenshot # capture screenshot
Script and style injection
cmux browser surface:23 addscript "console.log('injected')"
cmux browser surface:23 addstyle "body { background: red; }"
cmux browser surface:23 addinitscript "window.__injected = true" # runs on every nav
Sidebar Status and Progress
Show live status to the user without interrupting their flow:
cmux set-status agent "working" --icon hammer --color "#ff9500"
cmux set-status agent "done" --icon checkmark --color "#34c759"
cmux clear-status agent
cmux set-progress 0.3 --label "Running tests..."
cmux set-progress 1.0 --label "Complete"
cmux clear-progress
cmux log "Starting build"
cmux log --level success "All tests passed"
cmux log --level error --source build "Compilation failed"
Notifications
cmux notify --title "Task Complete" --body "All tests passing"
cmux notify --title "Need Input" --subtitle "Permission" --body "Approve deployment?"
Agent Teams with cmux
Use cmux splits to give each agent teammate a visible workspace. Coordinate via SendMessage and task lists — never via reading each other's terminal output.
The pattern
- Create splits for each teammate
- Spawn teammates via Agent tool — pass each their cmux surface ref
- Teammates run commands in their split via
cmux send-surface - Teammates report status via
cmux set-statusandcmux log - User sees all work side-by-side
Example: 3-agent team
# Create visible splits for each teammate
SPLIT_1=$(cmux --json new-split right | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
SPLIT_2=$(cmux --json new-split down | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
SPLIT_3=$(cmux --json new-split down | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
Then in each teammate's prompt:
You have a cmux terminal split at surface:42.
Run commands: cmux send-surface --surface surface:42 "command\n"
Read output: cmux capture-pane --surface surface:42
Set status: cmux set-status myagent "working" --icon hammer
Log progress: cmux log "message"
Never steal focus — always use --surface targeting.
Mixed layout: terminals + browsers
BUILD=$(cmux --json new-split right | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
DOCS=$(cmux --json browser open https://docs.example.com | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
TEST=$(cmux --json new-split down | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
Key rules
- Never spawn
claude -pin splits — use the Agent tool withteam_nameinstead - Create splits before spawning teammates — pass refs in their prompts
- One split per teammate — each owns their visible workspace
- Coordinate via SendMessage, not by reading each other's terminal output
- Clean up:
cmux close-surface --surface <ref>when done
Quick Reference
| Task | Command |
|---|---|
| Where am I? | cmux identify --json |
| Split right | cmux --json new-split right |
| Split down | cmux --json new-split down |
| Send command | cmux send-surface --surface <ref> "cmd\n" |
| Read output | cmux capture-pane --surface <ref> |
| Open browser | cmux --json browser open <url> |
| Page snapshot | cmux browser <ref> snapshot --interactive |
| Click element | cmux browser <ref> click e1 |
| Fill input | cmux browser <ref> fill e1 "text" |
| Wait for load | cmux browser <ref> wait --load-state complete --timeout-ms 15000 |
| Read page text | cmux browser <ref> get text body |
| Evaluate JS | cmux browser <ref> eval "expression" |
| Find by role | cmux browser <ref> find role button |
| Save auth | cmux browser <ref> state save ./auth.json |
| Load auth | cmux browser <ref> state load ./auth.json |
| Set status | cmux set-status <key> "text" --icon <name> |
| Progress bar | cmux set-progress 0.5 --label "Working..." |
| Log message | cmux log "message" |
| Notify | cmux notify --title "T" --body "B" |
| Close split | cmux close-surface --surface <ref> |
| Screenshot | cmux browser <ref> screenshot |
Common Patterns
Run build in background split, tail logs
LOG=$(cmux --json new-split down | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux send-surface --surface "$LOG" "cargo build --release 2>&1 | tee /tmp/build.log\n"
# ... do other work ...
cmux capture-pane --surface "$LOG" --scrollback | tail -20
QA test flow
BROWSER=$(cmux --json browser open https://myapp.vercel.app | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux browser $BROWSER wait --load-state complete --timeout-ms 15000
cmux browser $BROWSER snapshot --interactive
# Interact using e1, e2, e3 refs...
cmux browser $BROWSER screenshot
cmux browser $BROWSER errors list
cmux close-surface --surface $BROWSER
Status-driven long task
cmux set-status task "starting" --icon clock --color "#ff9500"
cmux set-progress 0.0 --label "Initializing..."
# ... step 1 ...
cmux set-progress 0.33 --label "Building..."
# ... step 2 ...
cmux set-progress 0.66 --label "Testing..."
# ... step 3 ...
cmux set-progress 1.0 --label "Done"
cmux set-status task "complete" --icon checkmark --color "#34c759"
cmux clear-progress
cmux notify --title "Task complete" --body "All steps passed"
FAQ
What does the cmux-terminal-multiplexer skill do?
AI-native terminal multiplexer with programmable socket API, full Playwright-equivalent browser automation, and agent team coordination — built for Claude Code and autonomous agent workflows
How do I install cmux-terminal-multiplexer?
Run npx skills add https://github.com/reason-machines/trending-skills --skill cmux-terminal-multiplexer in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/cmux-terminal-multiplexer/ (personal) or .claude/skills/cmux-terminal-multiplexer/ (project).
Which AI agents can use cmux-terminal-multiplexer?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is cmux-terminal-multiplexer safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains cmux-terminal-multiplexer?
It is published by reason-machines in reason-machines/trending-skills. It has 1,449 recorded installs.
More from reason-machines/trending-skills
openclaw-control-center
reason-machines/trending-skills
Local-first, security-first control center for OpenClaw agents — visibility dashboard with readonly defaults, token attribution, collaboration tracing, and safe write operations.
inkos-multi-agent-novel-writing
reason-machines/trending-skills
Multi-agent CLI system for autonomous novel writing, auditing, and revision with human review gates
claude-hud-statusline
reason-machines/trending-skills
A Claude Code plugin that displays a real-time HUD showing context usage, active tools, running agents, and todo progress in your terminal statusline.
understand-anything-knowledge-graph
reason-machines/trending-skills
Turn any codebase into an interactive knowledge graph using Claude Code skills — explore, search, and ask questions about any project visually.
agency-agents-ai-specialists
reason-machines/trending-skills
A collection of specialized AI agent personalities for Claude Code, Cursor, Aider, Windsurf, and other AI coding tools — covering engineering, design, marketing, sales, and more.
agent-browser-automation
reason-machines/trending-skills
Headless browser automation CLI for AI agents using native Rust binary with Chrome DevTools Protocol
Popular testing & qa skills
tdd
mattpocock/skills
Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.
grilling
mattpocock/skills
Grill the user relentlessly about a plan, decision, or idea. Use when the user wants to stress-test their thinking, or uses any 'grill' trigger phrases.
migrate-to-shoehorn
mattpocock/skills
Migrate test files from as type assertions to @total-typescript/shoehorn. Use when user mentions shoehorn, wants to replace as in tests, or needs partial test data.
run-train
lllllllama/rigorpilot-skills
Rigor Train skill for deep learning research repositories. Use when a documented or selected training command should be run conservatively for startup verification, short-run verification, full kickoff, or resume, with command, config, seed, log, checkpoint, status, and metric evidence written to standardized trainoutputs/. Do not use for environment setup, exploratory sweeps, speculative idea implementation, or end-to-end orchestration.
test-driven-development
obra/superpowers
Use when implementing any feature or bugfix, before writing implementation code
finishing-a-development-branch
obra/superpowers
Use when implementation is complete, all tests pass, and you need to decide how to integrate the work