supercode-cli 0.4.18

supercode — a lightweight, fully-customizable AI coding agent CLI in Rust. Any model via OpenRouter; natively continues Claude Code and Codex sessions.
//! ORCH-8 CLI acceptance: `supercode runs list|get` over the committed fire
//! stores.
//!
//! The harness homes are pointed at `crates/harness/tests/fixtures` through the
//! same environment variables a real install uses (`CLAUDE_CONFIG_DIR`,
//! `HERMES_HOME`, `OPENCLAW_STATE_DIR`), so the spawned binary reads exactly
//! the paths the loader reads on a machine — nothing is injected past the
//! product's own door. Every invocation is offline and read-only.

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

/// The health job in the committed OpenClaw fixture, which fired twice.
const OPENCLAW_HEALTH_JOB: &str = "85ad7832-896f-42be-af31-3e1ed2fbdc4b";

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

fn fixtures() -> PathBuf {
    PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../harness/tests/fixtures")
}

fn run(args: &[&str]) -> Output {
    let fixtures = fixtures();
    Command::new(bin())
        .env("CLAUDE_CONFIG_DIR", fixtures.join("claude_jobs_home"))
        .env("HERMES_HOME", fixtures.join("hermes_home"))
        .env("OPENCLAW_STATE_DIR", fixtures.join("openclaw_home"))
        .args(args)
        .output()
        .expect("supercode binary runs")
}

fn json_of(output: &Output) -> serde_json::Value {
    assert!(
        output.status.success(),
        "command failed: {}",
        String::from_utf8_lossy(&output.stderr)
    );
    serde_json::from_slice(&output.stdout).expect("stdout is the RPC result verbatim")
}

#[test]
fn runs_list_json_returns_the_rpc_rows_for_both_stores() {
    let result = json_of(&run(&["runs", "list", "--json"]));
    let ids: Vec<&str> = result["runs"]
        .as_array()
        .unwrap()
        .iter()
        .map(|run| run["id"].as_str().unwrap())
        .collect();
    assert_eq!(
        ids,
        vec![
            "b2c3d4e5f60718293a4b5c6d7e8f9012",
            "a1b2c3d4e5f60718293a4b5c6d7e8f90",
            "c3d4e5f60718293a4b5c6d7e8f901234",
            "f60718293a4b5c6d7e8f901234567890",
            "e5f60718293a4b5c6d7e8f9012345678",
            "d4e5f60718293a4b5c6d7e8f90123456",
            "run_health_0002",
            "8bb7d938-ca46-4a6d-90eb-c92331155566#1",
            "run_health_0001",
        ],
        "{result}"
    );
    // The rows are the RPC's, verbatim — including the fire→session join
    // Hermes itself does not record.
    let joined = result["runs"]
        .as_array()
        .unwrap()
        .iter()
        .find(|run| run["id"] == "a1b2c3d4e5f60718293a4b5c6d7e8f90")
        .unwrap();
    assert_eq!(joined["harness"], "hermes");
    assert_eq!(joined["job_id"], "job42");
    assert_eq!(joined["status"], "completed");
    assert_eq!(joined["session_id"], "cron_job42_20260902_120000");
    // job42 delivers `local`, so no platform obligation is addressed to it.
    assert!(joined["delivery"].is_null(), "{joined}");
    // ORCH-13: the fire whose job DOES deliver to a chat carries the ledger's
    // own state, attempts and address.
    let delivered = result["runs"]
        .as_array()
        .unwrap()
        .iter()
        .find(|run| run["id"] == "e5f60718293a4b5c6d7e8f9012345678")
        .unwrap();
    assert_eq!(delivered["delivery"]["state"], "delivered");
    assert_eq!(delivered["delivery"]["target"], "telegram:-100777:55");
    assert_eq!(delivered["delivery"]["attempts"], 1);
    assert!(result["sources"].as_array().unwrap().len() >= 4, "{result}");
}

#[test]
fn runs_list_table_carries_the_seven_declared_columns() {
    let output = run(&["runs", "list", "--harness", "hermes"]);
    assert!(output.status.success());
    let text = String::from_utf8_lossy(&output.stdout);
    let header = text.lines().next().unwrap();
    for column in [
        "HARNESS", "JOB", "STATUS", "STARTED", "FINISHED", "DELIVERY", "SESSION",
    ] {
        assert!(header.contains(column), "header `{header}` lacks {column}");
    }
    assert!(text.contains("cron_job42_20260902_120000"), "{text}");
    // ORCH-13: a fire whose send failed while the fire itself succeeded is
    // only distinguishable in the delivery column.
    assert!(text.contains("completed"), "{text}");
    assert!(text.contains("delivered"), "{text}");
    assert!(text.contains("failed"), "{text}");
    // The profile home's own ledger is read, not just the root one.
    assert!(text.contains("ops-once-boot"), "{text}");
    assert!(
        !text.contains("run_health_0001"),
        "--harness must filter: {text}"
    );
}

#[test]
fn runs_list_filters_by_job_and_caps_by_limit() {
    let result = json_of(&run(&[
        "runs",
        "list",
        "--harness",
        "openclaw",
        "--job",
        OPENCLAW_HEALTH_JOB,
        "--limit",
        "1",
        "--json",
    ]));
    let runs = result["runs"].as_array().unwrap();
    assert_eq!(runs.len(), 1, "{result}");
    assert_eq!(runs[0]["id"], "run_health_0002");
    assert_eq!(runs[0]["job_id"], OPENCLAW_HEALTH_JOB);
}

#[test]
fn runs_get_json_carries_the_row_and_the_native_record() {
    let result = json_of(&run(&[
        "runs",
        "get",
        "--harness",
        "hermes",
        "a1b2c3d4e5f60718293a4b5c6d7e8f90",
        "--json",
    ]));
    assert_eq!(result["run"]["job_id"], "job42");
    assert_eq!(result["run"]["status"], "completed");
    // The ledger's own columns survive beside the uniform row.
    assert_eq!(result["source"]["source"], "scheduler");
    assert_eq!(result["source"]["pid"], 4242);
}

/// ORCH-13: `runs get` prints the delivery the harness recorded, and says in
/// words when it recorded none — a bare `-` would read as "not delivered".
#[test]
fn runs_get_prints_the_delivery_or_says_none_was_recorded() {
    let text = String::from_utf8_lossy(
        &run(&[
            "runs",
            "get",
            "--harness",
            "hermes",
            "f60718293a4b5c6d7e8f901234567890",
        ])
        .stdout,
    )
    .into_owned();
    assert!(text.contains("status: completed"), "{text}");
    assert!(
        text.contains("delivery: failed \u{2192} telegram:-100777:55"),
        "{text}"
    );
    assert!(text.contains("delivery attempts: 3"), "{text}");
    assert!(
        text.contains("delivery error: telegram send failed: Bad Request: chat not found"),
        "{text}"
    );

    let none = String::from_utf8_lossy(
        &run(&[
            "runs",
            "get",
            "--harness",
            "hermes",
            "a1b2c3d4e5f60718293a4b5c6d7e8f90",
        ])
        .stdout,
    )
    .into_owned();
    assert!(
        none.contains("delivery: none recorded for this fire"),
        "{none}"
    );
}

#[test]
fn a_harness_that_keeps_no_run_store_fails_instead_of_listing_nothing() {
    // Claude Code HAS scheduled jobs; its fires are ordinary turns, so there
    // is no run store and an empty table would be a silent no-op.
    let output = run(&["runs", "list", "--harness", "claude-code", "--json"]);
    assert!(!output.status.success());
    let stderr = String::from_utf8_lossy(&output.stderr);
    assert!(stderr.contains("keeps no run store"), "{stderr}");
    assert!(stderr.contains("hermes, openclaw"), "{stderr}");
}