mod audio_feedback; mod cli; mod config; mod coordinator; mod hotkey; mod ipc; mod model_cache; mod overlay; mod paste; mod recorder; mod shared_state; mod transcriber; mod vad; use clap::{Parser, Subcommand}; #[derive(Parser)] #[command(name = "mouth", version, about = "Offline speech-to-text with global hotkey and paste")] struct Cli { #[command(subcommand)] command: Option, } #[derive(Subcommand)] enum Commands { /// Start the mouth daemon Run, /// View or edit configuration Config { /// Print current config to stdout #[arg(long)] show: bool, /// Reset config to defaults #[arg(long)] reset: bool, }, /// Manage speech-to-text models Models { /// Download the configured model #[arg(long)] download: bool, }, /// Show daemon status, loaded model, and version Status, } fn main() -> anyhow::Result<()> { tracing_subscriber::fmt() .with_env_filter( tracing_subscriber::EnvFilter::try_from_default_env() .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")), ) .init(); let cli = Cli::parse(); match cli.command { None | Some(Commands::Run) => cli::run_cmd::run(), Some(Commands::Config { show, reset }) => { if show { cli::config_cmd::show() } else if reset { cli::config_cmd::reset() } else { cli::config_cmd::interactive() } } Some(Commands::Models { download }) => { if download { cli::models_cmd::download() } else { cli::models_cmd::list() } } Some(Commands::Status) => cli::status_cmd::status(), } }