8 min read
Vibe Coded a `watch` Command for Autonomous LLMs, and It Became My Debugging Loop

GitHub: github.com/srijanshukla18/vigil

Most file watching tools are good enough until you have an LLM changing your codebase for you. Then the gap becomes obvious very quickly. You do not just want to know that a file changed. You want to know what changed, where it changed, and whether the agent is doing something sensible without constantly flipping back to your editor or git diff.

That was the real reason I built Vigil. I had LLMs working autonomously, and I wanted a live way to see the codebase breathe while they were making changes. Not after the fact. Not one commit later. While it was happening.

The obvious thought was: this must already exist. Something like watch ., but for directories. Recursive file events, inline diffs, and a terminal UI that stays pinned to the stream. Clear the screen when you want. Follow new events when you want. Scroll back when something interesting happens.

It did not exist in the shape I wanted. So I vibe coded it.

The short version is this: the individual building blocks already existed, but no single tool combined file events, diffs, and a usable TUI into one command. Once I saw that clearly, the project got much smaller. I was not inventing a new category. I was just stitching together the thing that should already have been there.

Let’s get into it.

The Existing Tools Were Close, Not Correct

The problem was not a total lack of tools. The problem was that each tool solved only one slice of the workflow.

The landscape looked roughly like this:

  • fswatch -r . gives you file events
  • entr gives you file-triggered execution
  • watch reruns a command on an interval
  • viddy gives you a nicer watch-style TUI
  • lazygit gives you git-aware diffs
  • watchman gives you strong file event plumbing

That sounds fine until you ask a slightly different question:

What if I want to stand in one directory and see all file-level and directory-level changes, plus inline diffs, in one terminal UI, without requiring git?

That is where the tools stop lining up.

The closest workaround looked like this:

fswatch -r . | xargs -I{} sh -c 'echo "--- {} ---" && git diff {}'

That is clever. It is also janky.

It assumes git. It is not a TUI. It is not pleasant to leave running. And it is not built for the specific workflow of watching an autonomous coding agent continuously mutate a working tree.

That framing matters. I was not trying to build a general-purpose file event daemon. I was trying to build an operator console for code changes.

Why This Problem Shows Up Once Agents Get Real

If you are editing code manually, your editor already gives you most of what you need.

  • you know what file you touched
  • you know what line you changed
  • you know why you changed it
  • diffs are local in your head

Once an agent is driving, that changes.

Now the questions are different:

  • what files is it touching right now?
  • is it thrashing across the tree or working cleanly?
  • did it just create a useful file or dump scaffolding everywhere?
  • is this a tiny patch or a cascading rewrite?
  • should I interrupt it?

That one decision explains most of Vigil’s shape. It is not just a filesystem watcher. It is a visibility tool for agentic development.

The UX I Wanted

The target interaction was simple:

vigil .

And from there:

  • recursive directory watch
  • stream events live
  • show inline diffs when files change
  • support create, modify, and delete events
  • stay in follow mode by default
  • let me clear the stream and just watch fresh changes
  • avoid flooding on save storms
  • ignore obvious junk by default

That is the whole product.

No browser. No daemon dashboard. No git dependency. No extra service. Just a terminal UI that tells me what changed.

What Vigil Actually Does

At a high level, Vigil combines three things:

  1. filesystem events
  2. text diffs
  3. terminal UI

The implementation is small because the boundaries are small.

  • notify handles cross-platform filesystem events
  • similar handles text diffing
  • ratatui handles the UI
  • crossterm handles terminal interaction
  • clap handles CLI parsing

That boundary is doing most of the work. I did not need a fancy backend. I needed a good event loop and sane defaults.

The current behavior is straightforward:

  • watch the current directory or a provided path
  • optionally filter by extension
  • optionally ignore paths by substring
  • show file events in a scrollable stream
  • show inline diffs for text files
  • skip binary files
  • skip very large files
  • debounce rapid event bursts
  • auto-follow new events until the user scrolls up

The keybindings are intentionally boring:

  • q quits
  • c clears the event stream
  • d toggles inline diffs
  • j / k scroll
  • G jumps to the bottom
  • g jumps to the top

That is exactly the kind of tool I want while an agent is editing code. I do not want to learn a product. I want a pane of visibility.

The Defaults Matter More Than The UI

The most important part of a watcher like this is not the box drawing. It is the policy.

Vigil ignores noisy directories by default:

  • .git
  • node_modules
  • target
  • __pycache__
  • .DS_Store

It also debounces event storms and caches baselines so the first time it sees a file it establishes a reference point, and the next time it can show a real diff instead of pretending every file was always under observation.

That one decision does a lot of work.

Without baseline caching, the tool becomes noisy. Without debounce, editor saves become spam. Without ignore rules, the stream becomes unreadable the moment you open a JavaScript or Rust project.

The TUI is the visible part. The defaults are what make it usable.

Why I Did Not Just Make This Git-Only

It would have been easier to say:

  • require git
  • shell out to git diff
  • call it done

But that would have been the wrong tool.

The whole point was to watch a directory, not a repository.

Sometimes the code is not committed yet. Sometimes the agent is generating files before they ever become part of git history. Sometimes you want to point the tool at a scratch workspace, a generated output directory, or a temp project.

Git is a great history system. It is not the right primitive for every live visibility problem.

What I Learned Building It

I learned two things.

First, the tool gap was real. This was not me failing to search properly. The workflow really was split across too many half-solutions.

Second, this kind of project becomes much easier once you stop trying to make it broader than it needs to be. Vigil does not need to be an IDE. It does not need collaboration features. It does not need remote streaming. It just needs to answer one question well:

What is changing in this directory right now?

That is enough.

Why This Tool Exists

The README says it plainly: watch your codebase breathe.

That is exactly the right description.

Once agents are doing real work, live change visibility stops being a nice-to-have. It becomes part of how you trust the system. You do not want to inspect every edit manually, but you also do not want the agent operating in the dark.

Vigil sits in that middle layer.

  • not intervention
  • not full review
  • just awareness

That is the job.

The Rule I Would Use Again

If I had to compress the whole project into one line, it would be this:

Once code changes become autonomous, observability for local file mutation becomes its own product surface.

watch was built for rerunning commands. kubectl -w was built for streaming resource state. Vigil was built for watching an active codebase while something else is driving.

That distinction is the whole point.