No description
Find a file
Pandi f23043c2b4 hermes-trigger: fire a command when a watched file changes
Event-driven counterpart to a cron schedule: watches a file or directory,
debounces the burst, dedupes on content hash and stays silent on empty
writes, then runs the configured argv command. Installed as the user unit
hermes-trigger.service.
2026-11-03 09:12:59 +01:00
src hermes-trigger: fire a command when a watched file changes 2026-11-03 09:12:59 +01:00
tests hermes-trigger: fire a command when a watched file changes 2026-11-03 09:12:59 +01:00
.gitignore hermes-trigger: fire a command when a watched file changes 2026-11-03 09:12:59 +01:00
Cargo.lock hermes-trigger: fire a command when a watched file changes 2026-11-03 09:12:59 +01:00
Cargo.toml hermes-trigger: fire a command when a watched file changes 2026-11-03 09:12:59 +01:00
README.md hermes-trigger: fire a command when a watched file changes 2026-11-03 09:12:59 +01:00

hermes-trigger

Fire a command when a file changes — so a Hermes cron job runs on the event that matters instead of on a clock.

cargo build --release
install -m 755 target/release/hermes-trigger ~/bin/hermes-trigger

Why

A schedule is a guess. hermes cron run <job_id> already queues a job for the next scheduler tick (~60 s); this daemon is the thing that decides when. systemd PathModified= could do the watching too, but not the three guards that make it usable here: debounce, content-hash dedupe, and silence on empty files — and it costs two unit files per watched path.

Usage

hermes-trigger [--config PATH]

Default config: ~/.config/hermes-trigger/config.toml.

[[watch]]
path = "/home/pandi/coding/user-response.md"
command = ["/home/pandi/.local/bin/hermes", "cron", "run", "01f927982bc8"]
debounce_ms = 2000   # quiet time after the last event (default 1500)
min_bytes = 1        # content below this is ignored (default 1)
  • path may be a file or a directory (non-recursive). Files are watched via their parent directory, so atomic save (write temp + rename) is seen.
  • command is an argv array — no shell, no quoting surprises. Use ["/bin/sh", "-c", "..."] when you actually need a shell.
  • Fires once per distinct non-empty content. Writing empty (the agent consuming its input) is silent and resets the memory; the same content written later fires again.
  • On startup the current content is recorded, so a restart never replays it.
  • Logs one line per event to stderr (journald under the unit).

Tests

cargo test — Gate unit tests (dedupe, empty-reset, min_bytes) and two integration tests running the real binary: change → fire, empty write → silent, config without command → exit 2.

Unit

~/.config/systemd/user/hermes-trigger.service, systemctl --user enable --now hermes-trigger.