use clap::Parser;
use double_o::{
Action, check_and_clear_learn_status, cmd_forget, cmd_help, cmd_hook, cmd_init, cmd_learn,
cmd_patterns, cmd_recall, cmd_rewrite, 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 indexed output");
println!(" forget Clear indexed output for this project");
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 claude|generic | --agent pi|claude-code [--global]] Set up hooks for agent frameworks (see: oo init --help)"
);
println!(" patterns List output compression patterns");
println!(" rewrite <command...> Print oo-prefixed form for agent hooks");
println!(
" hook <agent> Agent hook processor (e.g. `oo hook claude` reads PreToolUse JSON on stdin)"
);
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::Usage(text) => {
print!("{text}");
0
}
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(mode) => cmd_init(mode),
Action::Patterns => cmd_patterns(),
Action::Rewrite(command) => cmd_rewrite(&command),
Action::Hook(agent) => match agent {
Some(agent) => cmd_hook(&agent),
None => {
eprintln!("oo: hook requires an agent (e.g. `oo hook claude`)");
1
}
},
};
std::process::exit(exit_code);
}