diff --git a/Cargo.lock b/Cargo.lock index 655c202..8668a8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ [[package]] name = "agent-manager" -version = "1.1.2" +version = "1.1.3" dependencies = [ "anyhow", "base64", diff --git a/Cargo.toml b/Cargo.toml index 140943b..53689dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "agent-manager" -version = "1.1.2" +version = "1.1.3" edition = "2021" description = "Manage local AI coding agents: list, install, start, stop, update — with automatic dependency handling and a YAML-driven catalog." license = "MIT" diff --git a/ROADMAP.md b/ROADMAP.md index ff04b79..e612f97 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -82,6 +82,16 @@ > l'app — l'import écrasait la config réelle de la machine (et la suite > de tests détruisait la config utilisateur à chaque `cargo test`). > L'import respecte désormais `app.paths.config_dir` (--config/isolated). +> +> 🔧 **Maintenance v1.1.3 (2026-08-21)** : fix `resolve_exec` — pour un +> agent INSTALLÉ avec un binaire enregistré, le premier token de `run:` +> (ex. `picoclaw`) n'était jamais consommé : `am start ` lançait +> ` ` (picoclaw rejetait son propre nom comme +> sous-commande inconnue ; aichat recevait « aichat » comme prompt +> one-shot). Le token est désormais consommé dans la branche « binaire +> enregistré existant » (les branches non-installé/binaire manquant +> étaient déjà correctes). Test de régression +> `resolve_exec_installed_agent_does_not_leak_run_token`. --- diff --git a/sketches/001-dark-cockpit/index.html b/sketches/001-dark-cockpit/index.html new file mode 100644 index 0000000..f7e57cd --- /dev/null +++ b/sketches/001-dark-cockpit/index.html @@ -0,0 +1,298 @@ + + + + + +am web — Cockpit sombre (mockup) + + + +
+ + +
+
+
+

Vue d'ensemble

+
Dernière mise à jour : il y a 5 s
+
+
+ serveur local + 127.0.0.1:7878 + +
+
+ + +
+
+
🤖
Agents installés
9
▲ +1 cette semaine
+
⚡
En cours
2
● claude-code · codex
+
⏱
Sessions (7 j)
47
▲ +12 % vs semaine préc.
+
📜
Événements (24 h)
132
▼ 8 % vs hier
+
+
+
+

Top agents — sessions (7 j)

+
claude-code
18
+
aider
9
+
codex
8
+
gemini-cli
5
+
jcode
4
+
opencode
3
+
+
+

Activité — sessions par jour (14 j)

+
+ + + + + + +
04 août11 aoûtaujourd'hui
+
+
+
+
+
+

Activité récente

+
    +
  • claude-code terminé — session 3 h 12 minil y a 2 min
  • +
  • codex démarré — projet flowdeckil y a 14 min
  • +
  • jcode mis à jour 0.76.0 → 0.78.1il y a 1 h
  • +
  • aider échec — exit code 1il y a 3 h
  • +
  • gemini-cli terminé — session 42 minil y a 5 h
  • +
+
+
+

Sessions en cours

+ + + + + + +
AgentProjetDuréeDémarrée
claude-codeagent-manager3 h 12 min14:26
codexflowdeck14 min17:18
+ +
+
+
+ + +
+
+

Statistiques par agent — période 30 j

+ + + + + + + + + + +
AgentSessionsDurée totaleTaux de succèsCoût estiméDernière activité
claude-code5438 h 12 m94 %12,40 €il y a 2 min
aider3121 h 48 m87 %4,10 €il y a 3 h
codex2719 h 05 m89 %8,75 €il y a 14 min
gemini-cli146 h 33 m79 %0 € (local)il y a 5 h
jcode125 h 02 m67 %1,20 €hier
opencode94 h 40 m55 %0,90 €il y a 2 j
+
+
+ + +
+
+

Sessions — 7 derniers jours

+ + + + + + + + + + + + +
SessionAgentProjetStatutDuréeFin
20260818_172631_b4e2f1claude-codeagent-manageren cours3 h 12 min—
20260818_171812_c9d0a4codexflowdecken cours14 min—
20260818_153402_a1b2c3claude-codeagent-managerterminée1 h 05 min16:40
20260818_142118_d4e5f6aiderobsigateéchec12 min14:33
20260818_113047_e7f8a9gemini-cliimagoterminée42 min12:12
20260817_220933_b0c1d2claude-codeagent-managerterminée2 h 47 min23:50
20260817_183011_e2f3a4jcodeagent-managerterminée1 h 22 min19:35
+ +
+
+ + +
+
+

Journal d'événements — aujourd'hui

+
    +
  • start codex — projet flowdeck17:18
  • +
  • stop claude-code — session 1 h 05 min16:40
  • +
  • start claude-code — projet agent-manager15:34
  • +
  • run aider — exit code 1 (fichier manquant)14:33
  • +
  • update jcode 0.76.0 → 0.78.113:05
  • +
  • stop gemini-cli — session 42 min12:12
  • +
  • start gemini-cli — projet imago11:30
  • +
  • install opencode 0.14.2 — méthode binary10:02
  • +
+
+
+ + +
+
+
Projets suivis
4
▲ 1 nouveau cette semaine
+
Sessions (7 j)
47
▲ +12 %
+
Temps total
96 h
▲ +8 h vs semaine préc.
+
+
+

Projets

+ + + + + + + + +
ProjetAgentsSessions (7 j)TempsDernière activité
agent-manager · Rustclaude-code · jcode · codex2441 hil y a 2 min
flowdeck · Pythoncodex · aider1119 hil y a 14 min
obsigate · Pythonaider · gemini-cli822 hil y a 3 h
imago · Pythongemini-cli414 hil y a 5 h
+
+
+
+
+ + + + diff --git a/sketches/002-light-admin/index.html b/sketches/002-light-admin/index.html new file mode 100644 index 0000000..95a956f --- /dev/null +++ b/sketches/002-light-admin/index.html @@ -0,0 +1,216 @@ + + + + + +am web — Admin clair (mockup) + + + +
+
am agent-manager
+
+
Vue d'ensemble
+
Statistiques
+
Sessions
+
Événements
+
Projets
+
+
+ ● local + 127.0.0.1:7878 · v0.6.0 + +
+ +
+
Vue d'ensemble
+
Dernière mise à jour : il y a 5 s · lang FR
+ +
+
+
Agents installés
9
▲ +1 cette semaine
+
En cours
2
● claude-code · codex
+
Sessions (7 j)
47
▲ +12 %
+
Événements (24 h)
132
▼ 8 % vs hier
+
+
+
+

Top agents — sessions (7 j)

+
claude-code
18
+
aider
9
+
codex
8
+
gemini-cli
5
+
jcode
4
+
opencode
3
+
+
+

Activité — sessions par jour (14 j)

+ + + + + +
04 août11 aoûtaujourd'hui
+
+
+
+

Sessions — 7 derniers jours

+ + + + + + + + + + + +
SessionAgentProjetStatutDuréeFin
20260818_172631_b4e2f1claude-codeagent-manageren cours3 h 12 min—
20260818_171812_c9d0a4codexflowdecken cours14 min—
20260818_153402_a1b2c3claude-codeagent-managerterminée1 h 05 min16:40
20260818_142118_d4e5f6aiderobsigateéchec12 min14:33
20260818_113047_e7f8a9gemini-cliimagoterminée42 min12:12
20260817_220933_b0c1d2claude-codeagent-managerterminée2 h 47 min23:50
+
+
+ +
+
+

Statistiques par agent — période 30 j

+ + + + + + + + + +
AgentSessionsDurée totaleTaux de succèsCoût estiméDernière activité
claude-code5438 h 12 m94 %12,40 €il y a 2 min
aider3121 h 48 m87 %4,10 €il y a 3 h
codex2719 h 05 m89 %8,75 €il y a 14 min
gemini-cli146 h 33 m79 %0 € (local)il y a 5 h
jcode125 h 02 m67 %1,20 €hier
+
+
+ +
+
+

Sessions — 7 derniers jours

+ + + + + + + + + +
SessionAgentProjetStatutDuréeFin
20260818_172631_b4e2f1claude-codeagent-manageren cours3 h 12 min—
20260818_171812_c9d0a4codexflowdecken cours14 min—
20260818_153402_a1b2c3claude-codeagent-managerterminée1 h 05 min16:40
20260818_142118_d4e5f6aiderobsigateéchec12 min14:33
+
+
+ +
+
+

Journal d'événements — aujourd'hui

+ + + + + + + + + + +
HeureTypeAgentDétail
17:18startcodexprojet flowdeck
16:40stopclaude-codesession 1 h 05 min
15:34startclaude-codeprojet agent-manager
14:33runaiderexit code 1
13:05updatejcode0.76.0 → 0.78.1
10:02installopencode0.14.2 — méthode binary
+
+
+ +
+
+

Projets

+ + + + + + + + +
ProjetAgentsSessions (7 j)TempsDernière activité
agent-manager · Rustclaude-code · jcode · codex2441 hil y a 2 min
flowdeck · Pythoncodex · aider1119 hil y a 14 min
obsigate · Pythonaider · gemini-cli822 hil y a 3 h
imago · Pythongemini-cli414 hil y a 5 h
+
+
+
+ + + + diff --git a/sketches/003-terminal-dense/index.html b/sketches/003-terminal-dense/index.html new file mode 100644 index 0000000..a99ab4d --- /dev/null +++ b/sketches/003-terminal-dense/index.html @@ -0,0 +1,222 @@ + + + + + +am web — Terminal dense (mockup) + + + +
+ $am web +
+
overview
+
stats
+
sessions
+
events
+
projects
+
+
+ v0.6.0 · ● local · 127.0.0.1:7878 + +
+ +
+
+
+
agents installés
9
+
en cours
2
+
sessions 7j
47 ▲12%
+
events 24h
132 ▼8%
+
+
+
+
top agents · sessions 7j
+
+
claude-code
18
+
aider
9
+
codex
8
+
gemini-cli
5
+
jcode
4
+
opencode
3
+
+
+
+
activité 14j sessions/jour
+
+ + + + + +
04/0811/0818/08
+
+
+
+
+
sessions en cours
+
+ + + + + + +
idagentprojetduréedepuis
20260818_172631_b4e2f1claude-codeagent-manager3h12m14:26
20260818_171812_c9d0a4codexflowdeck14m17:18
+
+
+
+ +
+
+
stats par agent · 30j
+
+ + + + + + + + + + +
agentsessionsduréesuccèscoûtdernière act.
claude-code5438h12m94%12,40 €2 min
aider3121h48m87%4,10 €3 h
codex2719h05m89%8,75 €14 min
gemini-cli146h33m79%0 € local5 h
jcode125h02m67%1,20 €hier
opencode94h40m55%0,90 €2 j
+
+
+
+ +
+
+
sessions · 7j
+
+ +
+
+ + + + + + + + + + +
idagentprojetstatutduréefin
20260818_172631_b4e2f1claude-codeagent-managerrunning3h12m—
20260818_171812_c9d0a4codexflowdeckrunning14m—
20260818_153402_a1b2c3claude-codeagent-managerdone1h05m16:40
20260818_142118_d4e5f6aiderobsigatefailed12m14:33
20260818_113047_e7f8a9gemini-cliimagodone42m12:12
20260817_220933_b0c1d2claude-codeagent-managerdone2h47m23:50
+
+
+
+ +
+
+
events · aujourd'hui
+
+ + + + + + + + + + +
heuretypeagentdétail
17:18startcodexprojet flowdeck
16:40stopclaude-codesession 1h05m
15:34startclaude-codeprojet agent-manager
14:33runaiderexit code 1 — fichier manquant
13:05updatejcode0.76.0 → 0.78.1
10:02installopencode0.14.2 — méthode binary
+
+
+
+ +
+
+
projects
+
+ + + + + + + + +
projetagentssessions 7jtempsdernière act.
agent-manager · Rustclaude-code · jcode · codex2441h2 min
flowdeck · Pythoncodex · aider1119h14 min
obsigate · Pythonaider · gemini-cli822h3 h
imago · Pythongemini-cli414h5 h
+
+
+
+
+ + + + diff --git a/src/commands/mod.rs b/src/commands/mod.rs index a5c8252..38d71d9 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -319,6 +319,12 @@ pub fn resolve_exec( Some(e) if !e.bins.is_empty() => { let p = std::path::PathBuf::from(&e.bins[0]); if p.exists() || app.dry_run() { + // The recorded bin replaces the run command's first token + // (e.g. "picoclaw"): consume it so it is not appended to + // the argument list. Regression: am start + // lançait " " — picoclaw rejetait son propre + // nom comme sous-commande inconnue. + tokens.remove(0); p.display().to_string() } else { tokens.remove(0) @@ -473,6 +479,7 @@ pub fn select_method<'a>( #[cfg(test)] mod tests { use super::*; + use clap::Parser; #[test] fn routes_cmd_scripts_through_comspec() { @@ -498,4 +505,47 @@ mod tests { assert_eq!(program, "node"); assert_eq!(args, vec!["-v".to_string()]); } + + #[test] + fn resolve_exec_installed_agent_does_not_leak_run_token() { + let guard = tempfile::tempdir().unwrap(); + let dir = guard.path().to_path_buf(); + std::mem::forget(guard); + let cfg = dir.join("config.yaml"); + std::fs::write( + &cfg, + "version: \"1.0\"\nsettings:\n auto_install_deps: false\n confirm_before_run: false\nagents:\n - name: x\n run: x\n installable: false\n", + ) + .unwrap(); + let cli = crate::cli::Cli::parse_from(["am", "--config", cfg.to_str().unwrap()]); + let mut app = crate::app::App::from_cli(cli).unwrap(); + app.paths.state_file = dir.join("state.json"); + app.state = crate::state::StateStore::new(app.paths.state_file.clone()); + // A recorded installed bin that exists: the run token "x" must be + // consumed, not appended to the argument list. + let bin = dir.join("x.exe"); + std::fs::write(&bin, b"x").unwrap(); + app.state + .set(&crate::state::InstalledEntry { + name: "x".to_string(), + version: Some("1.0".to_string()), + method: "binary".to_string(), + install_dir: dir.display().to_string(), + bins: vec![bin.display().to_string()], + run: "x".to_string(), + installed_at: "2026-01-01T00:00:00Z".to_string(), + updated_at: None, + pid: None, + started_at: None, + }) + .unwrap(); + let agent = app.catalog.resolve("x").unwrap(); + let exec = resolve_exec(&app, agent, &[], &BTreeMap::new()).unwrap(); + assert_eq!(exec.program, bin.display().to_string()); + assert!( + exec.args.is_empty(), + "run token leaked into args: {:?}", + exec.args + ); + } }