pub mod coverage;
pub mod enrich;
pub mod evidence;
pub mod relations;
pub mod resolve;
#[cfg(test)]
mod e2e_tests;
pub use enrich::{Escalation, EscalationBudget, EscalationStats, SemanticVerdict, escalate_calls};
pub use evidence::{EdgeEvidence, EvidenceGrade, EvidenceOrigin};
use crate::core::config::SemanticMode;
use crate::core::property_graph::{CodeGraph, EdgeKind};
pub fn status_line(graph: &CodeGraph, mode: SemanticMode, project_root: &str) -> String {
let mode = match mode {
SemanticMode::Off => "off",
SemanticMode::Auto => "auto",
SemanticMode::Eager => "eager",
};
let coverage = coverage::coverage_by_language(graph);
let mut all = coverage::GradeCounts::default();
for c in coverage.values() {
all.verified += c.verified;
all.resolved += c.resolved;
all.heuristic += c.heuristic;
all.unannotated += c.unannotated;
}
let count = |kind: EdgeKind| graph.file_edges_of_kind(&kind).map_or(0, |e| e.len());
let (implements, extends, references) = (
count(EdgeKind::Implements),
count(EdgeKind::Extends),
count(EdgeKind::References),
);
let extra = if all.unannotated > 0 {
format!(" · {} unannotated", all.unannotated)
} else {
String::new()
};
let mut out = format!(
"Semantic: mode={mode} | calls {} verified · {} resolved · {} heuristic{extra} | implements {implements} · extends {extends} · references {references}",
all.verified, all.resolved, all.heuristic
);
for line in coverage::coverage_lines(&coverage, project_root) {
out.push('\n');
out.push_str(&line);
}
out
}