liminal-cli 0.3.4

The liminal command: serve the network, maintain its stores, or serve its discovery MCP over stdio
Documentation
use super::handshake::{Version, negotiated};
use super::queue::Prompts;
use super::stream::project;
use serde_json::json;

#[test]
fn accepts_one_and_two_and_refuses_three_by_name() -> anyhow::Result<()> {
    assert_eq!(negotiated(1)?, Version::One);
    assert_eq!(negotiated(2)?, Version::Two);
    let error = negotiated(3)
        .err()
        .ok_or_else(|| anyhow::anyhow!("3 was admitted"))?;
    assert_eq!(
        error.to_string(),
        "ACP protocol version 3 refused: offered 2, supported 2 and 1"
    );
    Ok(())
}

#[test]
fn thirty_third_unread_prompt_is_refused_without_displacing_mail() -> anyhow::Result<()> {
    let mut queue = Prompts::new(32);
    for n in 0..32 {
        queue.push(n.to_string())?;
    }
    let error = queue
        .push("overflow".to_owned())
        .err()
        .ok_or_else(|| anyhow::anyhow!("overflow admitted"))?;
    assert_eq!(
        error.to_string(),
        "prompt_queue 32 reached: 32 unread prompts"
    );
    for n in 0..32 {
        assert_eq!(queue.pop().as_deref(), Some(n.to_string().as_str()));
    }
    assert!(queue.pop().is_none());
    Ok(())
}

#[test]
fn stream_whitelists_title_and_status_and_never_copies_tool_bytes() -> anyhow::Result<()> {
    let item = project(Version::One, json!({
        "sessionId":"s", "update": {"sessionUpdate":"tool_call", "toolCallId":"t", "title":"Review", "status":"completed",
        "rawInput":{"secret":"input"}, "rawOutput":{"secret":"output"},
        "content":[{"type":"content","content":{"type":"text","text":"file bytes"}}]}
    }), "s", 128)?.ok_or_else(|| anyhow::anyhow!("tool title missing"))?;
    assert_eq!(item["title"], "Review");
    assert_eq!(item["status"], "completed");
    let encoded = serde_json::to_string(&item)?;
    for forbidden in ["rawInput", "rawOutput", "file bytes", "secret"] {
        assert!(!encoded.contains(forbidden));
    }
    Ok(())
}

#[test]
fn text_is_cut_at_a_character_boundary_and_marked() -> anyhow::Result<()> {
    let item = project(
        Version::One,
        json!({"sessionId":"s", "update":{
            "sessionUpdate":"agent_message_chunk", "content":{"type":"text","text":"é".repeat(128)}
        }}),
        "s",
        128,
    )?
    .ok_or_else(|| anyhow::anyhow!("chunk missing"))?;
    let text = item["text"]
        .as_str()
        .ok_or_else(|| anyhow::anyhow!("text missing"))?;
    assert!(text.chars().all(|ch| ch == 'é'));
    assert!(serde_json::to_vec(&item)?.len() <= 128);
    assert_eq!(item["truncated"], true);
    assert!(
        project(
            Version::One,
            json!({"sessionId":"foreign","update":{
                "sessionUpdate":"agent_message_chunk","content":{"type":"text","text":"private"}
            }}),
            "s",
            64
        )
        .is_err()
    );
    Ok(())
}

#[test]
fn v2_chunks_keep_the_required_message_identity() -> anyhow::Result<()> {
    let item = project(Version::Two, json!({"sessionId":"s","update":{
        "sessionUpdate":"agent_message_chunk","messageId":"message-1","content":{"type":"text","text":"response"}
    }}), "s", 256)?.ok_or_else(|| anyhow::anyhow!("v2 chunk missing"))?;
    assert_eq!(item["message_id"], "message-1");
    assert_eq!(item["text"], "response");
    Ok(())
}