Core LibraryunreleasedGuides

Choose documentation 2

latest

Current version

latest
English

Unreleased libtmux has not been released. Its API may change during development. This site's structure and URLs may change too.

Explicit operations

Named operations take the connection client first and a captured target where needed. They read current state to validate the target, then use its identity. Earlier captures remain unchanged. Every operation accepts :cancel-token, :timeout and :output-limit; the latter two default to the client settings and cover validation, dispatch and any follow-up acquisition together.

The current APIs require a live daemon. new-session creates a session there; daemon bootstrap is a separate unfinished part of the implementation.

OperationTarget / result
rename-window, rename-sessionPhysical entity; command outcome with optional replacement
select-windowWindow link, preserving session/index context
select-panePhysical pane
next-window, previous-window, last-windowSession; outcome containing its selected window link
last-panePhysical window; outcome containing its selected pane
new-sessionSelected live daemon; outcome containing the created session
new-windowCaptured session; outcome containing the physical window
split-paneCaptured pane; outcome containing the new pane
capture-panePane; UTF-8 text and diagnostic outcome as two values
capture-pane-bytesPane; owned octets and diagnostic outcome as two values
send-text, send-keys, send-prefixPane; command outcome for the send request
respawn-pane, respawn-windowPhysical target; explicit process replacement and optional captured result
pipe-panePane; explicit shell source, direction and daemon-owned pipe
switch-clientCaptured terminal client and destination session; outcome with optional replacement
detach-client, refresh-client, suspend-client, lock-clientCaptured terminal client; outcome acknowledging the request
lock-session, lock-serverFrontends attached to a captured session or the addressed daemon; request outcome
wait-forLiteral server channel; signal, wait, lock or unlock outcome
clear-history, copy-modePane; command outcome
resize-pane, resize-windowPhysical target; outcome with optional replacement
select-layout, next-layout, previous-layoutPhysical window; outcome with optional replacement
link-window, move-window, break-paneExplicit link/session/index context; outcome containing the destination link
swap-windows, swap-panesTwo targets; outcome containing a fresh vector in argument order
unlink-windowWindow link; outcome without a replacement
move-pane, join-pane, rotate-windowPhysical targets; outcome with optional replacement
list-buffersFresh vector of metadata plists and diagnostic outcome
show-bufferOwned octets and diagnostic outcome
set-buffer, load-buffer, save-buffer, delete-buffer, paste-bufferExplicit buffer data/path/name and optional pane; command outcome
set-option, unset-optionTyped live-catalog option mutation in one explicit table
set-hook, unset-hookTmux command-source installation/removal; never evaluates source as Lisp
set-environment, unset-environment, remove-environmentRaw global/session environment value, deletion or tombstone
kill-pane, kill-window, kill-sessionExact captured entity; outcome without replacement
kill-serverRetained live daemon; proven process exit or uncertain outcome

Creation defaults to detached mode. Selection uses explicit captured targets. new-window :index chooses a free session index. split-pane accepts :horizontal (left/right) or :vertical (top/bottom), with a cell :size or :percent. Creation returns a fresh captured entity through outcome-value.

For typed option/hook values, inherited table reads and environment presence, see decoded configuration. Raw printers remain available for unrestricted native inspection.

Names and child commands

Names and creation :cwd strings are literal, including #[...] and #{...} text. Rename’s :format-p t explicitly requests tmux format expansion. Tmux can normalize or reject a name; inspect the replacement observation for the resulting name. Cwd text follows tmux’s own relative-path rules. Tmux can fall back from an inaccessible cwd; use child-side evidence when the exact directory matters.

Creation accepts a nonempty :command list/vector of argv strings or a separate :shell-command string. Omission selects tmux’s default shell. Supplying an empty argv is invalid. Strings may contain spaces, quotes, semicolons, dollar signs, backslashes and Unicode; the encoder preserves their argument boundaries. One-element argv starts that executable with no added program argument. :environment is a list/vector of (name . value) string pairs.

The final encoded tmux command is limited to 16,000 UTF-8 bytes, including NUL terminators between argv entries. Nested command quoting counts toward this limit. Oversized named commands fail before their payload is dispatched. They are never silently split into multiple mutations.

Terminal input

send-text preserves literal text such as C-c; :enter t appends one Return key in the same request. send-keys accepts a nonempty list/vector of tmux key strings and a positive :repeat count. Tmux recognizes names such as C-c and Enter, and falls back to literal input for unrecognized strings. send-prefix uses the configured prefix; :second t selects prefix2.

The pane’s current tmux mode handles input. Successful dispatch means tmux processed the send request; it does not establish application consumption or readiness. Coordinate dependent work through an application signal.

copy-mode enters copy mode; :page-up t scrolls on entry, and :exit t exits. Page-up and exit are mutually exclusive. clear-history removes retained tmux history; it does not promise to clear the application’s current screen.

Geometry and selection

resize-pane and resize-window accept positive cell :width/:height, or a :direction (:left, :right, :up, :down) with positive :amount (default one). Absolute dimensions range from 1 through 10,000, the common supported range. Relative amounts range from 1 through 2,147,483,647. Tmux may clamp the actual layout; the replacement observation contains the resulting dimensions.

Pane :zoom t toggles zoom. Window :fit :smallest or :fit :largest fits the attached clients. These modes cannot be combined with dimensions or direction. A window resize sets tmux’s window-size option to manual.

select-layout accepts :even-horizontal, :even-vertical, :main-horizontal, :main-vertical, :tiled, or (:custom "tmux-layout-description"). Tmux validates custom checksums and geometry. Layout operations unzoom the window. next-layout and previous-layout follow tmux’s layout ordering.

next-window, previous-window and last-window take a captured session and return its newly observed active window link through outcome-value. Next and previous accept :activity t to restrict selection to alerting windows. last-pane takes a physical window and returns its observed active pane. Tmux signals when no last selection exists. These operations and geometry accept :observe nil to omit follow-up acquisition.

Attached terminal clients

Fetch-clients returns attached-client observations; they are distinct from the library connection passed as the first argument. The five client operations above require an ordinary terminal client captured through that connection. They reject control-mode observations. Preflight requires one matching name and the same PID, creation time and tty. It also rejects a name that matches another client’s full or abbreviated tty. A missing, replaced or foreign observation signals stale-target. Tmux has no dispatch-side client fingerprint guard across the supported floor, so replacement between preflight and dispatch remains possible.

switch-client takes an explicit destination session. It preserves that session’s environment by default; :update-environment t applies tmux’s update-environment option using the attached client’s environment. Its default :observe t acquires a replacement client observation; :observe nil omits that read. The earlier observation still points to its captured session.

refresh-client schedules a full redraw; :status-only t schedules only the status line. Refresh instead acquires a replacement observation. detach-client requests detachment of the selected client. suspend-client requests native SIGTSTP suspension; the controlling application owns resumption. lock-client asks the frontend to execute its configured lock-command through a shell. An already suspended client can make suspend or lock a no-op; an empty or oversized lock command is also ignored by tmux. These four calls return no replacement observation.

Success acknowledges the server’s request. It does not prove frontend exit, terminal restoration, completed redraw, process suspension, lock startup or authentication. Coordinate dependent work through the frontend’s own completion signal. Missing dispatch/completion evidence remains an unknown outcome; the library never retries these requests automatically.

lock-session requests locking for frontends attached to the selected session when tmux executes the command. lock-server requests it across the addressed daemon. Both use live membership, including frontends attached after the caller’s capture. They return one request outcome, with no per-frontend results. Control clients, already suspended frontends and empty or oversized lock commands are skipped; no eligible frontends is a successful no-op.

These requests run the configured frontend lock programs. They do not block other tmux commands or suspend pane processes. Closing the library client leaves the frontend programs running. Hooks can add effects or fail after requests have been sent, so a failed outcome does not undo a lock request. See tmux’s server_lock.

Message printing

display-message returns two values: owned strict UTF-8 text and its diagnostic command outcome. It uses tmux’s ordinary -p printer and preserves whitespace, including the final newline. Message text is literal by default, including #{...}, #(...), #[...] and %Y. Literal input disables expansion; it does not make the printer a byte-identical echo. Native versions can escape output, including $ on 3.4. The API retains that presentation rather than interpreting it as decoded field data.

An optional :target accepts a captured session, physical window, pane or window link owned by the supplied client. Use a link when its session and index matter. Physical windows and panes let tmux choose their session context; omitting the target lets tmux choose the complete context. Authority and stale link checks apply before the request. The call acquires no replacement.

:format-p t explicitly enables tmux format and time expansion. A #() expression may start a shell job, but expansion does not wait for its result. A fresh command client may print an empty or incomplete result. Those jobs belong to the native command client and are cleaned up on its disconnect; this API does not provide job completion or background process ownership.

After-hooks can print additional text or have effects. The returned text retains that output; it does not establish a single field’s value or presence. Use captured getters for local field reads. Decoded configuration acquisition remains a separate capability. Invalid UTF-8 raises decoding-error with the outcome’s original bytes.

Tmux 3.4 and newer provide native literal printing. The 3.3a fallback escapes format and time syntax and conservatively limits the intermediate after time expansion to 8,191 UTF-8 bytes. That limit is checked after live-version preflight and before payload dispatch. The encoded command limit also applies. See cmd_display_message_exec.

Commands and key bindings

list-commands and list-keys return ordinary UTF-8 printer text and the retained outcome. Both preserve native escaping, whitespace and after-hook output. The result is intended for inspection, not replay or decoded configuration lookup.

list-commands lists built-ins. Its optional :command accepts exact names or built-in aliases; configured command-alias entries are not part of that table. Through tmux 3.5a, an unknown selector produces no rows. From 3.6, unique prefixes work, while unknown or ambiguous selectors fail.

list-keys accepts an optional literal :table and :key. Omitted table means all tables. Unknown tables and invalid key syntax remain errors. A valid but unbound key is an error except on tmux 3.7 through 3.7c, which return empty text. Those four releases also send a single matching row to the server message log and any selected frontend’s status line instead of stdout, including with :format. Multiple matching rows print normally. Empty text therefore does not establish that a binding is absent, and inspection can display a status message. The native single-row branch changes in tmux 3.8.

Its :format requires tmux 3.7 or newer; older daemons reject it before payload dispatch. Both listing functions accept explicit tmux format source without time expansion, so %Y stays literal. Empty formatted rows may be omitted. Format jobs have the same asynchronous lifetime limits as message printing.

bind-key replaces one binding in :table, which defaults to "prefix". Supply exactly one of :command argv or :command-source, explicit tmux source. The argv form preserves token boundaries and rejects = in its command-name token. :note is literal text; :repeat t enables native repetition. The stored command nodes run when tmux dispatches that key, using the key event’s context. This does not carry a captured target’s authority into future execution.

Tmux parses binding source immediately. Assignments and directives can alter the daemon’s environment before a later parse error. Aliases resolve during binding and can introduce parser effects even through argv. A failed bind is not a rollback; missing completion evidence can leave its outcome unknown. Keep source and aliases under the application’s control. See tmux’s cmd_bind_key_exec and assignment grammar.

unbind-key removes exactly one key, also from "prefix" by default. A missing key in an existing table is a no-op; an absent table is an error. Removing a table’s last binding may delete the table, so a second removal need not succeed. Neither helper retries or implicitly removes all bindings. Binding success acknowledges storage and hooks, not later key execution. send-keys sends pane input and does not exercise a frontend’s key-binding dispatch.

Server access

server-access takes a literal account name and one access operation. :allow adds a writable entry; :deny removes one; :read-only and :read-write update or add an entry. Duplicate additions and missing removals remain errors. Tmux resolves names through the daemon’s name service; strings are not treated as numeric UIDs. Root and the daemon-owner UID cannot be changed. :group-p t selects a group name and requires live tmux 3.8; older daemons reject that request before payload dispatch.

Removal does not create a deny rule. From tmux 3.8, a user without an explicit entry can still match its connecting peer’s GID. An explicit UID entry wins over the GID entry; supplementary groups are not searched. Socket and directory access must be configured separately; an ACL entry alone does not make the endpoint reachable.

Permission changes can affect connected clients. In tmux 3.8, removal and read-only/read-write updates recompute every client’s effective ACL. A writable entry can therefore clear an unrelated frontend’s separately set read-only flag. A request can schedule disconnection without proving frontend exit, and a later grant does not cancel an already scheduled exit. :allow alone does not recompute connected-client flags. Earlier captures retain their values; use refresh to acquire a replacement observation. See the native command and ACL update.

list-server-access returns ordinary UTF-8 listing text and an outcome. Native rows use (R)/(W) before 3.8 and include U/G account kinds from 3.8. UID 0 is omitted; a failed name lookup prints unknown. Empty text cannot establish that nobody has access. This listing is intended for inspection and is not a decoded authorization model.

Tests cover entry lifecycle, literal input, version gates and the frontend flag effect on private sockets under one OS user. Cross-user connection, authorization and revocation behavior remain unverified by this library’s suite. No test changes users, socket permissions or privileges. Calls retain uncertain outcomes and never retry automatically.

Wait channels

wait-for accepts :operation :wait (the default), :signal, :lock or :unlock, and a nonempty literal channel name. Signal and unlock work on the supported tmux floor. Wait and lock require tmux 3.8’s client-loss cleanup; older daemons signal unsupported-capability before dispatch. This is a capability restriction, not a change to the core tmux floor.

A signal wakes existing waiters. With none waiting, one signal leaves a pending wake; a second can remove it. This is neither an idempotent latch nor a counting semaphore. Use an application protocol when acknowledgements or sender identity matter. Server shutdown can also flush waiting requests.

Locks belong to the daemon channel, not a Lisp client or thread. They survive a completed call and client closure within the daemon’s lifetime. Unlock explicitly; no resource macro or automatic cleanup unlocks them. Signals and locks share native channel state, so use different channel names for those protocols.

Each call blocks its caller. Use a second connection client to signal or unlock another client’s pending operation. Timeout and byte limits include preflight. Cancellation removes the owned command process; tmux 3.8 removes a disconnected queued waiter. Cancellation or lost receipts cannot prove that a signal was not consumed or a lock was not granted. Inspect the retained outcome and coordinate recovery through the application; the library does not retry a channel request. See cmd_wait_for_client_lost.

link-window and move-window take a source window link, a destination session and an explicit free index. The source link preserves session group context. Neither overwrites an occupied index. Moving removes only the selected source link; removing a session’s last link can destroy that session. unlink-window refuses a last reference unless :kill-if-last t is explicit; tmux session groups affect its last-reference check.

swap-windows takes two links and returns their replacement links in argument order. :select t selects the affected indexes; omission retains current indexes. An old link whose index now points at another window is stale.

move-pane and join-pane take source and destination physical panes. :direction, :size, :percent, :before and :full-size control placement; :detached t is the default. An emptied source window and all its links are destroyed. With :detached nil, tmux chooses the session context of the physical destination. Percentage sizing follows the installed tmux semantics: with :full-size t, 3.3a uses the destination pane’s dimensions while 3.8 uses the whole window. Use :size for cell-based control.

break-pane takes the pane, its explicit source link, a destination session and a free index. This source link matters when the pane is its window’s only pane: tmux moves that link while preserving other links and the physical window. The outcome contains the destination link. Its optional :name is literal.

Tmux 3.7 has an inverted new-window naming branch, corrected in 3.7a. The library selects the safe branch from the live pane count within the guarded request. For a new window with an explicit name, it follows the break with rename-window targeting the moved pane. This adds no subprocess or retry, but can run an after-rename-window hook and is not transactional: a failing hook can leave the pane moved and renamed. Inspect the retained command outcome before deciding what to do next. Unnamed single-pane moves keep their existing name and automatic-rename setting. See cmd_break_pane_exec in 3.7 and the corrected 3.7a branch.

swap-panes preserves physical IDs and returns replacements in argument order. rotate-window moves pane positions :up (default) or :down and advances the active pane. Both accept :preserve-zoom t. Placement operations preserve older observations; a successful operation may have a separate observation failure. Unlink has no replacement to observe.

Pane processes

respawn-pane restarts its process. respawn-window restarts the physical window as one pane, retaining its first pane and destroying every other pane, including through other session links. Neither kills a running process unless :kill t is supplied. Omit both :command and :shell-command to reuse the stored command; explicit argv, shell text, cwd and environment follow creation. By default, outcome-value supplies a new observation. Earlier captures remain local and unchanged. A fast-exiting process can disappear before acquisition.

pipe-pane accepts explicit :shell-command source. It preserves literal # and % text by default; :format-p t enables tmux format and time expansion before the shell runs. Literal commands must fit tmux’s 8,191-byte time-format capacity after format escaping. :direction is :output (pane to shell), :input (shell to pane) or :both. Omitting the command closes the pipe. :toggle t closes an existing pipe without starting its replacement.

Pipe success acknowledges configuration. It does not prove shell startup, command success or data consumption. Coordinate dependent work through an application signal. Tmux owns the pipe child, and closing the library client leaves it running. Pipe replacement or explicit closure releases the pane’s connection to that child.

Buffers

list-buffers returns a fresh vector of plists with :buffer/name, :buffer/size in bytes and :buffer/created in Unix seconds. It preserves tmux’s listing order, limits decoding to 10,000 rows by default, and returns #() when empty. Names are mutable locators, not captured entity identities.

set-buffer accepts a literal NUL-free string or an octet vector. Octets travel through tmux’s stdin buffer loader and preserve NUL and invalid UTF-8. :append t is supported for strings. show-buffer returns owned octets without decoding. Both accept a literal :name; setting without a name creates an automatic buffer. Creation through set/load rejects backslashes, ASCII controls and DEL before I/O because tmux versions otherwise rewrite or reject them. Spaces and Unicode are supported. Looking up an existing buffer preserves its actual name.

show-buffer uses one ordinary unattached tmux client with stdout reserved for buffer bytes. The same live server guard, operation budget and alias audit apply. It succeeds only after normal process completion and complete pipe draining, with exit zero and empty stderr. A hook cannot hide an error by changing its exit status. Post-launch read failure retains partial output and diagnostics; it does not prove that the read was never dispatched. Buffer contents are never parsed as receipts or errors. This contract does not apply to control mode.

load-buffer and save-buffer take literal file-path strings; :name selects the buffer. Save overwrites unless :append t is supplied. Relative paths follow the tmux command client’s cwd. A literal file named - must be spelled ./-; use set/show for in-memory bytes. Empty input or an empty loaded file is tmux’s no-op and preserves any existing buffer. Save success records tmux’s reported completion; it does not independently verify file contents or durability. Tmux 3.3a can suppress some file-write errors.

paste-buffer takes a physical pane and optional :name. Newlines become Return by default. :raw t preserves them; a separate :separator string replaces each newline. :bracketed t requests bracket markers when the pane enabled bracketed paste. :verbatim t preserves all bytes, disables newer tmux control-byte sanitization, and cannot add separators or bracket markers. It chooses flags from the live daemon version. :delete t removes the selected buffer after pasting. Input disablement and application consumption remain tmux/application concerns.

delete-buffer :name requires tmux 3.4 or newer. On 3.3a it signals unsupported-capability before dispatch, because that release can delete an unrelated top buffer when a named buffer is missing. The condition exposes error-feature, error-required-version and error-actual-version; the check uses the live daemon’s version, independently of the selected executable.

Omitting a buffer name for show, save, paste or delete uses tmux’s default: the newest buffer on 3.3a, and the newest automatic buffer from 3.4 onward. It does not select the newest explicitly named buffer on modern tmux.

Configuration inspection

show-options-text, show-hooks-text and show-environment-text return native UTF-8 printer text and a retained command outcome. Supply an explicit scope; local tables require the matching captured target. Normal client identity, preflight, last-moment target guards, cancellation and resource limits apply. These functions acquire state and do not change earlier observations.

This function from the executed example package returns three printer views plus their diagnostic outcomes. The REPL tutorial supplies the package’s tm nickname and setup.

(defun configuration-report (client session)
"Read native configuration text; return an owned report and diagnostic outcomes."
(let ((outcomes nil))
(flet ((inspect-text (reader &rest options)
(multiple-value-bind (text outcome) (apply reader client options)
(push outcome outcomes)
text)))
(let ((report
(list :options (inspect-text #'tm:show-options-text
:scope :session :target session
:name "status" :include-inherited t)
:hooks (inspect-text #'tm:show-hooks-text
:scope :session :target session)
:environment (inspect-text #'tm:show-environment-text
:scope :session :target session))))
(values report (coerce (nreverse outcomes) 'simple-vector))))))

Option and hook :name is a literal tmux reference: format-looking characters stay literal, while native abbreviations and array-reference syntax still apply. Omit it to list the table. :scope selects native flags; tmux can infer a built-in option’s table from its name instead. These raw inspectors do not enforce the typed mutation catalog’s name/type restrictions. A physical window’s native format context need not identify one particular captured session link; use a session target for session-table inspection.

show-options-text exposes :include-inherited (-A), :include-hooks (-H) and :value-only (-v). Native whole-table -A output does not promise inherited user @ options. show-hooks-text has no server-scope flag; its named printer can return an ordinary @ option without proving event registration. Its :monitors option selects native monitor presentation. Both printers’ :format and hook monitor inspection require the live daemon to be tmux 3.8. Format text is explicit tmux source with no implicit time expansion; #() can start command-client jobs whose results may be incomplete and whose cleanup follows client disconnect.

Environment scopes are :global and captured :session. Session output is the raw table, not a merged child environment. :hidden t selects hidden entries; the default selects ordinary entries. A visibility mismatch may succeed with empty text, which does not prove absence. :shell-format t returns native shell-looking text as data. Names may contain spaces, format punctuation and Unicode; only empty text, NUL and = are rejected. No reader executes this text.

Escaping, whitespace and ordinary hook output stay in the returned presentation. Foreign names and multiline values can make bulk text ambiguous. Missing names remain native errors with outcome evidence; invalid UTF-8 signals a decoding condition retaining the client and original bytes. These operations do not claim parsed values, presence, inherited provenance or complete decoded records. Decoded acquisition remains under development behind its separate transport admission gate.

Configuration mutations

set-option and unset-option address one explicit tmux option table. Server and global scopes reject a target. Session, window and pane scopes require a captured target of that type, so the normal generation and last-moment target guards apply. The exact live daemon version selects the reviewed option catalog after preflight; the executable’s version cannot silently substitute for it. The current catalogs cover the twelve exact supported releases from 3.3a through 3.8. An unreviewed neighboring release signals an error; see capabilities and current limits.

Literal writes validate the catalog’s native Boolean, integer, choice and text type before payload dispatch. nil is a valid false option value and becomes tmux off. :format-p t instead accepts explicit tmux format text and lets the daemon validate its expanded value. Registered array elements use :key and never allocate a vector by the greatest numeric key. Without :key, an array value uses the option’s native tmux list grammar and may create several entries; use :key when the value must remain one literal entry. :append t is accepted only where tmux implements it: strings, keyed string-array values and unkeyed array assignment. Public user-option writes accept the reversible @[A-Za-z0-9_.-]+ name grammar.

:only-if-unset t requests a local absent-only write. An inherited value permits a local override. An existing local value, including false or empty text, refuses replacement and retains the normal condition/outcome evidence. With :key, tmux tests that array element; other local keys may already exist. Without a key, it tests the local option entry. This condition applies once to the selected command; hooks and later operations remain independent. The default keeps ordinary replacement behavior.

set-hook accepts explicit tmux command source; it does not parse the source as Lisp or execute it locally. Ordinary installation never uses tmux’s immediate-run flag. Tmux can still run a registered native after-hook such as after-set-hook as a consequence of processing the command. Keyed hook entries do not support appending command text; unkeyed append adds hook entries through tmux’s array grammar. Use unset-hook to remove the hook. Registered hooks stay separate from ordinary option writes, and the live catalog gates dynamic event sources.

set-environment writes one raw global or captured-session environment table. It accepts literal text by default, explicit format expansion through :format-p t, and tmux’s hidden flag. unset-environment deletes an entry; remove-environment stores tmux’s removal marker. A tombstone, absence and a present empty string remain distinct. Names use [A-Za-z_][A-Za-z0-9_]* so later named acquisition is reversible.

All seven operations return a command-outcome, retain effective arguments and diagnostics, and never retry uncertain mutations. Use the guarded text inspectors for native printer views and decoded configuration for typed, presence-aware reads. Use run-command when raw tmux argv and its weaker target contract are intentional.

Explicit termination

kill-pane, kill-window and kill-session accept one captured physical target. The same preflight and last-moment guards used by other named mutations reject a missing, replaced or foreign-generation target. These functions do not expose tmux’s broad -a forms. Killing a physical window removes all its links; killing a session removes that session’s links and any now-unreferenced panes.

kill-server is deliberately separate from close-client. Closing releases library-owned resources and leaves tmux alive. Server termination succeeds only after a pre-dispatch receipt and readiness of the pidfd retained for the daemon accepted during this call’s preflight prove both dispatch and process exit. Daemon death without the receipt remains :unknown because another actor could have terminated it. After observed death, the client remains open but its generation is invalidated; retained captures still support local traversal and projection.

All four operations are destructive and never retry automatically. Select the target once, establish cardinality before dispatch, and inspect a retained condition outcome when completion is uncertain.

Outcomes and target checks

Mutators return command-outcome. outcome-value returns a value and presence as two values. Rename and selection accept :observe nil to omit follow-up acquisition. Otherwise a successful mutation followed by failed acquisition still has status :succeeded, no value, and an outcome-observation-error.

EvidenceOutcome
Preflight failed or live guard explicitly rejected the target:not-dispatched
Completion receipt, successful tmux process exit and empty stderr:succeeded
Completion receipt and nonzero process exit:failed
Successful process exit with diagnostic output:unknown
Dispatched operation lacks required receipts, or transport lost completion:unknown
Server pidfd proves exit but the pre-dispatch receipt is missing:unknown
Server receipt and retained pidfd both prove explicit termination:succeeded, phase :server-terminated
Server exit wait fails after dispatch:unknown, reason :server-exit-unobserved; cause retained

The outcome retains exit status, diagnostic bytes, effective arguments and elapsed time. A failed command queue can have completed effects; it does not imply rollback. An unknown mutation is never automatically retried.

Validation checks the live server generation and captured entity identity. The dispatch connection checks the daemon again and checks physical targets or session/index/window mappings immediately before the payload. A reused link index signals stale-target. These checks do not make selection and mutation a transaction; tmux hooks and other clients can change state.

Capture preserves whitespace and trailing lines. The text API strictly decodes UTF-8; decoding failures retain the client and raw command outcome. The byte API copies output without decoding. Its flags expose tmux’s history, wrapping, alternate-screen, pending-output and escape modes; they do not reconstruct terminal bytes that tmux did not retain.

Command aliases and daemon configuration

Named APIs require the original built-in command meanings and stable command-alias configuration during each call. show-options is the trusted bootstrap spelling used to inspect aliases. It must remain the built-in command. The audit cannot safely inspect an arbitrary override of itself or prevent configuration changes after inspection.

Before acquisition or a named operation, the library reads command-alias and signals unsupported-configuration for collisions with reserved command names. error-setting identifies the option; error-commands returns the colliding spellings. The reserved list is maintained in command-policy.lisp. Other alias names are allowed. The check conservatively rejects an apparent reserved assignment on any line of a multiline alias value.

Configured tmux hooks keep their ordinary behavior. The library does not remove aliases or hooks from the user’s daemon. run-command remains an explicit raw escape hatch with tmux’s command grammar and no captured-target or alias audit.

Esc

Type to search.

Reference previewOpen reference