Load a tmuxp-style file into a session, capture a session back into a file, convert it between YAML and JSON, or import a tmuxinator or Teamocil project. Flags follow tmuxp 1.74.0, and every command can answer in JSON or NDJSON.
io.github.libtmux:libtmux-workspace-cli — on Maven
Central.
Reference: the command manual on libtmux.org.
Releases are numbered
0.1.N, and each release incrementsN. The API is not settled: any release may change or remove exported identifiers, and the changelog marks each break. Pin an exact version to avoid one.Commands, flags and output records are part of the API.
Contents — Quick start · Find, convert, and import · Inspect a loaded workspace through MCP · Commands · What it leaves out · Support and status · Documentation
Build the launcher from the repository root and put its directory on PATH:
$ ./gradlew :libtmux-workspace-cli:installDist$ export PATH="$PWD/libtmux-workspace-cli/build/install/tmux-workspace/bin:$PATH"Check that it runs:
$ tmux-workspace --versionSave a workspace as workspace.yaml:
session_name: dev
windows:
- window_name: editor
window_index: 0
layout: even-horizontal
panes:
- null
- shell_command: echo readytmux-workspace load: build a session
load builds the workspace as a session. -d leaves it detached
and -S selects the tmux socket. Choose an unused socket path for this example;
an existing server on that path would receive the load:
$ mkdir -p /tmp/libtmux-java-dev$ tmux-workspace load ./workspace.yaml \
-S /tmp/libtmux-java-dev/workspace-example.sock \
-d \
--ndjsonIt starts a tmux server on the unused socket and prints one JSON event per line.
The last is a completed event with status ok, and the session dev now
holds two panes.
Without -S or -L, LIBTMUX_SOCKET_PATH and then LIBTMUX_SOCKET choose the
server. With neither set, no socket is passed and tmux picks: the server in
TMUX from inside a pane, and its default socket otherwise.
Every layout is checked before any script runs or any session changes.
tmux-workspace freeze: capture a session
freeze writes a live session back out as a workspace:
$ tmux-workspace freeze dev \
-S /tmp/libtmux-java-dev/workspace-example.sock \
--jsonIt prints the workspace as one JSON document: session_name is dev, and the
window lists two panes.
It recovers topology, directories, focus and options. It does not recover
command history.
Writing the capture to a file takes --save-to.
tmux-workspace ls: what is saved
ls lists the workspaces in the current project and in the global
configuration directory:
$ tmux-workspace lsIt prints one line for each workspace, its name and where it lives.
tmux-workspace search: find one by what is in it
search looks through names, paths, sessions, windows and pane
commands. This finds the workspaces with editor in a window's name:
$ tmux-workspace search editor --field windowEvery query must match unless you add --any.
tmux-workspace convert: YAML to JSON and back
convert rewrites a workspace file in the other format. It
never runs the workspace:
$ tmux-workspace convert ./workspace.yaml --save-to ./workspace.json --yesIt asks before writing unless you pass --yes, and it keeps an existing file
unless you pass --force.
tmux-workspace import: bring a tmuxinator or Teamocil file
import tmuxinator and
import teamocil translate the other tool's file into a
native workspace:
$ tmux-workspace import tmuxinator ./project.yml --save-to ./imported.yaml --yesA field it cannot carry is rejected before anything is written.
A loaded workspace is an ordinary tmux session, so an agent can read it through
libtmux-mcp. Build the launcher:
$ ./gradlew :libtmux-mcp:installDist \
--max-workers=2 \
--no-parallelRegister it on that socket, offering only the tools that read tmux:
$ claude mcp add tmux \
-e LIBTMUX_TOOLSETS=inspect \
-- libtmux-mcp/build/install/libtmux-mcp/bin/libtmux-mcp \
--socket /tmp/libtmux-java-dev/workspace-example.sockAnother client launches the same program with the same arguments and
environment variable. Use --socket-name when you loaded with -L.
Then the agent can:
- Find the panes with
list_sessions,list_windowswithsession_name: dev, andlist_panes. - Read one with
capture_pane, or wait for text withwait_for_text. - Read the selected endpoint from the
tmux://capabilitiesresource.
| command | what it does | reference |
|---|---|---|
load |
builds workspaces in order, creating or reusing a session | load |
freeze |
captures a running session as a workspace file | freeze |
convert |
converts a workspace file between YAML and JSON | convert |
import tmuxinator, import teamocil |
translates another tool's file into a workspace | import, tmuxinator, teamocil |
ls |
lists the local project and global workspaces | ls |
search |
searches names, paths, sessions, windows and pane commands | search |
edit |
resolves a workspace and opens it in EDITOR |
edit |
shell |
opens a Python shell on a session; needs Python with tmuxp 1.74.0 | shell |
debug-info |
reports runtime and configuration diagnostics | debug-info |
--generate |
writes the command schema or Bash, Zsh or Fish completion | completion |
- Rollback. A failed append reports what it kept and undoes nothing. Creating, reusing and appending has the rules.
- tmuxp's layout and focus defaults. A window with no
layouttiles its panes where tmuxp stacks them, and nofocuskeeps the first window active. Layouts and focus says why. - Unknown keys. Loading rejects a key it does not implement before it
contacts tmux, except
x-vendor extensions. Document rules has the rest. - Fields an import cannot carry. Hooks, project
preandpost, endpoint overrides and the like are rejected. Imports lists them. - Python, unless you ask. Loading, capture, conversion, imports, discovery
and search run on the JVM. Python covers the
shellcommand, plugins and custom builders.
- JDK 25 or newer, and tmux 3.3a or newer.
- Linux, including WSL. CI runs on Ubuntu. macOS is supported on a best-effort basis, and CI coverage for it is highly limited.
- Releases. Releases are numbered
0.1.N, and each release incrementsN. The API is not settled: any release may change or remove exported identifiers, and the changelog marks each break. Pin an exact version to avoid one. Commands, flags and output records are part of the API. - Machine output.
--jsonis one document and--ndjsonone record per line. A failure names onecode, and the exit status is0,1,2or130. Output has the full contract. - Optional Python. Only
shell, tmuxp plugins and custom builders need Python with tmuxp 1.74.0, named byTMUX_WORKSPACE_PYTHON, and a Python libtmux whoseTMUX_OPTIONAL_FEATURE_POLICY_VERSIONis 2 or more. No released libtmux has that yet; it comes with tmux-python/libtmux#780, so install libtmux from that source or skip those features.
- The
tmux-workspacereference — loading, document rules, imports, output, Python, and working on the CLI itself. - The command manual — a page for each command, with the configuration and output references.
libtmux-workspace— the library that builds a workspace from Java.- Changelog — what each release of this module changed