av-launcher is a menu-bar tray launcher for the fleet’s local web-server apps. It lets you pick a network interface and port, Start/Stop the server, Open the web UI, and leave it all in the system tray.
If you’re using srt-router, flock or RFutils as a desktop app, this is the shell you’re
looking at.
If the server won’t start on a clean Mac, read this first
The released builds are now Developer ID-signed and notarised, so this shouldn’t bite
anyone who downloads the .dmg or .pkg any more. It’s still the first thing to check if you
built the app yourself, or if you’re running a download from before that changed, because for
an unsigned .app that bundles helper binaries, approving the app does NOT unquarantine its
payload, and the helpers are SIGKILLed silently.
That’s this app’s shape to a tee: a tray app wrapping an embedded server binary. The failure mode is nasty:
- the app launches and looks completely fine;
- the server never starts;
- there’s no visible error.
This is the first thing to check, not a bug in the server. Clearing the quarantine attribute on the whole bundle is the usual fix:
xattr -dr com.apple.quarantine "/Applications/<the app>.app"
The apps built on it ship signing notes of their own. See each app’s launcher/SIGNING.md.
What has and hasn’t been tested
The Rust backend compiles and the panel UI has been exercised through its mock backend.
The tray app has been run on real Windows 11, where Start once did nothing at all (Tauri’s
resource dir came back as a verbatim \\?\ path, so no bundled binary resolved). v0.2.1 fixed
that, and since then Frame Ferret’s build of this shell reaches RUNNING there with its embedded
server answering. On macOS the full tray app hasn’t been run end to end against a live
server on the target machine.
Given the above, that gap matters: the untested path is the very one where the Gatekeeper problem shows up.
Using the panel

The same shell, themed per app. srt-router and RFutils get their own name, icon and colour, and behave the same way.
The URL under the RUNNING badge is the address the server is actually bound to, not a
template. If it says 127.0.0.1 when you expected a LAN address, the interface selector is the
thing to change. Copy that URL to reach the app from another machine.
| Control | Does |
|---|---|
| Network interface | which network interface the server binds |
| Port | which port |
| Start / Stop | run or kill the server |
| Open | open the web UI in your browser |
| Hide | back to the tray — the server keeps running |
| Quit | stops the server and exits |
Hide and Quit are different. Hiding leaves the server running; quitting kills it. If you close the panel expecting the app to keep serving, use Hide.
Interface and port
The Network interface dropdown lists every bindable IPv4 interface plus All interfaces (0.0.0.0).
- A specific interface → the server binds that IP, and the URL shows that IP.
- All interfaces → the server binds
0.0.0.0, and the URL shows your primary non-loopback IP so the link is still clickable.
“All interfaces” means the server is reachable from your whole network. Whether that’s a good idea depends on the app you’re launching and what it can do, and several of these fleet apps have no authentication. Pick a specific interface if you want it contained.
Your interface and port choice is remembered between launches, in the OS app-config directory.
If your port silently goes back to the default, the saved settings file is missing or unreadable. Every failure there falls back to the default without an error.
Starting and stopping
- Pressing Start when it’s already running does nothing harmful. It just reports the current status. It does not restart the server.
- If Start fails, the panel says why, in red under the buttons, and keeps saying it until you
press Start again, press Stop, or change the interface or port:
- “Port 8080 is already in use: another program is listening on it — perhaps flock is already running.” Something else holds the port — often another copy of this app (a second launcher, or the server started by hand). Open still works, so you can see what is there; otherwise stop it or pick a different port.
- “This computer refuses port 80…”: the operating system reserves it or wants administrator rights. Choose a port above 1023.
- “…is not an address of this computer right now”: the interface you chose has gone (cable out, Wi-Fi moved). Choose another.
- “The flock server exited right after starting (exit code 1). Its last output is below.” — the server itself failed, and its last lines are shown so you can see what it said. On macOS, “killed by signal 9” with no output is the Gatekeeper trap above.
- If the server exits on its own later, the panel notices the next time it refreshes status (within a couple of seconds), and reports it the same way.
- Stop and Quit ask the server to shut down, then make sure it has. On macOS and Linux the server is sent SIGTERM and given 3 seconds to save its state and stop anything it started. Only a server still running after that is killed outright. On Windows the server is ended at once (there’s no equivalent request to send it), so an app that writes state on exit may not get the chance there.
Troubleshooting
| Symptom | Cause |
|---|---|
| App opens, server never starts, no error (macOS) | The Gatekeeper quarantine trap (If the server won’t start on a clean Mac, read this first). Check this first. |
| Server starts then immediately stops | Often the working directory: several apps read relative paths (state/routes.json, data/registry.json) and fail if started elsewhere. That’s a launcher-config issue, not a server bug. |
| Port reverted to the default | The saved settings file is missing or unreadable; it falls back silently (Interface and port). |
| URL shows an IP I didn’t pick | You chose “All interfaces”, so it shows your primary non-loopback IP to keep the link clickable (Interface and port). |
| Others on the network can reach it | “All interfaces” binds 0.0.0.0 (Interface and port). |
| Closed the panel and the app kept serving | That’s Hide. Quit stops it (Using the panel). |
| Start did nothing | It was already running (Starting and stopping). Anything else that stops a start is now written under the buttons — a held port, a refused port, a server that died and what it said. |
| The app lost unsaved state on Quit | On Windows Quit ends the server at once; on macOS/Linux the server had 3 seconds after SIGTERM and did not finish in time (Starting and stopping). |
See also
- API.md: the launcher contract and the command surface
- adding-an-app.md: wrapping another app in this shell
- DEVELOPING.md: building it