1pub use anyhow;
2pub use crabtalk_command_codegen::command;
3pub use wcore;
4
5pub mod service;
6pub use service::{Service, install, render_service_template, uninstall, verbose_flag, view_logs};
7
8#[cfg(feature = "mcp")]
9pub use axum;
10#[cfg(feature = "mcp")]
11pub use service::{McpService, run_mcp};
12
13pub fn run<F, Fut>(verbose: u8, f: F)
16where
17 F: FnOnce() -> Fut,
18 Fut: std::future::Future<Output = anyhow::Result<()>>,
19{
20 let level = if verbose > 0 {
21 Some(match verbose {
22 1 => tracing::Level::INFO,
23 2 => tracing::Level::DEBUG,
24 _ => tracing::Level::TRACE,
25 })
26 } else {
27 std::env::var("RUST_LOG").ok().map(|v| {
28 match v.rsplit('=').next().unwrap_or(&v).to_lowercase().as_str() {
29 "trace" => tracing::Level::TRACE,
30 "debug" => tracing::Level::DEBUG,
31 "info" => tracing::Level::INFO,
32 "error" => tracing::Level::ERROR,
33 _ => tracing::Level::WARN,
34 }
35 })
36 };
37 if let Some(level) = level {
38 tracing_subscriber::fmt()
39 .with_writer(std::io::stderr)
40 .with_max_level(level)
41 .init();
42 }
43
44 let rt = match tokio::runtime::Runtime::new() {
45 Ok(rt) => rt,
46 Err(e) => {
47 eprintln!("Error: failed to create tokio runtime: {e}");
48 std::process::exit(1);
49 }
50 };
51 if let Err(e) = rt.block_on(f()) {
52 eprintln!("Error: {e}");
53 std::process::exit(1);
54 }
55}