docs(tui): MVU migration guide + module map
This commit is contained in:
@@ -175,4 +175,4 @@ The TUI is rendered on each iteration of the main application loop in `owlen-tui
|
|||||||
4. **State-Driven Rendering**: Each rendering function takes the current application state as an argument. It uses this state to decide what and how to render. For example, the border color of a panel might change if it is focused.
|
4. **State-Driven Rendering**: Each rendering function takes the current application state as an argument. It uses this state to decide what and how to render. For example, the border color of a panel might change if it is focused.
|
||||||
5. **Buffer and Diff**: `ratatui` does not draw directly to the terminal. Instead, it renders the widgets to an in-memory buffer. It then compares this buffer to the previous buffer and only sends the necessary changes to the terminal. This is highly efficient and prevents flickering.
|
5. **Buffer and Diff**: `ratatui` does not draw directly to the terminal. Instead, it renders the widgets to an in-memory buffer. It then compares this buffer to the previous buffer and only sends the necessary changes to the terminal. This is highly efficient and prevents flickering.
|
||||||
|
|
||||||
The command palette and other modal helpers expose lightweight state structs in `owlen_tui::state`. These components keep business logic (suggestion filtering, selection state, etc.) independent from rendering, which in turn makes them straightforward to unit test.
|
The command palette and other modal helpers expose lightweight state structs in `owlen_tui::state`. These components keep business logic (suggestion filtering, selection state, etc.) independent from rendering, which in turn makes them straightforward to unit test. The ongoing migration of more features into the `Model–View–Update` core is documented in [`docs/tui-mvu-migration.md`](tui-mvu-migration.md).
|
||||||
|
|||||||
109
docs/tui-mvu-migration.md
Normal file
109
docs/tui-mvu-migration.md
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
# 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.
|
||||||
Reference in New Issue
Block a user