magi-code 0.97.5

Repository-aware CLI coding agent for terminal work
Documentation
mod ast_grep;
mod bash;
pub(super) mod common;
mod find;
mod grep;
mod hash_edit;
mod list_files;
mod magi_control;
mod read;
mod view_image;
mod web;
mod write;
use super::*;
use common::*;
use grep::{grep_bool, grep_usize};

pub(super) fn project_tool_card(input: &ToolCardInput<'_>) -> CardDraft {
    let capability = ToolCapability::from_dispatch_name(input.tool_name);
    let mut card = match capability {
        Some(ToolCapability::ViewImage) => view_image::view_image_card(input),
        Some(ToolCapability::Write) => write::write_card(input),
        Some(ToolCapability::HashEdit) => hash_edit::hash_edit_card(input),
        Some(ToolCapability::Read) => read::read_card(input),
        Some(ToolCapability::Bash) if !input.bash_mode_response => bash::bash_card(input),
        Some(ToolCapability::AstGrep) => ast_grep::ast_grep_card(input),
        Some(ToolCapability::Grep) => grep::grep_card(input),
        Some(ToolCapability::ListFiles) => list_files::list_files_card(input),
        Some(ToolCapability::Find) => find::find_card(input),
        Some(ToolCapability::Web) => web::web_card(input),
        Some(ToolCapability::MagiControl) => magi_control::magi_control_card(input),
        None if input.tool_name == crate::code_mode::TOOL_NAME => {
            super::code_mode::project_code_mode_card(input)
        }
        _ => generic_tool_card(input),
    };
    if (capability.is_some() || input.tool_name == crate::code_mode::TOOL_NAME)
        && let Some(metadata) = prompt_injection_protection_metadata(input.detail)
    {
        card.metadata.push(metadata);
    }
    card
}

fn basic_card(role: ToolCardRole, title: impl Into<String>, body: &str) -> CardDraft {
    CardDraft {
        role,
        title: title.into(),
        status: CardStatus::None,
        metadata: Vec::new(),
        body: sanitize_display_text(body),
        body_lines: Vec::new(),
        activity_rows: Vec::new(),
    }
}

fn generic_tool_card(input: &ToolCardInput<'_>) -> CardDraft {
    let role =
        if ToolCapability::from_dispatch_name(input.tool_name) == Some(ToolCapability::Subagents) {
            ToolCardRole::SubagentBatch
        } else {
            ToolCardRole::Tool
        };
    let title = if input.bash_mode_response {
        "Bash Mode Response"
    } else if input.tool_name.trim().is_empty() {
        "Tool"
    } else {
        input.tool_name
    };
    // Generic sanitization cannot make arbitrary MCP metadata/output a public schema.
    let body = if input.bash_mode_response {
        bounded_preview_lines(input.preview)
    } else if role == ToolCardRole::Tool {
        "Detail unavailable for this tool".into()
    } else {
        String::new()
    };
    let mut card = basic_card(role, sanitized_single_line(title), &body);
    card.status = input_status(input);
    card
}