Sections

User Guide

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:

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:

State indicators:

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:

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:

{ "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:

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:

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:

  1. Shows up next to the tool name in the menu (My App • :3001).
  2. Gets auto-injected into startupCheck URLs that don't include an explicit port (e.g., http://localhost/api/health becomes http://localhost:3001/api/health).
  3. 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:

  1. installCommand if the marker path (default: node_modules) doesn't exist.
  2. Each startCommand in order. Commands with waitFor: "OtherLabel" pause until the other process passes its health check.
  3. Health check polling (if configured).

The tool transitions through startingrunning once all processes are healthy.

Stop

The Stop item either:

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.

At the bottom of the dropdown: