110 lines
5.6 KiB
Markdown
110 lines
5.6 KiB
Markdown
# TUI MVU Migration Guide
|
||
|
||
This guide explains how we are migrating the Owlen terminal UI to a predictable **Model–View–Update (MVU)** architecture. Use it to understand the current layout, decide where new logic belongs, and track which features have already moved to the MVU core.
|
||
|
||
---
|
||
|
||
## Goals
|
||
|
||
- Make UI state transitions pure and testable.
|
||
- Reduce duplicated control flow inside `chat_app.rs`.
|
||
- Keep rendering functions dumb; they should depend on read-only view models.
|
||
- Ensure new features land in MVU-first form so the imperative paths shrink over time.
|
||
|
||
Adopt the checklist below whenever you touch a feature that still lives in the imperative code path.
|
||
|
||
---
|
||
|
||
## Module Map (owlen-tui)
|
||
|
||
| Area | Path | Responsibility | MVU Status |
|
||
| --- | --- | --- | --- |
|
||
| Core state | `src/app/mvu.rs` | Shared `AppModel`, `AppEvent`, `AppEffect` definitions | **Ready** – composer + consent events implemented |
|
||
| Legacy app | `src/chat_app.rs` | Orchestrates IO, manages pending tasks, renders via ratatui | **Transitioning** – increasingly delegates to MVU |
|
||
| Event loop | `src/app/handler.rs` | Converts session messages into app updates | Needs cleanup once message flow is MVU aware |
|
||
| Rendering | `src/ui.rs` + `src/widgets/*` | Pure rendering helpers that pull data from `ChatApp` | Already read-only; keep that invariant |
|
||
| Commands | `src/commands/*` | Keymap and palette command registry | Candidate for MVU once palette state migrates |
|
||
| Shared state | `src/state/*` | Small state helpers (command palette, file tree, etc.) | Each module can become an MVU sub-model |
|
||
|
||
Use the table to find the right starting point before adding new events.
|
||
|
||
---
|
||
|
||
## Event Taxonomy
|
||
|
||
Current events live in `app/mvu.rs`.
|
||
|
||
- `AppEvent::Composer` – covers draft changes, mode switches, submissions.
|
||
- `AppEvent::ToolPermission` – bridges consent dialog choices back to the controller.
|
||
|
||
`AppEffect` represents side effects the imperative shell must execute:
|
||
|
||
- `SetStatus` – surface validation failures.
|
||
- `RequestSubmit` – hand control back to the async send pipeline.
|
||
- `ResolveToolConsent` – notify the session controller of user decisions.
|
||
|
||
### Adding a new feature
|
||
|
||
1. Extend `AppModel` with the new view state.
|
||
2. Create a dedicated event enum (e.g. `PaletteEvent`) and nest it under `AppEvent`.
|
||
3. Add pure update logic that mutates the model and returns zero or more effects.
|
||
4. Handle emitted effects inside `ChatApp::handle_app_effects`.
|
||
|
||
Keep the event names UI-centric. Provider-side actions should remain in `owlen-core`.
|
||
|
||
---
|
||
|
||
## Feature Migration Checklist
|
||
|
||
| Feature | Scope | MVU tasks | Status |
|
||
| --- | --- | --- | --- |
|
||
| Composer (input buffer) | Draft text, submission workflow | ✅ `ComposerModel`, `ComposerEvent`, `SubmissionOutcome` | ✅ Complete |
|
||
| Tool consent dialog | Approval / denial flow | ✅ `AppEvent::ToolPermission`, `AppEffect::ResolveToolConsent` | ✅ Complete |
|
||
| Chat timeline | Message ordering, cursor, scrollback | Model struct for timeline + events for history updates | ☐ TODO |
|
||
| Thinking pane | Agent reasoning text, auto-scroll | Model + event to toggle visibility and append lines | ☐ TODO |
|
||
| Model picker | Filters, search, selection | Convert `ModelSelectorItem` list + search metadata into MVU | ☐ TODO |
|
||
| Command palette | Suggestions, history, apply actions | Move palette state into `AppModel` and surface events | ☐ TODO |
|
||
| File workspace | Pane layout, file tree focus | Represent pane tree in MVU, drive focus + resize events | ☐ TODO |
|
||
| Toasts & status bar | Transient notifications | Consider MVU-managed queue with explicit events | ☐ TODO |
|
||
|
||
When you pick up one of the TODO rows, document the plan in the PR description and link back to this table.
|
||
|
||
---
|
||
|
||
## Migration Playbook
|
||
|
||
1. **Inventory state** – list every field in `ChatApp` that your feature touches.
|
||
2. **Define view model** – move the persistent state into `AppModel` (or a new sub-struct).
|
||
3. **Write events** – describe all user intents and background updates as `AppEvent` variants.
|
||
4. **Translate side effects** – whenever the update logic needs to call into async code, emit an `AppEffect`. Handle it inside `handle_app_effects`.
|
||
5. **Refactor call sites** – replace direct mutations with `apply_app_event` calls.
|
||
6. **Write tests** – cover the pure update function with table-driven unit tests.
|
||
7. **Remove duplicates** – once the MVU path handles everything, delete the legacy branch in `chat_app.rs`.
|
||
|
||
This flow keeps commits reviewable and avoids breaking the live UI during migration.
|
||
|
||
---
|
||
|
||
## Testing Guidance
|
||
|
||
- **Unit tests** – cover the pure update functions inside `app/mvu.rs`.
|
||
- **Integration tests** – add scenarios to `crates/owlen-tui/tests/agent_flow_ui.rs` when side effects change.
|
||
- **Golden behaviour** – ensure the ratatui renderers still consume read-only data; add lightweight snapshot tests if needed.
|
||
- **Manual verification** – run `cargo run -p owlen-cli -- --help` to open the TUI and confirm the migrated feature behaves as expected.
|
||
|
||
Every new MVU feature should land with unit tests plus a note about manual validation.
|
||
|
||
---
|
||
|
||
## Tracking TODOs
|
||
|
||
- Keep this file up to date when you migrate a feature.
|
||
- Add inline `// TODO(mvu)` tags in code with a short description so they are easy to grep.
|
||
- Use the `docs/` folder for design notes; avoid long comment blocks inside the code.
|
||
|
||
Future contributors should be able to glance at this document, see what is done, and understand where to continue the migration.
|
||
|
||
---
|
||
|
||
Questions? Reach out in the Owlen discussion board or drop a note in the relevant PR thread. Consistent updates here will keep MVU adoption predictable for everyone.
|