magi-code 0.96.2

Repository-aware CLI coding agent for terminal work
Documentation
mod json_scan;
mod metadata;
mod sanitize;
mod subagents;
mod summary;
use sanitize::sanitize_read_target;
use sanitize::sanitize_tool_label;
use sanitize::sanitize_tool_params;

use sanitize::sanitize_read_metadata;

use sanitize::sanitize_detail_json;

use sanitize::sanitize_detail_output;

use json_scan::json_string_boundary_map;
use json_scan::parse_json_string_at;
use json_scan::skip_diff_prefixed_value_start;
use json_scan::skip_json_whitespace;
use sanitize::sanitize_read_block_output;

use json_scan::encode_json_string_fragment;
use json_scan::json_value_end;

use subagents::subagents_safe_output;

use metadata::append_metadata_lines;
use subagents::subagent_identity_list;

use metadata::grep_pattern_label;

use summary::append_bash_protection_detail;
pub(crate) use summary::bash_file_tracking_summary;
pub(crate) use summary::bash_protection_summary;
pub(crate) use summary::humanize_protection_summary;
pub(crate) use summary::pending_tool_summary_metadata;
pub(crate) use summary::prompt_injection_protection_summary;
pub(crate) use summary::tool_summary_metadata;

use summary::file_count_label;
use summary::string_arg;
use summary::task_count_label;

use crate::{
    output::{
        ActivityStatus, ToolActivityDetail, ToolStatus, is_credential_like_key,
        redact_sensitive_text, sanitize_display_controls, sanitize_display_text,
    },
    providers::ToolCall,
    subagents::SubagentsOutput,
    tools::{
        ToolCapability, ToolResult,
        contract::{
            REDACTED_METADATA_KEYS, arg_key, display_label as label, metadata_key as meta,
            summary_metadata_label as summary_label,
        },
    },
};
use serde_json::Value;
use std::sync::Arc;
pub(crate) fn tool_activity_detail_pending(
    call: &ToolCall,
    label: impl Into<String>,
    status: ActivityStatus,
) -> ToolActivityDetail {
    let metadata = if is_tool(&call.name, ToolCapability::HashEdit) {
        call.arguments
            .get(arg_key::INPUT)
            .and_then(Value::as_str)
            .map(|input| serde_json::json!({"input_bytes": input.len()}))
            .unwrap_or_else(|| serde_json::json!({}))
    } else {
        serde_json::json!({})
    };
    ToolActivityDetail {
        tool_name: Arc::from(sanitize_display_text(&call.name)),
        label: Arc::from(sanitize_tool_label(call, &label.into())),
        params: sanitize_tool_params(call),
        metadata,
        status,
        output: Arc::from(""),
        applied_diff: None,
    }
}

pub(crate) fn tool_activity_detail(
    call: &ToolCall,
    result: &ToolResult,
    label: impl Into<String>,
    status: ActivityStatus,
) -> ToolActivityDetail {
    let read = is_tool(&call.name, ToolCapability::Read);
    let mut metadata = if read {
        sanitize_read_metadata(&result.metadata)
    } else {
        sanitize_detail_json(&result.metadata)
    };
    if call.name == crate::code_mode::TOOL_NAME {
        // Count the outer provider projection before display sanitization. Nested
        // outputs are not model context unless the script returns them.
        let mut response = crate::protection::prompt_injection::replay_projection(
            &result.content,
            &result.metadata["prompt_injection_protection"],
        )
        .unwrap_or_else(|| result.content.clone());
        crate::code_mode::preserve_execution_evidence(result, &mut response);
        if !metadata.is_object() {
            metadata = serde_json::json!({});
        }
        metadata["code_mode_response_token_estimate"] =
            serde_json::json!(crate::context::estimate_text_tokens(&response));
    }
    ToolActivityDetail {
        tool_name: Arc::from(sanitize_display_text(&call.name)),
        label: Arc::from(sanitize_tool_label(call, &label.into())),
        params: sanitize_tool_params(call),
        metadata,
        status,
        output: Arc::from(if read && !result.success {
            sanitize_read_target(&result.content)
        } else {
            sanitize_detail_output(&result.content)
        }),
        applied_diff: result
            .display
            .edit_diff
            .as_deref()
            .map(sanitize_detail_output)
            .map(Arc::from),
    }
}
pub(crate) fn format_tool_block(call: &ToolCall, result: &ToolResult) -> String {
    format_tool_block_with_options(call, result)
}

fn format_tool_block_with_options(call: &ToolCall, result: &ToolResult) -> String {
    let tool_name = if result.tool_name.is_empty() {
        call.name.as_str()
    } else {
        result.tool_name.as_str()
    };
    let use_subagents_safe_output = is_tool(tool_name, ToolCapability::Subagents);
    let mut lines = Vec::new();
    lines.push(format!(
        "STATUS: {}",
        if result.success { "success" } else { "failure" }
    ));
    append_metadata_lines(&mut lines, call, result);
    if should_display_output(&call.name, result) {
        lines.push("OUTPUT:".to_string());
    }

    let mut block = lines.join("\n");
    block.push('\n');
    if should_display_output(&call.name, result) {
        let display_content = if use_subagents_safe_output {
            subagents_safe_output(result)
        } else if is_tool(tool_name, ToolCapability::Read) {
            sanitize_read_block_output(result)
        } else {
            redact_sensitive_text(&result.content)
        };
        block.push_str(&display_content);
        if !display_content.ends_with('\n') {
            block.push('\n');
        }
    }
    block
}

fn should_display_output(_call_name: &str, result: &ToolResult) -> bool {
    !result.content.is_empty()
}

fn is_tool(name: &str, capability: ToolCapability) -> bool {
    ToolCapability::from_dispatch_name(name) == Some(capability)
}

pub(crate) fn tool_display_label(call: &ToolCall) -> String {
    let label = tool_label(call);
    if ToolCapability::from_dispatch_name(&call.name) == Some(ToolCapability::Read) {
        sanitize_read_target(&label)
    } else {
        redact_sensitive_text(&label)
    }
}

fn tool_label(call: &ToolCall) -> String {
    match ToolCapability::from_dispatch_name(&call.name) {
        Some(ToolCapability::Bash) => string_arg(&call.arguments, arg_key::COMMAND)
            .or_else(|| string_arg(&call.arguments, arg_key::CMD))
            .map(|command| format!("{} {command}", call.name))
            .unwrap_or_else(|| call.name.clone()),
        Some(ToolCapability::HashEdit | ToolCapability::Write) => {
            string_arg(&call.arguments, arg_key::PATH)
                .map(|path| format!("{} {path}", call.name))
                .unwrap_or_else(|| call.name.clone())
        }
        Some(ToolCapability::Read | ToolCapability::ViewImage) => {
            string_arg(&call.arguments, arg_key::PATH)
                .map(|path| format!("{} {path}", call.name))
                .or_else(|| {
                    call.arguments
                        .get(arg_key::PATHS)
                        .and_then(Value::as_array)
                        .map(|paths| format!("{} {}", call.name, file_count_label(paths.len())))
                })
                .unwrap_or_else(|| call.name.clone())
        }
        Some(ToolCapability::Grep) => grep_pattern_label(call),
        Some(ToolCapability::AstGrep) => string_arg(&call.arguments, arg_key::PATTERN)
            .map(|pattern| format!("{} {pattern}", call.name))
            .unwrap_or_else(|| call.name.clone()),
        Some(ToolCapability::Find) => string_arg(&call.arguments, arg_key::QUERY)
            .map(|query| format!("{} {query}", call.name))
            .unwrap_or_else(|| call.name.clone()),
        Some(ToolCapability::ListFiles) => string_arg(&call.arguments, arg_key::PATH)
            .map(|path| format!("{} {path}", call.name))
            .unwrap_or_else(|| call.name.clone()),
        Some(ToolCapability::Subagents) => call
            .arguments
            .get(arg_key::TASKS)
            .and_then(Value::as_array)
            .map(|tasks| format!("subagents ยท {}", task_count_label(tasks.len())))
            .unwrap_or_else(|| call.name.clone()),
        Some(ToolCapability::Web) => string_arg(&call.arguments, arg_key::QUERY)
            .map(|query| format!("{} {query}", call.name))
            .unwrap_or_else(|| call.name.clone()),
        Some(ToolCapability::MagiControl) => string_arg(&call.arguments, arg_key::ACTION)
            .map(|action| format!("{} {action}", call.name))
            .unwrap_or_else(|| call.name.clone()),
        None => call.name.clone(),
    }
}

pub(crate) fn should_show_pending_tool(call: &ToolCall) -> bool {
    matches!(
        ToolCapability::from_dispatch_name(&call.name),
        Some(
            ToolCapability::Write
                | ToolCapability::HashEdit
                | ToolCapability::ViewImage
                | ToolCapability::Find
                | ToolCapability::Web,
        )
    )
}

pub(crate) fn pending_tool_status(call: &ToolCall) -> ToolStatus {
    if matches!(
        ToolCapability::from_dispatch_name(&call.name),
        Some(ToolCapability::Write)
    ) {
        ToolStatus::Writing
    } else {
        ToolStatus::Running
    }
}