malvin 0.2.5

Non-interactive research and coding agent
use super::acp_tee::{
    AcpTeeDirection, AcpTeeLineFmt, AcpTeeStdoutEvent, acp_tee_display_line, acp_tee_log_line,
    format_line_acp_ansi_payload, print_stdout_acp_tee_line,
    print_stdout_acp_tee_line_with_timestamp, print_stdout_acp_tool_summary_tee,
};
use crate::output::stdout_log_pair::acp_tee_log_prefix;
use crate::terminal_palette::ansi_body;

#[test]
fn timestamp_present_on_acp_tee_helpers() {
    let ts = "20260413.121314.015";
    let ctx = AcpTeeLineFmt {
        ts,
        direction: AcpTeeDirection::FromAgent,
        who: "<check_plan",
        line: "[thinking]",
        dim_payload: true,
    };
    let tool_log = super::format_line_with_timestamp(ts, "<check_plan", "Run echo hi · 1ms · ✓");
    let tee_log = acp_tee_log_line(&ctx);
    assert!(
        super::is_log_timestamp_token(tool_log.split_whitespace().next().unwrap_or("")),
        "tool summary log should start with timestamp token; got {tool_log:?}"
    );
    assert!(
        super::is_log_timestamp_token(tee_log.split_whitespace().next().unwrap_or("")),
        "acp_tee_log_line should include timestamp; got {tee_log:?}"
    );
    let prefix = acp_tee_log_prefix(&AcpTeeLineFmt {
        ts,
        direction: AcpTeeDirection::FromAgent,
        who: "<router",
        line: "",
        dim_payload: false,
    });
    assert!(
        prefix.starts_with("20260413"),
        "markdown/log prefix should include timestamp; got {prefix:?}"
    );
}

#[test]
fn acp_display_and_log_helpers_include_timestamp_on_stdout_formatted_lines() {
    let ctx = AcpTeeLineFmt {
        ts: "20260413.121314.015",
        direction: AcpTeeDirection::ToAgent,
        who: "malvin",
        line: "hello",
        dim_payload: false,
    };
    let plain_acp = format_line_acp_ansi_payload(&ctx);
    assert!(
        !plain_acp.contains("20260413"),
        "raw non-timestamp helper remains non-ts"
    );
    assert!(acp_tee_display_line(&ctx).contains("hello"));
    assert!(
        !acp_tee_display_line(&ctx).starts_with("20260413"),
        "live stdout display must omit wall-clock prefix"
    );
    assert!(acp_tee_log_line(&ctx).starts_with("20260413"));
    assert!(acp_tee_log_prefix(&ctx).starts_with("20260413"));
    print_stdout_acp_tee_line(AcpTeeDirection::FromAgent, "<w", "probe");
    print_stdout_acp_tee_line_with_timestamp(&AcpTeeStdoutEvent {
        direction: AcpTeeDirection::ToAgent,
        who: "w",
        line: "plain",
        ts: "t",
        emit_stdout_markdown: false,
        dim_payload: false,
    });
    print_stdout_acp_tool_summary_tee(
        &AcpTeeStdoutEvent {
            direction: AcpTeeDirection::FromAgent,
            who: "k",
            line: "Run cargo test · 1.0s · ✓",
            ts: "ts",
            emit_stdout_markdown: false,
            dim_payload: false,
        },
        "Run cargo test · 1.0s · ✓",
    );
}

#[test]
fn ansi_acp_tee_directions_use_distinct_bracket_colors() {
    let _: Option<super::acp_tee::AcpTeeStdoutEvent> = None;
    let _ = super::acp_tee::print_stdout_acp_tee_line;
    let _ = super::acp_tee::print_stdout_acp_tee_line_with_timestamp;
    let _ = super::acp_tee::print_stdout_acp_tee_line_with_timestamp_dim_plain;
    let _: Option<super::acp_tee_markdown::TermimadStdoutGate> = None;
    let to_line = format_line_acp_ansi_payload(&AcpTeeLineFmt {
        ts: "20260413.121314.015",
        direction: AcpTeeDirection::ToAgent,
        who: ">stem",
        line: "out",
        dim_payload: false,
    });
    let from_line = format_line_acp_ansi_payload(&AcpTeeLineFmt {
        ts: "20260413.121314.015",
        direction: AcpTeeDirection::FromAgent,
        who: "<stem",
        line: "in",
        dim_payload: false,
    });
    assert!(to_line.contains('\x1b'));
    assert!(from_line.contains('\x1b'));
    assert_ne!(to_line, from_line);
    assert!(to_line.ends_with("out"));
    assert!(
        from_line.contains(&format!("{}in", ansi_body())),
        "FromAgent payload should be white; got {from_line:?}"
    );
    assert!(!to_line.starts_with("20260413"));
    assert!(!from_line.starts_with("20260413"));
}

#[test]
fn agent_message_prefix_rendered_payload_uses_white() {
    use super::acp_tee_markdown::agent_rendered_markup_payload;
    use crate::output::stdout_log_pair::{AcpTeeLineFmt, format_line_acp_ansi_payload};

    let ctx = AcpTeeLineFmt {
        ts: "20260413.121314.015",
        direction: AcpTeeDirection::FromAgent,
        who: "<stem",
        line: "hello agent",
        dim_payload: false,
    };
    let white = agent_rendered_markup_payload("hello agent");
    assert!(
        white.contains(&format!("{}hello agent", ansi_body())),
        "white wrapper should color agent payload; got {white:?}"
    );
    let prefix = format_line_acp_ansi_payload(&AcpTeeLineFmt { line: "", ..ctx });
    let full = format!("{prefix}{white}");
    assert!(
        full.contains(&white),
        "prefix-rendered tee line should carry white payload; got {full:?}"
    );
}

#[test]
fn ansi_acp_tee_agent_message_payload_uses_white() {
    let line = format_line_acp_ansi_payload(&AcpTeeLineFmt {
        ts: "20260413.121314.015",
        direction: AcpTeeDirection::FromAgent,
        who: "<stem",
        line: "hello agent",
        dim_payload: false,
    });
    let white = format!(
        "{}hello agent{}",
        ansi_body(),
        crate::terminal_palette::ANSI_RESET
    );
    assert!(
        line.contains(&white),
        "regular agent payload should be white; got {line:?}"
    );
}

#[test]
fn ansi_acp_tee_can_dim_payload_text() {
    let line = format_line_acp_ansi_payload(&AcpTeeLineFmt {
        ts: "20260413.121314.015",
        direction: AcpTeeDirection::FromAgent,
        who: "<stem",
        line: "[thinking]",
        dim_payload: true,
    });
    assert!(line.contains("\x1b[90m[thinking]\x1b[0m"));
    assert!(!line.starts_with("20260413"));
}