Core LibraryGuides

Choose documentation 2

latest

Current version

latest
English

Prerelease This site documents an alpha of libtmux. Its structure, URLs and APIs are subject to change.

Getting started

Drive tmux from PowerShell. Create sessions, arrange panes, send input, and read terminal output through native cmdlets. Snapshots return typed objects that you can traverse and filter with ordinary PowerShell pipelines.

Built on libtmux for .NET, in the same libtmux organization and with the same main author. The cmdlets return its native objects and add PowerShell parameter binding, help, formatting and -WhatIf / -Confirm.

Install · Object graph · Run to completion · Service readiness · Execution modes · Guides · MCP · Compatibility · Troubleshooting · Cmdlet reference · License

Alpha. APIs may change. Both modules are available on PowerShell Gallery: LibTmux and LibTmux.Workspace.

Install

Use PowerShell 7.4 or later with tmux on the same Linux host. On Windows, run both inside WSL. PowerShell 7.4 includes the PSResourceGet commands below; see compatibility for the support contract.

Run these commands in PowerShell. Install the core module for sessions, windows, panes, snapshots, input and capture:

Terminal window
$ Install-PSResource -Name LibTmux `
-Version 0.1.0-alpha2 `
-Prerelease `
-Repository PSGallery `
-Scope CurrentUser `
-TrustRepository

For YAML/JSON workspace declarations, install the matching workspace module. It also installs its exact core dependency, so this command alone installs both modules:

Terminal window
$ Install-PSResource -Name LibTmux.Workspace `
-Version 0.1.0-alpha2 `
-Prerelease `
-Repository PSGallery `
-Scope CurrentUser `
-TrustRepository

PowerShellGet is an alternative. Install the core module:

Terminal window
$ Install-Module -Name LibTmux -AllowPrerelease

Or install the workspace module with its matching core dependency:

Terminal window
$ Install-Module -Name LibTmux.Workspace -AllowPrerelease

Choose one installer. The prerelease flag includes the alpha releases; without it, the installers look for stable releases. Both Gallery pages also provide Azure Automation and manual download options. A manual download does not include dependencies; use a package manager to resolve them. Azure Automation runs need a host with PowerShell and tmux as described in compatibility.

Import both modules to run all the examples on this page:

Terminal window
$ Import-Module -Name LibTmux, LibTmux.Workspace `
-RequiredVersion 0.1.0 `
-ErrorAction Stop

PowerShell imports use the numeric module version, 0.1.0; Gallery packages carry the alpha2 prerelease label. Browse cmdlets with Get-Command -Module LibTmux and examples with Get-Help LibTmux\New-TmuxSession -Examples. The MCP server is a separate .NET tool; see MCP setup.

Build from source for development. The walkthrough below runs directly from the installed modules.

Create and read an object graph

Choose a unique socket and a clean tmux configuration. New-TmuxServer creates a handle without contacting tmux. The example does not touch your default server.

Terminal window
$server = LibTmux\New-TmuxServer `
-SocketName ('libtmux-readme-' + [Guid]::NewGuid().ToString('N')) `
-ConfigurationFile /dev/null

Create a session with an editor window, split it, add a logs window, and take one snapshot. cat keeps the three panes open without shell setup. The finally block removes only the session this example created.

Terminal window
$captured = & {
$ErrorActionPreference = 'Stop'
$session = $server |
New-TmuxSession -Name demo -WindowName editor -Command 'exec /bin/cat'
try {
$pane = $session | Get-TmuxPane
$null = $pane | Split-TmuxPane -Horizontal -Command 'exec /bin/cat'
$null = $session | New-TmuxWindow -Name logs -Command 'exec /bin/cat'
($server | Get-TmuxSnapshot).Sessions | Where-Object Name -CEQ demo
} finally {
$session | Remove-TmuxSession -Confirm:$false
}
}

$captured is a native LibTmux.Session. Its Windows contain native LibTmux.Window objects; each window’s Panes contain native LibTmux.Pane objects. The graph is still readable after cleanup:

ExpressionCaptured result
$capturedA Session named demo
$captured.WindowsTwo Window objects: editor and logs
$captured.Windows[0].PanesTwo Pane objects in editor; logs has one

Walk it and filter locally:

Terminal window
$captured.Windows |
Where-Object { $_.Panes.Count -gt 1 } |
Select-Object Name, @{ Name = 'PaneCount'; Expression = { $_.Panes.Count } }

The result is editor with two panes; logs has one. Where-Object, navigation, formatting, and property access use captured data and start no tmux client. Get-TmuxSnapshot explicitly reads fresh state. A linked window can have several session placements; its index belongs to the placement. See snapshots and linked windows for IDs, active children and captured versus unavailable fields.

The structured equivalent selects the one window with at least two captured panes. -ExactlyOne reports zero or multiple matches:

Terminal window
$captured.Windows |
Select-TmuxWindow -Criteria @{ 'Panes.Count' = @{ Ge = 2 } } -ExactlyOne

This query also performs no I/O. The query guide shows native predicates, Boolean and relationship criteria, and explicit fresh source queries.

Run a command to completion

When the shell’s exit status matters, run the command in a pane and inspect its native result. This example uses the private $server above and removes only the session it creates:

Terminal window
& {
$ErrorActionPreference = 'Stop'
$name = 'pane-run-' + [Guid]::NewGuid().ToString('N')
$session = $server | New-TmuxSession -Name $name -Command 'exec /bin/sh'
try {
$pane = $session | Get-TmuxPane
$pane |
Invoke-TmuxPaneCommand -Command 'exit 7' -Timeout 5 -Confirm:$false
} finally {
$session | Remove-TmuxSession -Confirm:$false
}
}

The result has ExitStatus = 7 and TimedOut = False. A nonzero shell exit is a result, not a tmux error. On timeout, the command may still be running, so the result has no exit status. See command completion for concurrency and output behavior.

Wait for service readiness

With Python 3 on PATH, start an HTTP server on an available loopback port. Use the private $server above, wait for the application’s readiness line, then make an HTTP request to check that it responds. The session’s cleanup also stops the server process:

Terminal window
& {
$ErrorActionPreference = 'Stop'
$session = $server | New-TmuxSession `
-Name ('http-' + [Guid]::NewGuid().ToString('N')) `
-Command 'exec python3 -u -m http.server 0 --bind 127.0.0.1'
try {
$pane = $session | Get-TmuxPane
$ready = $pane | Wait-TmuxPaneText `
-Pattern '^Serving HTTP on 127\.0\.0\.1 port [0-9]+' `
-CaseSensitive -Timeout 10 -TailLines 4 -Confirm:$false
if ($ready.Outcome -notin 'PresentAtEntry', 'Matched') {
throw "HTTP readiness ended with $($ready.Outcome)."
}
$tail = $ready.Tail -join "`n"
$port = [regex]::Match($tail, 'port ([0-9]+)').Groups[1].Value
$uri = "http://127.0.0.1:$port/"
$response = Invoke-WebRequest -Uri $uri -TimeoutSec 5 -NoProxy
$ready
$response.StatusCode
} finally {
$session | Remove-TmuxSession -Confirm:$false
}
}

The native PaneWaitResult has outcome PresentAtEntry or Matched, followed by HTTP status 200. The wait closes its temporary control client; the example removes only its session. A text match proves the readiness condition, and the HTTP request checks service behavior separately. See pane-text waits for stop patterns, bounded tails, cancellation and disclosed event loss. Use a cooperative channel when the application can signal completion itself.

Choose how to run

TaskUseExample
Read or change tmux stateTyped cmdlets and pipelinesCreate sessions and panes
Run a shell command and check its exit statusInvoke-TmuxPaneCommandRun to completion
Wait for a running application’s readiness lineWait-TmuxPaneTextReadiness and an HTTP health check
Enter a session interactivelyEnter-TmuxSessionAttach your foreground terminal
Run an ordered batchNew-TmuxCommand → Invoke-TmuxChainCompose commands
Reuse a connected clientConnect-TmuxControl → Invoke-TmuxControlCommandControl commands and cleanup
React to output and notificationsWatch-TmuxEventBounded event streams
Keep the prompt availableStart-ThreadJobBounded background jobs
Run commands concurrentlyForEach-Object -ParallelIndependent clients

Connect once to send a command through tmux control mode. This example uses the private endpoint from above, reads a session name, then disconnects and removes the session it created:

Terminal window
& {
$ErrorActionPreference = 'Stop'
$session = $server |
New-TmuxSession -Name control-demo -Command 'exec /bin/cat'
try {
$client = $server |
Connect-TmuxControl -Target 'control-demo' -ErrorAction Stop
try {
$command = New-TmuxCommand -Name display-message -Arguments @(
'-p', '#{session_name}'
)
$client |
Invoke-TmuxControlCommand -Command $command -ErrorAction Stop
} finally {
$client | Disconnect-TmuxControl -Confirm:$false
}
} finally {
$session | Remove-TmuxSession -Confirm:$false
}
}

The reply is control-demo. The client stays connected across commands inside the inner try block; use the control guide for multiple commands and cancellation behavior.

Foreground cmdlets and ForEach-Object -Parallel occupy their calling pipeline. Thread jobs return the prompt while they run; control mode keeps one client connected for repeated commands. Watchers accept event-count and text-byte limits. Choose a mode by its ownership and failure behavior, not a timing claim; the mode guide explains when chains merge failure attribution.

Modules and MCP

ProductUse it for
LibTmuxTyped cmdlets, snapshots, input, capture, control clients and event streams
LibTmux.WorkspaceDiscover YAML/JSON declarations, resolve directories, review plans and create workspaces
LibTmux.McpGive an assistant tmux tools through the separately installed .NET MCP server

Describe a two-pane workspace. Importing it parses YAML without contacting tmux or running its commands:

Terminal window
$workspace = LibTmux.Workspace\Import-TmuxWorkspace -Yaml @'
session_name: readme-workspace-preview
windows:
- window_name: editor
panes:
- shell_command: exec /bin/sh
- shell_command: exec /bin/sh
'@

Plan on the same private endpoint. Planning may read tmux state; it does not create the workspace:

Terminal window
$workspacePlan = $workspace | LibTmux.Workspace\Get-TmuxWorkspacePlan `
-Server $server -ServerStartup CreateOrJoin -ExistingSession Error

Review the actions. Their default view keeps command text, option values, paths and environment values hidden; inspect an action’s Request only in a trusted terminal:

Terminal window
$workspacePlan.Actions

Preview without applying the plan:

Terminal window
$workspacePlan | LibTmux.Workspace\Invoke-TmuxWorkspace -WhatIf

Apply that exact plan, then remove only the session it created. The captured result remains readable after cleanup:

Terminal window
$workspaceResult = & {
$result = $workspacePlan |
LibTmux.Workspace\Invoke-TmuxWorkspace -Confirm:$false -ErrorAction Stop
try { $result } finally {
$result.Session | Remove-TmuxSession -Confirm:$false
}
}
Terminal window
$workspaceResult.Windows |
Select-Object Name, @{ Name = 'PaneCount'; Expression = { $_.Panes.Count } }

This returns editor with two panes. The workspace guide covers failure recovery, attaching and exporting a declaration. For an MCP client, start with the client configuration, then read tools/list and tmux://capabilities before calling list_sessions or capture_pane.

Install both PowerShell modules at the same version. The MCP server is an independent .NET tool and does not require PowerShell.

Guides

The marked README blocks run together in the installed workflow test. The executable guides run against real tmux through the installed modules. See contributing for the runners and development checks.

The benchmark guide explains installed-package workloads, correctness checks, raw samples and reproduction commands.

Install from source

For development, install the pinned PowerShell and .NET SDK from .tool-versions with mise:

Terminal window
$ mise install

Install tmux with your operating system’s package manager and check that it is on PATH:

Terminal window
$ tmux -V

From the checkout root, restore the published .NET alpha.20 packages and build both PowerShell modules:

Terminal window
$ pwsh -NoLogo -NoProfile -File eng/Build.ps1 \
-Restore

Restore checks the committed lockfiles and stages both modules under build/Modules. Developing shared .NET changes uses the optional review-package workflow. Start PowerShell with the staged module path:

Terminal window
$ LIBTMUX_REVIEW_MODULE_ROOT="$PWD/build/Modules" \
pwsh \
-NoLogo \
-NoProfile

Import the exact staged manifests so an older installed module cannot shadow the new build:

Terminal window
$modules = $env:LIBTMUX_REVIEW_MODULE_ROOT
Import-Module -Name @(
"$modules/LibTmux/0.1.0/LibTmux.psd1",
"$modules/LibTmux.Workspace/0.1.0/LibTmux.Workspace.psd1"
) -ErrorAction Stop

Run the quick start from the checkout root. It creates a private server, splits the editor window, adds logs, and returns a captured native LibTmux.Session. Show each window’s pane IDs:

Terminal window
(./examples/QuickStart.ps1).Windows | Select-Object Name, @{
Name = 'PaneIds'
Expression = { $_.Panes.Id -join ', ' }
}

Output from the private server:

Name PaneIds
---- -------
editor %0, %1
logs %2

Assign ./examples/QuickStart.ps1 to a variable to keep the session object. Its Windows and Panes remain readable after the script removes its session. The script uses a unique socket and leaves your default tmux server alone.

License

MIT. See third-party notices for bundled dependencies.

Esc

Type to search.

Reference preview Open reference