codetether_agent/tui/ui/
main.rs1use ratatui::Frame;
9
10use crate::tui::app::state::App;
11use crate::tui::bus_log::{ProtocolSummary, render_bus_log_with_summary};
12use crate::tui::latency::render_latency;
13use crate::tui::lsp::render_lsp;
14use crate::tui::models::ViewMode;
15use crate::tui::ralph_view::render_ralph_view;
16use crate::tui::rlm::render_rlm;
17use crate::tui::settings::render_settings;
18use crate::tui::swarm_view::render_swarm_view;
19use crate::tui::symbol_search::render_symbol_search;
20
21use super::chat_view::render_chat_view;
22use super::sessions::render_sessions_view;
23
24pub fn ui(f: &mut Frame, app: &mut App, session: &crate::session::Session) {
37 dispatch_view(f, app, session);
38 render_overlays(f, app);
39}
40
41fn dispatch_view(f: &mut Frame, app: &mut App, session: &crate::session::Session) {
42 match app.state.view_mode {
43 ViewMode::Chat => render_chat_or_webview(f, app, session),
44 ViewMode::Sessions => render_sessions_view(f, app),
45 ViewMode::Swarm => render_swarm_view(f, &mut app.state.swarm, f.area()),
46 ViewMode::Ralph => render_ralph_view(f, &mut app.state.ralph, f.area()),
47 ViewMode::Bus => render_bus_view(f, app),
48 ViewMode::Model => crate::tui::model_picker::render_model_picker(f, f.area(), app, session),
49 ViewMode::Settings => render_settings(f, f.area(), &app.state),
50 ViewMode::Lsp => render_lsp(f, f.area(), &app.state.cwd_display, &app.state.status),
51 ViewMode::Rlm => render_rlm(
52 f,
53 f.area(),
54 &app.state.cwd_display,
55 &app.state.status,
56 app.state.sessions.len(),
57 app.state.selected_session,
58 ),
59 ViewMode::Latency => render_latency(f, f.area(), app),
60 ViewMode::Protocol => {}
61 ViewMode::FilePicker => crate::tui::app::file_picker::render_file_picker(f, f.area(), app),
62 ViewMode::Inspector => super::inspector::render_inspector_view(f, app),
63 }
64}
65
66fn render_chat_or_webview(f: &mut Frame, app: &mut App, session: &crate::session::Session) {
67 if super::webview::layout::is_webview(app.state.chat_layout_mode) {
68 super::webview::render(f, app);
69 } else {
70 render_chat_view(f, app, session);
71 }
72}
73
74fn render_bus_view(f: &mut Frame, app: &mut App) {
75 let mut registered_agents = app
76 .state
77 .worker_bridge_registered_agents
78 .iter()
79 .cloned()
80 .collect::<Vec<_>>();
81 registered_agents.sort();
82 let summary = ProtocolSummary {
83 cwd_display: app.state.cwd_display.clone(),
84 worker_id: app.state.worker_id.clone(),
85 worker_name: app.state.worker_name.clone(),
86 a2a_connected: app.state.a2a_connected,
87 processing: app.state.worker_bridge_processing_state,
88 registered_agents,
89 queued_tasks: app.state.worker_task_queue.len(),
90 recent_task: app.state.recent_tasks.last().cloned(),
91 };
92 render_bus_log_with_summary(f, &mut app.state.bus_log, f.area(), Some(summary))
93}
94
95fn render_overlays(f: &mut Frame, app: &mut App) {
96 if app.state.symbol_search.loading
97 || !app.state.symbol_search.query.is_empty()
98 || !app.state.symbol_search.results.is_empty()
99 || app.state.symbol_search.error.is_some()
100 {
101 render_symbol_search(f, &mut app.state.symbol_search, f.area());
102 }
103
104 if app.state.watchdog_notification.is_some() {
105 crate::tui::app::watchdog::render_watchdog_notification(f, f.area(), &app.state);
106 }
107}