Skip to content

tmux compatibility shim for AI tool integration #185

@srid

Description

@srid

Summary

Create a kolu-tmux CLI shim that implements the subset of tmux commands used by AI coding tools (Claude Code, etc.), translating them to Kolu HTTP RPC calls.

Depends on #184 (plain-text screen capture API) for capture-pane support.

Motivation

AI tools like Claude Code use tmux as a standard interface to discover, read, and write to terminals. A shim lets these tools work with Kolu without upstream changes.

Scope

Shim binary (kolu-tmux)

Parses tmux subcommands and flags, dispatches to Kolu's existing HTTP RPC (/rpc/*).

Commands to support:

Command Maps to
-V (version) Return fake version string
has-session -t name /api/health
list-sessions [-F fmt] Single "kolu" session
list-windows [-t session] [-F fmt] terminal.list(), top-level only
list-panes [-t window] [-F fmt] terminal.list(), filter by parentId
capture-pane -p [-t target] [-S start] [-E end] [-J] terminal.screenText (#184)
send-keys [-t target] [-l] text [key...] terminal.sendInput
new-session -s name [-c path] terminal.create
new-window [-t session] [-c path] terminal.create
split-window [-t window] [-h|-v] [-c path] terminal.create({ parentId })
kill-pane -t target terminal.kill
resize-pane -t target -x W -y H terminal.resize
break-pane / join-pane terminal.setParent
show-options -g prefix Return synthetic prefix
set-option (pane border colors, etc.) No-op (acknowledge silently)
select-layout No-op (Kolu sub-terminals are tabs, not spatial)

Target resolution

Resolve tmux-style targets (session:window.pane, %pane-id, numeric indices) to Kolu terminal UUIDs. Window index = position in terminal.list() order; pane index = sub-terminal order within parent.

-F format string evaluator

Support the format variables Claude Code actually uses: #{session_name}, #{window_index}, #{window_name}, #{pane_id}, #{pane_pid}, #{pane_current_path}, #{pane_active}, etc.

Environment injection

  • Set $TMUX in PTY shells (format: <socket>,<pid>,0) so tools detect multiplexer presence
  • Set $TMUX_PANE to a unique synthetic pane ID per terminal (e.g. %0, %1, %2... derived from terminal index) — this is how Claude Code identifies its "leader pane" and scopes teammate operations
  • Put kolu-tmux on $PATH as tmux within Kolu shells (symlink or wrapper)

Multi-instance isolation

A user may run Claude Code in N different Kolu terminals simultaneously (each in a different repo). Each instance must be isolated:

  • $TMUX_PANE per terminal — Claude Code reads $TMUX_PANE at startup to identify its leader pane. Each Kolu terminal gets a unique pane ID, so each Claude Code instance knows which pane is "self".
  • split-window without -t — must create a sub-terminal under the calling terminal (resolved from the caller's $TMUX_PANE). The shim needs to accept $TMUX_PANE from the calling environment to determine context.
  • Kolu's concept mapping — 1 Kolu server = 1 tmux session; N top-level terminals = N tmux windows; sub-terminals = panes within a window. Each Claude Code instance lives in its own window and creates teammate panes (sub-terminals) within that window only.
  • -L <socket> flag — Claude Code uses per-PID socket names for isolation in "external session" mode. Inside tmux (our case), it uses the existing session, so this is less critical. The shim should accept and ignore -L.

Claude Code integration

Once implemented, Claude Code's multi-agent (teammate/swarm) feature will work inside Kolu terminals with zero user configuration. Here's how:

How it works (automatic)

Claude Code detects tmux at startup via two checks:

  1. $TMUX env var — if set, Claude Code knows it's "inside tmux" and uses its TmuxBackend for teammate pane management
  2. tmux -V — checks if the tmux binary is available (the shim responds to this)

Since Kolu injects both $TMUX and the shim binary into PTY shells, Claude Code will automatically detect tmux support and use it. No settings changes needed.

What Claude Code uses tmux for

Claude Code does not use tmux for its own command execution (the Bash tool spawns processes directly). tmux is used exclusively for:

  • Agent teams: split-window to create teammate panes, send-keys to dispatch commands, kill-pane to clean up
  • Pane management: break-pane/join-pane to hide/show teammate panes, pane border colors for visual identification
  • Worktree sessions: --tmux -w flag creates a tmux session per worktree

Relevant Claude Code settings

Setting Values Effect
teammateMode "auto" (default), "tmux", "in-process" "auto" auto-detects tmux; "tmux" forces it; "in-process" disables pane creation
preferTmuxOverIterm2 true/false Irrelevant in Kolu (no iTerm2)

Users can override per-session with --teammate-mode tmux or --teammate-mode in-process.

Verifying it works

Inside a Kolu terminal:

# Should return the shim's version string
tmux -V

# Should show the kolu session
tmux list-sessions

# Launch Claude Code with teammates — panes appear as Kolu sub-terminals
claude --tmux -w

Additional shim commands for Claude Code teammate support

Beyond the basic tmux subset, Claude Code's TmuxBackend also uses:

  • select-layout — pane layout (main-vertical, tiled) — no-op in Kolu (sub-terminals are tabs, not spatial)
  • set-option pane-border-style — teammate color coding — no-op (Kolu could map to per-terminal theme accents in the future)

Non-goals

  • Full tmux protocol compatibility (only the subset AI tools use)
  • tmux control mode (-CC)
  • Copy mode / key bindings / status bar emulation

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions