magi-code 0.63.4

Repository-aware CLI coding agent for terminal work
Documentation
use crate::tui::state;

#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct PersistedPrimaryAgentResolution {
    pub(crate) selected_id: Option<String>,
    pub(crate) diagnostics: Vec<crate::primary_agents::PrimaryAgentProfileDiagnostic>,
}

pub(crate) fn resolve_persisted_primary_agent_selection(
    selected_id: Option<&str>,
    profiles: &std::collections::BTreeMap<String, crate::primary_agents::PrimaryAgentProfile>,
) -> PersistedPrimaryAgentResolution {
    let Some(selected_id) = selected_id else {
        return PersistedPrimaryAgentResolution {
            selected_id: None,
            diagnostics: Vec::new(),
        };
    };
    match crate::primary_agents::validate_primary_agent_id(selected_id) {
        Ok(id) if profiles.contains_key(&id) => PersistedPrimaryAgentResolution {
            selected_id: Some(id),
            diagnostics: Vec::new(),
        },
        Ok(id) => PersistedPrimaryAgentResolution {
            selected_id: None,
            diagnostics: vec![crate::primary_agents::PrimaryAgentProfileDiagnostic {
                id: Some(id),
                path: None,
                message: "stored primary agent selection is unavailable; using None".to_string(),
            }],
        },
        Err(error) => PersistedPrimaryAgentResolution {
            selected_id: None,
            diagnostics: vec![crate::primary_agents::PrimaryAgentProfileDiagnostic {
                id: Some(sanitized_primary_agent_diagnostic_text(selected_id)),
                path: None,
                message: format!("stored primary agent selection is invalid; using None: {error}"),
            }],
        },
    }
}

pub(crate) fn record_primary_agent_startup_diagnostics(
    state: &mut state::MissionControlState,
    diagnostics: &[crate::primary_agents::PrimaryAgentProfileDiagnostic],
) {
    if diagnostics.is_empty() {
        return;
    }
    let summary = format!(
        "{} primary agent profile diagnostic(s); invalid profiles skipped",
        diagnostics.len()
    );
    state.status = summary.clone();
    state.record_error_transcript(&summary);
    for diagnostic in diagnostics.iter().take(5) {
        state.record_error_transcript(&format!(
            "primary agent profile skipped: profile={} reason={}",
            sanitized_primary_agent_diagnostic_label(diagnostic),
            sanitized_primary_agent_diagnostic_text(&diagnostic.message)
        ));
    }
    if diagnostics.len() > 5 {
        state.record_error_transcript(&format!(
            "{} additional primary agent profile diagnostic(s) omitted",
            diagnostics.len() - 5
        ));
    }
}

fn sanitized_primary_agent_diagnostic_label(
    diagnostic: &crate::primary_agents::PrimaryAgentProfileDiagnostic,
) -> String {
    let label = diagnostic
        .path
        .as_ref()
        .and_then(|path| path.file_name())
        .and_then(|name| name.to_str())
        .or(diagnostic.id.as_deref())
        .unwrap_or("<unknown>");
    sanitized_primary_agent_diagnostic_text(label)
}

fn sanitized_primary_agent_diagnostic_text(text: &str) -> String {
    let one_line = text.split_whitespace().collect::<Vec<_>>().join(" ");
    let lower = one_line.to_ascii_lowercase();
    let looks_secret = lower.contains("secret")
        || lower.contains("token")
        || lower.contains("password")
        || lower.contains("apikey")
        || lower.contains("api_key")
        || lower.contains("openai")
        || one_line.starts_with("sk-");
    if looks_secret {
        "<redacted>".to_string()
    } else if one_line.chars().count() > 160 {
        format!("{}…", one_line.chars().take(160).collect::<String>())
    } else {
        one_line
    }
}

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

    fn profile(id: &str, name: &str, prompt: &str) -> crate::primary_agents::PrimaryAgentProfile {
        crate::primary_agents::PrimaryAgentProfile {
            id: id.to_string(),
            name: name.to_string(),
            description: String::new(),
            path: PathBuf::from(format!("{id}.md")),
            prompt: prompt.to_string(),
        }
    }

    #[test]
    fn primary_agent_startup_diagnostics_include_sanitized_actionable_details() {
        let mut state = state::MissionControlState::default();
        let diagnostics = vec![crate::primary_agents::PrimaryAgentProfileDiagnostic {
            id: Some("bad".to_string()),
            path: Some(PathBuf::from("bad.md")),
            message:
                "skipping primary agent profile: frontmatter field 'name' must be a YAML string"
                    .to_string(),
        }];

        record_primary_agent_startup_diagnostics(&mut state, &diagnostics);

        let transcript = state.transcript_visual_text();
        assert_eq!(
            state.status,
            "1 primary agent profile diagnostic(s); invalid profiles skipped"
        );
        assert!(transcript.contains("profile=bad.md"), "{transcript}");
        assert!(
            transcript.contains("frontmatter field 'name' must be a YAML string"),
            "{transcript}"
        );
    }

    #[test]
    fn primary_agent_startup_diagnostics_redact_secret_like_details() {
        let mut state = state::MissionControlState::default();
        let diagnostics = vec![crate::primary_agents::PrimaryAgentProfileDiagnostic {
            id: Some("OPENAI_TOKEN".to_string()),
            path: Some(PathBuf::from("sk-secret.md")),
            message: "sk-secret body text must not leak".to_string(),
        }];

        record_primary_agent_startup_diagnostics(&mut state, &diagnostics);

        let transcript = state.transcript_visual_text();
        assert!(transcript.contains("profile=<redacted>"), "{transcript}");
        assert!(transcript.contains("reason=<redacted>"), "{transcript}");
        assert!(!transcript.contains("sk-secret"), "{transcript}");
        assert!(!transcript.contains("body text"), "{transcript}");
    }

    #[test]
    fn persisted_primary_agent_resolution_accepts_absent_and_valid_ids() {
        let mut profiles = std::collections::BTreeMap::new();
        profiles.insert("tars".to_string(), profile("tars", "TARS", "body"));

        let absent = resolve_persisted_primary_agent_selection(None, &profiles);
        assert_eq!(absent.selected_id, None);
        assert!(absent.diagnostics.is_empty());

        let valid = resolve_persisted_primary_agent_selection(Some("tars"), &profiles);
        assert_eq!(valid.selected_id.as_deref(), Some("tars"));
        assert!(valid.diagnostics.is_empty());
    }

    #[test]
    fn persisted_primary_agent_resolution_warns_for_malformed_or_unknown_ids() {
        let profiles = std::collections::BTreeMap::new();

        let malformed = resolve_persisted_primary_agent_selection(Some("bad/token"), &profiles);
        assert_eq!(malformed.selected_id, None);
        assert_eq!(malformed.diagnostics.len(), 1);
        assert!(malformed.diagnostics[0].message.contains("invalid"));
        assert!(!malformed.diagnostics[0].message.contains("prompt body"));

        let unknown = resolve_persisted_primary_agent_selection(Some("missing"), &profiles);
        assert_eq!(unknown.selected_id, None);
        assert_eq!(unknown.diagnostics.len(), 1);
        assert!(unknown.diagnostics[0].message.contains("unavailable"));
    }
}