Skip to content
manustaysPublic

About

Quay — a native macOS menubar app to start, stop, and monitor your local dev services, Homebrew services, and terminal agents.

Topics

Resources

Contributing

Stars

18 stars

Watchers

0 watching

Forks

Repository files navigation

Quay Logo

Quay

Quay (pronounced "key") — Where your ports come in.

A native macOS menubar app to start, stop, and monitor your local dev services — Node/Python servers, Homebrew services, Docker containers, and long-running terminal agents — from one place, with live CPU/memory metrics.

License: MIT Platform: macOS Built with Tauri About Abhishek Support my work

Quick Install

Homebrew (recommended)

brew install --cask manustays/tools/quay

or, download the .dmg from the latest release.

The problem

If you build a lot of local services, you know the dance: remember which folder, cd into it, run the start command, switch to the browser, and repeat for every project. Keeping several running at once means juggling terminal tabs and trying to remember what's up and on which port.

Quay puts all of that one click away. Register an app folder once; then start it, see its live status, open its web UI, or drop into a terminal in its folder — straight from the menubar. It also manages Homebrew services (MySQL, MongoDB, Redis…), Docker containers, and long-running terminal agents.

Quay Popover Screenshot

Features

  • One unified list for five kinds of long-running things:
    • Project servers — Node/Python apps on localhost:<port> (npm run dev, python main.py, …)
    • Homebrew services — brew services formulae like mysql, mongodb-community, redis
    • Docker containers — pick an image (autocompleted from your local images), name the container, and Quay starts the daemon if needed, then runs/reuses it
    • Terminal agents — interactive tools you run in a terminal (e.g. Claude Code, custom agents)
    • Command services — daemons driven by their own CLI (omlx start / omlx stop, a launchd service, …). Quay runs both commands and reads status from the port, so starting or stopping one outside Quay shows up too
  • Start / stop each item from the menubar. Background services run headless (no foreground terminal); their output is logged to a file.
  • Live status — process liveness plus a port/HTTP health check, polled in the background and pushed to the UI (no manual refresh).
  • Resource metrics — live CPU % and memory per item (including per-container docker stats), sampled while the popover is open.
  • Open in browser — one click opens http://localhost:<port>, or a per-service URL (http://127.0.0.1:{port}/app, a LAN IP, …).
  • Open a terminal already cd'd into the service's folder, when you actually need to watch logs.
  • Auto-detect on add — pick a folder and the app reads package.json / requirements.txt / .env to pre-fill the start command and port.
  • Port radar — dev servers you started outside Quay show up in a Detected section (project name + framework icon), with one-click adopt as service, kill, or ignore. A stopped item whose port is taken by another process gets a ⚠ collision badge.
  • Agent radar — AI-agent sessions (Claude Code, Codex CLI, OpenCode, Pi) show up in an Agents section with project name + stack icon, session name on hover, memory/uptime, and a working / idle / waiting-on-you dot; sessions in the same folder club into a project row with stacked agent badges. Install per-agent hooks in one click (Settings) — each agent then reports its own lifecycle, so states are exact (including "waiting at a permission prompt") and Quay never reads the agents' own files. Sessions are discovered from those hook reports, so an agent with no hooks installed does not appear. Jump-to-session, reveal-in-Finder, kill, and ignore per session.
  • Tech-stack icons — rows show the detected framework/runtime (Vite, Next, Django, Rails, Go, Rust, Docker, …) as a brand-colored icon.
  • Groups — label related items (backend + frontend of one app) with a shared group; they cluster together with an aggregate status dot and start-all/stop-all.
  • Favorites + search — pin the services you use most; the rest tuck under a collapsible "More".
  • Quality of life — click a port to copy its localhost URL, per-row uptime, reveal-in-Finder, and crash errors that include the exit code + last log lines.
  • Per-item env vars, custom health path, and auto-start-on-launch.
  • Configurable terminal (Terminal.app or iTerm2) and launch-at-login.
  • Idles when you aren't looking — the heavy sampling loops stop when the popover is closed, and everything stops when your displays sleep or the Mac is locked, since nothing it computes is on screen then. Measured at 0.10 % CPU and ~0 idle wakeups per minute sitting in the menubar; see Performance.
  • Native & light — built with Tauri v2 (Rust core + system webview), no bundled Chromium.

Requirements

  • macOS (Apple Silicon or Intel). This app is macOS-only — it uses osascript, open, and brew. The download is a universal build, so one .dmg runs natively on both architectures.
  • For Homebrew items: Homebrew installed.
  • For Docker items: Docker Desktop installed (Quay can start the daemon for you, but it must be installed).
  • To build from source: see Development.

Permissions & Privacy

Quay does not read your agents' files. The Agent radar shows the state and name of coding-agent sessions (Claude Code, Codex CLI, OpenCode, Pi), and it learns all of it from the agents themselves: you install per-agent hooks in Settings with one click, and each agent reports its own lifecycle to Quay through a tiny helper.

Earlier versions had a fallback that read the session and log files those tools write under ~/.claude, ~/.codex and ~/.pi when hooks were not installed — which is what triggered the macOS Sequoia prompt "Quay wants to access data from other apps." Those readers are gone. The radar never opens those directories.

The one file Quay still touches there is the hook config you asked it to install (~/.claude/settings.json and the equivalents). It writes that on install, and re-reads it at launch to keep it current across app updates — so on a machine with hooks installed, macOS may still ask once. Install no hooks and Quay never goes near those directories at all.

The trade is that a session is only visible once its agent's hooks are installed. With none installed, the Agents section says so and offers the button that installs them.

(Session names come from the prompt you typed, which Claude Code and Codex pass to the hook. OpenCode and Pi don't, so those rows show the project without a session name.)

Why it's safe:

  • Read-only. Quay never writes to your agents' directories. The one exception is the hook config you explicitly install from Settings (and can uninstall).
  • Stays on your machine. No telemetry, no analytics — nothing about your sessions, projects, or prompts ever leaves the device.
  • Nearly zero network. The only network access is an optional check for app updates against GitHub Releases. There is no other outbound traffic.
  • Fully open source. The radar is src-tauri/src/agent_radar.rs and the hook helper is src-tauri/crates/quay-hook — audit them yourself.

Download

⬇ Download for macOS — latest release

Grab the .dmg from the latest release, open it, and drag Quay to /Applications.

First launch. Current releases are not yet code-signed/notarized, so macOS Gatekeeper will say "Quay can't be opened because it is from an unidentified developer." This is expected. To open it:

  1. Try to open Quay once (the warning appears).
  2. Go to System Settings → Privacy & Security, scroll down, and click Open Anyway next to the Quay message, then confirm.

(On macOS Sequoia and later, the older right-click → Open trick no longer reliably bypasses this for unsigned apps — use Open Anyway.) Full steps, plus the xattr alternative, are in the Installation guide.

Build from source

Prefer to build it yourself (or want your own signed .dmg)?

git clone https://github.com/manustays/quay.git
cd quay
npm install
npm run tauri build      # produces a .app and .dmg under src-tauri/target/release/bundle/

Or run it in dev mode while you try it out:

npm run tauri dev

Full details, including the Rust/Node prerequisites and how to package, sign, and notarize a distributable build:

Usage

  1. Click the menubar icon → + Add.
  2. Pick a folder (for a project or agent) — the app pre-fills name, start command, and port. Or choose kind = brew and pick a formula, or kind = docker and pick an image (Quay autocompletes from your local images and fills in a container name).
  3. Tweak fields if needed (run mode, env vars, health path, favorite, auto-start) → Save.
  4. Hit ▶ to start. Watch the dot go yellow → green. Use ↗ to open the browser, >_ to open a terminal, ■ to stop.

See the Usage guide for the full walkthrough of item kinds, run modes, and status semantics.

Documentation

Doc What's in it
Installation Prerequisites, build from source, install the .app
Usage Adding items, run modes, status, browser/terminal actions, favorites
Docker services Running and monitoring Docker containers as items
Port radar How unmanaged listeners are discovered, adopted, killed, ignored
Agent radar How terminal AI-agent sessions are detected, the working/idle/waiting states, and installing per-agent hooks
Metrics How live CPU/memory sampling works (processes + docker stats)
Performance Measuring Quay's own CPU and idle wakeups, and what the current readings are
Configuration config.json location + full field reference
Packaging & distribution Build a .dmg, code-sign, notarize, and the release CI
Development Dev setup, project layout, running tests
Architecture How the Rust core and webview fit together
Troubleshooting Common issues and fixes

How does it work

A Rust core owns all process supervision and state; a small vanilla-TypeScript webview is the popover UI. They talk over Tauri commands (UI → Rust) and events (Rust → UI). Background services are spawned as child processes in their own process group (so the whole tree can be stopped cleanly), with stdout/stderr written to a per-item log file. A background poll loop checks each item's process and port and pushes status changes to the UI. Quit from the tray's right-click Quit and the children Quay owns are terminated; what it doesn't own — terminal windows, brew services, Docker containers, command-service daemons — is left running. See Architecture.

Known limitations

  • macOS only.
  • Owned background services stop when you quit — quitting terminates the child processes Quay spawned itself, and they are not restarted on the next launch (turn on Auto-start per item for that). Anything Quay doesn't own — terminal windows, brew services, Docker containers, command-service daemons — keeps running, and its status is re-derived on relaunch.
  • Terminal-mode items are best-effort — the app opens a Terminal/iTerm window but doesn't own that process; "stop" for those is best-effort, and a terminal item with a configured port can sit at starting if its window is closed externally.
  • Releases are not yet code-signed/notarized — the download opens after an Open Anyway step (see Download); a signed build removes that.

Roadmap

  • Hotkey to open the popover (currently only click the menubar icon)
  • Per-item log viewer (currently you must open the log file in a terminal or editor)
  • Per-item hotkey to start/stop (currently only click the row buttons)
  • System notifications on status changes (currently only the dot and row color change)
  • Configure the port radar's scan interval and ignored ports (currently hardcoded)
  • Configure the menubar icon to show a badge with the number of running items (currently only the dot changes), or track a specific port's status (e.g. a backend service) and show its status in the menubar icon.
  • Cross-platform support (Windows, Linux) — the Rust core is cross-platform, but the UI and process supervision are macOS-specific
  • Signed & notarized releases (CI already publishes universal .dmgs — see .github/workflows/release.yml)

Support

Quay is an independent project I build and maintain in my spare time. The best way to support it is to use it, share feedback, report issues, or contribute.

If you find it useful and would also like to support my independent open-source work financially, GitHub Sponsors is available.

Contributing

Contributions welcome — see CONTRIBUTING.md. In short: open an issue to discuss, work on a feature/, bugfix/, or chore/ branch, use conventional commits, run the tests (cargo test + npm test) and npx tsc --noEmit before opening a PR.

License

MIT © 2026 Kumar Abhishek

About

Quay — a native macOS menubar app to start, stop, and monitor your local dev services, Homebrew services, and terminal agents.

Topics

Resources

Contributing

Stars

18 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Contributors

Languages