Skip to main content

ailint_core/
lib.rs

1//! # ailint-core
2//!
3//! Core library for `ailint`: discovers AI agent guidance files, parses them,
4//! runs a configurable set of lint rules, and emits reports in multiple
5//! formats.
6//!
7//! Discovers guidance files via [`discovery`], parses them via [`parser`],
8//! runs rules registered in [`rules::registry`], and emits reports via
9//! [`reporter`].
10
11#![deny(rust_2018_idioms)]
12#![warn(missing_debug_implementations)]
13#![warn(missing_docs)]
14
15pub mod config;
16pub mod discovery;
17pub mod file_type;
18pub mod fix;
19pub mod parser;
20pub mod reporter;
21pub mod rules;
22
23use std::path::{Path, PathBuf};
24
25use anyhow::Result;
26
27pub use crate::config::Config;
28pub use crate::file_type::FileType;
29pub use crate::fix::{apply_all as apply_fixes, FileFixResult, FixConflict};
30pub use crate::reporter::{Reporter, ReporterKind};
31pub use crate::rules::{RuleId, Severity, TextEdit, Violation};
32
33/// A single discovered guidance file and its detected type.
34#[derive(Debug, Clone)]
35pub struct DiscoveredFile {
36    /// Location on disk.
37    pub path: PathBuf,
38    /// Detected guidance file type.
39    pub file_type: FileType,
40}
41
42/// Top-level entry point: discover files under `root`, run enabled rules, and
43/// return the aggregated violations.
44pub fn lint(root: &Path, config: &Config) -> Result<Vec<Violation>> {
45    let files = discovery::walk(root, config)?;
46    tracing::debug!(root = %root.display(), files = files.len(), "ailint::lint");
47    let mut docs = Vec::with_capacity(files.len());
48    for file in files {
49        docs.push(parser::parse(&file.path, file.file_type)?);
50    }
51    let mut violations = Vec::new();
52    for doc in &docs {
53        violations.extend(rules::registry::run_all(doc, config));
54    }
55    violations.extend(rules::registry::run_all_batch(&docs, config));
56    Ok(violations)
57}
58
59/// Version string embedded from Cargo.
60pub const VERSION: &str = env!("CARGO_PKG_VERSION");