tmux

package
v0.3.49 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 10, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// WindowWorkspace is the single tmux window that hosts the primary pane
	// (and any additional panes, e.g. an adopted shell) for every session type.
	WindowWorkspace = 0

	// DefaultSendTimeout is the default timeout for delivery-confirmed sends.
	DefaultSendTimeout = 2 * time.Second

	// PaneRoleOption is the tmux user-option key storing a pane's questmaster role.
	PaneRoleOption = "@party_role"
	// PaneRemainOnExit is the tmux pane option that keeps panes alive after exit.
	PaneRemainOnExit = "remain-on-exit"
	// PaneBorderStatusOption is the tmux window option controlling pane border status.
	PaneBorderStatusOption = "pane-border-status"
	// PaneBorderStatusTop positions the pane border status at the top.
	PaneBorderStatusTop = "top"

	// Pane role values stored under PaneRoleOption.
	RolePrimary = "primary"
	RoleShell   = "shell"
)

Variables

View Source
var (
	// ErrRoleNotFound is returned when no pane matches the requested role.
	ErrRoleNotFound = errors.New("role not found")
	// ErrRoleAmbiguous is returned when multiple panes match the requested role.
	ErrRoleAmbiguous = errors.New("ambiguous role: multiple panes match")
)
View Source
var ErrSendTimeout = errors.New("send timeout: pane not idle")

ErrSendTimeout is returned when the pane does not become idle within the send timeout.

Functions

func FilterAgentLines

func FilterAgentLines(raw string, max int) []string

FilterAgentLines extracts the last max meaningful lines from captured pane output: ⏺/⎿-prefixed lines, plus live-progress status lines detected by IsProgressLine (so Claude's "✳ Lollygagging… (…tokens · thinking with high effort)" is surfaced regardless of which spinner frame is current). Continuation lines after ⎿ (indented, no prefix) are included to preserve full tool results. Returns a slice of cleaned lines.

func FilterCodexLines

func FilterCodexLines(raw string, max int) []string

FilterCodexLines extracts the last max meaningful lines from Codex CLI pane output. Accepts ⏺, ⎿, and • prefixed lines — the bullet marker is specific to Codex output and kept separate from FilterAgentLines to avoid widening Claude-pane previews. Continuation lines after ⎿ are included (same logic as FilterAgentLines).

func IsProgressLine

func IsProgressLine(clean string) bool

IsProgressLine reports whether a cleaned pane line is a live-progress status line from Claude or Codex. The "esc to interrupt" / "esc to clear" phrase is the reliable universal signal (both agents emit it only during active generation); "thinking with" is a Claude-specific supplement that appears during ER/effort turns. Claude's tool-execution spinner omits those phrases and instead renders `<glyph> <verb>… (<time> · ↓ <tokens>)` where glyph cycles through claudeSpinnerGlyphs; we match that shape by glyph prefix plus a required `…` (which excludes the static `✻ Worked for Xm Ys` line Claude shows post-completion).

func PaneTarget

func PaneTarget(sessionID string, windowIdx, paneIdx int) string

PaneTarget returns the tmux target string "session:window.pane".

func WindowTarget

func WindowTarget(sessionID string, windowIdx int) string

WindowTarget returns the tmux target string "session:window".

func WorkspaceTarget

func WorkspaceTarget(sessionID string) string

WorkspaceTarget returns the tmux target for the workspace window in a session.

Types

type Client

type Client struct {
	SendTimeout time.Duration
	// contains filtered or unexported fields
}

Client provides typed tmux operations.

func NewClient

func NewClient(r Runner) *Client

NewClient creates a Client with the given Runner.

func NewExecClient

func NewExecClient() *Client

NewExecClient creates a Client that executes real tmux commands.

func (*Client) CacheListSessions added in v0.3.35

func (c *Client) CacheListSessions(ttl time.Duration)

CacheListSessions enables a short-lived cache for the expensive tmux list-sessions call. Call ClearListSessionsCache when durable session state changes so push-driven refreshes still observe real changes promptly.

func (*Client) Capture

func (c *Client) Capture(ctx context.Context, target string, lines int) (string, error)

Capture returns the last N lines of a pane's scrollback buffer.

func (*Client) ClearListSessionsCache added in v0.3.35

func (c *Client) ClearListSessionsCache()

func (*Client) EnsureSessionRunning

func (c *Client) EnsureSessionRunning(ctx context.Context, sessionID, label string) error

EnsureSessionRunning checks that a tmux session exists and returns a descriptive error if it does not. The label (e.g. "worker", "master") is included in the error message for context.

func (*Client) HasSession

func (c *Client) HasSession(ctx context.Context, sessionID string) (bool, error)

HasSession returns true if the named tmux session exists. Returns (false, nil) for genuine "session not found" and (false, error) for transport failures (connection refused, no server running, etc.).

func (*Client) IsPaneIdle

func (c *Client) IsPaneIdle(ctx context.Context, target string) (bool, error)

IsPaneIdle checks whether the pane is NOT in copy/choice mode.

func (*Client) KillSession

func (c *Client) KillSession(ctx context.Context, sessionID string) error

KillSession destroys a tmux session. Returns nil if the session does not exist. Propagates transport errors (permission denied, lost server) so callers don't delete manifests for sessions that are still alive but temporarily inaccessible.

func (*Client) KillWindow

func (c *Client) KillWindow(ctx context.Context, target string) error

KillWindow destroys a tmux window. Returns nil if the window does not exist.

func (*Client) ListAllPanes

func (c *Client) ListAllPanes(ctx context.Context) ([]Pane, error)

ListAllPanes returns panes across all live sessions with their role metadata.

func (*Client) ListPanes

func (c *Client) ListPanes(ctx context.Context, sessionID string) ([]Pane, error)

ListPanes returns all panes in a session across all windows with their role metadata.

func (*Client) ListSessionDetails

func (c *Client) ListSessionDetails(ctx context.Context) ([]SessionInfo, error)

ListSessionDetails returns name and active-pane CWD for all live sessions.

func (*Client) ListSessions

func (c *Client) ListSessions(ctx context.Context) ([]string, error)

ListSessions returns the names of all live tmux sessions. Returns an empty slice when tmux exits non-zero (no server, no sessions), matching the shell convention of `tmux ls ... || true`. Propagates other errors (missing binary, context cancellation).

func (*Client) NewSession

func (c *Client) NewSession(ctx context.Context, name, windowName, cwd string) error

NewSession creates a detached tmux session. Temporarily unsets TMUX env to avoid "sessions should be nested with care" errors when called from within an existing tmux session.

func (*Client) NewWindow

func (c *Client) NewWindow(ctx context.Context, session, name, cwd string) error

NewWindow creates a new window in a session.

func (*Client) RenameWindow

func (c *Client) RenameWindow(ctx context.Context, target, name string) error

RenameWindow renames a window.

func (*Client) ResolveRole

func (c *Client) ResolveRole(ctx context.Context, sessionID, role string, preferredWindow int) (string, error)

ResolveRole finds the pane with the given @party_role using window-aware lookup. If preferredWindow >= 0, that window is searched first; duplicate roles across different windows are allowed. Ambiguity is only reported when multiple panes share the role within the same searched scope. Pass preferredWindow < 0 to search all windows without preference.

func (*Client) RespawnPane

func (c *Client) RespawnPane(ctx context.Context, target, cwd, cmd string) error

RespawnPane kills the current process in a pane and starts a new one.

func (*Client) RunBatch

func (c *Client) RunBatch(ctx context.Context, cmds ...[]string) (string, error)

RunBatch executes multiple tmux commands sequentially, stopping on the first error. Each element of cmds is a slice of args for one command. Returns the output of the last successful command (usually empty for set-option/select-pane).

func (*Client) SelectPane

func (c *Client) SelectPane(ctx context.Context, target string) error

SelectPane makes a pane the active pane.

func (*Client) SelectPaneTitle

func (c *Client) SelectPaneTitle(ctx context.Context, target, title string) error

SelectPaneTitle sets a pane's title via select-pane -T.

func (*Client) SelectWindow

func (c *Client) SelectWindow(ctx context.Context, target string) error

SelectWindow makes a window active.

func (*Client) Send

func (c *Client) Send(ctx context.Context, target, text string) SendResult

Send delivers text to a tmux pane with idle-check retry. Retries until the pane leaves copy mode or timeout. Returns a SendResult envelope — callers inspect .Delivered and .Err.

func (*Client) SessionName

func (c *Client) SessionName(ctx context.Context) (string, error)

SessionName returns the current tmux session name.

func (*Client) SetEnvironment

func (c *Client) SetEnvironment(ctx context.Context, session, key, value string) error

SetEnvironment sets a session environment variable.

func (*Client) SetHook

func (c *Client) SetHook(ctx context.Context, session, hookName, cmd string) error

SetHook registers a tmux hook on a session.

func (*Client) SetPaneOption

func (c *Client) SetPaneOption(ctx context.Context, target, key, value string) error

SetPaneOption sets a pane option (-p).

func (*Client) SetSessionOption

func (c *Client) SetSessionOption(ctx context.Context, target, key, value string) error

SetSessionOption sets a session option.

func (*Client) SetWindowOption

func (c *Client) SetWindowOption(ctx context.Context, target, key, value string) error

SetWindowOption sets a window option (-w).

func (*Client) ShowEnvironment

func (c *Client) ShowEnvironment(ctx context.Context, session, key string) (string, bool, error)

ShowEnvironment reads a session environment variable. Returns the value and true if set, or "" and false if not set.

func (*Client) SplitWindow

func (c *Client) SplitWindow(ctx context.Context, target, cwd, cmd string, horizontal bool, pct ...int) error

SplitWindow creates a new pane by splitting an existing one. If horizontal is true, splits horizontally (-h); otherwise vertically. An optional pct sets the new pane's size as a percentage (-p).

func (*Client) SwitchClientWithFallback

func (c *Client) SwitchClientWithFallback(ctx context.Context, target string) error

SwitchClientWithFallback tries switch-client, then falls back to explicit client targeting via list-clients. Required for popup contexts where the TTY isn't associated with a tmux client. When multiple clients exist, the first from list-clients is used. This is correct for the typical single-terminal case; multi-client setups may need explicit client targeting.

func (*Client) UnsetEnvironment

func (c *Client) UnsetEnvironment(ctx context.Context, session, key string) error

UnsetEnvironment removes a session or global environment variable. Pass session="" for global (-g) unset.

type ExecRunner

type ExecRunner struct{}

ExecRunner implements Runner using os/exec.

func (ExecRunner) Run

func (ExecRunner) Run(ctx context.Context, args ...string) (string, error)

Run executes a tmux command and returns its trimmed stdout. Wraps non-zero exits as *ExitError (with stderr) so callers can distinguish "session not found" from transport errors.

func (ExecRunner) RunWithoutEnv

func (ExecRunner) RunWithoutEnv(ctx context.Context, excludeKey string, args ...string) (string, error)

RunWithoutEnv executes a tmux command with the named env var filtered from the child process environment. Goroutine-safe — does not mutate process env.

type ExitError

type ExitError struct {
	Code   int
	Stderr string
}

ExitError indicates a tmux command ran but exited with a non-zero status. This distinguishes "tmux ran but failed" from "tmux binary not found". Stderr is captured so callers can distinguish "session not found" from transport errors (connection refused, no server running, etc.).

func (*ExitError) Error

func (e *ExitError) Error() string

func (*ExitError) IsConnectionError

func (e *ExitError) IsConnectionError() bool

IsConnectionError returns true if the error indicates an active tmux transport failure (permission denied, server crash) rather than the benign "no tmux server exists yet" case. The distinction matters because "no server" is functionally equivalent to "session not found", while a real transport failure (e.g. socket with wrong permissions) should not be silently treated as "session stopped".

type Pane

type Pane struct {
	SessionName string
	WindowIndex int
	PaneIndex   int
	Role        string // PaneRoleOption value
}

Pane represents a tmux pane with its role metadata.

func (Pane) Target

func (p Pane) Target() string

Target returns the tmux target string for this pane.

type Runner

type Runner interface {
	Run(ctx context.Context, args ...string) (string, error)
}

Runner executes tmux commands and returns stdout.

type SendResult

type SendResult struct {
	Delivered bool
	Target    string
	Err       error
}

SendResult represents the outcome of a delivery-confirmed send.

type SessionInfo

type SessionInfo struct {
	Name string
	Cwd  string
}

SessionInfo holds basic metadata about a live tmux session.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL