1use anyhow::Result;
20use clap::{Parser, Subcommand};
21use colored::Colorize;
22
23mod commands;
24
25use commands::{info, tools, verify};
26
27#[derive(Parser)]
32#[command(
33 name = "vex",
34 version,
35 about = "VEX CLI - Verified AI Agent Tooling",
36 long_about = "VEX provides cryptographically-verified AI agent tools.\n\n\
37 Every tool execution is hashed into a Merkle chain,\n\
38 enabling tamper-proof audit trails and verification."
39)]
40struct Cli {
41 #[arg(short, long, action = clap::ArgAction::Count, global = true)]
43 verbose: u8,
44
45 #[command(subcommand)]
46 command: Commands,
47}
48
49#[derive(Subcommand)]
50enum Commands {
51 #[command(name = "verify")]
53 Verify(verify::VerifyArgs),
54
55 #[command(name = "tools")]
57 Tools(tools::ToolsArgs),
58
59 #[command(name = "info")]
61 Info(info::InfoArgs),
62}
63
64#[tokio::main]
65async fn main() -> Result<()> {
66 let cli = Cli::parse();
67
68 setup_logging(cli.verbose);
70
71 match cli.command {
73 Commands::Verify(args) => verify::run(args).await,
74 Commands::Tools(args) => tools::run(args).await,
75 Commands::Info(args) => info::run(args),
76 }
77}
78
79fn setup_logging(verbosity: u8) {
81 use tracing_subscriber::EnvFilter;
82
83 let filter = match verbosity {
84 0 => "warn",
85 1 => "info",
86 2 => "debug",
87 _ => "trace",
88 };
89
90 tracing_subscriber::fmt()
91 .with_env_filter(
92 EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(filter)),
93 )
94 .init();
95}
96
97#[allow(dead_code)]
99pub fn print_success(msg: &str) {
100 println!("{} {}", "✓".green().bold(), msg);
101}
102
103#[allow(dead_code)]
105pub fn print_error(msg: &str) {
106 eprintln!("{} {}", "✗".red().bold(), msg);
107}
108
109#[allow(dead_code)]
111pub fn print_warning(msg: &str) {
112 println!("{} {}", "⚠".yellow().bold(), msg);
113}
114
115#[allow(dead_code)]
117pub fn print_info(msg: &str) {
118 println!("{} {}", "ℹ".blue().bold(), msg);
119}