Astrill VPN Control (macOS Menu-Bar Toggle + Dual-Probe Verification)
The Astrill macOS app ships no official CLI. Its menu-bar item
Menu → Toggle ON/OFFcan be located and clicked via AppleScript (System Events), and the menu item text mirrors the connection state — that menu anchor is what this skill relies on. Field-tested 2026-08-28 on OpenVPN full-tunnel mode with an on↔off round-trip.
Usage
Run the bundled script from this skill's base directory (the directory containing this SKILL.md):
bash <skill-dir>/scripts/astrill.sh status # inspect: app / tunnel / GUI menu / exit IP
bash <skill-dir>/scripts/astrill.sh on # connect (idempotent: no-op when already connected)
bash <skill-dir>/scripts/astrill.sh off # disconnect (idempotent: no-op when already disconnected; app stays alive)
Resolve <skill-dir> from the skill base directory announced at load time; when unavailable, ask the user for the installed skill path.
State Machine and Probes
| Signal | How collected | Meaning |
|---|---|---|
| App process | pgrep -x astrill |
prerequisite for GUI control; kept alive after off so on reconnects faster |
| VPN tunnel | pgrep -x asovpnc |
primary judge under OpenVPN mode; teardown takes ~10 s (script polls through it) |
| GUI menu | System Events reads items of the Menu menu |
Toggle OFF present = connected; Toggle ON present = disconnected |
| Exit IP | curl --max-time 6 ipinfo.io/ip |
cross-check: connected → foreign node IP; disconnected → local direct IP |
on and off are idempotent: each first reads the current state and returns success immediately when the desired state already holds.
One-Time Prerequisite: Accessibility Permission
The app that hosts the agent (terminal, IDE, or desktop app) must hold the macOS Accessibility permission: System Settings → Privacy & Security → Accessibility → add the host app. Without it the script reports GUI unreachable and the status output names the cause.
Known Boundaries
- OpenVPN vs OpenWeb: probes are most accurate under OpenVPN (full tunnel). In OpenWeb (browser-only proxy) mode the
asovpnctunnel probe does not apply — the GUI menu text stays the primary judge, and the exit-IP probe (curl) may not reflect the browser proxy state. - Teardown latency: after Toggle OFF the tunnel process exits ~10 s later than the UI flips; the script's 30 s polling window covers it.
- Toggle, not quit:
quit appalso disconnects but drops the GUI session; the script uses Toggle so the app keeps running and a lateronreconnects without relaunching. - Menu drift after updates: macOS or Astrill major updates may rename menus. When
MenuorToggle ON/OFFdisappears, re-probe withosascript -e 'tell application "System Events" to tell process "Astrill" to get name of every menu of menu bar 1'and update the script accordingly. - Bash pitfall when editing the script: after a
$var, a CJK/full-width character makes bash merge the following UTF-8 bytes into the variable name (set -uthen reports unbound variable). Always write${var}.