magi-code 0.63.4

Repository-aware CLI coding agent for terminal work
Documentation
use super::{overlay_block, render_overlay_fill, render_scroll_view_persistent};
use crate::tui::{PADDED_INLINE_SEPARATOR, input, state::MissionControlState, theme::MATRIX_GREEN};
use ratatui::{
    Frame,
    layout::{Alignment, Rect},
    text::{Line, Span},
    widgets::{Clear, Paragraph, Wrap},
};

pub(super) fn draw_status(frame: &mut Frame<'_>, area: Rect, state: &MissionControlState) {
    frame.render_widget(
        Paragraph::new(Line::from(Span::styled(
            footer_left_text(state),
            MATRIX_GREEN.status_line(),
        )))
        .style(MATRIX_GREEN.status_line()),
        area,
    );
    frame.render_widget(
        Paragraph::new(footer_right_line(state))
            .style(MATRIX_GREEN.status_line())
            .alignment(Alignment::Right),
        area,
    );
}

fn footer_left_text(state: &MissionControlState) -> String {
    let mut text = format!("📂Cwd: {}", state.footer_cwd);
    if let Some(branch) = state
        .footer_git_branch
        .as_deref()
        .filter(|branch| !branch.is_empty())
    {
        text.push_str(PADDED_INLINE_SEPARATOR);
        text.push_str("🪾Branch: ");
        text.push_str(branch);
    }
    text
}

fn footer_right_text(state: &MissionControlState) -> String {
    let base = format!("🤘MAGI-CODE v{}🤘", env!("CARGO_PKG_VERSION"));
    #[cfg(any(test, debug_assertions))]
    {
        if let Some(perf) = state.perf.footer_text() {
            return format!("{perf}{PADDED_INLINE_SEPARATOR}{base}");
        }
    }
    base
}

fn footer_right_line(state: &MissionControlState) -> Line<'static> {
    let text = footer_right_text(state);
    Line::from(Span::styled(text, MATRIX_GREEN.accent(false)))
}

pub(super) fn draw_help(frame: &mut Frame<'_>, area: Rect, state: &MissionControlState) {
    frame.render_widget(Clear, area);
    let block = overlay_block("Help");
    let inner = block.inner(area);
    frame.render_widget(block, area);
    let text_area = render_overlay_fill(frame, inner);
    let help_text = input::help_text();
    let wrap_width = super::scroll_view_content_width(text_area).max(1);
    let scroll = state.help_render_offset(text_area.height, wrap_width, help_text);
    render_scroll_view_persistent(
        frame,
        text_area,
        super::usize_to_u16_saturating(scroll),
        super::usize_to_u16_saturating(crate::tui::transcript::ratatui_wrapped_visual_rows(
            help_text, wrap_width,
        )),
        Paragraph::new(help_text)
            .style(MATRIX_GREEN.panel_alt())
            .wrap(Wrap { trim: false }),
        &state.scroll_views.help,
    );
}

#[cfg(test)]
mod tests {
    use super::*;
    use ratatui::{Terminal, backend::TestBackend};

    fn render_status_buffer(state: MissionControlState) -> ratatui::buffer::Buffer {
        let backend = TestBackend::new(100, 1);
        let mut terminal = Terminal::new(backend).unwrap();
        terminal
            .draw(|frame| draw_status(frame, Rect::new(0, 0, 100, 1), &state))
            .unwrap();
        terminal.backend().buffer().clone()
    }

    fn render_status_text(state: MissionControlState) -> String {
        render_status_buffer(state)
            .content()
            .iter()
            .map(|cell| cell.symbol())
            .collect()
    }

    #[test]
    fn footer_left_shows_cwd_and_branch_without_session_or_provider() {
        let mut state = MissionControlState {
            provider: crate::providers::OPENAI_CODEX_PROVIDER.to_string(),
            model: "gpt-5".to_string(),
            footer_session: "session".to_string(),
            footer_cwd: "/repo".to_string(),
            footer_git_branch: Some("main".to_string()),
            ..Default::default()
        };
        state.refresh_thinking_levels(
            crate::thinking::ThinkingLevel::Medium,
            crate::thinking::ThinkingLevel::EFFORT_GENERIC.to_vec(),
        );
        assert_eq!(footer_left_text(&state), "📂Cwd: /repo • 🪾Branch: main");
        let text = render_status_text(state);
        assert!(text.contains("📂 Cwd: /repo • 🪾 Branch: main"), "{text}");
        assert!(!text.contains("Sess:"), "{text}");
        assert!(!text.contains("Model:"), "{text}");
        assert!(!text.contains("openai-codex/gpt-5"), "{text}");
        assert!(!text.contains("Thinking:"), "{text}");
    }

    #[test]
    fn footer_left_omits_empty_branch() {
        let state = MissionControlState {
            footer_cwd: "/repo".to_string(),
            ..Default::default()
        };
        assert_eq!(footer_left_text(&state), "📂Cwd: /repo");
        let text = render_status_text(state);
        assert!(text.contains("📂 Cwd: /repo"), "{text}");
        assert!(!text.contains("🪾 Branch:"), "{text}");
    }

    #[test]
    fn footer_right_shows_version_without_update() {
        assert_eq!(
            footer_right_text(&MissionControlState::default()),
            format!("🤘MAGI-CODE v{}🤘", env!("CARGO_PKG_VERSION"))
        );
        let text = render_status_text(MissionControlState::default());
        assert!(
            text.contains(&format!("🤘 MAGI-CODE v{}🤘", env!("CARGO_PKG_VERSION"))),
            "{text}"
        );
        assert!(!text.contains("[F1] help"), "{text}");
    }

    #[test]
    fn footer_right_includes_perf_text_only_after_snapshot_exists() {
        let state = MissionControlState {
            #[cfg(any(test, debug_assertions))]
            perf: crate::tui::perf::TuiPerfCounters::with_enabled(true),
            ..Default::default()
        };
        assert!(!footer_right_text(&state).contains("perf drain"));

        #[cfg(any(test, debug_assertions))]
        {
            state.perf.record_drain_us(400);
            state.perf.increment_projected_cards();
            state.perf.set_backlog_before_drain(3);
            state.perf.set_backlog_after_drain(2);
            state.perf.set_backlog_before_draw(1);
            state.perf.record_draw_us(2100);
        }
        let text = footer_right_text(&state);
        assert!(text.contains("perf drain 0.4/0.4ms draw 2.1/2.1ms cards 1 backlog 3/2/1"));
        assert!(text.contains("MAGI-CODE v"));
    }
}