loc bengaluru, ist | local --:-- srijanshukla18@gmail.com
[post]/tech/vigil-watch-command-for-autonomous-llms

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

/ 5 min read· ai

Once I had LLMs editing code autonomously, I wanted to watch a directory breathe in real time. Existing tools gave me file events or diffs or a TUI, never all three, so I built vigil.

GitHub: github.com/srijanshukla18/vigil

Most file watchers were built for one narrow job.

  • watch: run a command on interval
  • fswatch: emit raw events
  • viddy: provide a TUI-like terminal view
  • lazygit: show git diffs
  • entr: trigger command execution

When an LLM is editing code continuously, you need all three in one place: event stream, inline context, and operator visibility.

I did not want a full IDE overlay. I wanted a reliable terminal pane I could keep open while agents ran.

Why Existing Workflows Felt Wrong

I started with a common shell pattern:

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

It worked in principle, but for long autonomous edits it broke quickly:

  • assumes git history is the only truth
  • floods on noisy saves
  • difficult to follow scroll state
  • no durable “ignore” policy for local noise
  • no explicit follow/pause semantics for long runs

That was my proof this was a product loop problem, and no amount of shell plumbing was going to fix it.

The UX I Wanted

One command, one predictable behavior:

vigil .

Then:

  • recursive watch on a path
  • live event stream with minimal jitter
  • inline diff for text changes
  • create / modify / delete visibility
  • follow stream by default with manual scroll control
  • clear stream without resetting context
  • debounce save bursts and skip large/binary files by default
  • ignore known noisy directories such as .git, node_modules, target, .DS_Store

No daemon. No remote dependency. Just a loop in the terminal.

Under The Hood

I kept the implementation boundaries small:

  • notify for filesystem events across platforms
  • similar for textual diffs
  • ratatui + crossterm for terminal UI behavior
  • clap for concise CLI arguments

No extra services. No backend. No special editor integration.

The behavior on top of that stays simple:

  • watch directory or explicit path
  • optional extension-based filtering
  • optional path-ignore rules
  • baseline initialization on first sight to avoid bogus “full-file diff” noise
  • stream updates with inline patch-like change view
  • automatic follow mode with manual overrides
  • light controls for navigation and stream management

Most command-line watchers behave like glue scripts. I wanted vigil to behave like an operator surface: same job every run, no surprises.

Why Not Git-Only

I could have built a watcher that shells out to git diff always. That would miss a lot of agent behavior:

  • temporary generated output
  • work outside repo boundaries
  • uncommitted scratch files
  • transient folders that are still important signals

When agents are autonomous, some useful work appears before commit. A git-only model delays visibility by definition.

Defaults Matter More Than Fancy UI

The first version that passed personal use did not win on UI polish. It won on policy:

  • baseline cache to avoid fake initial diffs
  • event debounce for “save storm” behavior
  • ignore list for repetitive directories
  • optional diff toggle so you can keep context without overload

Without these, the tool is noise. With these, it holds up in production-like sessions.

Small Interface, Long Utility

I kept keybindings boring:

  • q: quit
  • c: clear stream
  • d: toggle inline diff
  • j/k: scroll
  • g / G: jump top/bottom

Boring keys were a deliberate decision. In a loop where you are monitoring agent execution, cognitive load should be low.

vigil is not meant to replace your editor. It is meant to stay open, be readable, and require almost no training when you come back after stepping away.

I also kept the command surface minimal on purpose: path argument, optional filter flags, and explicit behavior. No maze of modes.

Why I Built It This Way

The reason is simple: in autonomous editing, observability is part of correctness.

You can have great prompts and great models and still misread what is happening if you cannot see changes with confidence.

Where it earns its keep:

  • watching whether an agent is in a tight loop
  • catching accidental broad edits before they become commits
  • validating that generated files land in the expected area
  • deciding whether to pause or let an agent continue

Vigil ended up as a practical middle layer: continuous awareness, short of full intervention, more than full delegation. That level is enough to decide whether to interrupt, let it continue, or reframe the task.

If your agent system touches code in real time, you need a local “change surface” as a first-class tool. watch and kubectl -w are excellent for their domains. Vigil is for active, local code mutation while another actor is driving.

That was the gap I kept feeling. That gap is why I still keep it running.