net-tools/tray
Natalie 2e8a5443a2 tray: add DO cloud config switcher + make green reflect new lime-based mesh
- derive visible hosts, Fleet label, and critical peers from dx.hide_homelan in mesh-hosts.json
- "Toggle homelan visibility (recovery)" menu action + immediate re-render of /etc/hosts+ssh
- only lime (DO backend with MCPs/tools) is core critical for the icon; redroid is shown but does not degrade
- stale homelan (pear etc) filtered from tray labels when using the new DO config (hide=true)
- tray README and module docs updated; the switcher makes the active config obvious in the menu bar
- this is the private path for MCPs on DO (and other internal tools): wg mesh (yuzu hub + lime spoke) + net-tools names, no public exposure

.
2026-06-28 14:49:28 -04:00
..
icons feat(@tools/net-tools): add icon generation tool 2026-06-10 05:35:11 -07:00
lilith_tray feat(@tools/net-tools): add tray icon system 2026-06-10 02:20:23 -07:00
.gitignore feat(@tools/net-tools): add tray icon system 2026-06-10 02:20:23 -07:00
com.natalie.wg-quick-wg1.plist feat(@tools/net-tools): add tray icon system 2026-06-10 02:20:23 -07:00
generate_icons.py feat(@tools/net-tools): add icon generation tool 2026-06-10 05:35:11 -07:00
install-tray.sh fix(tray): own the menu-bar tray with a RunAtLoad+KeepAlive LaunchAgent 2026-06-22 22:39:11 -04:00
README.md tray: add DO cloud config switcher + make green reflect new lime-based mesh 2026-06-28 14:49:28 -04:00
requirements.txt feat(@tools/net-tools): add tray icon system 2026-06-10 02:20:23 -07:00
vpn-toggle.applescript feat(@tools/net-tools): add tray icon system 2026-06-10 02:20:23 -07:00
vpn-tray feat(@tools/net-tools): add tray icon system 2026-06-10 02:20:23 -07:00
vpn_tray.py tray: add DO cloud config switcher + make green reflect new lime-based mesh 2026-06-28 14:49:28 -04:00

wireguard-vpn-tray

macOS menu-bar app showing live WireGuard mesh (wg1) status as a colored hexagon icon plus a Status menu item. This is also the switcher for the active fleet config (new DO cloud vs optional homelan recovery data).

  • 🟢 green — tunnel up, hub reachable, and all critical hosts for the active config (DO lime etc. when homelan hidden; or homelan+cloud when un-hidden) are reachable.
  • 🟠 orange — tunnel up + hub ok, but one or more critical hosts for the current config are down (partial mesh).
  • 🟡 yellow — tunnel up but the hub is not yet reachable (connecting)
  • 🔴 red — no tunnel interface present

The tray reads data/mesh-hosts.json (and its dx.hide_homelan) so the displayed hosts, the "Fleet:" label, and the critical set for the icon are always consistent with the active config. "DO cloud-only (homelan hidden)" is the normal production view; homelan data stays in the json for recovery but is filtered out of the tray (and of rendered ssh/hosts) until you toggle.

Click "Toggle homelan visibility (recovery)" in the menu to flip dx.hide_homelan, auto re-render this machine's /etc/hosts + ssh fleet block, and refresh the tray labels. Commit the json change (the toggle only does the local render) so the rest of the fleet sees the new config on their next pull.

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/.