multiplexer¶
The tmux abstraction: pane discovery, window splitting, keystroke delivery, and capture used by the spawn and push-notification paths. Read this page to change how cafleet drives tmux. Like every API page, it is for contributors changing cafleet and embedders driving it from Python; CLI users find the command surface in CLI options.
base ¶
Multiplexer Protocol contract for terminal-pane hosting backends.
The :class:Multiplexer Protocol defines the surface CAFleet uses to spawn
coding-agent panes, push keystrokes for message delivery, and reap dead
panes. Only the tmux impl is currently shipped
(cafleet.multiplexer.tmux), but the Protocol exists so alternative
backends (e.g. a screen-based or in-process fake) can be substituted under
test or in future host environments.
MultiplexerContext
dataclass
¶
Resolved pane identity, returned by Multiplexer.context_discovery().
Attributes:
| Name | Type | Description |
|---|---|---|
session |
str
|
Multiplexer session name (e.g. tmux |
window_id |
str
|
Multiplexer window id (e.g. tmux |
pane_id |
str
|
Multiplexer pane id (e.g. tmux |
Source code in cafleet/src/cafleet/multiplexer/base.py
Multiplexer ¶
Bases: Protocol
Terminal multiplexer that hosts coding-agent panes.
Source code in cafleet/src/cafleet/multiplexer/base.py
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | |
ensure_available ¶
Raise if the multiplexer binary is missing or the runtime context is not a live multiplexer session.
Raises:
| Type | Description |
|---|---|
Exception
|
A backend-specific exception when the precondition
fails (e.g. :class: |
Source code in cafleet/src/cafleet/multiplexer/base.py
context_discovery ¶
Resolve the calling shell's pane identity.
Returns:
| Type | Description |
|---|---|
MultiplexerContext
|
class: |
MultiplexerContext
|
and |
Source code in cafleet/src/cafleet/multiplexer/base.py
split_window ¶
Spawn a new pane inside target_window_id running command.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_window_id
|
str
|
Multiplexer window id to split. |
required |
env
|
dict[str, str]
|
Extra environment variables exported into the new pane. |
required |
command
|
list[str]
|
argv list executed in the new pane. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The new pane's id (e.g. tmux |
Source code in cafleet/src/cafleet/multiplexer/base.py
kill_pane ¶
Forcibly close target_pane_id.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_pane_id
|
str
|
Pane id to kill. |
required |
ignore_missing
|
bool
|
If True, do not raise when the pane is already gone — useful for idempotent teardown paths. |
False
|
Source code in cafleet/src/cafleet/multiplexer/base.py
pane_exists ¶
list_pane_ids ¶
Return the set of every live pane id across the multiplexer server.
The per-tick liveness query for cafleet monitor: one call resolves
pane liveness for every agent in a tick (e.g. tmux list-panes -a).
Returns:
| Type | Description |
|---|---|
set[str]
|
A set of pane ids (e.g. |
Source code in cafleet/src/cafleet/multiplexer/base.py
wait_for_pane_gone ¶
Block until target_pane_id disappears or timeout elapses.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_pane_id
|
str
|
Pane id to watch. |
required |
timeout
|
float
|
Maximum seconds to wait. |
15.0
|
interval
|
float
|
Poll interval in seconds. |
0.5
|
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
on timeout. |
Source code in cafleet/src/cafleet/multiplexer/base.py
send_exit ¶
Push /exit + Enter into the pane to gracefully terminate the
coding-agent process.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_pane_id
|
str
|
Pane id to signal. |
required |
ignore_missing
|
bool
|
If True, do not raise when the pane is already gone. |
False
|
Source code in cafleet/src/cafleet/multiplexer/base.py
send_poll_trigger ¶
Keystroke a cafleet message poll shortcut into the pane.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_pane_id
|
str
|
Pane id of the agent to nudge. |
required |
fleet_id
|
int
|
Fleet id embedded in the keystroked command. |
required |
agent_id
|
int
|
Recipient agent id embedded in the keystroked command. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
or the multiplexer is unreachable. |
Source code in cafleet/src/cafleet/multiplexer/base.py
send_resume_trigger ¶
Keystroke a single-line resume nudge into a member's pane.
Unlike :meth:send_poll_trigger (a bare cafleet … message poll),
this carries the poll command plus an instruction to review the
member's current task and continue working — so a member that
unexpectedly stopped resumes rather than going idle on an empty inbox.
The Director receives the bare poll-trigger; only members receive this.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_pane_id
|
str
|
Pane id of the member to nudge. |
required |
fleet_id
|
int
|
Fleet id embedded in the keystroked poll command. |
required |
agent_id
|
int
|
Recipient agent id embedded in the keystroked poll command. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
the multiplexer is unreachable. |
Source code in cafleet/src/cafleet/multiplexer/base.py
send_inline_preview ¶
send_inline_preview(*, target_pane_id: str, task_id: int, sender_id: int, ts: str, text: str) -> bool
Keystroke a 2-line message preview into the recipient's pane.
The first line carries an [cafleet msg <task_id> from <sender_id>
<ts>] header; the second line carries the (possibly truncated)
body. The recipient's coding agent processes the keystrokes as a
fresh user-turn input.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_pane_id
|
str
|
Recipient pane id. |
required |
task_id
|
int
|
Task id of the delivered message. |
required |
sender_id
|
int
|
Sender's agent id. |
required |
ts
|
str
|
Status timestamp string included in the header. |
required |
text
|
str
|
Message body (caller is responsible for truncation). |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
Source code in cafleet/src/cafleet/multiplexer/base.py
send_choice_key ¶
Keystroke a single digit (no Enter) into the pane.
Used by Director-driven AskUserQuestion answers to select one of the
first three options. The tmux backend rejects digits outside
{1, 2, 3}. Enter is not sent because the AskUserQuestion frame
commits the selection on digit press.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_pane_id
|
str
|
Recipient pane id. |
required |
digit
|
int
|
Decimal digit |
required |
Source code in cafleet/src/cafleet/multiplexer/base.py
send_freetext_and_submit ¶
Keystroke 4 + literal text + Enter into the pane.
Used by Director-driven AskUserQuestion freetext answers. The leading
4 selects the "Type something" option in the AskUserQuestion
frame; the literal text is then typed in and Enter submits it. The
tmux backend rejects newlines in text so each call is exactly
one prompt submission.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_pane_id
|
str
|
Recipient pane id. |
required |
text
|
str
|
Literal text to type into the pane (no newlines). |
required |
Source code in cafleet/src/cafleet/multiplexer/base.py
send_bash_command ¶
Keystroke ! <command> + Enter into the pane.
Uses the leading-! shell-shortcut convention honored by every
supported coding-agent backend (claude, codex, opencode),
so a single keystroke path serves all backends.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_pane_id
|
str
|
Recipient pane id. |
required |
command
|
str
|
Shell command to dispatch on the member's behalf. |
required |
Source code in cafleet/src/cafleet/multiplexer/base.py
capture_pane ¶
Return the last lines of the pane's visible buffer as text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
target_pane_id
|
str
|
Pane id to capture from. |
required |
lines
|
int
|
Number of trailing lines to capture (default 30). |
30
|
Returns:
| Type | Description |
|---|---|
str
|
Captured pane text, newline-joined. |
Source code in cafleet/src/cafleet/multiplexer/base.py
poll_until_pane_gone ¶
poll_until_pane_gone(pane_exists_fn: Callable[[], bool], *, timeout: float, interval: float) -> bool
Generic poll-until-False helper for any Multiplexer's wait_for_pane_gone.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
pane_exists_fn
|
Callable[[], bool]
|
Zero-arg callable returning whether the pane is still alive. |
required |
timeout
|
float
|
Maximum seconds to wait. |
required |
interval
|
float
|
Poll interval in seconds. |
required |
Returns:
| Type | Description |
|---|---|
bool
|
|
bool
|
|