fabro/crates/arc-cli/src/main.rs
Bryan Helmkamp 2d79362750 Unify ullm, arc-agent, arc-attractor into single arc binary
Three separate binaries are replaced by a single `arc` CLI with subcommands:
  arc llm prompt/models, arc agent, arc run, arc validate, arc serve

Extract public CLI modules (arc_llm::cli, arc_agent::cli::AgentArgs/run_with_args)
so the new arc-cli crate can dispatch to each library. Integration tests migrate
to crates/arc-cli/tests/cli.rs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-28 17:09:30 -05:00

73 lines
2.1 KiB
Rust

use anyhow::Result;
use clap::{Parser, Subcommand};
#[derive(Parser)]
#[command(name = "arc", version)]
struct Cli {
/// Skip loading .env file
#[arg(long, global = true)]
no_dotenv: bool,
#[command(subcommand)]
command: Command,
}
#[derive(Subcommand)]
enum Command {
/// LLM prompt and model operations
Llm {
#[command(subcommand)]
command: LlmCommand,
},
/// Run an agentic coding session
Agent(arc_agent::cli::AgentArgs),
/// Launch a pipeline
Run(arc_attractor::cli::RunArgs),
/// Validate a pipeline
Validate(arc_attractor::cli::ValidateArgs),
/// Start the HTTP API server
Serve(arc_attractor::cli::ServeArgs),
}
#[derive(Subcommand)]
enum LlmCommand {
/// Execute a prompt
Prompt(arc_llm::cli::PromptArgs),
/// Manage models
Models {
#[command(subcommand)]
command: Option<arc_llm::cli::ModelsCommand>,
},
}
#[tokio::main]
async fn main() -> Result<()> {
let cli = Cli::parse();
if !cli.no_dotenv {
dotenvy::dotenv().ok();
}
match cli.command {
Command::Llm { command } => match command {
LlmCommand::Prompt(args) => arc_llm::cli::run_prompt(args).await?,
LlmCommand::Models { command } => arc_llm::cli::run_models(command).await?,
},
Command::Agent(args) => arc_agent::cli::run_with_args(args).await?,
Command::Run(args) => {
let styles: &'static arc_util::terminal::Styles =
Box::leak(Box::new(arc_util::terminal::Styles::detect_stderr()));
arc_attractor::cli::run::run_command(args, styles).await?;
}
Command::Validate(args) => {
let styles = arc_util::terminal::Styles::detect_stderr();
arc_attractor::cli::validate::validate_command(&args, &styles)?;
}
Command::Serve(args) => {
let styles: &'static arc_util::terminal::Styles =
Box::leak(Box::new(arc_util::terminal::Styles::detect_stderr()));
arc_attractor::cli::serve::serve_command(args, styles).await?;
}
}
Ok(())
}