Pane Commands
Create, split, launch, signal, close, and wait on panes inside a daemon-managed session.
Panes are the unit of work in vmux. Each pane owns one PTY and tracks one process lifecycle. The pane subcommands are designed for both interactive use ("split this window in half") and scripting ("launch this build, wait for exit, get the code").
| Command | Purpose |
|---|---|
vmux pane create | Create a new pane in an existing session/tab, optionally as a split of another pane. |
vmux pane launch | Run a specific argv inside a pane, with explicit cwd, env, and role. |
vmux pane signal | Send a Unix signal (SIGINT, SIGTERM, custom) to a pane's process. |
vmux pane close | Close a pane and tear down its PTY, optionally --force (SIGKILL). |
vmux wait-pane-exit | Block until a pane reaches a terminal runtime state, exit with the pane's exit code. |
All pane commands work with pane UUIDs. You get those from vmux state, from the return value of vmux pane create, or by listing them with jq on the state JSON.
vmux pane create
vmux [global-flags] pane create
[-s NAME-OR-UUID | --session NAME-OR-UUID]
[--tab UUID]
[--from PANE-UUID]
[--axis horizontal|vertical]
[--role shell|teammate|system|unknown]
[--title STRING]Create a new pane and print its UUID on stdout.
| Flag | Default | Effect |
|---|---|---|
-s, --session, --name | server default | Session to create the pane in. Accepts a name or a UUID. |
--tab UUID | active tab of the session | Tab to create the pane in. |
--from PANE-UUID | none | Split this existing pane in half. Required when you want a split layout. |
--axis horizontal|vertical | inferred | Direction of the split. Only meaningful with --from. |
--role shell|teammate|system|unknown | shell | Logical role; surfaces in state and in GUI clients (e.g. teammate panes get a different chrome). |
--title STRING | empty | Display title shown in chrome. |
Without --from, the new pane is added to the session/tab as a fresh root or sibling. With --from, the targeted pane is split — the existing pane stays alive and the new pane gets the other half.
A freshly-created pane is in idleShell state: there is no process running yet. It does not have a shell unless you also call vmux pane launch.
# Add a pane to the active tab of "work"
NEW=$(vmux pane create -s work --role shell --title "build")
# Split an existing pane vertically (top/bottom)
SOURCE=$(vmux state -s work | jq -r '.tabs[0].activePaneID')
vmux pane create -s work --from "$SOURCE" --axis horizontalSplit axis convention: horizontal means the split line runs horizontally — i.e. one pane stacked on top of another. vertical means the split line is vertical — panes side by side.
vmux pane launch
vmux [global-flags] pane launch <PANE-UUID>
[--cwd PATH]
[--env KEY=VALUE]...
[--title STRING]
[--role shell|teammate|system|unknown]
[--task-id ID] [--task-title STRING] [--agent-name STRING]
[--replace]
-- <argv...>Run a process inside an existing pane. Everything after -- is the literal argv for the new process. The first positional argument before -- is the pane UUID.
| Flag | Default | Effect |
|---|---|---|
--cwd PATH | inherited from daemon | Working directory of the new process. |
--env KEY=VALUE (repeatable) | inherited | Add an environment variable. Repeat the flag to set more than one. |
--title STRING | empty | Pane title to show in chrome while this process runs. |
--role | shell | Logical role recorded with the launch. |
--task-id, --task-title, --agent-name | none | Optional teammate metadata; surfaces in state.panes[].teammate. Source is recorded as vmux-cli. |
--replace | false | If a process is already running in this pane, terminate it before launching. Without this flag, launching into a busy pane fails. |
Examples:
# Run "make test" with a project-local PATH and BUILD_ID
PANE=$(vmux pane create -s ci --role shell)
vmux pane launch "$PANE" \
--cwd "$PWD" \
--env "PATH=$PWD/bin:$PATH" \
--env "BUILD_ID=$BUILD_ID" \
--title "make test" \
-- make test
# Launch an agent-style teammate pane
vmux pane launch "$PANE" \
--role teammate \
--task-id agt-77 --task-title "fix flaky tests" --agent-name "claude-code" \
-- claude-code --task agt-77If the launch fails (binary not found, permission denied, etc.) the command writes vmux: <reason> to stderr and exits 1.
vmux pane signal
vmux [global-flags] pane signal <PANE-UUID> <SIGNAL>Send a Unix signal to the pane's running process.
<SIGNAL> is one of:
- A numeric signal number (e.g.
9). - A symbolic name with or without prefix:
INTorSIGINT,TERMorSIGTERM. Recognized:HUP,INT,QUIT,TERM,KILL,USR1,USR2.
# Polite stop
vmux pane signal "$PANE" TERM
# Hard stop
vmux pane signal "$PANE" KILL
# By number
vmux pane signal "$PANE" 2Exit 0 on success, 1 on failure with a stderr message.
vmux pane close
vmux [global-flags] pane close <PANE-UUID> [--force]Close a pane. The pane's PTY is torn down and the pane is removed from its tab.
| Flag | Effect |
|---|---|
--force | Send SIGKILL to the pane's process group instead of letting it exit cleanly. |
Without --force, the daemon sends SIGHUP to the foreground job and waits for the shell to exit. With --force, the pane is gone immediately regardless of what the process is doing.
If the pane was the last one in its tab, the tab is also removed. If the tab was the last one in the session, the session ends and all attached clients receive sessionEnded.
# Polite close — for an interactive shell, this usually triggers exit
vmux pane close "$PANE"
# Last resort
vmux pane close "$PANE" --forcevmux wait-pane-exit
vmux [global-flags] wait-pane-exit <PANE-UUID> [--timeout SECONDS]Block until the pane's runtime state becomes exited or failed. Used for scripting, where pane launch kicks off a job and the script needs the result.
| Flag | Default | Effect |
|---|---|---|
--timeout SECONDS | 30 | Maximum seconds to wait. Must be a number. On timeout the command exits 1 with vmux: waitForPaneExit timed out. |
On exit:
exited <code>is printed to stdout.- The command exits with the pane's exit code.
On failure:
vmux: <message>is written to stderr.- The command exits 1.
PANE=$(vmux pane create -s ci --role shell)
vmux pane launch "$PANE" --cwd "$PWD" -- ./run-suite.sh
if vmux wait-pane-exit "$PANE" --timeout 600; then
echo "suite passed"
else
echo "suite failed (exit=$?)"
fiThe wait command holds an open observation connection to the daemon and consumes both push events (processExited, processFailed) and polled paneState snapshots. It does not poll busily — it sleeps inside poll(2) until the daemon sends data or the deadline is reached.
Listing panes
There is no dedicated vmux pane ls. Use vmux state and jq:
# Every pane UUID in the work session
vmux state -s work | jq -r '.tabs[].panes[].paneID'
# Pane UUID, role, and runtime state
vmux state -s work | jq -r '
.tabs[].panes[] | "\(.paneID) \(.role) \(.runtimeState.kind)"
'
# Just running teammate panes
vmux state | jq -r '
.tabs[].panes[]
| select(.role == "teammate" and .runtimeState.kind == "running")
| .paneID
'Putting it together
A complete "spin up a build, wait for it, capture exit" script:
#!/usr/bin/env bash
set -euo pipefail
SESSION=ci-build
vmux session create -s "$SESSION" >/dev/null || true
PANE=$(vmux pane create -s "$SESSION" --role shell --title "make all")
vmux pane launch "$PANE" --cwd "$PWD" -- make all
if vmux wait-pane-exit "$PANE" --timeout 1800; then
echo "build ok"
else
rc=$?
vmux pane close "$PANE" --force || true
exit "$rc"
fi
vmux pane close "$PANE"You can also vmux attach -s ci-build from another terminal at any time to watch the build live. When the wait finishes and pane close runs, the attached client will see the session end and exit cleanly.
See also
- Sessions —
state,ls, andsession create. vmux attach— interactive entry into the same panes.- Built-in shell (vsh) — same split/focus vocabulary inside the GUI apps.