carrierclient

package
v0.0.21 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package carrierclient drives an imzero2 headless host over the remote-access carrier of ADR-0024, with the accessibility-tree channel, coordinate-free actuation and capture-on-demand added by ADR-0154.

It is the non-browser counterpart to the shipped viewer. Where the browser decodes the video stream and shows it to a person, this client ignores the pixels on the wire entirely and asks the host to write PNGs at moments it chooses — so a scripted run needs no compositor, no browser, no GPU compositing path and no `egui_inspection` port. That last part is the reason this exists at all: the inspection plugin the desktop host exposes to egui-mcp requires eframe, which the headless build exists to exclude, so the carrier is the only seam a headless host has.

The wire types in input_pb.out.go are generated from the canonical contract at proto/boxer/imzero2/v1/input.proto, the same file the Rust host generates from, so neither end can drift from it. Regenerate with:

go generate ./public/thestack/imzero2/carrierclient/

Typical use — connect, resolve a widget by name, actuate it by id, capture:

c, err := carrierclient.Connect(carrierclient.Config{URL: "ws://127.0.0.1:8089/"})
tree, err := c.Tree(5 * time.Second)
node := carrierclient.FindByName(tree, "Panes")
err = c.ClickNode(node.GetId())
done, err := c.Capture("panes-open", 5 * time.Second)

Only the ACTIVE connection's input, tree requests and captures are honoured (ADR-0086); the first connection to a host is admitted active, so a driver pointed at a host someone is already watching will be passive and silently ineffective.

Index

Constants

View Source
const (
	ActionClick          uint32 = 0
	ActionFocus          uint32 = 1
	ActionSetValue       uint32 = 2
	ActionScrollIntoView uint32 = 3
)

AccessKit action codes (ADR-0154 SD3), pinned by the wire rather than by AccessKit's own enum. Mirrors `treemap.rs`.

View Source
const (
	FlagDisabled uint32 = 1
	FlagHidden   uint32 = 2
	FlagFocused  uint32 = 4
	FlagSelected uint32 = 8
)

TreeNode flag bits (ADR-0154 SD2).

Variables

View Source
var (
	Role_name = map[int32]string{
		0: "ROLE_PASSIVE",
		1: "ROLE_ACTIVE",
	}
	Role_value = map[string]int32{
		"ROLE_PASSIVE": 0,
		"ROLE_ACTIVE":  1,
	}
)

Enum value maps for Role.

View Source
var File_boxer_imzero2_v1_input_proto protoreflect.FileDescriptor

Functions

func Center

func Center(n *TreeNode) (x, y float32)

Center returns a node's midpoint in logical points — the coordinate fallback for a painter-only child of a node, and what a `pos`-based step resolves to.

func Path

func Path(snap *TreeSnapshot, n *TreeNode) (path string)

func RunTrace

func RunTrace(c *Client, steps []Step, opts RunOptions) (err error)

RunTrace executes steps against a connected client.

Anchors resolve against a tree fetched lazily and re-fetched after anything that could have changed the UI, so a trace pays for one snapshot per group of steps rather than one per step.

Types

type AccessKitAction

type AccessKitAction struct {
	NodeId uint64 `protobuf:"varint,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"`
	// Wire-stable action code, numbered here rather than taken from
	// `accesskit::Action as u32` for the same reason CursorShape pins its
	// own codes: an upstream variant inserted mid-enum would silently
	// renumber the wire. The host maps it with an explicit match; an unknown
	// code is ignored rather than guessed at.
	//
	//	0 click   1 focus   2 set-value   3 scroll-into-view
	Action uint32 `protobuf:"varint,2,opt,name=action,proto3" json:"action,omitempty"`
	// Payload for set-value (action 2); ignored otherwise. Sliders and drag
	// values take a numeric string, text edits take the literal text.
	Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
	// contains filtered or unexported fields
}

ADR-0154 SD3: a coordinate-free action against a node of the tree TreeSnapshot reports. `node_id` is the AccessKit node id, which for egui is the raw widget id — a pure function of the widget's path down the id stack, so it is stable across runs and resolutions. Actions egui honours when injected: click, focus, set-value, scroll-into-view. A driver falls back to synthetic pointer events for painter-only widgets, which have no node at all.

func (*AccessKitAction) Descriptor deprecated

func (*AccessKitAction) Descriptor() ([]byte, []int)

Deprecated: Use AccessKitAction.ProtoReflect.Descriptor instead.

func (*AccessKitAction) GetAction

func (x *AccessKitAction) GetAction() uint32

func (*AccessKitAction) GetNodeId

func (x *AccessKitAction) GetNodeId() uint64

func (*AccessKitAction) GetValue

func (x *AccessKitAction) GetValue() string

func (*AccessKitAction) ProtoMessage

func (*AccessKitAction) ProtoMessage()

func (*AccessKitAction) ProtoReflect

func (x *AccessKitAction) ProtoReflect() protoreflect.Message

func (*AccessKitAction) Reset

func (x *AccessKitAction) Reset()

func (*AccessKitAction) String

func (x *AccessKitAction) String() string

type CaptureDone

type CaptureDone struct {
	Path       string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
	Width      uint32 `protobuf:"varint,2,opt,name=width,proto3" json:"width,omitempty"`
	Height     uint32 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"`
	FrameIndex uint64 `protobuf:"varint,4,opt,name=frame_index,json=frameIndex,proto3" json:"frame_index,omitempty"`
	// contains filtered or unexported fields
}

Server→client: the capture landed. `path` is the file the host actually wrote, after sanitising.

func (*CaptureDone) Descriptor deprecated

func (*CaptureDone) Descriptor() ([]byte, []int)

Deprecated: Use CaptureDone.ProtoReflect.Descriptor instead.

func (*CaptureDone) GetFrameIndex

func (x *CaptureDone) GetFrameIndex() uint64

func (*CaptureDone) GetHeight

func (x *CaptureDone) GetHeight() uint32

func (*CaptureDone) GetPath

func (x *CaptureDone) GetPath() string

func (*CaptureDone) GetWidth

func (x *CaptureDone) GetWidth() uint32

func (*CaptureDone) ProtoMessage

func (*CaptureDone) ProtoMessage()

func (*CaptureDone) ProtoReflect

func (x *CaptureDone) ProtoReflect() protoreflect.Message

func (*CaptureDone) Reset

func (x *CaptureDone) Reset()

func (*CaptureDone) String

func (x *CaptureDone) String() string

type CaptureRequest

type CaptureRequest struct {
	Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	// contains filtered or unexported fields
}

ADR-0154 SD4. Client→server: write the current frame as a PNG. Replaces picking one out of a periodic dump, so the client chooses the moment.

`name` is sanitised to a basename by the host and written under the configured dump directory; with no dump directory configured the request is ignored. The carrier already grants the active connection full input control, which is no reason to also grant it arbitrary filesystem writes.

func (*CaptureRequest) Descriptor deprecated

func (*CaptureRequest) Descriptor() ([]byte, []int)

Deprecated: Use CaptureRequest.ProtoReflect.Descriptor instead.

func (*CaptureRequest) GetName

func (x *CaptureRequest) GetName() string

func (*CaptureRequest) ProtoMessage

func (*CaptureRequest) ProtoMessage()

func (*CaptureRequest) ProtoReflect

func (x *CaptureRequest) ProtoReflect() protoreflect.Message

func (*CaptureRequest) Reset

func (x *CaptureRequest) Reset()

func (*CaptureRequest) String

func (x *CaptureRequest) String() string

type Client

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

Client drives an imzero2 headless host over its remote-access carrier (ADR-0024) — the seam that needs no compositor, no browser and no `egui_inspection` port.

It is deliberately *not* a viewer: video access units are counted and discarded. Pixels come back through Client.Capture, which asks the host to write a PNG and tells us where it landed, so a caller chooses the moment rather than sifting a periodic frame dump.

One goroutine may call the request methods; they serialize internally.

func Connect

func Connect(cfg Config) (inst *Client, err error)

Connect dials the carrier and completes the session handshake: it announces itself, then waits for the host's SessionHello so the caller knows the stream geometry before it computes anything in logical points.

The first connection to a carrier is admitted ACTIVE (ADR-0086), and only the active connection's input, tree requests and captures are honoured — so a driver run against a host someone is already watching will be passive and silently ineffective. Client.Hello plus the host's roster log are how that shows up; taking the session from a human is deliberately not automatic.

func (*Client) Capture

func (inst *Client) Capture(name string, timeout time.Duration) (done *CaptureDone, err error)

Capture asks the host to write the current frame as a PNG under its dump directory and returns the acknowledgement (ADR-0154 SD4).

The host reduces name to a basename and owns the directory, so the path it reports back may differ from what was asked for; use the returned path. A host with no IMZERO2_HEADLESS_DUMP_DIR ignores the request, which surfaces here as a timeout.

func (*Client) ClickAt

func (inst *Client) ClickAt(x, y float32) (err error)

ClickAt presses and releases the primary button at a position. The events are sent back to back; the host applies every event queued since the last pass in one batch, so egui sees the press and release together.

func (*Client) ClickNode

func (inst *Client) ClickNode(nodeID uint64) (err error)

ClickNode actuates a widget by node id, with no coordinates involved (ADR-0154 SD3).

func (*Client) Close

func (inst *Client) Close() (err error)

Close tears the connection down.

func (*Client) FocusNode

func (inst *Client) FocusNode(nodeID uint64) (err error)

FocusNode moves keyboard focus to a node.

func (*Client) Hello

func (inst *Client) Hello() *SessionHello

Hello returns the stream geometry the host announced, refreshed whenever it re-announces (a resize or a codec switch).

func (*Client) MoveMouse

func (inst *Client) MoveMouse(x, y float32) (err error)

MoveMouse and ClickAt are the coordinate fallback, for painter-only widgets (a timeline, a treemap, a map) that have no accessibility node at all. Prefer the node actions above wherever a node exists: a coordinate that has gone stale still lands somewhere, and the wrong widget answers.

func (*Client) PressKey

func (inst *Client) PressKey(key string, modifiers uint32) (err error)

PressKey sends a key down/up pair. Names follow the browser's KeyboardEvent.key, which is also what egui::Key::from_name accepts ("Enter", "ArrowDown", "A").

func (*Client) Resize

func (inst *Client) Resize(width, height, scale float32) (err error)

Resize asks the host for a different logical viewport. The host clamps and re-announces its hello, which Client.Hello then reflects.

func (*Client) Scroll

func (inst *Client) Scroll(dx, dy float32) (err error)

Scroll sends a wheel delta in points at the current pointer position.

func (*Client) ScrollNodeIntoView

func (inst *Client) ScrollNodeIntoView(nodeID uint64) (err error)

ScrollNodeIntoView brings a node into the visible area, which is how a driver reaches a widget the layout has scrolled away.

func (*Client) SendInput

func (inst *Client) SendInput(ev *InputEvent) (err error)

SendInput sends one input event.

func (*Client) SetCadence

func (inst *Client) SetCadence(cadence uint32) (err error)

SetCadence switches the host's render cadence: 0 = continuous, 1 = reactive.

Reactive is the default and the right one for a served deployment, but a driver waiting on an animation or a debounced fetch may want the host producing steadily.

func (*Client) SetNodeValue

func (inst *Client) SetNodeValue(nodeID uint64, value string) (err error)

SetNodeValue sets a widget's value directly — sliders and drag values take a numeric string, text edits the literal text.

func (*Client) Tree

func (inst *Client) Tree(timeout time.Duration) (snap *TreeSnapshot, err error)

Tree asks for the accessibility tree and returns the next snapshot (ADR-0154 SD1).

The request also switches AccessKit generation on host-side for as long as something is asking, so the first call costs a pass more than later ones.

func (*Client) TypeText

func (inst *Client) TypeText(text string) (err error)

TypeText sends printable text to the focused widget.

type ClientHello

type ClientHello struct {
	Webcodecs bool   `protobuf:"varint,1,opt,name=webcodecs,proto3" json:"webcodecs,omitempty"`
	Label     string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"`
	// contains filtered or unexported fields
}

Client→server (ADR-0086 SD8/SD9): the viewer's capabilities and an optional device label, sent once just after connect. `webcodecs` gates takeover — only a decode-capable connection may become active (SD2). Geometry is not here: it continues to flow on ViewportResize (active-only).

func (*ClientHello) Descriptor deprecated

func (*ClientHello) Descriptor() ([]byte, []int)

Deprecated: Use ClientHello.ProtoReflect.Descriptor instead.

func (*ClientHello) GetLabel

func (x *ClientHello) GetLabel() string

func (*ClientHello) GetWebcodecs

func (x *ClientHello) GetWebcodecs() bool

func (*ClientHello) ProtoMessage

func (*ClientHello) ProtoMessage()

func (*ClientHello) ProtoReflect

func (x *ClientHello) ProtoReflect() protoreflect.Message

func (*ClientHello) Reset

func (x *ClientHello) Reset()

func (*ClientHello) String

func (x *ClientHello) String() string

type ClipboardData

type ClipboardData struct {
	Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"`
	// contains filtered or unexported fields
}

Both ways (ADR-0082 SD6): clipboard text. Server→client carries text the host copied (drained from egui OutputCommand::CopyText) for the viewer to write to navigator.clipboard; client→server carries a paste the viewer read, which the host injects as egui::Event::Paste. Only the active session syncs.

func (*ClipboardData) Descriptor deprecated

func (*ClipboardData) Descriptor() ([]byte, []int)

Deprecated: Use ClipboardData.ProtoReflect.Descriptor instead.

func (*ClipboardData) GetText

func (x *ClipboardData) GetText() string

func (*ClipboardData) ProtoMessage

func (*ClipboardData) ProtoMessage()

func (*ClipboardData) ProtoReflect

func (x *ClipboardData) ProtoReflect() protoreflect.Message

func (*ClipboardData) Reset

func (x *ClipboardData) Reset()

func (*ClipboardData) String

func (x *ClipboardData) String() string

type CodecCapability

type CodecCapability struct {
	Codec          string `protobuf:"bytes,1,opt,name=codec,proto3" json:"codec,omitempty"`                                          // WebCodecs codec string (avc1.* / vp09.* / av01.*)
	Supported      bool   `protobuf:"varint,2,opt,name=supported,proto3" json:"supported,omitempty"`                                 // VideoDecoder.isConfigSupported
	Smooth         bool   `protobuf:"varint,3,opt,name=smooth,proto3" json:"smooth,omitempty"`                                       // navigator.mediaCapabilities.decodingInfo
	PowerEfficient bool   `protobuf:"varint,4,opt,name=power_efficient,json=powerEfficient,proto3" json:"power_efficient,omitempty"` // navigator.mediaCapabilities.decodingInfo
	// contains filtered or unexported fields
}

One probed WebCodecs configuration.

func (*CodecCapability) Descriptor deprecated

func (*CodecCapability) Descriptor() ([]byte, []int)

Deprecated: Use CodecCapability.ProtoReflect.Descriptor instead.

func (*CodecCapability) GetCodec

func (x *CodecCapability) GetCodec() string

func (*CodecCapability) GetPowerEfficient

func (x *CodecCapability) GetPowerEfficient() bool

func (*CodecCapability) GetSmooth

func (x *CodecCapability) GetSmooth() bool

func (*CodecCapability) GetSupported

func (x *CodecCapability) GetSupported() bool

func (*CodecCapability) ProtoMessage

func (*CodecCapability) ProtoMessage()

func (*CodecCapability) ProtoReflect

func (x *CodecCapability) ProtoReflect() protoreflect.Message

func (*CodecCapability) Reset

func (x *CodecCapability) Reset()

func (*CodecCapability) String

func (x *CodecCapability) String() string

type Config

type Config struct {
	// URL of the carrier's WebSocket, e.g. "ws://127.0.0.1:8089/". Note the
	// carrier serves the viewer page on the same port and on port+1.
	URL string
	// Label shown in the host's roster (ADR-0086), for the operator's benefit
	// when a human viewer is watching the same host.
	Label string
	// DialTimeout bounds the TCP connect and the opening handshake.
	DialTimeout time.Duration
	Logger      zerolog.Logger
}

Config holds the connection parameters.

type CursorShape

type CursorShape struct {

	// Wire-stable shape code. Deliberately NOT `egui::CursorIcon as u32`: that
	// enum carries no `#[repr]` and no ordering guarantee, so a variant inserted
	// upstream would silently renumber every shape on the wire. The host maps it
	// with an exhaustive match (inputmap::cursor_shape_code), which fails to
	// compile — rather than mis-decoding — when egui gains a variant.
	//
	// The numbering below mirrors egui 0.35's declaration order and is now
	// frozen; append new shapes at the end. The CSS keyword each code maps to is
	// in parentheses; a receiver that does not know a code MUST fall back to
	// `default` rather than error.
	//
	//	 0 default (default)        12 copy (copy)              24 resize-se (se-resize)
	//	 1 none (none)              13 move (move)              25 resize-s (s-resize)
	//	 2 context-menu             14 no-drop (no-drop)        26 resize-sw (sw-resize)
	//	 3 help (help)              15 not-allowed              27 resize-w (w-resize)
	//	 4 pointing-hand (pointer)  16 grab (grab)              28 resize-nw (nw-resize)
	//	 5 progress (progress)      17 grabbing (grabbing)      29 resize-n (n-resize)
	//	 6 wait (wait)              18 all-scroll (all-scroll)  30 resize-ne (ne-resize)
	//	 7 cell (cell)              19 resize-h (ew-resize)     31 resize-col (col-resize)
	//	 8 crosshair (crosshair)    20 resize-nesw (nesw-)      32 resize-row (row-resize)
	//	 9 text (text)              21 resize-nwse (nwse-)      33 zoom-in (zoom-in)
	//	10 vertical-text            22 resize-v (ns-resize)     34 zoom-out (zoom-out)
	//	11 alias (alias)            23 resize-e (e-resize)
	Shape uint32 `protobuf:"varint,1,opt,name=shape,proto3" json:"shape,omitempty"`
	// contains filtered or unexported fields
}

Server→client (ADR-0024 Update 2026-07-28): the mouse cursor shape egui resolved for this frame, so the viewer can set its canvas `cursor` CSS property. Nothing cursor-shaped is ever drawn into the stream — the pointer the user sees is the browser's own — so this is the only way a remote egui can ask for a text caret over a TextEdit or a resize arrow over a splitter.

Sent to the ACTIVE connection only: the shape is resolved from *its* pointer position, so pushing it to a passive viewer would morph that viewer's local cursor from someone else's hover.

func (*CursorShape) Descriptor deprecated

func (*CursorShape) Descriptor() ([]byte, []int)

Deprecated: Use CursorShape.ProtoReflect.Descriptor instead.

func (*CursorShape) GetShape

func (x *CursorShape) GetShape() uint32

func (*CursorShape) ProtoMessage

func (*CursorShape) ProtoMessage()

func (*CursorShape) ProtoReflect

func (x *CursorShape) ProtoReflect() protoreflect.Message

func (*CursorShape) Reset

func (x *CursorShape) Reset()

func (*CursorShape) String

func (x *CursorShape) String() string

type DecodeCapabilities

type DecodeCapabilities struct {
	Codecs []*CodecCapability `protobuf:"bytes,1,rep,name=codecs,proto3" json:"codecs,omitempty"`
	// ADR-0128: the browser has a usable WebGL2 context — the mesh draw-stream
	// lane's decode requirement (it has no WebCodecs codec string to probe). Its
	// own value is geometry-independent, but it rides on this message because
	// build_video_caps already reads it; with it set the host offers codec id 4
	// (mesh) in the Go video-output control. Additive (field 2), per the
	// versioning policy above.
	Webgl2 bool `protobuf:"varint,2,opt,name=webgl2,proto3" json:"webgl2,omitempty"`
	// contains filtered or unexported fields
}

Client→server: the viewer's decode capabilities (ADR-0088 SD2/SD8), probed against the current stream geometry. (Re)sent after the hello and after a resize, since smooth / power-efficient depend on resolution. The host forwards these to the Go interpreter, which offers the intersection of browser-can-decode and host-can-encode in the output control.

func (*DecodeCapabilities) Descriptor deprecated

func (*DecodeCapabilities) Descriptor() ([]byte, []int)

Deprecated: Use DecodeCapabilities.ProtoReflect.Descriptor instead.

func (*DecodeCapabilities) GetCodecs

func (x *DecodeCapabilities) GetCodecs() []*CodecCapability

func (*DecodeCapabilities) GetWebgl2

func (x *DecodeCapabilities) GetWebgl2() bool

func (*DecodeCapabilities) ProtoMessage

func (*DecodeCapabilities) ProtoMessage()

func (*DecodeCapabilities) ProtoReflect

func (x *DecodeCapabilities) ProtoReflect() protoreflect.Message

func (*DecodeCapabilities) Reset

func (x *DecodeCapabilities) Reset()

func (*DecodeCapabilities) String

func (x *DecodeCapabilities) String() string

type InputEvent

type InputEvent struct {

	// Types that are valid to be assigned to Event:
	//
	//	*InputEvent_MouseMove
	//	*InputEvent_MouseButton
	//	*InputEvent_MouseWheel
	//	*InputEvent_Key
	//	*InputEvent_Text
	//	*InputEvent_PointerGone
	//	*InputEvent_PinchZoom
	//	*InputEvent_AccesskitAction
	Event isInputEvent_Event `protobuf_oneof:"event"`
	// contains filtered or unexported fields
}

func (*InputEvent) Descriptor deprecated

func (*InputEvent) Descriptor() ([]byte, []int)

Deprecated: Use InputEvent.ProtoReflect.Descriptor instead.

func (*InputEvent) GetAccesskitAction

func (x *InputEvent) GetAccesskitAction() *AccessKitAction

func (*InputEvent) GetEvent

func (x *InputEvent) GetEvent() isInputEvent_Event

func (*InputEvent) GetKey

func (x *InputEvent) GetKey() *KeyEvent

func (*InputEvent) GetMouseButton

func (x *InputEvent) GetMouseButton() *MouseButton

func (*InputEvent) GetMouseMove

func (x *InputEvent) GetMouseMove() *MouseMove

func (*InputEvent) GetMouseWheel

func (x *InputEvent) GetMouseWheel() *MouseWheel

func (*InputEvent) GetPinchZoom

func (x *InputEvent) GetPinchZoom() *PinchZoom

func (*InputEvent) GetPointerGone

func (x *InputEvent) GetPointerGone() *PointerGone

func (*InputEvent) GetText

func (x *InputEvent) GetText() *TextInput

func (*InputEvent) ProtoMessage

func (*InputEvent) ProtoMessage()

func (*InputEvent) ProtoReflect

func (x *InputEvent) ProtoReflect() protoreflect.Message

func (*InputEvent) Reset

func (x *InputEvent) Reset()

func (*InputEvent) String

func (x *InputEvent) String() string

type InputEvent_AccesskitAction

type InputEvent_AccesskitAction struct {
	// ADR-0154 SD3: actuate a widget by node id instead of by position.
	AccesskitAction *AccessKitAction `protobuf:"bytes,8,opt,name=accesskit_action,json=accesskitAction,proto3,oneof"`
}

type InputEvent_Key

type InputEvent_Key struct {
	Key *KeyEvent `protobuf:"bytes,4,opt,name=key,proto3,oneof"`
}

type InputEvent_MouseButton

type InputEvent_MouseButton struct {
	MouseButton *MouseButton `protobuf:"bytes,2,opt,name=mouse_button,json=mouseButton,proto3,oneof"`
}

type InputEvent_MouseMove

type InputEvent_MouseMove struct {
	MouseMove *MouseMove `protobuf:"bytes,1,opt,name=mouse_move,json=mouseMove,proto3,oneof"`
}

type InputEvent_MouseWheel

type InputEvent_MouseWheel struct {
	MouseWheel *MouseWheel `protobuf:"bytes,3,opt,name=mouse_wheel,json=mouseWheel,proto3,oneof"`
}

type InputEvent_PinchZoom

type InputEvent_PinchZoom struct {
	PinchZoom *PinchZoom `protobuf:"bytes,7,opt,name=pinch_zoom,json=pinchZoom,proto3,oneof"`
}

type InputEvent_PointerGone

type InputEvent_PointerGone struct {
	PointerGone *PointerGone `protobuf:"bytes,6,opt,name=pointer_gone,json=pointerGone,proto3,oneof"`
}

type InputEvent_Text

type InputEvent_Text struct {
	Text *TextInput `protobuf:"bytes,5,opt,name=text,proto3,oneof"`
}

type KeyEvent

type KeyEvent struct {

	// Browser KeyboardEvent.key (also accepted spelled-out by
	// egui::Key::from_name: "ArrowDown", "Enter", "A", ...).
	Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
	// Browser KeyboardEvent.code ("KeyA", ...). Reserved for a future
	// layout-aware mapping; the v1 mapper uses `key`.
	Code      string `protobuf:"bytes,2,opt,name=code,proto3" json:"code,omitempty"`
	Pressed   bool   `protobuf:"varint,3,opt,name=pressed,proto3" json:"pressed,omitempty"`
	Repeat    bool   `protobuf:"varint,4,opt,name=repeat,proto3" json:"repeat,omitempty"`
	Modifiers uint32 `protobuf:"varint,5,opt,name=modifiers,proto3" json:"modifiers,omitempty"`
	// contains filtered or unexported fields
}

func (*KeyEvent) Descriptor deprecated

func (*KeyEvent) Descriptor() ([]byte, []int)

Deprecated: Use KeyEvent.ProtoReflect.Descriptor instead.

func (*KeyEvent) GetCode

func (x *KeyEvent) GetCode() string

func (*KeyEvent) GetKey

func (x *KeyEvent) GetKey() string

func (*KeyEvent) GetModifiers

func (x *KeyEvent) GetModifiers() uint32

func (*KeyEvent) GetPressed

func (x *KeyEvent) GetPressed() bool

func (*KeyEvent) GetRepeat

func (x *KeyEvent) GetRepeat() bool

func (*KeyEvent) ProtoMessage

func (*KeyEvent) ProtoMessage()

func (*KeyEvent) ProtoReflect

func (x *KeyEvent) ProtoReflect() protoreflect.Message

func (*KeyEvent) Reset

func (x *KeyEvent) Reset()

func (*KeyEvent) String

func (x *KeyEvent) String() string

type Locator

type Locator struct {
	// ID matches a node exactly. Set it and nothing else is consulted.
	ID uint64
	// Name matches the accessible name.
	Name string
	// NameContains matches a substring of the accessible name — for labels
	// carrying a live count or value that would defeat an exact match.
	NameContains string
	// Value and ValueContains match the accessible value, exactly or by
	// substring.
	//
	// They exist because a large class of widgets has no accessible *name* at
	// all: egui puts a Label's text in the value slot and leaves the label
	// slot empty, so a plain label, a monospace readout or a tree row is
	// unreachable by Name however it is spelled. Interactive widgets carry a
	// name and are matched by it; static text is matched here.
	//
	// A separate pair rather than widening Name: a Name locator that silently
	// started matching values could turn a resolving anchor in an existing
	// trace into an ambiguous one, which fails the run. Opting in cannot.
	//
	// Pair them with Role: "label". egui emits a `text_run` child under some —
	// not all — of its labels, carrying the same text as the label itself, so
	// a bare value anchor resolves on one label and reports an ambiguity on
	// the next for no reason the trace author can see.
	Value         string
	ValueContains string
	// Role matches the AccessKit role ("button", "check_box", "text_input"…).
	Role string
	// Nth picks among several matches, 0-based. Without it, several matches is
	// an error; with it, the caller has said the ambiguity is expected and
	// which one it wants.
	Nth int
	// HasNth distinguishes "Nth: 0" from "Nth unset".
	HasNth bool
}

Locator selects one node of a snapshot. Fields are ANDed; leave a field zero to ignore it.

func (Locator) Matches

func (inst Locator) Matches(n *TreeNode) bool

Matches reports whether one node satisfies the locator, ignoring Nth.

type MouseButton

type MouseButton struct {
	X float32 `protobuf:"fixed32,1,opt,name=x,proto3" json:"x,omitempty"`
	Y float32 `protobuf:"fixed32,2,opt,name=y,proto3" json:"y,omitempty"`
	// 0=primary, 1=secondary, 2=middle, 3=extra1, 4=extra2 (matches
	// browser MouseEvent.button order and egui::PointerButton).
	Button    uint32 `protobuf:"varint,3,opt,name=button,proto3" json:"button,omitempty"`
	Pressed   bool   `protobuf:"varint,4,opt,name=pressed,proto3" json:"pressed,omitempty"`
	Modifiers uint32 `protobuf:"varint,5,opt,name=modifiers,proto3" json:"modifiers,omitempty"`
	// contains filtered or unexported fields
}

func (*MouseButton) Descriptor deprecated

func (*MouseButton) Descriptor() ([]byte, []int)

Deprecated: Use MouseButton.ProtoReflect.Descriptor instead.

func (*MouseButton) GetButton

func (x *MouseButton) GetButton() uint32

func (*MouseButton) GetModifiers

func (x *MouseButton) GetModifiers() uint32

func (*MouseButton) GetPressed

func (x *MouseButton) GetPressed() bool

func (*MouseButton) GetX

func (x *MouseButton) GetX() float32

func (*MouseButton) GetY

func (x *MouseButton) GetY() float32

func (*MouseButton) ProtoMessage

func (*MouseButton) ProtoMessage()

func (*MouseButton) ProtoReflect

func (x *MouseButton) ProtoReflect() protoreflect.Message

func (*MouseButton) Reset

func (x *MouseButton) Reset()

func (*MouseButton) String

func (x *MouseButton) String() string

type MouseMove

type MouseMove struct {
	X float32 `protobuf:"fixed32,1,opt,name=x,proto3" json:"x,omitempty"`
	Y float32 `protobuf:"fixed32,2,opt,name=y,proto3" json:"y,omitempty"`
	// contains filtered or unexported fields
}

Coordinates are in logical points (the egui coordinate space of the stream); the viewer converts from CSS pixels using the SessionHello geometry.

func (*MouseMove) Descriptor deprecated

func (*MouseMove) Descriptor() ([]byte, []int)

Deprecated: Use MouseMove.ProtoReflect.Descriptor instead.

func (*MouseMove) GetX

func (x *MouseMove) GetX() float32

func (*MouseMove) GetY

func (x *MouseMove) GetY() float32

func (*MouseMove) ProtoMessage

func (*MouseMove) ProtoMessage()

func (*MouseMove) ProtoReflect

func (x *MouseMove) ProtoReflect() protoreflect.Message

func (*MouseMove) Reset

func (x *MouseMove) Reset()

func (*MouseMove) String

func (x *MouseMove) String() string

type MouseWheel

type MouseWheel struct {
	Dx float32 `protobuf:"fixed32,1,opt,name=dx,proto3" json:"dx,omitempty"`
	Dy float32 `protobuf:"fixed32,2,opt,name=dy,proto3" json:"dy,omitempty"`
	// 0=points (browser deltaMode PIXEL), 1=lines, 2=pages — matches
	// egui::MouseWheelUnit.
	Unit      uint32 `protobuf:"varint,3,opt,name=unit,proto3" json:"unit,omitempty"`
	Modifiers uint32 `protobuf:"varint,4,opt,name=modifiers,proto3" json:"modifiers,omitempty"`
	// contains filtered or unexported fields
}

func (*MouseWheel) Descriptor deprecated

func (*MouseWheel) Descriptor() ([]byte, []int)

Deprecated: Use MouseWheel.ProtoReflect.Descriptor instead.

func (*MouseWheel) GetDx

func (x *MouseWheel) GetDx() float32

func (*MouseWheel) GetDy

func (x *MouseWheel) GetDy() float32

func (*MouseWheel) GetModifiers

func (x *MouseWheel) GetModifiers() uint32

func (*MouseWheel) GetUnit

func (x *MouseWheel) GetUnit() uint32

func (*MouseWheel) ProtoMessage

func (*MouseWheel) ProtoMessage()

func (*MouseWheel) ProtoReflect

func (x *MouseWheel) ProtoReflect() protoreflect.Message

func (*MouseWheel) Reset

func (x *MouseWheel) Reset()

func (*MouseWheel) String

func (x *MouseWheel) String() string

type PinchZoom

type PinchZoom struct {
	Factor float32 `protobuf:"fixed32,1,opt,name=factor,proto3" json:"factor,omitempty"`
	// contains filtered or unexported fields
}

Pinch gesture (touch clients): multiplicative zoom factor for this step, 1.0 = no change — maps to egui's Zoom event. Desktop pinch arrives as ctrl+wheel through MouseWheel instead and needs no event here (egui zooms on ctrl+scroll by itself).

func (*PinchZoom) Descriptor deprecated

func (*PinchZoom) Descriptor() ([]byte, []int)

Deprecated: Use PinchZoom.ProtoReflect.Descriptor instead.

func (*PinchZoom) GetFactor

func (x *PinchZoom) GetFactor() float32

func (*PinchZoom) ProtoMessage

func (*PinchZoom) ProtoMessage()

func (*PinchZoom) ProtoReflect

func (x *PinchZoom) ProtoReflect() protoreflect.Message

func (*PinchZoom) Reset

func (x *PinchZoom) Reset()

func (*PinchZoom) String

func (x *PinchZoom) String() string

type Ping

type Ping struct {
	Nonce uint64 `protobuf:"varint,1,opt,name=nonce,proto3" json:"nonce,omitempty"`
	// contains filtered or unexported fields
}

func (*Ping) Descriptor deprecated

func (*Ping) Descriptor() ([]byte, []int)

Deprecated: Use Ping.ProtoReflect.Descriptor instead.

func (*Ping) GetNonce

func (x *Ping) GetNonce() uint64

func (*Ping) ProtoMessage

func (*Ping) ProtoMessage()

func (*Ping) ProtoReflect

func (x *Ping) ProtoReflect() protoreflect.Message

func (*Ping) Reset

func (x *Ping) Reset()

func (*Ping) String

func (x *Ping) String() string

type PointerGone

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

Pointer left the canvas (browser pointerleave) — clears hover state.

func (*PointerGone) Descriptor deprecated

func (*PointerGone) Descriptor() ([]byte, []int)

Deprecated: Use PointerGone.ProtoReflect.Descriptor instead.

func (*PointerGone) ProtoMessage

func (*PointerGone) ProtoMessage()

func (*PointerGone) ProtoReflect

func (x *PointerGone) ProtoReflect() protoreflect.Message

func (*PointerGone) Reset

func (x *PointerGone) Reset()

func (*PointerGone) String

func (x *PointerGone) String() string

type Role

type Role int32

Connection role in the session (ADR-0086 SD1). Server-authoritative: exactly one ACTIVE connection drives input + geometry; PASSIVE connections watch read-only. PASSIVE is the proto3 default (0) — the safe role.

const (
	Role_ROLE_PASSIVE Role = 0
	Role_ROLE_ACTIVE  Role = 1
)

func (Role) Descriptor

func (Role) Descriptor() protoreflect.EnumDescriptor

func (Role) Enum

func (x Role) Enum() *Role

func (Role) EnumDescriptor deprecated

func (Role) EnumDescriptor() ([]byte, []int)

Deprecated: Use Role.Descriptor instead.

func (Role) Number

func (x Role) Number() protoreflect.EnumNumber

func (Role) String

func (x Role) String() string

func (Role) Type

func (Role) Type() protoreflect.EnumType

type Roster

type Roster struct {
	YouId       uint64         `protobuf:"varint,1,opt,name=you_id,json=youId,proto3" json:"you_id,omitempty"`
	YouRole     Role           `protobuf:"varint,2,opt,name=you_role,json=youRole,proto3,enum=boxer.imzero2.v1.Role" json:"you_role,omitempty"`
	ActiveId    uint64         `protobuf:"varint,3,opt,name=active_id,json=activeId,proto3" json:"active_id,omitempty"` // 0 = no active connection (slot empty)
	Count       uint32         `protobuf:"varint,4,opt,name=count,proto3" json:"count,omitempty"`
	Max         uint32         `protobuf:"varint,5,opt,name=max,proto3" json:"max,omitempty"`
	Connections []*RosterEntry `protobuf:"bytes,6,rep,name=connections,proto3" json:"connections,omitempty"`
	// contains filtered or unexported fields
}

Server→client (ADR-0086 SD1): the session roster, built PER RECIPIENT and rebroadcast on every membership/role change. `you_id`/`you_role` identify the receiving connection so its viewer can mirror its own role into the ViewMode and detect its own promotion/demotion — this folds the separate RoleChanged of SD8 into the roster.

func (*Roster) Descriptor deprecated

func (*Roster) Descriptor() ([]byte, []int)

Deprecated: Use Roster.ProtoReflect.Descriptor instead.

func (*Roster) GetActiveId

func (x *Roster) GetActiveId() uint64

func (*Roster) GetConnections

func (x *Roster) GetConnections() []*RosterEntry

func (*Roster) GetCount

func (x *Roster) GetCount() uint32

func (*Roster) GetMax

func (x *Roster) GetMax() uint32

func (*Roster) GetYouId

func (x *Roster) GetYouId() uint64

func (*Roster) GetYouRole

func (x *Roster) GetYouRole() Role

func (*Roster) ProtoMessage

func (*Roster) ProtoMessage()

func (*Roster) ProtoReflect

func (x *Roster) ProtoReflect() protoreflect.Message

func (*Roster) Reset

func (x *Roster) Reset()

func (*Roster) String

func (x *Roster) String() string

type RosterEntry

type RosterEntry struct {
	Id        uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
	Role      Role   `protobuf:"varint,2,opt,name=role,proto3,enum=boxer.imzero2.v1.Role" json:"role,omitempty"`
	Label     string `protobuf:"bytes,3,opt,name=label,proto3" json:"label,omitempty"`
	Webcodecs bool   `protobuf:"varint,4,opt,name=webcodecs,proto3" json:"webcodecs,omitempty"`
	// contains filtered or unexported fields
}

One connection as seen in the roster (ADR-0086 SD9). Identity stays minimal: id, role, an optional label, and the takeover-capable (webcodecs) flag. Peer IP is used for rate-limiting/audit (ADR-0082) only and never appears here.

func (*RosterEntry) Descriptor deprecated

func (*RosterEntry) Descriptor() ([]byte, []int)

Deprecated: Use RosterEntry.ProtoReflect.Descriptor instead.

func (*RosterEntry) GetId

func (x *RosterEntry) GetId() uint64

func (*RosterEntry) GetLabel

func (x *RosterEntry) GetLabel() string

func (*RosterEntry) GetRole

func (x *RosterEntry) GetRole() Role

func (*RosterEntry) GetWebcodecs

func (x *RosterEntry) GetWebcodecs() bool

func (*RosterEntry) ProtoMessage

func (*RosterEntry) ProtoMessage()

func (*RosterEntry) ProtoReflect

func (x *RosterEntry) ProtoReflect() protoreflect.Message

func (*RosterEntry) Reset

func (x *RosterEntry) Reset()

func (*RosterEntry) String

func (x *RosterEntry) String() string

type RunOptions

type RunOptions struct {
	// Timeout bounds each individual request to the host.
	Timeout time.Duration
	// SettleMs is applied after any step that does not set its own.
	SettleMs int
	// DryRun resolves every anchor and reports what it would do, without
	// sending input or writing captures. The cheap way to find out whether a
	// trace still matches the app after a UI change.
	DryRun bool
	Logger zerolog.Logger
}

RunOptions tunes a trace run.

type SessionControl

type SessionControl struct {

	// Types that are valid to be assigned to Control:
	//
	//	*SessionControl_Hello
	//	*SessionControl_ViewportResize
	//	*SessionControl_Ping
	//	*SessionControl_SetCadence
	//	*SessionControl_DecodeCapabilities
	//	*SessionControl_ClientHello
	//	*SessionControl_Roster
	//	*SessionControl_TakeSession
	//	*SessionControl_Clipboard
	//	*SessionControl_CursorShape
	//	*SessionControl_TreeRequest
	//	*SessionControl_TreeSnapshot
	//	*SessionControl_CaptureRequest
	//	*SessionControl_CaptureDone
	Control isSessionControl_Control `protobuf_oneof:"control"`
	// contains filtered or unexported fields
}

func (*SessionControl) Descriptor deprecated

func (*SessionControl) Descriptor() ([]byte, []int)

Deprecated: Use SessionControl.ProtoReflect.Descriptor instead.

func (*SessionControl) GetCaptureDone

func (x *SessionControl) GetCaptureDone() *CaptureDone

func (*SessionControl) GetCaptureRequest

func (x *SessionControl) GetCaptureRequest() *CaptureRequest

func (*SessionControl) GetClientHello

func (x *SessionControl) GetClientHello() *ClientHello

func (*SessionControl) GetClipboard

func (x *SessionControl) GetClipboard() *ClipboardData

func (*SessionControl) GetControl

func (x *SessionControl) GetControl() isSessionControl_Control

func (*SessionControl) GetCursorShape

func (x *SessionControl) GetCursorShape() *CursorShape

func (*SessionControl) GetDecodeCapabilities

func (x *SessionControl) GetDecodeCapabilities() *DecodeCapabilities

func (*SessionControl) GetHello

func (x *SessionControl) GetHello() *SessionHello

func (*SessionControl) GetPing

func (x *SessionControl) GetPing() *Ping

func (*SessionControl) GetRoster

func (x *SessionControl) GetRoster() *Roster

func (*SessionControl) GetSetCadence

func (x *SessionControl) GetSetCadence() *SetCadence

func (*SessionControl) GetTakeSession

func (x *SessionControl) GetTakeSession() *TakeSession

func (*SessionControl) GetTreeRequest

func (x *SessionControl) GetTreeRequest() *TreeRequest

func (*SessionControl) GetTreeSnapshot

func (x *SessionControl) GetTreeSnapshot() *TreeSnapshot

func (*SessionControl) GetViewportResize

func (x *SessionControl) GetViewportResize() *ViewportResize

func (*SessionControl) ProtoMessage

func (*SessionControl) ProtoMessage()

func (*SessionControl) ProtoReflect

func (x *SessionControl) ProtoReflect() protoreflect.Message

func (*SessionControl) Reset

func (x *SessionControl) Reset()

func (*SessionControl) String

func (x *SessionControl) String() string

type SessionControl_CaptureDone

type SessionControl_CaptureDone struct {
	CaptureDone *CaptureDone `protobuf:"bytes,14,opt,name=capture_done,json=captureDone,proto3,oneof"` // server→client
}

type SessionControl_CaptureRequest

type SessionControl_CaptureRequest struct {
	CaptureRequest *CaptureRequest `protobuf:"bytes,13,opt,name=capture_request,json=captureRequest,proto3,oneof"` // client→server
}

type SessionControl_ClientHello

type SessionControl_ClientHello struct {
	// ADR-0086 active/passive roster:
	ClientHello *ClientHello `protobuf:"bytes,6,opt,name=client_hello,json=clientHello,proto3,oneof"` // client→server, post-connect
}

type SessionControl_Clipboard

type SessionControl_Clipboard struct {
	// ADR-0082 SD6 clipboard (both ways):
	Clipboard *ClipboardData `protobuf:"bytes,9,opt,name=clipboard,proto3,oneof"`
}

type SessionControl_CursorShape

type SessionControl_CursorShape struct {
	// ADR-0024 Update 2026-07-28 mouse cursor shape:
	CursorShape *CursorShape `protobuf:"bytes,10,opt,name=cursor_shape,json=cursorShape,proto3,oneof"` // server→client, active connection only
}

type SessionControl_DecodeCapabilities

type SessionControl_DecodeCapabilities struct {
	DecodeCapabilities *DecodeCapabilities `protobuf:"bytes,5,opt,name=decode_capabilities,json=decodeCapabilities,proto3,oneof"`
}

type SessionControl_Hello

type SessionControl_Hello struct {
	Hello *SessionHello `protobuf:"bytes,1,opt,name=hello,proto3,oneof"`
}

type SessionControl_Ping

type SessionControl_Ping struct {
	Ping *Ping `protobuf:"bytes,3,opt,name=ping,proto3,oneof"`
}

type SessionControl_Roster

type SessionControl_Roster struct {
	Roster *Roster `protobuf:"bytes,7,opt,name=roster,proto3,oneof"` // server→client, per recipient
}

type SessionControl_SetCadence

type SessionControl_SetCadence struct {
	SetCadence *SetCadence `protobuf:"bytes,4,opt,name=set_cadence,json=setCadence,proto3,oneof"`
}

type SessionControl_TakeSession

type SessionControl_TakeSession struct {
	TakeSession *TakeSession `protobuf:"bytes,8,opt,name=take_session,json=takeSession,proto3,oneof"` // client→server
}

type SessionControl_TreeRequest

type SessionControl_TreeRequest struct {
	// ADR-0154 accessibility tree + capture on demand. All four are
	// honoured from / sent to the ACTIVE connection only, like input.
	TreeRequest *TreeRequest `protobuf:"bytes,11,opt,name=tree_request,json=treeRequest,proto3,oneof"` // client→server
}

type SessionControl_TreeSnapshot

type SessionControl_TreeSnapshot struct {
	TreeSnapshot *TreeSnapshot `protobuf:"bytes,12,opt,name=tree_snapshot,json=treeSnapshot,proto3,oneof"` // server→client
}

type SessionControl_ViewportResize

type SessionControl_ViewportResize struct {
	ViewportResize *ViewportResize `protobuf:"bytes,2,opt,name=viewport_resize,json=viewportResize,proto3,oneof"`
}

type SessionHello

type SessionHello struct {
	WidthPx        uint32  `protobuf:"varint,1,opt,name=width_px,json=widthPx,proto3" json:"width_px,omitempty"`
	HeightPx       uint32  `protobuf:"varint,2,opt,name=height_px,json=heightPx,proto3" json:"height_px,omitempty"`
	PixelsPerPoint float32 `protobuf:"fixed32,3,opt,name=pixels_per_point,json=pixelsPerPoint,proto3" json:"pixels_per_point,omitempty"`
	// Current host cadence (0 = continuous, 1 = reactive) so the viewer's
	// toggle reflects truth at connect.
	Cadence uint32 `protobuf:"varint,4,opt,name=cadence,proto3" json:"cadence,omitempty"`
	// WebCodecs codec string for VideoDecoder.configure (ADR-0088 SD6).
	// Empty for H.264 (the viewer derives avc1.* from the in-band SPS);
	// VP9/AV1 are named here (e.g. "vp09.00.41.08", "av01.0.08M.08"). A
	// codec switch re-announces the hello with the new string.
	Codec string `protobuf:"bytes,5,opt,name=codec,proto3" json:"codec,omitempty"`
	// contains filtered or unexported fields
}

Server→client: stream geometry the viewer needs to size its canvas and map pointer coordinates. Sent as the first message after connect AND re-announced whenever the host applies a viewport resize — geometry change implies a fresh encoder stream (SPS/PPS + IDR) follows, so the viewer drops its decoder and rejoins at the next key frame.

func (*SessionHello) Descriptor deprecated

func (*SessionHello) Descriptor() ([]byte, []int)

Deprecated: Use SessionHello.ProtoReflect.Descriptor instead.

func (*SessionHello) GetCadence

func (x *SessionHello) GetCadence() uint32

func (*SessionHello) GetCodec

func (x *SessionHello) GetCodec() string

func (*SessionHello) GetHeightPx

func (x *SessionHello) GetHeightPx() uint32

func (*SessionHello) GetPixelsPerPoint

func (x *SessionHello) GetPixelsPerPoint() float32

func (*SessionHello) GetWidthPx

func (x *SessionHello) GetWidthPx() uint32

func (*SessionHello) ProtoMessage

func (*SessionHello) ProtoMessage()

func (*SessionHello) ProtoReflect

func (x *SessionHello) ProtoReflect() protoreflect.Message

func (*SessionHello) Reset

func (x *SessionHello) Reset()

func (*SessionHello) String

func (x *SessionHello) String() string

type SetCadence

type SetCadence struct {
	Cadence uint32 `protobuf:"varint,1,opt,name=cadence,proto3" json:"cadence,omitempty"`
	// contains filtered or unexported fields
}

Client→server: switch the host render cadence at runtime. 0 = continuous (fixed tick at the configured fps), 1 = reactive (pass only when egui schedules a repaint, with a 1 s idle heartbeat; frames identical to the previous one are never encoded in either mode). Scope is the host, not the session — it survives reconnects. Note: the Go side reads IMZERO2_RENDER_CADENCE at startup; full idle savings need the server launched reactive (otherwise the Go side keeps requesting per-frame repaints and reactive degrades to dedup-only).

func (*SetCadence) Descriptor deprecated

func (*SetCadence) Descriptor() ([]byte, []int)

Deprecated: Use SetCadence.ProtoReflect.Descriptor instead.

func (*SetCadence) GetCadence

func (x *SetCadence) GetCadence() uint32

func (*SetCadence) ProtoMessage

func (*SetCadence) ProtoMessage()

func (*SetCadence) ProtoReflect

func (x *SetCadence) ProtoReflect() protoreflect.Message

func (*SetCadence) Reset

func (x *SetCadence) Reset()

func (*SetCadence) String

func (x *SetCadence) String() string

type Step

type Step struct {
	// Do is the verb: click, hover, type, set_value, focus, scroll_into_view,
	// key, scroll, wait, capture, cadence, resize, note, sleep.
	Do string `json:"do"`

	// Anchor (ADR-0127 §SD4). Id wins; then name/contains plus role; nth
	// disambiguates. Absent for verbs that target no widget.
	//
	// value / valueContains match the accessible value rather than the name,
	// which is the only way to reach static text: egui leaves a Label's name
	// empty and puts the text in the value. See [Locator].
	ID            uint64 `json:"id,omitempty"`
	Name          string `json:"name,omitempty"`
	Contains      string `json:"contains,omitempty"`
	Value         string `json:"value,omitempty"`
	ValueContains string `json:"valueContains,omitempty"`
	Role          string `json:"role,omitempty"`
	Nth           *int   `json:"nth,omitempty"`

	// Text carries the payload of `type`, `set_value`, `key` and `capture`
	// (the capture's file name) and the prose of `note`.
	Text string `json:"text,omitempty"`

	// X, Y are the last-rung coordinate target, for painter-only widgets that
	// have no node. Also the scroll delta for `scroll`.
	X float32 `json:"x,omitempty"`
	Y float32 `json:"y,omitempty"`

	// Pointer makes an anchored `click` press the resolved node's bounds
	// centre with a synthetic pointer instead of sending it an AccessKit
	// click action.
	//
	// It is the rung between "resolve by anchor" and "click a coordinate",
	// and it exists for widgets whose clickable region is not the node the
	// text lives in. A tree row is the case that found it: the row's sense
	// region sits *behind* its cells so the disclosure control can win its own
	// rect (ADR-0176 SD7), which leaves the row's label an ordinary
	// non-interactive node — findable, but deaf to an action request. Aiming
	// at where that label was drawn hits the region behind it.
	//
	// Prefer the default. An action request goes to the widget that declared
	// it and does not care what is drawn on top; a pointer press is a
	// position, and a tooltip or an overlay in the way will take it.
	Pointer bool `json:"pointer,omitempty"`

	// Modifiers is the key modifier bitmask (1=alt, 2=ctrl, 4=shift,
	// 8=mac_cmd, 16=command), matching egui::Modifiers.
	Modifiers uint32 `json:"modifiers,omitempty"`

	// Cadence for the `cadence` verb: 0 continuous, 1 reactive.
	Cadence uint32 `json:"cadence,omitempty"`

	// W, H, Scale for the `resize` verb.
	W     float32 `json:"w,omitempty"`
	H     float32 `json:"h,omitempty"`
	Scale float32 `json:"scale,omitempty"`

	// SettleMs pauses after the step, for animations and debounced fetches
	// the tree cannot report on. Also the duration of `sleep`.
	SettleMs int `json:"settleMs,omitempty"`

	// Comment is free prose kept beside the step; the runner logs it.
	Comment string `json:"comment,omitempty"`
}

Step is one line of a trace.

func ParseTrace

func ParseTrace(r io.Reader) (steps []Step, err error)

ParseTrace reads a JSON Lines trace.

type TakeSession

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

Client→server (ADR-0086 SD2): request to become the active connection. Honoured only from a webcodecs-capable connection; unilateral — it demotes the prior active to passive.

func (*TakeSession) Descriptor deprecated

func (*TakeSession) Descriptor() ([]byte, []int)

Deprecated: Use TakeSession.ProtoReflect.Descriptor instead.

func (*TakeSession) ProtoMessage

func (*TakeSession) ProtoMessage()

func (*TakeSession) ProtoReflect

func (x *TakeSession) ProtoReflect() protoreflect.Message

func (*TakeSession) Reset

func (x *TakeSession) Reset()

func (*TakeSession) String

func (x *TakeSession) String() string

type TextInput

type TextInput struct {
	Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"`
	// contains filtered or unexported fields
}

func (*TextInput) Descriptor deprecated

func (*TextInput) Descriptor() ([]byte, []int)

Deprecated: Use TextInput.ProtoReflect.Descriptor instead.

func (*TextInput) GetText

func (x *TextInput) GetText() string

func (*TextInput) ProtoMessage

func (*TextInput) ProtoMessage()

func (*TextInput) ProtoReflect

func (x *TextInput) ProtoReflect() protoreflect.Message

func (*TextInput) Reset

func (x *TextInput) Reset()

func (*TextInput) String

func (x *TextInput) String() string

type TreeNode

type TreeNode struct {
	Id uint64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
	// AccessKit role, lower-snake ("button", "check_box", "text_input", …).
	// A string rather than an enum: roles are open-ended upstream, and a
	// client matching on unknown roles should see them, not a zero.
	Role string `protobuf:"bytes,2,opt,name=role,proto3" json:"role,omitempty"`
	// Accessible name — the label a locator matches on.
	Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
	// Current value, where the widget has one (text edits, sliders, labels
	// that carry their text as a value).
	Value string  `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"`
	X     float32 `protobuf:"fixed32,5,opt,name=x,proto3" json:"x,omitempty"`
	Y     float32 `protobuf:"fixed32,6,opt,name=y,proto3" json:"y,omitempty"`
	W     float32 `protobuf:"fixed32,7,opt,name=w,proto3" json:"w,omitempty"`
	H     float32 `protobuf:"fixed32,8,opt,name=h,proto3" json:"h,omitempty"`
	// Bitmask: 1=disabled, 2=hidden, 4=focused, 8=selected.
	Flags uint32 `protobuf:"varint,9,opt,name=flags,proto3" json:"flags,omitempty"`
	// 0 when this is the root.
	Parent   uint64   `protobuf:"varint,10,opt,name=parent,proto3" json:"parent,omitempty"`
	Children []uint64 `protobuf:"varint,11,rep,packed,name=children,proto3" json:"children,omitempty"`
	// contains filtered or unexported fields
}

One widget. A deliberately reduced projection of `accesskit::Node`: enough to resolve a locator and to assert an effect, and nothing whose meaning would shift under an AccessKit upgrade. Bounds are in logical points, the same frame as MouseMove/MouseButton and, at pixels_per_point 1.0, as the streamed pixels.

func FindByName

func FindByName(snap *TreeSnapshot, name string) (node *TreeNode)

FindByName is the common case: the one visible node with this accessible name, or nil.

func Resolve

func Resolve(snap *TreeSnapshot, loc Locator) (node *TreeNode, err error)

Resolve returns the single node the locator selects.

Ambiguity is an error unless Nth was given. Hidden nodes are skipped: they are laid out but not on screen, so actuating one would succeed on the wire and do nothing a viewer could see.

func (*TreeNode) Descriptor deprecated

func (*TreeNode) Descriptor() ([]byte, []int)

Deprecated: Use TreeNode.ProtoReflect.Descriptor instead.

func (*TreeNode) GetChildren

func (x *TreeNode) GetChildren() []uint64

func (*TreeNode) GetFlags

func (x *TreeNode) GetFlags() uint32

func (*TreeNode) GetH

func (x *TreeNode) GetH() float32

func (*TreeNode) GetId

func (x *TreeNode) GetId() uint64

func (*TreeNode) GetName

func (x *TreeNode) GetName() string

func (*TreeNode) GetParent

func (x *TreeNode) GetParent() uint64

func (*TreeNode) GetRole

func (x *TreeNode) GetRole() string

func (*TreeNode) GetValue

func (x *TreeNode) GetValue() string

func (*TreeNode) GetW

func (x *TreeNode) GetW() float32

func (*TreeNode) GetX

func (x *TreeNode) GetX() float32

func (*TreeNode) GetY

func (x *TreeNode) GetY() float32

func (*TreeNode) ProtoMessage

func (*TreeNode) ProtoMessage()

func (*TreeNode) ProtoReflect

func (x *TreeNode) ProtoReflect() protoreflect.Message

func (*TreeNode) Reset

func (x *TreeNode) Reset()

func (*TreeNode) String

func (x *TreeNode) String() string

type TreeRequest

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

ADR-0154 SD1. Client→server: send me the accessibility tree as of the next completed pass. Request/response rather than a push subscription: the cursor shape is four bytes that change rarely, whereas a tree is hundreds of nodes that any hover mutates, so pushing on change would put a per-pass build and diff on the render loop for a consumer that reads it a handful of times per session. The first request also switches AccessKit generation on (`egui::Context::enable_accesskit`), so a host nobody asks pays nothing.

func (*TreeRequest) Descriptor deprecated

func (*TreeRequest) Descriptor() ([]byte, []int)

Deprecated: Use TreeRequest.ProtoReflect.Descriptor instead.

func (*TreeRequest) ProtoMessage

func (*TreeRequest) ProtoMessage()

func (*TreeRequest) ProtoReflect

func (x *TreeRequest) ProtoReflect() protoreflect.Message

func (*TreeRequest) Reset

func (x *TreeRequest) Reset()

func (*TreeRequest) String

func (x *TreeRequest) String() string

type TreeSnapshot

type TreeSnapshot struct {
	Nodes []*TreeNode `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"`
	// Node id holding keyboard focus, or 0 when nothing is focused.
	Focus uint64 `protobuf:"varint,2,opt,name=focus,proto3" json:"focus,omitempty"`
	// The host's frame counter when the tree was taken, so a client can tell
	// two snapshots apart and pair one with a capture.
	Pass uint64 `protobuf:"varint,3,opt,name=pass,proto3" json:"pass,omitempty"`
	// contains filtered or unexported fields
}

Server→client: the widget tree of one pass, flattened. Node order is unspecified; use `parent`/`children` to walk it. Sent only to the connection that asked.

func (*TreeSnapshot) Descriptor deprecated

func (*TreeSnapshot) Descriptor() ([]byte, []int)

Deprecated: Use TreeSnapshot.ProtoReflect.Descriptor instead.

func (*TreeSnapshot) GetFocus

func (x *TreeSnapshot) GetFocus() uint64

func (*TreeSnapshot) GetNodes

func (x *TreeSnapshot) GetNodes() []*TreeNode

func (*TreeSnapshot) GetPass

func (x *TreeSnapshot) GetPass() uint64

func (*TreeSnapshot) ProtoMessage

func (*TreeSnapshot) ProtoMessage()

func (*TreeSnapshot) ProtoReflect

func (x *TreeSnapshot) ProtoReflect() protoreflect.Message

func (*TreeSnapshot) Reset

func (x *TreeSnapshot) Reset()

func (*TreeSnapshot) String

func (x *TreeSnapshot) String() string

type VideoChunk

type VideoChunk struct {
	FrameIndex uint64 `protobuf:"varint,1,opt,name=frame_index,json=frameIndex,proto3" json:"frame_index,omitempty"`
	// Microseconds since the encoder stream started; monotonic per
	// connection (each (re)connect restarts the stream at an IDR).
	TimestampMicros uint64 `protobuf:"varint,2,opt,name=timestamp_micros,json=timestampMicros,proto3" json:"timestamp_micros,omitempty"`
	Keyframe        bool   `protobuf:"varint,3,opt,name=keyframe,proto3" json:"keyframe,omitempty"`
	Data            []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"`
	// contains filtered or unexported fields
}

Server→client video payload (prefix 0x01). One message per H.264 access unit (ADR-0024 SD4); SPS/PPS ride in-band on every key frame (`dump_extra=freq=keyframe`).

func (*VideoChunk) Descriptor deprecated

func (*VideoChunk) Descriptor() ([]byte, []int)

Deprecated: Use VideoChunk.ProtoReflect.Descriptor instead.

func (*VideoChunk) GetData

func (x *VideoChunk) GetData() []byte

func (*VideoChunk) GetFrameIndex

func (x *VideoChunk) GetFrameIndex() uint64

func (*VideoChunk) GetKeyframe

func (x *VideoChunk) GetKeyframe() bool

func (*VideoChunk) GetTimestampMicros

func (x *VideoChunk) GetTimestampMicros() uint64

func (*VideoChunk) ProtoMessage

func (*VideoChunk) ProtoMessage()

func (*VideoChunk) ProtoReflect

func (x *VideoChunk) ProtoReflect() protoreflect.Message

func (*VideoChunk) Reset

func (x *VideoChunk) Reset()

func (*VideoChunk) String

func (x *VideoChunk) String() string

type ViewportResize

type ViewportResize struct {
	LogicalWidth  float32 `protobuf:"fixed32,1,opt,name=logical_width,json=logicalWidth,proto3" json:"logical_width,omitempty"`
	LogicalHeight float32 `protobuf:"fixed32,2,opt,name=logical_height,json=logicalHeight,proto3" json:"logical_height,omitempty"`
	PixelScale    float32 `protobuf:"fixed32,3,opt,name=pixel_scale,json=pixelScale,proto3" json:"pixel_scale,omitempty"`
	// contains filtered or unexported fields
}

Client→server. ADR-0024 SD7/SD8 (amended at acceptance): the client's viewport in CSS pixels plus its pixel scale (devicePixelRatio × page zoom). The host clamps it, rebuilds the offscreen target and encoder at logical×scale physical pixels (rounded even), and answers with a fresh SessionHello.

func (*ViewportResize) Descriptor deprecated

func (*ViewportResize) Descriptor() ([]byte, []int)

Deprecated: Use ViewportResize.ProtoReflect.Descriptor instead.

func (*ViewportResize) GetLogicalHeight

func (x *ViewportResize) GetLogicalHeight() float32

func (*ViewportResize) GetLogicalWidth

func (x *ViewportResize) GetLogicalWidth() float32

func (*ViewportResize) GetPixelScale

func (x *ViewportResize) GetPixelScale() float32

func (*ViewportResize) ProtoMessage

func (*ViewportResize) ProtoMessage()

func (*ViewportResize) ProtoReflect

func (x *ViewportResize) ProtoReflect() protoreflect.Message

func (*ViewportResize) Reset

func (x *ViewportResize) Reset()

func (*ViewportResize) String

func (x *ViewportResize) String() string

Directories

Path Synopsis
Package drivecmd is the `imzero2 drive` subcommand: replay an interaction trace against a running headless host (ADR-0154 §SD6).
Package drivecmd is the `imzero2 drive` subcommand: replay an interaction trace against a running headless host (ADR-0154 §SD6).

Jump to

Keyboard shortcuts

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