supercode-cli 0.4.15

supercode — a lightweight, fully-customizable AI coding agent CLI in Rust. Any model via OpenRouter; natively continues Claude Code and Codex sessions.
//! ORCH-18 CLI acceptance: `supercode jobs create|update|pause|resume|run|
//! delete` against a FAKE `hermes` CLI.
//!
//! The binary is driven exactly as a user drives it — the harness home comes
//! from `HERMES_HOME`, the executable from the documented test override
//! `SUPERCODE_HERMES_BIN` — and nothing is injected past the product's own
//! door. The fake records its argv and writes the harness's own job store, so
//! the human output under test is the real one: the `ran` line (what the
//! harness was asked to do) followed by the row read back from that store.
//!
//! Offline, no gateway, no model spend.

use std::path::{Path, PathBuf};
use std::process::{Command, Output};

fn bin() -> PathBuf {
    PathBuf::from(env!("CARGO_BIN_EXE_supercode"))
}

fn scratch() -> PathBuf {
    let root = std::env::temp_dir().join(format!(
        "supercode-orch18-cli-{}-{}",
        std::process::id(),
        std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap()
            .as_nanos()
    ));
    std::fs::create_dir_all(&root).unwrap();
    root
}

fn hermes_job(enabled: bool) -> String {
    format!(
        r#"[{{"id": "job-1", "name": "health", "schedule": {{"kind": "interval", "minutes": 10}},
            "prompt": "nightly health check", "deliver": "local", "enabled": {enabled}}}]"#
    )
}

/// A fake `hermes` that copies `hermes.<verb>.json` over `$HERMES_HOME/cron/jobs.json`.
fn fake_hermes(root: &Path) -> PathBuf {
    let path = root.join("fake-hermes");
    std::fs::write(
        &path,
        "#!/bin/sh\n\
         dir=$(dirname \"$0\")\n\
         verb=$2\n\
         mkdir -p \"$HERMES_HOME/cron\"\n\
         if [ -f \"$dir/hermes.$verb.json\" ]; then\n\
         cp \"$dir/hermes.$verb.json\" \"$HERMES_HOME/cron/jobs.json\"\n\
         fi\n\
         printf 'ok\\n'\n",
    )
    .unwrap();
    #[cfg(unix)]
    {
        use std::os::unix::fs::PermissionsExt;
        std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o755)).unwrap();
    }
    std::fs::write(root.join("hermes.create.json"), hermes_job(true)).unwrap();
    std::fs::write(root.join("hermes.pause.json"), hermes_job(false)).unwrap();
    std::fs::write(root.join("hermes.remove.json"), "[]").unwrap();
    path
}

fn run(root: &Path, args: &[&str]) -> Output {
    Command::new(bin())
        .env("HERMES_HOME", root.join("hermes_home"))
        .env("SUPERCODE_HERMES_BIN", root.join("fake-hermes"))
        .args(args)
        .output()
        .expect("supercode binary runs")
}

fn stdout_of(output: &Output) -> String {
    assert!(
        output.status.success(),
        "command failed: {}",
        String::from_utf8_lossy(&output.stderr)
    );
    String::from_utf8_lossy(&output.stdout).into_owned()
}

#[test]
fn jobs_create_pause_delete_narrate_the_harness_command_and_the_row() {
    let root = scratch();
    fake_hermes(&root);

    let created = stdout_of(&run(
        &root,
        &[
            "jobs",
            "create",
            "--harness",
            "hermes",
            "--name",
            "health",
            "--every",
            "10m",
            "--message",
            "nightly health check",
            "--deliver",
            "local",
        ],
    ));
    // The narration names the harness's own verb, not supercode's.
    assert!(
        created.contains(
            "cron create --name health --deliver local 'every 10m' 'nightly health check'"
        ),
        "{created}"
    );
    // The row is the one the harness's store holds afterwards.
    assert!(created.contains("hermes job job-1"), "{created}");
    assert!(created.contains("schedule: every 10 min"), "{created}");
    assert!(
        created.contains("state: active (enabled: true)"),
        "{created}"
    );

    let paused = stdout_of(&run(
        &root,
        &["jobs", "pause", "--harness", "hermes", "job-1"],
    ));
    assert!(paused.contains("cron pause job-1"), "{paused}");
    assert!(
        paused.contains("state: paused (enabled: false)"),
        "{paused}"
    );

    let deleted = stdout_of(&run(
        &root,
        &["jobs", "delete", "--harness", "hermes", "job-1", "--json"],
    ));
    let result: serde_json::Value = serde_json::from_str(&deleted).expect("--json is the RPC row");
    assert_eq!(result["deleted"], true, "{result}");
    assert_eq!(result["id"], "job-1");
    assert!(result["ran"]
        .as_str()
        .is_some_and(|ran| ran.ends_with("cron remove job-1")));
    // The harness's own store agrees: the job is gone.
    let listing = stdout_of(&run(
        &root,
        &["jobs", "list", "--harness", "hermes", "--json"],
    ));
    let listing: serde_json::Value = serde_json::from_str(&listing).unwrap();
    assert_eq!(listing["jobs"].as_array().unwrap().len(), 0, "{listing}");
    std::fs::remove_dir_all(&root).ok();
}

#[test]
fn a_harness_with_no_client_callable_verb_fails_instead_of_pretending() {
    let root = scratch();
    fake_hermes(&root);
    let output = run(
        &root,
        &["jobs", "pause", "--harness", "claude-code", "release-watch"],
    );
    assert!(
        !output.status.success(),
        "claude-code jobs are made by the model inside a session; a silent success would be a lie"
    );
    let stderr = String::from_utf8_lossy(&output.stderr);
    assert!(stderr.contains("CronCreate"), "{stderr}");
    std::fs::remove_dir_all(&root).ok();
}