Skip to main content

🌐 Vigía-eew

Real-time earthquake alerts for your desktop. Impossible to ignore.

What is it?

Vigía (vigia-eew) is a cross-platform desktop agent that monitors earthquakes in real time and fires an alert that can't be ignored or dismissed by accident.

It connects over WebSocket to the EMSC real-time feed (push — no constant polling) and uses the USGS FDSN service as a reconciliation fallback so no event is missed. When an earthquake occurs within your configured radius, Vigía instantly displays its magnitude, location, distance from your reference point, and depth — and stays on screen until you explicitly acknowledge it.

It runs on Linux, Windows, and macOS, with no API keys, no paid services, and no dependency on any phone.

Why?

A regular desktop notification gets silenced by Do Not Disturb, dismissed with a stray click, or buried behind other windows. In a seismic emergency, that's exactly what must not happen. Vigía forces an alert window to the front, with sound scaled to severity, that only disappears once you confirm you've seen it.

It was born in the aftermath of the June 2026 Venezuela earthquake, with a clear goal: a self-hosted, free, and robust tool that each machine can run on its own, with no single point of failure. Depending on your distance from the epicenter, the notification may reach you before the most destructive seismic waves; and even when it doesn't, it guarantees the alert isn't missed and is logged.

Key features

  • 🛰️ Real WebSocket push (EMSC) as the primary channel — no constant polling.
  • 🔁 REST fallback (USGS FDSN) that reconciles and recovers anything the WebSocket may drop.
  • 🇻🇪 FUNVISIS local coverage (Venezuela only): polls the Venezuelan national network so the small local quakes (M2–3) that EMSC/USGS don't catalog still trigger alerts. Polling (no push); enabled by default, harmless elsewhere (its events fall outside your radius).
  • 🚨 Non-dismissable alert: a front-most window, with sound, that only closes on acknowledgment. Where "front-most" is guaranteed, and where it is not — see Scope of the alert guarantee.
  • 📍 Configurable geographic filter: reference point, radius in km, and minimum magnitude — auto-detected by IP geolocation if you don't set one manually.
  • 🌎 Optional country filter: only notify earthquakes in your own country (offshore/coastal quakes kept), determined offline — opt-in, off by default.
  • 🟢 Cross-platform: Linux, Windows, and macOS, with autostart on login.
  • 📦 Full distribution: PyPI, .exe, .dmg, AppImage, .deb, .rpm.
  • 🧪 --simulate mode to test the alert without waiting for a real earthquake.
  • 🖥️ System tray icon: connection status, last alert, pause/resume notifications, edit config, quit — best-effort, never blocks startup if unavailable on your desktop.
  • ⌨️ Headless TUI dashboard (--tui): run the agent on a server over SSH with no display — a terminal dashboard with live status, an alerts log, and a non-dismissable modal alert (ENTER acknowledges). Combine with --simulate to test it.

Scope of the alert guarantee

The product's central promise is an alert that is hard to ignore: a window above everything else, that only closes when you acknowledge it. That promise does not hold equally everywhere, and the honest thing is to say where.

Desktop session Above every window Why
Windows ✅ Guaranteed The platform honours always-on-top for an application window
macOS ✅ Guaranteed Same
Linux · X11 ✅ Guaranteed X11 honours always-on-top and focus requests from the alert window
Linux · Wayland ⚠️ Not guaranteed The compositor owns window stacking. The toolkit's always-on-top request is accepted and then silently dropped, so another window can cover the alert
Anything else ❓ Not confirmed The session could not be identified. The alert is shown; being above everything is not verified there

The alert is always shown, with its sound and its desktop notification, in every one of these. What varies is whether it can place itself above whatever you are looking at.

How the Wayland row was established, since it is a claim about somebody else's software: on a GNOME/Wayland session, the topmost request (measured with Tk's wm_attributes("-topmost", True), before the GUI moved to Flet) returns successfully and reading the attribute back gives 0. The same call, on the same machine, under a plain X server gives 1. Nothing at the call site can tell the difference — which is why the agent reasons about the session rather than trusting the return value.

Your own machine tells you which row it is on. The tray menu shows it, and the agent logs it at startup:

presentation_guarantee session=wayland guarantee=degraded

If you are on GNOME and need the guarantee today, an X11 login session provides it. Closing this gap on Wayland is tracked as ADR-010.

Installation

There are two ways to install Vigía: a prebuilt package (recommended for everyday desktop use) or from source (for development or unsupported platforms).

Download the artifact for your OS from the latest GitHub Release. No Python installation is required — the binary is self-contained.

OS Artifact Install
Linux vigia-eew-*-x86_64.AppImage chmod +x vigia-eew-*.AppImage && ./vigia-eew-*.AppImage
Linux (Debian/Ubuntu) vigia-eew_*_amd64.deb sudo apt install ./vigia-eew_*_amd64.deb
Linux (Fedora/RHEL) vigia-eew-*.x86_64.rpm sudo dnf install ./vigia-eew-*.x86_64.rpm
Windows vigia-eew-*-setup.exe Run the installer: Start Menu entries, optional desktop shortcut and optional autostart. (vigia-eew.exe alone still works, unpackaged.)
macOS vigia-eew-*.dmg Open the .dmg and drag the app to Applications.

The .deb/.rpm packages install a vigia-eew command on your PATH and a launcher entry: after installing, Vigía-eew appears in your applications menu, and right-clicking it offers Settings (the configuration panel) and Test the alert — and Vigía-eew — Configuración is an entry of its own, so the panel is one search away. The AppImage carries the same entry; the Windows installer puts Vigía-eew and Vigía-eew — Configuración in the Start Menu; on macOS the .app lands in Applications like any other.

Option B — From source (Python 3.11+)

Requires Python 3.11 or newer. With uv (recommended):

git clone https://github.com/ecrespo/vigia-eew.git
cd vigia-eew
uv venv && uv pip install -e .        # add ".[dev]" for the test/lint tooling
uv run vigia-eew --help

Or with plain pip:

python -m venv .venv && source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install -e .
vigia-eew --help

If your release also publishes to PyPI, pipx install vigia-eew (or pip install vigia-eew) works too — PyPI upload is optional in CI, so check the release notes.

Configuration

Vigía runs with sensible defaults centered on Caracas and needs no configuration to start. To customize it, create a config.toml. On first run Vigía auto-creates one from the bundled template at the path below; you can also copy config.toml.example there by hand and edit it.

Where the file lives (the default location Vigía reads on startup):

OS Path
Linux ~/.config/vigia-eew/config.toml
macOS ~/Library/Application Support/vigia-eew/config.toml
Windows %LOCALAPPDATA%\vigia-eew\config.toml

You can also point at any file explicitly with --config <path>.

Three ways into the settings, deliberately:

vigia-eew --settings      # the configuration panel, on its own; no agent, no tray
  • The panel — every setting, with live validation and a reorderable list of seismic networks. Reach it with vigia-eew --settings, from the launcher entry's Settings action (right-click the application icon), from the Start Menu shortcut on Windows, or from the tray menu's "Configuration…".
  • The tray menu, which also offers "Edit configuration…" and "About…".
  • The file, which is what lets you version it with Git, copy it between machines, or reach it over SSH.

On GNOME/Wayland the tray menu may not open at all. Without PyGObject installed, pystray falls back to a legacy X11 tray icon: a shell extension still draws the icon, and clicking it does nothing. The log says so (tray_menu_unreachable). Use vigia-eew --settings or the launcher's Settings action — neither needs the tray.

The panel and the About window are in English, like the configuration schema their labels come from; the alert, the toast and the tray menu follow [notification] language. "About…" — in the tray menu and in the panel's footer — shows the installed version, the copyright, the licence and the warranty notice.

Saving from the panel preserves every comment in the file, keeps the previous version as config.toml.bak, and refuses to overwrite an edit you made elsewhere while it was open. Changes apply when the agent restarts — the configuration is read once, at startup.

"History…" opens the record of every earthquake the agent evaluated — alerted or discarded, and why it was discarded — as a filterable table with a map beside it. It is a local SQLite file that never leaves your machine; entries older than [history] retention_days (90 by default) are removed when the agent starts, and enabled = false turns the whole thing off.

The map draws tiles from OpenStreetMap, only while it is open, and caches them so a zone you have already looked at is not requested again. While it is open the provider can infer roughly which area you are looking at; with no connection and nothing cached the map says it is unavailable and the table carries on working.

Most useful settings (see config.toml.example for the full schema):

[reference]                 # your location; delete this whole section to auto-detect by IP
name = "Caracas"
lat = 10.4806
lon = -66.9036

[filter]
radius_km = 300.0           # only alert on earthquakes within this radius
min_magnitude = 2.5         # raise to ignore smaller quakes (e.g. 3.0)
country_filter = false      # true = don't notify quakes in *other* countries (offshore kept)
country = "auto"            # "auto" derives it from the reference point, or set "VE", "CO", ...

[notification]
fullscreen = false          # make the alert take the whole screen
sound = true                # play a severity-scaled sound
tray_icon = true            # show the system tray icon (best-effort)
language = "auto"           # "auto" = detect from OS locale; or "en" / "es"
  • Location — set [reference] manually, or delete/comment the whole section to have Vigía detect your location by IP on first startup (cached afterwards).
  • What triggers an alert — radius_km and min_magnitude in [filter].
  • Only my country — set [filter] country_filter = true to suppress earthquakes in other countries (offshore/coastal quakes are kept). Off by default.
  • Language — [notification] language ("auto", "en", or "es").
  • FUNVISIS (Venezuela) — [sources.funvisis] polls the Venezuelan network for local quakes EMSC/USGS miss. Enabled by default; it only reports Venezuelan events (harmless elsewhere — they fall outside your radius) and it's polled over plain HTTP (FUNVISIS has no HTTPS). Set enabled = false to turn it off.

Validate a config without starting the agent:

vigia-eew --check-config              # uses the default path
vigia-eew --config ./my.toml --check-config

Usage

On the desktop (default)

Just run it — from the launcher (packaged app) or the console:

vigia-eew

Vigía starts in the background and connects to the feeds. From then on:

  • When a qualifying earthquake occurs, a front-most, non-dismissable alert window appears with sound, showing magnitude, place, distance, and depth. It stays until you click ACKNOWLEDGED — a stray click, Esc, or the window's X won't close it.
  • A system tray icon shows connection status and the last alert, and lets you pause/resume notifications, edit the configuration, or quit (best-effort; if your desktop can't show a tray icon, the agent still runs).

Start automatically on login (installs a systemd user service / LaunchAgent / scheduled task, depending on the OS):

vigia-eew --install-autostart
vigia-eew --uninstall-autostart   # to remove it

Test the alert without waiting for a real earthquake (injects a simulated M6.1 near La Guaira):

vigia-eew --simulate

From the console (CLI)

Run vigia-eew --help to see every flag:

Flag What it does
(none) Start the full agent with the desktop GUI + tray icon.
--tui Run the headless terminal dashboard instead of the desktop GUI (for servers over SSH with no display).
--simulate Inject a simulated earthquake to test the alert. Combine with --tui.
--config <path> Use a specific config.toml.
--check-config Validate the configuration and print the reference point, then exit.
--install-autostart / --uninstall-autostart Install/remove autostart on login.
--version Print the version and exit.

Headless / over SSH — the TUI dashboard:

vigia-eew --tui                # live status bar + alerts log in the terminal
vigia-eew --tui --simulate     # same, with a test alert to see the modal

The TUI shows the WebSocket connection status and a log of recent alerts. Each qualifying event opens a non-dismissable modal inside the terminal that only ENTER acknowledges (Esc is disabled — same "impossible to ignore" contract as the desktop window). Keys: p pause/resume notifications, q quit. There is no tray icon or toast in this mode.

Development

Contributing? CONTRIBUTING.md has the full picture: the devcontainer, the quality gate, the testing conventions and the commit format. The rest of this section is the short version.

The project uses a src/ layout, so it must be installed in editable mode before running the tests or the CLI from a checkout (otherwise import vigia_eew fails).

With uv (recommended):

uv venv
uv pip install -e ".[dev]"      # runtime + dev deps (pytest, ruff, mypy)

Or with plain pip:

python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"

Then run the checks:

uv run pytest      # test suite
uv run ruff check .   # lint
uv run mypy src    # type check
uv run vigia-eew --help  # console entry point

Pre-commit hooks

The repo ships a .pre-commit-config.yaml that mirrors the CI gates locally. Enable it once per clone:

uv run pre-commit install     # registers the pre-commit and pre-push git hooks
  • On each commit (fast): file hygiene, ruff, mypy, bandit, gitleaks.
  • Before each push (slower): pytest, pip-audit, semgrep, trivy (trivy is best-effort locally — it runs only if the binary is installed; CI enforces it).

Run everything on demand: uv run pre-commit run --all-files (add --hook-stage pre-push for the push-stage hooks). These match .github/workflows/ci.yml and security.yml.


Built with Spec-Driven Development · Source and docs in Spanish

Metadata

Release files for vigia-eew 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for vigia-eew 1.0.0
File Size Uploaded Provenance Actions
vigia_eew-1.0.0.tar.gz 640.3 kB Without provenance Details for vigia_eew-1.0.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for vigia-eew 1.0.0
File Interpreter ABI Platform Actions
vigia_eew-1.0.0-py3-none-any.whl Python 3 none any Details for vigia_eew-1.0.0-py3-none-any.whl

Total release size: 892.6 kB

Release files / vigia_eew-1.0.0.tar.gz

Download URL vigia_eew-1.0.0.tar.gz
Size 640.3 kB
Tags Source
SHA-256 checksum
How to use checksums
2b09f12eaa762a4a697a3174e81467c8d21adc2417466c2730c4357bf7eee6ba
BLAKE2b-256 checksum
How to use checksums
06e866c2555ff6c7ed3494ea09f446fbdb9ef0bea9eff3e2107e5943e20cb07c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / vigia_eew-1.0.0-py3-none-any.whl

Download URL vigia_eew-1.0.0-py3-none-any.whl
Size 252.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f629a199244854874cf2f228e86acaf24a30df4e90d3969c766796067e5b0a56
BLAKE2b-256 checksum
How to use checksums
daa4a699da9a55c8430bafdb23ef07434817e325a489c1ea1be4a36a5aa9bd77
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.1 {"installer":{"name":"uv","version":"0.13.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for vigia-eew 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page