use tracing::info;
use tracing_subscriber::{fmt, EnvFilter};
use xbp_cli::{api, cli};
const MAIN_THREAD_STACK_SIZE: usize = 8 * 1024 * 1024;
fn main() {
let result = std::thread::Builder::new()
.name("xbp-main".into())
.stack_size(MAIN_THREAD_STACK_SIZE)
.spawn(|| {
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.thread_name("xbp-worker")
.build()
.expect("failed to build tokio runtime");
runtime.block_on(async_main())
})
.expect("failed to spawn xbp main thread")
.join();
match result {
Ok(Ok(())) => {}
Ok(Err(code)) => std::process::exit(code),
Err(_) => {
eprintln!("xbp main thread panicked");
std::process::exit(1);
}
}
}
async fn async_main() -> Result<(), i32> {
fmt()
.with_env_filter(EnvFilter::from_default_env())
.with_ansi(cli::ui::should_emit_ansi())
.init();
if std::env::var("PORT_XBP_MCP").is_ok() {
info!("Starting XBP MCP server mode");
if let Err(e) = xbp_mcp::serve_from_env().await {
eprintln!("MCP server error: {}", e);
return Err(1);
}
} else if std::env::var("PORT_XBP_API").is_ok() {
info!("Starting XBP API server mode");
if let Err(e) = api::start_api_server().await {
eprintln!("API server error: {}", e);
return Err(1);
}
} else if let Err(e) = cli::run().await {
eprintln!("{}", e);
return Err(1);
}
Ok(())
}