use clap::Parser;
use double_o::{
Action, check_and_clear_learn_status, cmd_forget, cmd_help, cmd_init, cmd_learn, cmd_patterns,
cmd_recall, cmd_run, learn, parse_action,
};
#[derive(Parser)]
#[command(
name = "oo",
version,
about = "Context-efficient command runner for AI coding agents",
long_about = "oo\n\nContext-efficient command runner for AI coding agents."
)]
struct Cli {
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
args: Vec<String>,
}
fn main() {
let raw_args: Vec<String> = std::env::args().collect();
if raw_args.get(1).is_some_and(|a| a == "_learn_bg") {
if let Some(path) = raw_args.get(2) {
let _ = learn::run_background(path);
}
std::process::exit(0);
}
let cli = Cli::parse();
{
let status_path = learn::learn_status_path();
check_and_clear_learn_status(&status_path);
}
let exit_code = match parse_action(&cli.args) {
Action::Help(None) => {
println!("oo — Context-efficient command runner for AI coding agents");
println!();
println!("Usage: oo <command> [args...]");
println!();
println!("Commands:");
println!(" recall [--full] <query> Search session output");
println!(" forget Clear session data");
println!(" learn [--hint <text>] <cmd> [args...] Learn output compression patterns");
println!(
" help [cmd] Show help (or cheat-sheet for cmd via cheat.sh)"
);
println!(" init [format] Set up hooks for agent frameworks");
println!(" patterns List output compression patterns");
println!(" version Show version");
println!();
println!("Any other command is run in the shell, e.g. oo git log");
0
}
Action::Help(Some(cmd)) => cmd_help(&cmd),
Action::Version => {
println!("oo {}", env!("CARGO_PKG_VERSION"));
0
}
Action::Run(args) => cmd_run(&args),
Action::Recall { query, full } => cmd_recall(&query, full),
Action::Forget => cmd_forget(),
Action::Learn(args, hint) => cmd_learn(&args, hint.as_deref()),
Action::Init(format) => cmd_init(format),
Action::Patterns => cmd_patterns(),
};
std::process::exit(exit_code);
}