Semantic snapshot of the UI for agent / programmatic consumption.
Unlike Buffer (which produces cells), this module produces
a tree of semantic nodes: widget type, id, role, current value, focus state.
Agents read snapshot/1 to perceive the UI and dispatch actions through
Runtime to act on it — no ANSI parsing required.
Why this is NOT a Buffer
The buffer is coordinate-based (draw_char, fill_rect). An agent tree is structural (parent/child) and semantic (role/value/state). Forcing it through Buffer would throw away the very information agents need.
Summary
Functions
Find a node in a snapshot by its id. Convenience for agents that want a single widget instead of walking the tree.
Produce a semantic snapshot of the current UI.
Types
@type action() :: {:focus, term()} | {:set_value, term(), String.t()} | {:select_index, term(), non_neg_integer()} | {:toggle, term()} | {:set_checked, term(), boolean()} | {:click, term()} | {:key, map()} | {:mouse, map()} | {:paste, String.t()}
Actions an agent can dispatch via Runtime.dispatch/2.
Semantic actions mutate widget state directly (and fire their on_change callbacks exactly as a human interaction would). Key/mouse passthrough actions route through EventManager unchanged — use them to reach widget behaviors bound to specific keystrokes (e.g. Ctrl+K in TextInput).
@type node_snapshot() :: %{ id: term() | nil, type: ElixirOpentui.Element.element_type(), role: role(), focused: boolean(), visible: boolean(), state: map(), children: [node_snapshot()] }
@type role() ::
:textbox
| :listbox
| :checkbox
| :button
| :scrollable
| :tablist
| :text
| :container
@type t() :: %{ focused_id: term() | nil, frame: non_neg_integer(), root: node_snapshot() }
Functions
@spec find_node(t() | node_snapshot() | nil, term()) :: node_snapshot() | nil
Find a node in a snapshot by its id. Convenience for agents that want a single widget instead of walking the tree.
@spec snapshot(ElixirOpentui.Runtime.model()) :: t()
Produce a semantic snapshot of the current UI.
Called with the Runtime's model. Walks the element tree, merges in the current component state for each widget, and returns a JSON-serializable map.