Skip to content
Registry

tmux

v0.1.1

tmux as an iii worker — list, create, rename and kill sessions and windows, see which pane runs Claude Code or Codex (working, waiting for you, idle), which runs `iii compose` and every listening port by process and pane, plus a Console page whose terminal is a live tmux client.

license: Apache-2.0agentsconsolemultiplexerportssessionsterminaltmux

Install

bash
iii trigger compose::add worker=tmux@next

Run in your project with the iii engine running. Exact versions are immutable and digest-pinned.

iii-config.yaml
- max_terminals: 8
  poll_interval_ms: 1000
  ports_interval_ms: 3000
  terminal_idle_timeout_ms: 30000
  tmux_binary: tmux

tmux

tmux as an iii worker. It lists every tmux session, window and pane on the host, creates, renames and kills sessions and windows, and tells you what is running where: which pane holds Claude Code or Codex and whether that agent is working, waiting for you or idle, which pane runs iii compose and on which port its engine listens, and every TCP port your processes listen on, traced back to the pane that started them. Its Console page embeds a terminal that is a real tmux client: what you type goes straight into the session, and the screen updates as tmux draws it, the same way a second terminal attached with tmux attach would.

Install

iii trigger compose::add worker=tmux

The worker drives the tmux binary installed on the host (Linux or macOS) and talks to the same tmux server you use from your terminal. Without tmux it still starts and reports available: false.

Quickstart

Open the tmux page in the Console to browse sessions, open one in the terminal, and see the Ports tab. From code or an agent:

# Every session → window → pane, with agent / compose / port status
iii trigger tmux::sessions::list

# A new session running a dev server, then a second window in it
iii trigger tmux::sessions::create name=api cwd=~/code/api command="pnpm dev"
iii trigger tmux::windows::create session=api name=logs

# Who listens on which port, and which compose stacks are up
iii trigger tmux::ports::list

A pane running an agent and a pane running iii compose look like this in tmux::sessions::list:

{ "id": "%3", "command": "claude",
  "agent": { "id": "claude", "label": "Claude Code", "state": "waiting", "since_ms": 1791936000000,
             "title": "Fix the login redirect" } }
{ "id": "%7", "command": "iii:c:default",
  "compose": { "namespace": "default", "pid": 2759592 },
  "ports": [ { "port": 49135, "role": "engine", "process": "iii:e:default" },
             { "port": 3111, "role": "worker", "worker": "http" },
             { "port": 3114, "role": "worker", "worker": "ade" } ] }

Agent state comes from the pane's last lines: a permission or choice prompt is waiting, Claude Code's esc to interrupt line is working. The agent's title is the session title it put on its pane (Claude Code's conversation topic) without the ✳ or spinner in front; it is null while the pane shows tmux's default title, the host name. Selecting a window (tmux::windows::select) works like tmux itself: every client attached to that session, your own terminal included, switches to it.

Panes work the same way. tmux::panes::select makes a pane active and, with zoom: true, zooms the window on it the way prefix z does, for every client looking at that window; zoom: false unzooms. tmux::panes::capture returns a pane's visible screen with its colour escapes, its size and cursor:

iii trigger tmux::panes::select pane=%3 zoom=true
iii trigger tmux::panes::capture pane=%3

Configuration

tmux_binary: tmux            # name on PATH or absolute path (never this worker's own binary)
socket_name: null            # tmux -L <name>; null = your default tmux server
socket_path: null            # tmux -S <path>; wins over socket_name
poll_interval_ms: 1000       # live feed cadence for sessions and agent state
ports_interval_ms: 3000      # process and listening-port re-scan cadence
busy_window_ms: 2000         # agents without working patterns: "working" while the pane changed this recently
command_timeout_ms: 5000     # one tmux command
max_terminals: 8             # concurrent Console terminals (each one is a tmux client)
terminal_idle_timeout_ms: 30000  # detach a Console terminal its page stopped heart-beating
agents:                      # first match wins; patterns are case-insensitive regexes over the pane's last lines
  - id: claude
    label: Claude Code
    process: [claude]
    working_patterns: ["esc to interrupt"]
    waiting_patterns: ["❯\\s*1\\.\\s*Yes", "Do you want to proceed\\?", "Enter to select"]

The built-in list also recognises codex, opencode and gemini; see src/config.rs. Edit the configuration from the page's settings action or with configuration::set.

Custom trigger types

Trigger type Fires when Payload to subscribers
tmux::changed Once when bound, then whenever sessions, windows, panes, agent states, compose stacks or listening ports change { sessions, ports } — the same shapes tmux::sessions::list and tmux::ports::list return

Bind it with config: {}. The worker only polls tmux while at least one binding exists.

Search the registry

Find workers, kits and executables, or jump to a page.