rho-coding-agent 1.8.1

A lightweight agent harness inspired by Pi
Documentation
use std::path::Path;

use super::*;

#[test]
fn builtins_share_one_catalog() {
    let root = tempfile::tempdir().unwrap();
    let catalog = AgentCatalog::discover_with_home(root.path(), None).unwrap();
    let ids = catalog
        .iter()
        .map(|entry| entry.definition.id.as_str())
        .collect::<Vec<_>>();
    assert_eq!(ids, ["default", "explorer", "reviewer", "worker"]);
}

#[test]
fn rejects_unknown_tools_with_context() {
    let root = tempfile::tempdir().unwrap();
    let agents = root.path().join(".rho/agents");
    std::fs::create_dir_all(&agents).unwrap();
    let path = agents.join("bad.md");
    std::fs::write(&path, "---\ndescription: bad\ntools: [teleport]\n---\n").unwrap();

    let error = AgentCatalog::discover_with_home(root.path(), Some(root.path())).unwrap_err();

    assert_eq!(error.path, path);
    assert_eq!(error.field.as_deref(), Some("tools"));
    assert!(error.to_string().contains("unknown tool 'teleport'"));
}

#[test]
fn semantic_fingerprint_ignores_formatting_and_source() {
    let a = parse_definition(
        Path::new("a.md"),
        "worker",
        "---\ndescription: work\ntools: [read_file, write_file]\n---\nship it\n",
    )
    .unwrap();
    let b = parse_definition(
        Path::new("elsewhere.md"),
        "worker",
        "---\nid: worker\ndescription: work\ntools:\n  - write_file\n  - read_file\n---\n\nship it\n",
    )
    .unwrap();
    assert_eq!(a.fingerprint(), b.fingerprint());
}

#[test]
fn same_tier_duplicates_are_rejected() {
    let root = tempfile::tempdir().unwrap();
    let agents = root.path().join(".rho/agents");
    std::fs::create_dir_all(&agents).unwrap();
    for file in ["one.md", "two.md"] {
        std::fs::write(
            agents.join(file),
            "---\nid: duplicate\ndescription: duplicate\n---\n",
        )
        .unwrap();
    }
    let error = AgentCatalog::discover_with_home(root.path(), Some(root.path())).unwrap_err();
    assert_eq!(error.field.as_deref(), Some("id"));
    assert!(error.to_string().contains("duplicate agent ID"));
}

#[test]
fn project_definitions_require_explicit_trust() {
    let project = tempfile::tempdir().unwrap();
    let agents = project.path().join(".agents/agents");
    std::fs::create_dir_all(&agents).unwrap();
    std::fs::write(
        agents.join("project.md"),
        "---\ndescription: project agent\n---\n",
    )
    .unwrap();

    let untrusted =
        AgentCatalog::discover_with_home_and_trust(project.path(), None, ProjectTrust::Untrusted)
            .unwrap();
    assert!(untrusted.find("project").is_err());
    let trusted =
        AgentCatalog::discover_with_home_and_trust(project.path(), None, ProjectTrust::Trusted)
            .unwrap();
    assert_eq!(
        trusted.find("project").unwrap().metadata.origin,
        AgentOrigin::Project
    );
}