with-watch
with-watch reruns a delegated command when its inferred or explicit filesystem inputs change.
It executes the delegated command once immediately after input inference, watcher setup, and baseline capture, then waits for later filesystem changes to trigger reruns.
Why use
- Keep familiar POSIX/coreutils-style commands while adding automatic reruns.
- Let
with-watchinfer watched inputs for common read/write utilities such ascat,cp,sed, andfind. - Fall back to explicit
exec --inputglobs when inference would be ambiguous or when the delegated command has no meaningful filesystem inputs.
Install
Command modes
- Passthrough mode:
with-watch [--no-hash] <utility> [args...] - Shell mode:
with-watch [--no-hash] --shell '<expr>' - Explicit-input mode:
with-watch exec [--no-hash] --input <glob>... -- <command> [args...]
Use passthrough mode for a single delegated command, shell mode for simple command-line expressions that need &&, ||, or |, and exec --input when you want to declare the watched files yourself.
Quick start
Inference Model
- Passthrough and shell modes use built-in command adapters before falling back to conservative path heuristics.
- Known outputs, inline scripts, patterns, and shell output redirects are filtered out of the watch set.
- Pathless defaults are intentionally narrow: only
ls,dir,vdir,du, andfindimplicitly watch the current directory. ls-style commands watch directory listings via metadata snapshots: plainlswatches immediate children,ls -Rstays recursive, andls -dwatches only the named path.exec --inputremains the explicit escape hatch when a delegated command has no meaningful filesystem inputs or when fallback inference would be ambiguous.
Recognized command inventory
with-watch --help lists the full recognized command inventory in the same order as the analyzer.
Wrapper commands:
env,nice,nohup,stdbuf,timeout
Dedicated built-in adapters and aliases:
cp,mv,install,ln,link,rm,unlink,rmdir,shredsort,uniq,split,csplit,teegrep,egrep,fgrep,sedawk,gawk,mawk,nawkfind,xargs,tar,touch,truncatechmod,chown,chgrp,dd
Generic read-path commands:
cat,tac,head,tail,wc,nl,od,cut,fmt,fold,paste,pr,trexpand,unexpand,stat,readlink,realpathmd5sum,b2sum,cksum,sum,sha1sum,sha224sum,sha256sum,sha384sumsha512sum,sha512_224sum,sha512_256sumbase32,base64,basenc,comm,join,cmp,tsort,shuf
Safe current-directory defaults:
find,ls,dir,vdir,du
Recognized but not auto-watchable commands:
echo,printf,seq,yes,sleep,date,uname,pwd,true,falsebasename,dirname,nproc,printenv,whoami,logname,users,hostidnumfmt,mktemp,mkdir,mkfifo,mknod
These commands are recognized, but they do not expose stable filesystem inputs on their own. Use exec --input when you want them to rerun from explicit globs or paths.
When to use exec --input
Use exec --input when the delegated command does not read a stable filesystem input by itself, or when you want the watch set to be explicit.
For example, commands like echo hello are intentionally rejected because there is nothing safe to watch:
with-watch reruns the delegated command exactly as provided. It does not inject changed paths into argv or environment variables.
Shell limitations
--shellis for command-line expressions, not shell scripts.- Supported operators are
&&,||, and|. - Input redirects (
<,<>) are treated as watched inputs. - Output redirects (
>,>>,&>,&>>,>|) are filtered as outputs and are not watched. - Broader shell control-flow remains out of scope for v1.
Rerun behavior
with-watchalways performs one initial run after it has inferred inputs and armed the watcher, even before any external filesystem change occurs.- The default rerun filter compares content hashes, which avoids reruns from metadata churn alone.
ls,dir, andvdiruse metadata-based listing snapshots instead of hashing every file under the watched directory before the first run.--no-hashswitches the filter to metadata-only comparison.- Commands that write excluded outputs such as
cp src.txt dest.txtshould rerun when the source input changes, not when the output file changes. - Commands that mutate watched inputs directly, such as
sed -i.bak -e 's/old/new/' config.txt, refresh their baseline after each run so they do not loop on their own writes. - Path-based inputs anchor the watcher at the nearest existing directory so replace-style writers keep producing later external change events.
Logging
with-watchreadstracingfilter directives only fromWW_LOG.- Diagnostic logs are off by default. Set
WW_LOG=with_watch=infoorWW_LOG=with_watch=debugwhen you want planner and watcher details. RUST_LOGdoes not configurewith-watchlogging.WITH_WATCH_LOG_COLORandNO_COLORcontinue to control ANSI log coloring.- Fatal user-facing errors still print to stderr even when diagnostic logging is off.
Troubleshooting
No watch inputs could be inferred from the delegated command: switch towith-watch exec --input ... -- <command>.--shell cannot be combined with delegated argv or the exec subcommand: choose exactly one command mode per invocation.--shellworks only for simple command-line expressions on Unix-like platforms.