Builds the ratatui TUI: EngineHandle bridging the async engine to the render loop, chat viewport rendering with a markdown renderer, input handling, a permission modal wired to the real oneshot ask path, and a session picker. Adds TestBackend snapshot tests covering empty session, tool cards (running/completed/error), permission modal, session picker, and message rendering.
39 lines
1.3 KiB
Rust
39 lines
1.3 KiB
Rust
//! Modal helpers for permission dialogs and the session picker.
|
|
//!
|
|
//! Rendering lives in `render.rs`; key handling lives in `input.rs`. This module
|
|
//! provides shared utilities for modal state transitions.
|
|
|
|
use harness_app::EngineHandle;
|
|
use harness_core::permission::PermissionReply;
|
|
use harness_core::types::Session;
|
|
|
|
use crate::state::{AppState, ModalState};
|
|
|
|
/// Resolve the current permission request with `reply`.
|
|
pub fn resolve_permission(state: &mut AppState, engine: &EngineHandle, reply: PermissionReply) {
|
|
state.handle_permission_reply(reply, engine);
|
|
}
|
|
|
|
/// Open the session picker with the supplied sessions.
|
|
pub fn open_session_picker(state: &mut AppState, sessions: Vec<Session>) {
|
|
state.open_session_picker(sessions);
|
|
}
|
|
|
|
/// Load a session's messages and parts into state.
|
|
pub async fn select_session(
|
|
state: &mut AppState,
|
|
engine: &EngineHandle,
|
|
session: Session,
|
|
) -> Result<(), harness_app::AppError> {
|
|
let session_id = session.id.clone();
|
|
let messages = engine.session_messages(session_id).await?;
|
|
let mut all_parts = Vec::new();
|
|
for message in &messages {
|
|
let parts = engine.message_parts(message.id.clone()).await?;
|
|
all_parts.extend(parts);
|
|
}
|
|
state.set_session(session, messages, all_parts);
|
|
state.modal = ModalState::None;
|
|
Ok(())
|
|
}
|