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
- Variables
- func HelperMain(arguments []string, diagnostics io.Writer) (handled bool, exitCode int)
- func Probe(ctx context.Context, runner CommandRunner, tmuxPath string) error
- func ResolveBinary(runner CommandRunner, configuredPath string) (string, error)
- func SessionName(runID, agentID string) string
- type CommandError
- type CommandRunner
- type CommandSpec
- type ExitError
- type InteractiveBackend
- type Manager
- func (m *Manager) AnsiOutput(id string) (string, error)
- func (m *Manager) AttachCommand(ctx context.Context, id string) (*exec.Cmd, error)
- func (m *Manager) BeginShutdown()
- func (m *Manager) Close(ctx context.Context) error
- func (m *Manager) Context() context.Context
- func (m *Manager) Done(id string) (<-chan struct{}, error)
- func (m *Manager) Name() string
- func (m *Manager) Output(id string) (string, error)
- func (m *Manager) PendingEvent(ctx context.Context, id string) (*adapters.Event, error)
- func (m *Manager) Remove(ctx context.Context, id string) error
- func (m *Manager) Resize(ctx context.Context, id string, size terminal.Size) error
- func (m *Manager) Resync(ctx context.Context, id string, columns, rows int) error
- func (m *Manager) RuntimeDirectory() string
- func (m *Manager) Send(ctx context.Context, id string, data []byte) error
- func (m *Manager) SendEvent(ctx context.Context, id, eventID string, data []byte) error
- func (m *Manager) SendInput(id, value string) error
- func (m *Manager) SendLine(ctx context.Context, id, line string) error
- func (m *Manager) SendRaw(ctx context.Context, id string, data []byte) error
- func (m *Manager) SetRecorder(recorder terminal.Recorder)
- func (m *Manager) Snapshot(ctx context.Context, id string) (terminal.Snapshot, error)
- func (m *Manager) Start(ctx context.Context, spec agent.Spec, size terminal.Size) (_ terminal.Info, resultErr error)
- func (m *Manager) Stop(ctx context.Context, id string) error
- type Options
- type Size
- type Snapshot
- type Status
Constants ¶
const ( StatusRunning = terminal.StatusRunning StatusDetached = terminal.StatusDetached StatusAttached = terminal.StatusAttached StatusExited = terminal.StatusExited StatusFailed = terminal.StatusFailed )
const (
// HelperSubcommand is private protocol between Relayer and its tmux panes.
HelperSubcommand = "__relayer_tmux_exec"
)
Variables ¶
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") )
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 ¶
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 ¶
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 ¶
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 ¶
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.
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) AttachCommand ¶
func (*Manager) BeginShutdown ¶
func (m *Manager) BeginShutdown()
func (*Manager) Close ¶
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) PendingEvent ¶
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
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) Resync ¶
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 ¶
RuntimeDirectory exposes only the private directory location for diagnostics and permission tests; it never exposes a specification path or its content.
func (*Manager) SendEvent ¶
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) SendLine ¶
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
SendRaw writes raw terminal input bytes directly to the tmux pane without prompt serialization.
func (*Manager) SetRecorder ¶ added in v0.7.0
SetRecorder attaches a transcript recorder. Like the PTY backend, it must be called before the first Start.
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.