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}}}]"#
)
}
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",
],
));
assert!(
created.contains(
"cron create --name health --deliver local 'every 10m' 'nightly health check'"
),
"{created}"
);
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")));
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();
}