agentcarousel 0.2.1

Check YAML/TOML fixtures for agents and skills, run cases (mock or live), and keep run rows in SQLite for reports and evidence export.
Documentation
use assert_cmd::Command;
use std::fs;
use std::path::{Path, PathBuf};
use std::time::{SystemTime, UNIX_EPOCH};

fn temp_workspace() -> PathBuf {
    let unique = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .expect("unix epoch")
        .as_nanos();
    let dir = std::env::temp_dir().join(format!("agentcarousel-init-negative-{unique}"));
    fs::create_dir_all(&dir).expect("create temp workspace");
    dir
}

fn write_template(root: &Path) {
    let templates_dir = root.join("templates");
    fs::create_dir_all(&templates_dir).expect("create templates dir");
    fs::write(
        templates_dir.join("fixture-skeleton.yaml"),
        "schema_version: 1\nskill_or_agent: <skill-or-agent-id>\ncases: []\n",
    )
    .expect("write fixture template");
}

#[test]
fn init_rejects_path_separator_names() {
    let workspace = temp_workspace();
    write_template(&workspace);

    Command::cargo_bin("agentcarousel")
        .unwrap()
        .current_dir(&workspace)
        .args(["init", "--skill", "../escape"])
        .assert()
        .failure()
        .code(4);

    let _ = fs::remove_dir_all(workspace);
}

#[test]
fn init_rejects_non_kebab_names() {
    let workspace = temp_workspace();
    write_template(&workspace);

    Command::cargo_bin("agentcarousel")
        .unwrap()
        .current_dir(&workspace)
        .args(["init", "--agent", "Not-Kebab"])
        .assert()
        .failure()
        .code(4);

    let _ = fs::remove_dir_all(workspace);
}

#[test]
fn init_creates_fixture_with_sanitized_name() {
    let workspace = temp_workspace();
    write_template(&workspace);

    Command::cargo_bin("agentcarousel")
        .unwrap()
        .current_dir(&workspace)
        .args(["init", "--skill", "sample-agent"])
        .assert()
        .success();

    let output_path = workspace.join("fixtures/sample-agent.yaml");
    assert!(output_path.exists(), "expected generated fixture to exist");
    let contents = fs::read_to_string(output_path).expect("read generated fixture");
    assert!(contents.contains("skill_or_agent: sample-agent"));

    let _ = fs::remove_dir_all(workspace);
}