feat: epique v1.1.0 — onboarding, copilot & roles aichat (am setup)
release / release (push) Successful in 13m21s
release / macos (push) Canceled after 0s

F1 — Wizard d'onboarding (src/setup.rs) :
- am setup : provider (anthropic, openai, deepseek, google, ollama, custom),
  token masque (rpassword) -> keyring OS (jamais en clair), modele par defaut
  (liste declaree + champ libre), ping API non-bloquant
- Declencheurs non-bloquants : am ai / am ask et banner REPL proposent
  am setup quand aucun provider n'est configure ; re-executable (mode revoir)
- settings.default_provider + providers.* ecrits via persist_setting

F2 — Integration aichat :
- Etape wizard 'Installer le moteur IA (aichat) ? [Y/n]' -> am install aichat
- am ai sans aichat -> 'aichat est manquant. Installer ? [Y/n]'
- install.ps1/install.sh enchainent sur am setup si stdin interactif

F3 — Roles copilot aichat (src/roles.rs) :
- 6 agents generes dans ~/.config/aichat/agents (ou %APPDATA%\aichat\agents) :
  am-copilot, am-operator, am-dev, am-do, am-analyst, am-orchestrator
- Prompts bilingues (FR defaut) privilegiant les contrats --json ; le prompt
  am-copilot embarque la liste des commandes am
- am ai --role <nom> (valide le fichier genere, passe --agent a aichat),
  completion REPL ; config aichat creee seulement si absente
- Câblage complet : cli, dispatch, help, REPL, tip, man (am-setup.1), i18n

Tests : 450 verts (roles + setup unitaires, ai_test ajustes locale-agnostic)
v1.1.0 ; ROADMAP axe 14 + maintenance note ; README Premier lancement
This commit is contained in:
2026-08-20 23:09:21 -04:00
parent 50f515e406
commit d71c3dd34d
20 changed files with 870 additions and 12 deletions
+23 -2
View File
@@ -115,6 +115,7 @@ const COMMAND_DESCRIPTIONS: &[(&str, &str)] = &[
("suggest", "recommend an agent for a request"),
("ask", "natural language → am commands (local rules first, optional LLM refinement)"),
("ai", "natural language → shell action via AIChat (--exec to run, dry-run by default)"),
("setup", "onboarding wizard: provider, token, default model, aichat, copilot roles"),
("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"),
@@ -240,7 +241,7 @@ impl AmCompleter {
"start", "stop", "restart", "run", "doctor", "config", "completion",
"self-update", "self-uninstall", "export", "import", "shell", "theme", "lang",
"tip", "dashboard", "favorite", "unfavorite", "note", "tag", "untag", "tags",
"profile", "man", "models", "catalog", "providers", "suggest", "ask", "ai", "registry", "audit",
"profile", "man", "models", "catalog", "providers", "suggest", "ask", "ai", "setup", "registry", "audit",
"service", "schedule", "monitor", "web", "serve", "sync", "migrate", "playbook", "lab", "plugins",
"ls", "dir", "cd", "ps", "where", "get", "help", "version", "exit",
],
@@ -800,7 +801,7 @@ pub fn banner_box(
.to_string(),
));
rows.push(inner(
" models models · models --prune · catalog · suggest · ask · ai · audit".to_string(),
" models models · models --prune · catalog · suggest · ask · ai · setup · audit".to_string(),
));
rows.push(inner(
" automate service install · schedule add · doctor --watch · monitor · sync · migrate · playbook".to_string(),
@@ -1110,6 +1111,14 @@ pub fn run(app: &App) -> Result<i32> {
app.log.verbose(&format!("history migration skipped: {e:#}"));
}
print!("{}", banner(app, &session, &sid));
// Onboarding tip (v1.1.0 F1): one discreet line when no provider is
// configured yet.
if crate::setup::needs_setup(app) {
app.log.info(crate::i18n::tr_in(
app.lang(),
"am n'est pas configuré — lancez am setup (provider + token)",
));
}
let result = match run_with_editor(app, &mut session, &sid) {
Ok(code) => Ok(code),
Err(e) => {
@@ -1611,6 +1620,7 @@ fn handle_line(
let mut files: Vec<std::path::PathBuf> = Vec::new();
let mut provider: Option<String> = None;
let mut model: Option<String> = None;
let mut role: Option<String> = None;
let mut prompt: Vec<String> = Vec::new();
let mut i = 0;
while i < rest.len() {
@@ -1636,6 +1646,12 @@ fn handle_line(
model = Some(rest[i].clone());
}
}
"--role" => {
i += 1;
if i < rest.len() {
role = Some(rest[i].clone());
}
}
other => prompt.push(other.to_string()),
}
i += 1;
@@ -1652,10 +1668,14 @@ fn handle_line(
files,
provider,
model,
role,
yes,
dry_run,
})
},
"setup" => Command::Setup {
roles: flag("--roles"),
},
"alias" => match rest.first().map(|s| s.as_str()) {
Some("add") if rest.len() >= 3 => Command::Alias(crate::cli::AliasCmd::Add {
name: rest[1].clone(),
@@ -2073,6 +2093,7 @@ pub fn is_am_command(word: &str) -> bool {
| "suggest"
| "ask"
| "ai"
| "setup"
| "audit"
| "service"
| "schedule"