WeaveDocs
Agentfs

Watching

Filesystem watching in AgentFS — register watchers per context, batch events, and react to local-first filesystem changes.

Purpose

Local agent filesystem with contexts, registry, permissions, metadata hooks, sync, watchers, and atomic writes.

This page follows the real source shape for Agentfs and explains the workflow a developer is likely to use first.

Developer workflow

Start from the smallest constructor or builder, perform one meaningful operation, inspect the returned state, then add the relevant policy, storage, or network integration. The examples below should be expanded whenever the crate API changes.

Primary types to know

  • AgentContext — local/agentfs/src/agent.rs
  • AgentContext — local/agentfs/src/agent_refactored.rs
  • AgentFS — local/agentfs/src/fs.rs
  • AgentFS — local/agentfs/src/fs_refactored.rs
  • AgentFSConfig — local/agentfs/src/config.rs
  • AgentPermission — local/agentfs/src/permissions.rs
  • AgentPermission — local/agentfs/src/permissions_refactored.rs
  • AgentRegistry — local/agentfs/src/agent.rs
  • AgentRegistry — local/agentfs/src/agent_refactored.rs
  • ConflictInfo — local/agentfs/src/sync_refactored.rs
  • FsckReport — local/agentfs/src/fs.rs
  • FsMetrics — local/agentfs/src/fs.rs

Example shape

use agentfs::{FSWatcher, WatchEvent};
use tokio::time::{timeout, Duration};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // FSWatcher wraps the `notify` crate's recommended watcher and translates
    // raw events into typed WatchEvent values (Created/Modified/Deleted/Renamed).
    let dir = tempfile::tempdir()?;
    let mut watcher = FSWatcher::new(dir.path().to_path_buf())?;

    // Trigger a change inside the watched root so we have at least one event.
    tokio::spawn({
        let path = dir.path().join("touched.txt");
        async move {
            tokio::time::sleep(Duration::from_millis(50)).await;
            let _ = tokio::fs::write(path, b"first write").await;
        }
    });

    // Bounded wait: the OS may coalesce events, so the channel may yield None.
    if let Ok(Some(event)) = timeout(Duration::from_secs(2), watcher.recv()).await {
        match event {
            WatchEvent::Created(p) | WatchEvent::Modified(p) => {
                println!("change observed at {}", p.display());
            }
            other => println!("event: {other:?}"),
        }
    }
    println!("watcher id={} root={}", watcher.id(), watcher.root().display());
    Ok(())
}