supercode-harness 0.4.4

The optional native Supercode agent and tool harness
Documentation
//! Session-container adapters over the message-slice reduction engine.

use super::{
    invert_messages, invert_one_messages, project_messages, stub, verify_log_messages,
    ReductionLog, ReductionPolicy, REDUCTION_SENTINEL,
};
use crate::message::ChatMessage;
use crate::session::{Session, SessionFormat};
use crate::{Error, Result};

/// Pure function of `(session, policy, prior)`: the compatibility entry point
/// producing what the model sees (SPEC.md A5).
pub fn project(
    session: &Session,
    policy: &ReductionPolicy,
    prior: &ReductionLog,
) -> (Vec<ChatMessage>, ReductionLog) {
    project_messages(&session.messages, policy, prior)
}

/// Reconstruct a full view from a reduced view and sidecar session.
pub fn invert(
    reduced: &[ChatMessage],
    log: &ReductionLog,
    sidecar_session: &Session,
) -> Result<Vec<ChatMessage>> {
    Ok(invert_messages(reduced, log, &sidecar_session.messages)?)
}

/// Verify every reduction against a sidecar session.
pub fn verify_log(log: &ReductionLog, sidecar: &Session) -> Result<()> {
    verify_log_messages(log, &sidecar.messages)?;
    Ok(())
}

/// Rehydrate one reduction by id against a sidecar session.
pub fn invert_one(
    reduced: &[ChatMessage],
    log: &ReductionLog,
    id: &str,
    sidecar_session: &Session,
) -> Result<(Vec<ChatMessage>, ReductionLog)> {
    Ok(invert_one_messages(
        reduced,
        log,
        id,
        &sidecar_session.messages,
    )?)
}

/// Export a live session from its full-fidelity sidecar.
pub fn export_session(sidecar: &str, format: SessionFormat) -> Result<String> {
    let session = Session::from_sidecar_str(sidecar)?;
    reject_reduced_sidecar(&session, "export_session")?;
    Ok(session.to_jsonl(format)?)
}

/// Export a live session while replaying an imported native prefix verbatim.
pub fn export_session_spliced(
    sidecar: &str,
    format: SessionFormat,
    session_id: Option<&str>,
) -> Result<String> {
    export_session_spliced_with_overrides(sidecar, format, session_id, None)
}

/// Spliced sidecar export with an optional working-directory override.
pub fn export_session_spliced_with_overrides(
    sidecar: &str,
    format: SessionFormat,
    session_id: Option<&str>,
    cwd: Option<&std::path::Path>,
) -> Result<String> {
    let mut session = Session::from_sidecar_str(sidecar)?;
    reject_reduced_sidecar(&session, "export_session_spliced")?;
    if let Some(cwd) = cwd {
        session.meta.cwd = Some(cwd.to_path_buf());
    }
    Ok(session.to_jsonl_spliced(format, session_id)?)
}

fn reject_reduced_sidecar(session: &Session, operation: &str) -> Result<()> {
    if session_contains_reduction_stub(session) {
        return Err(Error::Other(format!(
            "{operation}: refusing to export — the sidecar contains a grammar-valid \
             reduction stub beginning with {REDUCTION_SENTINEL:?}; a reduced view leaked \
             into an export path that must only read the full-fidelity sidecar"
        )));
    }
    Ok(())
}

fn string_contains_reduction_stub(value: &str) -> bool {
    value.lines().any(|line| stub::parse(line).is_some())
}

fn json_value_contains_reduction_stub(value: &serde_json::Value) -> bool {
    match value {
        serde_json::Value::String(value) => string_contains_reduction_stub(value),
        serde_json::Value::Array(values) => values.iter().any(json_value_contains_reduction_stub),
        serde_json::Value::Object(fields) => {
            fields.values().any(json_value_contains_reduction_stub)
        }
        _ => false,
    }
}

fn session_contains_reduction_stub(session: &Session) -> bool {
    session.messages.iter().any(|message| {
        message
            .content
            .as_deref()
            .is_some_and(string_contains_reduction_stub)
            || message
                .content_parts
                .as_ref()
                .is_some_and(|parts| parts.iter().any(json_value_contains_reduction_stub))
            || message.tool_calls().iter().any(|call| {
                serde_json::from_str::<serde_json::Value>(&call.function.arguments)
                    .map(|value| json_value_contains_reduction_stub(&value))
                    .unwrap_or_else(|_| string_contains_reduction_stub(&call.function.arguments))
            })
    })
}