use anyhow::Result;
use colored::Colorize;
async fn build_embedder() -> Option<std::sync::Arc<dyn trusty_search_core::Embedder>> {
match trusty_search_core::FastEmbedder::new().await {
Ok(e) => Some(std::sync::Arc::new(e)),
Err(e) => {
tracing::warn!("FastEmbedder init failed ({e}); daemon falling back to BM25-only mode");
None
}
}
}
pub async fn handle_start(port: u16, foreground: bool) -> Result<()> {
let _ = foreground;
if let Some(pid) = trusty_search_service::running_daemon_pid() {
tracing::info!("daemon already running (pid {pid}), exiting cleanly");
eprintln!(
"{} trusty-search daemon already running (pid {pid}); nothing to do",
"✓".green()
);
return Ok(());
}
let embedder = build_embedder().await;
let mut state = trusty_search_service::SearchAppState::new(
trusty_search_core::registry::IndexRegistry::new(),
);
if let Some(e) = embedder {
state = state.with_embedder(e);
}
match trusty_search_service::run_daemon(state, port).await {
Ok(()) => {}
Err(trusty_search_service::DaemonError::AlreadyRunning(p)) => {
tracing::info!(
"daemon already running (lock at {}), exiting cleanly",
p.display()
);
eprintln!(
"{} trusty-search daemon already running (lock at {}); nothing to do",
"✓".green(),
p.display()
);
return Ok(());
}
Err(e) => {
eprintln!("{} daemon failed: {e}", "✗".red());
std::process::exit(1);
}
}
Ok(())
}