diff --git a/CHANGELOG.md b/CHANGELOG.md index 62b3e39..3a05445 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Command palette offers fuzzy `:model` filtering and `:provider` completions for fast switching. - Inline guidance overlay adds a three-step onboarding tour, keymap-aware cheat sheets (F1 / `?`), and persists completion state via `ui.guidance`. - Status surface renders a layered HUD with streaming/tool indicators, contextual gauges, and redesigned toast cards featuring icons, countdown timers, and a compact history log. +- Published a TUI UX & keybinding playbook documenting modal ergonomics, command metadata, theming tokens, and animation policy. - Cloud usage tracker persists hourly/weekly token totals, adds a `:limits` command, shows live header badges, and raises toast warnings at 80 %/95 % of the configured quotas. - Message rendering caches wrapped lines and throttles streaming redraws to keep the TUI responsive on long sessions. - Model picker badges now inspect provider capabilities so vision/audio/thinking models surface the correct icons even when descriptions are sparse. diff --git a/README.md b/README.md index f9ed2e3..fd87bd3 100644 --- a/README.md +++ b/README.md @@ -156,6 +156,7 @@ For more detailed information, please refer to the following documents: - **[docs/repo-map.md](docs/repo-map.md)**: Snapshot of the workspace layout and key crates. - **[docs/provider-implementation.md](docs/provider-implementation.md)**: Trait-level details for implementing providers. - **[docs/adding-providers.md](docs/adding-providers.md)**: Step-by-step checklist for wiring a provider into the multi-provider architecture and test suite. +- **[docs/tui-ux-playbook.md](docs/tui-ux-playbook.md)**: Design principles, modal ergonomics, and keybinding guidance for the TUI. - **Experimental providers staging area**: [crates/providers/experimental/README.md](crates/providers/experimental/README.md) records the placeholder crates (OpenAI, Anthropic, Gemini) and their current status. - **[docs/platform-support.md](docs/platform-support.md)**: Current OS support matrix and cross-check instructions. diff --git a/docs/tui-ux-playbook.md b/docs/tui-ux-playbook.md new file mode 100644 index 0000000..ee2ee1a --- /dev/null +++ b/docs/tui-ux-playbook.md @@ -0,0 +1,178 @@ +# 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.