mod commands;
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(name = "jammi", version, about = "Jammi AI — inference engine CLI")]
struct Cli {
#[arg(long, global = true)]
config: Option<String>,
#[arg(long, global = true)]
tenant: Option<String>,
#[command(subcommand)]
command: Option<Commands>,
}
#[derive(Subcommand)]
enum Commands {
Serve,
Sources {
#[command(subcommand)]
action: commands::sources::SourceAction,
},
Models {
#[command(subcommand)]
action: commands::models::ModelAction,
},
Query {
sql: String,
},
Explain {
sql: String,
},
Trigger {
#[command(subcommand)]
action: commands::trigger::TriggerAction,
},
Channels {
#[command(subcommand)]
action: commands::channels::ChannelAction,
},
Mutable {
#[command(subcommand)]
action: commands::mutable::MutableAction,
},
}
#[tokio::main]
async fn main() {
let cli = Cli::parse();
let config_path = cli.config.as_deref();
let tenant = cli.tenant.as_deref();
if let Err(e) = run(cli.command, config_path, tenant).await {
eprintln!("Error: {e}");
std::process::exit(1);
}
}
async fn run(
command: Option<Commands>,
config_path: Option<&str>,
tenant: Option<&str>,
) -> Result<(), Box<dyn std::error::Error>> {
let config = jammi_db::config::JammiConfig::load(config_path.map(std::path::Path::new))?;
let tenant = match tenant {
None => None,
Some(s) => {
use std::str::FromStr;
Some(jammi_db::TenantId::from_str(s)?)
}
};
match command {
Some(Commands::Serve) => commands::serve::run(config).await,
Some(Commands::Sources { action }) => commands::sources::run(config, tenant, action).await,
Some(Commands::Models { action }) => commands::models::run(config, tenant, action).await,
Some(Commands::Query { sql }) => commands::query::run(config, tenant, &sql).await,
Some(Commands::Explain { sql }) => commands::query::explain(config, tenant, &sql).await,
Some(Commands::Trigger { action }) => commands::trigger::run(config, tenant, action).await,
Some(Commands::Channels { action }) => {
commands::channels::run(config, tenant, action).await
}
Some(Commands::Mutable { action }) => commands::mutable::run(config, tenant, action).await,
None => {
use clap::CommandFactory;
Cli::command().print_help()?;
println!();
Ok(())
}
}
}