diff options
| author | Michelle Tilley <michelle@michelletilley.net> | 2026-02-13 10:54:38 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-13 18:54:38 +0000 |
| commit | e6a8bb033434541974262699c12e2805cc054153 (patch) | |
| tree | ff682af16556266a9777b4d21c84aa66c55d015e /crates/atuin-ai/src/commands.rs | |
| parent | chore(deps): update to rust 1.93.1 (#3181) (diff) | |
| download | atuin-e6a8bb033434541974262699c12e2805cc054153.zip | |
feat: add Atuin AI inline CLI MVP (#3178)
Diffstat (limited to 'crates/atuin-ai/src/commands.rs')
| -rw-r--r-- | crates/atuin-ai/src/commands.rs | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/crates/atuin-ai/src/commands.rs b/crates/atuin-ai/src/commands.rs new file mode 100644 index 00000000..56741544 --- /dev/null +++ b/crates/atuin-ai/src/commands.rs @@ -0,0 +1,97 @@ +use clap::{Parser, Subcommand}; +use tracing::Level; +use tracing_subscriber::{EnvFilter, Layer, fmt, layer::SubscriberExt, util::SubscriberInitExt}; + +pub mod init; +pub mod inline; + +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +struct Cli { + /// Enable verbose logging + #[arg(short, long, global = true)] + verbose: bool, + + /// Custom API endpoint + #[arg(long, global = true, env = "ATUIN_AI_API_ENDPOINT")] + api_endpoint: Option<String>, + + #[command(subcommand)] + command: Commands, +} + +#[derive(Subcommand, Debug)] +enum Commands { + /// Initialize shell integration + Init, + + /// Complete current command line + Complete { + /// Current command line to complete + #[arg(value_name = "COMMAND")] + command: Option<String>, + }, + + /// Inline completion mode with small TUI overlay + Inline { + /// Current command line to complete + #[arg(value_name = "COMMAND")] + command: Option<String>, + + /// Start in natural language mode + #[arg(long)] + natural_language: bool, + }, + + /// Interactive mode with TUI + Interactive, +} + +pub async fn run() -> eyre::Result<()> { + let cli = Cli::parse(); + + init_tracing(cli.verbose); + + match cli.command { + Commands::Init => init::run().await, + Commands::Inline { + command, + natural_language, + } => inline::run(command, natural_language, cli.api_endpoint).await, + Commands::Complete { command } => inline::run(command, false, cli.api_endpoint).await, + Commands::Interactive => Err(eyre::eyre!("interactive mode not implemented yet")), + } +} + +fn init_tracing(verbose: bool) { + let level = if verbose { Level::DEBUG } else { Level::INFO }; + + // Create env filter + let env_filter = EnvFilter::from_default_env().add_directive( + format!("atuin_ai={}", level.as_str().to_lowercase()) + .parse() + .unwrap(), + ); + + // Create console layer (only for verbose mode) + let console_layer = if verbose { + Some( + fmt::layer() + .with_writer(std::io::stderr) + .with_ansi(true) + .with_target(false) + .with_filter(env_filter), + ) + } else { + None + }; + + // Initialize subscriber + let subscriber = tracing_subscriber::registry(); + + if let Some(console) = console_layer { + subscriber.with(console).init(); + } else { + subscriber.init(); + } +} |
