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 ​