AI-native macOS terminal for developers who run Claude Code and agent CLIs all day — built Vietnamese-first, IME-correct for every input method.
Website: https://hoang.tech/herminal/ · Download: latest release · Source: this repo
Status: v1.0.0
is publicly available as a signed, notarized DMG; main carries post-v1 fixes.
See CHANGELOG. Platform: macOS 14+ Apple Silicon.
🇻🇳 Phiên bản tiếng Việt:
README.vi.md
Live agents and worktrees on the left, splits in the middle, per-session notes on the right. The left slot is one slot: the agent dashboard and the SSH manager take turns in it.
![]() |
![]() |
Real screenshots, captured from the CI-built app by the screenshots workflow — re-run it after any chrome change and they regenerate.
A local-first macOS terminal built around two daily realities the existing 2026 terminals each miss part of:
- You run Claude Code / Codex / Aider all day and need a glanceable view of which agents are alive, idle, or done — without an open-a-second-window detour.
- You type a language an English keyboard can't reach — Vietnamese Telex / VNI, Korean 2-Set Hangul, Japanese romaji, Chinese Pinyin — and need the composition to land correctly the first time, in tmux, in vim, every time.
herminal pairs the libghostty engine (Zig, mature, native performance) with a Swift / AppKit shell that owns the IME and the chrome. Storage is SQLite for both per-session notes and saved SSH hosts. No cloud, no telemetry, no account.
The composition APIs live on the terminal surface itself, not in a wrapper text field — so one bridge serves every input method macOS offers. Vietnamese is the release gate because it's the PRD's headline persona, not because it's special-cased in code.
In 2026 nothing on the market hits all five at once:
| Need | iTerm2 | Warp | Wave | Ghostty | herminal |
|---|---|---|---|---|---|
| Native macOS speed | ✓ | partial | partial | ✓ | ✓ |
| Vietnamese IME + in-preedit shell completion | ✓ | × | × | partial | automated¹ |
| tmux + multi-session | ✓ | partial | × | ✓ | ✓ |
| Built-in agent dashboard | × | partial | × | × | ✓ |
| Local-only persistent notes per session | × | × | × | × | ✓ |
The IME row is scored on Vietnamese because that's the rubric's persona.
The bridge underneath is generic — Korean, Japanese and Chinese get their
own smoke matrix in
docs/QA/cjk-ime-checklist.md.
See docs/research/ for the full comparison and
scoring rubric the table is derived from.
Shipped in v1.0.0; main continues with post-release fixes:
- Native terminal core via libghostty (Metal renderer, p95 keystroke <5ms)
- Vietnamese IME bridge with automated Tab/preedit regressions; live Telex/VNI release gate pending¹
- Multi-session workspace: tmux-style recursive splits, drag-to-resize dividers, directional pane focus, pane zoom
- Agent dashboard: running / idle / starting / needs-input badges, npx/python wrapper detection, per-pane attribution, accessible filtering
- Agent worktree cockpit — ⌘⌥W spawns an agent in an isolated git worktree
- Session continuity: restore-on-launch, named workspaces, filterable Claude session browser (⌘⇧C →
claude --resume) - Per-session notes (SQLite WAL) with Markdown round-trip
- SSH Connection Manager with one-click spawn,
~/.ssh/configimport, and host filtering - Dark + light chrome with follow-system (Raycast/Linear style)
- tmux compatibility verified against vim, less, htop, fzf, lazygit, btop, starship
- Telemetry-free local crash diary with redacted export
- Developer-ID codesign + notarize pipeline
¹ The implementation and state-transition regressions are green, and a dated
live run cleared the core Telex and VNI one-Tab commit-and-complete paths
(docs/QA/results/vietnamese-ime-live-2026-08-15.md).
The full T1–T7 visual matrix still wants an owner pass — see
issue #2.
Still deferred — see docs/ROADMAP.md for the feedback gates: groups / folders and per-host keypair UI in the SSH manager, Sparkle auto-update (today the app's manual Check for Updates… action opens the official GitHub releases page; automatic Sparkle checks are still stub-only), App Store distribution (sandbox-incompatible by design), Linux / Windows.
brew install --cask hoangperry/herminal/herminalbrew upgrade --cask herminal keeps it current. Public artifacts must be
Developer-ID signed, notarized, and stapled so Gatekeeper can validate them;
macOS may still show its standard first-open confirmation.
- Grab
herminal-vX.Y.Z.dmgfrom the Releases page. - Open the DMG → drag
herminal.appinto/Applications. - Launch. Verify the publisher in the standard macOS first-open confirmation.
git clone --recurse-submodules https://github.com/hoangperry/herminal
cd herminal
Scripts/bootstrap.sh # builds libghostty xcframework (~5-15 min cold)
Scripts/make-app-bundle.sh # assembles .app with ad-hoc signature
open .build/herminal.appPrereqs: Xcode 26+, Swift 6.2+, Zig 0.15.2+
(for libghostty), clang for the kernel-probe binaries used by the
integration scripts.
- ⌘T / ⌘W — new tab / close current pane (closes tab when last)
- ⌘D / ⌘⇧D — split vertical / horizontal
- ⌘⇧] / ⌘⇧[ — next / previous tab
- ⌘⌥A — new Claude pane (split)
- ⌘⌥W — new isolated agent worktree
- ⌘⇧A — toggle agent dashboard (live agents + worktrees)
- ⌘1…⌘9 — jump to tab N / last tab
- ⌘⇧S — toggle SSH host manager (mutex with the agent dashboard in the left slot)
- ⌘⇧N — toggle the per-session notes panel on the right
- ⌘⇧C — Claude session browser: pick a past session, it reopens
with
claude --resumein the right cwd - ⌘⇧L — toggle light / dark theme
- ⌥⌘← → ↑ ↓ / ⌘⇧↩ — directional pane focus / zoom the focused pane
Full map in docs/KEYBOARD-SHORTCUTS.md.
Agent worktrees: working on two fixes at once? ⌘⌥W creates an
isolated checkout under ../<repo>.worktrees/<branch> via
git worktree add and opens it in a new tab running the agent you pick
(claude / codex / aider) or a plain shell. The dashboard lists
every worktree with open / remove — remove always confirms and never
passes --force.
Agents are detected by walking herminal's process subtree — start
claude, codex, or aider in any tab and they'll appear in the
dashboard within ~2 seconds with a running / idle / starting
badge tracked via CPU sampling.
No agent has to cooperate and no API key is involved — the signal is
derived entirely from the process tree. argv is read only to recognise
node / python / bun / deno wrappers, and is dropped immediately
after. See docs/CONTRIBUTOR-TOUR-AGENT-SIGNAL.md
to follow one signal end to end.
| Layer | Tech | Why |
|---|---|---|
| Terminal engine | libghostty 1.3.1 (C ABI via Zig) | Mature, native, no Electron |
| App | Swift 6 + AppKit + SwiftUI chrome | Real NSTextInputClient, real Metal layer |
| Surface | NSView hosting libghostty's Metal layer |
Pixel-precise IME |
| Storage | SQLite WAL (notes + SSH hosts) | Local-only, atomic, indexable |
| Distribution | Developer-ID signed + notarized DMG/zip and Homebrew cask | App Store sandbox is incompatible |
libghostty is consumed as an upstream release through its published C
ABI — not vendored as a fork. Full write-up in
docs/ARCHITECTURE.md.
herminal/
├── Sources/
│ ├── HerminalCore/ # libghostty C ABI bridge + BellRegistry
│ ├── HerminalDB/ # NotesStore + SSHHostsStore + SSHConfigImporter
│ ├── HerminalAgent/ # process-subtree detection + status + pane mapping
│ └── HerminalApp/ # NSApp, WorkspaceView, panels, worktree cockpit, Diary
├── App/ # Info.plist + entitlements
├── Tests/ # Swift Testing unit and integration suites
├── Scripts/ # bootstrap, bundle, verify-*, dogfood, sign, release, capture-screenshots
├── Vendor/libghostty/ # git submodule (Ghostty v1.3.1)
└── docs/
├── assets/ # README diagrams + app screenshots
├── research/ # market scan + scoring
├── define/herminal.prd.md # source-of-truth PRD
├── backlog/ # monthly task lists + retrospectives
├── QA/ # IME checklists (VI + CJK), dogfood checklist + journal
└── launch/ # press kit + tweet/LinkedIn drafts
Read CONTRIBUTING.md first — the project is opinionated about what's in scope. Bug reports go through the bug template which prompts for the diary excerpt; security issues go to SECURITY.md. From the app, Help > Report a Security Issue… opens the private reporting path without sending anything automatically.
If Herminal is useful in your daily workflow, a GitHub star helps more macOS and Vietnamese developers discover the project.
Made with 🐈 by Yuuhou Meow team in Việt Nam.



