feat: phase 2 — automatisation: doctor --watch, schedule, service, orchestration, conteneurs (closes #55 #56 #57 #58 #59)

This commit is contained in:
2026-08-18 10:57:00 -04:00
parent 6a6676fc5d
commit 63dc36660b
27 changed files with 1408 additions and 35 deletions
+58 -1
View File
@@ -110,6 +110,8 @@ const COMMAND_DESCRIPTIONS: &[(&str, &str)] = &[
("catalog", "manage remote catalogs"),
("suggest", "recommend an agent for a request"),
("audit", "who changed what, when (config checksums)"),
("service", "register an agent as a system service (autostart)"),
("schedule", "plan am commands (daily) and check the fleet health"),
("shell", "show or switch the system shell"),
("theme", "show or switch the color theme"),
("tip", "cheat sheet of the most useful commands"),
@@ -224,6 +226,7 @@ impl AmCompleter {
"self-update", "self-uninstall", "export", "import", "shell", "theme",
"tip", "dashboard", "favorite", "unfavorite", "note", "tag", "untag", "tags",
"profile", "man", "models", "catalog", "suggest", "audit",
"service", "schedule",
"ls", "dir", "cd", "ps", "where", "get", "help", "version", "exit",
],
config_sub: vec!["show", "path", "edit", "validate", "add"],
@@ -772,6 +775,9 @@ pub fn banner_box(
rows.push(inner(
" models models · models --prune · catalog · suggest · audit".to_string(),
));
rows.push(inner(
" automate service install · schedule add · doctor --watch".to_string(),
));
rows.push(inner(
" system self-update · self-uninstall · export · import".to_string(),
));
@@ -1632,12 +1638,63 @@ fn handle_line(
}
}
"audit" => Command::Audit,
"doctor" => Command::Doctor { fix: flag("--fix") },
"service" => match rest.first().map(|s| s.as_str()) {
Some(action) if rest.len() >= 2 => Command::Service(match action {
"install" => crate::cli::ServiceCmd::Install {
agent: rest[1].clone(),
autostart: flag("--autostart"),
},
"uninstall" => crate::cli::ServiceCmd::Uninstall {
agent: rest[1].clone(),
},
"status" => crate::cli::ServiceCmd::Status {
agent: rest[1].clone(),
},
_ => {
app.log
.error("usage: service install|uninstall|status <agent> [--autostart]");
return Ok(false);
}
}),
_ => {
app.log
.error("usage: service install|uninstall|status <agent> [--autostart]");
return Ok(false);
}
},
"schedule" => match rest.first().map(|s| s.as_str()) {
Some("add") => Command::Schedule(crate::cli::ScheduleCmd::Add {
command: rest[1..]
.iter()
.filter(|a| !a.starts_with("--"))
.cloned()
.collect(),
at: opt_value("--at"),
}),
Some("list") | None => Command::Schedule(crate::cli::ScheduleCmd::List),
Some("remove") if rest.len() >= 2 => Command::Schedule(
crate::cli::ScheduleCmd::Remove {
id: rest[1].clone(),
},
),
Some("run") if rest.len() >= 2 => Command::Schedule(crate::cli::ScheduleCmd::Run {
id: rest[1].clone(),
}),
_ => {
app.log.error("usage: schedule add <cmd...> | schedule list | schedule remove <id>");
return Ok(false);
}
},
"doctor" => Command::Doctor {
fix: flag("--fix"),
watch: opt_value("--watch").and_then(|v| v.parse().ok()),
},
"run" => {
let agent = need("agent name")?;
Command::Run {
agent,
model: opt_value("--model"),
container: flag("--container"),
args: rest[1..].iter().map(|s| s.as_str().into()).collect(),
}
}