magi-code 0.96.1

Repository-aware CLI coding agent for terminal work
Documentation
mod welcome;

use super::{
    render_scroll_view_persistent_with_metrics_and_theme, transcript_scroll_view_content_width,
};
use crate::tui::state::MissionControlState;
use ratatui::{
    Frame,
    layout::Rect,
    widgets::{Paragraph, Wrap},
};

pub(super) fn draw_transcript(frame: &mut Frame<'_>, area: Rect, state: &MissionControlState) {
    let theme = state.theme;
    let focused = state.is_transcript_focused()
        && state.diff.dialog.is_none()
        && (state.top_modal().is_none()
            || (state.header_modal_visible() && state.modals.focused_header_modal.is_none()));
    frame.render_widget(
        super::bordered_block()
            .title(ratatui::text::Line::styled(
                "Transcript",
                theme.title(focused),
            ))
            .border_style(theme.border(focused))
            .style(theme.pane()),
        area,
    );
    let text_area = super::transcript_text_area_for_pane(area);
    if state.transcript.is_empty() || crate::tui::release_notes::shows_restart_welcome(state) {
        welcome::draw_welcome(frame, text_area, state);
        return;
    }
    let visible = crate::tui::transcript_projection::visible_transcript_lines(
        state,
        transcript_scroll_view_content_width(text_area).max(1),
        text_area.height,
    );
    for (row, image_row) in &visible.image_rows {
        if *row >= visible.scroll_offset {
            let y = row - visible.scroll_offset;
            if y < usize::from(text_area.height) {
                state.images.borrow_mut().place_row(
                    image_row,
                    Rect::new(
                        text_area.x,
                        text_area.y + y as u16,
                        transcript_scroll_view_content_width(text_area),
                        1,
                    ),
                );
            }
        }
    }
    // Projection uses reverse tail distance; widget state uses top-origin offset
    // within bounded projection. Keep these authorities separate.
    state
        .scroll_views
        .transcript
        .borrow_mut()
        .set_offset(ratatui::layout::Position::new(
            0,
            crate::tui::transcript::usize_to_u16_saturating(visible.scroll_offset),
        ));
    render_scroll_view_persistent_with_metrics_and_theme(
        frame,
        text_area,
        transcript_scroll_view_content_width(text_area),
        0,
        visible
            .scroll_offset
            .saturating_add(text_area.height as usize)
            .max(visible.scroll_offset.saturating_add(visible.lines.len()))
            .try_into()
            .unwrap_or(u16::MAX),
        visible.scrollbar.content_length,
        visible.scrollbar.position,
        visible.scrollbar.viewport_length,
        Paragraph::new(visible.lines)
            .style(theme.pane())
            .wrap(Wrap { trim: false }),
        &state.scroll_views.transcript,
        theme,
    );
}

#[cfg(test)]
mod profiling {
    use super::*;
    use ratatui::backend::TestBackend;

    #[test]
    #[ignore = "release-mode TestBackend transcript measurement; run with --release --ignored --nocapture"]
    fn transcript_test_backend_measurement() {
        let area = Rect::new(0, 0, 120, 40);
        let mut state = MissionControlState::default();
        for index in 0..500 {
            state.transcript.push_back(format!(
                "assistant: entry {index} {}",
                "wrapped transcript text ".repeat(30)
            ));
        }
        state.set_scroll_offset(&state.scroll_views.transcript, 200);
        let mut terminal =
            ratatui::Terminal::new(TestBackend::new(area.width, area.height)).unwrap();
        terminal
            .draw(|frame| draw_transcript(frame, area, &state))
            .unwrap();
        crate::tui::transcript_cards::reset_project_entry_count_for_profiling();
        let started = std::time::Instant::now();
        for _ in 0..100 {
            terminal
                .draw(|frame| draw_transcript(frame, area, &state))
                .unwrap();
        }
        eprintln!(
            "transcript_render backend=TestBackend physical_terminal=false frames=100 elapsed_us={} projected_cards={}",
            started.elapsed().as_micros(),
            crate::tui::transcript_cards::project_entry_count_for_profiling()
        );
    }
}