Documentation
¶
Overview ¶
Package protocol defines the NDJSON wire format spoken between the pupptyeer daemon and its clients over a unix socket.
One JSON object per message; clients emit them newline-delimited. Raw PTY bytes ride in the base64 `data` field. A single Message shape is used for every message; the `type` field discriminates. The design goal is cross-language ergonomics (Go, TS, Python clients) over raw throughput. See PROTOCOL.md for the canonical wire contract.
Index ¶
Constants ¶
const ( TypeNewSession = "new_session" TypeListSessions = "list_sessions" TypeAttach = "attach" TypeDetach = "detach" TypeWritePane = "write_pane" TypeCapturePane = "capture_pane" TypeResize = "resize" TypeKill = "kill" TypeGC = "gc" )
Message types (client → server).
const ( TypeOK = "ok" TypeError = "error" TypeSessions = "sessions" TypeAttached = "attached" TypeOutput = "output" TypeScrollbackEnd = "scrollback_end" TypeCapture = "capture" TypeExit = "exit" TypeSessionClosed = "session_closed" TypeReaped = "reaped" )
Message types (server → client).
Variables ¶
This section is empty.
Functions ¶
func DecodeData ¶
DecodeData decodes the `data` field back to raw bytes.
func EncodeData ¶
EncodeData base64-encodes raw bytes for the `data` field.
Types ¶
type Cursor ¶ added in v0.2.0
Cursor is the cursor position in a rendered capture. Row/Col are 0-based; Col may equal the grid width (a pending-wrap cursor). Visible reflects the terminal's cursor-visibility (DECTCEM) state.
type Decoder ¶
type Decoder struct {
// contains filtered or unexported fields
}
Decoder reads newline-delimited messages from r. It uses a large buffer because base64 output lines can be tens of KiB.
func NewDecoder ¶
NewDecoder returns a Decoder reading from r.
type Encoder ¶
type Encoder struct {
// contains filtered or unexported fields
}
Encoder writes newline-delimited messages to w.
type Message ¶
type Message struct {
Type string `json:"type"`
ID int `json:"id,omitempty"`
Session string `json:"session,omitempty"`
// namespace scopes a session: identity is (namespace, id). Carried by
// new_session and every session-addressed verb, and echoed on the
// server->client events (output/exit/capture/...) so a client can tell
// apart sessions whose ids collide across namespaces. Empty means the
// "default" namespace - so old clients that send none operate entirely
// there (backward compatible). See PROTOCOL.md.
Namespace string `json:"namespace,omitempty"`
// All, on list_sessions/gc, selects every namespace instead of just the
// one in Namespace. An explicit flag, deliberately not a "*" sentinel.
All bool `json:"all,omitempty"`
// new_session
Command string `json:"command,omitempty"`
Args []string `json:"args,omitempty"`
Cwd string `json:"cwd,omitempty"`
Env map[string]string `json:"env,omitempty"`
Cols int `json:"cols,omitempty"`
Rows int `json:"rows,omitempty"`
Raw bool `json:"raw,omitempty"` // new_session: don't run a terminal emulator for this session (no rendered capture; lower CPU/latency)
// new_session, caller-supplied id. RequestedID, if set, becomes the
// session's id instead of a daemon-generated UUID. With GetOrCreate, an
// alive session already holding RequestedID is returned as-is (no new
// process); without it, a clash is an error.
RequestedID string `json:"requested_id,omitempty"`
GetOrCreate bool `json:"get_or_create,omitempty"`
// gc
MaxIdleSeconds int `json:"max_idle_seconds,omitempty"`
// data-bearing (output / write_pane / capture)
Data string `json:"data,omitempty"` // base64 of raw PTY bytes
Text string `json:"text,omitempty"` // convenience: raw UTF-8 input for write_pane
// capture_pane options
Render bool `json:"render,omitempty"` // return the rendered grid instead of raw bytes
SettleMs int `json:"settle_ms,omitempty"` // hold reply until PTY quiet for this long
TimeoutMs int `json:"timeout_ms,omitempty"` // cap on settle wait; <=0 uses the default
// rendered capture response (Render == true). Cols/Rows above carry the
// grid dimensions; Lines/Cursor/AltScreen describe the visible screen.
Lines []string `json:"lines,omitempty"`
Cursor *Cursor `json:"cursor,omitempty"`
AltScreen bool `json:"alt_screen,omitempty"`
// responses / events
Message string `json:"message,omitempty"` // error text
ExitCode *int `json:"exit_code,omitempty"` // pointer so 0 is preserved
Sessions []SessionInfo `json:"sessions,omitempty"`
}
Message is the single wire shape. Fields are omitempty so a given message only carries what its type needs. Clients read the fields relevant to the type they received.
type SessionInfo ¶
type SessionInfo struct {
ID string `json:"id"`
Namespace string `json:"namespace"`
Command string `json:"command"`
Args []string `json:"args,omitempty"`
Cwd string `json:"cwd,omitempty"`
Cols int `json:"cols"`
Rows int `json:"rows"`
Created string `json:"created"`
LastActivity string `json:"last_activity"`
Attached int `json:"attached"`
Alive bool `json:"alive"`
Raw bool `json:"raw,omitempty"` // session was created with raw:true (no terminal emulator)
}
SessionInfo is the metadata returned by list_sessions (and the reaped list from gc). LastActivity is the RFC3339 time of the most recent PTY input or output; gc ages sessions by it.