libtmux for Ruby
Ruby
- Python Unavailable
- Ruby
- Lua Unavailable
- TypeScript Unavailable
- Rust Unavailable
- Go Unavailable
- Java Unavailable
- .NET Unavailable
- C++ Unavailable
- Swift Unavailable
Create tmux sessions, split windows, send input, and capture pane output from
Ruby. Read server state into a snapshot, then query it with where, select,
and the rest of Enumerable.
Quick start · Queries · Gems · Guide · API reference · Recipes
Alpha. APIs may change between releases. See the initial alpha notes and release guide.
InstallLink to section
Install the core prerelease from RubyGems:
$ gem install libtmux --preThe companion gems install separately; use --pre for their alpha
versions too.
Install from sourceLink to section
Use the Ruby pinned in .tool-versions and have tmux on your
PATH. From this checkout, install the development bundle:
$ mise install$ mise exec -- bundle config set --local path vendor/bundle$ mise exec -- bundle installThe gemspecs declare Ruby 3.3+. The compatibility workflow tests Ruby 3.3, 3.4, and 4.0 with tmux 3.2a–3.7c on Linux and macOS. Check the results for your revision before relying on a particular combination.
Quick startLink to section
Create a session and split its logs window. Server.start owns a private
tmux server and closes it when the block exits. The snapshot remains readable
afterward.
require "libtmux"
snapshot = LibTmux::Server.start do |server| session = server.new_session(name: "work", window_name: "main", command: ["/bin/cat"]) window = session.new_window(name: "logs", command: ["/bin/cat"]) window.split(direction: :horizontal, size: "40%", command: ["/bin/cat"])
server.snapshotend
snapshot.windows.each do |window| puts "#{window.name}: #{window.panes.map(&:id).join(', ')}"endRun the complete example:
$ mise exec -- bundle exec ruby examples/quickstart.rbOutput:
main: %0logs: %1, %2Pane commands take argument arrays. To use an existing server, open an explicit
endpoint with LibTmux::Server.open(socket_path: ...); closing that binding
leaves the daemon running. See ownership and errors.
Query a snapshotLink to section
Continue with the snapshot above. where accepts criteria as data; select
accepts a Ruby block. These queries make no tmux calls.
panes = snapshot.panesactive_ids = panes.where(active: true).map(&:id)wide_panes = panes.select { |pane| pane.width >= 40 }panes_by_window = panes.group_by { |pane| pane.window.name }
logs = snapshot.windows.one(name: "logs")missing = snapshot.windows.one_or_nil(name: "missing")one raises NoMatchError or MultipleMatchesError unless exactly one record
matches. one_or_nil returns nil for no match and still rejects duplicates.
Both errors live under LibTmux.
Selections retain captured membership. Call server.snapshot again while the
server is open to read later changes. The field catalog
lists query fields and wire names; the list/filter recipe
also covers exact matches and queries after close.
GemsLink to section
Start with libtmux. Add the companion for your caller:
| Gem | Require | Use it for |
|---|---|---|
| libtmux | libtmux | Blocking scripts, snapshots, and control connections |
| libtmux-async | libtmux/async | Concurrent commands and bounded streams in Async tasks |
| libtmux-mcp | libtmux/mcp | An MCP server with explicit endpoints and tool policy |
| libtmux-workspace | libtmux/workspace | YAML/JSON workspace plans and a CLI to apply them |
Requiring a gem starts no tmux process, scheduler, or protocol server. Execution modes explains blocking calls, Async tasks, and control subscriptions. Tracked MCP captures, waits, and authored runs require tmux 3.3+ and native process identity; see the MCP guide. Workspace client-switching semantics are in the workspace guide.
To use the core outside this checkout, build the artifacts:
$ mise exec -- bundle exec rake buildInstall into the Ruby environment that will run your application. The core’s runtime dependencies must already be installed for this local-only command:
$ gem install \ --local \ --no-document \ pkg/libtmux-0.1.0.alpha.1.gemCompanion gems need their declared runtime dependencies too. The packaging check verifies each gem in an isolated installation and runs the recipes outside the checkout.
More examples and referenceLink to section
- Send text and capture output: split panes, wait for output events, and round-trip binary buffers.
- Work with linked windows: address one window at several session indexes.
- Capture concurrently: read panes while another request waits, then cancel it.
- Load a workspace: parse a configuration, plan, and apply it.
- All recipes: cancellation, control streams, command groups, and MCP.
- API reference: public methods, source links, and behavioral contracts. RBS declarations ship with each gem; selected installed calls are checked, without a whole-program typing guarantee.
- Benchmarks: workloads, measurements, and their limits.
See Contributing for setup and checks. MIT license.