# Getting started

Source: https://libtmux.org/en/powershell/latest/guides/getting-started/

> Getting started: LibTmux documentation.

Drive [tmux](https://github.com/tmux/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](https://github.com/libtmux/libtmux-dotnet), in the
same [libtmux organization](https://github.com/libtmux) and with the same main
author. The cmdlets return its native objects and add PowerShell parameter
binding, help, formatting and `-WhatIf` / `-Confirm`.

[Install](https://libtmux.org/en/powershell/latest/guides/getting-started/#install) · [Object graph](https://libtmux.org/en/powershell/latest/guides/getting-started/#create-and-read-an-object-graph) ·
[Run to completion](https://libtmux.org/en/powershell/latest/guides/getting-started/#run-a-command-to-completion) ·
[Service readiness](https://libtmux.org/en/powershell/latest/guides/getting-started/#wait-for-service-readiness) ·
[Execution modes](https://libtmux.org/en/powershell/latest/guides/getting-started/#choose-how-to-run) · [Guides](https://libtmux.org/en/powershell/latest/guides/getting-started/#guides) ·
[MCP](https://libtmux.org/en/powershell/latest/guides/mcp/#discover-before-calling) ·
[Compatibility](https://libtmux.org/en/powershell/latest/guides/compatibility/) ·
[Troubleshooting](https://libtmux.org/en/powershell/latest/guides/troubleshooting/) ·
[Cmdlet reference](https://github.com/libtmux/libtmux-powershell/blob/b06c64f844f3173de66b187eaeaf3915814318c6/docs/reference/README.md) · [License](https://libtmux.org/en/powershell/latest/guides/getting-started/#license)

**Alpha.** APIs may change. Both modules are available on PowerShell Gallery:
[LibTmux](https://www.powershellgallery.com/packages/LibTmux)
and [LibTmux.Workspace](https://www.powershellgallery.com/packages/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](https://libtmux.org/en/powershell/latest/guides/compatibility/) for the support contract.

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

```console
$ 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:

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

PowerShellGet is an alternative. Install the core module:

```console
$ Install-Module -Name LibTmux -AllowPrerelease
```

Or install the workspace module with its matching core dependency:

```console
$ 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](https://libtmux.org/en/powershell/latest/guides/compatibility/).

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

```console
$ 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](https://libtmux.org/en/powershell/latest/guides/mcp/#install-and-select-a-server).

[Build from source](https://libtmux.org/en/powershell/latest/guides/getting-started/#install-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`](<https://libtmux.org/en/powershell/latest/reference/libtmux-new-tmuxserver/>)
creates a handle without contacting tmux. The example does not touch your
default server.

<!-- example: read.endpoint -->
```powershell
$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.

<!-- example: readme.create -->
```powershell
$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`](<https://libtmux.org/en/csharp/latest/reference/libtmux-session/>). Its [`Windows`][session-windows]
contain native [`LibTmux.Window`](<https://libtmux.org/en/csharp/latest/reference/libtmux-window/>) objects; each window's [`Panes`][window-panes]
contain native [`LibTmux.Pane`](<https://libtmux.org/en/csharp/latest/reference/libtmux-pane/>) objects. The graph is still readable after
cleanup:

| Expression | Captured result |
| --- | --- |
| `$captured` | A [`Session`](<https://libtmux.org/en/csharp/latest/reference/libtmux-session/>) named `demo` |
| [`$captured.Windows`][session-windows] | Two [`Window`](<https://libtmux.org/en/csharp/latest/reference/libtmux-window/>) objects: `editor` and `logs` |
| [`$captured.Windows[0].Panes`][window-panes] | Two [`Pane`](<https://libtmux.org/en/csharp/latest/reference/libtmux-pane/>) objects in `editor`; `logs` has one |

Walk it and filter locally:

<!-- example: readme.filter -->
```powershell
$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`](<https://learn.microsoft.com/powershell/module/microsoft.powershell.core/where-object?view=powershell-7.4>),
navigation, formatting, and property access use captured data and start no
tmux client. [`Get-TmuxSnapshot`](<https://libtmux.org/en/powershell/latest/reference/libtmux-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](https://libtmux.org/en/powershell/latest/guides/read/) 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:

<!-- example: readme.related -->
```powershell
$captured.Windows |
    Select-TmuxWindow -Criteria @{ 'Panes.Count' = @{ Ge = 2 } } -ExactlyOne
```

This query also performs no I/O. [The query guide](https://libtmux.org/en/powershell/latest/guides/query/) 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:

<!-- example: input.run -->
```powershell
& {
    $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](https://libtmux.org/en/powershell/latest/guides/input/#run-a-command-to-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:

<!-- example: input.http-ready -->
```powershell
& {
    $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`](<https://libtmux.org/en/csharp/latest/reference/libtmux-panewaitresult/>) has outcome [`PresentAtEntry`](<https://libtmux.org/en/csharp/latest/reference/libtmux-panewaitoutcome-presentatentry/>) or [`Matched`](<https://libtmux.org/en/csharp/latest/reference/libtmux-panewaitoutcome-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](https://libtmux.org/en/powershell/latest/guides/input/#wait-for-an-applications-readiness-line)
for stop patterns, bounded tails, cancellation and disclosed event loss.
Use [a cooperative channel](https://libtmux.org/en/powershell/latest/guides/input/#send-a-command-and-wait-for-its-output)
when the application can signal completion itself.

## Choose how to run

| Task | Use | Example |
| --- | --- | --- |
| Read or change tmux state | Typed cmdlets and pipelines | [Create sessions and panes](https://libtmux.org/en/powershell/latest/guides/create/) |
| Run a shell command and check its exit status | [`Invoke-TmuxPaneCommand`](<https://libtmux.org/en/powershell/latest/reference/libtmux-invoke-tmuxpanecommand/>) | [Run to completion](https://libtmux.org/en/powershell/latest/guides/input/#run-a-command-to-completion) |
| Wait for a running application's readiness line | [`Wait-TmuxPaneText`](<https://libtmux.org/en/powershell/latest/reference/libtmux-wait-tmuxpanetext/>) | [Readiness and an HTTP health check](https://libtmux.org/en/powershell/latest/guides/getting-started/#wait-for-service-readiness) |
| Enter a session interactively | [`Enter-TmuxSession`](<https://libtmux.org/en/powershell/latest/reference/libtmux-enter-tmuxsession/>) | [Attach your foreground terminal](https://libtmux.org/en/powershell/latest/reference/libtmux-enter-tmuxsession/) |
| Run an ordered batch | [`New-TmuxCommand`](<https://libtmux.org/en/powershell/latest/reference/libtmux-new-tmuxcommand/>) → [`Invoke-TmuxChain`](<https://libtmux.org/en/powershell/latest/reference/libtmux-invoke-tmuxchain/>) | [Compose commands](https://libtmux.org/en/powershell/latest/guides/commands/) |
| Reuse a connected client | [`Connect-TmuxControl`](<https://libtmux.org/en/powershell/latest/reference/libtmux-connect-tmuxcontrol/>) → [`Invoke-TmuxControlCommand`](<https://libtmux.org/en/powershell/latest/reference/libtmux-invoke-tmuxcontrolcommand/>) | [Control commands and cleanup](https://libtmux.org/en/powershell/latest/guides/commands/) |
| React to output and notifications | [`Watch-TmuxEvent`](<https://libtmux.org/en/powershell/latest/reference/libtmux-watch-tmuxevent/>) | [Bounded event streams](https://libtmux.org/en/powershell/latest/guides/watch/) |
| Keep the prompt available | [`Start-ThreadJob`](<https://learn.microsoft.com/powershell/module/threadjob/start-threadjob?view=powershell-7.4>) | [Bounded background jobs](https://libtmux.org/en/powershell/latest/guides/watch/#bound-background-output) |
| Run commands concurrently | `ForEach-Object -Parallel` | [Independent clients](https://libtmux.org/en/powershell/latest/guides/watch/#run-independent-commands-concurrently) |

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:

<!-- example: readme.control -->
```powershell
& {
    $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](https://libtmux.org/en/powershell/latest/guides/commands/#reuse-a-control-client)
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](https://libtmux.org/en/powershell/latest/guides/commands/) explains when chains merge failure attribution.

## Modules and MCP

| Product | Use it for |
| --- | --- |
| [LibTmux](https://github.com/libtmux/libtmux-powershell/blob/b06c64f844f3173de66b187eaeaf3915814318c6/docs/reference/README.md) | Typed cmdlets, snapshots, input, capture, control clients and event streams |
| [LibTmux.Workspace](https://libtmux.org/en/powershell/latest/workspace/source-guide/#plan-and-review) | Discover YAML/JSON declarations, resolve directories, review plans and create workspaces |
| [LibTmux.Mcp](https://libtmux.org/en/powershell/latest/guides/mcp/#discover-before-calling) | Give 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:

<!-- example: readme.workspace.01-import -->
```powershell
$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:

<!-- example: readme.workspace.02-plan -->
```powershell
$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`][workspaceaction-request] only in a trusted terminal:

<!-- example: readme.workspace.03-review -->
```powershell
$workspacePlan.Actions
```

Preview without applying the plan:

<!-- example: readme.workspace.04-preview -->
```powershell
$workspacePlan | LibTmux.Workspace\Invoke-TmuxWorkspace -WhatIf
```

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

<!-- example: readme.workspace.05-apply -->
```powershell
$workspaceResult = & {
    $result = $workspacePlan |
        LibTmux.Workspace\Invoke-TmuxWorkspace -Confirm:$false -ErrorAction Stop
    try { $result } finally {
        $result.Session | Remove-TmuxSession -Confirm:$false
    }
}
```

<!-- example: readme.workspace.06-graph -->
```powershell
$workspaceResult.Windows |
    Select-Object Name, @{ Name = 'PaneCount'; Expression = { $_.Panes.Count } }
```

This returns `editor` with two panes. The
[workspace guide](https://libtmux.org/en/powershell/latest/workspace/source-guide/#apply-the-reviewed-plan) covers failure
recovery, attaching and exporting a declaration. For an MCP client, start with
the [client configuration](https://libtmux.org/en/powershell/latest/guides/mcp/#install-and-select-a-server), then read
`tools/list` and `tmux://capabilities` before calling
[`list_sessions` or `capture_pane`](https://libtmux.org/en/powershell/latest/guides/mcp/#discover-before-calling).

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

## Guides

- **Read:** [snapshots and filtering](https://libtmux.org/en/powershell/latest/guides/read/), [structured queries](https://libtmux.org/en/powershell/latest/guides/query/),
  [pane contents and scrollback](https://libtmux.org/en/powershell/latest/guides/capture/), [attached clients](https://libtmux.org/en/powershell/latest/guides/clients/).
- **Automate:** [create](https://libtmux.org/en/powershell/latest/guides/create/), [send text and keys](https://libtmux.org/en/powershell/latest/guides/input/),
  [arrange and resize](https://libtmux.org/en/powershell/latest/guides/layout/), [link and move windows](https://libtmux.org/en/powershell/latest/guides/placement/),
  [remove](https://libtmux.org/en/powershell/latest/guides/remove/).
- **Configure:** [options](https://libtmux.org/en/powershell/latest/guides/options/), [hooks](https://libtmux.org/en/powershell/latest/guides/hooks/),
  [environment for new panes](https://libtmux.org/en/powershell/latest/guides/environment/).
- **Coordinate:** [chains and control clients](https://libtmux.org/en/powershell/latest/guides/commands/),
  [event streams, jobs and parallel workers](https://libtmux.org/en/powershell/latest/guides/watch/).
- **Assistants:** [install and configure the MCP server](https://libtmux.org/en/powershell/latest/guides/mcp/).
- **Workspaces:** [load, review and apply](https://libtmux.org/en/powershell/latest/workspace/source-guide/),
  [export a starting declaration](https://libtmux.org/en/powershell/latest/workspace/source-guide/#export-a-starting-declaration),
  [edit a declaration](https://libtmux.org/en/powershell/latest/workspace/source-guide/#edit-the-declaration).

The marked README blocks run together in the
[installed workflow test](https://github.com/libtmux/libtmux-powershell/blob/b06c64f844f3173de66b187eaeaf3915814318c6/tests/ReadmeWorkflow.Tests.ps1). The
[executable guides](https://github.com/libtmux/libtmux-powershell/blob/b06c64f844f3173de66b187eaeaf3915814318c6/examples/Guides.ps1) run against real tmux through the
installed modules. See [contributing](https://github.com/libtmux/libtmux-powershell/blob/b06c64f844f3173de66b187eaeaf3915814318c6/.github/CONTRIBUTING.md) for the runners
and development checks.

The [benchmark guide](https://github.com/libtmux/libtmux-powershell/blob/b06c64f844f3173de66b187eaeaf3915814318c6/benchmarks/README.md) 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](https://github.com/libtmux/libtmux-powershell/blob/b06c64f844f3173de66b187eaeaf3915814318c6/.tool-versions) with
[mise](https://mise.jdx.dev/):

```console
$ mise install
```

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

```console
$ tmux -V
```

From the checkout root, restore the published
[.NET alpha.20 packages](https://www.nuget.org/packages/LibTmux/0.0.0-alpha.20)
and build both PowerShell modules:

```console
$ 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](https://github.com/libtmux/libtmux-powershell/blob/b06c64f844f3173de66b187eaeaf3915814318c6/.github/CONTRIBUTING.md#review-package-builds).
Start PowerShell with the staged module path:

```console
$ 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:

<!-- example: readme.install.import -->
```powershell
$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](https://github.com/libtmux/libtmux-powershell/blob/b06c64f844f3173de66b187eaeaf3915814318c6/examples/QuickStart.ps1) from the checkout root. It
creates a private server, splits the `editor` window, adds `logs`, and returns
a captured native [`LibTmux.Session`](<https://libtmux.org/en/csharp/latest/reference/libtmux-session/>). Show each window's pane IDs:

<!-- example: readme.quickstart -->
```powershell
(./examples/QuickStart.ps1).Windows | Select-Object Name, @{
    Name = 'PaneIds'
    Expression = { $_.Panes.Id -join ', ' }
}
```

Output from the private server:

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

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

## License

[MIT](https://github.com/libtmux/libtmux-powershell/blob/b06c64f844f3173de66b187eaeaf3915814318c6/LICENSE). See [third-party notices](https://github.com/libtmux/libtmux-powershell/blob/b06c64f844f3173de66b187eaeaf3915814318c6/licenses/THIRD-PARTY-NOTICES.md)
for bundled dependencies.

[session-windows]: https://libtmux.org/en/csharp/latest/reference/libtmux-session-windows/
[window-panes]: https://libtmux.org/en/csharp/latest/reference/libtmux-window-panes/
[workspaceaction-request]: https://libtmux.org/en/csharp/latest/workspace/reference/libtmux-workspace-workspaceaction-request/
[session-panes]: https://libtmux.org/en/csharp/latest/reference/libtmux-session-panes/
