Files
owlen/docs/tui-ux-playbook.md

179 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 Owlens 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.051.0` |
| `pane_decay` | Decay applied to pulse effects on pane switches. | `0.20.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 Owlens keyboard-first UX remains
predictable, accessible, and discoverable.