Skip to main content

apm/cmd/
agents.rs

1use anyhow::Result;
2use apm_core::config::Config;
3use apm_core::wrapper::WrapperKind;
4use std::path::Path;
5
6pub fn run_list(root: &Path) -> Result<()> {
7    let config = Config::load(root)?;
8    let entries = apm_core::agents::list_wrappers(root, &config)?;
9
10    let name_w = entries.iter().map(|e| e.name.len()).max().unwrap_or(4).max(4);
11    let kind_w = "built-in".len();
12    let parser_w = "canonical".len();
13
14    println!(
15        "{:<name_w$}  {:<kind_w$}  {:<parser_w$}  STATUS",
16        "NAME", "KIND", "PARSER"
17    );
18    for entry in &entries {
19        let kind_str = match &entry.kind {
20            WrapperKind::Builtin(_) => "built-in",
21            WrapperKind::Custom { .. } => "project",
22        };
23        let status = entry.configured_as.join(", ");
24        println!(
25            "{:<name_w$}  {:<kind_w$}  {:<parser_w$}  {}",
26            entry.name, kind_str, entry.parser, status
27        );
28    }
29    Ok(())
30}
31
32pub fn run_new(root: &Path, name: &str, force: bool) -> Result<()> {
33    apm_core::agents::scaffold_wrapper(root, name, force)?;
34
35    let dir = root.join(".apm").join("agents").join(name);
36    println!("Created:");
37    println!("  {}", dir.join("wrapper.sh").display());
38    println!("  {}", dir.join("manifest.toml").display());
39    println!("  {}", dir.join("apm.worker.md").display());
40    println!("  {}", dir.join("apm.spec-writer.md").display());
41    println!();
42    println!("Next steps:");
43    println!("  1. Edit {}/wrapper.sh to invoke your AI tool", dir.display());
44    println!("  2. Run: apm agents test {name}");
45    Ok(())
46}
47
48pub fn run_test(root: &Path, name: &str) -> Result<()> {
49    let report = apm_core::agents::test_wrapper(root, name)?;
50
51    let label = if report.passed { "PASS" } else { "FAIL" };
52    println!(
53        "{}  exit={}  events={}  non-canonical={}  stderr={}  wall={}ms",
54        label,
55        report.exit_code,
56        report.canonical_events,
57        report.non_canonical_lines,
58        report.stderr_lines,
59        report.wall_millis,
60    );
61
62    if !report.passed {
63        anyhow::bail!("wrapper test failed");
64    }
65    Ok(())
66}
67
68pub fn run_eject(root: &Path, name: &str) -> Result<()> {
69    apm_core::agents::eject_wrapper(root, name)?;
70
71    let script = root.join(".apm").join("agents").join(name).join("wrapper.sh");
72    println!("Ejected to: {}", script.display());
73    println!("Run: apm agents test {name}");
74    Ok(())
75}