//! CLI entrypoint. //! //! Keep command dispatch thin here. Each subcommand should delegate to its //! feature module so the side effects remain localized and easier to audit. mod account; mod atomic; mod auth_file; mod cli; mod config_store; mod jwt; mod oauth; mod paths; mod quota; mod run_cmd; mod server; mod session; mod sync_client; mod token; use anyhow::Result; use clap::Parser; use crate::cli::{ AccountCommands, Cli, Commands, HomeCommands, ImportCommands, LoginCommands, ServerCommands, ServerUserCommands, SessionCommands, SessionVisibilityCommands, SyncCommands, }; #[tokio::main] async fn main() -> Result<()> { let cli = Cli::parse(); match cli.command.unwrap_or(Commands::List { json: false, force: false, }) { Commands::Login(args) => match args.command { Some(LoginCommands::Oauth { manual, port, switch, }) => oauth::login_oauth(manual, port, switch).await, None => oauth::login_oauth(args.manual, args.port, args.switch).await, }, Commands::Import(args) => match args.command { Some(ImportCommands::Auth { file, codex_home, switch, }) => account::import_auth(file, codex_home, switch), None => account::import_auth(args.file, args.codex_home, args.switch), }, Commands::List { json, force } => account::list_accounts(json, force).await, Commands::Switch { account, codex_home, apply_fingerprint, } => account::switch_account(&account, codex_home, apply_fingerprint).await, Commands::Run(args) => { run_cmd::run_with_account_or_home( args.account, args.home, args.codex_home, args.command, ) .await } Commands::Quota { account, all, json } => quota::quota_command(account, all, json).await, Commands::RefreshToken { account } => token::refresh_token_command(&account).await, Commands::Account { command } => match command { AccountCommands::List { json, force } => account::list_accounts(json, force).await, AccountCommands::Current { json } => account::current_account(json), AccountCommands::Show { account, json } => account::show_account(&account, json), AccountCommands::Remove { account } => account::remove_account(&account), AccountCommands::AddApiKey { key, base_url, switch, } => account::add_api_key(key, base_url, switch), }, Commands::Home { command } => match command { HomeCommands::List { json } => account::list_homes(json), HomeCommands::Create { name, path, account, } => account::create_home(&name, path, account), HomeCommands::Bind { name, account } => account::bind_home(&name, &account), HomeCommands::Path { name } => account::home_path(&name), HomeCommands::Remove { name } => account::remove_home(&name), }, Commands::Server { command } => match command { ServerCommands::Run { bind, data } => server::run_server(bind, data).await, ServerCommands::User { command } => match command { ServerUserCommands::Add { username, password, data, } => server::add_user(data, &username, &password), }, }, Commands::Sync { command } => match command { SyncCommands::Login { server, user, password, } => sync_client::login(&server, &user, &password).await, SyncCommands::Pull => sync_client::pull().await, SyncCommands::Push => sync_client::push().await, SyncCommands::Status => sync_client::status(), }, Commands::Session { command } => match command { SessionCommands::List { all_homes, json } => session::list_sessions(all_homes, json), SessionCommands::Stats { session_id, all_homes, json, } => session::session_stats(&session_id, all_homes, json), SessionCommands::Trash { session_ids, all_homes, } => session::trash_sessions(session_ids, all_homes), SessionCommands::TrashList { all_homes, json } => session::list_trash(all_homes, json), SessionCommands::Restore { session_ids, all_homes, } => session::restore_sessions(session_ids, all_homes), SessionCommands::Visibility { command } => match command { SessionVisibilityCommands::Check { all_homes, json } => { session::visibility_check(all_homes, json) } SessionVisibilityCommands::Repair { all_homes, json } => { session::visibility_repair(all_homes, json) } }, SessionCommands::SyncThreads { all_homes, dry_run, json, } => session::sync_threads(all_homes, dry_run, json), }, } }