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