magi-code 0.77.1

Repository-aware CLI coding agent for terminal work
Documentation
use super::{
    overlay_block_with_theme, render_overlay_fill_with_theme,
    render_scroll_view_persistent_with_theme,
};
#[cfg(any(test, debug_assertions))]
use crate::tui::PADDED_INLINE_SEPARATOR;
use crate::tui::{input, state::MissionControlState};
use ratatui::{
    Frame,
    layout::Rect,
    text::{Line, Span},
    widgets::{Clear, Paragraph, Wrap},
};

pub(super) fn branch_text(state: &MissionControlState) -> String {
    state
        .footer_git_branch
        .as_deref()
        .filter(|branch| !branch.is_empty())
        .map(|branch| format!("Branch: {branch}"))
        .unwrap_or_default()
}

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
}

pub(super) fn version_title(state: &MissionControlState) -> Line<'static> {
    Line::from(Span::styled(
        footer_right_text(state),
        state.theme.accent(false),
    ))
}

pub(super) fn draw_help(frame: &mut Frame<'_>, area: Rect, state: &MissionControlState) {
    let theme = state.theme;
    frame.render_widget(Clear, area);
    let block = overlay_block_with_theme(theme, "Help");
    let inner = block.inner(area);
    frame.render_widget(block, area);
    let text_area = render_overlay_fill_with_theme(frame, inner, theme);
    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_with_theme(
        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(theme.panel_alt())
            .wrap(Wrap { trim: false }),
        &state.scroll_views.help,
        theme,
    );
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn branch_header_omits_directory() {
        let state = MissionControlState {
            footer_cwd: "/repo".to_string(),
            footer_git_branch: Some("main".to_string()),
            ..Default::default()
        };
        assert_eq!(branch_text(&state), "Branch: main");
    }

    #[test]
    fn branch_header_is_empty_for_missing_or_empty_branch() {
        for branch in [None, Some(String::new())] {
            let state = MissionControlState {
                footer_cwd: "/repo".to_string(),
                footer_git_branch: branch,
                ..Default::default()
            };
            assert_eq!(branch_text(&state), "");
        }
    }

    #[test]
    fn version_title_uses_accent_and_package_version() {
        let state = MissionControlState::default();
        let title = version_title(&state);
        assert_eq!(
            title.to_string(),
            format!("MAGI-CODE v{}", env!("CARGO_PKG_VERSION"))
        );
        assert_eq!(title.spans[0].style, state.theme.accent(false));
    }

    #[test]
    fn version_title_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!(!version_title(&state).to_string().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);
            state.perf.record_prompt_edit_to_draw_us(17_300);
        }
        let text = version_title(&state).to_string();
        assert!(text.contains("perf drain 0.4/0.4ms draw 2.1/2.1ms cards 1 backlog 3/2/1"));
        assert!(text.contains("edit->draw 17.3ms"));
        assert!(text.contains("MAGI-CODE v"));
    }
}