peer

package
v0.1.1-beta.2 Latest Latest
Warning

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

Go to latest
Published: Mar 15, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// MsgAuth is the challenge-response auth message
	MsgAuth = "auth"
	// MsgStateUpdate is a full session state snapshot
	MsgStateUpdate = "state-update"
	// MsgStateEvent is an incremental state change
	MsgStateEvent = "state-event"
	// MsgToolEvent forwards a local tool event
	MsgToolEvent = "tool-event"
	// MsgActivityUpdate sends periodic sparkline data
	MsgActivityUpdate = "activity-update"
	// MsgStats sends system stats
	MsgStats = "stats"
)

Message types sent from peer to hub over control WebSocket

View Source
const (
	// MsgChallenge is the auth challenge from hub
	MsgChallenge = "challenge"
	// MsgAuthOK indicates successful authentication
	MsgAuthOK = "auth-ok"
	// MsgAuthFail indicates failed authentication
	MsgAuthFail = "auth-fail"
	// MsgPeerState is aggregated state from all other peers
	MsgPeerState = "peer-state"
	// MsgPeerConnected notifies that a new peer joined
	MsgPeerConnected = "peer-connected"
	// MsgPeerDisconnected notifies that a peer left
	MsgPeerDisconnected = "peer-disconnected"
	// MsgPTYOpen requests the peer to spawn a PTY
	MsgPTYOpen = "pty-open"
	// MsgPTYClose requests the peer to close a PTY
	MsgPTYClose = "pty-close"
	// MsgPTYResize requests the peer to resize a PTY
	MsgPTYResize = "pty-resize"
	// MsgSessionAction forwards an API action to the peer
	MsgSessionAction = "session-action"
	// MsgRequestState asks the peer for a full state refresh
	MsgRequestState = "request-state"
)

Message types sent from hub to peer over control WebSocket

View Source
const (
	// OfflineTimeout is how long to keep an offline peer's sessions visible
	OfflineTimeout = 5 * time.Minute
)

Variables

This section is empty.

Functions

func Bridge

func Bridge(browserWS, peerWS *websocket.Conn, streamID string)

Bridge runs the bidirectional relay between browser and peer WebSocket connections. This blocks until one side disconnects.

func GenerateStreamID

func GenerateStreamID() string

GenerateStreamID creates a random stream ID

Types

type ActiveBridge

type ActiveBridge struct {
	StreamID  string
	BrowserWS *websocket.Conn
	PeerWS    *websocket.Conn
}

ActiveBridge is an active PTY relay between browser and peer

type ActivePTY

type ActivePTY struct {
	StreamID string
	PTY      *tmux.PTYSession
	HubWS    *websocket.Conn
}

ActivePTY is a local PTY session being relayed to a remote browser via the hub

type ActivityUpdatePayload

type ActivityUpdatePayload struct {
	Snapshots []*activity.Snapshot `json:"snapshots"`
}

ActivityUpdatePayload carries sparkline data from a peer

type AuthPayload

type AuthPayload struct {
	PublicKey string `json:"public_key"`
	Signature string `json:"signature"` // base64-encoded signature of the challenge
}

AuthPayload is sent by the peer in response to a challenge

type ChallengePayload

type ChallengePayload struct {
	Challenge string `json:"challenge"` // base64-encoded random bytes
}

ChallengePayload is sent by the hub to initiate auth

type Client

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

Client connects to a hub and syncs local state

func NewClient

func NewClient(hubURL string, id *identity.Identity, peerStore *identity.PeerStore,
	localMgr *state.Manager, peerMgr *Manager, actTracker *activity.Tracker,
	toolTracker *toolevents.Tracker, tmuxPath string, insecure bool) *Client

NewClient creates a new peer client

func (*Client) HubURL

func (c *Client) HubURL() string

HubURL returns the hub URL for PTY connections

func (*Client) Insecure

func (c *Client) Insecure() bool

Insecure returns whether TLS verification is skipped

func (*Client) Run

func (c *Client) Run(ctx context.Context)

Run connects to the hub and maintains the connection with reconnection

func (*Client) TLSConfig

func (c *Client) TLSConfig() *tls.Config

TLSConfig returns the TLS configuration (exported for PTYManager)

type Handler

type Handler struct {
	CACertPEM string // CA certificate PEM to include in pairing responses
	// contains filtered or unexported fields
}

Handler handles incoming peer WebSocket connections (hub side)

func NewHandler

func NewHandler(manager *Manager, peerStore *identity.PeerStore, tracker *toolevents.Tracker, pairing *identity.PairingManager, ptyRelay *PTYRelay) *Handler

NewHandler creates a new peer connection handler

func (*Handler) HandlePairing

func (h *Handler) HandlePairing(w http.ResponseWriter, r *http.Request)

HandlePairing handles the POST /api/pair/complete endpoint for the pairing handshake

func (*Handler) HandlePeer

func (h *Handler) HandlePeer(w http.ResponseWriter, r *http.Request)

HandlePeer handles the /ws/peer endpoint for control channel connections

type HostInfo

type HostInfo struct {
	ID       string                 `json:"id"` // public key fingerprint
	Name     string                 `json:"name"`
	Version  string                 `json:"version,omitempty"`
	Local    bool                   `json:"local,omitempty"`
	Online   bool                   `json:"online"`
	Sessions []*tmux.Session        `json:"sessions"`
	Activity []*activity.Snapshot   `json:"activity,omitempty"`
	Stats    map[string]interface{} `json:"stats,omitempty"`
	LastSeen time.Time              `json:"last_seen"`
}

HostInfo represents a peer's state as seen by the hub

type HostState

type HostState struct {
	ID         string // public key fingerprint
	Name       string
	Version    string
	PublicKey  string
	Sessions   []*tmux.Session
	Stats      map[string]interface{}
	Activity   []*activity.Snapshot
	ToolEvents []*toolevents.Event
	Connected  bool
	LastSeen   time.Time
	Conn       *PeerConnection // nil for local host
}

HostState holds all known state for a single peer

type Manager

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

Manager aggregates state from local tmux and remote peers

func NewManager

func NewManager(id *identity.Identity, peerStore *identity.PeerStore, localMgr *state.Manager) *Manager

NewManager creates a new peer manager

func (*Manager) GetAllActivity

func (m *Manager) GetAllActivity() []*activity.Snapshot

GetAllActivity returns activity snapshots from all remote peers (not local)

func (*Manager) GetAllSessions

func (m *Manager) GetAllSessions() []*tmux.Session

GetAllSessions returns sessions from all hosts, with host fields stamped

func (*Manager) GetHostName

func (m *Manager) GetHostName(id string) string

GetHostName returns the display name for a host ID

func (*Manager) GetHosts

func (m *Manager) GetHosts() []HostInfo

GetHosts returns info about all known hosts

func (*Manager) GetLocalSessions

func (m *Manager) GetLocalSessions() []*tmux.Session

GetLocalSessions returns only this node's sessions

func (*Manager) GetPeerConnection

func (m *Manager) GetPeerConnection(id string) *PeerConnection

GetPeerConnection returns the connection for a specific peer

func (*Manager) HasHost

func (m *Manager) HasHost(id string) bool

HasHost returns true if a host with the given ID is known

func (*Manager) IsLocal

func (m *Manager) IsLocal(hostID string) bool

IsLocal returns true if the given host ID is this node

func (*Manager) LocalID

func (m *Manager) LocalID() string

LocalID returns this node's fingerprint

func (*Manager) LocalName

func (m *Manager) LocalName() string

LocalName returns this node's display name

func (*Manager) RegisterPeer

func (m *Manager) RegisterPeer(id, name, publicKey string, conn *PeerConnection)

RegisterPeer registers a newly connected peer

func (*Manager) Run

func (m *Manager) Run()

Run starts forwarding local state events to peer manager subscribers and pruning offline peers

func (*Manager) Subscribe

func (m *Manager) Subscribe() chan state.StateEvent

Subscribe returns a channel that receives state events from all hosts

func (*Manager) UnregisterPeer

func (m *Manager) UnregisterPeer(id string)

UnregisterPeer marks a peer as disconnected

func (*Manager) Unsubscribe

func (m *Manager) Unsubscribe(ch chan state.StateEvent)

Unsubscribe removes a subscriber channel

func (*Manager) UpdatePeerActivity

func (m *Manager) UpdatePeerActivity(id string, snapshots []*activity.Snapshot)

UpdatePeerActivity updates a peer's activity snapshots

func (*Manager) UpdatePeerSessions

func (m *Manager) UpdatePeerSessions(id string, sessions []*tmux.Session)

UpdatePeerSessions updates a peer's session list

func (*Manager) UpdatePeerStats

func (m *Manager) UpdatePeerStats(id string, stats map[string]interface{})

UpdatePeerStats updates a peer's system stats

func (*Manager) UpdatePeerVersion

func (m *Manager) UpdatePeerVersion(id, version string)

UpdatePeerVersion updates a peer's reported version

type Message

type Message struct {
	Type    string          `json:"type"`
	Payload json.RawMessage `json:"payload"`
}

Message is the envelope for all control WebSocket messages

func NewMessage

func NewMessage(msgType string, payload interface{}) (*Message, error)

NewMessage creates a Message with a typed payload

type PTYClosePayload

type PTYClosePayload struct {
	StreamID string `json:"stream_id"`
}

PTYClosePayload requests a peer to close a PTY session

type PTYManager

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

PTYManager manages local PTY sessions spawned on behalf of remote browsers

func NewPTYManager

func NewPTYManager(tmuxPath string, actTracker *activity.Tracker, client *Client) *PTYManager

NewPTYManager creates a new PTY manager

func (*PTYManager) Close

func (pm *PTYManager) Close(streamID string)

Close closes a PTY session by stream ID

func (*PTYManager) Open

func (pm *PTYManager) Open(req PTYOpenPayload)

Open spawns a local PTY and connects it to the hub via a dedicated WebSocket

func (*PTYManager) Resize

func (pm *PTYManager) Resize(streamID string, cols, rows uint16)

Resize resizes a PTY session

type PTYOpenPayload

type PTYOpenPayload struct {
	StreamID string `json:"stream_id"`
	Session  string `json:"session"`
	Cols     uint16 `json:"cols"`
	Rows     uint16 `json:"rows"`
}

PTYOpenPayload requests a peer to spawn a PTY session

type PTYRelay

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

PTYRelay bridges browser WebSocket connections to peer PTY WebSocket connections

func NewPTYRelay

func NewPTYRelay() *PTYRelay

NewPTYRelay creates a new PTY relay

func (*PTYRelay) CompletePending

func (r *PTYRelay) CompletePending(streamID string, peerWS *websocket.Conn) bool

CompletePending is called when a peer connects its PTY WebSocket for a stream

func (*PTYRelay) HandlePeerPTY

func (r *PTYRelay) HandlePeerPTY(w http.ResponseWriter, req *http.Request)

HandlePeerPTY handles the /ws/peer-pty endpoint where peers connect their PTY WebSocket

func (*PTYRelay) RegisterPending

func (r *PTYRelay) RegisterPending(streamID, hostID string, browserWS *websocket.Conn) *PendingStream

RegisterPending registers a browser connection waiting for a peer PTY

func (*PTYRelay) Remove

func (r *PTYRelay) Remove(streamID string)

Remove removes a stream from tracking

type PTYResizePayload

type PTYResizePayload struct {
	StreamID string `json:"stream_id"`
	Cols     uint16 `json:"cols"`
	Rows     uint16 `json:"rows"`
}

PTYResizePayload requests a peer to resize a PTY session

type PeerConnection

type PeerConnection struct {
	HostID string
	Send   chan *Message // messages queued for sending to this peer
}

PeerConnection wraps a control WebSocket to a peer

type PeerNotifyPayload

type PeerNotifyPayload struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

PeerNotifyPayload is sent when a peer connects or disconnects

type PeerStatePayload

type PeerStatePayload struct {
	Hosts []HostInfo `json:"hosts"`
}

PeerStatePayload is the aggregated state sent from hub to peers

type PendingStream

type PendingStream struct {
	StreamID  string
	HostID    string
	BrowserWS *websocket.Conn
	Ready     chan *websocket.Conn // peer sends its WS connection here
}

PendingStream is a browser waiting for a peer to open a PTY WebSocket

type SessionActionPayload

type SessionActionPayload struct {
	Action string          `json:"action"` // new, rename, select-window
	Params json.RawMessage `json:"params"`
}

SessionActionPayload forwards a session API action to a peer

type StateEventPayload

type StateEventPayload struct {
	EventType string `json:"event_type"` // session-added, session-removed, sessions-changed
	Session   string `json:"session,omitempty"`
}

StateEventPayload carries an incremental state change

type StateUpdatePayload

type StateUpdatePayload struct {
	Sessions []*tmux.Session `json:"sessions"`
	Version  string          `json:"version,omitempty"`
}

StateUpdatePayload carries a full session snapshot from a peer

type StatsPayload

type StatsPayload struct {
	Stats map[string]interface{} `json:"stats"`
}

StatsPayload carries system stats from a peer

type ToolEventPayload

type ToolEventPayload struct {
	Event *toolevents.Event `json:"event"`
}

ToolEventPayload wraps a tool event from a peer

Jump to

Keyboard shortcuts

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