#![allow(dead_code)] // Phase 1: methods consumed as screens are implemented //! Full FrankenTUI Model implementation for the lore TUI. //! //! LoreApp is the central coordinator: it owns all state, dispatches //! messages through a 5-stage key pipeline, records crash context //! breadcrumbs, manages async tasks via the supervisor, and routes //! view() to per-screen render functions. mod tests; mod update; use crate::clock::{Clock, SystemClock}; use crate::commands::{CommandRegistry, build_registry}; use crate::crash_context::CrashContext; use crate::db::DbManager; use crate::message::InputMode; use crate::navigation::NavigationStack; use crate::state::AppState; use crate::task_supervisor::TaskSupervisor; // --------------------------------------------------------------------------- // LoreApp // --------------------------------------------------------------------------- /// Root model for the lore TUI. /// /// Owns all state and implements the FrankenTUI Model trait. The /// update() method is the single entry point for all state transitions. pub struct LoreApp { pub state: AppState, pub navigation: NavigationStack, pub supervisor: TaskSupervisor, pub crash_context: CrashContext, pub command_registry: CommandRegistry, pub input_mode: InputMode, pub clock: Box, pub db: Option, } impl LoreApp { /// Create a new LoreApp with default state. /// /// Uses a real system clock and no DB connection (set separately). #[must_use] pub fn new() -> Self { Self { state: AppState::default(), navigation: NavigationStack::new(), supervisor: TaskSupervisor::new(), crash_context: CrashContext::new(), command_registry: build_registry(), input_mode: InputMode::Normal, clock: Box::new(SystemClock), db: None, } } /// Create a LoreApp for testing with a custom clock. #[cfg(test)] fn with_clock(clock: Box) -> Self { Self { clock, ..Self::new() } } } impl Default for LoreApp { fn default() -> Self { Self::new() } }