pub struct App {Show 38 fields
pub prompt: PromptInputState,
pub blocks: Vec<TranscriptBlock>,
pub should_quit: bool,
pub session_id: Option<String>,
pub connected: bool,
pub scroll_offset: u16,
pub screen: AppScreen,
pub start_time: Instant,
pub usage: UsageStats,
pub turn: TurnState,
pub turn_count: u64,
pub pending_latency_ms: Option<u64>,
pub model_name: String,
pub spinner_frame: usize,
pub modals: Vec<Modal>,
pub commands: CommandRegistry,
pub tool_catalog: Vec<(String, String)>,
pub command_menu_selected: Option<usize>,
pub planning_mode_on: bool,
pub plan_awaiting_approval: bool,
pub plan_mode_request_pending: bool,
pub double_press: DoublePressTracker,
pub atfile_query: String,
pub atfile_suggestions: Vec<String>,
pub atfile_selected: Option<usize>,
pub hsearch_query: String,
pub hsearch_matches: Vec<usize>,
pub hsearch_selected: usize,
pub pending_permission: Option<PendingPermission>,
pub auto_allowed_tools: HashSet<String>,
pub permission_hook_enabled: Arc<AtomicBool>,
pub current_todos: Vec<TodoItem>,
pub active_goal: Option<GoalState>,
pub workspace_path: PathBuf,
pub theme: &'static Theme,
pub last_printed_idx: usize,
pub print_queue: Vec<Vec<Line<'static>>>,
pub modal_scroll: u16,
}Fields§
§prompt: PromptInputStateMulti-mode input state (Goal 145).
blocks: Vec<TranscriptBlock>§should_quit: bool§session_id: Option<String>§connected: bool§scroll_offset: u16§screen: AppScreen§start_time: InstantTracks when the TUI session started. Used by /status to report uptime.
usage: UsageStats§turn: TurnState§turn_count: u64§pending_latency_ms: Option<u64>§model_name: String§spinner_frame: usize§modals: Vec<Modal>Goal-146: stack of overlay modals. The topmost (last) modal receives keys; an empty stack means chat keys are active.
commands: CommandRegistryGoal-146: registry of /-prefixed slash commands. Lazily
initialised in App::new with [CommandRegistry::default_set].
tool_catalog: Vec<(String, String)>Goal-146: list of tools the runtime has registered. Populated
by main.rs from Backend::tool_specs() after the worker
boots, and read by the /tools command. Defaults to a static
list when running offline.
Goal-146: cursor / selected index into the command-menu
completion popup. None means the user hasn’t navigated
(Enter executes the literal buffer).
planning_mode_on: boolGoal-146: planning-mode flag mirrored on the UI side. Reflects
the latest /plan on|off invocation. Used to render an
indicator and to seed /status.
plan_awaiting_approval: boolSet when the agent has proposed a plan via exit_plan_mode and we are
waiting for the user to approve or reject it. Cleared by
PlanConfirmed / PlanRejected events. Used to show a status-bar
indicator so the user knows input is expected.
plan_mode_request_pending: boolGoal-202: set when the agent has called request_plan_mode and we are
waiting for the user to allow or skip planning. Cleared by
PlanModeApproved / PlanModeRejected events.
double_press: DoublePressTrackerGoal-147: tracks the most recent Esc / Ctrl+C presses so the
second press within double_press_window can promote a soft
action (interrupt / clear) into a real exit. See
App::handle_key.
atfile_query: StringThe text the user has typed after @ while in AtFile mode.
atfile_suggestions: Vec<String>Candidate file paths matching [atfile_query]. Refreshed on
every keystroke in AtFile mode. Contains at most
MAX_ATFILE_SUGGESTIONS entries.
atfile_selected: Option<usize>Currently highlighted row in the AtFile popup. None means
nothing is highlighted yet (typing narrows the list).
hsearch_query: StringCurrent search query in HistorySearch mode.
hsearch_matches: Vec<usize>Indices into prompt.history that match [hsearch_query],
in priority order (prefix matches first). Capped at
MAX_HSEARCH_RESULTS.
hsearch_selected: usizeCurrently highlighted row in the history-search popup.
pending_permission: Option<PendingPermission>A pending tool-permission request delivered from the backend
worker via the side-channel. None means no permission dialog
is open. When Some, the modal is rendered and all keys are
routed to handle_permission_key.
auto_allowed_tools: HashSet<String>Set of tool names the user has chosen to “Allow All” for the current session. Requests for these tools skip the modal.
permission_hook_enabled: Arc<AtomicBool>Whether the runtime permission hook is currently active.
Toggled by /permissions on|off. Shared with the backend worker.
current_todos: Vec<TodoItem>Goal-167: current task list maintained by todo_write calls.
Empty when no task list has been set this session.
active_goal: Option<GoalState>Goal-168: mirrored goal state, updated by UiEvent::Goal* events.
workspace_path: PathBufGoal-171: workspace root path, used by /resume to list sessions.
theme: &'static ThemeGoal-174: active colour palette. Defaults to [DARK]; switchable
via /theme <name> without restart.
last_printed_idx: usizeBlocks from self.blocks[0..last_printed_idx] have already been
flushed to the terminal’s scrollback buffer via
terminal.insert_before(). The inline viewport only renders
blocks at index >= last_printed_idx (in-flight content).
print_queue: Vec<Vec<Line<'static>>>Queue of rendered lines waiting to be pushed to the scrollback
buffer in the next event-loop iteration. Drained by the main
loop using terminal.insert_before().
modal_scroll: u16Vertical scroll offset (in lines) for the currently-active modal. Reset to 0 whenever a new modal is pushed. For list-based modals (ResumePicker, McpServers, Journal) the key handler auto-updates this to keep the selection visible.
Implementations§
Source§impl App
impl App
Sourcepub fn handle_key(&mut self, key: KeyEvent) -> Option<UserAction>
pub fn handle_key(&mut self, key: KeyEvent) -> Option<UserAction>
Process one key event. Returns an optional UserAction that
the caller must forward to the backend worker.
Handle a key in command-completion-menu context. Returns
Some(action) (with action itself optional) if the key was
consumed; the outer None means “fall through to the regular
chat key path”.
Sourcepub fn handle_atfile_key(&mut self, key: KeyEvent) -> Option<UserAction>
pub fn handle_atfile_key(&mut self, key: KeyEvent) -> Option<UserAction>
Handle a key when InputMode::AtFile is active.
Sourcepub fn handle_history_search_key(&mut self, key: KeyEvent) -> Option<UserAction>
pub fn handle_history_search_key(&mut self, key: KeyEvent) -> Option<UserAction>
Handle a key when InputMode::HistorySearch is active.
Sourcepub fn handle_permission_key(&mut self, key: KeyEvent) -> Option<UserAction>
pub fn handle_permission_key(&mut self, key: KeyEvent) -> Option<UserAction>
Handle a key while a permission modal is active.
y/Y/Enter→ allow oncen/N/Esc→ denya/A→ allow + add tool to auto-allow list
Sourcepub fn handle_modal_key_action(&mut self, key: KeyEvent) -> Option<UserAction>
pub fn handle_modal_key_action(&mut self, key: KeyEvent) -> Option<UserAction>
Handle a key event when at least one modal is on the stack.
Returns Some(action) if the modal layer wants to forward a
UserAction to the backend (currently only the PlanReview
modal does this). The outer key dispatcher should not also
process this key against the chat layer.
Sourcepub fn handle_modal_key(&mut self, key: KeyEvent) -> bool
pub fn handle_modal_key(&mut self, key: KeyEvent) -> bool
Handle a key event when at least one modal is on the stack.
Returns true if the key was consumed by the modal layer
(so the caller should skip the chat key path).
Source§impl App
impl App
Sourcepub fn handle_ui_event(&mut self, event: UiEvent)
pub fn handle_ui_event(&mut self, event: UiEvent)
Apply an event coming from the backend worker.
Sourcepub fn flush_ready_blocks(&mut self)
pub fn flush_ready_blocks(&mut self)
Scan blocks[last_printed_idx..] and push any “finalized”
blocks into print_queue so the main loop can flush them to
the terminal’s scrollback buffer via terminal.insert_before().
A block is considered finalized when:
User— alwaysAssistant— when!streamingToolCall— whenresult.is_some()Reasoning— only when the immediately following block is NOT a streamingAssistant(prevents the reasoning from being separated from its answer in the scrollback)- All other variants — always
This is idempotent and safe to call after every event.
Source§impl App
impl App
pub fn new() -> Self
Sourcepub fn push_modal(&mut self, modal: Modal)
pub fn push_modal(&mut self, modal: Modal)
Push a modal onto the stack and reset the modal scroll to the top.
Sourcepub fn input(&self) -> &str
pub fn input(&self) -> &str
Backwards-compat shim for legacy code paths that still expect
a single input string. Reads the prompt buffer.
Sourcepub fn set_input<S: Into<String>>(&mut self, value: S)
pub fn set_input<S: Into<String>>(&mut self, value: S)
Replace the prompt buffer (used by PlanReview’s e-edit path
and a handful of unit tests). Resets cursor to end and mode to
Prompt.
pub fn scroll_to_bottom(&mut self)
Sourcepub fn push_system(&mut self, text: impl Into<String>)
pub fn push_system(&mut self, text: impl Into<String>)
Push a System block onto the transcript and scroll to bottom.
Public so [crate::commands] handlers can use it directly.
Sourcepub fn push_error(&mut self, text: impl Into<String>)
pub fn push_error(&mut self, text: impl Into<String>)
Push an Error block onto the transcript and scroll to bottom.
Sourcepub fn reset_transcript(&mut self)
pub fn reset_transcript(&mut self)
Reset the transcript to a single fresh welcome block and zero
out per-session usage. Called by /clear.
Sourcepub fn set_pending_permission(&mut self, req: PermissionRequest)
pub fn set_pending_permission(&mut self, req: PermissionRequest)
Receive a pending permission request from the backend side-channel.
Auto-allow if the tool is in the auto_allowed_tools set;
otherwise store it so the UI can display the modal on the next render.
Trait Implementations§
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<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
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 more