pub struct App {
pub metrics: MetricsSnapshot,
pub should_quit: bool,
pub subagent_sidebar: SubAgentSidebarState,
/* private fields */
}Expand description
Central state machine for the TUI dashboard.
App owns all widget state, the render cache, the message history, and
the event channel endpoints. The main loop in crate::run_tui calls
draw once per frame and routes events through
handle_event and
handle_agent_event.
§Construction
use tokio::sync::mpsc;
use zeph_tui::App;
let (user_tx, _user_rx) = mpsc::channel(64);
let (_agent_tx, agent_rx) = mpsc::channel(64);
let app = App::new(user_tx, agent_rx);Use the builder methods to wire optional components:
with_metrics_rx— live metrics watch channel.with_cancel_signal— Ctrl-C cancel notify.with_command_tx— slash-command dispatch channel.
Fields§
§metrics: MetricsSnapshot§should_quit: boolInteractive selection state for the subagent sidebar (stays global per arch v2 E5).
Implementations§
Source§impl App
impl App
Sourcepub fn handle_event(&mut self, event: AppEvent)
pub fn handle_event(&mut self, event: AppEvent)
Dispatch a top-level AppEvent to the appropriate handler.
Called once per event in the main crate::run_tui loop.
Sourcepub fn poll_agent_event(
&mut self,
) -> impl Future<Output = Option<AgentEvent>> + use<'_>
pub fn poll_agent_event( &mut self, ) -> impl Future<Output = Option<AgentEvent>> + use<'_>
Await the next AgentEvent from the agent channel.
Returns None when all senders have been dropped (agent exited).
Called from the select! block in crate::run_tui.
Sourcepub fn try_recv_agent_event(&mut self) -> Result<AgentEvent, TryRecvError>
pub fn try_recv_agent_event(&mut self) -> Result<AgentEvent, TryRecvError>
Non-blocking poll for a pending AgentEvent.
Used to drain the channel after a first event has been received, coalescing multiple events into a single render frame.
§Errors
Returns TryRecvError::Empty if no events are pending, or
TryRecvError::Disconnected if the sender has been dropped.
Sourcepub fn handle_agent_event(&mut self, event: AgentEvent)
pub fn handle_agent_event(&mut self, event: AgentEvent)
Handle an AgentEvent and update widget state accordingly.
This is the main state-transition function for agent-driven updates: appending streaming chunks, recording tool events, displaying confirm dialogs, and wiring late-bound channels (cancel signal, metrics).
pub fn confirm_state(&self) -> Option<&ConfirmState>
Source§impl App
impl App
Sourcepub fn has_recent_security_events(&self) -> bool
pub fn has_recent_security_events(&self) -> bool
Returns true if there are security events within the last 60 seconds.
Sourcepub fn poll_pending_file_index(&mut self)
pub fn poll_pending_file_index(&mut self)
Checks if the background file index build has completed and, if so, installs the result and refreshes an open mention picker’s Files category (FR-011/ NFR-004) — seamless transition, no input loss even if the popup opened before the index was ready.
Source§impl App
impl App
Sourcepub fn new(
user_input_tx: Sender<String>,
agent_event_rx: Receiver<AgentEvent>,
) -> Self
pub fn new( user_input_tx: Sender<String>, agent_event_rx: Receiver<AgentEvent>, ) -> Self
Create a new App with the given I/O channels.
The app starts in insert mode with the splash screen visible and no messages in the buffer.
§Arguments
user_input_tx— sender used to forward the user’s typed text to the agent loop viaTuiChannel.agent_event_rx— receiver forAgentEventproduced by the agent.
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
let (user_tx, _user_rx) = mpsc::channel(64);
let (_agent_tx, agent_rx) = mpsc::channel(64);
let app = App::new(user_tx, agent_rx);
assert!(app.show_splash());Sourcepub fn with_theme(self, theme: Theme) -> Self
pub fn with_theme(self, theme: Theme) -> Self
Override the visual theme with a palette-derived crate::theme::Theme.
Called once at startup after crate::theme::Theme::from_palette_with_mode has been
built from the user’s config and detected terminal colour capability.
§Examples
use tokio::sync::mpsc;
use zeph_tui::{App, theme::{Theme, SemanticPalette}};
let (user_tx, _) = mpsc::channel(64);
let (_, agent_rx) = mpsc::channel(64);
let app = App::new(user_tx, agent_rx)
.with_theme(Theme::from_palette(&SemanticPalette::zephyr()));Sourcepub fn with_theme_name(self, name: impl Into<String>) -> Self
pub fn with_theme_name(self, name: impl Into<String>) -> Self
Set the active theme name for cycle tracking and status echoes.
Must be called at every construction site that supplies a non-default theme so that
cycle_theme starts cycling from the correct position.
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
let (user_tx, _) = mpsc::channel(64);
let (_, agent_rx) = mpsc::channel(64);
let app = App::new(user_tx, agent_rx).with_theme_name("gruvbox-dark");Sourcepub fn with_effective_color_mode(self, mode: EffectiveColorMode) -> Self
pub fn with_effective_color_mode(self, mode: EffectiveColorMode) -> Self
Set the resolved colour mode used to re-derive themes on runtime swap.
Store the EffectiveColorMode resolved once at startup so that apply_theme
produces consistent downgrade behaviour without re-running OS detection per swap.
§Examples
use tokio::sync::mpsc;
use zeph_tui::{App, theme::EffectiveColorMode};
let (user_tx, _) = mpsc::channel(64);
let (_, agent_rx) = mpsc::channel(64);
let app = App::new(user_tx, agent_rx)
.with_effective_color_mode(EffectiveColorMode::Truecolor);Sourcepub fn theme_generation(&self) -> u64
pub fn theme_generation(&self) -> u64
Return the current theme generation counter.
Passed into RenderCacheKey::theme_generation so the render cache is
invalidated after every theme swap.
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
let (user_tx, _) = mpsc::channel(64);
let (_, agent_rx) = mpsc::channel(64);
let app = App::new(user_tx, agent_rx);
assert_eq!(app.theme_generation(), 0);Sourcepub fn apply_theme(&mut self, name: &str) -> Result<bool, ThemeLoadError>
pub fn apply_theme(&mut self, name: &str) -> Result<bool, ThemeLoadError>
Apply a named theme preset or user file.
Returns Ok(true) when the theme was applied immediately (built-in preset).
Returns Ok(false) when the user file load was dispatched asynchronously; the
result will be installed by poll_pending_theme on the next tick.
Cancels any in-flight user-file load when switching to a preset, so the earlier async result cannot silently revert the newer choice.
§Errors
Returns crate::theme::ThemeLoadError for empty or path-unsafe names.
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
let (user_tx, _) = mpsc::channel(64);
let (_, agent_rx) = mpsc::channel(64);
let mut app = App::new(user_tx, agent_rx);
let gen_before = app.theme_generation();
let _ = app.apply_theme("zephyr-light");
assert!(app.theme_generation() > gen_before);Sourcepub fn poll_pending_theme(&mut self)
pub fn poll_pending_theme(&mut self)
Install a pending user-theme load result if the background task has completed.
Must be called once per tick from tui_loop (alongside poll_pending_file_index).
Sourcepub fn cycle_theme(&mut self)
pub fn cycle_theme(&mut self)
Cycle to the next preset in the fixed cycle list ["zephyr", "zephyr-light", "high-contrast"].
Finds the current theme name in the cycle list and advances to the next entry,
wrapping around. If the current name is not in the list, starts from "zephyr".
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
let (user_tx, _) = mpsc::channel(64);
let (_, agent_rx) = mpsc::channel(64);
let mut app = App::new(user_tx, agent_rx).with_theme_name("zephyr");
app.cycle_theme();
assert_eq!(app.active_theme_name(), "zephyr-light");Sourcepub fn active_theme_name(&self) -> &str
pub fn active_theme_name(&self) -> &str
Return the name of the currently-active theme.
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
let (user_tx, _) = mpsc::channel(64);
let (_, agent_rx) = mpsc::channel(64);
let app = App::new(user_tx, agent_rx).with_theme_name("gruvbox-dark");
assert_eq!(app.active_theme_name(), "gruvbox-dark");Sourcepub fn effective_color_mode(&self) -> EffectiveColorMode
pub fn effective_color_mode(&self) -> EffectiveColorMode
Return the resolved terminal colour mode stored at startup.
Used by widgets to choose between Unicode and ASCII fallback rendering.
§Examples
use tokio::sync::mpsc;
use zeph_tui::{App, theme::EffectiveColorMode};
let (user_tx, _) = mpsc::channel(64);
let (_, agent_rx) = mpsc::channel(64);
let app = App::new(user_tx, agent_rx);
assert_eq!(app.effective_color_mode(), EffectiveColorMode::Truecolor);Sourcepub fn is_ascii_only(&self) -> bool
pub fn is_ascii_only(&self) -> bool
Return true when the terminal cannot render Unicode glyphs and ASCII-only output
should be used in place of box-drawing characters and spinners.
Unicode capability is detected independently from colour support. A terminal with
NO_COLOR set (which produces EffectiveColorMode::Never) may still render ▹▸
perfectly. Only TERM=dumb or a non-UTF-8 locale forces ASCII mode.
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
let (user_tx, _) = mpsc::channel(64);
let (_, agent_rx) = mpsc::channel(64);
// Default app created in a normal environment reports Unicode capable.
let app = App::new(user_tx, agent_rx);
// is_ascii_only() depends on TERM/LANG env vars, not color mode.
let _ = app.is_ascii_only();Sourcepub fn show_splash(&self) -> bool
pub fn show_splash(&self) -> bool
Return true while the splash screen should be displayed.
The splash screen is hidden as soon as the first chat message arrives.
Sourcepub fn show_side_panels(&self) -> bool
pub fn show_side_panels(&self) -> bool
Return true when the side panels column is visible.
Controlled by the s keybinding and automatically disabled on narrow
terminals (< 80 columns).
Sourcepub fn plan_view_active(&self) -> bool
pub fn plan_view_active(&self) -> bool
Returns true when the user has toggled back to subagents view (plan view overridden).
Sourcepub fn render_cache(&self) -> &RenderCache
pub fn render_cache(&self) -> &RenderCache
Returns the active session’s render cache.
Sourcepub fn render_cache_mut(&mut self) -> &mut RenderCache
pub fn render_cache_mut(&mut self) -> &mut RenderCache
Returns a mutable reference to the active session’s render cache.
Sourcepub fn view_target(&self) -> &AgentViewTarget
pub fn view_target(&self) -> &AgentViewTarget
Returns the current chat area view target (main conversation or sub-agent transcript).
Sourcepub fn transcript_cache(&self) -> Option<&TranscriptCache>
pub fn transcript_cache(&self) -> Option<&TranscriptCache>
Returns the cached transcript for the currently-focused sub-agent, if any.
Sourcepub fn load_history(&mut self, messages: &[(&str, &str)])
pub fn load_history(&mut self, messages: &[(&str, &str)])
Populate the message buffer from a persisted session history.
Each element is a (role, content) pair where role is one of
"user", "assistant", or "tool". Tool outputs are detected by a
sentinel suffix and rendered as MessageRole::Tool messages.
The splash screen is hidden after loading if any messages are present.
Sourcepub fn backfill_history_display_only(&mut self, entries: &[TranscriptEntry])
pub fn backfill_history_display_only(&mut self, entries: &[TranscriptEntry])
Backfill the message buffer from a bounded /history transcript slice
(spec-068 §13.6-§13.7).
Unlike App::load_history, this never pushes into input_history — display
backfill and readline/up-arrow recall are deliberately separate code paths (INV-SP-6,
AC-20). Entries arrive already role-classified by
zeph_commands::transcript::TranscriptFormatter’s upstream producer
(MessageAccess::transcript_page), so no sentinel/tool-output re-parsing is needed
here (contrast with load_history, which still receives raw (role_str, content)
pairs from the legacy SQLite projection).
Sourcepub fn with_cancel_signal(self, signal: Arc<Notify>) -> Self
pub fn with_cancel_signal(self, signal: Arc<Notify>) -> Self
Attach a cancel signal that Ctrl-C in the TUI will trigger.
§Examples
use std::sync::Arc;
use tokio::sync::{Notify, mpsc};
use zeph_tui::App;
let (tx, _rx) = mpsc::channel(1);
let (_atx, arx) = mpsc::channel(1);
let notify = Arc::new(Notify::new());
let _app = App::new(tx, arx).with_cancel_signal(notify);Sourcepub fn with_metrics_rx(self, rx: Receiver<MetricsSnapshot>) -> Self
pub fn with_metrics_rx(self, rx: Receiver<MetricsSnapshot>) -> Self
Attach a metrics watch channel for live dashboard updates.
The current snapshot is read immediately; subsequent updates are polled
by poll_metrics each frame.
§Examples
use tokio::sync::{mpsc, watch};
use zeph_tui::{App, MetricsSnapshot};
let (tx, _rx) = mpsc::channel(1);
let (_atx, arx) = mpsc::channel(1);
let (_metrics_tx, metrics_rx) = watch::channel(MetricsSnapshot::default());
let _app = App::new(tx, arx).with_metrics_rx(metrics_rx);Sourcepub fn with_command_tx(self, tx: Sender<TuiCommand>) -> Self
pub fn with_command_tx(self, tx: Sender<TuiCommand>) -> Self
Attach the command dispatch sender used for slash-command routing.
§Examples
use tokio::sync::mpsc;
use zeph_tui::{App, TuiCommand};
let (tx, _rx) = mpsc::channel(1);
let (_atx, arx) = mpsc::channel(1);
let (cmd_tx, _cmd_rx) = mpsc::channel(8);
let _app = App::new(tx, arx).with_command_tx(cmd_tx);Sourcepub fn with_tool_density(self, density: ToolDensity) -> Self
pub fn with_tool_density(self, density: ToolDensity) -> Self
Set the initial tool-output density from a loaded TuiConfig.
Applied once at startup; runtime changes via the c key override this
but are not persisted back to config.
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
use zeph_config::ToolDensity;
let (tx, _rx) = mpsc::channel(1);
let (_atx, arx) = mpsc::channel(1);
let _app = App::new(tx, arx).with_tool_density(ToolDensity::Compact);Sourcepub fn with_remote_daemon_url(self, url: impl Into<String>) -> Self
pub fn with_remote_daemon_url(self, url: impl Into<String>) -> Self
Record the remote daemon URL this session was attached to via --connect <URL>.
Set once at startup in run_tui_remote; there is no runtime mechanism to attach
to or detach from a daemon mid-session (#5509). Used by daemon:status to report
real connection state instead of a stub message.
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
let (user_tx, _) = mpsc::channel(64);
let (_, agent_rx) = mpsc::channel(64);
let app = App::new(user_tx, agent_rx).with_remote_daemon_url("http://localhost:8765");Sourcepub fn with_task_supervisor(self, supervisor: TaskSupervisor) -> Self
pub fn with_task_supervisor(self, supervisor: TaskSupervisor) -> Self
Wire a TaskSupervisor into the App for the task registry panel.
The supervisor’s task list is snapshotted once per render tick before
terminal.draw(), keeping the draw closure free of mutex contention.
Toggle the panel visibility with /tasks.
§Examples
use tokio::sync::mpsc;
use tokio_util::sync::CancellationToken;
use zeph_common::task_supervisor::TaskSupervisor;
use zeph_tui::App;
let (user_tx, _) = mpsc::channel(64);
let (_, agent_rx) = mpsc::channel(64);
let cancel = CancellationToken::new();
let supervisor = TaskSupervisor::new(cancel);
let _app = App::new(user_tx, agent_rx).with_task_supervisor(supervisor);Sourcepub fn set_task_supervisor(&mut self, supervisor: TaskSupervisor)
pub fn set_task_supervisor(&mut self, supervisor: TaskSupervisor)
Wire a TaskSupervisor into a running App instance.
Used by the two-phase TUI startup path to connect the supervisor after
early startup (Phase 2), mirroring App::set_cancel_signal and
App::set_metrics_rx so the task registry panel works on that path too.
Sourcepub fn supervisor_activity_label(&self) -> Option<String>
pub fn supervisor_activity_label(&self) -> Option<String>
Return a truncated label for active TaskSupervisor tasks, or None when idle.
Used by the input widget to show a braille spinner with the name of the first active (Running/Restarting) task when no other status is being displayed.
Sourcepub fn set_cancel_signal(&mut self, signal: Arc<Notify>)
pub fn set_cancel_signal(&mut self, signal: Arc<Notify>)
Wire a cancel signal into a running App instance.
Used by the two-phase TUI startup path to connect the agent’s cancel signal after the agent has been constructed (Phase 2).
Sourcepub fn set_metrics_rx(&mut self, rx: Receiver<MetricsSnapshot>)
pub fn set_metrics_rx(&mut self, rx: Receiver<MetricsSnapshot>)
Wire a metrics receiver into a running App instance.
Used by the two-phase TUI startup path to connect the metrics channel after the metrics watch channel has been created (Phase 2).
Sourcepub fn poll_metrics(&mut self)
pub fn poll_metrics(&mut self)
Check the metrics watch channel for an updated snapshot and apply it.
Also clamps the sidebar selection and triggers a transcript reload if the sub-agent’s turn count has advanced. Called once per render frame.
Sourcepub fn messages(&self) -> &[ChatMessage]
pub fn messages(&self) -> &[ChatMessage]
Return a slice of all chat messages currently in the buffer.
For the currently-displayed messages (which may be a sub-agent
transcript) use visible_messages instead.
Sourcepub fn input_mode(&self) -> InputMode
pub fn input_mode(&self) -> InputMode
Return the current input mode (normal vs. insert).
Sourcepub fn cursor_position(&self) -> usize
pub fn cursor_position(&self) -> usize
Return the cursor byte position within the input string.
Sourcepub fn scroll_offset(&self) -> usize
pub fn scroll_offset(&self) -> usize
Return the number of lines the chat view is scrolled up from the bottom.
0 means the view is at the bottom (latest messages visible).
Sourcepub fn tool_expanded(&self) -> bool
pub fn tool_expanded(&self) -> bool
Return true when tool-output blocks are expanded to full height.
Sourcepub fn paste_state(&self) -> Option<&PasteState>
pub fn paste_state(&self) -> Option<&PasteState>
Return the active paste indicator state, if any.
Some when a multiline paste is in the input buffer and no edit
keypress has occurred since the paste. None otherwise.
Sourcepub fn tool_density(&self) -> ToolDensity
pub fn tool_density(&self) -> ToolDensity
Return the current tool-output density level.
Sourcepub fn show_source_labels(&self) -> bool
pub fn show_source_labels(&self) -> bool
Return true when source-label badges are shown on assistant messages.
Sourcepub fn set_show_source_labels(&mut self, v: bool)
pub fn set_show_source_labels(&mut self, v: bool)
Toggle source-label visibility.
Clears the render cache so all messages are re-rendered with the new setting on the next frame.
Sourcepub fn show_balance(&self) -> bool
pub fn show_balance(&self) -> bool
Return true when the Cocoon TON balance should be shown in the status bar.
Controlled by [cocoon] show_balance in config (default true). When false,
the balance is redacted to *** TON per spec §15.2.
Sourcepub fn set_show_balance(&mut self, v: bool)
pub fn set_show_balance(&mut self, v: bool)
Set whether the Cocoon TON balance is shown in the status bar.
Sourcepub fn set_hyperlinks(&mut self, links: Vec<HyperlinkSpan>)
pub fn set_hyperlinks(&mut self, links: Vec<HyperlinkSpan>)
Replace the current hyperlink span list with links.
Called by the render loop after each frame to store spans detected in the terminal buffer so they can be emitted as OSC 8 sequences.
Sourcepub fn take_hyperlinks(&mut self) -> Vec<HyperlinkSpan>
pub fn take_hyperlinks(&mut self) -> Vec<HyperlinkSpan>
Take ownership of the accumulated hyperlink spans, clearing the list.
Called once per frame; the caller writes OSC 8 sequences to the terminal.
Sourcepub fn status_label(&self) -> Option<&str>
pub fn status_label(&self) -> Option<&str>
Return the current raw activity status label, if any.
This is the internal label as set by the agent loop (e.g.
"Searching memory…", "Executing tool: bash"), not yet transformed
for display. The status bar passes it through
crate::widgets::status_verbs::humanize before rendering it next to
the spinner; other consumers (logs, debug output) use the raw form.
Return the persistent “Resuming session” banner text, if a non-empty prior
conversation was resumed at startup (spec-068 §13.5). None for a fresh
conversation — render nothing in that case (AC-16).
Sourcepub fn queued_count(&self) -> usize
pub fn queued_count(&self) -> usize
Return the number of messages queued or pending for the agent.
Displayed in the input bar to indicate backpressure.
Sourcepub fn context_token_estimate(&self) -> usize
pub fn context_token_estimate(&self) -> usize
Return the projected context token count from the last assembly, or 0 if not yet known.
The value is approximate (character-level heuristic) and is updated once per agent turn.
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
let (tx, _) = mpsc::channel(1);
let (_, rx) = mpsc::channel(1);
let app = App::new(tx, rx);
assert_eq!(app.context_token_estimate(), 0);Sourcepub fn editing_queued(&self) -> bool
pub fn editing_queued(&self) -> bool
Return true when the user is currently editing a queued message.
Sourcepub fn is_agent_busy(&self) -> bool
pub fn is_agent_busy(&self) -> bool
Return true when the agent is actively processing (streaming or running a tool).
Used by the render loop to decide whether to show the activity spinner.
Sourcepub fn has_running_tool(&self) -> bool
pub fn has_running_tool(&self) -> bool
Return true when the last message is a streaming tool output.
Sourcepub fn throbber_state(&self) -> &ThrobberState
pub fn throbber_state(&self) -> &ThrobberState
Return a reference to the throbber animation state.
Used by the status widget to render the spinner frame.
Sourcepub fn throbber_state_mut(&mut self) -> &mut ThrobberState
pub fn throbber_state_mut(&mut self) -> &mut ThrobberState
Return a mutable reference to the throbber animation state.
Called by the tick handler to advance the spinner frame each tick.
Sourcepub fn toggle_panel_collapse(&mut self, idx: usize)
pub fn toggle_panel_collapse(&mut self, idx: usize)
Toggle the collapsed state of a side-panel section by index.
Index mapping: 0 = Skills, 1 = Memory, 2 = Resources, 3 = SubAgents.
Out-of-range indices are silently ignored.
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
let (tx, _) = mpsc::channel(1);
let (_, rx) = mpsc::channel(1);
let mut app = App::new(tx, rx);
app.toggle_panel_collapse(0);
assert!(app.collapsed_panels()[0]);
app.toggle_panel_collapse(0);
assert!(!app.collapsed_panels()[0]);Sourcepub fn collapsed_panels(&self) -> [bool; 4]
pub fn collapsed_panels(&self) -> [bool; 4]
Return the current per-section collapse mask.
Index mapping: 0 = Skills, 1 = Memory, 2 = Resources, 3 = SubAgents.
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
let (tx, _) = mpsc::channel(1);
let (_, rx) = mpsc::channel(1);
let app = App::new(tx, rx);
assert_eq!(app.collapsed_panels(), [false; 4]);Sourcepub fn effective_collapsed(&self) -> [bool; 4]
pub fn effective_collapsed(&self) -> [bool; 4]
Compute the effective collapse mask used for rendering (which content each slot shows, not how many rows it gets — sizing is a crate-internal concern).
A slot’s user-set collapsed_panels pin means “show the single summary row”
regardless of content; unpinned (false) means “auto, content-sized” — the slot
renders its real widget and is sized from that widget’s own desired_height
(pre-#6675 this meant “equal share” via Fill(1); the mask’s own pin/auto
semantics are unchanged).
Index 3 (SubAgents slot) is forced expanded (false) whenever an overlay currently
owns that slot — Fleet, Durable, Settings, Tasks — or the base layer itself is
showing something other than the plain idle list (interactive focus, plan view,
security events). Indices 0–2 pass through the raw collapsed_panels value
unchanged.
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
let (tx, _) = mpsc::channel(1);
let (_, rx) = mpsc::channel(1);
let mut app = App::new(tx, rx);
// Collapsing slot 3 is honoured when no overlay is active.
app.toggle_panel_collapse(3);
assert!(app.effective_collapsed()[3]);Sourcepub fn with_motion(self, motion: Motion) -> Self
pub fn with_motion(self, motion: Motion) -> Self
Configure the animation budget from config.
§Examples
use tokio::sync::mpsc;
use zeph_config::Motion;
use zeph_tui::App;
let (user_tx, _) = mpsc::channel(1);
let (_, agent_rx) = mpsc::channel(1);
let app = App::new(user_tx, agent_rx).with_motion(Motion::Minimal);
assert_eq!(app.motion(), Motion::Minimal);Sourcepub fn wave_tick(&self) -> u64
pub fn wave_tick(&self) -> u64
Return the monotonic wave-tick counter.
Passed as t into crate::widgets::wave::sample / crate::widgets::wave::glyphs.
Sourcepub fn advance_wave_tick(&mut self)
pub fn advance_wave_tick(&mut self)
Advance the wave animation clock by one tick.
Called from the render loop’s internal interval as an animation heartbeat
that is independent of the EventReader’s AppEvent::Ticks, so the
equalizer keeps moving even when the event channel is briefly starved by a
streaming burst. Only the wave counter is advanced here — the throbber and
micro-delights stay driven by AppEvent::Tick.
Sourcepub fn with_delights(self, delights: DelightsConfig) -> Self
pub fn with_delights(self, delights: DelightsConfig) -> Self
Apply micro-delight configuration (#5104).
Called at construction time from tui_bridge to propagate [tui.delights] config.
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
use zeph_config::DelightsConfig;
let (tx, _) = mpsc::channel(1);
let (_, rx) = mpsc::channel(1);
let app = App::new(tx, rx).with_delights(DelightsConfig::default());Sourcepub fn anim_tick(&self) -> u64
pub fn anim_tick(&self) -> u64
Return the current animation tick counter.
Aliased from wave_tick so animation code can read it by an intent-revealing name.
Free-running at ~10fps (100ms/tick via EventReader). Never pauses.
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
let (tx, _) = mpsc::channel(1);
let (_, rx) = mpsc::channel(1);
let app = App::new(tx, rx);
assert_eq!(app.anim_tick(), 0);Sourcepub fn wants_animation_frame(&self) -> bool
pub fn wants_animation_frame(&self) -> bool
Whether any animation-driven feature is currently active.
Provided as an optional future hook for a deferred CPU-optimization issue
(suppress idle redraws when nothing animates). NOT wired to the redraw gate
in this PR — the EventReader already drives 10fps unconditionally.
Sourcepub fn wave_state(&self) -> WaveState
pub fn wave_state(&self) -> WaveState
Derive the current wave animation state from live agent state.
Stalled is checked first so a hung turn never reads as Streaming or Swell.
§Stall behaviour
A slow time-to-first-token > stall_threshold shows Stalled before any token
arrives, because last_progress_at is set when the turn goes busy (Typing/Status)
and the threshold starts counting from that moment. Accepted for v1 simplicity.
Sourcepub fn background_inflight(&self) -> u64
pub fn background_inflight(&self) -> u64
Count in-flight background/external requests for the wave equalizer.
Combines the task-supervisor inflight gauge (bg_inflight — all classes,
already includes enrichment + telemetry) with in-flight background shell
runs. Used by Self::wave_state to drive the violet Network wave and
by the draw loop to keep the equalizer visible while background work runs
even when the agent itself is idle.
Sourcepub fn with_mouse(self, enabled: bool) -> Self
pub fn with_mouse(self, enabled: bool) -> Self
Enable or disable opt-in mouse capture at startup.
Called from the builder chain in tui_bridge when config.tui.mouse is true.
Actual terminal-level capture is enabled after the first frame is drawn
(C3 — avoid delivering mouse events before last_layout is populated).
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
let (tx, _) = mpsc::channel(1);
let (_, rx) = mpsc::channel(1);
let app = App::new(tx, rx).with_mouse(true);
assert!(app.mouse_enabled());Sourcepub fn with_panel_sizing(self, mode: PanelSizingMode) -> Self
pub fn with_panel_sizing(self, mode: PanelSizingMode) -> Self
Set the side-panel sizing strategy at startup (#6675).
Called from the builder chain in tui_bridge with config.tui.panel_sizing.
§Examples
use tokio::sync::mpsc;
use zeph_config::PanelSizingMode;
use zeph_tui::App;
let (tx, _) = mpsc::channel(1);
let (_, rx) = mpsc::channel(1);
let app = App::new(tx, rx).with_panel_sizing(PanelSizingMode::Even);
assert_eq!(app.panel_sizing(), PanelSizingMode::Even);Sourcepub fn panel_sizing(&self) -> PanelSizingMode
pub fn panel_sizing(&self) -> PanelSizingMode
Return the current side-panel sizing strategy.
Sourcepub fn mouse_enabled(&self) -> bool
pub fn mouse_enabled(&self) -> bool
Return true when opt-in mouse capture is currently active.
§Examples
use tokio::sync::mpsc;
use zeph_tui::App;
let (tx, _) = mpsc::channel(1);
let (_, rx) = mpsc::channel(1);
let app = App::new(tx, rx);
assert!(!app.mouse_enabled());Source§impl App
impl App
Sourcepub fn set_view_target(&mut self, target: AgentViewTarget)
pub fn set_view_target(&mut self, target: AgentViewTarget)
Switch the chat view target. Clears render cache and scroll offset. All view changes MUST go through this method (W5).
Sourcepub fn poll_pending_transcript(&mut self)
pub fn poll_pending_transcript(&mut self)
Poll the pending transcript load and install result if ready.
Sourcepub fn visible_messages(&self) -> Vec<ChatMessage>
pub fn visible_messages(&self) -> Vec<ChatMessage>
Returns the messages to display in the chat area.
Always returns an owned Vec — the cost is one clone of at most
MAX_TUI_MESSAGES (2000) ref-counted strings inside ChatMessage.
When viewing a subagent, returns transcript entries converted to ChatMessage.
When no transcript is loaded yet, returns a loading placeholder.
Sourcepub fn transcript_truncation_info(&self) -> Option<String>
pub fn transcript_truncation_info(&self) -> Option<String>
Returns the truncation info string if the transcript was truncated.
Auto Trait Implementations§
impl !RefUnwindSafe for App
impl !UnwindSafe for App
impl Freeze for App
impl Send for App
impl Sync for App
impl Unpin for App
impl UnsafeUnpin for App
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request