No description
Find a file
Natalie b9e1b32f1c feat(wireguard): add agent status integration
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-06-09 22:09:58 -07:00
icons feat(@applications/wireguard-vpn-tray): add tray icon support 2026-05-22 00:01:09 -07:00
lilith_tray feat(@applications/wireguard-vpn-tray): add tray icon support 2026-05-22 00:01:09 -07:00
.gitignore feat(@applications/wireguard-vpn-tray): add tray icon support 2026-05-22 00:01:09 -07:00
com.natalie.wg-quick-wg1.plist feat(@applications/wireguard-vpn-tray): add tray icon support 2026-05-22 00:01:09 -07:00
com.wireguard.vpn-tray.plist feat(@applications/wireguard-vpn-tray): add tray icon support 2026-05-22 00:01:09 -07:00
generate_icons.py feat(@applications/wireguard-vpn-tray): add tray icon support 2026-05-22 00:01:09 -07:00
README.md feat(@applications/wireguard-vpn-tray): add tray icon support 2026-05-22 00:01:09 -07:00
requirements.txt feat(@applications/wireguard-vpn-tray): add tray icon support 2026-05-22 00:01:09 -07:00
vpn-toggle.applescript feat(@applications/wireguard-vpn-tray): add tray icon support 2026-05-22 00:01:09 -07:00
vpn-tray feat(@applications/wireguard-vpn-tray): add tray icon support 2026-05-22 00:01:09 -07:00
vpn_tray.py feat(wireguard): add agent status integration 2026-06-09 22:09:58 -07:00

wireguard-vpn-tray

macOS menu-bar app showing live WireGuard mesh (wg1) status as a colored hexagon icon plus a Status menu item.

  • 🟢 green — tunnel up and the mesh hub (10.9.0.1) is reachable
  • 🟡 yellow — tunnel up but the hub is not yet reachable (connecting)
  • 🔴 red — no tunnel interface present

Built on the in-house lilith_tray framework (vendored here under lilith_tray/) via its macOS rumps backend.

Interface detection

macOS assigns the WireGuard utun device dynamically — the number changes between boots. The app therefore identifies the tunnel by the address it carries (the utun with a 10.9.0.x inet address), never by a hardcoded name. The tray icon and the Status label are both derived from a single status computation in poll_status(), so they can never disagree.

Layout

Path Purpose
vpn_tray.py the tray app
vpn-tray launcher — activates the venv and runs the app
lilith_tray/ vendored tray framework
icons/ colored status icons
generate_icons.py regenerates the icon set
vpn-toggle.applescript standalone connect/disconnect applet
com.wireguard.vpn-tray.plist launchd agent for the tray
com.natalie.wg-quick-wg1.plist launchd agent bringing wg1 up at boot
requirements.txt Python dependencies

The bundled launchd plists carry absolute paths for the current install (~/.wireguard/); adjust them if the app is installed elsewhere.

Setup

python3 -m venv .venv
.venv/bin/pip install -r requirements.txt

Install the launchd agent:

cp com.wireguard.vpn-tray.plist ~/Library/LaunchAgents/
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.wireguard.vpn-tray.plist

Secrets

WireGuard keys (*.key) and the tunnel config (wg1.conf) are intentionally not in this repo — see .gitignore. They live in ~/.wireguard/.