use clap::{ArgGroup, Parser, Subcommand};
use std::path::PathBuf;
mod commands;
mod run_registry;
use commands::output::OutputFormat;
#[derive(Parser)]
#[command(name = "bzzz")]
#[command(about = "Bzzz - Agent orchestration CLI", long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Init {
#[arg(short, long)]
file: PathBuf,
#[arg(long)]
pattern: Option<String>,
#[arg(long)]
template: Option<String>,
},
Inspect {
#[arg(short, long)]
file: PathBuf,
},
Run {
#[arg(short, long)]
file: PathBuf,
#[arg(short, long)]
background: bool,
#[arg(short, long)]
timeout: Option<u64>,
#[arg(short, long, default_value = "local")]
runtime: String,
#[arg(short, long)]
input: Option<String>,
#[arg(short = 'o', long = "output", default_value = "text")]
output: OutputFormat,
#[arg(short, long)]
adaptive: bool,
},
Spawn {
#[arg(short, long)]
role: String,
#[arg(short, long)]
command: String,
#[arg(short, long)]
env: Vec<String>,
#[arg(short, long)]
timeout: Option<u64>,
#[arg(short, long)]
input: Option<String>,
#[arg(short = 'o', long = "output", default_value = "text")]
output: OutputFormat,
},
Status {
#[arg(short, long)]
id: String,
},
Stop {
#[arg(short, long)]
id: String,
#[arg(short, long)]
force: bool,
},
#[command(group(ArgGroup::new("list_mode").args(&["running", "agents", "patterns", "templates"])))]
List {
#[arg(short, long)]
running: bool,
#[arg(long)]
agents: bool,
#[arg(short, long)]
file: Option<PathBuf>,
#[arg(long)]
url: Option<String>,
#[arg(long)]
patterns: bool,
#[arg(long)]
templates: bool,
#[arg(short = 'o', long = "output", default_value = "text")]
output: OutputFormat,
},
Validate {
#[arg(short, long)]
file: PathBuf,
},
Serve {
#[arg(short, long)]
port: Option<u16>,
},
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt::init();
let cli = Cli::parse();
match cli.command {
Commands::Init { file, pattern, template } => {
commands::init::execute(file, pattern, template)?;
}
Commands::Inspect { file } => {
commands::inspect::execute(file).await?;
}
Commands::Run { file, background, timeout, runtime, input, output, adaptive } => {
commands::run::execute(file, background, timeout, &runtime, input, output, adaptive).await?;
}
Commands::Spawn { role, command, env, timeout, input, output } => {
commands::spawn::execute(role, command, env, timeout, input, output).await?;
}
Commands::Status { id } => {
commands::status::execute(&id).await?;
}
Commands::Stop { id, force } => {
commands::stop::execute(&id, force).await?;
}
Commands::List { running, agents, file, url, patterns, templates, output } => {
if agents {
if let Some(agent_url) = url {
commands::list::execute_agents_discovery(agent_url, output).await?;
} else {
let swarm_file = file.expect("--agents requires -f <file> or --url <url>");
commands::list::execute_agents(swarm_file, output).await?;
}
} else if patterns {
commands::list::execute_patterns(output)?;
} else if templates {
commands::list::execute_templates(output)?;
} else {
commands::list::execute(running, output).await?;
}
}
Commands::Validate { file } => {
commands::validate::execute(file).await?;
}
Commands::Serve { port } => {
commands::serve::execute(port).await?;
}
}
Ok(())
}