magi-code 0.77.1

Repository-aware CLI coding agent for terminal work
Documentation
use super::*;

#[test]
fn render_transcript_shows_streaming_assistant_label_until_complete() {
    let mut state = MissionControlState::default();
    state.apply_output_event(&OutputEvent::AssistantDelta {
        text: "working".to_string(),
    });
    let backend = TestBackend::new(80, 20);
    let mut terminal = ratatui::Terminal::new(backend).unwrap();
    terminal.draw(|frame| draw(frame, &state)).unwrap();
    let buffer = terminal.backend().buffer();
    assert!(find_text(buffer, "Agent").is_some());
    assert!(find_text(buffer, "Agent …").is_some());

    state.apply_output_event(&OutputEvent::AssistantComplete {
        text: "working".to_string(),
    });
    terminal.draw(|frame| draw(frame, &state)).unwrap();
    let completed = terminal.backend().buffer();

    assert!(find_text(completed, "Agent").is_some());
    assert!(find_text(completed, "Agent").is_some());
    assert!(find_text(completed, "Agent …").is_none());
}

#[test]
fn render_places_activity_tree_above_detail_with_wider_transcript() {
    let mut state = MissionControlState::default();
    state.apply_output_event(&OutputEvent::AssistantDelta {
        text: "hello".to_string(),
    });
    state.apply_activity_event(ActivityEvent::Started {
        id: ActivityId::new("a1"),
        parent_id: None,
        kind: ActivityKind::Tool,
        status: ActivityStatus::Running,
        metadata: ActivityMetadata::new("bash echo"),
    });

    let area = Rect::new(0, 0, 100, 30);
    let layout = layout_for(area, &state);
    let activity_tree = layout.activity_tree.expect("activity tree");
    let detail = layout.detail.expect("detail");
    assert_eq!(
        state.layout_mode,
        crate::tui::state::TuiLayoutMode::TranscriptFocused
    );
    assert!(layout.transcript.width > activity_tree.width);
    assert_eq!(activity_tree.width, detail.width);
    assert_eq!(activity_tree.x, detail.x);
    assert!(activity_tree.y < detail.y);

    let backend = TestBackend::new(100, 30);
    let mut terminal = ratatui::Terminal::new(backend).unwrap();
    terminal.draw(|frame| draw(frame, &state)).unwrap();
    let buffer = terminal.backend().buffer();

    let transcript = find_text(buffer, "Session:").unwrap();
    let tree = find_text(buffer, "Activity Tree").unwrap();
    let detail = find_text(buffer, "Selected Activity Detail").unwrap();

    assert!(tree.0 <= detail.0 + 1);
    assert!(tree.1 < detail.1);
    assert!(transcript.0 < tree.0);
}

#[test]
fn render_transcript_tails_overflow_by_default() {
    let mut state = MissionControlState::default();
    for line in 0..8 {
        state.apply_output_event(&OutputEvent::UserPrompt {
            text: format!("line-{line}"),
        });
    }

    let backend = TestBackend::new(80, 12);
    let mut terminal = ratatui::Terminal::new(backend).unwrap();
    terminal.draw(|frame| draw(frame, &state)).unwrap();
    let rendered = terminal
        .backend()
        .buffer()
        .content()
        .iter()
        .map(|cell| cell.symbol())
        .collect::<String>();

    assert!(rendered.contains("line-7"));
    assert!(!rendered.contains("line-0"));
}

#[test]
fn render_transcript_tails_single_long_wrapped_message() {
    let mut state = MissionControlState::default();
    state.apply_output_event(&OutputEvent::AssistantComplete {
        text: format!("HEAD {}\nTAIL-WRAPPED", "x".repeat(180)),
    });

    let backend = TestBackend::new(50, 12);
    let mut terminal = ratatui::Terminal::new(backend).unwrap();
    terminal.draw(|frame| draw(frame, &state)).unwrap();
    let rendered = terminal
        .backend()
        .buffer()
        .content()
        .iter()
        .map(|cell| cell.symbol())
        .collect::<String>();

    assert!(rendered.contains("TAIL"), "{rendered:?}");
    assert!(rendered.contains("-WRAPPED"), "{rendered:?}");
    assert!(!rendered.contains("HEAD"));
}

#[test]
fn render_transcript_tails_word_wrapped_overflow() {
    let state = MissionControlState {
        transcript: vec![
            "assistant: alpha beta gamma delta epsilon zeta eta theta iota kappa lambda mu nu xi omicron pi rho sigma tau upsilon phi chi psi omega SENTINEL".to_string(),
        ]
        .into(),
        ..Default::default()
    };

    let backend = TestBackend::new(33, 12);
    let mut terminal = ratatui::Terminal::new(backend).unwrap();
    terminal.draw(|frame| draw(frame, &state)).unwrap();
    let rendered = terminal
        .backend()
        .buffer()
        .content()
        .iter()
        .map(|cell| cell.symbol())
        .collect::<String>();

    assert!(
        rendered.contains("SE") && rendered.contains("NTINEL"),
        "{rendered}"
    );
}

#[test]
fn render_transcript_markdown_code_and_boundaries() {
    let mut state = MissionControlState::default();
    state.apply_output_event(&OutputEvent::UserPrompt {
        text: "show code".to_string(),
    });
    state.apply_output_event(&OutputEvent::AssistantComplete {
        text: "# Plan\n\n- use `render`\n\n```rust\nfn main() {}\n```".to_string(),
    });
    state.apply_output_event(&OutputEvent::ToolResult {
        changed_paths: Vec::new(),
        call: Box::new(crate::providers::ToolCall {
            id: "tool-1".to_string(),
            name: "bash".to_string(),
            arguments: serde_json::json!({}),
        }),
        result: Box::new(crate::tools::ToolResult {
            tool_name: "bash".to_string(),
            success: true,
            content: "ok".to_string(),
            metadata: serde_json::json!({}),
            display: crate::tools::ToolResultDisplay::default(),
        }),
        summary: Box::new(ToolDisplaySummary {
            tool_name: "bash".to_string(),
            status: ToolStatus::Success,
            unicode_mark: "",
            ascii_mark: "OK",
            label: "bash echo ok".to_string(),
            metadata: Vec::new(),
        }),
    });

    let backend = TestBackend::new(100, 40);
    let mut terminal = ratatui::Terminal::new(backend).unwrap();
    terminal.draw(|frame| draw(frame, &state)).unwrap();
    terminal.draw(|frame| draw(frame, &state)).unwrap();
    let buffer = terminal.backend().buffer();
    let rendered = buffer
        .content()
        .iter()
        .map(|cell| cell.symbol())
        .collect::<String>();

    assert!(find_text(buffer, "User: ").is_some());
    assert!(find_text(buffer, "You").is_none());
    assert!(find_text(buffer, "Agent").is_some());
    assert!(find_text(buffer, "Agent").is_some());
    assert!(rendered.contains("bash echo ok"));
    assert!(rendered.contains("# Plan"));
    assert!(rendered.contains("• use "));
    assert!(rendered.contains("language: rust"));
    assert!(rendered.contains("│ fn main"));
    let code = find_text(buffer, "fn main").unwrap();
    assert_eq!(
        buffer[code].bg,
        MissionControlTheme::default().surface_panel()
    );
    let heading = find_text(buffer, "# Plan").unwrap();
    assert_eq!(buffer[heading].style().fg, state.theme.heading_style().fg);
}

#[test]
fn render_transcript_assistant_diff_fence_uses_diff_styles() {
    let mut state = MissionControlState::default();
    state.apply_output_event(&OutputEvent::AssistantComplete {
        text: "```diff\n-old\n+new\n```".to_string(),
    });

    let backend = TestBackend::new(80, 20);
    let mut terminal = ratatui::Terminal::new(backend).unwrap();
    terminal.draw(|frame| draw(frame, &state)).unwrap();
    terminal.draw(|frame| draw(frame, &state)).unwrap();
    let buffer = terminal.backend().buffer();

    assert!(find_text(buffer, "language: diff").is_some());
    let removed = find_text(buffer, "-old").unwrap();
    assert_eq!(
        buffer[removed].fg,
        MissionControlTheme::default().transcript_error_label_color()
    );
    assert_eq!(
        buffer[removed].bg,
        MissionControlTheme::default().surface_panel()
    );
    let inserted = find_text(buffer, "+new").unwrap();
    assert_eq!(
        buffer[inserted].fg,
        MissionControlTheme::default().text_accent()
    );
    assert_eq!(
        buffer[inserted].bg,
        MissionControlTheme::default().surface_panel()
    );
}

#[test]
fn render_transcript_multiline_markdown_preserves_alignment() {
    let mut state = MissionControlState::default();
    state.apply_output_event(&OutputEvent::AssistantComplete {
        text: "First paragraph\n\n- one\n- two\n\nAfter".to_string(),
    });

    let backend = TestBackend::new(80, 20);
    let mut terminal = ratatui::Terminal::new(backend).unwrap();
    terminal.draw(|frame| draw(frame, &state)).unwrap();
    terminal.draw(|frame| draw(frame, &state)).unwrap();
    let layout = layout_for(Rect::new(0, 0, 80, 20), &state);
    let rendered = rendered_text_in_area(terminal.backend().buffer(), layout.transcript);

    assert!(rendered.contains("  First paragraph"), "{rendered}");
    assert!(rendered.contains("  • one"), "{rendered}");
    assert!(rendered.contains("  • two"), "{rendered}");
    assert!(rendered.contains("  After"), "{rendered}");
}

fn render_transcript_scrollbar_case(transcript: Vec<String>) -> (Buffer, Rect) {
    let state = MissionControlState {
        transcript: transcript.into(),
        ..Default::default()
    };
    let area = Rect::new(0, 0, 80, 20);
    let layout = layout_for(area, &state);
    let backend = TestBackend::new(area.width, area.height);
    let mut terminal = ratatui::Terminal::new(backend).unwrap();
    terminal.draw(|frame| draw(frame, &state)).unwrap();
    (
        terminal.backend().buffer().clone(),
        transcript_text_area_for_pane(layout.transcript),
    )
}

fn assert_transcript_scrollbar_gutter(
    buffer: &Buffer,
    text_area: Rect,
    adjacent_row_text: &str,
    expected_adjacent: &str,
) {
    let gutter_x = text_area.x + text_area.width - 1;
    let gap_x = gutter_x - 1;
    let card_padding_x = gutter_x - 2;
    let adjacent_x = gutter_x - 3;
    let adjacent_row = find_text_in_area(buffer, text_area, adjacent_row_text)
        .unwrap_or_else(|| panic!("transcript fixture text missing: {adjacent_row_text}"))
        .1;
    let scrollbar_symbol = buffer[(gutter_x, adjacent_row)].symbol();
    assert!(matches!(scrollbar_symbol, "" | ""));
    assert_eq!(
        buffer[(gutter_x, adjacent_row)].fg,
        if scrollbar_symbol == "" {
            MissionControlTheme::default().text_accent()
        } else {
            MissionControlTheme::default().text_dim()
        }
    );
    assert_eq!(
        buffer[(gutter_x, adjacent_row)].bg,
        MissionControlTheme::default().surface_background()
    );
    assert_eq!(buffer[(gap_x, adjacent_row)].symbol(), " ");
    assert_eq!(
        buffer[(gap_x, adjacent_row)].bg,
        MissionControlTheme::default().surface_background()
    );
    assert_eq!(
        buffer[(card_padding_x, adjacent_row)].bg,
        MissionControlTheme::default().surface_panel()
    );
    assert_eq!(
        buffer[(adjacent_x, adjacent_row)].symbol(),
        expected_adjacent
    );
    assert!(
        (text_area.y..text_area.y + text_area.height)
            .any(|y| buffer[(gutter_x, y)].symbol() == "")
    );
}
#[test]
fn production_transcript_scrollbar_is_visible_without_overflow() {
    let fixture = format!("fit-sentinel{}", "F".repeat(100));
    let (buffer, text_area) = render_transcript_scrollbar_case(vec![fixture]);

    assert_transcript_scrollbar_gutter(&buffer, text_area, "fit-sentinel", "F");
}

#[test]
fn production_transcript_scrollbar_is_visible_with_overflow() {
    let (buffer, text_area) = render_transcript_scrollbar_case(
        (0..40)
            .map(|line| format!("overflow-line-{line}{}", "O".repeat(60)))
            .collect(),
    );

    assert_transcript_scrollbar_gutter(&buffer, text_area, "overflow-line-39", "O");
    assert!(find_text_in_area(&buffer, text_area, "overflow-line-0").is_none());
}