- apply_provider : providers::resolve_for (flag > agent > défaut) + apply_env_map_resolved (api_key = @secret, base_url/model du provider résolu) - start/run/restart : --provider et --model dans le CLI, le REPL et la complétion ; specs help + man pages - Tests unitaires : résolution, cascade, canal déclaré, erreur provider inconnu (liste), absence de fuite (env sans valeur sk-), fallback embarqué
845 lines
30 KiB
Rust
845 lines
30 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>,
|
|
|
|
/// Output language: fr (default) or en (issue #74)
|
|
#[arg(long, global = true, value_enum, value_name = "LANG")]
|
|
pub lang: Option<crate::i18n::LangArg>,
|
|
|
|
#[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>,
|
|
/// Only show running agents
|
|
#[arg(long)]
|
|
running: bool,
|
|
/// Sort by name, version or status (default: name)
|
|
#[arg(long, value_name = "KEY")]
|
|
sort: Option<String>,
|
|
},
|
|
/// Tail the log file of an agent (--follow for a live view)
|
|
Logs {
|
|
/// Agent name or alias
|
|
agent: String,
|
|
/// Number of lines to show (default: 20)
|
|
#[arg(long, value_name = "N", default_value = "20")]
|
|
lines: usize,
|
|
/// Follow the log as it grows
|
|
#[arg(long)]
|
|
follow: bool,
|
|
},
|
|
/// Open an agent's installation directory in the file manager
|
|
Open {
|
|
/// Agent name or alias
|
|
agent: String,
|
|
},
|
|
/// Supervise an agent and optionally restart it on crash
|
|
Watch {
|
|
/// Agent name or alias
|
|
agent: String,
|
|
/// Restart the agent automatically when it dies (with backoff)
|
|
#[arg(long)]
|
|
restart: bool,
|
|
/// Desktop notification on every restart
|
|
#[arg(long)]
|
|
notify: bool,
|
|
/// Check interval in seconds (default: 5)
|
|
#[arg(long, value_name = "SECS", default_value = "5")]
|
|
interval: u64,
|
|
},
|
|
/// Live TUI dashboard: overview, activity, stats, sessions, projects
|
|
Dashboard,
|
|
/// Mark an agent as a favorite (star in list and status)
|
|
Favorite {
|
|
/// Agent name or alias
|
|
agent: String,
|
|
},
|
|
/// Remove the favorite star from an agent
|
|
Unfavorite {
|
|
/// Agent name or alias
|
|
agent: String,
|
|
},
|
|
/// Attach a free-form note to an agent (shown in 'am info');
|
|
/// 'am note <agent>' without text prints the current note
|
|
Note {
|
|
/// Agent name or alias
|
|
agent: String,
|
|
/// Note text (several words are joined); empty prints the note
|
|
#[arg(value_name = "TEXT...", num_args = 0..)]
|
|
text: Vec<String>,
|
|
},
|
|
/// Add a personal tag to an agent
|
|
Tag {
|
|
/// Agent name or alias
|
|
agent: String,
|
|
/// One or more tags to add
|
|
#[arg(value_name = "TAG", num_args = 1.., required = true)]
|
|
words: Vec<String>,
|
|
},
|
|
/// Remove a personal tag from an agent
|
|
Untag {
|
|
/// Agent name or alias
|
|
agent: String,
|
|
/// Tag to remove
|
|
tag: String,
|
|
},
|
|
/// List personal tags (with counts), optionally for one agent
|
|
Tags {
|
|
/// Only show the tags of this agent
|
|
agent: Option<String>,
|
|
},
|
|
/// Manage environment profiles (dev, prod, ...)
|
|
#[command(subcommand)]
|
|
Profile(ProfileCmd),
|
|
/// Generate a man page for am (or for one command)
|
|
Man {
|
|
/// Command name (omit for the whole CLI)
|
|
command: Option<String>,
|
|
/// Write the page(s) to this directory instead of stdout
|
|
#[arg(long, value_name = "DIR")]
|
|
output: Option<PathBuf>,
|
|
},
|
|
/// Set or show the active color theme (persisted for the next run)
|
|
Theme {
|
|
/// Theme name (omit to list available themes)
|
|
name: Option<String>,
|
|
},
|
|
/// Internal: list agent names for shell completions (hidden)
|
|
#[command(name = "_agents", hide = true)]
|
|
Agents {
|
|
/// Only installed agents (managed + external), aliases and groups
|
|
#[arg(long)]
|
|
installed: bool,
|
|
},
|
|
/// Manage command aliases (cc -> claude-code)
|
|
#[command(subcommand)]
|
|
Alias(AliasCmd),
|
|
/// Manage secrets in the OS keyring (never in plaintext config)
|
|
#[command(subcommand)]
|
|
Secret(SecretCmd),
|
|
/// Audit the configuration: who changed what, when (issue #63)
|
|
Audit,
|
|
/// Register an agent as a system service (issue #55)
|
|
#[command(subcommand)]
|
|
Service(ServiceCmd),
|
|
/// Schedule am commands (issue #56)
|
|
#[command(subcommand)]
|
|
Schedule(ScheduleCmd),
|
|
/// List local models (ollama, llama.cpp, LM Studio) and prune unused ones
|
|
Models(ModelsArgs),
|
|
/// Manage remote catalogs: update the official one, add external ones
|
|
#[command(subcommand)]
|
|
Catalog(CatalogCmd),
|
|
/// Manage the LLM provider registry: base URLs, models, default provider
|
|
Providers(ProviderArgs),
|
|
/// Suggest agents matching a query, boosted by real usage (issue #61)
|
|
Suggest {
|
|
/// Free-form request ("un agent pour du Python")
|
|
#[arg(value_name = "QUERY", num_args = 1.., required = true)]
|
|
words: Vec<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>,
|
|
/// Resume a finished session: relaunch the agent with its recorded arguments
|
|
#[arg(long, value_name = "ID")]
|
|
resume: Option<String>,
|
|
/// Export one session (metadata, commands, log excerpt) to a JSON file
|
|
#[arg(long, value_name = "ID")]
|
|
export: Option<String>,
|
|
/// Destination of the export (default: ./am-session-<ID>.json)
|
|
#[arg(long, value_name = "FILE")]
|
|
output: Option<String>,
|
|
/// Purge sessions finished more than N days ago (settings default 90)
|
|
#[arg(long, value_name = "DAYS")]
|
|
retention: Option<u64>,
|
|
},
|
|
/// Show usage statistics computed from the event journal
|
|
Stats {
|
|
/// Agent name or alias (omit for the global view)
|
|
agent: Option<String>,
|
|
/// Only events of the last period (7d, 30d, 90d, all)
|
|
#[arg(long, value_name = "PERIOD")]
|
|
period: Option<String>,
|
|
/// Show token usage and estimated spend per agent (issue #49)
|
|
#[arg(long, action = ArgAction::SetTrue)]
|
|
costs: bool,
|
|
},
|
|
/// Real-time monitor of the managed processes (issue #50)
|
|
Monitor {
|
|
/// Refresh interval in seconds (default 2)
|
|
#[arg(long, value_name = "SECONDS")]
|
|
interval: Option<u64>,
|
|
/// Print one JSON document per tick instead of the TUI
|
|
#[arg(long, action = ArgAction::SetTrue)]
|
|
json: bool,
|
|
},
|
|
/// Local read-only web dashboard with charts (issue #54)
|
|
Web(WebArgs),
|
|
/// Push the state into the configured git repository (issue #66)
|
|
Sync {
|
|
/// Commit message (default: "am sync — state update")
|
|
#[arg(long, value_name = "MESSAGE")]
|
|
message: Option<String>,
|
|
},
|
|
/// Transfer the installation and state to another machine (issue #68)
|
|
Migrate {
|
|
/// Export the bundle (default) or import one
|
|
#[arg(long, action = ArgAction::SetTrue)]
|
|
export: bool,
|
|
/// Bundle path for export (default agent-manager-migrate.amx)
|
|
#[arg(long, value_name = "FILE")]
|
|
output: Option<PathBuf>,
|
|
/// Bundle path to import
|
|
#[arg(value_name = "BUNDLE")]
|
|
bundle: Option<PathBuf>,
|
|
},
|
|
/// Show the most used agents (top 10)
|
|
Top {
|
|
/// Only events of the last period (7d, 30d, 90d, all)
|
|
#[arg(long, value_name = "PERIOD")]
|
|
period: Option<String>,
|
|
},
|
|
/// Write a markdown activity report
|
|
Report {
|
|
/// Cover the last 7 days
|
|
#[arg(long, conflicts_with = "last_month")]
|
|
last_week: bool,
|
|
/// Cover the last 30 days
|
|
#[arg(long)]
|
|
last_month: bool,
|
|
/// Output file (default: report-YYYYMMDD.md in the state directory)
|
|
#[arg(long, value_name = "FILE")]
|
|
output: Option<PathBuf>,
|
|
},
|
|
/// Show which agent works on which project
|
|
Projects {
|
|
/// Project name (omit to list every project)
|
|
name: Option<String>,
|
|
},
|
|
/// One chronological view of every activity (journal + REPL history)
|
|
Timeline {
|
|
/// Only activity of this agent
|
|
agent: Option<String>,
|
|
/// Only activity of this project
|
|
#[arg(long, value_name = "PROJECT")]
|
|
project: Option<String>,
|
|
/// Only activity at or after this date (YYYY-MM-DD or RFC 3339)
|
|
#[arg(long, value_name = "DATE")]
|
|
since: Option<String>,
|
|
/// Maximum number of entries (default: 50)
|
|
#[arg(long, value_name = "N", default_value = "50")]
|
|
limit: usize,
|
|
},
|
|
/// Read the event journal: everything am did
|
|
Log {
|
|
/// Only events of this agent
|
|
agent: Option<String>,
|
|
/// Only these event kinds (comma separated: start,stop,run,install,...)
|
|
#[arg(long, value_name = "KINDS")]
|
|
kind: Option<String>,
|
|
/// Only events at or after this date (YYYY-MM-DD or RFC 3339)
|
|
#[arg(long, value_name = "DATE")]
|
|
since: Option<String>,
|
|
/// Maximum number of events (default: 50)
|
|
#[arg(long, value_name = "N", default_value = "50")]
|
|
limit: usize,
|
|
/// Follow the journal as new events arrive
|
|
#[arg(long)]
|
|
follow: bool,
|
|
},
|
|
/// 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,
|
|
/// Provider to configure (default: the agent's provider, else settings.default_provider) (issue #90)
|
|
#[arg(long, value_name = "PROVIDER")]
|
|
provider: Option<String>,
|
|
/// Model to configure (default: the provider's default model) (issue #90)
|
|
#[arg(long, value_name = "MODEL")]
|
|
model: Option<String>,
|
|
/// Skip the post-install provider configuration (issue #91)
|
|
#[arg(long)]
|
|
no_config: 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,
|
|
/// Roll back to a pre-update backup instead of updating
|
|
/// ("latest" or a backup id; "--rollback list" shows them)
|
|
#[arg(long, num_args = 0..=1, default_missing_value = "latest")]
|
|
rollback: Option<String>,
|
|
},
|
|
/// Search the catalog by keyword (name, description, category, tags)
|
|
Search {
|
|
/// Keyword to search for (case-insensitive substring)
|
|
#[arg(value_name = "KEYWORD", required_unless_present = "tag")]
|
|
keyword: Option<String>,
|
|
/// Restrict to this category
|
|
#[arg(long, value_name = "CATEGORY")]
|
|
category: Option<String>,
|
|
/// Only agents carrying this personal tag
|
|
#[arg(long, value_name = "TAG")]
|
|
tag: Option<String>,
|
|
},
|
|
/// Search the command history (am and shell commands)
|
|
History {
|
|
/// Only commands of this kind (am or shell)
|
|
#[arg(long, value_name = "KIND")]
|
|
kind: Option<String>,
|
|
/// Only commands run in this directory
|
|
#[arg(long, value_name = "DIR")]
|
|
cwd: Option<String>,
|
|
/// Full-text search in the command line
|
|
#[arg(long, value_name = "TEXT")]
|
|
search: Option<String>,
|
|
/// Only failed commands
|
|
#[arg(long)]
|
|
failed: bool,
|
|
/// Only commands of this session
|
|
#[arg(long, value_name = "ID")]
|
|
session: Option<String>,
|
|
/// Maximum number of entries (default: 100)
|
|
#[arg(long, value_name = "N", default_value = "100")]
|
|
limit: usize,
|
|
/// Re-run the Nth most recent entry (with confirmation)
|
|
#[arg(long, value_name = "N")]
|
|
rerun: Option<usize>,
|
|
/// Range to export as a playbook: "12..25" (1-based, newest first)
|
|
#[arg(value_name = "RANGE")]
|
|
range: Option<String>,
|
|
/// Export the range as a playbook YAML file (issue #51)
|
|
#[arg(long, value_name = "FILE")]
|
|
save: Option<PathBuf>,
|
|
},
|
|
/// Replay a saved playbook step by step with confirmation (issue #51)
|
|
Playbook {
|
|
/// Playbook file (state_dir/playbooks/ when a bare name is given)
|
|
#[arg(value_name = "FILE")]
|
|
path: PathBuf,
|
|
/// Variable values, repeatable: --var name=value
|
|
#[arg(long, value_name = "NAME=VALUE")]
|
|
var: Vec<String>,
|
|
},
|
|
/// Benchmark: run the same task on several agents and compare (issue #62)
|
|
Lab(LabArgs),
|
|
/// List the event plugins and test one (issue #75)
|
|
Plugins(PluginsArgs),
|
|
/// Show detailed information about one agent
|
|
Info {
|
|
/// Agent name or alias
|
|
agent: String,
|
|
},
|
|
/// Generate a local agent-manager.yaml for the current directory
|
|
Init {
|
|
/// Overwrite an existing agent-manager.yaml
|
|
#[arg(long)]
|
|
force: bool,
|
|
/// Use a template (web, python, rust, cli) instead of stack detection;
|
|
/// "list" shows the available templates
|
|
#[arg(long, value_name = "TEMPLATE")]
|
|
template: Option<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,
|
|
/// Cheat sheet: the most useful commands, their key options, your
|
|
/// most-used commands and a rotating tip of the day
|
|
Tip {
|
|
/// Show a single random tip instead of the whole page
|
|
#[arg(long)]
|
|
random: bool,
|
|
},
|
|
/// 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,
|
|
/// Re-run the checks every N seconds, alerting on failure (issue #59)
|
|
#[arg(long, value_name = "SECONDS")]
|
|
watch: Option<u64>,
|
|
},
|
|
/// Run the agent command directly with the given arguments (no process management)
|
|
Run {
|
|
/// Agent name or alias
|
|
agent: String,
|
|
/// Local model to use for this run (validated against the local runtimes)
|
|
#[arg(long, value_name = "MODEL")]
|
|
model: Option<String>,
|
|
/// Provider to use for this run (issue #92): registry lookup, base_url + keyring token + model
|
|
#[arg(long, value_name = "PROVIDER")]
|
|
provider: Option<String>,
|
|
/// Run the agent inside a container (issue #58)
|
|
#[arg(long)]
|
|
container: bool,
|
|
/// 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,
|
|
/// Add dynamic completion of the installed agents, aliases and
|
|
/// groups (queried from 'am _agents' at Tab time)
|
|
#[arg(long)]
|
|
installed: bool,
|
|
},
|
|
/// Update agent-manager itself from the latest release
|
|
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> (defaults to the project's default agent)
|
|
pub agent: Option<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,
|
|
/// Apply an environment profile (env + args, defined in the config)
|
|
#[arg(long, value_name = "NAME")]
|
|
pub profile: Option<String>,
|
|
/// Local model to use for this run (validated against the local runtimes)
|
|
#[arg(long, value_name = "MODEL")]
|
|
pub model: Option<String>,
|
|
/// Provider to use for this run (issue #92): registry lookup, base_url + keyring token + model
|
|
#[arg(long, value_name = "PROVIDER")]
|
|
pub provider: Option<String>,
|
|
/// Start every member of a group simultaneously (issue #57)
|
|
#[arg(long, action = ArgAction::SetTrue)]
|
|
pub parallel: bool,
|
|
/// Run the agent inside a container (issue #58)
|
|
#[arg(long, action = ArgAction::SetTrue)]
|
|
pub container: bool,
|
|
}
|
|
|
|
/// Arguments of the models command: inventory by default, prune with --prune.
|
|
#[derive(Args, Debug, Clone, Default)]
|
|
pub struct ModelsArgs {
|
|
/// Purge unused models instead of listing them
|
|
#[arg(long)]
|
|
pub prune: bool,
|
|
/// Only list what would be pruned, delete nothing
|
|
#[arg(long, conflicts_with = "yes")]
|
|
pub dry_run: bool,
|
|
/// Answer yes to the deletion prompt
|
|
#[arg(long)]
|
|
pub yes: bool,
|
|
/// Consider a model unused after N days (default: 30)
|
|
#[arg(long, value_name = "DAYS")]
|
|
pub days: Option<u64>,
|
|
}
|
|
|
|
/// Arguments of the lab command (issue #62).
|
|
#[derive(Args, Debug, Clone, Default)]
|
|
pub struct LabArgs {
|
|
/// Comma-separated agent names (or aliases) to benchmark
|
|
#[arg(long, value_name = "AGENTS", required_unless_present = "list")]
|
|
pub agents: Option<String>,
|
|
/// Task file (a bare name resolves under state_dir/lab/, .yaml appended)
|
|
#[arg(long, value_name = "FILE", required_unless_present = "list")]
|
|
pub task: Option<PathBuf>,
|
|
/// Run every agent concurrently instead of one after another
|
|
#[arg(long, action = ArgAction::SetTrue)]
|
|
pub parallel: bool,
|
|
/// Override the task timeout in seconds
|
|
#[arg(long, value_name = "SECS")]
|
|
pub timeout: Option<u64>,
|
|
/// List the task files of the lab directory
|
|
#[arg(long, action = ArgAction::SetTrue)]
|
|
pub list: bool,
|
|
}
|
|
|
|
/// Arguments of the plugins command (issue #75).
|
|
#[derive(Args, Debug, Clone, Default)]
|
|
pub struct PluginsArgs {
|
|
/// Run one plugin against a synthetic event and print its response
|
|
#[arg(long, value_name = "NAME")]
|
|
pub test: Option<String>,
|
|
}
|
|
|
|
/// Arguments of the web command (issue #54).
|
|
#[derive(Args, Debug, Clone, Default)]
|
|
pub struct WebArgs {
|
|
/// Port to listen on (default 7878)
|
|
#[arg(long, value_name = "PORT")]
|
|
pub port: Option<u16>,
|
|
/// Do not open the browser automatically
|
|
#[arg(long, action = ArgAction::SetTrue)]
|
|
pub no_open: bool,
|
|
}
|
|
|
|
/// Remote catalog subcommands (issues #60 #67).
|
|
#[derive(Subcommand, Debug, Clone)]
|
|
pub enum CatalogCmd {
|
|
/// Fetch the official catalog, show the diff and register it as an include
|
|
Update,
|
|
/// Register an external catalog (same YAML format) by URL
|
|
Add {
|
|
/// Catalog URL (http, https or file)
|
|
#[arg(value_name = "URL")]
|
|
url: String,
|
|
},
|
|
/// List the registered remote catalogs
|
|
List,
|
|
}
|
|
|
|
/// LLM provider registry subcommands (issue #88). The subcommand is
|
|
/// optional: `am providers` alone lists the registry.
|
|
#[derive(Args, Debug, Clone, Default)]
|
|
pub struct ProviderArgs {
|
|
#[command(subcommand)]
|
|
pub sub: Option<ProvidersCmd>,
|
|
}
|
|
|
|
#[derive(Subcommand, Debug, Clone)]
|
|
pub enum ProvidersCmd {
|
|
/// List the registered providers (the default one is starred)
|
|
List,
|
|
/// Show one provider in detail (base URL, models, default model)
|
|
Show {
|
|
/// Provider name
|
|
name: String,
|
|
},
|
|
/// Register a provider, or update an existing one
|
|
Add {
|
|
/// Provider name (lowercase slug, e.g. openai)
|
|
name: String,
|
|
/// Base URL of the provider API
|
|
#[arg(long, value_name = "URL", required = true)]
|
|
base_url: String,
|
|
/// Model used by default for this provider
|
|
#[arg(long, value_name = "MODEL")]
|
|
model: Option<String>,
|
|
/// Comma-separated model list
|
|
#[arg(long, value_name = "MODELS")]
|
|
models: Option<String>,
|
|
},
|
|
/// Remove a provider from the registry
|
|
Remove {
|
|
/// Provider name
|
|
name: String,
|
|
},
|
|
/// Store the provider API token in the OS keyring (shared by every
|
|
/// agent of this provider through the @secret cascade, issue #89)
|
|
SetToken {
|
|
/// Provider name
|
|
name: String,
|
|
/// Token value (never logged)
|
|
#[arg(long, value_name = "VALUE")]
|
|
value: String,
|
|
},
|
|
/// Check whether a provider token exists (the value is never shown)
|
|
Token {
|
|
/// Provider name
|
|
name: String,
|
|
},
|
|
/// Set the default provider
|
|
Default {
|
|
/// Provider name
|
|
name: String,
|
|
},
|
|
}
|
|
|
|
/// Environment profile subcommands (issue #40).
|
|
#[derive(Subcommand, Debug, Clone)]
|
|
pub enum ProfileCmd {
|
|
/// List every defined profile
|
|
List,
|
|
/// Show one profile in detail (agent, env, args)
|
|
Show {
|
|
/// Profile name
|
|
name: String,
|
|
},
|
|
}
|
|
|
|
/// 'am service' subcommands (issue #55).
|
|
#[derive(Subcommand, Debug, Clone)]
|
|
pub enum ServiceCmd {
|
|
/// Install the service unit (systemd / launchd / Task Scheduler)
|
|
Install {
|
|
/// Agent name
|
|
agent: String,
|
|
/// Enable autostart (boot/logon)
|
|
#[arg(long)]
|
|
autostart: bool,
|
|
},
|
|
/// Remove the service unit
|
|
Uninstall {
|
|
/// Agent name
|
|
agent: String,
|
|
},
|
|
/// Show whether the service is installed
|
|
Status {
|
|
/// Agent name
|
|
agent: String,
|
|
},
|
|
}
|
|
|
|
/// 'am schedule' subcommands (issue #56).
|
|
#[derive(Subcommand, Debug, Clone)]
|
|
pub enum ScheduleCmd {
|
|
/// Add a daily schedule (ex: 'am schedule add update --all')
|
|
Add {
|
|
/// Command to run, e.g. ["update", "--all"]
|
|
#[arg(trailing_var_arg = true, allow_hyphen_values = true, value_name = "CMD...")]
|
|
command: Vec<String>,
|
|
/// Time of day HH:MM (default 08:00)
|
|
#[arg(long, value_name = "HH:MM")]
|
|
at: Option<String>,
|
|
},
|
|
/// List the schedules
|
|
List,
|
|
/// Remove a schedule by id
|
|
Remove {
|
|
/// Schedule id ('am schedule list' shows them)
|
|
id: String,
|
|
},
|
|
/// Run a schedule now (invoked by the OS task, issue #56)
|
|
Run {
|
|
/// Schedule id
|
|
id: String,
|
|
},
|
|
}
|
|
#[derive(Subcommand, Debug, Clone)]
|
|
pub enum SecretCmd {
|
|
/// Store a secret for an agent (or a provider, issue #89)
|
|
Set {
|
|
/// Secret name (the environment variable name)
|
|
name: String,
|
|
/// Agent it belongs to (required unless --provider is given)
|
|
#[arg(long, value_name = "AGENT")]
|
|
agent: Option<String>,
|
|
/// Provider it belongs to (shared by every agent of this provider)
|
|
#[arg(long, value_name = "PROVIDER")]
|
|
provider: Option<String>,
|
|
/// Secret value (prefer --value over shell history; never logged)
|
|
#[arg(long, value_name = "VALUE")]
|
|
value: String,
|
|
},
|
|
/// Remove a secret
|
|
Unset {
|
|
/// Secret name
|
|
name: String,
|
|
/// Agent it belongs to (required unless --provider is given)
|
|
#[arg(long, value_name = "AGENT")]
|
|
agent: Option<String>,
|
|
/// Provider it belongs to
|
|
#[arg(long, value_name = "PROVIDER")]
|
|
provider: Option<String>,
|
|
},
|
|
/// List stored secret names (values are never shown)
|
|
List,
|
|
}
|
|
|
|
/// Alias management subcommands.
|
|
#[derive(Subcommand, Debug, Clone)]
|
|
pub enum AliasCmd {
|
|
/// Add an alias (am alias add cc claude-code)
|
|
Add {
|
|
/// Short name of the alias
|
|
name: String,
|
|
/// Agent name (or another alias) it points to
|
|
target: String,
|
|
},
|
|
/// Remove an alias
|
|
Remove {
|
|
/// Alias to remove
|
|
name: String,
|
|
},
|
|
/// List every alias
|
|
List,
|
|
}
|
|
|
|
/// 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,
|
|
},
|
|
/// Set one configuration key without an editor (config set settings.default_shell pwsh)
|
|
Set {
|
|
/// Dotted key path, e.g. settings.default_shell
|
|
key: String,
|
|
/// New value (booleans and integers keep their type)
|
|
value: String,
|
|
},
|
|
}
|