Repository navigation
CLI Usage
English · Português (Brasil)
If you installed from the binaries, the command is screen-watch; from the source code, use
python -m screen_watch. Both have the same command surface.
python -m screen_watch --help
python -m screen_watch <command> --helpGlobal flags:
| Flag | Effect |
|---|---|
--language TAG |
GUI language (auto, pt-BR, en-US or a discovered tag); does not affect the CLI, which is fixed English |
--verbose |
DEBUG-level diagnostic logging |
| Command | What it does |
|---|---|
init-config [--path PATH] [--force] |
creates the default config.yaml v2 in app-data (or at the given path); without --force, it does not overwrite |
validate-config [--config PATH] [--selections] |
validates the YAML (and, with --selections, the overrides of each selection) |
show-paths |
shows app-data, config, selections, state, logs and the effective prints folder (captures:) |
python -m screen_watch init-config
python -m screen_watch validate-config --selections
python -m screen_watch show-paths| Command | What it does |
|---|---|
list-windows |
lists the windows: handle, state (ok/minimized), position/size and title |
| `select --handle H [--name NAME] [--mode light | default |
select-manual --handle H --roi X Y W H [--name NAME] [--title T] [--mode ...] |
writes the selection by coordinates, without the overlay |
list-selections [--json] |
lists the selections (app name, region, mode; marks the last used one); --json prints one object per file for scripting |
edit-selection NAME [--mode ...] [--roi X Y W H] [--mask X Y W H]... [--clear-masks] [--poll-interval-s S] [--rearm/--no-rearm] [--text-watch TEXT --text-expect appears|disappears] [--clear-text-watch] [--clear-override KEY] |
edits the selection JSON without the overlay (mode, ROI, masks, poll interval, re-arm, text watch and overrides) |
rename-selection OLD NAME |
renames a selection (display name + file slug, same rules as the GUI) |
remove-selection NAME... |
deletes one or more selection JSON files (clears state.json.last_selection when it pointed to a removed one) |
migrate-config [--path PATH] [--dry-run] |
converts a v1 YAML (targets:) into selections/*.json + v2 YAML |
python -m screen_watch list-windows
python -m screen_watch select --handle 12345 --name painel
python -m screen_watch select-manual --handle 12345 --roi 120 340 400 80 --name painel
python -m screen_watch list-selections --json
python -m screen_watch edit-selection painel --mode advanced --mask 10 10 40 20 \
--poll-interval-s 1.5 --text-watch "CONCLUÍDO" --text-expect appears
python -m screen_watch edit-selection painel --roi 100 200 400 80 # re-anchors and clears the masks
python -m screen_watch edit-selection painel --clear-masks --clear-override rearm
python -m screen_watch rename-selection painel "painel erp"
python -m screen_watch remove-selection painel antigo-
edit-selectionfollows the GUI rules:--modeupdatesoverrides.modewhen the key exists (elsemode);--roi X Y W Hre-anchorsorigin_at_selectionand clears both mask fields (relative to the old ROI);--maskis repeatable and replaces the effective masks;--clear-masksempties both;--poll-interval-s/--rearm/--no-rearmwrite intooverrides;--clear-overrideacceptsmode,poll_interval_s,rearm,masksandtext_watch. - The JSON is written atomically and on error the file stays intact; passing no edit option exits with code 2.
-
list-selections --jsonprints one object per file:file,name,label,window_handle,roi_relative,mode,masks(effective-mask count),overrides(keys) andlast. - The default mode of selections is
advanced; you can change it later in the GUI selector or through the JSONoverrides. - The minimum accepted area is 10×10 logical pixels.
- In the overlay (
selectand the GUI's New Target/re-edit), the ROI must fit entirely inside the window; a region that extrapolates it is rejected (runtime.roi_outside_window).
| Command | What it does |
|---|---|
| `run [--config C] [--profile P] [--selection S] [--actions a,b | all |
gui [--config C] [--profile P] |
opens the GUI with tray (see GUI and tray) |
How run resolves the selection: --selection NAME looks for selections/NAME.json in app-data;
it also accepts a path to a .json. Without --selection, it uses state.json.last_selection; if
there is none, it lists the available ones and exits with an error.
How run builds the target: selection JSON + YAML profile; the selection overrides
replace the profile values (they do not add up). Without a YAML (or with a v1 YAML without a matching
target), it uses the default alerts: sound + popup + log (Telegram requires chat_id, so it does not
enter the default).
python -m screen_watch run --selection painel
python -m screen_watch run --selection "%APPDATA%\screen_watch\selections\painel.json"
python -m screen_watch run --profile trabalho --selection painel
python -m screen_watch run --selection painel --actions reprocessar,confirmar # subset for this session only
python -m screen_watch run --selection painel --actions none # only monitorsDuring execution, each trigger prints a line [action] rehearsal|armed <name> -> ok|failed (reason). Ctrl+C ends with shutting down.... On Wayland, run warns and exits (code 2).
| Command | What it does |
|---|---|
test-alert --selection S [--list] [--only ID] |
fires a synthetic alert (severity 3); --list prints id/type/state/destination; --only ID sends to one destination (text mode, ignores enabled) |
test-evidence --selection S |
writes an example baseline+change pair and prints the paths |
test-action --selection S [--armed] [--actions ...] [--no-countdown] |
rehearses (default) or runs the actions; --armed shows the 3 s countdown; one-off runs ignore the action trigger (notice line) |
list-actions --selection S |
lists the resolved actions and the saved subset, including each action trigger (change/at/every/after), without starting a session |
record-actions --selection S [--name NAME] [--out FILE] [--no-countdown] |
records clicks/keys and generates an actions: snippet (input extra; F10 ends it) |
compare-modes --selection S [--delay 5] [--repeat 1] [--modes light,default,advanced] |
measures changed/score/threshold/severity/time of each mode (calibration) |
probe-dpi |
prints the monitor matrix (physical mss × logical Qt × scale) and the rect of a window |
features [--json] |
environment diagnostics (version/origin, Tesseract, input, sound, tray, monitors) |
validate-i18n |
validates the language catalogs (keys, error.*, help.*, _meta) |
python -m screen_watch test-alert --selection painel
python -m screen_watch test-alert --selection painel --list
python -m screen_watch test-alert --selection painel --only siem
python -m screen_watch test-action --selection painel # rehearsal
python -m screen_watch test-action --selection painel --armed # actually executes
python -m screen_watch compare-modes --selection painel --delay 5
python -m screen_watch features --jsonThe whole selection lifecycle works without the overlay — list-windows → select-manual →
edit-selection → validate-config --selections → run --selection:
python -m screen_watch list-windows
python -m screen_watch select-manual --handle 123456 --roi 120 340 400 80 --name "painel erp"
python -m screen_watch edit-selection painel-erp --mode advanced --mask 10 10 40 20 \
--poll-interval-s 1.5 --text-watch "CONCLUÍDO" --text-expect appears
python -m screen_watch validate-config --selections
python -m screen_watch run --selection painel-erpThis resolves the README "Radar" item.
Masks are [x, y, w, h] rectangles relative to the ROI, painted black before comparison —
useful for spinners/clocks that change on their own. The GUI draws/removes them with the
Edit masks… button (see Window and tray); without the GUI, edit masks (or
overrides.masks, which has precedence) in the selection JSON — the profile has no masks.
compare-modes captures the ROI, waits --delay seconds (change the panel during that interval) and measures
changed/score/threshold/severity and the compare time of each mode; for advanced,
it also prints the texts recognized by OCR. Use this to adjust similarity_threshold,
upscale, psm and the severity_min of the alerts/actions. Record each adjustment with the context in
which it was made (doc/00 §18, item 8).
With rearm: true (default), a sustained change alarms once; a new change re-arms. If
an alert fails (e.g.: Telegram down), it is retried respecting cooldown_s (backoff),
without hammering on every tick. Manual re-arm is in the tray, in the window's Re-arm baseline button and in the
rearm hotkey.
-
target_unavailable— window closed, minimized or ROI out of bounds; the loop keeps retrying. -
capture_clipped— the ROI was clipped against the virtual desktop (monitor off/off-screen). -
roi_off_screen— the ROI is 100% off-screen: the tick is skipped, without breaking the loop. - Consecutive identical failures are reported once (not on every tick).
-
Configuration —
config.yaml, overrides, migration -
Pseudo-human actions —
actions:format and arming flow - Alerts — channels, severity and cooldown