# Owlen TUI UX & Keybinding Playbook *Last updated: October 25, 2025* This playbook documents the design principles, modal ergonomics, command metadata, theming tokens, and animation policy that guide Owlen’s terminal UI. Use it both as a contributor reference and as a migration guide when extending custom keymaps or UI affordances. --- ## 1. Modal Philosophy Owlen embraces a Vim-inspired modal workflow with discoverability helpers layered on top. | Mode | Entry | Primary Purpose | Escape | |-----------------|------------------------------------------|----------------------------------------------------------------------|--------| | **Normal** | `Esc`, `Ctrl+[`, application start | Navigation, pane switching, command prefixes, leader chords | `i`, `:`, `?`, `F1` | | **Editing** | `i`, `a`, `Enter` in Normal | Compose prompt, multi-line editing, history cycling (`Ctrl+↑/↓`) | `Esc` | | **Visual** | `v` in Normal | Region selection across chat, thinking, and input panes | `Esc`, `v` | | **Command** | `:` | Run palette commands (`:session save`, `:mode code`, `:limits`) | `Esc`, `Enter` | | **Help** | `F1`, `?` | Cheat sheet tabs, onboarding tour | `Esc`, `F1` | | **Browsers** | `:sessions`, `:themes`, repo search keys | Context-specific pickers with shared navigation primitives | `Esc` | Modal transitions fire `AppEvent::Composer::ModeChanged`, enabling keymap state to reset cleanly (see `ChatApp::set_input_mode`). Maintain this flow when adding new modes to avoid orphaned key sequences. ### Focus Shortcuts - `Ctrl+1…5` focus Files, Chat, Code, Thinking, Input (mirrors leader chords). - `Tab` / `Shift+Tab` cycle panes; `g t` toggles Files visibility in Vim keymap. - `Ctrl+Alt+5` (Vim) / `Alt+5` (Emacs) jump back to the input editor. Keep focus hops single-chord and mnemonic. Prefer documenting any new shortcut in the cheat sheet (`render_guidance_cheatsheet`) and the status HUD hints. --- ## 2. Keybinding Design & Migration ### Built-in Profiles - **Vim** (default): stored in [`crates/owlen-tui/keymap.toml`](../crates/owlen-tui/keymap.toml). - **Emacs**: stored in [`crates/owlen-tui/keymap_emacs.toml`](../crates/owlen-tui/keymap_emacs.toml). Switch at runtime via `:keymap vim|emacs`; persist with `ui.keymap_profile = "vim"` or `"emacs"` in `config.toml`. ### Custom Keymaps Set `ui.keymap_path = "/absolute/path/to/keymap.toml"` to override the built-in profiles. The schema matches the shipped TOML files: ```toml [[bindings]] mode = "normal" sequence = ["g", "t"] command = "workspace.toggle_files" ``` **Migration notes (v0.2+)** 1. **Multi-step sequences**: All keymaps now support arbitrary-length sequences (`Ctrl+W`, `w`, `Ctrl+K`, `←`). Update custom maps to the trie syntax if you previously shadowed hard-coded Rust handlers. 2. **Leader remapping**: `ui.keymap_leader` defaults to space. Custom profiles should mirror the new leader sections so the cheat sheet can surface alternate hints (`binding_pair_string`). 3. **Discoverability hooks**: Register new commands in `commands::catalog()` with category, summary, tags, and optional `preview` callback. The command palette relies on this metadata for fuzzy search and tag filtering. 4. **Help overlay**: If you introduce new focus or layout commands, add them to `build_cheatsheet_sections` so onboarding and help stay in sync. Run `cargo test -p owlen-tui --test chat_snapshots` after keymap changes to refresh guidance snapshots. --- ## 3. Command Metadata Schema Located in [`crates/owlen-tui/src/commands/catalog.rs`](../crates/owlen-tui/src/commands/catalog.rs), each command descriptor should populate: - `category`: High-level grouping shown in the palette (`navigation`, `session`, `provider`). - `keywords`: Fuzzy aliases; include verbs (open, focus), nouns (chat, files), and tags (`#agent`). - `key_hint`: Optional string rendered in previews (e.g., `Ctrl+Shift+F`). - `modes`: Restrict availability by `InputMode` when needed (e.g., editing-only commands). - `preview`: Use for sidecar previews (`commands::Preview`), returning lines that explain impact. When adding new commands: 1. Define the handler in `commands::handlers`. 2. Register metadata in `catalog()` and supply tests in `crates/owlen-tui/tests/state_tests.rs` or palette-specific snapshots. 3. Update the cheat sheet if the command introduces a new focus or mode affordance. --- ## 4. Theming & Layer Tokens Themes live in `owlen_core::theme`. The TUI applies a glass/neon layer via `GlassPalette::for_theme_with_mode` using `config.ui.layers`: | Setting | Default | Description | |--------------------------|---------|----------------------------------------------------------| | `shadow_elevation` | `2` | Depth of drop shadow around the chat stage. | | `glass_tint` | `0.82` | Opacity mix between base theme background and frosted layer. | | `neon_intensity` | `60` | Percentage controlling accent saturation. | | `focus_ring` | `true` | Draws neon outlines around the active stage container. | **Best practices** - Keep contrasts AA+; avoid low-alpha custom tints when `accessibility_high_contrast = true`. - Re-render custom palettes through the snapshot suite to catch regression diffs. --- ## 5. Animation Policy Controlled by `config.ui.animations`: | Field | Effect | Range | |--------------------|--------------------------------------------------|------------| | `micro` | Enables pane glow, gauge easing, mode flash. | `true/false` | | `gauge_smoothing` | Exponential smoothing factor for usage gauges. | `0.05–1.0` | | `pane_decay` | Decay applied to pulse effects on pane switches. | `0.2–0.95` | Accessibility flags (`ui.accessibility.high_contrast`, `ui.accessibility.reduced_chrome`) automatically disable micro animations. When adding new animations: 1. Guard with `ChatApp::micro_animations_enabled()`. 2. Provide non-animated fallbacks (e.g., direct gauge `snap`). 3. Update documentation and consider adding snapshot coverage under both animated and non-animated configurations. --- ## 6. Status Surface & Toasts The status HUD (`render_status`) now renders three columns: 1. **Left**: Mode/operating badges, focus hints, agent state, help shortcuts. 2. **Center**: Primary status message with auto-leveled badge (info/success/warning/error) and contextual usage gauges. 3. **Right**: Repository/path summary, provider & model badge, streaming hints, and toast history. Toast enhancements: - Icons per severity (`ⓘ`, `✔`, `⚠`, `✖`). - Optional keyboard hints via `push_toast_with_hint`. - Progress bar countdown plus remaining seconds. - Persistent history (20 entries) exposed to the HUD for quick recall. **Guidelines** - Provide actionable hints (e.g., `"F12 · Debug log"`, `":limits"`). - Reserve `ToastLevel::Error` for recoverable issues the user must address. - Use status primary line for the most recent action; employ `system_status` for secondary context. --- ## 7. Contributor Checklist When modifying TUI UX or keybindings: 1. Update this playbook if the change affects modal ergonomics, theming tokens, animation policy, or keymap conventions. 2. Extend the cheat sheet / onboarding overlays for new focus or command shortcuts. 3. Refresh snapshots: `INSTA_UPDATE=always cargo test -p owlen-tui --test chat_snapshots`. 4. Run `cargo clippy -p owlen-tui -- -D warnings` and the `owlen-tui` test suite. 5. Document user-facing changes in `CHANGELOG.md`. Keeping these steps in sync ensures Owlen’s keyboard-first UX remains predictable, accessible, and discoverable.