2
0
Files
shell/src/main.rs

154 lines
7.1 KiB
Rust

use std::env;
fn parse_flag(flag: &str) -> Option<String> {
let args: Vec<String> = env::args().collect();
args.iter().position(|a| a == flag).and_then(|i| args.get(i + 1).cloned())
}
// ascii-image-converter -W 30 -b ai.png
const LOGO: &str = "\
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⣤⣿⣿⣿⣿⣿⣿⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⠟⠉⠀⠀⠀⠀⠉⠻⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠘⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⢀⣾⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣷⡀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⣠⣿⣿⣿⣿⣿⣿⣦⣀⠀⠀⠀⠀⣀⣴⣿⣿⣿⣿⣿⣿⣄⠀⠀⠀⠀
⠀⠀⢀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⡀⠀⠀
⠀⠀⠈⠁⠀⠀⠀⠀⠀⠀⠉⠛⠿⠿⠿⠿⠿⠿⠛⠉⠀⠀⠀⠀⠀⠀⠈⠁⠀⠀";
fn main() {
match env::args().nth(1).as_deref() {
Some("v" | "version" | "--version" | "-v") => {
println!("{}", env!("CARGO_PKG_VERSION"));
}
Some("help" | "--help" | "-h") => print_help(),
None | Some("tui") => {
// Show logo before entering alternate screen
eprintln!("\x1b[38;5;226m{}\x1b[0m\n\x1b[1m aishell\x1b[0m v{}\n",
LOGO, env!("CARGO_PKG_VERSION"));
let config_path = parse_flag("-f");
if let Err(e) = aishell::tui::run(config_path.as_deref()) {
eprintln!("aishell: {}", e);
std::process::exit(1);
}
}
Some("run") => {
// -p preset
if let Some(preset_name) = parse_flag("-p") {
match aishell::config::preset(&preset_name) {
Some(_) => {
if let Err(e) = aishell::headless::run_preset(&preset_name) {
eprintln!("aishell: {e}");
std::process::exit(1);
}
}
None => {
eprintln!("unknown preset: {preset_name}");
eprintln!("available: daily, review, improve");
std::process::exit(1);
}
}
} else {
let config_or_task = parse_flag("-f")
.or_else(|| {
let all: Vec<String> = env::args().skip(2).collect();
let mut parts = Vec::new();
let mut skip = false;
for a in &all {
if skip { skip = false; continue; }
if a == "-c" || a == "-n" || a == "-f" || a == "-p" { skip = true; continue; }
parts.push(a.clone());
}
if parts.is_empty() { None } else { Some(parts.join(" ")) }
})
.unwrap_or_else(|| {
eprintln!("usage: aishell run <task>");
eprintln!(" aishell run -f <config>");
eprintln!(" aishell run -p <preset> (daily|review|improve)");
std::process::exit(1);
});
let cwd = parse_flag("-c");
let name = parse_flag("-n");
if let Err(e) = aishell::headless::run(&config_or_task, cwd.as_deref(), name.as_deref()) {
eprintln!("aishell: {e}");
std::process::exit(1);
}
}
}
Some("status") => {
let verbose = env::args().any(|a| a == "-v" || a == "--verbose");
aishell::headless::status(verbose);
}
Some("log") => {
let id = env::args().nth(2).unwrap_or_else(|| {
eprintln!("usage: aishell log <id|name>");
std::process::exit(1);
});
aishell::headless::log(&id);
}
Some("decision") => aishell::headless::decision(),
Some("commit") => aishell::headless::commit(),
Some("context") => aishell::headless::context(),
Some("remember") => aishell::headless::remember(),
Some("history") => {
let sub = env::args().nth(2);
match sub.as_deref() {
Some("cmd") => {
let filter = env::args().nth(3);
aishell::headless::history_cmd(filter.as_deref());
}
Some("clean") => aishell::headless::history_clean(),
other => aishell::headless::history(other),
}
}
Some("watch") => {
let dir = env::args().nth(2).unwrap_or_else(|| ".".to_string());
let config = parse_flag("-f");
if let Err(e) = aishell::watch::run(&dir, config.as_deref()) {
eprintln!("aishell: {}", e);
std::process::exit(1);
}
}
Some("next") => {
let save: Vec<usize> = env::args().skip(2)
.filter_map(|s| s.parse().ok())
.collect();
aishell::headless::signal_next(save);
}
Some("stop") => aishell::headless::signal_quit(),
Some(cmd) => {
eprintln!("unknown: {cmd}");
eprintln!("try: aishell help");
std::process::exit(1);
}
}
}
fn print_help() {
println!("aishell v{}\n", env!("CARGO_PKG_VERSION"));
println!("USAGE:");
println!(" aishell TUI (AI + Agents + Shell)");
println!(" aishell run <task> Run single agent");
println!(" aishell run -p <preset> Preset: daily, review, improve");
println!(" aishell run -f <config> Custom config file");
println!(" aishell commit Git commit with AI-suggested message");
println!(" aishell status [-v] Show agent status");
println!(" aishell log <id|name> Show agent output");
println!(" aishell decision Show AI integration result");
println!(" aishell context Full project context (for AI)");
println!(" aishell remember Save latest decision to AI memory");
println!(" aishell history [id] Show past sessions");
println!(" aishell history cmd [grep] Command history (filterable)");
println!(" aishell history clean Remove old sessions (keep 10)");
println!(" aishell watch <dir> [-f cfg] Watch files, auto-trigger loop");
println!(" aishell next Resume loop");
println!(" aishell stop Stop the loop");
println!(" aishell help This help");
println!(" aishell v Version");
}