Skip to content
JinJieBeWaterPublic

About

macOS menu bar companion for monitoring and opening local or SSH-hosted Herdr agents in Ghostty

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

Herdling

English | 简体中文

Herdling is a macOS menu bar companion for Herdr. It shows local and SSH-hosted Herdr agents, keeps their status current, and opens the selected session in Ghostty.

Features

  • Groups agents by machine, session, Space, and worktree while preserving Herdr order.
  • Activity prioritizes normally followed agents: blocked, done, working, then the three most recently updated idle agents. Sources opens the full directory; expand one source or keep them all closed.
  • Check Mute in an agent's secondary actions menu to keep its live status without adding blocked/done to attention counts. Muted rows use lighter title and status ink, without an extra badge; Activity moves them below normal agents immediately. Unmuting restores normal priority. Mouse actions keep the viewport in place; keyboard focus follows the selected target. Running counts, navigation and the Sources hierarchy remain unchanged; the choice is saved locally.
  • Keeps rows in place while browsing, with live status; reopen to rebuild the list. Failed jumps retain their target for retry.
  • Updates local and remote sessions through Herdr's socket event stream, with discovery and CLI fallback where needed.
  • Reuses an existing Ghostty Herdr client when possible. New clients open in a tab by default; Settings can switch this to a window.
  • Reads SSH hosts from ~/.ssh/config, including Include files.
  • Supports Launch at Login, keyboard shortcuts, VoiceOver labels, light/dark appearance, and Reduce Motion.

Requirements

  • macOS 15 or later
  • Swift 6.2 toolchain
  • Herdr installed locally and on each enabled SSH host
  • Ghostty for opening and focusing sessions
  • Key-based or otherwise non-interactive SSH access for remote hosts

Herdling finds herdr through HERDR_BIN_PATH or common Homebrew/system paths. Remote commands run through the host's login shell.

Build and run

There are no signed or notarized binary releases yet. Build the app from source:

git clone https://github.com/JinJieBeWater/herdling.git
cd herdling
bash scripts/build-app.sh release
open .build/Herdling.app

The script creates an ad-hoc-signed app at .build/Herdling.app. Move it to a stable location such as /Applications before enabling Launch at Login.

For a development build:

bash scripts/build-app.sh
open .build/Herdling.app

Setup

  1. Start at least one Herdr session.
  2. Open Herdling from the menu bar.
  3. Open Settings with ⌘, or by right-clicking the menu bar item.
  4. Enable required aliases under SSH Sources.
  5. Choose whether new Ghostty clients open as tabs or windows.
  6. Optionally record a global panel shortcut in Settings. No combination is assigned by default.

The first Ghostty action may trigger a macOS Automation permission prompt. Permission status appears in Settings.

Remote hosts

Herdling uses named Host entries from ~/.ssh/config. Wildcard and negated entries are ignored. Each enabled host must:

  • connect without an interactive password prompt;
  • expose herdr through its login shell;
  • provide nc with Unix-domain socket support.

Check the connection before enabling it:

ssh -o BatchMode=yes my-server '$SHELL -lc "herdr session list --json"'

Controls

Action Result
Left-click menu bar item Open or close roster
Right-click menu bar item Open Refresh/Settings/Quit menu
Right-click an agent Select it for inspection and open its fixed-corner actions menu; toggle Mute without navigation or a seen change
Click a machine in Sources Toggle its directory; expanding one closes the previous source
Click an agent, worktree, Space, or session Focus it in Ghostty
Global panel shortcut (when configured) Toggle panel; select a target without navigating
↑ / ↓ Select a row without navigating
Enter Open selected target; source rows only toggle their directory
← / → in Sources Return to parent / collapse or expand a source
Tab / Shift-Tab Move among native controls
⌘, Open Settings
Esc in roster Close panel
⌘Q Quit Herdling

Herdr focus can mark every pane in the destination tab as seen and affect all shell clients in that session. A failed jump may already have changed focus; it does not imply rollback or that a task was handled. Recent idle rows come from Herdr's state timestamps, not navigation history.

Development

Run tests:

swift test

Treat warnings as errors:

swift test -Xswiftc -warnings-as-errors

Build release app:

bash scripts/build-app.sh release

Architecture

  • AppKit owns NSStatusItem and a nonactivating NSPanel; SwiftUI renders panel content.
  • Local and remote monitors maintain one NDJSON socket stream per Herdr session.
  • Periodic discovery finds added or removed sessions. CLI polling remains a fallback when a stream is unavailable.
  • Ghostty activation uses AppleScript plus terminal/process validation to reuse the correct client and avoid duplicate tabs or windows.

Troubleshooting

  • No local sessions: confirm herdr session list --json works in a new shell. Set HERDR_BIN_PATH if Herdr is installed elsewhere.
  • SSH source stays offline: run the BatchMode command above. Fix host keys, authentication, remote PATH, or missing nc before retrying.
  • Ghostty does not open or focus: check System Settings → Privacy & Security → Automation and allow Herdling to control Ghostty.
  • Launch at Login is unavailable: run Herdling from .build/Herdling.app or another app bundle, not through swift run.

License

Herdling itself does not currently declare a software license. The bundled Herdr mark is covered by third-party notices and the bundled Apache License 2.0 text.

About

macOS menu bar companion for monitoring and opening local or SSH-hosted Herdr agents in Ghostty

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages