255 lines
9.2 KiB
Rust
255 lines
9.2 KiB
Rust
//! Command line interface definition (clap v4, derive API).
|
|
|
|
use clap::{ArgAction, Args, Parser, Subcommand};
|
|
use clap_complete::Shell;
|
|
use std::path::PathBuf;
|
|
|
|
/// Manage local AI coding agents: install, start, stop, update.
|
|
#[derive(Parser, Debug, Clone)]
|
|
#[command(
|
|
name = "am",
|
|
bin_name = "am",
|
|
version,
|
|
// The help subcommand is provided by the custom Nushell-style help
|
|
// (cli::Command::Help) instead of clap's generated one.
|
|
disable_help_subcommand = true,
|
|
about = "agent-manager (am) — manage local AI coding agents",
|
|
long_about = "agent-manager (am) — a CLI to manage local AI coding agents.
|
|
|
|
Install, uninstall, start, stop, restart and update AI agents from a YAML
|
|
catalog. Handles dependencies (Node, Python, Go, Rust, Bun), binaries from
|
|
GitHub Releases, install scripts, and git repositories. All state lives under
|
|
your user directories; nothing pollutes the system."
|
|
)]
|
|
pub struct Cli {
|
|
/// Use an alternate configuration file
|
|
#[arg(short = 'c', long, global = true, value_name = "FILE")]
|
|
pub config: Option<PathBuf>,
|
|
|
|
/// Verbose output: show every command executed and its details
|
|
#[arg(short = 'v', long, global = true, action = ArgAction::SetTrue)]
|
|
pub verbose: bool,
|
|
|
|
/// Quiet mode: only errors are printed
|
|
#[arg(short = 'q', long, global = true, conflicts_with = "verbose", action = ArgAction::SetTrue)]
|
|
pub quiet: bool,
|
|
|
|
/// Answer yes to every confirmation prompt
|
|
#[arg(short = 'y', long, global = true, action = ArgAction::SetTrue)]
|
|
pub yes: bool,
|
|
|
|
/// Simulate the action without changing anything
|
|
#[arg(long, global = true, action = ArgAction::SetTrue)]
|
|
pub dry_run: bool,
|
|
|
|
/// Emit machine-readable JSON on stdout (for scripts)
|
|
#[arg(long, global = true, action = ArgAction::SetTrue)]
|
|
pub json: bool,
|
|
|
|
/// Disable ANSI colors
|
|
#[arg(long, global = true, action = ArgAction::SetTrue)]
|
|
pub no_color: bool,
|
|
|
|
/// Color theme for the output (see 'am help theme' for the list)
|
|
#[arg(long, global = true, value_name = "THEME")]
|
|
pub theme: Option<String>,
|
|
|
|
#[command(subcommand)]
|
|
pub command: Option<Command>,
|
|
}
|
|
|
|
#[derive(Subcommand, Debug, Clone)]
|
|
pub enum Command {
|
|
/// List installed agents (default); use --all for the whole catalog
|
|
List {
|
|
/// Show every agent known to the catalog, not only the installed ones
|
|
#[arg(long)]
|
|
all: bool,
|
|
/// Only show agents of this category
|
|
#[arg(long, value_name = "CATEGORY")]
|
|
category: Option<String>,
|
|
},
|
|
/// Start an agent (foreground by default, or detached with --background)
|
|
Start(StartArgs),
|
|
/// Stop a background agent (SIGTERM, then SIGKILL after the timeout)
|
|
Stop {
|
|
/// Agent name, alias, or group:<name>
|
|
agent: String,
|
|
/// Kill immediately instead of terminating gracefully
|
|
#[arg(long)]
|
|
force: bool,
|
|
/// Grace period in seconds before killing (default: from config, 5s)
|
|
#[arg(long, value_name = "SECS")]
|
|
timeout: Option<u64>,
|
|
},
|
|
/// Restart an agent: stop, then start with the same options
|
|
Restart {
|
|
#[command(flatten)]
|
|
start: StartArgs,
|
|
/// Kill immediately instead of terminating gracefully
|
|
#[arg(long)]
|
|
force: bool,
|
|
/// Grace period in seconds before killing (default: from config, 5s)
|
|
#[arg(long, value_name = "SECS")]
|
|
timeout: Option<u64>,
|
|
},
|
|
/// Show the state of one agent, or of every installed agent
|
|
Status {
|
|
/// Agent name or alias (omit to show all installed agents)
|
|
agent: Option<String>,
|
|
},
|
|
/// List the sessions of every agent (and of the interactive shell)
|
|
Sessions {
|
|
/// Only sessions of this agent
|
|
agent: Option<String>,
|
|
/// Only sessions of this project
|
|
#[arg(long, value_name = "PROJECT")]
|
|
project: Option<String>,
|
|
/// Only sessions with this status (running, stopped, failed, interrupted)
|
|
#[arg(long, value_name = "STATUS")]
|
|
status: Option<String>,
|
|
/// Show one session in detail (summary + log excerpt)
|
|
#[arg(long, value_name = "ID")]
|
|
show: Option<String>,
|
|
},
|
|
/// Install an agent and its dependencies
|
|
Install {
|
|
/// Agent name or alias
|
|
agent: String,
|
|
/// Select the install method (index, or type: npm, pip, uv, cargo, go, bun, curl, binary, git)
|
|
#[arg(long, value_name = "METHOD")]
|
|
method: Option<String>,
|
|
/// Reinstall even if already installed
|
|
#[arg(long)]
|
|
force: bool,
|
|
},
|
|
/// Uninstall an agent (managed or external) and clean its files
|
|
Uninstall {
|
|
/// Agent name or alias
|
|
agent: String,
|
|
/// Also remove logs and the agent entry from the user config file
|
|
#[arg(long)]
|
|
purge: bool,
|
|
},
|
|
/// Update an installed agent to the latest available version
|
|
Update {
|
|
/// Agent name or alias (required unless --all)
|
|
agent: Option<String>,
|
|
/// Update every installed managed agent
|
|
#[arg(long)]
|
|
all: bool,
|
|
},
|
|
/// Search the catalog by keyword (name, description, category, tags)
|
|
Search {
|
|
/// Keyword to search for (case-insensitive substring)
|
|
keyword: String,
|
|
/// Restrict to this category
|
|
#[arg(long, value_name = "CATEGORY")]
|
|
category: Option<String>,
|
|
},
|
|
/// Show detailed information about one agent
|
|
Info {
|
|
/// Agent name or alias
|
|
agent: String,
|
|
},
|
|
/// Display help: the overview, a command, the command list, or a search
|
|
Help {
|
|
/// Command name (also accepts an agent name or alias); "commands" lists every command
|
|
command: Option<String>,
|
|
/// Search through all help commands table
|
|
#[arg(long, value_name = "TEXT")]
|
|
find: Option<String>,
|
|
},
|
|
/// Display version and build information
|
|
Version,
|
|
/// Manage the configuration file
|
|
#[command(subcommand)]
|
|
Config(ConfigCmd),
|
|
/// Check the environment: tools, config validity, paths, permissions
|
|
Doctor {
|
|
/// Attempt to repair problems (create directories, fix the state file)
|
|
#[arg(long)]
|
|
fix: bool,
|
|
},
|
|
/// Run the agent command directly with the given arguments (no process management)
|
|
Run {
|
|
/// Agent name or alias
|
|
agent: String,
|
|
/// Arguments passed through to the agent command
|
|
#[arg(trailing_var_arg = true, allow_hyphen_values = true, value_name = "ARGS...")]
|
|
args: Vec<std::ffi::OsString>,
|
|
},
|
|
/// Generate a shell completion script
|
|
Completion {
|
|
/// Shell to generate completions for
|
|
#[arg(value_enum, value_name = "SHELL")]
|
|
shell: Shell,
|
|
},
|
|
/// Update agent-manager itself from GitHub Releases
|
|
SelfUpdate {
|
|
/// Only check whether a newer version exists
|
|
#[arg(long)]
|
|
check: bool,
|
|
/// Download the new binary to this path instead of replacing the current one
|
|
#[arg(long, value_name = "FILE")]
|
|
to: Option<PathBuf>,
|
|
},
|
|
/// Remove agent-manager and everything it created from this machine
|
|
///
|
|
/// Stops every managed background agent, then deletes the data, state and
|
|
/// configuration directories, and finally the executable itself. Combine
|
|
/// with --yes for a fully automated one-liner.
|
|
SelfUninstall,
|
|
/// Export the configuration and installation state (backup)
|
|
Export {
|
|
/// Output file (default: am-export.json)
|
|
#[arg(long, value_name = "FILE", default_value = "am-export.json")]
|
|
output: PathBuf,
|
|
},
|
|
/// Import a previously exported configuration and state
|
|
Import {
|
|
/// File exported by the export command
|
|
file: PathBuf,
|
|
},
|
|
}
|
|
|
|
/// Arguments shared by start and restart.
|
|
#[derive(Args, Debug, Clone, Default)]
|
|
pub struct StartArgs {
|
|
/// Agent name, alias, or group:<name>
|
|
pub agent: String,
|
|
/// Run detached in the background; output goes to the agent log file
|
|
#[arg(short = 'b', long, conflicts_with = "foreground", action = ArgAction::SetTrue)]
|
|
pub background: bool,
|
|
/// Run in the foreground, attached to this terminal (the default)
|
|
#[arg(short = 'f', long, action = ArgAction::SetTrue)]
|
|
pub foreground: bool,
|
|
/// Extra arguments passed to the agent (repeatable; quoted strings are split on spaces)
|
|
#[arg(long, value_name = "ARGS", num_args = 0.., action = ArgAction::Append)]
|
|
pub args: Vec<String>,
|
|
/// Set an environment variable for the agent (repeatable): --env KEY=VALUE
|
|
#[arg(long, value_name = "KEY=VALUE", action = ArgAction::Append)]
|
|
pub env: Vec<String>,
|
|
/// Send a desktop notification once the agent has started
|
|
#[arg(long, action = ArgAction::SetTrue)]
|
|
pub notify: bool,
|
|
}
|
|
|
|
/// Configuration management subcommands.
|
|
#[derive(Subcommand, Debug, Clone)]
|
|
pub enum ConfigCmd {
|
|
/// Print the effective (merged) configuration as YAML
|
|
Show,
|
|
/// Print the location of the configuration file(s)
|
|
Path,
|
|
/// Open the user configuration file in your editor
|
|
Edit,
|
|
/// Validate the configuration file(s)
|
|
Validate,
|
|
/// Add another agent definition file to the user configuration
|
|
Add {
|
|
/// YAML (or JSON) file defining agents to include
|
|
file: PathBuf,
|
|
},
|
|
}
|