use clap::Parser;
use kya_validator::types::ValidationConfig;
use kya_validator::validator;
use serde_json::Value;
use std::fs;
use std::path::PathBuf;
#[derive(Parser, Debug)]
#[command(name = "kya-validate")]
#[command(about = "Validate Know Your Agent (KYA) manifests", long_about = None)]
struct Args {
#[arg(long)]
manifest: PathBuf,
#[arg(short, long)]
config: Option<PathBuf>,
#[arg(long, default_value = "strict")]
mode: String,
#[arg(long)]
no_signature_check: bool,
#[arg(long)]
no_link_check: bool,
#[arg(long)]
check_attestations: bool,
#[arg(short, long, default_value = "text")]
format: String,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args = Args::parse();
let manifest_str = fs::read_to_string(&args.manifest)?;
let manifest: Value = serde_json::from_str(&manifest_str)?;
let mut config = match args.mode.as_str() {
"lenient" => ValidationConfig::lenient(),
"self-audit" => ValidationConfig::self_audit(),
_ => ValidationConfig::strict(),
};
let _ = args.no_signature_check;
if args.no_link_check {
config.link_checks = vec![];
}
if args.check_attestations {
config.attestation_checks = vec![];
}
let report = validator::validate_manifest_with_config(&manifest, &config);
if args.format == "json" {
let output = serde_json::json!({
"valid": report.is_valid(),
"errors": report.errors(),
"warnings": report.warnings(),
});
println!("{}", serde_json::to_string_pretty(&output)?);
} else if report.is_valid() {
if report.is_valid() {
println!("✅ KYA Manifest is VALID");
if !report.warnings().is_empty() {
println!("\nWarnings:");
for warning in report.warnings() {
println!(" ⚠️ {}", warning);
}
}
} else {
println!("❌ KYA Manifest is INVALID");
println!("\nErrors:");
for error in report.errors() {
println!(" - {}", error);
}
std::process::exit(1);
}
}
Ok(())
}