Skip to content

tmux is a terminal multiplexer that allows you to run multiple terminal sessions within a single window. Open Orchestrator uses tmux to manage isolated terminal environments for each worktree.

Why tmux?

tmux provides several key benefits for parallel development:

  1. Session Persistence - Sessions survive terminal disconnections
  2. Background Execution - AI tools run even when you're not attached
  3. Control Plane Architecture - A persistent session hosts the prioritized control plane UI
  4. Programmatic Control - Send commands to specific panes

Control Plane Session Architecture

Open Orchestrator uses a two-tier tmux session model:

The Control Plane Session

When you run owt (no arguments), a persistent tmux session named owt-switchboard is created. This session hosts the Textual-based Control Plane UI -- a prioritized decision surface with NEEDS YOU / READY TO SHIP / IN FLIGHT sections -- and stays alive as long as you have active worktrees.

Per-Worktree Sessions

Each worktree gets its own tmux session named owt-{sanitized-branch-name}:

owt-switchboard          (persistent, hosts the Control Plane UI)

  ├── owt-feat-auth      (worktree session, running Claude Code)
  ├── owt-fix-login      (worktree session, running OpenCode)
  └── owt-feat-api       (worktree session, running Droid)
ActionEffect
a (in the Control Plane)Attach to the selected worktree session
Alt+s (in any session)Switch back to the Control Plane
Alt+c (in any session)Open the AI tool picker popup

This creates a fluid workflow: Control Plane -> attach to agent -> work -> Alt+s back to the Control Plane -> attach to another agent.

How Open Orchestrator Uses tmux

Session Creation

When you create a worktree with owt new "Add user authentication":

  1. A tmux session named owt-feat-user-authentication is created
  2. The working directory is set to the worktree path
  3. A single pane is created (default layout)
  4. The AI tool is started in the pane

Session Naming

Sessions follow the pattern: owt-{sanitized-branch-name}

BranchSession Name
feat/authowt-feat-auth
fix/login-issueowt-fix-login-issue
refactor/db-queriesowt-refactor-db-queries

Default Layout

By default, each worktree session has a single pane with the AI tool running in it. This is the simplest and most common configuration.

┌─────────────────────────────┐
│                             │
│        Claude Code          │
│                             │
│                             │
└─────────────────────────────┘

MAIN_VERTICAL Layout

For users who want a shell alongside the AI tool, the MAIN_VERTICAL layout splits the terminal:

┌─────────────────┬───────────┐
│                 │           │
│   Claude Code   │   Shell   │
│     (60%)       │   (40%)   │
│                 │           │
└─────────────────┴───────────┘

Configure this in .worktreerc:

toml
[tmux]
default_layout = "MAIN_VERTICAL"

Global Keybindings

Open Orchestrator registers these tmux keybindings that work from any worktree session:

KeybindingAction
Alt+sSwitch back to the Control Plane
Alt+mMerge current worktree
Alt+dDelete current worktree
Alt+cCreate a new worktree (opens popup)

These keybindings are registered when the Control Plane starts and work across all owt-* sessions.

Mouse Mode

tmux mouse mode can be enabled for click-to-select and scroll support:

toml
[tmux]
mouse_mode = true

This enables:

  • Click to select panes (in multi-pane layouts)
  • Scroll through output with the mouse wheel
  • Resize panes by dragging borders

Sending Keys to Panes

The owt send command uses tmux's send-keys to transmit commands:

bash
# Send a task to an AI agent
owt send feat/auth "implement login form"

# Send without pressing Enter
owt send feat/auth "partial command" --no-enter

Paste-Buffer for Long Prompts

For long prompts, Open Orchestrator delivers them using tmux's load-buffer + paste-buffer instead of send-keys -l. This avoids the send-keys character limit (~2K) which can silently truncate long prompts (e.g., structured session-init protocols with project context).

The delivery pipeline:

  1. Write prompt text to a temp file
  2. tmux load-buffer <file> — loads into a tmux paste buffer
  3. tmux paste-buffer -d -t <pane> — pastes into the target pane
  4. tmux send-keys Enter — submits the pasted text

AI Readiness Detection

Before delivering a prompt, Open Orchestrator polls the pane content for up to 15 seconds, looking for signs the AI tool is ready for input:

  • Input prompt indicators>, Human:, claude>, droid>
  • Claude startup banner — detects "claude" or "anthropic" in pane output
  • Permission prompts — logs a warning but proceeds (the agent is interactive)

If no readiness signal is detected within the timeout, the prompt is sent anyway with a logged warning.

Configuration

Configure tmux behavior in .worktreerc:

toml
[tmux]
# Automatically start AI tool in the pane
auto_start_ai = true

# Which AI tool to start
ai_tool = "claude"  # claude, pi, opencode, droid

# Session name prefix
session_prefix = "owt"

# Enable mouse support
mouse_mode = false

# Custom tmux prefix key
prefix_key = "C-b"

tmux Tips

Common tmux keybindings (prefix is Ctrl+B by default):

KeyAction
Ctrl+B, dDetach from session
Ctrl+B, oSwitch to next pane
Ctrl+B, arrowMove to pane in direction
Ctrl+B, [Enter scroll mode
Ctrl+B, zToggle pane zoom

Session Management

bash
# List all sessions
tmux ls

# Attach to session
tmux attach -t owt-feat-auth

# Kill session
tmux kill-session -t owt-feat-auth

Customizing tmux

Your ~/.tmux.conf settings apply to Open Orchestrator sessions. Common customizations:

bash
# Change prefix to Ctrl+A
set -g prefix C-a

# Enable mouse
set -g mouse on

# Start window numbering at 1
set -g base-index 1

Troubleshooting

"Session not found"

The tmux session may not exist. Check available sessions:

bash
tmux ls
owt list

"No AI tool running"

The AI tool may have crashed or exited. Attach to the session from the Control Plane (press a) and restart the tool manually.

Commands Not Being Received

Ensure the worktree session exists and the AI tool is running:

bash
# Check active worktrees
owt list

# Attach via the Control Plane
owt

Next Steps