Menu Bar Guide
How each tool type renders in the Runyard menu, and what every action does.
Runyard's entire UI lives in the menu bar. This page walks through what you see and how to interact with each piece.
The Runyard icon
Click the Runyard icon in the menu bar to open the dropdown. Right-click (or Control-click) does the same thing — there's no hidden context menu.
Alongside the icon you may see, depending on your settings:
- A short status text (e.g.,
2 runningorStarting Backend, Frontend…) — toggleable in Settings → General → Menu Bar. - A red ⚠︎ triangle whenever any health-check probe is failing.
- A dynamic tooltip (on hover) listing every active service with its detected port.
For everything in this paragraph, see the Settings Window guide. Per-tool status is shown inside the menu — the four states are listed below.
The four tool types
Runyard has four kinds of tools. They render differently in the menu.
Service
A service is a managed process — a backend, a dev server, a Docker stack. It's the most common type.
A service renders as:
- A bold header line with the tool name and a state indicator.
- A Start or Stop button.
- A View Logs item.
- Any actions you've defined (Open URL, Run Command, etc.), filtered by the current state.
State indicators:
- Gray dot + "Stopped" — the tool is not running.
- Yellow dot + "Starting…" — processes are spawning, or Runyard is polling the health check.
- Green dot + port number (e.g.,
:3000) — the tool is healthy and listening on a detected port. - Green dot + "Running" — healthy, but no port was detected.
- Red dot + "Error" — something failed (install, startup, or health check).
- Yellow dot + "Stopping…" — Runyard is sending SIGTERM or running your custom stop commands.
Shortcut
A shortcut is a flat list of actions under a bold header. No process management, no start/stop, no state. Use it for quick links (Grafana, Jira, internal dashboards) or one-shot scripts.
{
"name": "Shortcuts",
"type": "shortcut",
"actions": [
{ "label": "Open Grafana", "url": "https://grafana.example.com" },
{ "label": "Open Jira", "url": "https://jira.example.com" }
]
}
Group
A group is a submenu. The tool name becomes a parent menu item; hovering expands a submenu containing the group's own actions plus any nested services and shortcuts.
Use a group to keep related tools together — for example, all the pieces of one product stack.
{
"name": "QA Stack",
"type": "group",
"actions": [
{ "label": "Open Dashboard", "url": "https://qa.example.com" }
],
"tools": [
{ "name": "API Server", "type": "service", "...": "..." },
{ "name": "Links", "type": "shortcut", "...": "..." }
]
}
Nested services work exactly like top-level ones — they have their own state indicator, Start/Stop button, and logs. Groups cannot be nested inside other groups.
Health check (probe)
A probe polls an HTTP or TCP endpoint on a fixed interval and shows its status live in the menu. Use it to keep an eye on a third-party service, an internal API, or anything you don't manage as a process.
A probe renders as a single row with:
- A status dot — green (healthy), red (failing), or grey (unknown / paused).
- The probe name.
- A pause/resume button (⏸ / ▶) that toggles polling without restarting Runyard. The state survives reloads — pausing writes
autoStart: falsetoconfig.json. - A submenu with the polled endpoint, the last check timestamp and outcome, Check Now to trigger an immediate poll, and View Logs to open the probe's log file.
Probes have no Start/Stop and no actions of their own. Their failureThreshold (how many consecutive failures before flipping to red) and interval are configured in Settings → Tools or directly in config.json. See config.json Reference → Health Checks for the full schema.
{
"name": "Apple Status",
"type": "probe",
"interval": 60,
"failureThreshold": 2,
"http": { "url": "https://www.apple.com/support/systemstatus/" }
}
When any probe is failing, a red ⚠︎ triangle also appears next to the Runyard menu bar icon.
Actions
Actions are extra menu items per tool. Each action has a label and exactly one type:
| Type | Field | What it does |
|---|---|---|
| Open URL | url |
Opens the URL in your default browser. Supports {{port}} placeholders. |
| Run command | command + args |
Runs a shell command (in the tool's directory by default). Output goes to an action log. |
| Reveal in Finder | reveal |
Opens a folder in Finder. Relative paths resolve from the tool's directory. |
| Inline AppleScript | applescript |
Executes an AppleScript snippet. |
| AppleScript file | applescriptFile |
Runs a .applescript file. |
| Health check | healthCheck |
Runs a one-shot HTTP or TCP probe and shows the result inline on the menu item for ~3 seconds. See config.json Reference → Health Checks. |
Port placeholders in URLs
Action URLs can include {{port}} and {{port:Label}} placeholders:
{{port}}— replaced with the detected port of the tool's last process (typically the user-facing one).{{port:Backend}}— replaced with the detected port of the specific process namedBackend.
{ "label": "Open Frontend", "url": "http://localhost:{{port}}/" }
{ "label": "API Docs", "url": "http://localhost:{{port:Backend}}/swagger" }
If the tool isn't running (no port detected yet), the placeholder stays literal and the link won't open.
Controlling when actions appear
For service tools, actions have a showWhen field:
"running"(default) — only visible when the service is running."stopped"— only visible when stopped or errored."always"— visible either way.
This is useful for keeping the menu tidy: put "Open in Browser" under running and "Seed Database" under stopped, for example.
showWhen is ignored on shortcut and group actions — those are always visible.
Keep menu open
By default, clicking a menu item closes the menu. If you want to watch a tool start without the menu snapping shut, set keepMenuOpen: true:
- On a tool — applies to the Start/Stop buttons.
- On an action — applies only to that action.
The menu stays open until you click outside of it or press Escape.
Port detection
Runyard uses lsof to watch the PID tree of each process you spawn and picks up the first TCP port it starts listening on. The detected port:
- Shows up next to the tool name in the menu (
My App • :3001). - Gets auto-injected into
startupCheckURLs that don't include an explicit port (e.g.,http://localhost/api/healthbecomeshttp://localhost:3001/api/health). - Replaces
{{port}}placeholders in action URLs.
If your dev server picks different ports on different runs, you don't have to do anything — Runyard adapts.
Fallback: if auto-detection doesn't find a port (rare — some tools fork in unusual ways), set startupFallbackPort on the process. Runyard uses that as a hint.
Start, Stop, and Logs
Start
The Start item runs:
installCommandif the marker path (default:node_modules) doesn't exist.- Each
startCommandin order. Commands withwaitFor: "OtherLabel"pause until the other process passes its health check. - Health check polling (if configured).
The tool transitions through starting → running once all processes are healthy.
Stop
The Stop item either:
- Runs your custom
stopCommandsin order, then force-kills any leftovers. - Or, if no
stopCommandsare configured, sends SIGTERM → waits → sends SIGKILL.
View Logs
Every spawned process writes to its own log file under ~/Library/Logs/Runyard/. The View Logs submenu lists each one; clicking opens it in Console.app. See Troubleshooting → Logs for the full path scheme.
Global menu items
At the bottom of the dropdown:
- Settings… — opens the Settings window (General, Tools, Advanced, About).
- Edit Configuration — opens
config.jsonin your default editor. - Reload Configuration — reparses
config.jsonand rebuilds the menu. Running tools are stopped first. - Quit Runyard — stops all tools and exits.