supercode-harness 0.4.11

The optional native Supercode agent and tool harness
Documentation
use std::path::{Path, PathBuf};

use rusqlite::Connection;
use supercode_harness::audit::{audit_dir, Corpus};
use supercode_harness::reduce::export_session_spliced;
use supercode_harness::{
    ChatMessage, DiscoveryQuery, Fidelity, HarnessCatalog, HarnessHomes, HarnessId, Role, Session,
    SessionFormat, SessionSource,
};

fn fixture() -> PathBuf {
    Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/fixtures/goose_session.json")
}

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

#[test]
fn native_export_is_byte_exact_and_preserves_goose_only_blocks() {
    let source = std::fs::read_to_string(fixture()).unwrap();
    let session = Session::from_goose_str(&source).unwrap();

    assert_eq!(session.meta.source, SessionSource::Goose);
    assert_eq!(
        session.meta.session_id.as_deref(),
        Some("20260818_goose_fixture")
    );
    assert_eq!(session.meta.model.as_deref(), Some("gpt-5.6"));
    assert_eq!(session.load_fidelity(), Fidelity::ByteLossless);
    assert_eq!(session.messages.len(), 4);
    assert_eq!(session.messages[0].role, Role::User);
    assert_eq!(
        session.messages[1].content.as_deref(),
        Some("I will inspect it.")
    );
    assert_eq!(
        session.messages[1].tool_calls()[0].function.name,
        "developer__shell"
    );
    assert_eq!(
        session.messages[2].tool_call_id.as_deref(),
        Some("goose-call-1")
    );

    assert_eq!(session.to_jsonl(SessionFormat::Goose).unwrap(), source);
    assert!(session
        .to_native_jsonl()
        .lines()
        .next()
        .unwrap()
        .contains("\"source\":\"goose\""));
    let native = session.to_native_jsonl();
    let reloaded = Session::from_native_str(&native).unwrap();
    assert_eq!(reloaded.to_jsonl(SessionFormat::Goose).unwrap(), source);
}

#[test]
fn appended_turns_form_a_stock_importable_goose_document_after_disk_reload() {
    let source = Session::from_goose(fixture()).unwrap();
    let appended = vec![
        ChatMessage::user("Continue through Supercode."),
        ChatMessage::assistant("Goose continuation is intact."),
    ];
    let sidecar = source.to_native_jsonl_v2(&appended);
    let dir = temp_dir("sidecar");
    let sidecar_path = dir.join("session.supercode.jsonl");
    std::fs::write(&sidecar_path, sidecar).unwrap();
    let reloaded_sidecar = std::fs::read_to_string(&sidecar_path).unwrap();
    let artifact = export_session_spliced(
        &reloaded_sidecar,
        SessionFormat::Goose,
        Some("goose-resumed"),
    )
    .unwrap();

    let value: serde_json::Value = serde_json::from_str(&artifact).unwrap();
    assert_eq!(value["id"], "goose-resumed");
    assert_eq!(value["message_count"], 6);
    assert_eq!(value["conversation"][1]["content"][0]["type"], "thinking");

    let reloaded = Session::from_goose_str(&artifact).unwrap();
    assert_eq!(
        reloaded.messages[4].content.as_deref(),
        Some("Continue through Supercode.")
    );
    assert_eq!(
        reloaded.messages[5].content.as_deref(),
        Some("Goose continuation is intact.")
    );
    std::fs::remove_dir_all(dir).unwrap();
}

#[test]
fn sqlite_loader_reconstructs_the_official_export_boundary_read_only() {
    let dir = temp_dir("sqlite");
    let db = dir.join("sessions.db");
    let connection = Connection::open(&db).unwrap();
    connection
        .execute_batch(
            "
        CREATE TABLE sessions (
            id TEXT PRIMARY KEY,
            name TEXT NOT NULL,
            working_dir TEXT NOT NULL,
            created_at TEXT NOT NULL,
            updated_at TEXT NOT NULL,
            session_type TEXT NOT NULL,
            extension_data TEXT,
            goose_mode TEXT NOT NULL,
            provider_name TEXT,
            model_config_json TEXT,
            archived_at TEXT
        );
        CREATE TABLE messages (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            message_id TEXT,
            session_id TEXT NOT NULL,
            role TEXT NOT NULL,
            content_json TEXT NOT NULL,
            created_timestamp INTEGER NOT NULL,
            metadata_json TEXT
        );
        INSERT INTO sessions VALUES (
            'sqlite-goose', 'SQLite Goose', '/tmp/goose', '2026-08-18T12:00:00Z',
            '2026-08-18T12:00:01Z', 'user', '{}', 'auto', 'openai',
            '{\"model_name\":\"gpt-5.6\"}', NULL
        );
        INSERT INTO messages (
            message_id, session_id, role, content_json, created_timestamp, metadata_json
        ) VALUES (
            'msg-1', 'sqlite-goose', 'user',
            '[{\"type\":\"text\",\"text\":\"Loaded from Goose SQLite\"}]',
            1787054400, '{\"userVisible\":true,\"agentVisible\":true}'
        );
        ",
        )
        .unwrap();
    drop(connection);

    let catalog = HarnessCatalog::new();
    let discovered = catalog
        .discover(&DiscoveryQuery {
            harnesses: vec![HarnessId::from(HarnessId::GOOSE)],
            homes: HarnessHomes {
                goose: db.clone(),
                ..HarnessHomes::default()
            },
            ..DiscoveryQuery::default()
        })
        .unwrap();
    assert_eq!(discovered.len(), 1);
    assert_eq!(discovered[0].locator.harness.as_str(), HarnessId::GOOSE);
    assert_eq!(discovered[0].message_count, Some(1));
    assert_eq!(discovered[0].model.as_deref(), Some("gpt-5.6"));

    let session = catalog.load(&discovered[0].locator).unwrap();
    assert_eq!(session.load_fidelity(), Fidelity::ValueLossless);
    assert_eq!(
        session.messages[0].content.as_deref(),
        Some("Loaded from Goose SQLite")
    );
    let exported: serde_json::Value =
        serde_json::from_str(&session.to_jsonl(SessionFormat::Goose).unwrap()).unwrap();
    assert_eq!(exported["id"], "sqlite-goose");
    assert_eq!(exported["conversation"][0]["id"], "msg-1");
    let mut follower = catalog.follow(&discovered[0].locator).unwrap();
    assert!(follower.poll().unwrap().is_some());
    let audit = audit_dir(&db, Corpus::Goose, Some(1));
    assert_eq!(audit.files, 1);
    assert_eq!(audit.lines, 1);
    assert_eq!(audit.parse_errors, 0);
    assert!(audit.notes.is_empty(), "{:?}", audit.notes);
    std::fs::remove_dir_all(dir).unwrap();
}