use anyhow::Result;
use clap::{Parser, Subcommand};
use instruction_files::AuditConfig;
use std::path::PathBuf;
#[derive(Parser)]
#[command(name = "instruction-files", about = "Audit and validate AI agent instruction files")]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Audit {
#[arg(short, long)]
root: Option<PathBuf>,
#[arg(long, default_value_t = true)]
broad: bool,
#[arg(long)]
ontology_dir: Option<PathBuf>,
},
Init {
#[arg(short, long)]
root: Option<PathBuf>,
},
List {
#[arg(short, long)]
root: Option<PathBuf>,
},
}
fn main() -> Result<()> {
let cli = Cli::parse();
match cli.command {
Commands::Audit {
root,
broad: _,
ontology_dir,
} => {
let config = AuditConfig::agent_doc();
#[cfg(feature = "ontology")]
{
let _ = &ontology_dir;
instruction_files::run(&config, root.as_deref(), ontology_dir.as_deref())?;
}
#[cfg(not(feature = "ontology"))]
{
let _ = &ontology_dir;
instruction_files::run(&config, root.as_deref())?;
}
}
Commands::Init { root } => {
let root = root.unwrap_or_else(|| PathBuf::from("."));
let written = instruction_files::init_runbooks(&root)?;
if written > 0 {
eprintln!("Initialized {written} runbook(s) in .agent/runbooks/");
} else {
eprintln!("Runbooks already initialized.");
}
}
Commands::List { root } => {
let config = AuditConfig::agent_doc();
let project_root = match root {
Some(r) => r,
None => instruction_files::find_root(&config),
};
let files = instruction_files::find_instruction_files(&project_root, &config);
if files.is_empty() {
println!("No instruction files found.");
} else {
for f in &files {
let rel = f.strip_prefix(&project_root).unwrap_or(f);
println!(" {}", rel.display());
}
println!("\n{} file(s) found.", files.len());
}
}
}
Ok(())
}