proto

package
v1.0.260758 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package proto defines versioned messages for TTYPE Desk (in-process now, IPC later).

Index

Constants

View Source
const (
	FrameJSON  byte = 1
	FrameDiff  byte = 2
	FrameAudio byte = 3
)

Frame types for the length-prefixed wire framing every attach connection uses (replaces the original newline-delimited JSON-only framing). Input (key/mouse/attach/detach) stays JSON — small, and changing it wasn't the point; only the snapshot direction, which used to re-encode every window's full cell grid as JSON on every tick regardless of whether anything had changed, needed to go. FrameAudio carries raw PCM captured on the host (see internal/audiocap) to an attached client's speakers, opt-in and independent of the diff stream.

View Source
const Version = 1

Variables

This section is empty.

Functions

func DecodeAudioChunk

func DecodeAudioChunk(data []byte) []int16

DecodeAudioChunk reverses EncodeAudioChunk.

func DecodePayload

func DecodePayload[T any](env Envelope) (T, error)

func Encode

func Encode(typ MessageType, window string, payload any) ([]byte, error)

Encode builds a fire-and-forget envelope (no ReqID). Use EncodeReq for a request that expects a correlated reply.

func EncodeAudioChunk

func EncodeAudioChunk(samples []int16) []byte

EncodeAudioChunk serializes interleaved int16 PCM samples (as captured by internal/audiocap, at its fixed SampleRate/Channels) into a FrameAudio payload — raw little-endian bytes, no header, since the frame envelope already carries type and length.

func EncodeDiffFrame

func EncodeDiffFrame(f DiffFrame) []byte

EncodeDiffFrame serializes f to the FrameDiff binary payload.

func EncodeReq

func EncodeReq(typ MessageType, window, reqID string, payload any) ([]byte, error)

EncodeReq builds an envelope with a ReqID, for request/response message pairs (see Envelope's doc comment).

func ReadFrame

func ReadFrame(r *bufio.Reader) (typ byte, payload []byte, err error)

ReadFrame reads one length-prefixed frame written by WriteFrame.

func WriteFrame

func WriteFrame(w io.Writer, typ byte, payload []byte) error

WriteFrame writes one length-prefixed frame: a 4-byte big-endian length (of the type byte + payload), the type byte, then payload.

Types

type AudioChunkPayload

type AudioChunkPayload struct {
	PCM []byte `json:"pcm"`
}

AudioChunkPayload is TypeAudioChunk's payload: PCM holds proto.EncodeAudioChunk's binary encoding (interleaved int16 samples, little-endian — see internal/proto/binary.go), base64-encoded automatically by encoding/json since it's a []byte field. Reused as-is rather than a JSON int array: half the bytes over the wire, and it's already implemented for the remote-attach audio path (Phase 8).

type ClipboardSetRequest

type ClipboardSetRequest struct {
	Text string `json:"text"`
}

ClipboardSetRequest is TypeClipboardSet's payload.

type ClipboardValueResponse

type ClipboardValueResponse struct {
	Text string `json:"text"`
}

ClipboardValueResponse answers TypeClipboardGet.

type CreateWindow

type CreateWindow struct {
	Kind  string `json:"kind"` // pty, app, gfx
	Title string `json:"title"`
	Cmd   string `json:"cmd,omitempty"`
	Path  string `json:"path,omitempty"` // for imageview
	App   string `json:"app,omitempty"`  // clock, imageview
}

type CredentialLoadedResponse

type CredentialLoadedResponse struct {
	Value []byte `json:"value,omitempty"`
	Err   string `json:"err,omitempty"`
}

CredentialLoadedResponse answers TypeLoadCredential. Err is empty on success; a non-empty Err (matching os.ErrNotExist's message when nothing was saved under Key) means Value is meaningless.

type CredentialSavedResponse

type CredentialSavedResponse struct {
	Err string `json:"err,omitempty"`
}

CredentialSavedResponse answers TypeSaveCredential. Err is empty on success.

type DiffFrame

type DiffFrame struct {
	Cols, Rows int
	Windows    []DiffWindow
}

DiffFrame is the binary replacement for a JSON Snapshot.

func DecodeDiffFrame

func DecodeDiffFrame(data []byte) (DiffFrame, error)

DecodeDiffFrame parses a FrameDiff payload produced by EncodeDiffFrame.

type DiffWindow

type DiffWindow struct {
	ID         string
	Title      string
	X, Y       int
	W, H, Z    int
	Focused    bool
	Maximized  bool
	Kind       string
	Cols, Rows int
	Cells      []cell.Cell // nil if unchanged this frame
}

DiffWindow is one window's metadata, always present, plus its cell grid, present only when it changed since the last DiffFrame sent to this specific connection — Cells is nil for a window whose content the receiver should keep reusing from its own cache. Metadata (position, size, title, focus, …) is cheap enough to resend every frame; the cell grid is the part worth skipping.

type Envelope

type Envelope struct {
	Version int             `json:"v"`
	Type    MessageType     `json:"type"`
	Window  string          `json:"window,omitempty"`
	ReqID   string          `json:"req_id,omitempty"`
	Payload json.RawMessage `json:"payload,omitempty"`
}

Envelope wraps every message. ReqID correlates a request/response pair (e.g. TypeLoadCredential -> TypeCredentialLoaded) — set by the caller on the request, echoed back unchanged on the reply. Empty for fire-and- forget message types, which is most of them.

func Decode

func Decode(data []byte) (Envelope, error)

type FilePickedResponse

type FilePickedResponse struct {
	Path string `json:"path,omitempty"`
	Ok   bool   `json:"ok"`
}

FilePickedResponse answers TypePickFile, asynchronously, whenever the user actually picks a file or cancels — not immediately like the other request/response pairs here.

type FocusEvent

type FocusEvent struct {
	Focused bool `json:"focused"`
}

type InitPayload

type InitPayload struct {
	WindowID string `json:"window_id"`
	Cols     int    `json:"cols"`
	Rows     int    `json:"rows"`
}

InitPayload is the out-of-process App SDK's one-time startup message (see TypeInit): the window id an app needs for logging/reference, and its initial canvas size (also delivered again via a normal TypeResize on every later resize).

type KeyEvent

type KeyEvent struct {
	Rune  rune   `json:"rune,omitempty"`
	Key   string `json:"key,omitempty"`
	Ctrl  bool   `json:"ctrl,omitempty"`
	Alt   bool   `json:"alt,omitempty"`
	Shift bool   `json:"shift,omitempty"`
	Bytes []byte `json:"bytes,omitempty"`
}

type LaunchPayload

type LaunchPayload struct {
	Action string `json:"action"`
}

LaunchPayload is TypeLaunch's payload — see uiapp.Host.Launch.

type LoadCredentialRequest

type LoadCredentialRequest struct {
	Key string `json:"key"`
}

LoadCredentialRequest is TypeLoadCredential's payload.

type MessageType

type MessageType string

MessageType identifies a protocol message.

const (
	TypeKey          MessageType = "key"
	TypeMouse        MessageType = "mouse"
	TypeResize       MessageType = "resize"
	TypeFocus        MessageType = "focus"
	TypeCreateWindow MessageType = "create_window"
	TypeCloseWindow  MessageType = "close_window"
	TypeMaximize     MessageType = "maximize"
	TypeScreenDiff   MessageType = "screen_diff"
	TypeTitleChanged MessageType = "title_changed"
	TypeBell         MessageType = "bell"
	TypeAttach       MessageType = "attach"
	TypeDetach       MessageType = "detach"
	TypeSnapshot     MessageType = "snapshot"

	// The out-of-process App SDK (internal/extapp; see docs/extapp.md)
	// reuses the types above for the lifecycle it shares with in-process
	// uiapp.App (Key/Mouse/Resize/Focus host->app; ScreenDiff app->host
	// for Draw; TitleChanged app->host for Host.SetTitle; CloseWindow
	// app->host for Host.RequestClose) and adds these three for the parts
	// that don't already have an equivalent:
	TypeInit     MessageType = "init"      // host -> app: window id + initial size, once at startup
	TypeReady    MessageType = "ready"     // app -> host: Init complete (Err set on failure)
	TypeNotify   MessageType = "notify"    // app -> host: Host.Notify
	TypeLaunch   MessageType = "launch"    // app -> host: Host.Launch
	TypeOpenPath MessageType = "open_path" // app -> host: Host.OpenPath

	// Request/response pairs (correlated via Envelope.ReqID — the app sets
	// it on the request, the host echoes it back on the matching reply, so
	// several in-flight requests of different kinds don't need to be
	// resolved in send order) covering the rest of uiapp.Host that v1 of
	// this SDK originally shipped without: credential storage, the file
	// picker, and clipboard access.
	TypeSaveCredential   MessageType = "save_credential"   // app -> host, replied by TypeCredentialSaved
	TypeCredentialSaved  MessageType = "credential_saved"  // host -> app
	TypeLoadCredential   MessageType = "load_credential"   // app -> host, replied by TypeCredentialLoaded
	TypeCredentialLoaded MessageType = "credential_loaded" // host -> app
	TypePickFile         MessageType = "pick_file"         // app -> host, replied by TypeFilePicked (async — whenever the user actually picks/cancels)
	TypeFilePicked       MessageType = "file_picked"       // host -> app
	TypeClipboardGet     MessageType = "clipboard_get"     // app -> host, replied by TypeClipboardValue
	TypeClipboardValue   MessageType = "clipboard_value"   // host -> app
	TypeClipboardSet     MessageType = "clipboard_set"     // app -> host, fire-and-forget (no reply — nothing meaningful can fail)

	// Audio playback (uiapp.Host.PlayAudio): fire-and-forget, not
	// request/response — TypePlayAudio starts a stream, repeated
	// TypeAudioChunk messages carry PCM, TypeStopAudio ends it. No reply
	// to any of these; a genuine playback failure just never plays audio,
	// which is already how the in-process Host.PlayAudio error is mostly
	// used (apps generally don't hard-fail just because sound didn't
	// start).
	TypePlayAudio  MessageType = "play_audio"  // app -> host: start streaming
	TypeAudioChunk MessageType = "audio_chunk" // app -> host: one chunk of PCM
	TypeStopAudio  MessageType = "stop_audio"  // app -> host: stop streaming
)

type MouseEvent

type MouseEvent struct {
	X      int    `json:"x"`
	Y      int    `json:"y"`
	Button int    `json:"button"`
	Action string `json:"action"` // press, release, drag, move, wheel
	Ctrl   bool   `json:"ctrl,omitempty"`
	Alt    bool   `json:"alt,omitempty"`
	Shift  bool   `json:"shift,omitempty"`
}

type NotifyPayload

type NotifyPayload struct {
	Title string `json:"title"`
	Body  string `json:"body"`
	Icon  string `json:"icon,omitempty"`
}

NotifyPayload is TypeNotify's payload — see uiapp.Host.Notify.

type OpenPathPayload

type OpenPathPayload struct {
	Path string `json:"path"`
}

OpenPathPayload is TypeOpenPath's payload — see uiapp.Host.OpenPath.

type PickFileRequest

type PickFileRequest struct {
	StartDir   string   `json:"start_dir,omitempty"`
	Extensions []string `json:"extensions,omitempty"`
}

PickFileRequest is TypePickFile's payload — see uiapp.Host.PickFile.

type ReadyPayload

type ReadyPayload struct {
	Err string `json:"err,omitempty"`
}

ReadyPayload answers TypeInit. Err is empty on success; a non-empty Err marks the window crashed with that message, same as an in-process app panicking in Init.

type ResizeEvent

type ResizeEvent struct {
	Cols int `json:"cols"`
	Rows int `json:"rows"`
}

type SaveCredentialRequest

type SaveCredentialRequest struct {
	Key   string `json:"key"`
	Value []byte `json:"value"`
}

SaveCredentialRequest is TypeSaveCredential's payload — see uiapp.Host.SaveCredential. Value is base64-encoded automatically by encoding/json ([]byte fields always are).

type ScreenDiffPayload

type ScreenDiffPayload struct {
	Diff cell.Diff `json:"diff"`
}

type Snapshot

type Snapshot struct {
	Cols    int              `json:"cols"`
	Rows    int              `json:"rows"`
	Windows []SnapshotWindow `json:"windows"`
}

type SnapshotWindow

type SnapshotWindow struct {
	ID        string      `json:"id"`
	Title     string      `json:"title"`
	X         int         `json:"x"`
	Y         int         `json:"y"`
	W         int         `json:"w"`
	H         int         `json:"h"`
	Z         int         `json:"z"`
	Focused   bool        `json:"focused"`
	Maximized bool        `json:"maximized"`
	Kind      string      `json:"kind"`
	Cells     []cell.Cell `json:"cells,omitempty"`
	Cols      int         `json:"cols"`
	Rows      int         `json:"rows"`
}

type TitleChanged

type TitleChanged struct {
	Title string `json:"title"`
}

Jump to

Keyboard shortcuts

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