tmuxbackend

package
v0.8.19 Latest Latest
Warning

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

Go to latest
Published: Oct 9, 2026 License: MIT Imports: 24 Imported by: 0

Documentation

Overview

Package tmuxbackend owns Relayer-created tmux sessions.

It deliberately exposes process-neutral operations to callers: tmux command construction, ownership tracking and output transport stay inside this package. User commands are launched by Relayer's helper from a private JSON specification; they are never concatenated into a tmux shell command.

Index

Constants

View Source
const (
	StatusRunning  = terminal.StatusRunning
	StatusDetached = terminal.StatusDetached
	StatusAttached = terminal.StatusAttached
	StatusExited   = terminal.StatusExited
	StatusFailed   = terminal.StatusFailed
)
View Source
const (
	// HelperSubcommand is private protocol between Relayer and its tmux panes.
	HelperSubcommand = "__relayer_tmux_exec"
)

Variables

View Source
var (
	// ErrTmuxNotFound identifies an unavailable requested tmux executable.
	ErrTmuxNotFound = errors.New("tmux not found")
	// Aliases keep errors recognizable through the neutral terminal contract.
	ErrSessionNotFound = terminal.ErrSessionNotFound
	ErrClosed          = terminal.ErrClosed
	ErrUnsupported     = terminal.ErrUnsupported
	// ErrStopUncertain means tmux accepted a termination attempt but Relayer
	// could not confirm that the immutable owned session ID disappeared.
	ErrStopUncertain = errors.New("tmux session stop not confirmed")
)
View Source
var ErrProbeFailed = errors.New("tmux inutilisable")

ErrProbeFailed reports a tmux executable that was found but cannot serve Relayer's machine-readable protocol.

Functions

func HelperMain

func HelperMain(arguments []string, diagnostics io.Writer) (handled bool, exitCode int)

HelperMain handles the private tmux launch mode before public CLI parsing. Callers should exit with exitCode when handled is true.

func Probe

func Probe(ctx context.Context, runner CommandRunner, tmuxPath string) error

Probe reports whether a resolved tmux executable can actually run a Relayer session. Finding the binary on PATH is not sufficient evidence: tmux sanitizes unprintable bytes while rendering a format, so a tmux whose responses cannot be parsed makes every session start fail with an opaque identity error long after startup reported success.

The check is self-contained and never touches the user's tmux server. It creates one short-lived session on a private socket inside a 0700 temporary directory, reads its identity through the same format the runtime uses, then kills that session by name. The private server exits with its last session, so the probe never calls kill-server.

The user's tmux configuration is deliberately loaded: a configuration that breaks format rendering would break the real backend too, and the probe exists to observe exactly that.

func ResolveBinary

func ResolveBinary(runner CommandRunner, configuredPath string) (string, error)

ResolveBinary locates tmux and returns a recognizable error when an explicit tmux backend cannot be satisfied. It is also used by backend:auto selection.

func SessionName

func SessionName(runID, agentID string) string

SessionName returns a stable name inside one Relayer run. The run component isolates concurrent Relayer processes, while the hash prevents slug collisions such as "agent a" and "agent-a".

Types

type CommandError

type CommandError struct {
	Operation string
	Err       error
}

CommandError identifies the failed tmux operation without echoing argv, which may contain paths or other private metadata.

func (*CommandError) Error

func (e *CommandError) Error() string

func (*CommandError) Unwrap

func (e *CommandError) Unwrap() error

type CommandRunner

type CommandRunner interface {
	LookPath(file string) (string, error)
	Run(context.Context, CommandSpec) ([]byte, error)
	Command(context.Context, CommandSpec) *exec.Cmd
}

CommandRunner makes tmux behavior deterministic in unit tests. Command is separate from Run because tea.ExecProcess needs the unstarted *exec.Cmd.

type CommandSpec

type CommandSpec struct {
	Path  string
	Args  []string
	Stdin []byte
}

CommandSpec is an argv-safe process invocation. Args never pass through a shell and Stdin keeps sensitive answers out of argv and process listings.

type ExitError

type ExitError struct {
	Code int
}

ExitError preserves a non-zero pane status in session.Exited events.

func (*ExitError) Error

func (e *ExitError) Error() string

type InteractiveBackend

type InteractiveBackend interface {
	Name() string
	AttachCommand(context.Context, string) (*exec.Cmd, error)
	Resync(context.Context, string, int, int) error
}

InteractiveBackend is the optional capability consumed by the Bubble Tea layer when Enter temporarily hands the real terminal to tmux.

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager is the sole owner of tmux sessions bearing its generated run prefix.

func NewManager

func NewManager(
	parent context.Context,
	events chan<- session.Event,
	patterns []intercept.Pattern,
	ringCapacity int,
	options Options,
) (*Manager, error)

NewManager verifies tmux before creating any session and allocates a private 0700 runtime directory for specs and FIFO transports.

func NewManagerWithRegistry

func NewManagerWithRegistry(
	parent context.Context,
	events chan<- session.Event,
	registry *adapters.Registry,
	ringCapacity int,
	options Options,
) (*Manager, error)

NewManagerWithRegistry is the production constructor. Each Start resolves an independent adapter instance from registry before any tmux process is created; the legacy constructor above only translates intercept_patterns.

func (*Manager) AnsiOutput

func (m *Manager) AnsiOutput(id string) (string, error)

func (*Manager) AttachCommand

func (m *Manager) AttachCommand(ctx context.Context, id string) (*exec.Cmd, error)

func (*Manager) BeginShutdown

func (m *Manager) BeginShutdown()

func (*Manager) Close

func (m *Manager) Close(ctx context.Context) error

Close is idempotent after success and retryable after a timeout or cleanup error. PersistOnExit skips owned session kills, but private tmux buffers and failed-Start placeholders are always cleaned. Every kill is ownership checked and every attempt shares one bounded caller-aware cleanup budget.

func (*Manager) Context

func (m *Manager) Context() context.Context

func (*Manager) Done

func (m *Manager) Done(id string) (<-chan struct{}, error)

func (*Manager) Name

func (m *Manager) Name() string

func (*Manager) Output

func (m *Manager) Output(id string) (string, error)

func (*Manager) PendingEvent

func (m *Manager) PendingEvent(ctx context.Context, id string) (*adapters.Event, error)

PendingEvent returns cached processor state only. In particular, it never starts a tmux subprocess from Bubble Tea's Update path.

func (*Manager) Remove added in v0.4.0

func (m *Manager) Remove(ctx context.Context, id string) error

Remove forgets one fully stopped session so a later Start can recreate it under the same identity. A session still present on the tmux server — including one intentionally persisted by remain-on-exit — is killed first with the same ownership proof Stop requires. When that proof or the kill fails, the identity stays registered and locked so no replacement process can ever share it.

func (*Manager) Resize

func (m *Manager) Resize(ctx context.Context, id string, size terminal.Size) error

func (*Manager) Resync

func (m *Manager) Resync(ctx context.Context, id string, columns, rows int) error

Resync suppresses live adapter events while the real terminal is attached, then atomically reconciles the Processor against the current active pane line. Event occurrence IDs provide deduplication across output and snapshots.

func (*Manager) RuntimeDirectory

func (m *Manager) RuntimeDirectory() string

RuntimeDirectory exposes only the private directory location for diagnostics and permission tests; it never exposes a specification path or its content.

func (*Manager) Send

func (m *Manager) Send(ctx context.Context, id string, data []byte) error

func (*Manager) SendEvent

func (m *Manager) SendEvent(ctx context.Context, id, eventID string, data []byte) error

SendEvent serializes an exact event decision with terminal delivery. The Processor clears the pending occurrence only after tmux accepted the bytes; an empty eventID preserves the legacy raw Send contract.

func (*Manager) SendInput

func (m *Manager) SendInput(id, value string) error

func (*Manager) SendLine

func (m *Manager) SendLine(ctx context.Context, id, line string) error

SendLine serializes ordinary text with tmux delivery, event detection and process termination. Processor.SendLine appends the sole carriage return and does not acknowledge an actionable event.

func (*Manager) SendRaw added in v0.6.0

func (m *Manager) SendRaw(ctx context.Context, id string, data []byte) error

SendRaw writes raw terminal input bytes directly to the tmux pane without prompt serialization.

func (*Manager) SetRecorder added in v0.7.0

func (m *Manager) SetRecorder(recorder terminal.Recorder)

SetRecorder attaches a transcript recorder. Like the PTY backend, it must be called before the first Start.

func (*Manager) Snapshot

func (m *Manager) Snapshot(ctx context.Context, id string) (terminal.Snapshot, error)

func (*Manager) Start

func (m *Manager) Start(ctx context.Context, spec agent.Spec, size terminal.Size) (_ terminal.Info, resultErr error)

Start configures capture and remain-on-exit before releasing the helper gate, ensuring that even very short-lived commands are observable.

func (*Manager) Stop

func (m *Manager) Stop(ctx context.Context, id string) error

type Options

type Options struct {
	Runner           CommandRunner
	TmuxPath         string
	HelperPath       string
	RuntimeDir       string
	RunID            string
	PersistOnExit    bool
	CleanupOnSuccess bool
	PollInterval     time.Duration
	CaptureLimit     int
	// contains filtered or unexported fields
}

Options controls tmux command execution, retention and private runtime data. Zero values select conservative defaults.

type Size

type Size = terminal.Size

type Snapshot

type Snapshot = terminal.Snapshot

type Status

type Status = terminal.Status

Jump to

Keyboard shortcuts

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