mod app;
mod commands;
mod components;
mod error;
mod helpers;
mod mcp;
mod session;
mod shell;
mod systems;
mod telemetry;
mod utils;
mod workflows;
use app::{App as CLI, Commands, DebugCommands, PluginCommands};
use clap::Parser;
use session::ProtoSession;
use starbase::{
App, MainResult,
tracing::{LogLevel, TracingOptions},
};
use starbase_utils::{envx, string_vec};
use std::env;
use std::process::ExitCode;
use tracing::debug;
fn get_tracing_modules() -> Vec<String> {
let mut modules = string_vec!["proto", "schematic", "starbase", "warpgate"];
if envx::bool_var("PROTO_DEBUG_WASM") || envx::bool_var("PROTO_WASM_LOG") {
modules.push("extism".into());
} else {
modules.push("extism::pdk".into());
}
modules
}
#[tokio::main]
async fn main() -> MainResult {
sigpipe::reset();
let cli = CLI::parse();
cli.setup_env_vars();
let app = App::default();
app.setup_diagnostics();
let _guard = app.setup_tracing(TracingOptions {
default_level: if matches!(cli.command, Commands::Bin { .. } | Commands::Run { .. }) {
LogLevel::Warn
} else if matches!(cli.command, Commands::Completions { .. }) {
LogLevel::Off
} else {
LogLevel::Info
},
dump_trace: cli.dump && !matches!(cli.command, Commands::Run { .. }),
filter_modules: get_tracing_modules(),
log_env: "PROTO_APP_LOG".into(),
log_file: cli.log_file.clone(),
show_spans: cli.log.is_verbose(),
..TracingOptions::default()
})?;
let session = ProtoSession::new(cli);
let mut args = env::args_os().collect::<Vec<_>>();
debug!(
exe = ?args.remove(0),
args = ?args,
shim = env::var("PROTO_SHIM_NAME").ok(),
shim_exe = env::var("PROTO_SHIM_PATH").ok(),
pid = std::process::id(),
"Running proto v{}",
session.cli_version
);
let exit_code = app
.run(session, |session| async {
match session.cli.command.clone() {
Commands::Activate(args) => commands::activate(session, args).await,
Commands::Alias(args) => commands::alias(session, args).await,
Commands::Bin(args) => commands::bin(session, args).await,
Commands::Clean(args) => commands::clean(session, args).await,
Commands::Completions(args) => commands::completions(session, args).await,
Commands::Debug { command } => match command {
DebugCommands::Config(args) => commands::debug::config(session, args).await,
DebugCommands::Env(args) => commands::debug::env(session, args).await,
},
Commands::Diagnose(args) => commands::diagnose(session, args).await,
Commands::Exec(args) => commands::exec(session, args).await,
Commands::Install(args) => commands::install(session, args).await,
Commands::Mcp(args) => commands::mcp(session, args).await,
Commands::Migrate(args) => commands::migrate(session, args).await,
Commands::Outdated(args) => commands::outdated(session, args).await,
Commands::Pin(args) => commands::pin(session, args).await,
Commands::Plugin { command } => match command {
PluginCommands::Add(args) => commands::plugin::add(session, args).await,
PluginCommands::Info(args) => commands::plugin::info(session, args).await,
PluginCommands::List(args) => commands::plugin::list(session, args).await,
PluginCommands::Remove(args) => commands::plugin::remove(session, args).await,
PluginCommands::Search(args) => commands::plugin::search(session, args).await,
},
Commands::Regen(args) => commands::regen(session, args).await,
Commands::Run(args) => commands::run(session, args).await,
Commands::Setup(args) => commands::setup(session, args).await,
Commands::Shell(args) => commands::shell(session, args).await,
Commands::Status(args) => commands::status(session, args).await,
Commands::Unalias(args) => commands::unalias(session, args).await,
Commands::Uninstall(args) => commands::uninstall(session, args).await,
Commands::Unpin(args) => commands::unpin(session, args).await,
Commands::Upgrade(args) => commands::upgrade(session, args).await,
Commands::Versions(args) => commands::versions(session, args).await,
}
})
.await?;
Ok(ExitCode::from(exit_code))
}