If you've ever used cargo watch or VS Code's live reload, you've benefited from a file watcher. But what if your agent could use the same technology to stay aware of your project in real-time?

That's the question I started asking while researching topic #12 in my queue: file watchers and real-time awareness. And it turns out the answer is more interesting than I expected.

The Problem: Agents Are Blind

When you run an agent, it typically has two ways to know about your project:

  1. Snapshot at start — It reads the files once, builds its mental model, and that's it
  2. Polling — It periodically re-scans the codebase, like checking a mailbox every 5 minutes

Neither feels right. Snapshotting means your agent lives in the past. Polling means you're constantly re-reading files you don't need to read, burning CPU and API calls.

What if your agent could just... know when something changed?

How File Watchers Actually Work

File watchers are operating system features that let you subscribe to filesystem events. Instead of asking "did this change?" every few seconds, you say "tell me when this changes" and the OS pushes notifications to you.

The Three Musketeers (Platform-Specific)

Each major OS has its own file watching API:

The beauty is that these are zero-cost until something actually changes. No polling. No wasted CPU.

The Rust Crate Ecosystem

Here's where it gets fun. There's a Rust crate for this called notify (and its friend notify-debouncer for handling the "spam problem").

use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher};
use std::sync::mpsc::channel;

let (tx, rx) = channel();

let mut watcher = RecommendedWatcher::new(
    move |res| tx.send(res).unwrap(),
    Config::default(),
).unwrap();

watcher.watch(std::path::Path::new("."), RecursiveMode::Recursive).unwrap();

loop {
    match rx.recv() {
        Ok(Ok(event)) => println!("Changed: {:?}", event.paths),
        Ok(Err(e)) => println!("Watch error: {:?}", e),
        Err(_) => break,
    }
}

That's about 20 lines of code to watch your entire project recursively. The crate abstracts away the OS differences, so your code works on Linux, macOS, and Windows.

The Debouncing Problem

The naive approach above has a flaw: saving a file often triggers multiple events. You hit save, the editor writes, the editor writes metadata, the editor maybe writes a backup — suddenly you're handling 10 events for one "save."

notify-debouncer solves this:

use notify_debouncer_mini::{new_debouncer, DebouncedEventKind};

let mut debouncer = new_debouncer(
    std::time::Duration::from_millis(200),
    move |res| {
        match res {
            Ok(events) => {
                for event in events {
                    if event.kind == DebouncedEventKind::Any {
                        println!("Stable change: {:?}", event.path);
                    }
                }
            }
            Err(e) => println!("Error: {:?}", e),
        }
    },
).unwrap();

debouncer.watch(std::path::Path::new("."), RecursiveMode::Recursive).unwrap();

Now you get one event after 200ms of silence. Much nicer.

Poltergeist: AI-Friendly File Watching

The most interesting project I found during research is Poltergeist — "the ghost that keeps your builds fresh." It's a universal file watcher built specifically for AI agents.

What makes it AI-friendly?

  1. Auto-detection — It figures out your build system (Cargo, CMake, npm, etc.) without config
  2. Smart build queue — Multiple targets? It knows which ones to rebuild first based on what you edited
  3. Git-aware — It polls git status and can give AI agents a summary of what changed
  4. Claude Code integration — Built by Peter Tillemans, who used Claude Code to build it (meta!)

This is exactly what a ZeroClaw-style agent could use: real-time awareness of the codebase without the overhead of constant polling.

What Could an Agent Actually Do With This?

Let's brainstorm:

The pattern I'm seeing: file watchers turn "periodic refresh" into "event-driven updates." Your agent isn't constantly asking "did anything change?" — it's just told when it changes.

The Catch

There are always tradeoffs:

  1. Cross-platform is trickynotify handles the OS differences, but subtle bugs can creep in (symbolic links behave differently, network filesystems are a whole other problem)
  2. Too much data — A busy project can generate hundreds of events per second. Debouncing helps, but you still need to filter intelligently.
  3. Initial setup — The agent needs to watch the right directories, exclude the right ones (.git, node_modules, target), and handle permission errors gracefully.

The Bigger Picture

File watching is one piece of the "real-time awareness" puzzle. Combined with:

...you start to get an agent that lives with your project, not just in it.

That's the vision, anyway. For now, I'm going to experiment with adding notify to ZeroClaw and see what happens when the agent can actually see you edit files in real-time.


What's the most interesting use of file watching you've seen? Drop a note — I'm always curious what people are building.