use std::path::{Path, PathBuf};
const RULES_FILES: &[&str] = &["AGENT.md", "RULES.md", "rules.md"];
const RULES_DIR: &str = ".echo-agent";
pub fn load_project_rules(working_dir: &Path) -> Option<(PathBuf, String)> {
let canonical = working_dir
.canonicalize()
.unwrap_or_else(|_| working_dir.to_path_buf());
for ancestor in canonical.ancestors() {
let rules_dir = ancestor.join(RULES_DIR);
if !rules_dir.is_dir() {
continue;
}
for filename in RULES_FILES {
let rules_file = rules_dir.join(filename);
match std::fs::read_to_string(&rules_file) {
Ok(content) if !content.trim().is_empty() => {
return Some((rules_file, content));
}
_ => continue,
}
}
}
None
}
pub fn rules_injection(working_dir: &Path) -> Option<String> {
let (path, content) = load_project_rules(working_dir)?;
let path_display = path.display();
Some(format!(
"<!-- PROJECT RULES: {} -->\n{}\n<!-- END PROJECT RULES -->",
path_display, content
))
}
pub fn inject_rules(existing_prompt: &str, working_dir: &Path) -> String {
match rules_injection(working_dir) {
Some(rules) => format!("{}\n\n{}", rules, existing_prompt),
None => existing_prompt.to_string(),
}
}