feat(tui): Phase 3 power features — Who, Search, Timeline, Trace, File History screens

Complete TUI Phase 3 implementation with all 5 power feature screens:

- Who screen: 5 modes (expert/workload/reviews/active/overlap) with
  mode tabs, input bar, result rendering, and hint bar
- Search screen: full-text search with result list and scoring display
- Timeline screen: chronological event feed with time-relative display
- Trace screen: file provenance chains with expand/collapse, rename
  tracking, and linked issues/discussions
- File History screen: per-file MR timeline with rename chain display
  and discussion snippets

Also includes:
- Command palette overlay (fuzzy search)
- Bootstrap screen (initial sync flow)
- Action layer split from monolithic action.rs to per-screen modules
- Entity and render cache infrastructure
- Shared who_types module in core crate
- All screens wired into view/mod.rs dispatch
- 597 tests passing, clippy clean (pedantic + nursery), fmt clean
This commit is contained in:
teernisse
2026-02-18 22:56:24 -05:00
parent f8d6180f06
commit fb40fdc677
44 changed files with 14650 additions and 2905 deletions

View File

@@ -31,6 +31,10 @@ pub mod view; // View layer: render_screen + common widgets (bd-26f2)
pub mod action; // Data-fetching actions for TUI screens (bd-35g5+)
pub mod filter_dsl; // Filter DSL tokenizer for list screen filter bars (bd-18qs)
// Phase 4 modules.
pub mod entity_cache; // Bounded LRU entity cache for detail view reopens (bd-2og9)
pub mod render_cache; // Bounded render cache for expensive per-frame computations (bd-2og9)
/// Options controlling how the TUI launches.
#[derive(Debug, Clone)]
pub struct LaunchOptions {
@@ -52,6 +56,14 @@ pub struct LaunchOptions {
///
/// Loads config from `options.config_path` (or default location),
/// opens the database read-only, and enters the FrankenTUI event loop.
///
/// ## Preflight sequence
///
/// 1. **Schema preflight** — validate the database schema version before
/// creating the app. If incompatible, print an actionable error and exit
/// with a non-zero code.
/// 2. **Data readiness** — check whether the database has any entity data.
/// If empty, start on the Bootstrap screen; otherwise start on Dashboard.
pub fn launch_tui(options: LaunchOptions) -> Result<()> {
let _options = options;
// Phase 1 will wire this to LoreApp + App::fullscreen().run()
@@ -59,6 +71,30 @@ pub fn launch_tui(options: LaunchOptions) -> Result<()> {
Ok(())
}
/// Run the schema preflight check.
///
/// Returns `Ok(())` if the schema is compatible, or an error with an
/// actionable message if it's not. The caller should exit non-zero on error.
pub fn schema_preflight(conn: &rusqlite::Connection) -> Result<()> {
use state::bootstrap::SchemaCheck;
match action::check_schema_version(conn, action::MINIMUM_SCHEMA_VERSION) {
SchemaCheck::Compatible { .. } => Ok(()),
SchemaCheck::NoDB => {
anyhow::bail!(
"No lore database found.\n\
Run 'lore init' to create a config, then 'lore sync' to fetch data."
);
}
SchemaCheck::Incompatible { found, minimum } => {
anyhow::bail!(
"Database schema version {found} is too old (minimum: {minimum}).\n\
Run 'lore migrate' to upgrade, or 'lore sync' to rebuild."
);
}
}
}
/// Launch the TUI with an initial sync pass.
///
/// Runs `lore sync` in the background while displaying a progress screen,