magi-code 0.102.1

Repository-aware CLI coding agent for terminal work
Documentation
use serde_json::json;

use super::{
    args::ListFilesArgs,
    contract::{metadata_key as meta, tool_name},
    result::{ToolResult, ToolResultDisplay},
};

const MAX_FILES: usize = 1000;

pub(in crate::tools) struct ListFilesContext<'a> {
    pub(in crate::tools) paths: crate::tools::fs::PathContext<'a>,
    pub(in crate::tools) settings: &'a crate::config::ListFilesToolSettings,
    pub(in crate::tools) fs_cache: &'a super::fs_cache::FsCache,
}

impl ListFilesContext<'_> {
    pub(super) fn list_files(&self, args: ListFilesArgs) -> anyhow::Result<ToolResult> {
        let path = self.paths.resolve_existing_path(
            &args.path,
            super::fs::ExistingPathPolicy::list_files(self.settings.absolute_paths),
        )?;
        if !path.is_dir() {
            anyhow::bail!("list_files path must be a directory");
        }

        let listing = self.fs_cache.read_dir_listing(&path)?;
        let mut entries = Vec::new();
        let mut file_count = 0usize;
        let mut directory_count = 0usize;
        let mut truncated = false;
        for entry in listing.entries.iter() {
            if entry.file_type.is_file() || (args.include_directories && entry.file_type.is_dir()) {
                if entries.len() == MAX_FILES {
                    truncated = true;
                    break;
                }
                if entry.file_type.is_dir() {
                    directory_count += 1;
                } else {
                    file_count += 1;
                }
                entries.push(entry.name.clone());
            }
        }
        entries.sort();

        Ok(ToolResult {
            tool_name: tool_name::LIST_FILES.to_string(),
            success: true,
            content: entries.join("\n"),
            metadata: json!({
                (meta::PATH): args.path,
                (meta::FILES): file_count,
                (meta::DIRECTORIES): directory_count,
                (meta::TRUNCATED): truncated
            }),
            display: ToolResultDisplay::default(),
        })
    }
}