supercode-cli 0.4.6

supercode — a lightweight, fully-customizable AI coding agent CLI in Rust. Any model via OpenRouter; natively continues Claude Code and Codex sessions.
//! Process-level coverage for harness-native id resolution in `resume`.

use std::fs;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::time::{SystemTime, UNIX_EPOCH};

use supercode::{ChatMessage, SessionStore};

fn bin() -> &'static str {
    env!("CARGO_BIN_EXE_supercode")
}

fn temp_home(label: &str) -> PathBuf {
    let nonce = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_nanos();
    let home = std::env::temp_dir().join(format!(
        "supercode-resume-id-cli-{label}-{}-{nonce}",
        std::process::id()
    ));
    fs::create_dir_all(&home).unwrap();
    home
}

fn write_claude(path: &Path, id: &str, malformed_tail: bool) {
    fs::create_dir_all(path.parent().unwrap()).unwrap();
    let mut text = format!(
        "{{\"type\":\"user\",\"sessionId\":{},\"cwd\":\"/tmp\",\"message\":{{\"role\":\"user\",\"content\":\"hi\"}}}}\n",
        serde_json::to_string(id).unwrap()
    );
    if malformed_tail {
        text.push_str("{truncated\n");
    }
    fs::write(path, text).unwrap();
}

fn write_codex(path: &Path, id: &str) {
    fs::create_dir_all(path.parent().unwrap()).unwrap();
    fs::write(
        path,
        format!(
            "{{\"timestamp\":\"2026-01-01T00:00:00Z\",\"type\":\"session_meta\",\"payload\":{{\"id\":{},\"cwd\":\"/tmp\"}}}}\n",
            serde_json::to_string(id).unwrap()
        ),
    )
    .unwrap();
}

fn run(home: &Path, input: &str) -> std::process::Output {
    Command::new(bin())
        .env("HOME", home)
        .env("SUPERCODE_HOME", home.join("supercode-home"))
        .env_remove("CLAUDE_CONFIG_DIR")
        .env_remove("CODEX_HOME")
        .env_remove("PI_CODING_AGENT_SESSION_DIR")
        .env_remove("PI_CODING_AGENT_DIR")
        .env_remove("OPENCODE_DB")
        .env_remove("XDG_DATA_HOME")
        .env_remove("GROK_HOME")
        .env_remove("OPENROUTER_API_KEY")
        .args(["--quiet", "resume", input])
        .stdin(Stdio::null())
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .output()
        .expect("run supercode")
}

fn run_dry(home: &Path, input: &str) -> std::process::Output {
    run_dry_with(home, input, &[])
}

fn run_dry_with(home: &Path, input: &str, extra: &[&str]) -> std::process::Output {
    let mut args = vec![
        "--quiet",
        "--model",
        "z-ai/glm-5.2",
        "--reduced",
        "resume",
        input,
        "--dry-run",
    ];
    args.extend_from_slice(extra);
    Command::new(bin())
        .env("HOME", home)
        .env("SUPERCODE_HOME", home.join("supercode-home"))
        .env_remove("OPENROUTER_API_KEY")
        .args(args)
        .stdin(Stdio::null())
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .output()
        .expect("run supercode dry resume")
}

#[test]
fn dry_run_loads_named_and_full_path_supercode_store_sessions() {
    let home = temp_home("supercode-store");
    let store = SessionStore::open(home.join("supercode-home/sessions")).unwrap();
    let name = "chosen-store-session";
    let messages = [
        ChatMessage::system("stored system"),
        ChatMessage::user("stored request"),
        ChatMessage::assistant("stored response"),
    ];
    let jsonl = messages
        .iter()
        .map(|message| serde_json::to_string(message).unwrap())
        .collect::<Vec<_>>()
        .join("\n");
    store.save(name, "chosen", &jsonl).unwrap();

    for input in [
        name.to_string(),
        store.session_path(name).unwrap().display().to_string(),
    ] {
        let output = run_dry(&home, &input);
        assert!(
            output.status.success(),
            "input={input}; stderr={}",
            String::from_utf8_lossy(&output.stderr)
        );
        let report: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap();
        assert_eq!(report["source"], "Native");
        assert_eq!(report["replay_message_count"], messages.len());
        assert_eq!(report["provider_request_sent"], false);
        assert_eq!(report["store_written"], false);
    }

    fs::remove_dir_all(home).ok();
}

#[test]
fn named_resume_honors_the_configured_session_directory() {
    let home = temp_home("configured-supercode-store");
    let redirected = home.join("redirected-sessions");
    let config_home = home.join("supercode-home");
    fs::create_dir_all(&config_home).unwrap();
    fs::write(
        config_home.join("config.toml"),
        format!(
            "[core.session]\ndir = {}\n",
            serde_json::to_string(redirected.to_str().unwrap()).unwrap()
        ),
    )
    .unwrap();
    let store = SessionStore::open(&redirected).unwrap();
    let name = "redirected-session";
    let message = ChatMessage::user("loaded from configured store");
    store
        .save(
            name,
            "redirected",
            &serde_json::to_string(&message).unwrap(),
        )
        .unwrap();

    let output = run_dry(&home, name);
    assert!(
        output.status.success(),
        "{}",
        String::from_utf8_lossy(&output.stderr)
    );
    let report: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap();
    assert_eq!(report["replay_message_count"], 1);
    assert!(!config_home.join("sessions").exists());

    fs::remove_dir_all(home).ok();
}

#[test]
fn ambiguous_native_id_requires_harness_disambiguation() {
    let home = temp_home("collision");
    write_claude(
        &home.join(".claude/projects/project/shared.jsonl"),
        "shared-id",
        false,
    );
    write_codex(
        &home.join(".codex/sessions/2026/07/shared.jsonl"),
        "shared-id",
    );

    let output = run(&home, "shared-id");
    assert!(!output.status.success());
    let stderr = String::from_utf8_lossy(&output.stderr);
    assert!(stderr.contains("ambiguous across harnesses"), "{stderr}");
    assert!(stderr.contains("--harness"), "{stderr}");
    assert!(stderr.contains("claude-code"), "{stderr}");
    assert!(stderr.contains("codex"), "{stderr}");
    fs::remove_dir_all(home).ok();
}

#[test]
fn existing_path_wins_over_the_same_catalog_id() {
    let home = temp_home("path-precedence");
    let explicit = home.join("explicit.jsonl");
    write_claude(&explicit, "explicit-source", true);
    write_codex(
        &home.join(".codex/sessions/2026/07/path-id.jsonl"),
        explicit.to_str().unwrap(),
    );

    let output = run(&home, explicit.to_str().unwrap());
    assert!(!output.status.success());
    let stderr = String::from_utf8_lossy(&output.stderr);
    assert!(stderr.contains("refusing to continue"), "{stderr}");
    assert!(stderr.contains("no provider call was made"), "{stderr}");
    assert!(!stderr.contains("no discovered"), "{stderr}");
    fs::remove_dir_all(home).ok();
}

#[test]
fn dry_run_restores_claude_context_and_runtime_without_key_or_writes() {
    let home = temp_home("dry-run");
    let project = home.join("fleet");
    fs::create_dir_all(project.join(".claude/agents")).unwrap();
    fs::create_dir_all(home.join(".claude")).unwrap();
    fs::write(home.join(".claude/CLAUDE.md"), "GLOBAL RULE").unwrap();
    fs::write(
        project.join(".claude/agents/pilot-tick.md"),
        "---\nname: pilot-tick\ntools: Bash, Read\nmodel: sonnet\n---\nPilot.\n",
    )
    .unwrap();
    let transcript = home.join("session.jsonl");
    fs::write(
        &transcript,
        format!(
            "{{\"type\":\"permission-mode\",\"permissionMode\":\"bypassPermissions\"}}\n\
             {{\"type\":\"user\",\"sessionId\":\"dry-session\",\"cwd\":{},\"message\":{{\"role\":\"user\",\"content\":\"continue\"}}}}\n\
             {{\"type\":\"queue-operation\",\"operation\":\"enqueue\",\"content\":\"queued follow-up\"}}\n",
            serde_json::to_string(project.to_str().unwrap()).unwrap()
        ),
    )
    .unwrap();

    let output = run_dry(&home, transcript.to_str().unwrap());
    assert!(
        output.status.success(),
        "stderr: {}",
        String::from_utf8_lossy(&output.stderr)
    );
    let report: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap();
    assert_eq!(report["target_model"], "z-ai/glm-5.2");
    assert_eq!(report["target_context_limit"], 1_048_576);
    assert_eq!(report["provider_request_sent"], false);
    assert_eq!(report["store_written"], false);
    assert_eq!(report["runtime_activation"], "paused");
    assert_eq!(report["runtime_would_activate"], true);
    assert_eq!(report["runtime"]["execution_state"], "paused");
    assert_eq!(report["runtime"]["queue"]["unmatched_evidence_count"], 1);
    assert_eq!(report["runtime"]["queue"]["reconstructable"], true);
    assert_eq!(report["runtime"]["queue"]["will_replay"], true);
    assert_eq!(report["reduction"]["reversible"], true);
    let baseline_input = report["reduction"]["baseline_input_tokens"]
        .as_u64()
        .unwrap();
    let full_messages = report["reduction"]["full_message_tokens"].as_u64().unwrap();
    assert!(baseline_input >= full_messages);
    assert_eq!(report["reduction"]["target_applied"], false);
    assert_eq!(report["reduction"]["target_input_tokens"], baseline_input);
    assert_eq!(report["reduction"]["target_met"], true);
    assert_eq!(
        report["runtime"]["posture"]["permission_mode"],
        "bypassPermissions"
    );
    assert_eq!(report["custom_agents"][0]["name"], "pilot-tick");
    assert_eq!(
        report["custom_agents"][0]["resolved_model"],
        "anthropic/claude-sonnet-4-6"
    );
    assert_eq!(report["claude_global_instructions_loaded"], true);
    fs::remove_dir_all(home).ok();
}

#[test]
fn dry_run_reports_explicit_paused_opt_out() {
    let home = temp_home("dry-run-paused");
    let transcript = home.join("session.jsonl");
    fs::write(
        &transcript,
        "{\"type\":\"user\",\"sessionId\":\"dry-paused-session\",\"cwd\":\"/tmp\",\"message\":{\"role\":\"user\",\"content\":\"hi\"}}\n\
         {\"type\":\"queue-operation\",\"operation\":\"enqueue\",\"content\":\"stay paused\"}\n",
    )
    .unwrap();

    let output = run_dry_with(&home, transcript.to_str().unwrap(), &["--paused"]);
    assert!(
        output.status.success(),
        "stderr: {}",
        String::from_utf8_lossy(&output.stderr)
    );
    let report: serde_json::Value = serde_json::from_slice(&output.stdout).unwrap();
    assert_eq!(report["runtime_activation"], "paused");
    assert_eq!(report["runtime_would_activate"], false);
    assert_eq!(report["source_log_modified"], false);
    assert_eq!(report["store_written"], false);
    assert_eq!(report["provider_request_sent"], false);
    assert_eq!(report["runtime"]["queue"]["unmatched_evidence_count"], 1);
    assert_eq!(report["runtime"]["queue"]["reconstructable"], true);
    assert_eq!(report["runtime"]["queue"]["will_replay"], false);
    fs::remove_dir_all(home).ok();
}