NAME

LibTmux::Server - Explicit tmux acquisition and commands

SYNOPSIS

use v5.44;
use LibTmux::Server;
my $server = LibTmux::Server->new(socket_name => 'application');
my $snapshot = $server->snapshot;
my $pane = $snapshot->panes->first;
say $server->capture_pane(pane => $pane) if defined $pane;

CONTRACT

Construction and planning perform no I/O. Acquisition and mutation are explicit, bounded operations. Captured LibTmux::Snapshot entities retain their observed graph; mutations do not refresh them. Acquire another snapshot to observe changes. Connection settings remain owned by the server wrapper; destroying it never kills a tmux daemon. See the orchestration guide.

Physical entity targets accept stable ID strings or generation-checked handles. Session-relative window operations require LibTmux::WindowLink. Checks across subprocesses are optimistic rather than transactional. Single-quote session IDs such as '$1' to avoid interpolating a Perl capture variable.

ERRORS

Invalid arguments throw "InvalidArgument" in LibTmux::X before dispatch. Acquisition and checked commands propagate typed LibTmux::X failures, including missing executables, absent daemons, vanished targets, stale handles, codec errors, timeouts, and output limits. Failures never become empty selections. Cancellation or a timeout after dispatch does not prove nonexecution or roll back effects.

METHODS

new

new(executable => tmux, socket_name|socket_path => string, timeout => seconds, max_output => bytes, config_file => path, env => hashref).

Return a new server wrapper without I/O. Select socket_name or socket_path, never both. Defaults are executable tmux, timeout 5 seconds, and an 8 MiB combined retained-output limit. env is copied; child processes clear ambient TMUX and TMUX_PANE. Invalid configuration throws "InvalidArgument" in LibTmux::X.

my $server = LibTmux::Server->new(socket_name => 'application');

execute

execute(argv => arrayref, stdin => bytes?, timeout => seconds?, cancel_fh => handle?).

Perform one raw command and return LibTmux::CommandResult, including nonzero exits. stdout and stderr remain separate octet strings. stdin is optional bytes; cancel_fh is borrowed and remains open. Transport failures throw typed LibTmux::X with bounded partial output when available.

my $result = $server->execute(argv => ['list-sessions']);

cmd

cmd(@literal_arguments).

Perform one checked literal tmux command and return LibTmux::CommandResult. No shell wrapper or implicit tmux command list is used. Nonzero exits throw "Command" in LibTmux::X or a more specific target/server error; transport failures propagate.

my $result = $server->cmd('display-message', '-p', '#{version}');

new_session

new_session(name => string, command => arrayref?, shell_command => string?, width => integer?, height => integer?, cwd => bytes?, environment => hashref?).

Create a detached session and return its captured LibTmux::Session. command is a literal argument vector; shell_command explicitly requests a shell and is mutually exclusive. Omitting both uses tmux's default command. cwd is path octets; environment supplies NAME/value pairs to the first process. Performs I/O. If creation succeeds but acquisition fails, "Creation" in LibTmux::X retains the known generation-scoped creation receipt and cause.

my $session = $server->new_session(name => 'application', command => ['/bin/cat']);

new_window

new_window(session => Session|session_id, name => string?, command => arrayref?, shell_command => string?, cwd => bytes?, environment => hashref?).

Create a detached physical window in the selected session and return its captured LibTmux::Window. command, shell_command, cwd, and environment follow "new_session". The new link uses tmux's next available index. Performs I/O; "Creation" in LibTmux::X preserves known effects if subsequent acquisition fails.

my $window = $server->new_window(session => $session, name => 'logs', command => ['/bin/cat']);

split_pane

split_pane(pane => Pane|pane_id, horizontal => boolean?, command => arrayref?, cwd => bytes?, environment => hashref?).

Split the targeted pane and return the new captured LibTmux::Pane. horizontal selects side-by-side placement; false uses tmux's vertical split. command, shell_command, cwd, and environment follow "new_session". Performs I/O; creation/acquisition failures follow "Creation" in LibTmux::X.

my $other = $server->split_pane(pane => $pane, horizontal => true, command => ['/bin/cat']);

snapshot

snapshot().

Perform strict graph acquisition and return LibTmux::Snapshot. Physical windows/panes appear once; LibTmux::WindowLink retains each contextual association. Capture start/end describe an observation interval, not an atomic transaction. Acquisition, unsupported capabilities, and incomplete topology throw typed LibTmux::X; no partial snapshot is returned.

my $snapshot = $server->snapshot;

listings

listings(kind).

Perform acquisition and return a fresh unblessed array reference of contextual hash records in tmux order, preserving duplicate physical identities. kind is session, window, pane, or client. An attached-client listing can be empty. Records are detached values; "snapshot" normalizes the graph. Acquisition/codec failures propagate through LibTmux::X.

my $rows = $server->listings('window');

query_panes

query_panes(where => criteria|Filter?, pushdown => auto|never|require?, native_filter => string?, on_verification => coderef?).

Acquire and return a new LibTmux::PaneSelection in captured physical-pane order. where accepts a hash reference or LibTmux::Filter. auto verifies safe scalar candidates after complete local evaluation; never disables the native comparison. The default auto costs one extra command and supervisor when lowering is available; it does not reduce acquisition. Select never when only the captured answer is needed. require throws "Unsupported" in LibTmux::X unless lowering is exact, or "QueryMismatch" in LibTmux::X on disagreement. native_filter is an exclusive expert escape hatch. Empty successful matches remain a typed selection; acquisition/evaluation failures propagate.

on_verification receives one detached report hashref in void context after a successful decision, including auto fallback. It runs inline once; its return is ignored and exceptions propagate unchanged unless the operation has already been cancelled. Cancellation suppresses subsequent result/error delivery. Failed queries do not invoke it. Report edits cannot change the returned selection. See "VERIFICATION REPORT" and "explain_panes".

my $panes = $server->query_panes(where => {active => true}, pushdown => 'auto');

explain_panes

explain_panes(where => criteria|Filter, pushdown => policy?).

Validate criteria and return an inspectable LibTmux::QueryPlan without I/O or mutation. The plan records required fields/relations, source commands, residuals, and conditional daemon capability needs. Invalid criteria throw "InvalidFilter" in LibTmux::X. Executing "query_panes" discovers the connected generation and capabilities.

my $plan = $server->explain_panes(where => {width => {-gte => 120}});

rename_session

rename_session(session => Session|session_id, name => string).

Rename the selected LibTmux::Session using a literal name. Existing captured handles keep the old observed name; use "snapshot" to observe the change.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->rename_session(session => $session, name => 'application');

rename_window

rename_window(window => Window|window_id, name => string).

Rename the physical LibTmux::Window across all its links. Names remain literal rather than expanding tmux formats. Captured handles keep their observed name.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->rename_window(window => $window, name => 'logs');

link_window(window => Window|window_id, session => Session|session_id, index => integer?).

Add an association from a physical LibTmux::Window to a LibTmux::Session. index is optional; conflicts remain command failures. Existing associations are preserved. Inspect new LibTmux::WindowLink records through "snapshot".

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->link_window(window => $window, session => $session, index => 4);

unlink_window(link => WindowLink|session_id:index).

Remove exactly one LibTmux::WindowLink, given a captured link or session_id:index string. Removing the final link can destroy its physical window; other linked associations retain their context.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->unlink_window(link => $link);

move_window

move_window(link => WindowLink|session_id:index, session => Session|session_id, index => integer?).

Move one contextual LibTmux::WindowLink into the destination session/index. Other links of the physical window keep their own associations. Use "link_window" to add an association without moving one.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->move_window(link => $link, session => $session, index => 4);

select_window

select_window(link => WindowLink|session_id:index).

Select a LibTmux::WindowLink within its session. A physical window alone cannot identify session-relative active state. Capture again through "snapshot" to observe the selected link.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->select_window(link => $link);

select_pane

select_pane(pane => Pane|pane_id).

Change the active LibTmux::Pane of its physical window. This differs from selecting a session's LibTmux::WindowLink.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->select_pane(pane => $pane);

select_layout

select_layout(window => Window|window_id, layout => string).

Apply an unambiguous predefined layout name or a checksum-prefixed native layout to a LibTmux::Window. Unknown or ambiguous predefined names throw "InvalidArgument" in LibTmux::X before dispatch, including on tmux 3.3a. Native custom-layout validation remains tmux's responsibility.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->select_layout(window => $window, layout => 'tiled');

resize_pane

resize_pane(pane => Pane|pane_id, width => positive_integer?, height => positive_integer?).

Resize a LibTmux::Pane to the supplied positive width and/or height. tmux's layout constraints may affect the resulting dimensions; inspect another LibTmux::Snapshot for observed values.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->resize_pane(pane => $pane, width => 100);

set_title

set_title(pane => Pane|pane_id, title => string).

Set a LibTmux::Pane title. Literal input is protected from format expansion; tmux's own title sanitization remains observable in a new LibTmux::Snapshot.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->set_title(pane => $pane, title => 'build.v2');

send_keys

send_keys(pane => Pane|pane_id, keys => arrayref).

Send the array's named keys in order to a LibTmux::Pane. tmux interprets key names; arguments beginning with a dash remain key operands. An empty array sends no keys. Acceptance does not prove the pane application consumed input. Use "send_text" for literal text.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->send_keys(pane => $pane, keys => ['Enter']);

send_text

send_text(pane => Pane|pane_id, text => string|bytes, enter => boolean?).

Send literal text/bytes to a LibTmux::Pane, then optionally send Enter. Empty text is permitted. Acceptance does not prove application completion. Use an application-specific observable handshake before relying on output; "capture_pane" reads observed terminal content.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->send_text(pane => $pane, text => 'hello', enter => true);

capture_pane

capture_pane(pane => Pane|pane_id, start => integer?, end => integer?).

Read a LibTmux::Pane and return raw terminal octets, including tmux's final newline. Optional start/end select native history rows; no UTF-8 replacement is performed. This I/O reads current observed content without waiting for application work. Command/transport failures propagate through LibTmux::X.

my $bytes = $server->capture_pane(pane => $pane, start => -20);

kill_pane

kill_pane(pane => Pane|pane_id).

Destroy the selected LibTmux::Pane. Killing a window's final pane may destroy the physical window and its LibTmux::WindowLink associations. Previously captured records remain readable observations.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->kill_pane(pane => $pane);

kill_window

kill_window(window => Window|window_id).

Destroy the physical LibTmux::Window and every LibTmux::WindowLink referring to it. Use "unlink_window" when removing one association is the intended effect.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->kill_window(window => $window);

kill_session

kill_session(session => Session|session_id).

Destroy the selected LibTmux::Session and its links. Windows linked elsewhere can survive. Captured data remains local; later mutations through stale generation handles are checked.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->kill_session(session => $session);

kill_server

kill_server().

Explicitly request destruction of the connected tmux daemon. This method can affect a borrowed server and must be called intentionally; wrapper destruction never calls it. Successful command acceptance alone does not prove every daemon/client process exited.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->kill_server;

clients

clients().

Acquire a graph and return its LibTmux::ClientSelection. A daemon without attached clients produces an empty selection. Membership is copied away from graph storage. Acquisition failures propagate through LibTmux::X; "detach_client" changes client state explicitly.

my $clients = $server->clients;

attach_argv

attach_argv(session => session_id).

Return a fresh literal argument array for a caller-owned interactive terminal without I/O. The session target is a stable ID string; obtain it through "id" in LibTmux::Session. The caller owns terminal/process setup and exit observation; the bounded capture transport does not allocate a TTY. Invalid inputs throw "InvalidArgument" in LibTmux::X.

my $argv = $server->attach_argv(session => '$1');

detach_client

detach_client(client => Client|client_name).

Request detachment of a captured LibTmux::Client or explicit native client name. Command acceptance can precede client-process exit; callers owning an attached process must observe its exit separately.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->detach_client(client => $client);

set_option

set_option(name => string, value => string|integer, scope => session|window|pane|server, target => id?, global => boolean?).

Set an option at explicit session/window/pane/server scope. Supply an exact target ID for local settings or global => true for the global level. Empty and zero values are preserved. "get_option" controls whether inherited values participate.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->set_option(scope => 'window', target => $window->id, name => '@build', value => '0');

get_option

get_option(name => string, scope => scope, target => id?, global => boolean?, inherited => boolean?).

Read an option and return its octets, decoding tmux's quoted string values. Literal backslashes and non-UTF-8 bytes remain distinct on older daemons. Key, numeric and command options retain native printed syntax. Array values are joined with newlines in native index order; an empty array returns ''. Empty text and '0' remain values. inherited => true requests tmux's -A behavior; otherwise only the selected local level is queried. Performs I/O without mutation. Native missing-option errors throw "Command" in LibTmux::X; malformed output throws "Codec" in LibTmux::X. A built-in option without a local override may produce empty output. See "set_option" and "unset_option".

my $value = $server->get_option(scope => 'window', target => $window->id, name => '@build');

unset_option

unset_option(name => string, scope => scope, target => id?, global => boolean?).

Remove the selected local/global option so inheritance can take effect. Scope and target follow "set_option"; removing an override differs from assigning empty text.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->unset_option(scope => 'window', target => $window->id, name => '@build');

set_hook

set_hook(name => hook_or_hook[index], command => explicit_tmux_command_string, target => session_id?, global => boolean?).

Set a native hook or sparse hook[index] entry for an explicit session target or global scope. command is deliberately a tmux command string, unlike literal process argv. "show_hooks" preserves native indexes/quoting rather than inventing a flattened hook list.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->set_hook(target => $session->id, name => 'after-select-window[3]', command => 'display-message hook');

show_hooks

show_hooks(target => session_id?, global => boolean?).

Read hooks and return raw octets preserving sparse indexes and tmux quoting. No hooks produce empty text. Performs I/O; failures propagate through LibTmux::X. See "set_hook" for explicit command-string semantics.

my $hooks = $server->show_hooks(target => $session->id);

set_environment

set_environment(name => env_name, value => bytes, session => session_target?).

Set a literal environment value for a LibTmux::Session handle or explicit session ID, or globally when session is omitted. Empty text and '0' remain values. Existing pane processes are unaffected; creation-time environment belongs to "new_session", "new_window", and "split_pane". Captured handles are checked against the connected daemon generation before dispatch; stale handles throw "StaleReference" in LibTmux::X. Raw IDs target the current session. The probe and mutation remain separate operations.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->set_environment(session => $session, name => 'BUILD', value => '0');

get_environment

get_environment(name => env_name, session => session_target?).

Read a session/global variable and return its octets. The native quoted representation is parsed as data; no shell evaluates it. Literal backslashes, newlines and non-UTF-8 bytes remain distinct. Empty text and '0' remain values. Performs I/O without mutation; missing or explicitly unset variables throw "Command" in LibTmux::X, and malformed output throws "Codec" in LibTmux::X. Captured targets follow "set_environment"'s generation checks.

my $value = $server->get_environment(session => $session, name => 'BUILD');

unset_environment

unset_environment(name => env_name, session => session_target?).

Unset the named session/global variable. This differs from setting an empty value; "get_environment" reports the unset state as a command error.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->unset_environment(session => $session, name => 'BUILD');

set_buffer

set_buffer(name => string, data => bytes).

Load a named tmux buffer through stdin bytes rather than interpolating data into a command. Empty data is permitted. "show_buffer" retrieves bytes; buffer ownership remains in the daemon until "delete_buffer" or an external change.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->set_buffer(name => 'application', data => "a\0b");

show_buffer

show_buffer(name => string).

Read a named tmux buffer and return raw octets, including embedded NUL bytes. Empty data remains an empty string. Performs I/O; a missing buffer throws "Command" in LibTmux::X. See "set_buffer".

my $bytes = $server->show_buffer(name => 'application');

delete_buffer

delete_buffer(name => string).

Delete the named daemon buffer loaded through "set_buffer". Other daemon buffers remain untouched; later "show_buffer" calls report absence as a command failure.

Returns undef after command acceptance. Performs I/O; failures propagate through LibTmux::X. Captured objects are not modified.

$server->delete_buffer(name => 'application');

batch

batch(arrayref_of_argv).

Perform ordered independent literal requests and return a fresh array reference of {result, error} records in input order. Each result is LibTmux::CommandResult or undef; each dispatch error is the original typed LibTmux::X or undef. Nonzero command exits stay raw results. An empty input returns an empty array without command I/O. Requests are attempted in order, without rollback or tmux command-list attribution.

my $results = $server->batch([['display-message', '-p', '#{version}']]);

operation

operation($name, %arguments) validates and copies arguments, returning one LibTmux::Operation without I/O. The optional Future facade shares this preparation and parsing boundary. Use the named methods above for synchronous execution. Invalid arguments or criteria throw "InvalidArgument" in LibTmux::X or "InvalidFilter" in LibTmux::X before submission.

my $operation = $server->operation('snapshot');

VERIFICATION REPORT

"query_panes" supplies a fresh, detached hashref to on_verification. It contains no entity handles. Every ID array retains stable order; editing the report cannot mutate captured data or the query result.

policy, status, comparison

Policy is auto, never, require, or native for the expert escape hatch. Status is disabled (never), local (no safe lowering), agreed, disagreed, or native. Comparison is none, exact_ids, candidate_superset, or captured_membership. Partial lowering checks inclusion of local matches; expert queries check only membership in the captured graph. Neither establishes full filter equivalence.

native_checked, translation_exact, native_filter, reasons

native_checked is Boolean. translation_exact is Boolean, or undef for never and expert queries. native_filter is the executed expression, or undef when no native check ran. reasons is a fresh arrayref of lowering limitations. Exact translation and agreement between two observations are separate facts.

server_id, generation, daemon_version, capture_start, capture_end

Identity strings and the captured interval in wall-clock seconds since the epoch, from "metadata" in LibTmux::Snapshot. This is not an atomic observation.

captured_ids, local_ids, native_ids

captured_ids and local_ids follow physical capture order; local_ids is undef for expert queries. native_ids holds unique IDs in native first-occurrence order, or undef when no check ran. An empty array is an observed empty set.

missing_ids, unexpected_ids, uncaptured_ids

missing_ids lists local matches absent natively, in local order. For exact lowering, unexpected_ids lists native matches absent locally. uncaptured_ids lists native IDs absent from the graph. The latter two follow native order; inapplicable lists are empty. Any applicable mismatch produces disagreed. "QueryMismatch" in LibTmux::X carries this report for require or expert failures; the observer is not called for a failed query. A discrepancy has no inferred cause: concurrent changes, compiler defects and backend differences all need investigation.