weavatrix 1.3.0

Native MCP server for Weavatrix repository intelligence: 42 read-only evidence, impact, architecture, API, Git, search, semantic, and memory operations
use super::RepositorySession;
use crate::mcp::ports::{ChangeMonitor, ChangeMonitorFactory, RepositoryPort};
use blazingly_json::{Value, json};
use std::io;
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};

#[derive(Default)]
struct RepositoryCounts {
    refreshes: usize,
    calls: usize,
}

struct CountingRepository {
    root: PathBuf,
    counts: Arc<Mutex<RepositoryCounts>>,
}

impl RepositoryPort for CountingRepository {
    fn root(&self) -> &Path {
        &self.root
    }

    fn is_loaded(&self) -> bool {
        true
    }

    fn ensure_loaded(&mut self) -> Result<(), String> {
        Ok(())
    }

    fn refresh_if_stale(&mut self) -> Result<bool, String> {
        self.counts.lock().unwrap().refreshes += 1;
        Ok(false)
    }

    fn call(&mut self, _name: &str, _arguments: Value) -> Result<Value, String> {
        self.counts.lock().unwrap().calls += 1;
        Ok(json!({"status": "COMPLETE"}))
    }
}

struct QuietMonitor;

impl ChangeMonitor for QuietMonitor {
    fn changed(&self) -> io::Result<bool> {
        Ok(false)
    }
}

struct QuietMonitorFactory;

impl ChangeMonitorFactory for QuietMonitorFactory {
    fn create(&self, _root: &Path) -> io::Result<Box<dyn ChangeMonitor>> {
        Ok(Box::new(QuietMonitor))
    }
}

#[test]
fn quiet_watcher_never_suppresses_the_repository_revision_check() {
    let counts = Arc::new(Mutex::new(RepositoryCounts::default()));
    let repository = CountingRepository {
        root: PathBuf::from("fixture"),
        counts: Arc::clone(&counts),
    };
    let mut session = RepositorySession::new(Box::new(repository), Arc::new(QuietMonitorFactory));

    for _ in 0..3 {
        session.call("graph_stats", json!({})).unwrap();
    }

    let counts = counts.lock().unwrap();
    assert_eq!(counts.calls, 3);
    assert_eq!(
        counts.refreshes, 3,
        "every tool call must check the repository revision even without watcher events"
    );
}