moo-mac-terminal

agent
Security Audit
Fail
Health Pass
  • License — License: NOASSERTION
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 10 GitHub stars
Code Fail
  • exec() — Shell command execution in Moo/MarkdownPreview/Resources/markdown-preview-chunk-blockDiagram-I7D4REHJ-F2YS2VSV.js
Permissions Pass
  • Permissions — No dangerous permissions requested

No AI report is available for this listing yet.

SUMMARY

Open-source native macOS terminal, up to 4× faster than Ghostty, with workspaces, notifications when Claude Code and other agents need you, herdr agents in the sidebar, Markdown and browser (ad-blocked) tabs, a ⌘K command palette, and a modern settings UI

README.md

⭐ If Moo is useful to you, please star it: click the ☆ Star button at the top right of the GitHub repo page.

Moo Terminal

Moo Terminal

A native, open-source macOS terminal with Ghostty-class speed — faster on throughput and keystroke latency in measured runs — and the workspace features that make cmux good for running agents.

License: MIT Platform: macOS GitHub stars

Table of Contents

Overview

Moo is my personal terminal setup: the one I use all day, tuned to how I work.
I share it in case it is useful to someone else, but its defaults, shortcuts
and features follow my workflow.

It aims for two things at once:

  • The speed of Ghostty. Moo runs on SwiftTerm
    with engine work of its own, and in side-by-side runs it pushes output
    through a pty faster than Ghostty and gets a keystroke on screen sooner.
  • The workflow of cmux. Terminals are grouped into workspaces in a sidebar
    that says which ones are busy, finished or waiting for you. Tabs hold Markdown
    previews and web pages beside shells, panes split and zoom, and ⌘K reaches
    every command and anything worth grabbing on screen.

Screenshots

figlet "Moo Mac Terminal" piped through lolcat in a Moo window

Terminal
A Moo window with the workspaces sidebar, a terminal, and Markdown and browser tabs
Fast, native, and out of the way: workspaces down the side, tabs across the top.

herdr agents
Claude Code running inside herdr in a Moo window, with herdr's spaces and agents panels
Run agents in herdr inside a Moo tab; Moo tracks each one and tells you when it needs you.

Markdown preview
A rendered Markdown tab
Markdown files open rendered, in a tab beside the shell
Browser tabs
A web page open in a browser tab
Web pages open as browser tabs, with ad blocking
Workspaces (Projects)
Terminal with the projects sidebar
Workspaces in the sidebar, each with its own tabs and status
Project settings
Projects settings
Choose what each project row shows, and reopen everything on launch
Themes
The theme picker
Over 140 bundled themes, browsable as a list or in 2D and 3D
Appearance
Appearance settings
Fonts, cursor, opacity and colors, set per profile
Notifications
Notifications settings
Banners, Dock badge, bounce, sound or speech when a program is waiting for you
herdr notifications
The menu bar notifications list with "herdr: claude needs you" entries
herdr agents that need you land in the menu bar list, labeled as detected by herdr
Multiple agents
Two Claude Code agents in herdr tabs, listed in herdr's agents panel
Each herdr agent is tracked on its own, so one answer never hides another

More at moo.vpetkov.net.

Quick Install

Download Moo.dmg,
open it, and drag Moo to Applications. Or from a terminal:

curl -fLO https://moo.vpetkov.net/Moo.dmg
hdiutil attach Moo.dmg && cp -R /Volumes/Moo/Moo.app /Applications/
hdiutil detach /Volumes/Moo && open /Applications/Moo.app

Requires macOS 15.5+ on Apple silicon or Intel. The app is signed with a
Developer ID and notarized by Apple, and it updates itself: new releases are
checked for automatically and can be installed from Moo → Check for
Updates…
. To build it yourself, see Building from Source.

Speed

Moo 0.1.9 against Ghostty 1.3.1, measured on 2026-10-03 on an M3 MacBook Pro at 120 Hz:

Moo Ghostty
100 MB plain text through a pty 0.36 s 1.21 s 3.3× faster
60 MB 256-color text 0.47 s 0.70 s 1.5× faster
40 MB CJK and emoji 0.19 s 0.34 s 1.8× faster
5,000 full-screen redraws 0.03 s 0.13 s 4.0× faster
Keystroke to screen, p50 / p99 23 / 34–38 ms 37–40 / 48 ms about 15 / 12 ms sooner
Idle CPU, one focused window, per minute 0.54 s < 0.01 s Ghostty lower (the cursor blink)

Plain text is already at the limit of a macOS pty, so the gains that matter are
colored output, redraws and latency. How each number was taken, what was tried
and rejected, and the traps in measuring terminals are in
docs/PERFORMANCE.md.

Features

  • Workspaces. A sidebar groups terminals into projects, each with its own
    tabs. Switching swaps the whole working set; the shells left behind keep
    running. Each row shows whether it is idle, running, has new output, or is
    waiting for you. Workspaces, tabs and splits reopen after a relaunch.
  • Waiting-for-you notifications. When an agent such as Claude Code asks
    for input, its tab, its workspace, the menu bar bell and the Dock say so.
    Click an entry to land in that window, workspace, tab and split.
  • Command status. A tab whose last command failed gets a red mark, and a
    long command finishing in a pane you are not looking at notifies you.
  • herdr agents in the sidebar. Run herdr in a tab and
    turn on Settings → Notifications → herdr: each agent shows under the
    project as working, finished or needing you, and a blocked agent notifies
    you. Moo only reads herdr; it never types into it.
  • Command palette. ⌘K lists every menu command plus the links, paths,
    commit hashes and IP addresses on screen. Return runs or copies; ⌘Return
    opens.
  • Tabs beyond shells. Markdown files open as rendered, GitHub-style tabs
    with Back and Forward through the links you follow; web pages open as
    browser tabs with ad blocking, next to the terminal that printed them.
  • Splits and zoom. Split with ⌘D and ⇧⌘D; ⇧⌘↩ zooms one pane to fill the
    tab and back, keeping the dividers where you left them. Right-click a pane
    for its split, zoom, theme, clear, reset and font commands.
  • Open from Finder. Right-click a folder or file, then Services → New Moo
    Tab Here, New Moo Window Here or New Moo Workspace Here.
  • Settings you can find. Settings are grouped into app-wide pages and
    per-profile pages, every setting is searchable and highlighted when you pick
    it, and each page has a help button into docs/SETTINGS.md.
  • Profiles that travel. Export a profile with its theme and your app
    settings, and import someone else's. Imports keep only the appearance unless
    you choose otherwise, after Moo lists any shell, environment variables or key
    mappings the file would bring.
  • Updates on your terms. Moo updates itself from its own signed feed. Let
    it open the update window, just mark the title bar with a purple dot, or
    never check.
  • Safe by default. Secure Keyboard Entry turns on by itself at password
    prompts. Links in terminal output open only the web and mail without asking,
    and files that would run are revealed in Finder instead. Programs can never
    read your clipboard, and must ask before writing to it. Images that name a
    local file or shared memory stay off until you allow them (Settings →
    General → Images), which Claude Code plugins such as intermission need.

Usage

Create a workspace from the sidebar (⌘B shows it), or press ⌘T for a new tab
in the current one. The status on each row is live: Idle at a prompt,
Running with a command in flight, Activity when a background workspace
printed something, Waiting when a program asked for you.

Notifications come from the escape sequences iTerm2, Ghostty and kitty use
(OSC 9, 777 and 99) and collect in the menu bar bell and Window → Notifications.
Settings → Notifications picks banners, Dock badge, sounds and the long-command
threshold. Claude Code only notifies terminals it recognizes: inside Claude
Code, run /config and set Notifications to ghostty.

Command status needs Moo's shell integration for zsh, bash, fish or elvish,
which reports when each command starts and how it exited.

Links and files: hold ⌘ to underline what is clickable in terminal output,
including bare file names from ls such as README.md. ⌘-click opens it:
Markdown files and web links as Moo tabs, folders in the Finder, and other
files in their default app. Anything that would run (apps, scripts) is only
revealed in the Finder, never launched.

Markdown and web tabs: command-click a .md path or a link, or use ⇧⌘M and
the File menu; ⌥⌘-click opens it in the default app instead. Ads and trackers
are blocked with EasyList and AdGuard's base and tracking-protection lists.
Previews draw Mermaid diagrams, reload as the file changes and are light by
default;
Settings → Links & Markdown can make them follow the terminal theme. A link to
another Markdown file opens in a new tab (⌘-click opens it in place, or the
other way round if you change the setting), and ⌘[ / ⌘] go back and forward.

Keyboard: holding a letter repeats it, so j held in vim scrolls (Settings
→ General → Keyboard turns macOS's accent picker back on). ⌘1–9 pick projects
or the current project's tabs. ⇧⌘K clears the screen and scrollback like
Terminal.app's ⌘K; ⌥⌘K clears only the scrollback.

Restore is on by default (Settings → General → Startup). Shells start fresh in each
pane's last directory; scrollback, commands and environment are never saved.

Keyboard Shortcuts

Keys Action
⌘K Command palette
⇧⌘K   /   ⌥⌘K Clear screen and scrollback / clear scrollback only
⌘1–⌘8   /   ⌘9 Select a project or tab / the last one
⌘T   /   ⌘W New tab / close pane or tab
⌘D   /   ⇧⌘D Split side by side / stacked
⇧⌘↩ Zoom pane
⌥⌘ arrows Move between splits
⇧⌘[   /   ⇧⌘] Previous / next tab
⌘[   /   ⌘] Back / forward in Markdown and browser tabs; previous / next split in a terminal
⌘↑   /   ⌘↓ Jump to the previous / next prompt
⌘B Show or hide the sidebar
⇧⌘U Newest unread notification
⇧⌘M Open a Markdown preview
Right-click / ⌃-click Pane menu

Every shortcut, grouped by component: docs/SHORTCUTS.md,
also listed in Settings → Keyboard → Shortcuts.

How Moo Came Out of Tecolot

Moo started on 2026-09-10 as a personal customization of Miguel de Icaza's
Tecolot, forked at v0.0.22. What
began as three additions (projects, Markdown tabs, browser tabs) grew into a
hard fork: it now goes its own way, takes upstream fixes by hand, and sends
fixes that belong upstream back as pull requests to Tecolot and SwiftTerm.

What Moo adds on top of Tecolot:

  • Workspaces: projects in a sidebar with live status, their own tabs, and
    selection kept per window, restored with their tabs and splits on relaunch.
  • Markdown preview tabs, hardened against hostile files, with Back and
    Forward through followed links.
  • Browser tabs with ad blocking, sandboxed against hostile pages.
  • Waiting-for-you notifications from OSC 9, 777 and 99, with a menu bar
    bell, Dock badge, sounds and tab marks.
  • Failed-command marks and long-command notifications from OSC 133.
  • herdr agent status in the sidebar and notifications, read-only.
  • A ⌘K command palette over every menu command and what is on screen.
  • Pane zoom, horizontal splits on ⇧⌘D, a right-click pane menu with
    Copy and Paste, optional copy-on-select, and new tabs that open where the
    last one was.
  • Finder services to open a tab, window or workspace in a folder.
  • Settings regrouped by scope (app-wide or per profile), searchable, with
    a help button on every page and a catalog of every keyboard shortcut.
  • In-app updates from Moo's own signed Sparkle feed, with a choice of the
    update window, a quiet purple dot in the title bar, or no checks.
  • Engine speed: SwiftTerm built from a branch carrying an attribute intern
    cache (+26.5% on colored output) and idle process polling cut back.
  • Security: automatic Secure Keyboard Entry at password prompts; links from
    output limited to web and mail unless confirmed; files that would run revealed,
    never launched; remote shells' directories never treated as local; clipboard
    reads refused and writes asked first, naming the pane and defaulting to Deny;
    titles and paths from programs cleaned of control characters; imported
    profiles reviewed and limited to their appearance by default.
  • Everyday details: drop files onto the terminal to insert their paths,
    command-click a bare filename, key repeat for held letters, Clear to Start
    (⇧⌘K), ⌘1–9 for a project's tabs, Terminal.app-style window titles, tabs
    named after the running program, a layout kept when the last window closes,
    and profile files that carry their theme and app settings.

Building from Source

git clone https://github.com/ventz/moo-mac-terminal
cd moo-mac-terminal
xcodebuild -downloadComponent MetalToolchain   # one time, ~688 MB
open Moo.xcodeproj                             # ⌘R to build and run

Requires Xcode 26 or later. The Metal Toolchain is not optional: the renderer
compiles a Metal shader, and a stock Xcode fails about 90% of the way through
the build without it.

Debug build and run from the command line:

xcodebuild build -project Moo.xcodeproj -scheme Moo \
  -configuration Debug -destination "platform=macOS" \
  -skipPackagePluginValidation \
  -derivedDataPath build/DerivedData
open build/DerivedData/Build/Products/Debug/Moo.app

-skipPackagePluginValidation is required: SwiftTerm ships a build-tool
plugin. Release builds are universal (x86_64 arm64); local Debug builds are
arm64-only. Release packaging, signing and notarization are in
docs/DEVELOPING.md.

Documentation

docs/DEVELOPING.md: the developer guide, covering
build prerequisites, code signing and why the certificate type matters,
notarization, cutting a release, tracking upstream, and troubleshooting.

docs/SETTINGS.md: every setting, page by page, with
its options, its default and what it does.

docs/SHORTCUTS.md: every keyboard and mouse
shortcut, grouped by windows, tabs, splits, terminal, Markdown previews and
browser tabs.

docs/PERFORMANCE.md: how Moo compares with Ghostty
on throughput, keystroke latency and idle CPU, where the latency goes, the
engine changes that paid off and the ones that did not, and how each number
was measured.

Acknowledgements

Moo Terminal exists because of Miguel de Icaza.

Tecolot is the application underneath: the windows and panes, the profiles and
themes, the automation, the persistence. SwiftTerm, also his, is the emulation
itself: parsing, buffers, rendering, the pty. Nearly every line of this program
is his work.

Both Tecolot and SwiftTerm are MIT licensed, © 2026 Miguel de Icaza. Moo is not
affiliated with or endorsed by him, nor by the Ghostty or cmux projects it is
compared with here.

Please report bugs to the right place. If a problem reproduces in Tecolot
itself, it belongs upstream,
where everyone benefits from the fix. Only fork-specific behavior belongs here.

SwiftTerm in turn builds on the work of the
xterm.js authors, SourceLair Private
Company, and Christopher Jeffrey.

Third-Party Components

Component Author License
SwiftTerm Miguel de Icaza MIT
Sparkle Sparkle contributors MIT
swift-argument-parser Apple Apache 2.0
swift-png Taylor Swift (tayloraswift) MPL 2.0
Symbols Nerd Font (Nerd Fonts 3.4.0) Nerd Fonts contributors MIT

Moo updates itself through Sparkle, from its own feed at
moo.vpetkov.net only — never upstream's,
which would install the upstream app over Moo. Every update is signed with
Moo's EdDSA key and notarized by Apple.

License

MIT © Miguel de Icaza (original work) and © Ventz Petkov (fork changes)

Reviews (0)

No results found