magi-code 0.96.1

Repository-aware CLI coding agent for terminal work
Documentation
use std::{
    collections::HashSet,
    path::{Path, PathBuf},
};
const AGENTS_FILE_NAME: &str = "AGENTS.md";
const MAX_SUBDIR_AGENTS_BYTES: u64 = 256 * 1024;

#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct DiscoveredInstruction {
    pub path: PathBuf,
    pub content: String,
    pub bytes: usize,
}

pub(crate) fn discover_subdir_instructions(
    touched_path: &Path,
    root_canonical: &Path,
    already_loaded: &HashSet<PathBuf>,
) -> (Vec<DiscoveredInstruction>, Vec<String>) {
    discover_subdir_instructions_with_diagnostics(touched_path, root_canonical, already_loaded)
}

fn discover_subdir_instructions_with_diagnostics(
    touched_path: &Path,
    root_canonical: &Path,
    already_loaded: &HashSet<PathBuf>,
) -> (Vec<DiscoveredInstruction>, Vec<String>) {
    let mut diagnostics = Vec::new();
    let root = match root_canonical.canonicalize() {
        Ok(root) => root,
        Err(error) => {
            diagnostics.push(format!("failed to canonicalize root: {error}"));
            return (Vec::new(), diagnostics);
        }
    };

    let touched = match touched_path.canonicalize() {
        Ok(touched) => touched,
        Err(error) => {
            diagnostics.push(format!("failed to canonicalize touched path: {error}"));
            return (Vec::new(), diagnostics);
        }
    };
    if !touched.starts_with(&root) {
        return (Vec::new(), diagnostics);
    }

    let mut cursor = if touched.is_dir() {
        touched
    } else {
        touched.parent().unwrap_or(&touched).to_path_buf()
    };
    let mut discovered = Vec::new();
    let mut seen = HashSet::new();

    while cursor.starts_with(&root) && cursor != root {
        let candidate = cursor.join(AGENTS_FILE_NAME);
        if candidate.exists() {
            match candidate.canonicalize() {
                Ok(canonical) => {
                    if canonical.starts_with(&root)
                        && !already_loaded.contains(&canonical)
                        && seen.insert(canonical.clone())
                    {
                        match load_candidate(&canonical) {
                            Ok(instruction) => discovered.push(instruction),
                            Err(message) => {
                                diagnostics.push(format!("{}: {message}", canonical.display()))
                            }
                        }
                    }
                }
                Err(error) => diagnostics.push(format!(
                    "{}: failed to canonicalize candidate: {error}",
                    candidate.display()
                )),
            }
        }

        let Some(parent) = cursor.parent() else {
            break;
        };
        cursor = parent.to_path_buf();
    }

    (discovered, diagnostics)
}

fn load_candidate(path: &Path) -> Result<DiscoveredInstruction, String> {
    let file = crate::prompt_file::read_prompt_file(path, MAX_SUBDIR_AGENTS_BYTES, false)
        .map_err(|error| error.to_string())?;
    Ok(DiscoveredInstruction {
        path: path.to_path_buf(),
        content: file.text,
        bytes: file.bytes,
    })
}