use anyhow::Result;
use clap::Parser;
use mermaid_cli::{
app::{load_config, persist_last_model, resolve_model_id},
cli::{Cli, Commands, OutputFormat},
ollama::ensure_model as ensure_ollama_model,
runtime::{NonInteractiveRunner, Orchestrator, format_result},
utils::init_logger,
};
#[tokio::main]
async fn main() -> Result<()> {
let cli = Cli::parse();
init_logger(cli.verbose);
if let Some(Commands::Run {
prompt,
format,
max_tokens,
no_execute,
}) = &cli.command
{
return run_non_interactive(&cli, prompt.clone(), *format, *max_tokens, *no_execute).await;
}
let orchestrator = Orchestrator::new(cli)?;
orchestrator.run().await
}
async fn run_non_interactive(
cli: &Cli,
prompt: String,
format: OutputFormat,
max_tokens: Option<usize>,
no_execute: bool,
) -> Result<()> {
let config = load_config().unwrap_or_default();
let cli_model_provided = cli.model.is_some();
let model_id = resolve_model_id(cli.model.as_deref(), &config).await?;
ensure_ollama_model(&model_id).await?;
if cli_model_provided {
let _ = persist_last_model(&model_id);
}
let effective_max_tokens = max_tokens.or(Some(config.non_interactive.max_tokens));
let effective_no_execute = no_execute || config.non_interactive.no_execute;
let runner =
NonInteractiveRunner::new(model_id, config, effective_no_execute, effective_max_tokens)
.await?;
let result = runner.execute(prompt).await?;
let formatted = format_result(&result, format);
println!("{}", formatted);
if !result.errors.is_empty() {
std::process::exit(1);
}
Ok(())
}