Files
agent-manager/src/cli.rs
T
bruno 6d51ce9504 feat: v0.7.0 — am run/start --provider/--model : résolution cloud via le registre (base_url + keyring + modèle), fallback cloud quand le modèle local est inconnu, canal model_env/model_arg/env_map, jamais de token en clair (closes #92)
- 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é
2026-08-19 21:05:39 -04:00

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,
},
}