use std::fs;
use std::path::Path;
use memnite_core::Scope;
use crate::error::IngestError;
use crate::parse::split_h2_sections;
use crate::source::{IngestSource, IngestedMemory};
pub struct RepoBrainSource;
impl IngestSource for RepoBrainSource {
fn name(&self) -> &str {
"brain"
}
fn collect(&self, root: &Path) -> Result<Vec<IngestedMemory>, IngestError> {
let mut out = Vec::new();
let ul_path = root.join("UBIQUITOUS_LANGUAGE.md");
if ul_path.exists() {
let content = fs::read_to_string(&ul_path)?;
let sections = split_h2_sections(&content);
if let Some(start) = sections
.iter()
.position(|(h, _)| h.eq_ignore_ascii_case("Terms"))
{
for (heading, body) in sections.into_iter().skip(start + 1) {
out.push(IngestedMemory {
source_key: format!("ubiquitous-language::{heading}"),
title: heading,
body,
mem_type: "term".to_string(),
topic_key: Some("ubiquitous-language".to_string()),
scope: Scope::Repo,
});
}
}
}
for (rel, title, mem_type, topic) in [
(
"docs/wiki/ai/CONTRACTS.md",
"CONTRACTS",
"contract",
"contracts",
),
(
"docs/wiki/ai/CONSTRAINTS.md",
"CONSTRAINTS",
"constraint",
"constraints",
),
] {
let path = root.join(rel);
if path.exists() {
let content = fs::read_to_string(&path)?;
out.push(IngestedMemory {
source_key: topic.to_string(),
title: title.to_string(),
body: content.trim().to_string(),
mem_type: mem_type.to_string(),
topic_key: Some(topic.to_string()),
scope: Scope::Repo,
});
}
}
Ok(out)
}
}