Files
owlen/docs/tui-mvu-migration.md

5.6 KiB
Raw Permalink Blame History

TUI MVU Migration Guide

This guide explains how we are migrating the Owlen terminal UI to a predictable ModelViewUpdate (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.