# TUI Orchestrator - Complete TUI Framework ## Overview `tui_orchestrator` is a **ready-to-use TUI framework** that provides a complete runtime for building terminal user interfaces. Users define their pages, buttons, and logic—library handles everything else: input routing, focus management, page navigation, lifecycle hooks, and event orchestration. ### Key Philosophy **"Register pages with buttons and logic—it just works."** The library is a **complete application framework** where: - User defines components (pages with focusable elements) - Library orchestrates all runtime concerns - Everything is optional—define what you need - Fully extendable for complex apps like komp_ac ### Zero Boilerplate Users write: ```rust impl Component for LoginPage { fn targets(&self) -> &[Focus]; fn handle(&mut self, focus: &Focus, action: Action) -> Result> { // What happens when button pressed } } ``` Library handles: - Input processing - Focus management - Page navigation - Lifecycle hooks - Event routing - Default keybindings ### Extension Model komp_ac can use the library for 90% of functionality while extending: - Mode resolution (dynamic Canvas-style modes) - Overlay management (command palette, find file, search) - Event routing (global vs page vs canvas actions) - Custom behaviors (boundary detection, navigation rules) **Defaults work, override what's different.** --- ## Architecture ``` ┌─────────────────────────────────────────────────┐ │ User Code (What You Define) │ │ │ │ Component trait │ │ - Page structs/enums │ │ - Focus targets (buttons, fields) │ │ - Button logic (what happens on press) │ │ - Lifecycle hooks (optional) │ └─────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────┐ │ Orchestrator (Library Runtime) │ │ │ │ - ComponentRegistry │ │ - FocusManager │ │ - Bindings (default + custom) │ │ - Router + history │ │ - ModeStack │ │ - OverlayStack │ │ - EventBus │ └─────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────┐ │ Extension Points (For komp_ac) │ │ │ │ - ModeResolver (dynamic mode resolution) │ │ - OverlayManager (custom overlay types) │ │ - EventHandler (custom event routing) │ │ - FocusNavigation (boundary detection) │ └─────────────────────────────────────────────────┘ ``` --- ## Implementation Phases ### Phase 1: Core Foundation ✅ COMPLETE **Completed:** - `src/input/` - Key types, bindings, sequence handling - `src/focus/` - Focus manager, queries, traits **What this provides:** - Backend-agnostic key representation - Key-to-action mappings - Focus tracking with navigation - Generic focus IDs (user-defined enums, `usize`, `String`, etc.) --- ### Phase 2: Component System (CURRENT) **Goal:** Unified abstraction for pages/components. **Files to create:** - `src/component/mod.rs` - Component trait - `src/component/action.rs` - Standard component actions - `src/component/error.rs` - Component-specific errors **Component Trait:** ```rust pub trait Component { type Focus: FocusId + Clone; type Action: Action + Clone; type Event: Clone + core::fmt::Debug; fn targets(&self) -> &[Self::Focus]; fn handle(&mut self, focus: &Self::Focus, action: Self::Action) -> Result>; fn on_enter(&mut self) -> Result<()> { Ok(()) } fn on_exit(&mut self) -> Result<()> { Ok(()) } fn on_focus(&mut self, focus: &Self::Focus) -> Result<()> { Ok(()) } fn on_blur(&mut self, focus: &Self::Focus) -> Result<()> { Ok(()) } fn handle_text(&mut self, focus: &Self::Focus, ch: char) -> Result> { Ok(None) } fn can_navigate_forward(&self, focus: &Self::Focus) -> bool { true } fn can_navigate_backward(&self, focus: &Self::Focus) -> bool { true } } ``` **Standard Component Actions:** ```rust pub enum ComponentAction { Next, // Tab by default Prev, // Shift+Tab by default First, Last, Select, // Enter by default Cancel, // Esc by default TypeChar(char), Backspace, Delete, Custom(usize), // User extension } ``` --- ### Phase 3: Router & Lifecycle **Goal:** Page navigation with automatic lifecycle hooks. **Files to create:** - `src/router/mod.rs` - Router trait and implementation - `src/router/history.rs` - Navigation history **Router API:** ```rust pub struct Router { pages: alloc::collections::HashMap, current: Option, history: alloc::vec::Vec, } impl Router { pub fn new() -> Self; pub fn navigate(&mut self, id: &str) -> Result<()>; pub fn back(&mut self) -> Result>; pub fn forward(&mut self) -> Result>; pub fn current(&self) -> Option<&C>; } ``` **Automatic behavior:** - `navigate()` calls `old_page.on_exit()` → swaps page → calls `new_page.on_enter()` - `back()`/`forward()` manage history stack - Focus targets auto-updated from `targets()` --- ### Phase 4: Orchestrator (The Core Runtime) **Goal:** Wire everything together into complete TUI runtime. **Files to create:** - `src/orchestrator/mod.rs` - Orchestrator struct - `src/orchestrator/modes.rs` - Mode stack and resolution - `src/orchestrator/overlays.rs` - Overlay stack - `src/orchestrator/events.rs` - Event bus - `src/orchestrator/bindings.rs` - Default + custom bindings **Orchestrator API:** ```rust pub struct Orchestrator { registry: ComponentRegistry, focus: FocusManager, bindings: Bindings, router: Router, modes: ModeStack, overlays: OverlayStack, events: EventBus, } impl Orchestrator { pub fn new() -> Self; pub fn register_page(&mut self, id: &str, page: C) -> Result<()>; pub fn navigate_to(&mut self, id: &str) -> Result<()>; pub fn process_frame(&mut self, key: Key) -> Result>; pub fn run(&mut self, input: I) -> Result<()>; // Extension points pub fn set_mode_resolver(&mut self, resolver: R); pub fn set_overlay_manager(&mut self, manager: O); pub fn set_event_handler + 'static>(&mut self, handler: H); } ``` **Process flow:** 1. Check overlay active → route to overlay 2. Get current mode + focus 3. Lookup binding → get action 4. Get current component 5. Call `component.handle(action, focus)` 6. Collect events returned 7. Handle internal events (focus changes, page nav) 8. Return external events to user --- ### Phase 5: Extension Traits **Goal:** Provide extension points for komp_ac's custom behavior. **Files to create:** - `src/extension/mod.rs` - Extension traits - `src/extension/mode.rs` - Mode resolver - `src/extension/overlay.rs` - Overlay manager - `src/extension/event.rs` - Event handler **ModeResolver (for dynamic mode resolution):** ```rust pub trait ModeResolver { fn resolve(&self, focus: &dyn core::any::Any) -> alloc::vec::Vec; } pub struct DefaultModeResolver; impl ModeResolver for DefaultModeResolver { fn resolve(&self, _focus: &dyn core::any::Any) -> alloc::vec::Vec { alloc::vec![ModeName::General] } } ``` **OverlayManager (for custom overlays):** ```rust pub trait OverlayManager { fn is_active(&self) -> bool; fn handle_input(&mut self, key: Key) -> Option; } pub enum OverlayResult { Dismissed, Selected(OverlayData), Continue, } ``` **EventHandler (for custom event routing):** ```rust pub trait EventHandler { fn handle(&mut self, event: E) -> Result; } pub enum HandleResult { Consumed, Forward, Navigate(String), } ``` --- ### Phase 6: Builder & Defaults **Goal:** Easy setup with sensible defaults. **Files to create:** - `src/builder/mod.rs` - Builder pattern - `src/defaults/bindings.rs` - Preset keybindings **Builder API:** ```rust impl Orchestrator { pub fn builder() -> Builder { Builder::new() } } pub struct Builder { orchestrator: Orchestrator, } impl Builder { pub fn with_page(mut self, id: &str, page: C) -> Result; pub fn with_default_bindings(mut self) -> Self; pub fn with_mode_resolver(mut self, resolver: R) -> Self; pub fn with_overlay_manager(mut self, manager: O) -> Self; pub fn build(self) -> Result>; } ``` **Default bindings:** ```rust pub fn default_bindings() -> Bindings { let mut bindings = Bindings::new(); bindings.bind(Key::tab(), ComponentAction::Next); bindings.bind(Key::shift_tab(), ComponentAction::Prev); bindings.bind(Key::enter(), ComponentAction::Select); bindings.bind(Key::esc(), ComponentAction::Cancel); bindings.bind(Key::ctrl('c'), ComponentAction::Custom(0)); // Quit } ``` --- ### Phase 7: Integration (Optional) **Goal:** Seamless integration with komp_ac. **Files to create:** - `src/integration/mod.rs` - Integration helpers - `src/integration/komp_ac.rs` - komp_ac-specific adapters **Adapter pattern:** ```rust impl Component for komp_ac::LoginPage { type Focus = komp_ac::FocusTarget; type Action = komp_ac::ResolvedAction; type Event = komp_ac::AppEvent; fn targets(&self) -> &[Self::Focus] { ... } fn handle(&mut self, focus: &Self::Focus, action: Self::Action) -> Result> { ... } } ``` --- ## File Structure ``` src/ ├── lib.rs # Routing only, re-exports ├── prelude.rs # Common imports │ ├── input/ # Phase 1 ✅ │ ├── mod.rs │ ├── key.rs # KeyCode, KeyModifiers │ ├── bindings.rs # Bindings │ ├── handler.rs # InputHandler │ ├── result.rs # MatchResult │ └── action.rs # Action trait │ ├── focus/ # Phase 1 ✅ │ ├── mod.rs │ ├── id.rs # FocusId trait │ ├── manager.rs # FocusManager │ ├── query.rs # FocusQuery │ ├── error.rs # FocusError │ └── traits.rs # Focusable │ ├── component/ # Phase 2 │ ├── mod.rs │ ├── trait.rs # Component trait │ ├── action.rs # ComponentAction │ └── error.rs # ComponentError │ ├── router/ # Phase 3 │ ├── mod.rs │ ├── router.rs # Router │ └── history.rs # HistoryStack │ ├── orchestrator/ # Phase 4 │ ├── mod.rs │ ├── core.rs # Orchestrator │ ├── modes.rs # ModeStack, ModeResolver │ ├── overlays.rs # OverlayStack │ ├── bindings.rs # Component bindings │ └── events.rs # EventBus │ ├── extension/ # Phase 5 │ ├── mod.rs │ ├── mode.rs # ModeResolver trait │ ├── overlay.rs # OverlayManager trait │ └── event.rs # EventHandler trait │ ├── builder/ # Phase 6 │ ├── mod.rs │ ├── builder.rs # Builder pattern │ └── defaults.rs # Default bindings │ └── integration/ # Phase 7 ├── mod.rs └── komp_ac.rs # komp_ac adapters tests/ # Mirror src/ structure ├── input/ ├── focus/ ├── component/ ├── router/ ├── orchestrator/ └── integration/ ``` --- ## Design Principles ### From AGENTS.md - **Feature-based tree structure**—group by domain - **Each feature is self-contained**—handler, logic, types, tests - **Functional programming style**—pure functions, stateless where possible - **Use structs, traits, enums, impl, match** over if - **No Arc/Mutex/RefCell** - **Result everywhere** - **mod.rs is for routing only** - **No comments unless necessary** ### Additional for Framework - **Batteries included**—not just building blocks - **Sensible defaults**—zero configuration works - **Optional everything**—define only what you need - **Extension points**—override defaults when needed - **no_std compatible**—works on embedded, WASM - **Backend-agnostic**—no crossterm/ratatui dependencies - **User-focused**—"register page" not "register_chord" --- ## Dependencies ### Core (no_std) - `alloc` - For dynamic collections (Vec, HashMap) ### Optional Features - `std` - Enable std library support - `sequences` - Enable multi-key sequences --- ## User Experience ### Before (Building Blocks) Users must manually wire everything: - Create focus manager - Create bindings - Create router - Set up components - Write main loop - Handle lifecycle manually **Result:** Lots of boilerplate, easy to get wrong. ### After (Framework) Users define components and run: ```rust #[derive(Debug, Clone)] struct LoginPage; impl Component for LoginPage { fn targets(&self) -> &[Focus] { ... } fn handle(&mut self, focus: &Focus, action: Action) -> Result> { ... } } fn main() -> Result<()> { let mut orch = Orchestrator::new(); orch.register_page("login", LoginPage::new())?; orch.run()?; } ``` **Result:** Zero boilerplate, everything just works. --- ## Migration for komp_ac ### Before Integration komp_ac has: - Custom orchestrator - Custom mode resolution (Canvas-style) - Custom overlays (command bar, find file, search) - Custom action routing (page vs canvas vs global) ### After Integration komp_ac: 1. Implements `Component` trait for all pages 2. Uses library's `Orchestrator` as runtime 3. Extends with custom `ModeResolver` 4. Extends with custom `OverlayManager` 5. Extends with custom `EventHandler` **Result:** - Library handles 90% of runtime - komp_ac keeps all custom behavior - No code duplication - Cleaner, more maintainable codebase --- ## Feature Checklist - [x] Phase 1: Input handling (keys, bindings, focus) - [ ] Phase 2: Component trait and actions - [ ] Phase 3: Router with lifecycle - [ ] Phase 4: Orchestrator runtime - [ ] Phase 5: Extension traits - [ ] Phase 6: Builder and defaults - [ ] Phase 7: Integration with komp_ac - [ ] Documentation updates - [ ] Example applications - [ ] Full test coverage