Documentation
¶
Index ¶
- Constants
- Variables
- func FilterAgentLines(raw string, max int) []string
- func FilterCodexLines(raw string, max int) []string
- func IsProgressLine(clean string) bool
- func PaneTarget(sessionID string, windowIdx, paneIdx int) string
- func ResolveRoleFromPanes(sessionID string, panes []Pane, role string, preferredWindow int) (string, error)
- func WindowTarget(sessionID string, windowIdx int) string
- func WorkspaceTarget(sessionID string) string
- type Client
- func (c *Client) Capture(ctx context.Context, target string, lines int) (string, error)
- func (c *Client) CurrentSessionName(ctx context.Context) (string, error)
- func (c *Client) EnsureSessionRunning(ctx context.Context, sessionID, label string) error
- func (c *Client) HasSession(ctx context.Context, sessionID string) (bool, error)
- func (c *Client) IsPaneIdle(ctx context.Context, target string) (bool, error)
- func (c *Client) KillSession(ctx context.Context, sessionID string) error
- func (c *Client) KillWindow(ctx context.Context, target string) error
- func (c *Client) ListAllPanes(ctx context.Context) ([]Pane, error)
- func (c *Client) ListPanes(ctx context.Context, sessionID string) ([]Pane, error)
- func (c *Client) ListSessionClients(ctx context.Context, sessionID string) ([]string, error)
- func (c *Client) ListSessionDetails(ctx context.Context) ([]SessionInfo, error)
- func (c *Client) ListSessions(ctx context.Context) ([]string, error)
- func (c *Client) NewSession(ctx context.Context, name, windowName, cwd string) error
- func (c *Client) NewWindow(ctx context.Context, session, name, cwd string) error
- func (c *Client) RenameWindow(ctx context.Context, target, name string) error
- func (c *Client) ResizePane(ctx context.Context, target, width string) error
- func (c *Client) ResolveRole(ctx context.Context, sessionID, role string, preferredWindow int) (string, error)
- func (c *Client) RespawnPane(ctx context.Context, target, cwd, cmd string) error
- func (c *Client) RunBatch(ctx context.Context, cmds ...[]string) (string, error)
- func (c *Client) RunShell(ctx context.Context, target, cmd string) error
- func (c *Client) SelectPane(ctx context.Context, target string) error
- func (c *Client) SelectPaneTitle(ctx context.Context, target, title string) error
- func (c *Client) SelectWindow(ctx context.Context, target string) error
- func (c *Client) Send(ctx context.Context, target, text string) SendResult
- func (c *Client) SessionCwd(ctx context.Context, sessionID string) (string, error)
- func (c *Client) SessionName(ctx context.Context) (string, error)
- func (c *Client) SetEnvironment(ctx context.Context, session, key, value string) error
- func (c *Client) SetHook(ctx context.Context, session, hookName, cmd string) error
- func (c *Client) SetPaneOption(ctx context.Context, target, key, value string) error
- func (c *Client) SetSessionOption(ctx context.Context, target, key, value string) error
- func (c *Client) SetWindowOption(ctx context.Context, target, key, value string) error
- func (c *Client) ShowEnvironment(ctx context.Context, session, key string) (string, bool, error)
- func (c *Client) SplitWindow(ctx context.Context, target, cwd, cmd string, horizontal bool, pct ...int) error
- func (c *Client) SwitchClient(ctx context.Context, target string) error
- func (c *Client) SwitchClientTarget(ctx context.Context, clientTTY, target string) error
- func (c *Client) SwitchClientWithFallback(ctx context.Context, target string) error
- func (c *Client) UnsetEnvironment(ctx context.Context, session, key string) error
- type ExecRunner
- type ExitError
- type Pane
- type Runner
- type SendResult
- type SessionInfo
Constants ¶
const ( // WindowWorkspace is the single tmux window that hosts the tracker, // primary, and shell panes 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 party 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" RoleTracker = "tracker" RoleShell = "shell" )
Variables ¶
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") )
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 ¶
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 ¶
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 ¶
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 ¶
PaneTarget returns the tmux target string "session:window.pane".
func ResolveRoleFromPanes ¶
func ResolveRoleFromPanes(sessionID string, panes []Pane, role string, preferredWindow int) (string, error)
ResolveRoleFromPanes resolves a role using a caller-provided pane index.
func WindowTarget ¶
WindowTarget returns the tmux target string "session:window".
func WorkspaceTarget ¶
WorkspaceTarget returns the tmux target for the workspace window in a session.
Types ¶
type Client ¶
Client provides typed tmux operations.
func NewExecClient ¶
func NewExecClient() *Client
NewExecClient creates a Client that executes real tmux commands.
func (*Client) CurrentSessionName ¶
CurrentSessionName returns the name of the tmux session this process is attached to. Only meaningful when the TMUX env var is set (i.e., running inside tmux).
func (*Client) EnsureSessionRunning ¶
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 ¶
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 ¶
IsPaneIdle checks whether the pane is NOT in copy/choice mode.
func (*Client) KillSession ¶
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 ¶
KillWindow destroys a tmux window. Returns nil if the window does not exist.
func (*Client) ListAllPanes ¶
ListAllPanes returns panes across all live sessions with their role metadata.
func (*Client) ListPanes ¶
ListPanes returns all panes in a session across all windows with their role metadata.
func (*Client) ListSessionClients ¶
ListSessionClients returns client TTYs attached to a session.
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 ¶
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 ¶
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) RenameWindow ¶
RenameWindow renames a window.
func (*Client) ResizePane ¶
ResizePane sets a pane's width to the given percentage string (e.g. "20%").
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 ¶
RespawnPane kills the current process in a pane and starts a new one.
func (*Client) RunBatch ¶
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 ¶
SelectPane makes a pane the active pane.
func (*Client) SelectPaneTitle ¶
SelectPaneTitle sets a pane's title via select-pane -T.
func (*Client) SelectWindow ¶
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) SessionCwd ¶
SessionCwd returns the active pane's current path for the named session.
func (*Client) SessionName ¶
SessionName returns the current tmux session name.
func (*Client) SetEnvironment ¶
SetEnvironment sets a session environment variable.
func (*Client) SetPaneOption ¶
SetPaneOption sets a pane option (-p).
func (*Client) SetSessionOption ¶
SetSessionOption sets a session option.
func (*Client) SetWindowOption ¶
SetWindowOption sets a window option (-w).
func (*Client) ShowEnvironment ¶
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) SwitchClient ¶
SwitchClient switches the current tmux client to the target session.
func (*Client) SwitchClientTarget ¶
SwitchClientTarget switches a specific client to a target session.
func (*Client) SwitchClientWithFallback ¶
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 via SwitchClient.
type ExecRunner ¶
type ExecRunner struct{}
ExecRunner implements Runner using os/exec.
func (ExecRunner) Run ¶
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 ¶
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) IsConnectionError ¶
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.
type SendResult ¶
SendResult represents the outcome of a delivery-confirmed send.
type SessionInfo ¶
SessionInfo holds basic metadata about a live tmux session.