UI-neutral session state shared by terminal and LiveView renderers.
This struct is the semantic UI source of truth. Reducers update it from Vibe UI events and renderers adapt it to terminal widgets, LiveView assigns, or tests. Keep terminal control sequences and renderer-specific details outside this state so alternate clients can consume the same session model.
Summary
Types
@type message() :: %{ :role => :user | :assistant | :tool | :subagent, :at => DateTime.t(), optional(atom()) => term() }
@type t() :: %Vibe.UI.State{ active_sessions: non_neg_integer() | nil, cwd: String.t() | nil, editor: map(), effort: Vibe.Model.Effort.t() | nil, events: [Vibe.Event.t()], goal: Vibe.Goals.Goal.t() | nil, hidden_thinking_label: String.t() | nil, messages: [message()], model: String.t() | nil, notifications: [Vibe.UI.Notification.t()], overlays: [map()], pending_tools: map(), plugin_statuses: map(), plugin_widgets: map(), runtime_alerts: %{required(String.t()) => Vibe.SystemAlarms.Alert.t()}, selector: Vibe.UI.Selector.t() | nil, session_id: String.t() | nil, status: atom(), streaming_message: map() | nil, title: String.t() | nil, truncate?: boolean(), usage: map(), usage_preview: map(), working_message: String.t() | nil }