https://github.com/vaayne/mori
A native macOS workspace terminal organized around Projects and Worktrees, powered by tmux and libghostty
https://github.com/vaayne/mori
ghostty git macos swift terminal tmux workspace worktree
Last synced: 11 days ago
JSON representation
A native macOS workspace terminal organized around Projects and Worktrees, powered by tmux and libghostty
- Host: GitHub
- URL: https://github.com/vaayne/mori
- Owner: vaayne
- License: mit
- Created: 2026-03-19T09:57:15.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-04-03T07:20:33.000Z (24 days ago)
- Last Synced: 2026-04-03T13:58:10.510Z (23 days ago)
- Topics: ghostty, git, macos, swift, terminal, tmux, workspace, worktree
- Language: Swift
- Size: 11.6 MB
- Stars: 169
- Watchers: 1
- Forks: 12
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
English | 中文
A native macOS workspace terminal organized around **Projects** and **Worktrees**, powered by **tmux** and **libghostty**.
Instead of managing loose terminal tabs, Mori treats your git repositories as first-class projects. Each worktree (branch checkout) gets its own persistent tmux session with multiple windows and panes — all presented through a native sidebar and GPU-accelerated terminal.
## Why Mori
- **Project-first navigation** — switch between repos and branches, not anonymous tabs
- **Local + remote projects** — add local folders or SSH-hosted repositories from one Add flow
- **Persistent sessions** — close the app, reopen later, everything is still running in tmux
- **Native macOS experience** — sidebar, command palette, notifications, keyboard shortcuts
- **GPU-rendered terminal** — libghostty (Ghostty's rendering engine) with Metal acceleration
- **Worktree-aware** — multiple branches of the same repo run side-by-side with independent sessions
## How It Works
```
Project (git repo)
└─ Worktree (branch checkout)
└─ tmux Session
├─ Window (tab) → Pane
├─ Window → Pane | Pane
└─ Window → Pane
```
Each worktree maps to one tmux session. Windows and panes are standard tmux constructs. Mori provides the UI layer on top — organizing, navigating, and displaying status.
## Architecture
```
App (AppKit shell + SwiftUI sidebar views)
├─ MoriCore — Models + observable app state
├─ MoriUI — SwiftUI sidebar views
├─ MoriTmux — tmux CLI integration (actor)
├─ MoriGit — Git worktree/status discovery (actor)
├─ MoriTerminal — libghostty terminal surface
├─ MoriPersistence — SQLite via GRDB
└─ MoriIPC — Unix socket IPC + `ws` CLI
```
## Requirements
- macOS 14 (Sonoma) or later
- tmux
- [mise](https://mise.jdx.dev/) (task runner)
- Zig 0.15.2 + Xcode (for building libghostty)
## Install
### Homebrew
```bash
brew tap vaayne/tap
brew install --cask mori
```
### GitHub Releases
Download the latest release from [GitHub Releases](https://github.com/vaayne/mori/releases).
- `.dmg`: Open the disk image and move `Mori.app` into `/Applications`
- `.zip`: Extract the archive and move `Mori.app` into `/Applications`
The Homebrew tap installs `Mori.app`. Release bundles also embed the `mori` CLI for Homebrew-based installs, and the cask declares `tmux` as a dependency.
## Build & Run
```bash
mise run build # Debug build
mise run build:release # Release build
mise run dev # Build + run
mise run test # Run all tests
mise run clean # Clean build artifacts
```
`mise run build` and `mise run build:release` automatically bootstrap the libghostty XCFramework on first run. You can also build it manually:
```bash
mise run build:ghostty # Requires Zig 0.15.2 + Xcode (downloads Metal Toolchain if missing)
```
## CLI
The `mori` command lets you interact with Mori from the terminal:
```bash
mori project list
mori open /path/to/repo
mori worktree create
mori focus
mori send "command"
mori new-window
mori pane list
mori pane read [--lines N]
mori pane message "text"
mori pane id
```
## Terminal Configuration
Mori uses Ghostty's configuration system. Customize your terminal in `~/.config/ghostty/config`. Mori only overrides a few embedding-specific settings (no window decorations, no quit-on-last-window).
## Keyboard Shortcuts
See [docs/worktrees.md](docs/worktrees.md) for worktree management and [docs/keymaps.md](docs/keymaps.md) for the full shortcut list. Highlights:
| Shortcut | Action |
| ------------------------------------------------------------ | --------------------- |
| ⌘+T | New tab (tmux window) |
| ⌘+W | Close pane |
| ⌘+D / ⌘+⇧+D | Split right / down |
| ⌘+1–⌘+9 | Go to tab N |
| ⌃+Tab / ⌃+⇧+Tab | Cycle worktrees |
| ⌘+⇧+N | New worktree |
| ⌘+⇧+P | Command palette |
| ⌘+B | Toggle sidebar |
| ⌘+G | Lazygit |
| ⌘+E | Yazi |
## License
[MIT](LICENSE)