use std::path::{Path, PathBuf};
use regex::Regex;
use super::arms_report::parse_arms_report;
use super::bench_report::parse_bench_readme_report;
use super::formatting::required_arg;
use super::probes::{probe_explore_text, probe_node_text, probe_sweep_report};
use super::run_report::parse_run_report;
use super::seq_matrix_report::seq_matrix_report;
use super::session_report::parse_session_report;
pub fn run_cli(args: &[String]) -> Result<(), String> {
match args.get(1).map(String::as_str) {
Some("parse-run") => {
let file = required_arg(args, 2, "usage: rustcodegraph agent-eval parse-run <jsonl>")?;
print!("{}", parse_run_report(Path::new(file))?);
Ok(())
}
Some("parse-session") => {
let project = required_arg(
args,
2,
"usage: rustcodegraph agent-eval parse-session <project-dir>",
)?;
print!("{}", parse_session_report(Path::new(project))?);
Ok(())
}
Some("parse-arms") => {
let root = args
.get(2)
.map(PathBuf::from)
.unwrap_or_else(|| "/tmp/arms".into());
print!("{}", parse_arms_report(&root)?);
Ok(())
}
Some("parse-bench-readme") => {
let root = args
.get(2)
.map(PathBuf::from)
.unwrap_or_else(|| "/tmp/ab-readme".into());
print!("{}", parse_bench_readme_report(&root)?);
Ok(())
}
Some("seq-matrix") => {
let root = args
.get(2)
.filter(|arg| !arg.starts_with("--"))
.map(PathBuf::from)
.unwrap_or_else(|| "/tmp/ab-matrix".into());
print!("{}", seq_matrix_report(&root, Path::new("."))?);
Ok(())
}
Some("probe-explore") => {
let repo = required_arg(
args,
2,
"usage: rustcodegraph agent-eval probe-explore <repo> <query>",
)?;
let query = args.get(3..).unwrap_or(&[]).join(" ");
if query.trim().is_empty() {
return Err(
"usage: rustcodegraph agent-eval probe-explore <repo> <query>".to_string(),
);
}
let text = probe_explore_text(Path::new(repo), &query)?;
println!("{text}");
eprintln!();
eprintln!("--- PROBE STATS ---");
eprintln!("output chars: {}", text.chars().count());
eprintln!(
"triggerRender body present (-> setState({{}})): {}",
Regex::new(r"triggerRender[\s\S]{0,400}setState\(\{\}\)")
.expect("probe regex should compile")
.is_match(&text)
);
eprintln!(
"App.tsx in source section: {}",
Regex::new(r"(?m)^#### .*App\.tsx")
.expect("probe regex should compile")
.is_match(&text)
);
Ok(())
}
Some("probe-node") => {
let repo = required_arg(
args,
2,
"usage: rustcodegraph agent-eval probe-node <repo> <symbol> [code]",
)?;
let symbol = required_arg(
args,
3,
"usage: rustcodegraph agent-eval probe-node <repo> <symbol> [code]",
)?;
let include_code = args.get(4).is_some_and(|arg| arg == "code");
println!(
"{}",
probe_node_text(Path::new(repo), symbol, include_code)?
);
Ok(())
}
Some("probe-sweep") => {
print!("{}", probe_sweep_report(args.get(2..).unwrap_or(&[]))?);
Ok(())
}
Some("probe-context") | Some("probe-trace") => {
Err("context and trace probes are retired; use probe-explore instead".to_string())
}
Some("-h" | "--help") | None => {
println!("{}", agent_eval_help());
Ok(())
}
Some(other) => Err(format!("unknown agent-eval command '{other}'")),
}
}
fn agent_eval_help() -> &'static str {
"Usage: rustcodegraph agent-eval <command>
Commands:
parse-run <jsonl>
parse-session <project-dir>
parse-arms [root]
parse-bench-readme [root]
seq-matrix [root]
probe-explore <repo> <query>
probe-node <repo> <symbol> [code]
probe-sweep [--tool=explore] [--repos=a,b]"
}