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.

Start a private tmux server from OCaml

Use Workspace.submit_bootstrap when the endpoint is known to be missing. It creates the first session and binds a client through the same control connection. The native workspace builder needs no JSON package; Workspace.await performs startup.

For an existing daemon, use Client.connect, capture its graph, and create a session through that client. See control and recovery.

Run the complete program

Complete the source installation, then run from the checkout:

Terminal window
$ opam exec -- dune exec examples/showcase_bootstrap.exe -- tmux

The program prints its temporary socket path followed by bootstrapped: 1 session, 1 window, 1 pane. It creates a bootstrap-demo session whose editor window runs /bin/cat -u, captures the graph, and reads that snapshot after closing its client.

The complete source includes its private directory, tmux configuration, local version discovery and cleanup. To use the whole program outside this checkout, save it as main.ml in the Dune project from first use with:

(executable
(name main)
(libraries libtmux libtmux-workspace libtmux-unix unix))

CI compiles that complete file against installed packages and checks its exact outcome line, graph assertions, directory cleanup and owned process exit on tmux 3.3a and 3.8. The executed inventory records its command and workflow.

Build, plan, await and capture

The central function receives the binary’s discovered version and a new private socket path. Config.make, Plan.make and submission perform no I/O; the function returns a retained execution handle:

let bootstrap ~binary ~version ~directory endpoint =
let spawn = Spawn.make (Exec { program = "/bin/cat"; args = [ "-u" ] }) in
let config =
Config.make ~directory ~session:"bootstrap-demo"
[ Config.window ~name:"editor" [ Config.pane ~spawn () ] ]
|> checked Config.pp_error
in
let plan =
Plan.make ~endpoint ~version ~observed:None config |> checked Plan.pp_error
in
get (Workspace.submit_bootstrap ~binary plan)

Passing None as the observed argument means the endpoint is known to be missing. The full program uses a newly created private directory to establish that precondition. A failed capture must remain an error; treating it as a missing observation discards that failure and produces the wrong plan. A plan remains advisory; another process can still change the endpoint before execution.

Keep that handle outside the cleanup scope. Await it, check the receipt, then borrow its client for the capture:

let snapshot =
protect
~finally:(fun () -> get (Workspace.close execution))
(fun () ->
let receipt = get (Workspace.await execution) in
require_success receipt;
let client = Option.get (Workspace.client execution) in
get (Client.capture client))

require_success reports failed steps and compensation before raising. The protect helper keeps that primary exception if closing also fails, reporting the cleanup failure separately. Both helpers are in the complete source. Workspace.inspect execution reads the retained journal after closure; inspect reported creations and uncertainty before choosing another action. The program stops without retrying. The workspace guide explains those receipts.

Workspace.client borrows the bootstrapped client. Close the workspace handle after using that client; its snapshot stays readable.

Choose the daemon’s lifetime

Bootstrapping owns the new client, not the tmux daemon. Closing the handle releases that client. The example explicitly configures its private daemon with exit-unattached on, supplied through a small shell exec wrapper. The daemon and its demonstration pane exit after the final client detaches. It then removes only its own temporary files.

For an application that keeps the server, choose its normal tmux lifetime policy and retain the workspace handle while using the borrowed client. An existing or newly visible daemon does not become owned merely because this application connected to it. Cancellation and a partial bootstrap can leave effects; use retained operation recovery and the workspace receipt rather than assuming closure undoes them.

Object graph · Workspaces · Guide

Esc

Type to search.

Reference previewOpen reference