magi-code 0.98.0

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

#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub(crate) enum PublicProtectionDecision {
    NotReported,
    Allowed,
    ApprovalRequired,
    Blocked,
    Denied,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct PublicProtection {
    pub(crate) decision: PublicProtectionDecision,
    pub(crate) summary: Option<String>,
}

// Fixed public labels only. Never return a source decision string or assessment.
pub(super) fn public_decision(
    detail: Option<&ToolActivityDetail>,
    key: &str,
) -> Option<(PublicProtectionDecision, &'static str)> {
    public_decision_label(detail?.metadata[key]["decision"].as_str()?)
}

pub(crate) fn public_decision_label(
    label: &str,
) -> Option<(PublicProtectionDecision, &'static str)> {
    use PublicProtectionDecision::*;
    Some(match label {
        "allowed" => (Allowed, "allowed"),
        "allowed automatically" => (Allowed, "allowed automatically"),
        "allowed by user" => (Allowed, "allowed by user"),
        "allowed by API failure policy" => (Allowed, "allowed by API failure policy"),
        "denied by API failure policy" => (Denied, "denied by API failure policy"),
        "denied by user" => (Denied, "denied by user"),
        "denied; approval unavailable" => (Denied, "denied; approval unavailable"),
        "denied; needs humanizing" => (Denied, "denied; needs humanizing"),
        "approval required" => (ApprovalRequired, "approval required"),
        "no added prose" => (Allowed, "no added prose"),
        "no comments or documentation" => (Allowed, "no comments or documentation"),
        _ => return None,
    })
}

pub(super) fn public_protection(
    input: &ToolCardInput<'_>,
    summaries: &[String],
) -> PublicProtection {
    use PublicProtectionDecision::*;
    let mut decision = NotReported;
    if ToolCapability::from_dispatch_name(input.tool_name).is_some()
        || input.tool_name == crate::code_mode::TOOL_NAME
    {
        decision = ["bash_protection", "humanize_protection"]
            .into_iter()
            .filter_map(|key| public_decision(input.detail, key))
            .map(|(decision, _)| decision)
            .max()
            .unwrap_or(NotReported);
        if let Some(detail) = input.detail
            && detail.metadata["prompt_injection_protection"]["enforced"].as_bool() == Some(true)
            && detail.metadata["prompt_injection_protection"]["action"].as_str()
                == Some("quarantine")
            && decision != Denied
        {
            decision = Blocked;
        }
    }
    let summary = summaries
        .iter()
        .filter(|line| {
            line.starts_with("Jev: ")
                && !line.starts_with("Jev: file tracking")
                && !line.starts_with("Jev: File tracking")
                && !line.starts_with("Jev: Inferred file activity")
                && !line.ends_with("• not reported")
        })
        .cloned()
        .collect::<Vec<_>>()
        .join(" • ");
    PublicProtection {
        decision,
        summary: (!summary.is_empty()).then_some(summary),
    }
}