magi-code 0.63.4

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

pub(crate) fn session_picker_visible_rows(terminal_area: ratatui::layout::Rect) -> usize {
    picker_visible_rows(render::sessions_modal_list_area(terminal_area))
}

pub(crate) fn skills_modal_visible_rows(terminal_area: ratatui::layout::Rect) -> usize {
    picker_visible_rows(render::skills_modal_list_area(terminal_area))
}

pub(crate) fn mcp_modal_visible_rows(terminal_area: ratatui::layout::Rect) -> usize {
    picker_visible_rows(render::mcp_modal_list_area(terminal_area))
}

pub(crate) fn tools_modal_visible_rows(terminal_area: ratatui::layout::Rect) -> usize {
    picker_visible_rows(render::tools_modal_list_area(terminal_area))
}

pub(crate) fn subagents_modal_visible_rows(terminal_area: ratatui::layout::Rect) -> usize {
    picker_visible_rows(render::subagents_modal_list_area(terminal_area))
}

pub(crate) fn models_modal_visible_rows(terminal_area: ratatui::layout::Rect) -> usize {
    picker_visible_rows(render::models_modal_list_area(terminal_area))
}

pub(crate) fn model_picker_visible_rows(
    terminal_area: ratatui::layout::Rect,
    has_notice: bool,
) -> usize {
    picker_visible_rows(render::model_picker_list_area(terminal_area, has_notice))
}

pub(crate) fn auth_picker_visible_rows(
    terminal_area: ratatui::layout::Rect,
    has_notice: bool,
) -> usize {
    picker_visible_rows(render::auth_picker_list_area(terminal_area, has_notice))
}

pub(crate) fn codex_refresh_error_message(error: impl std::fmt::Display) -> String {
    let error = error.to_string();
    if error.contains("run /login openai-codex") {
        format!("openai-codex credential refresh failed: {error}")
    } else {
        format!("openai-codex credential refresh failed: {error}; run /login openai-codex")
    }
}

pub(crate) fn next_activity_namespace() -> String {
    let run_id = NEXT_TUI_RUN_ID.fetch_add(1, Ordering::Relaxed);
    format!("run-{run_id}/")
}

pub(crate) fn cached_thinking_levels_for_model(
    paths: &crate::config::McPaths,
    provider: &str,
    model: &str,
    scope: crate::thinking::ThinkingCapabilityScope,
) -> Vec<crate::thinking::ThinkingLevel> {
    let cached = crate::model_catalog::cached_model_thinking_metadata(paths, provider, model);
    crate::thinking::available_thinking_levels(provider, model, cached.as_ref(), scope)
}

pub(crate) fn open_url_in_browser(url: &str) -> anyhow::Result<()> {
    #[cfg(target_os = "macos")]
    let mut command = {
        let mut command = Command::new("open");
        command.arg(url);
        command
    };

    #[cfg(target_os = "windows")]
    let mut command = {
        let mut command = Command::new("rundll32");
        command.args(["url.dll,FileProtocolHandler", url]);
        command
    };

    #[cfg(all(unix, not(target_os = "macos")))]
    let mut command = {
        let mut command = Command::new("xdg-open");
        command.arg(url);
        command
    };

    #[cfg(not(any(unix, target_os = "windows")))]
    {
        let _ = url;
        anyhow::bail!("opening a browser is not supported on this platform");
    }

    #[cfg(any(unix, target_os = "windows"))]
    {
        let mut child = command.spawn()?;
        // fire-and-forget: browser opener waits for detached OS child process so TUI input is not blocked.
        thread::spawn(move || {
            let _ = child.wait();
        });
        Ok(())
    }
}