You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A commit-by-commit history of tmux control mode (tmux -C / -CC), the text
protocol used by iTerm2, WezTerm and similar integrations. For every protocol change:
the introducing commit and the release it first shipped in.
Reconstructed from the source code and git history, not from documentation.
Method
Read-only git archaeology in the upstream tmux repository:
git log --diff-filter=A --follow on control.c / control-notify.c for the origin;
pickaxe git log --all -S/-G '<string>' for each %... notification;
release mapping via git tag --contains <hash> --sort=version:refname, taking the
first real release tag (cross-checked with git describe --contains --match '[0-9]*').
Every hash, date, release and protocol string below was read directly from the repository.
Control mode is a joint effort of George Nachman (author of iTerm2,
tmux@georgester.com — original design and most feature diffs) and Nicholas Marriott
(tmux maintainer, nicm — integration and commits). Both names appear in the copyright
header of control.c / control-notify.c from their very first versions, and nearly every
incremental control-mode commit is annotated "from George Nachman".
Notes
Duplicate commits. The repo interleaves Nicholas Marriott's portable commits with
their "Sync OpenBSD patchset" mirrors. Two changes therefore have an identical hash pair
(same author/date/subject): notifications intro 41a44819 ≡ 9247c90d; guard flags field
a0172a6a ≡ 662d4712. The first of each pair is cited below.
%flags-changed does not exist in tmux — zero occurrences across all refs. It is an
iTerm2-side control-mode concept, never emitted by the tmux server.
No on-wire protocol version. Nothing in the control protocol advertises a version
number. Only the doubled -CC variant emits a handshake: DCS \033P1000p on attach and
ST \033\\ on exit.
Timeline by release
tmux 1.7 (2012) — genesis
Commit
Date
Release
Protocol change
2942eca8
2012-06-18
1.7
Birth. Adds control.c, the CLIENT_CONTROL flag and the -C / -CC command-line options (the doubled -CC additionally enables termios handling). A line-by-line read loop executes each line as a tmux command. %begin / %end are bare (no arguments, emitted from cmd-list.c at this point), plus %error in line "%s": %s for an unparsable line. Deliberately undocumented.
%output %<pane> <data> — the pane output stream sent to the client. The piece that makes -CC usable as a real multiplexer transport.
tmux 1.8 (2013) — consolidation & modern framing
Commit
Date
Release
Protocol change
3964309c
2013-02-23
1.8
Command queue rewrite: guard emission moves into cmd-queue.c (cmdq_guard).
70397e4a
2013-03-04
1.8
A failed command block now closes with %error instead of %end → the %begin / %end / %error triad.
208881a7
2013-03-04
1.8
%exit and %exit <reason> (the reason argument exists from the start). -CC handshake: DCS \033P1000p on attach, ST \033\\ on exit.
801d64a1
2013-03-21
1.8
refresh-client -C W,H — a control client sets its own size. (Subject says "-c" but the code adds uppercase -C.)
c41d92d2
2013-03-11
1.8
Guards gain a timestamp + command number: %begin <time> <number> (likewise %end/%error).
0ef24f99
2013-03-25
1.8
Only send the %end guard if %begin was sent.
7b4084a1
2013-03-11
1.8
Control mode is documented in the man page for the first time.
tmux 1.9 (2014) — final guard shape
Commit
Date
Release
Protocol change
a0172a6a
2013-06-23
1.9
Guards gain a third flags argument → the modern form %begin <time> <number> <flags> (flags = !!(cmd->flags & CMD_CONTROL), i.e. the command itself came from a control client). Current emitter in cmd-queue.c: control_write(c, "%%%s %ld %u %d", guard, t, number, flags).
4c9f41f1
2013-10-10
1.9
flags passed to cmdq_guard as an argument (robustness when cmd is NULL).
%pause %<pane> / %continue %<pane>; the pause-after[=<sec>] flag (via -f); CLIENT_CONTROL_PAUSED.
fddcad69
2020-06-10
3.2
%extended-output %<pane> <age> : <data> — a variant of %output carrying the output age when pause-after is set.
23d79cfd
2020-06-10
3.2
A 300-second limit of buffered data per control client.
50ee4142
2020-06-11
3.2
-A option to pause a pane manually.
Generalized client flags:
Commit
Date
Release
Protocol change
0bdbf47e
2020-05-14
3.2
The active-pane flag.
cf9baddd
2020-05-16
3.2
refresh-client -f (generalized to any client; -F becomes an alias); the read-only and ignore-size flags.
2372b0fd
2020-06-18
3.2
The wait-exit flag: the client waits for an empty line before exiting (avoids stray commands ending up in the shell).
Subscriptions & detach:
Commit
Date
Release
Protocol change
66d5e5de
2020-07-06
3.2
refresh-client -B <name>:<what>:<format> (what = session / @window / %pane) + %subscription-changed <name> $<sess> <@win|-> <idx|-> <%pane|-> : <value>. Subscribe to a format instead of polling (GitHub #2242).
8b800b41
2021-03-16
3.2
%client-detached <client> (from Mohsin Kaleem).
tmux 3.3 (2021) — per-window size
Commit
Date
Release
Protocol change
fd756a15
2021-08-27
3.3
refresh-client -C @<win>:<W>x<H> — a hard per-window size limit (sscanf "@%u:%ux%u"); @<win>: alone clears it (GitHub #2594). The old -C W,H / WxH form still works.
tmux 3.4 (2023) — buffer & message notifications
Commit
Date
Release
Protocol change
a888ce99
2022-06-20
3.4
%config-error <msg> — config file errors sent to the control client instead of a pane (GitHub #3193).
7c2dcd72
2022-08-15
3.4
%paste-changed (initial name). From George Nachman (GitHub #3302).
8edece2c
2022-10-28
3.4
Renamed to %paste-buffer-changed <name> + new %paste-buffer-deleted <name>. (Both final forms first exposed in 3.4.)
93b1b781
2023-02-05
3.4
%message <msg> — display-message works for control clients (GitHub #3449).
tmux 3.5 (2025) — peripheral
Commit
Date
Release
Protocol change
093b5a55
2024
3.5
refresh-client -r — OSC 10/11 (color) responses; peripheral to the core protocol.
One-line recap per milestone
2942eca8 — 1.7 — skeleton: -C/-CC, bare %begin/%end, %error in line.