use crate::config::StoreConfig;
use crate::git_store::GitStore;
use crate::manifest::Manifest;
use crate::observability::CliOutput;
use crate::store::Store;
use crate::types::DocType;
use anyhow::Result;
use std::path::{Path, PathBuf};
pub fn run(store_root: &Path, output: &dyn CliOutput) -> Result<()> {
let (git, mut manifest) = match Store::open(store_root) {
Ok(store) => (store.git, store.manifest),
Err(_) => {
let git = GitStore::open(store_root)?;
let config = StoreConfig::load(store_root)?;
let manifest = Manifest::create_empty(config.store, store_root)?;
(git, manifest)
}
};
let head = git.head_md_files()?;
let mut added = 0;
let mut removed = 0;
for path in &head {
let rel = path.strip_prefix(store_root).unwrap_or(path);
if !manifest.is_tracked(rel) {
manifest.register(rel, DocType::Scratch, "")?;
added += 1;
}
}
let stale: Vec<PathBuf> = manifest
.documents()
.iter()
.filter(|d| !store_root.join(&d.path).exists())
.map(|d| d.path.clone())
.collect();
for path in &stale {
let _ = manifest.untrack(path);
removed += 1;
}
manifest.save(store_root)?;
output.line(&format!(
"Repair complete: {} added, {} removed. {} documents tracked.",
added,
removed,
manifest.len()
))?;
Ok(())
}