server

package
v0.5.0 Latest Latest
Warning

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

Go to latest
Published: Apr 15, 2026 License: MIT Imports: 45 Imported by: 0

Documentation

Index

Constants

View Source
const (
	EventLayout           = eventloop.EventLayout
	EventOutput           = eventloop.EventOutput
	EventTerminal         = eventloop.EventTerminal
	EventIdle             = eventloop.EventIdle
	EventBusy             = eventloop.EventBusy
	EventExited           = eventloop.EventExited
	EventClientConnect    = eventloop.EventClientConnect
	EventClientDisconnect = eventloop.EventClientDisconnect
	EventPaneExit         = eventloop.EventPaneExit
)
View Source
const (
	DisconnectReasonServerReload   = eventloop.DisconnectReasonServerReload
	DisconnectReasonExplicitDetach = eventloop.DisconnectReasonExplicitDetach
	DisconnectReasonSocketError    = eventloop.DisconnectReasonSocketError
)
View Source
const (
	MsgTypeInput        = proto.MsgTypeInput
	MsgTypeResize       = proto.MsgTypeResize
	MsgTypeAttach       = proto.MsgTypeAttach
	MsgTypeDetach       = proto.MsgTypeDetach
	MsgTypeCommand      = proto.MsgTypeCommand
	MsgTypeRender       = proto.MsgTypeRender
	MsgTypeCmdResult    = proto.MsgTypeCmdResult
	MsgTypeExit         = proto.MsgTypeExit
	MsgTypeNotify       = proto.MsgTypeNotify
	MsgTypeBell         = proto.MsgTypeBell
	MsgTypePaneOutput   = proto.MsgTypePaneOutput
	MsgTypeLayout       = proto.MsgTypeLayout
	MsgTypeServerReload = proto.MsgTypeServerReload
	MsgTypeCopyMode     = proto.MsgTypeCopyMode
	MsgTypeClipboard    = proto.MsgTypeClipboard
	MsgTypeInputPane    = proto.MsgTypeInputPane

	// Bidirectional — capture routed through attached client
	MsgTypeCaptureRequest  = proto.MsgTypeCaptureRequest
	MsgTypeCaptureResponse = proto.MsgTypeCaptureResponse

	// Server → Client — inject keystrokes into client input pipeline
	MsgTypeTypeKeys = proto.MsgTypeTypeKeys

	// Client → Server — transient client-local UI state transitions
	MsgTypeUIEvent = proto.MsgTypeUIEvent

	// Server → Client — retained pane history bootstrap during attach.
	MsgTypePaneHistory = proto.MsgTypePaneHistory
)
View Source
const (
	DefaultTermCols = proto.DefaultTermCols
	DefaultTermRows = proto.DefaultTermRows
)

Default terminal dimensions when the client doesn't report a size.

View Source
const DefaultEventThrottle = eventloop.DefaultEventThrottle
View Source
const DefaultOutputLines = 50

DefaultOutputLines is how many lines `amux output` shows by default.

View Source
const DefaultSessionName = "main"

DefaultSessionName is the implicit session used when callers do not specify one.

View Source
const ReloadServerExecPathFlag = remotecmd.ReloadServerExecPathFlag
View Source
const WindowNameFormat = "window-%d"

WindowNameFormat is the default name for auto-created windows.

Variables

View Source
var BuildVersion string

BuildVersion is set by main at startup for version reporting in status.

Functions

func DetectCrashedSession

func DetectCrashedSession(sessionName string) string

DetectCrashedSession checks if a crash checkpoint exists for the given session AND the server socket is stale or missing. Returns the checkpoint path if a crashed session is detected, or "" if no recovery is needed.

func FormatKillCommandError

func FormatKillCommandError(err error, command string) string

FormatKillCommandError rewrites usage errors for the requested command name.

func KillCommandUsage

func KillCommandUsage(command string) string

KillCommandUsage formats the user-facing usage string for the kill command.

func PprofSocketPath added in v0.3.0

func PprofSocketPath(session string) string

func SocketDir

func SocketDir() string

SocketDir returns the directory for amux Unix sockets.

func SocketPath

func SocketPath(session string) string

SocketPath returns the socket path for a session.

func ValidateKillCommandArgs

func ValidateKillCommandArgs(args []string) error

ValidateKillCommandArgs validates kill CLI arguments without mutating state.

func WriteMsg

func WriteMsg(w io.Writer, msg *Message) error

WriteMsg encodes and writes a message to w.

Types

type CheckpointCoordinator added in v0.4.0

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

CheckpointCoordinator owns crash checkpoint scheduling and file writes for a session.

func NewCheckpointCoordinator added in v0.4.0

func NewCheckpointCoordinator(cfg CheckpointCoordinatorConfig) *CheckpointCoordinator

func (*CheckpointCoordinator) Stop added in v0.4.0

func (c *CheckpointCoordinator) Stop()

func (*CheckpointCoordinator) Trigger added in v0.4.0

func (c *CheckpointCoordinator) Trigger()

func (*CheckpointCoordinator) Write added in v0.4.0

func (c *CheckpointCoordinator) Write()

func (*CheckpointCoordinator) WriteNow added in v0.4.0

func (c *CheckpointCoordinator) WriteNow() (string, error)

type CheckpointCoordinatorConfig added in v0.4.0

type CheckpointCoordinatorConfig struct {
	Clock                   Clock
	Debounce                time.Duration
	Periodic                time.Duration
	SessionName             func() string
	SessionStart            func() time.Time
	BuildCrashCheckpoint    func() *checkpoint.CrashCheckpoint
	IsShuttingDown          func() bool
	OnCheckpointWritten     func(string)
	LogCheckpointWrite      func(string, time.Duration, error)
	LogDirectoryUnavailable func(error)
	WriteCrash              func(*checkpoint.CrashCheckpoint, string, time.Time) error
	MkdirAll                func(string, os.FileMode) error
}

type Clock

type Clock interface {
	Now() time.Time
	NewTimer(d time.Duration) Timer
	AfterFunc(d time.Duration, f func()) Timer
}

Clock abstracts time operations for testability.

type CommandContext

type CommandContext struct {
	CommandName string
	CC          *clientConn
	Srv         *Server
	Sess        *Session
	Args        []string
	ActorPaneID uint32
	// contains filtered or unexported fields
}

CommandContext provides all state a command handler needs.

type CommandHandler

type CommandHandler func(ctx *CommandContext)

CommandHandler processes a single CLI command.

type ConnectionLog

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

func (*ConnectionLog) Append

func (l *ConnectionLog) Append(entry ConnectionLogEntry)

func (*ConnectionLog) Snapshot

func (l *ConnectionLog) Snapshot() []ConnectionLogEntry

type ConnectionLogEntry

type ConnectionLogEntry struct {
	Timestamp        time.Time
	Event            string
	ClientID         string
	Cols             int
	Rows             int
	DisconnectReason string
}

type Event

type Event = eventloop.Event

type IdleTracker added in v0.4.0

type IdleTracker struct {
	VTIdleSettle  time.Duration
	VTIdleTimeout time.Duration
	// contains filtered or unexported fields
}

IdleTracker owns the server's per-pane input-idle and vt-idle bookkeeping.

func NewIdleTracker added in v0.4.0

func NewIdleTracker(clock func() Clock) *IdleTracker

func (*IdleTracker) HandleIdleTimeout added in v0.4.0

func (t *IdleTracker) HandleIdleTimeout(paneID uint32)

func (*IdleTracker) HandleVTIdleTimeout added in v0.4.0

func (t *IdleTracker) HandleVTIdleTimeout(paneID uint32, expected time.Time) bool

func (*IdleTracker) IsIdle added in v0.4.0

func (t *IdleTracker) IsIdle(id uint32) bool

func (*IdleTracker) LastOutput added in v0.4.0

func (t *IdleTracker) LastOutput(paneID uint32) (time.Time, bool)

func (*IdleTracker) PaneStatus added in v0.4.0

func (t *IdleTracker) PaneStatus(paneID uint32, createdAt, now time.Time) paneIdleStatus

func (*IdleTracker) PrimeSettling added in v0.4.0

func (t *IdleTracker) PrimeSettling(paneID uint32, at time.Time)

func (*IdleTracker) Settle added in v0.4.0

func (t *IdleTracker) Settle() time.Duration

func (*IdleTracker) SnapshotFull added in v0.4.0

func (t *IdleTracker) SnapshotFull() (map[uint32]bool, map[uint32]time.Time)

func (*IdleTracker) SnapshotState added in v0.4.0

func (t *IdleTracker) SnapshotState(panes []*mux.Pane, now time.Time) map[uint32]bool

func (*IdleTracker) StopPane added in v0.4.0

func (t *IdleTracker) StopPane(paneID uint32)

func (*IdleTracker) Timeout added in v0.4.0

func (t *IdleTracker) Timeout() time.Duration

func (*IdleTracker) TrackOutput added in v0.4.0

func (t *IdleTracker) TrackOutput(paneID uint32, onIdle func(), onSettled func(time.Time)) bool

func (*IdleTracker) WaitState added in v0.4.0

func (t *IdleTracker) WaitState(paneID uint32, createdAt time.Time) idleWaitState

type Message

type Message = proto.Message

func ReadMsg

func ReadMsg(r io.Reader) (*Message, error)

ReadMsg reads a message from r.

type MsgType

type MsgType = proto.MsgType

Re-export wire protocol types from proto to maintain backwards compatibility. All callsites using server.WriteMsg, server.ReadMsg, server.Message, etc. continue to work unchanged.

type MutationContext added in v0.3.0

type MutationContext struct {
	Name             string
	Window           *mux.Window
	Windows          []*mux.Window
	ActiveWindowID   uint32
	PreviousWindowID uint32
	Panes            []*mux.Pane
	RemoteManager    proto.PaneTransport
	// contains filtered or unexported fields
}

MutationContext exposes the subset of session state and helpers that command mutation callbacks can use while running on the session event loop.

func (*MutationContext) ScheduleClose added in v0.3.0

func (ctx *MutationContext) ScheduleClose(pane *mux.Pane)

func (*MutationContext) ScheduleStart added in v0.3.0

func (ctx *MutationContext) ScheduleStart(pane *mux.Pane)

type PaneLog

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

PaneLog is a circular buffer of pane lifecycle events.

func (*PaneLog) Append

func (l *PaneLog) Append(entry PaneLogEntry)

func (*PaneLog) Snapshot

func (l *PaneLog) Snapshot() []PaneLogEntry

type PaneLogEntry

type PaneLogEntry struct {
	Timestamp  time.Time
	Event      string
	PaneID     uint32
	PaneName   string
	Host       string
	Cwd        string
	GitBranch  string
	ExitReason string
}

PaneLogEntry records a pane lifecycle event.

type PaneTakeoverFactory

type PaneTakeoverFactory func(PaneTransportHooks) PaneTakeoverTransport

PaneTakeoverFactory builds a takeover-only transport for sessions that do not have a general remote pane transport configured.

type PaneTakeoverTransport

type PaneTakeoverTransport interface {
	AttachForTakeover(hostName, sshAddr, sshUser, remoteUID, sessionName string, paneMappings map[uint32]uint32) error
	DeployToAddress(hostName, sshAddr, sshUser string)
}

PaneTakeoverTransport is the narrower transport surface needed only for SSH takeover attach/deploy flows.

type PaneTransportFactory

type PaneTransportFactory func(PaneTransportHooks) proto.PaneTransport

PaneTransportFactory builds one transport for a session using the session's actor-safe callback hooks.

type PaneTransportHooks

type PaneTransportHooks struct {
	OnPaneOutput  func(localPaneID uint32, data []byte)
	OnPaneExit    func(localPaneID uint32, reason string)
	OnStateChange func(hostName string, state proto.ConnState)
}

PaneTransportHooks are the server-owned callbacks a transport uses to route remote output, exits, and state changes back into the session actor.

type Reader added in v0.4.0

type Reader = proto.Reader

func NewReader added in v0.4.0

func NewReader(r io.Reader) *Reader

NewReader binds a connection-scoped wire reader to r.

type RealClock

type RealClock struct{}

RealClock delegates to the standard time package.

func (RealClock) AfterFunc

func (RealClock) AfterFunc(d time.Duration, f func()) Timer

func (RealClock) NewTimer

func (RealClock) NewTimer(d time.Duration) Timer

func (RealClock) Now

func (RealClock) Now() time.Time

type Server

type Server struct {
	Env ServerEnv

	// ResolveReloadExecPath resolves the executable path for server reload.
	// Defaults to reload.ResolveExecutable; tests inject stubs.
	ResolveReloadExecPath func() (string, error)
	// contains filtered or unexported fields
}

Server listens on a Unix socket and manages sessions.

func NewServerFromCheckpointWithScrollback

func NewServerFromCheckpointWithScrollback(cp *checkpoint.ServerCheckpoint, scrollbackLines int) (*Server, error)

NewServerFromCheckpointWithScrollback restores a server from a checkpoint using an explicit retained scrollback limit for restored panes.

func NewServerFromCheckpointWithScrollbackLogger added in v0.2.0

func NewServerFromCheckpointWithScrollbackLogger(cp *checkpoint.ServerCheckpoint, scrollbackLines int, logger *charmlog.Logger) (*Server, error)

func NewServerFromCrashCheckpointWithListenerFd

func NewServerFromCrashCheckpointWithListenerFd(sessionName string, listenerFd int, cp *checkpoint.CrashCheckpoint, crashPath string, scrollbackLines int) (*Server, error)

NewServerFromCrashCheckpointWithListenerFd restores crash state onto the listener inherited across a failed hot-reload restore.

func NewServerFromCrashCheckpointWithListenerFdLogger added in v0.2.0

func NewServerFromCrashCheckpointWithListenerFdLogger(sessionName string, listenerFd int, cp *checkpoint.CrashCheckpoint, crashPath string, scrollbackLines int, logger *charmlog.Logger) (*Server, error)

func NewServerFromCrashCheckpointWithScrollback

func NewServerFromCrashCheckpointWithScrollback(sessionName string, cp *checkpoint.CrashCheckpoint, crashPath string, scrollbackLines int) (*Server, error)

NewServerFromCrashCheckpointWithScrollback restores a server from a crash checkpoint with an explicit retained scrollback limit.

func NewServerFromCrashCheckpointWithScrollbackLogger added in v0.2.0

func NewServerFromCrashCheckpointWithScrollbackLogger(sessionName string, cp *checkpoint.CrashCheckpoint, crashPath string, scrollbackLines int, logger *charmlog.Logger) (*Server, error)

func NewServerWithScrollback

func NewServerWithScrollback(sessionName string, scrollbackLines int) (*Server, error)

func NewServerWithScrollbackLogger added in v0.2.0

func NewServerWithScrollbackLogger(sessionName string, scrollbackLines int, logger *charmlog.Logger) (*Server, error)

func (*Server) EnablePprof added in v0.3.0

func (s *Server) EnablePprof() error

func (*Server) EnsureInitialWindow

func (s *Server) EnsureInitialWindow(cols, rows int) error

EnsureInitialWindow creates the first window and pane for the first session if the session is currently empty. This is used by takeover-managed startup, where a remote server must be ready before any interactive client attaches.

func (*Server) Reload

func (s *Server) Reload(execPath string) error

Reload checkpoints the server state and exec's the new binary. On success, this function never returns (the process image is replaced). On failure, the old server continues running.

func (*Server) Run

func (s *Server) Run() error

Run accepts client connections in a loop.

func (*Server) SetLogger added in v0.2.0

func (s *Server) SetLogger(logger *charmlog.Logger)

func (*Server) SetPaneMetaAutoRefresh

func (s *Server) SetPaneMetaAutoRefresh(enabled bool)

SetPaneMetaAutoRefresh enables or disables background cwd/git refresh on idle transitions for all current sessions. Callers must use this during startup before the server begins mutating s.sessions concurrently.

func (*Server) SetupPaneTakeoverTransport

func (s *Server) SetupPaneTakeoverTransport(factory PaneTakeoverFactory)

SetupPaneTakeoverTransport installs the takeover-only transport used for SSH takeover flows when no generic remote pane transport is configured.

func (*Server) SetupPaneTransport

func (s *Server) SetupPaneTransport(hostColor func(string) string, factory PaneTransportFactory)

SetupPaneTransport installs per-session transports without importing the concrete transport package into the server package.

func (*Server) Shutdown

func (s *Server) Shutdown()

type ServerEnv

type ServerEnv struct {
	ExitUnattached bool // AMUX_EXIT_UNATTACHED=1
	NoWatch        bool // AMUX_NO_WATCH=1
}

ServerEnv holds server-only environment variables that are read once at startup and unset so child processes (pane shells, inner amux) don't inherit them. The values are re-exported before syscall.Exec in Reload() so they survive hot-reload.

func ReadServerEnv

func ReadServerEnv() ServerEnv

ReadServerEnv reads all server-only env vars and unsets them from the process environment. Call once at startup in runServer().

func (ServerEnv) Export

func (e ServerEnv) Export() []string

Export returns the env vars as key=value strings for syscall.Exec. Only exports vars that are set (non-zero).

type Session

type Session struct {
	Name string

	Windows        []*mux.Window // ordered list of windows
	ActiveWindowID uint32        // which window is displayed
	// PreviousWindowID tracks the last active window for `last-window`.
	PreviousWindowID uint32
	Panes            []*mux.Pane // flat list of ALL panes across all windows

	// Configurable timing — zero values use defaults. Tests inject short durations.
	VTIdleSettle time.Duration // default: 2s
	Clock        Clock         // nil uses RealClock
	// PaneMetaResolver refreshes live cwd/git metadata for a pane. Nil uses
	// the pane's DetectCwdBranch implementation.
	PaneMetaResolver func(*mux.Pane) (cwd, branch string)
	// DisablePaneMetaAutoRefresh skips background cwd/git refresh on idle
	// transitions.
	DisablePaneMetaAutoRefresh bool

	// Remote pane management — nil when no remote transport is configured.
	RemoteManager proto.PaneTransport
	// contains filtered or unexported fields
}

Session holds the state for one amux session.

type Timer

type Timer interface {
	C() <-chan time.Time
	Stop() bool
	Reset(d time.Duration) bool
}

Timer is the subset of *time.Timer used by wait commands.

type UndoManager added in v0.4.0

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

UndoManager owns soft-close state, grace-period timers, and undo cleanup event handling for a session.

type VTIdleTracker

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

VTIdleTracker tracks per-pane output quiescence. Event-loop only.

func NewVTIdleTracker

func NewVTIdleTracker(clock Clock) *VTIdleTracker

func (*VTIdleTracker) IsSettled

func (t *VTIdleTracker) IsSettled(paneID uint32, createdAt time.Time, settle time.Duration, now time.Time) bool

func (*VTIdleTracker) LastOutput

func (t *VTIdleTracker) LastOutput(paneID uint32) (time.Time, bool)

func (*VTIdleTracker) MarkSettled

func (t *VTIdleTracker) MarkSettled(paneID uint32, expected time.Time) bool

MarkSettled records that the quiet timer still matches the most recent output edge. Stale callbacks return false.

func (*VTIdleTracker) PrimeSettling

func (t *VTIdleTracker) PrimeSettling(paneID uint32, at time.Time)

PrimeSettling marks a pane as having recent activity without scheduling a synthetic settled callback. Restores use this when a fresh runtime replaces an older pane but the pane keeps its historical CreatedAt for display.

func (*VTIdleTracker) Remaining

func (t *VTIdleTracker) Remaining(paneID uint32, createdAt time.Time, settle time.Duration, now time.Time) time.Duration

func (*VTIdleTracker) StopTimer

func (t *VTIdleTracker) StopTimer(paneID uint32)

func (*VTIdleTracker) TrackOutput

func (t *VTIdleTracker) TrackOutput(paneID uint32, settle time.Duration, onSettled func(time.Time))

TrackOutput records fresh output and schedules a screen-quiet callback for the settle window.

type Writer added in v0.4.0

type Writer = proto.Writer

func NewWriter added in v0.4.0

func NewWriter(w io.Writer) *Writer

NewWriter binds a connection-scoped wire writer to w.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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