noxid-cli 0.2.1

The Noxid compiler command line: check, build, test, adapt, and the agent surface
//! WO-53 stage (c): `noxid describe guide <topic>` pulls one budgeted
//! agent-guide topic on demand, so a model loads a single surface instead of
//! the whole guide. The same `kind: "guide"` is served by the MCP describe
//! operation (crates/cli/src/mcp.rs).

use std::process::{Command, Output};

fn noxid(args: &[&str]) -> Output {
    Command::new(env!("CARGO_BIN_EXE_noxid"))
        .args(args)
        .output()
        .expect("run noxid")
}

#[test]
fn describe_guide_prints_only_the_requested_topic() {
    let output = noxid(&["describe", "guide", "routing"]);
    assert!(
        output.status.success(),
        "describe guide routing failed: {}",
        String::from_utf8_lossy(&output.stderr)
    );
    let text = String::from_utf8_lossy(&output.stdout);
    assert!(
        text.contains("Noxid routing"),
        "did not print the routing topic: {text}"
    );
    assert!(
        text.contains("Context first: call query_project"),
        "topic did not open with the context-first preamble"
    );
    // Only the routing topic — not the siblings it was split from.
    assert!(!text.contains("Noxid storage"), "leaked the storage topic");
    assert!(
        !text.contains("Noxid realtime"),
        "leaked the realtime topic"
    );
    // A single budgeted topic, not the whole guide.
    assert!(
        text.len() < 6 * 1024,
        "topic exceeded the 6 KB budget at {} bytes",
        text.len()
    );
}

#[test]
fn describe_guide_serves_the_split_topics() {
    for topic in ["storage", "realtime"] {
        let output = noxid(&["describe", "guide", topic]);
        assert!(
            output.status.success(),
            "describe guide {topic} failed: {}",
            String::from_utf8_lossy(&output.stderr)
        );
    }
}

#[test]
fn describe_guide_rejects_unknown_topic() {
    let output = noxid(&["describe", "guide", "does-not-exist"]);
    assert!(!output.status.success(), "unknown topic should fail");
    let combined = format!(
        "{}{}",
        String::from_utf8_lossy(&output.stdout),
        String::from_utf8_lossy(&output.stderr)
    );
    assert!(
        combined.contains("unknown agent-guide topic"),
        "wrong error for unknown topic: {combined}"
    );
}