mod app;
mod appserver;
mod citations;
mod cli;
mod config;
mod db;
mod events;
mod extract;
mod input;
mod markdown;
mod provider;
mod selection;
mod skills;
mod space;
mod theme;
mod tools;
mod ui;
mod update;
use anyhow::Result;
#[tokio::main]
async fn main() -> Result<()> {
if let Some(cmd) = cli::parse() {
return cli::run(cmd).await;
}
let saved = config::load_all_providers().await?;
let key = config::first_configured(&saved).map(|(_, k)| k);
let space = space::Space::open()?;
let space_root = space.spaces_root();
let db = db::Db::open(&space.db_path())?;
let mut app = app::App::new(db, key.as_deref(), space);
app.saved = saved;
app.rebuild_all_backends();
app.app_server = appserver::AppServer::start(space_root).await;
app.refresh_toolbox();
let mut terminal = ratatui::init();
let _ = crossterm::execute!(
std::io::stdout(),
crossterm::event::EnableMouseCapture,
crossterm::event::EnableBracketedPaste
);
let enhanced = crossterm::terminal::supports_keyboard_enhancement().unwrap_or(false);
if enhanced {
use crossterm::event::{KeyboardEnhancementFlags, PushKeyboardEnhancementFlags};
let _ = crossterm::execute!(
std::io::stdout(),
PushKeyboardEnhancementFlags(KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES)
);
}
app.init(); let handoff = app.space.root.join("pending-open");
if let Ok(id) = std::fs::read_to_string(&handoff) {
let _ = std::fs::remove_file(&handoff);
let id = id.trim();
if !id.is_empty()
&& let Ok((space_id, session)) = cli::resolve_session(&app.db, id)
&& let Ok(rows) = app.db.list_spaces()
&& let Some(row) = rows.into_iter().find(|s| s.id == space_id)
{
app.set_active_space(row);
let _ = app.switch_to_session_by_id(&session.id);
}
}
app.spawn_update_check(); app.run_due_watches(); let result = events::run(app, &mut terminal).await;
if enhanced {
let _ = crossterm::execute!(
std::io::stdout(),
crossterm::event::PopKeyboardEnhancementFlags
);
}
let _ = crossterm::execute!(
std::io::stdout(),
crossterm::event::DisableMouseCapture,
crossterm::event::DisableBracketedPaste
);
ratatui::restore();
result
}