proto_cli 0.57.3

A multi-language version manager, a unified toolchain.
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(),
        // test_env: "PROTO_TEST".into(),
        ..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))
}