supercode-interchange 0.4.21

Canonical, provider-neutral session interchange primitives for Supercode
Documentation
use std::fs;

use supercode_interchange::session::Session;
use supercode_interchange::watch::normalized_session_json;

#[test]
fn native_terminal_session_end_is_observable_without_a_channel_binding() {
    let path = std::env::temp_dir().join(format!("hermes-lifecycle-{}.db", std::process::id()));
    let db = rusqlite::Connection::open(&path).unwrap();
    db.execute_batch(include_str!(
        "../src/orchestration/codec/hermes_state_v22.sql"
    ))
    .unwrap();
    db.execute_batch(
        "INSERT INTO sessions (id, source, started_at, ended_at, end_reason) VALUES
         ('worker', 'kanban', 100, 200.75, 'cli_close'),
         ('active', 'cli', 201, NULL, NULL);",
    )
    .unwrap();
    drop(db);
    let before = fs::read(&path).unwrap();
    let ended =
        normalized_session_json(&Session::from_hermes_sqlite(&path, Some("worker")).unwrap());
    assert_eq!(ended["ended_at"], "1970-01-01T00:03:20.750Z");
    assert_eq!(ended["end_reason"], "cli_close");
    assert_eq!(ended["trigger"], "task");
    assert!(ended["surface"].is_null());
    let active =
        normalized_session_json(&Session::from_hermes_sqlite(&path, Some("active")).unwrap());
    assert!(active["ended_at"].is_null());
    assert!(active["end_reason"].is_null());
    assert_eq!(fs::read(&path).unwrap(), before);
    fs::remove_file(path).unwrap();
}