Skip to content
Skip to Content

Reference / CLI

verbatra watch

Re-translate on every source change until interrupted, so locale files stay in sync while you edit the source; each run sends only new and changed keys.

Watch the source locale file and re-run a translation after each debounced change, until you interrupt it. watch runs an initial translation at startup, then keeps your target locales current as you save. Each run works like verbatra translate, except that watch has no --dry-run, --prune, --include-human, --estimate or --max-tokens and never exits 3. At startup it also adds missing entries to an existing .gitignore, see .gitignore entries.

Synopsis

verbatra watch [flags]

Examples

# watch and re-translate on each change
verbatra watch

# calmer in a busy editor: wait 1s after the last change, stream NDJSON
verbatra watch --debounce 1000 --json

# keep only German current while you work
verbatra watch --locales de

Flags

FlagArgumentDefaultEffect
--locales<list>every configured target localewatch only this comma-separated subset; checked once at startup, where an unconfigured locale fails with UNKNOWN_LOCALE
--debounce<ms>300wait this many milliseconds after the last change before translating; a whole number from 1 to 60000
--lock-timeout<seconds>600wait this long for a held per-locale write lock in each run; a whole number from 1 to 3600
--concurrency<n>1translate up to n target locales at once per run; a whole number from 1 to 100, refused under a maxTokens budget
--no-cachenoneoff (cache on)bypass the translation-memory cache (verbatra.cache.json) on every run

Also takes the global flags --cwd, --config and --json; here --json prints one record per run. Before it starts, watch loads the environment files.

Behavior

Each run

Every run translates the --locales subset, or every target, with a fresh token budget. A locale whose write lock stays contended past --lock-timeout fails with LOCK_CONTENDED in that run's summary while the other locales still run; a lock left by a verbatra process that is no longer running is reclaimed at once. A failed run never stops the watcher. A wait for a lock prints the lock-wait line described under translate.

A --concurrency above 1 together with a configured maxTokens budget is refused at startup with exit 2, before the initial run, because which locale loses its remaining work would depend on how the locales interleave.

A provider that cannot be built, most often because its API key variable is unset, is refused at startup too: watch exits 2 with PROVIDER_CONSTRUCTION_FAILED and a next: line naming the variable, exactly like translate, instead of waiting for changes no run could translate. Before 0.12.0 it kept waiting.

Stopping

The first interrupt (Ctrl-C or SIGTERM) lets the current run finish, stops the watcher, and exits 0. A second interrupt while that shutdown is still in flight force-stops with exit 130, after releasing the session's write locks. Without --json, stderr says verbatra: waiting for changes... after every run, verbatra: press Ctrl-C to stop after the startup line on an interactive terminal, and verbatra: stopped once the shutdown has finished. --quiet drops these lines, but not the startup line or verbatra: stopping, finishing current run... on the first interrupt: those are written in every mode, --json included.

JSON output

Schema: watch-envelope.json validates the whole envelope; Schemas lists the others.

With --json, stdout is NDJSON: one envelope per run, with command: "watch". A succeeded run is an ok: true record carrying that run's RunSummary; a failed run is an ok: false record with the failure's own code, or WATCH_RUN_FAILED when it had none, plus its hint when it has one. A failed run is only a record: it neither stops the watcher nor changes the exit code. The startup line, the stopping notice and progress go to stderr. Without --json, a run's summary goes to stdout and a failed run's verbatra: error [CODE] message line to stderr.

Terminal feedback

Without --json, watch names the source file once a change to it has settled, then reports the run as translate does, with the same spinner on an interactive terminal:

Output
verbatra: change detected: locales/en.json
verbatra: translating de
verbatra: de batch 1/1
verbatra: de: writing
verbatra: de done, 1 translated
verbatra: run finished, 1 locale processed
verbatra: waiting for changes...

These lines go to stderr, and --quiet drops them. See Terminal output.

Exit codes

CodeMeaning
0stopped cleanly by a single interrupt
2could not start or stop: a config error, a startup or shutdown failure, or a usage error such as an invalid --debounce
130force-stopped by a second interrupt

A failed run during the session never changes the exit code. See the exit-code contract.

Edit on GitHub

On this page