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