1#![cfg_attr(not(feature = "testing"), allow(dead_code, unused_imports))]
4
5pub mod cli;
6pub mod error;
7pub mod settings;
8
9#[cfg(not(feature = "testing"))]
13mod testing;
14#[cfg(feature = "testing")]
15pub mod testing;
16
17macro_rules! internal_modules {
18 ($($name:ident),* $(,)?) => {
19 $(
20 #[cfg(feature = "testing")]
21 pub mod $name;
22 #[cfg(not(feature = "testing"))]
23 mod $name;
24 )*
25 };
26}
27
28internal_modules!(
29 app,
30 attachment,
31 conversation,
32 command,
33 file_index,
34 git_review,
35 renderer,
36 request,
37 runtime,
38 screens,
39 session,
40 surfaces,
41 theme,
42 view,
43);
44
45use agent_client_protocol::{Client, ConnectTo, schema::v2::SessionId};
46pub use session::Session;
47
48use app::App;
49use error::AppError;
50use renderer::Renderer;
51use settings::UiSettings;
52use std::fs::create_dir_all;
53use std::path::Path;
54use tracing_appender::rolling::daily;
55use tracing_subscriber::EnvFilter;
56
57pub async fn run_tui(agent_command: &str, settings: UiSettings, log_dir: Option<&str>) -> Result<(), AppError> {
59 setup_logging(log_dir.map(Path::new));
60 let session = Session::connect(agent_command).await?;
61 run_with_session(session, settings).await
62}
63
64pub async fn run_remote_tui(
66 transport: impl ConnectTo<Client> + 'static,
67 requested_session: Option<SessionId>,
68 settings: UiSettings,
69 log_dir: Option<&Path>,
70) -> Result<(), AppError> {
71 setup_logging(log_dir);
72 let session = Session::connect_remote_to(transport, requested_session).await?;
73 run_with_session(session, settings).await
74}
75
76pub async fn run_with_session(session: Session, settings: UiSettings) -> Result<(), AppError> {
78 let (app, event_rx, client_handle) = App::from_session(session, settings);
79 runtime::run(app, Renderer::new(), event_rx, client_handle).await
80}
81
82fn setup_logging(log_dir: Option<&Path>) {
83 let dir = log_dir.unwrap_or_else(|| Path::new(DEFAULT_LOG_DIR));
84 create_dir_all(dir).ok();
85 let _ = tracing_subscriber::fmt()
86 .with_writer(daily(dir, "wisp.log"))
87 .with_ansi(false)
88 .with_env_filter(EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("info")))
89 .try_init();
90}
91
92pub const DEFAULT_LOG_DIR: &str = "/tmp/wisp-logs";