131 lines
4.2 KiB
Rust
131 lines
4.2 KiB
Rust
//! agent-manager — a CLI to manage local AI coding agents.
|
|
//!
|
|
//! The crate is organised around a few core concepts:
|
|
//!
|
|
//! * cli — clap definitions for the am command line interface.
|
|
//! * config — YAML schema, loading, validation, includes, path expansion.
|
|
//! * catalog — the merged agent catalog (embedded defaults + user config).
|
|
//! * state — the local installation database (JSON file).
|
|
//! * process — background/foreground process management (PID bookkeeping).
|
|
//! * installers — one installer per method (npm, pip, cargo, go, bun, curl,
|
|
//! binary, git).
|
|
//! * commands — one module per CLI command.
|
|
|
|
pub mod app;
|
|
pub mod automation;
|
|
pub mod backup;
|
|
pub mod catalog;
|
|
pub mod costs;
|
|
pub mod templates;
|
|
pub mod catalog_remote;
|
|
pub mod cli;
|
|
pub mod commands;
|
|
pub mod config;
|
|
pub mod context;
|
|
pub mod dashboard;
|
|
pub mod deps;
|
|
pub mod doctor;
|
|
pub mod download;
|
|
pub mod events;
|
|
pub mod help;
|
|
pub mod history;
|
|
pub mod hooks;
|
|
pub mod i18n;
|
|
pub mod installers;
|
|
pub mod lab;
|
|
pub mod models;
|
|
pub mod nav;
|
|
pub mod output;
|
|
pub mod probe;
|
|
pub mod projects;
|
|
pub mod ps;
|
|
pub mod process;
|
|
pub mod repl;
|
|
pub mod runner;
|
|
pub mod secrets;
|
|
pub mod sessions;
|
|
pub mod shell;
|
|
pub mod state;
|
|
pub mod sync;
|
|
pub mod playbook;
|
|
pub mod plugins;
|
|
pub mod tables;
|
|
pub mod theme;
|
|
pub mod toolchain;
|
|
pub mod version;
|
|
|
|
use clap::Parser;
|
|
|
|
/// CLI entry point used by the am binary. Returns the process exit code.
|
|
///
|
|
/// The whole run happens on a dedicated thread with a large stack: clap's
|
|
/// derive code for the full command tree (40+ subcommands) uses deep stack
|
|
/// frames in debug builds, which overflows the Windows main-thread default
|
|
/// (1 MB). An 8 MB thread keeps every build mode on every platform safe.
|
|
pub fn main_entry() -> i32 {
|
|
std::thread::Builder::new()
|
|
.name("am-main".to_string())
|
|
.stack_size(8 * 1024 * 1024)
|
|
.spawn(real_main)
|
|
.expect("cannot spawn the am main thread")
|
|
.join()
|
|
.unwrap_or(1)
|
|
}
|
|
|
|
/// The actual entry point, running on the big-stack thread.
|
|
fn real_main() -> i32 {
|
|
// Enable ANSI escape sequences on Windows consoles (best effort): the
|
|
// colored crate and the theme palettes both emit raw VT codes.
|
|
#[cfg(windows)]
|
|
let _ = colored::control::set_virtual_terminal(true);
|
|
|
|
// Nushell-style help: 'am -h', 'am install -h', 'am ls --help', ... all
|
|
// show the custom help before clap gets a chance to parse the line.
|
|
let args: Vec<String> = std::env::args().collect();
|
|
if let Some(code) = help::intercept(&args) {
|
|
return code;
|
|
}
|
|
let cli = cli::Cli::parse();
|
|
// Issue #74: resolve the output language before anything else so even
|
|
// config errors are localized; the REPL can switch it at runtime.
|
|
i18n::set_lang(i18n::resolve(cli.lang));
|
|
match app::App::from_cli(cli) {
|
|
Ok(app) => {
|
|
// Issue #53: enforce the session retention at every startup
|
|
// (silent; the primary event journal is never touched).
|
|
let days = app
|
|
.config
|
|
.settings
|
|
.sessions_retention_days
|
|
.unwrap_or(sessions::DEFAULT_RETENTION_DAYS);
|
|
if let Err(e) = sessions::purge_expired(&app, days) {
|
|
app.log.verbose(&format!("session retention skipped: {e:#}"));
|
|
}
|
|
match commands::execute(&app) {
|
|
Ok(code) => code,
|
|
Err(err) => {
|
|
if app.json() {
|
|
let payload = serde_json::json!({
|
|
"error": format!("{:#}", err),
|
|
});
|
|
let _ = serde_json::to_writer_pretty(std::io::stdout(), &payload);
|
|
let _ = writeln!(std::io::stdout());
|
|
} else {
|
|
eprintln!("{} {}", "error:".red().bold(), format!("{:#}", err));
|
|
}
|
|
1
|
|
}
|
|
}
|
|
}
|
|
Err(err) => {
|
|
// Config could not even be loaded: fall back to plain stderr output.
|
|
eprintln!("{} {}", "error:".red().bold(), format!("{:#}", err));
|
|
1
|
|
}
|
|
}
|
|
}
|
|
|
|
#[allow(unused_imports)]
|
|
use colored::Colorize;
|
|
use std::io::Write;
|