Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
52c30d3
chore: bump ghostty pin to include fmt and doc fixes
DananzMolt Jul 26, 2026
ea3852c
fix(ivrix): bundle Resources/Fonts in every build
DananzMolt Jul 26, 2026
95adf8f
feat(ivrix): use Rubik for Hebrew instead of Miriam Mono CLM
DananzMolt Jul 26, 2026
bbea5fe
fix(ivrix): give the Hebrew fallback a uniform advance (Ivrix Mono He)
DananzMolt Jul 27, 2026
a8a9914
feat(ivrix): base the Hebrew fallback on Miriam Libre
DananzMolt Jul 27, 2026
832c953
feat(ivrix): add a DMG packaging script for local builds
DananzMolt Jul 27, 2026
48b16d3
chore: bump ghostty pin to RTL cursor placement fix
DananzMolt Jul 27, 2026
9328eec
chore: bump ghostty pin to include RTL cursor regression tests
DananzMolt Jul 27, 2026
cd04f43
chore: bump ghostty pin to cursor-row resolution fix
DananzMolt Jul 27, 2026
08520ad
chore: bump ghostty pin to UAX#9 L4 glyph mirroring
DananzMolt Jul 27, 2026
b5036de
chore: bump ghostty pin to RTL arrow key reversal
DananzMolt Jul 27, 2026
ac212c5
feat(ivrix): pick the Hebrew face from Settings
DananzMolt Jul 27, 2026
4227fe0
fix(ivrix): apply a Hebrew face change without a restart
DananzMolt Jul 27, 2026
bf3852a
chore: bump ghostty pin to modified-arrow binding mirror
DananzMolt Jul 27, 2026
31a511a
chore: bump ghostty pin to row-direction arrow mirroring
DananzMolt Jul 27, 2026
d964000
feat(ivrix): undo the current line edit with Cmd+Z
DananzMolt Jul 27, 2026
806e2e7
docs: changelog entry for the Ivrix 1.0.0 release
DananzMolt Jul 27, 2026
72b8259
docs: make the README about Ivrix, and findable
DananzMolt Jul 27, 2026
ee412ce
docs: keep the upstream install section from being mistaken for Ivrix
DananzMolt Jul 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,45 @@

All notable changes to cmux are documented here.

## Ivrix [1.0.0] - 2026-07-28

Ivrix is a Hebrew-first fork of cmux. This release rebases the fork onto the
latest upstream cmux (1919 commits) and makes right-to-left text genuinely
usable in a terminal.

### Added
- **Right-to-left rendering.** Hebrew rows are mirrored and right-anchored, per
UAX #9. The direction is resolved per row, so Latin rows are untouched.
- **RTL/LTR toggle** in the window titlebar, applied to live terminals without a
restart.
- **Bidi-aware cursor.** The cursor is placed by visual position, so it sits
beside the Hebrew it follows instead of at its logical column.
- **Mirrored glyphs (UAX #9 rule L4).** A mirrorable character on a
right-to-left row renders as its counterpart, so a prompt chevron points into
the text and brackets face the right way. All 428 pairs come from the Unicode
Character Database.
- **Direction-aware arrow keys.** On a mirrored row the horizontal arrows follow
the text, including word-wise (alt) and line-wise (cmd) movement, which are
keybindings rather than encoded keys. Pane-focus shortcuts are deliberately
left alone, since panes follow the physical screen. Latin rows behave exactly
as before.
- **Twelve Hebrew faces**, selectable from Settings > Terminal and applied
without a restart: Noto Sans Hebrew, Miriam Libre, Alef, Heebo, Assistant, IBM
Plex Sans Hebrew, Rubik, Varela Round, Frank Ruhl Libre, David Libre, Secular
One and Cousine.
- **Cmd+Z** undoes the last edit on the line being typed.

### Notes
- A terminal gives every Hebrew letter one cell, and every Hebrew face measured
varies 18-25% in advance width across the alphabet, which reads as broken
spacing. Each bundled face is therefore normalised to a uniform 0.600em
advance by `scripts/make-hebrew-font.py`, so choosing one changes letterforms
only and never the grid. Combining marks keep their zero advance.
- Cmd+Z sends readline's undo, so it undoes an edit on the current line. It
cannot un-run a submitted command and does not affect terminal output.
- Cmd+Z is a ghostty keybind and is not yet remappable from Settings.


## [0.64.20] - 2026-07-19

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ public struct TerminalCatalogSection: SettingCatalogSection {
userDefaultsKey: "terminal.showScrollBar"
)

/// Hebrew fallback face for the terminal.
public let hebrewFont = DefaultsKey<HebrewFontFace>(
id: HebrewFontFace.settingsPath,
defaultValue: HebrewFontFace.defaultFace,
userDefaultsKey: HebrewFontFace.settingsPath
)

public let copyOnSelect = DefaultsKey<Bool>(
id: "terminal.copyOnSelect",
defaultValue: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import Foundation

/// Hebrew fallback face used by the terminal (Ivrix).
///
/// Every option is the same source family put through
/// `scripts/make-hebrew-font.py`: subset to Hebrew and normalised to a uniform
/// 0.600em advance matching the Latin cell. Switching therefore changes
/// letterforms only, never the terminal grid.
public enum HebrewFontFace: String, CaseIterable, Sendable, SettingCodable {
case noto
case miriam
case alef
case heebo
case assistant
case plex
case rubik
case varela
case frankRuhl
case david
case secular
case cousine

public static let defaultFace: HebrewFontFace = .noto

/// Settings path and `UserDefaults` key for the selected face.
public static let settingsPath = "terminal.hebrewFont"

/// Bundled family name, as written into the font's name table.
public var familyName: String {
switch self {
case .noto: return "Ivrix He Noto"
case .miriam: return "Ivrix He Miriam"
case .alef: return "Ivrix He Alef"
case .heebo: return "Ivrix He Heebo"
case .assistant: return "Ivrix He Assistant"
case .plex: return "Ivrix He Plex"
case .rubik: return "Ivrix He Rubik"
case .varela: return "Ivrix He Varela"
case .frankRuhl: return "Ivrix He FrankRuhl"
case .david: return "Ivrix He David"
case .secular: return "Ivrix He Secular"
case .cousine: return "Ivrix He Cousine"
}
}

/// Upstream face name. Proper nouns, so these are not localized.
public var displayName: String {
switch self {
case .noto: return "Noto Sans Hebrew"
case .miriam: return "Miriam Libre"
case .alef: return "Alef"
case .heebo: return "Heebo"
case .assistant: return "Assistant"
case .plex: return "IBM Plex Sans Hebrew"
case .rubik: return "Rubik"
case .varela: return "Varela Round"
case .frankRuhl: return "Frank Ruhl Libre"
case .david: return "David Libre"
case .secular: return "Secular One"
case .cousine: return "Cousine"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public struct TerminalSection: View {
@State private var sessionContentAlignment: DefaultsValueModel<SessionContentAlignment>
@State private var scrollBar: DefaultsValueModel<Bool>
@State private var copyOnSelect: DefaultsValueModel<Bool>
@State private var hebrewFont: DefaultsValueModel<HebrewFontFace>
@State private var autoResume: DefaultsValueModel<Bool>
@State private var hibernation: DefaultsValueModel<Bool>
@State private var idleSeconds: DefaultsValueModel<Double>
Expand All @@ -49,6 +50,7 @@ public struct TerminalSection: View {
_sessionContentAlignment = State(initialValue: DefaultsValueModel(store: defaultsStore, key: catalog.terminal.sessionContentAlignment))
_scrollBar = State(initialValue: DefaultsValueModel(store: defaultsStore, key: catalog.terminal.showScrollBar))
_copyOnSelect = State(initialValue: DefaultsValueModel(store: defaultsStore, key: catalog.terminal.copyOnSelect))
_hebrewFont = State(initialValue: DefaultsValueModel(store: defaultsStore, key: catalog.terminal.hebrewFont))
_autoResume = State(initialValue: DefaultsValueModel(store: defaultsStore, key: catalog.terminal.autoResumeAgentSessions))
_hibernation = State(initialValue: DefaultsValueModel(store: defaultsStore, key: catalog.terminal.agentHibernationEnabled))
_idleSeconds = State(initialValue: DefaultsValueModel(store: defaultsStore, key: catalog.terminal.agentHibernationIdleSeconds))
Expand Down Expand Up @@ -77,6 +79,7 @@ public struct TerminalSection: View {
sessionContentAlignment,
scrollBar,
copyOnSelect,
hebrewFont,
autoResume,
hibernation,
idleSeconds,
Expand Down Expand Up @@ -310,6 +313,32 @@ public struct TerminalSection: View {
.accessibilityIdentifier("SettingsSessionContentAlignmentPicker")
}
SettingsCardDivider()
SettingsCardRow(
configurationReview: .json(HebrewFontFace.settingsPath),
String(localized: "settings.terminal.hebrewFont", defaultValue: "Hebrew Font"),
subtitle: String(
localized: "settings.terminal.hebrewFont.subtitle",
defaultValue: "Face used for Hebrew text. Every option is normalised to the Latin cell width, so this changes letterforms only."
),
controlWidth: 250
) {
Picker(
"",
selection: Binding(
get: { hebrewFont.current },
set: { hebrewFont.set($0) }
)
) {
ForEach(HebrewFontFace.allCases, id: \.self) { face in
Text(face.displayName).tag(face)
}
}
.labelsHidden()
.pickerStyle(.menu)
.frame(width: 210)
.accessibilityIdentifier("SettingsHebrewFontPicker")
}
SettingsCardDivider()
SettingsCardRow(
configurationReview: .json("terminal.scrollSpeed"),
String(localized: "settings.terminal.scrollSpeed", defaultValue: "Scroll Speed"),
Expand Down
97 changes: 84 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,79 @@
<h1 align="center">cmux</h1>
<p align="center">A Ghostty-based macOS terminal with vertical tabs and notifications for AI coding agents</p>
<h1 align="center">Ivrix</h1>
<p align="center"><strong>A macOS terminal that actually gets Hebrew right.</strong></p>
<p align="center">Real right-to-left (RTL) and bidirectional (BiDi) text support, built on <a href="https://ghostty.org">Ghostty</a>.<br/>
A fork of <a href="https://github.com/manaflow-ai/cmux">cmux</a>.</p>

<p align="center" dir="rtl"><strong>מסוף (טרמינל) ל־macOS עם תמיכה אמיתית בעברית ובכתיבה מימין לשמאל</strong></p>

<p align="center">
<a href="https://github.com/manaflow-ai/cmux/releases/latest/download/cmux-macos.dmg">
<img src="./docs/assets/macos-badge.png" alt="Download cmux for macOS" width="180" />
<a href="https://github.com/DananzMolt/Ivrix/releases/latest">
<img src="./docs/assets/macos-badge.png" alt="Download Ivrix for macOS" width="180" />
</a>
</p>

<p align="center">
English | <a href="README.ja.md">日本語</a> | <a href="README.vi.md">Tiếng Việt</a> | <a href="README.zh-CN.md">简体中文</a> | <a href="README.zh-TW.md">繁體中文</a> | <a href="README.ko.md">한국어</a> | <a href="README.de.md">Deutsch</a> | <a href="README.es.md">Español</a> | <a href="README.fr.md">Français</a> | <a href="README.it.md">Italiano</a> | <a href="README.da.md">Dansk</a> | <a href="README.pl.md">Polski</a> | <a href="README.ru.md">Русский</a> | <a href="README.bs.md">Bosanski</a> | <a href="README.ar.md">العربية</a> | <a href="README.no.md">Norsk</a> | <a href="README.pt-BR.md">Português (Brasil)</a> | <a href="README.th.md">ไทย</a> | <a href="README.tr.md">Türkçe</a> | <a href="README.km.md">ភាសាខ្មែរ</a> | <a href="README.uk.md">Українська</a>
<a href="https://github.com/DananzMolt/Ivrix/releases/latest"><img src="https://img.shields.io/github/v/release/DananzMolt/Ivrix?label=release&color=4c71f2" alt="Latest release" /></a>
<img src="https://img.shields.io/badge/macOS-universal-555?logo=apple" alt="macOS universal" />
<img src="https://img.shields.io/badge/notarized-Apple-555?logo=apple" alt="Notarized by Apple" />
</p>

<p align="center">
<a href="https://x.com/manaflowai"><img src="https://img.shields.io/badge/@manaflow-555?logo=x" alt="X / Twitter" /></a>
<a href="https://discord.gg/xsgFEVrWCZ"><img src="https://img.shields.io/badge/Discord-555?logo=discord" alt="Discord" /></a>
<a href="https://github.com/manaflow-ai/cmux"><img src="https://img.shields.io/github/stars/manaflow-ai/cmux?style=flat&logo=github&label=stars&color=4c71f2" alt="GitHub stars" /></a>
</p>
## Why Ivrix

Terminal emulators are built left-to-right. Hebrew and Arabic mostly "work" in the
sense that the characters appear, but the moment you actually edit a line the
illusion breaks: the cursor lands somewhere else, arrow keys move the wrong way,
and the prompt arrow points away from your text.

Ivrix fixes that layer properly, following the Unicode bidirectional algorithm
([UAX #9](https://unicode.org/reports/tr9/)):

- **Right-to-left rendering.** Hebrew lines are mirrored and right-anchored. The
direction is resolved **per line**, so English lines are untouched and mixed
Hebrew/English content behaves correctly in both.
- **RTL/LTR toggle** in the titlebar, applied to open terminals without a restart.
- **A cursor that follows the text.** Placed by visual position, so it sits beside
the Hebrew it belongs to instead of stranded at the left edge.
- **Mirrored glyphs (UAX #9 rule L4).** On a Hebrew line the prompt chevron points
into the text and brackets face the right way. All 428 mirror pairs come from the
Unicode Character Database.
- **Direction-aware arrow keys.** On a Hebrew line the arrows follow the text,
including word-wise (⌥) and line-wise (⌘) movement. On English lines they behave
exactly as always.
- **Twelve Hebrew fonts** built in, switchable live from *Settings → Terminal →
Hebrew Font*.

### Hebrew fonts that fit the grid

A terminal gives every Hebrew letter exactly one cell, and every Hebrew typeface we
measured varies **18–25%** in advance width across the alphabet. Dropping one in
as-is leaves ragged gaps between letters. Every bundled face is normalised to a
uniform cell width, so switching changes letterforms only and never the grid.
Nikud keep zero width and stack on the letter instead of taking a cell of their own.

Included: Noto Sans Hebrew (default), Miriam Libre, Alef, Heebo, Assistant, IBM Plex
Sans Hebrew, Rubik, Varela Round, Frank Ruhl Libre, David Libre, Secular One and
Cousine.

## Install

[**Download the latest release**](https://github.com/DananzMolt/Ivrix/releases/latest),
open the DMG and drag Ivrix to Applications.

Signed and notarized by Apple, so it opens without a Gatekeeper warning. Universal
binary — Apple Silicon and Intel.

## Everything else, from cmux

Ivrix is a fork of [cmux](https://github.com/manaflow-ai/cmux) and inherits all of
it: vertical tabs, notification rings for AI coding agents, splits, workspaces, the
browser pane and the CLI. The upstream feature tour follows below.

<p align="center">
<img src="./docs/assets/main-first-image.png" alt="cmux screenshot" width="900" />
English | <a href="README.ja.md">日本語</a> | <a href="README.vi.md">Tiếng Việt</a> | <a href="README.zh-CN.md">简体中文</a> | <a href="README.zh-TW.md">繁體中文</a> | <a href="README.ko.md">한국어</a> | <a href="README.de.md">Deutsch</a> | <a href="README.es.md">Español</a> | <a href="README.fr.md">Français</a> | <a href="README.it.md">Italiano</a> | <a href="README.da.md">Dansk</a> | <a href="README.pl.md">Polski</a> | <a href="README.ru.md">Русский</a> | <a href="README.bs.md">Bosanski</a> | <a href="README.ar.md">العربية</a> | <a href="README.no.md">Norsk</a> | <a href="README.pt-BR.md">Português (Brasil)</a> | <a href="README.th.md">ไทย</a> | <a href="README.tr.md">Türkçe</a> | <a href="README.km.md">ភាសាខ្មែរ</a> | <a href="README.uk.md">Українська</a>
</p>

<p align="center">
<a href="https://www.youtube.com/watch?v=i-WxO5YUTOs">▶ Demo video</a> · <a href="https://cmux.com/blog/zen-of-cmux">The Zen of cmux</a>
<img src="./docs/assets/main-first-image.png" alt="Ivrix screenshot" width="900" />
</p>

## Features
Expand Down Expand Up @@ -93,7 +144,11 @@ Sidebar shows git branch, linked PR status/number, working directory, listening
- **Keyboard shortcuts** — [Extensive shortcuts](https://cmux.com/docs/keyboard-shortcuts) for workspaces, splits, browser, and more
- **Open source** — Free and GPL-licensed

## Install
## Installing upstream cmux

The links in this section install **cmux**, not Ivrix. For Ivrix, use the
[Ivrix release](https://github.com/DananzMolt/Ivrix/releases/latest) linked at the
top of this page.

### DMG (recommended)

Expand Down Expand Up @@ -445,3 +500,19 @@ for portions for which Manaflow controls the necessary rights. They do not
relicense third-party material or outside contributions for which Manaflow
lacks a separate grant. See [LICENSE](LICENSE) for the exact scope and contact
[founders@manaflow.com](mailto:founders@manaflow.com) for details.

---

## About

**Ivrix** is a Hebrew terminal for macOS: a right-to-left (RTL) terminal emulator with
full bidirectional text (BiDi) support, Hebrew fonts, and a bidi-aware cursor and
keyboard navigation. It is a fork of [cmux](https://github.com/manaflow-ai/cmux),
which is built on [Ghostty](https://ghostty.org).

If you searched for a Hebrew terminal, an RTL terminal for Mac, Hebrew support in
iTerm/Terminal.app/Ghostty, or תמיכה בעברית בטרמינל — this is what Ivrix is for.

Upstream cmux is by [manaflow-ai](https://github.com/manaflow-ai/cmux); Ghostty is by
[Mitchell Hashimoto](https://ghostty.org). Bundled Hebrew fonts ship under the SIL
Open Font License with their original attribution.
Binary file added Resources/Fonts/IvrixHeAlef-Bold.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeAlef-BoldItalic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeAlef-Italic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeAlef-Regular.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeAssistant-Bold.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeAssistant-BoldItalic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeAssistant-Italic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeAssistant-Regular.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeCousine-Regular.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeDavid-Regular.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeFrankRuhl-Bold.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeFrankRuhl-BoldItalic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeFrankRuhl-Italic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeFrankRuhl-Regular.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeHeebo-Bold.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeHeebo-BoldItalic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeHeebo-Italic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeHeebo-Regular.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeMiriam-Bold.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeMiriam-BoldItalic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeMiriam-Italic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeMiriam-Regular.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeNoto-Bold.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeNoto-BoldItalic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeNoto-Italic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeNoto-Regular.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHePlex-Bold.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHePlex-BoldItalic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHePlex-Italic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHePlex-Regular.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeRubik-Bold.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeRubik-BoldItalic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeRubik-Italic.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeRubik-Regular.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeSecular-Regular.ttf
Binary file not shown.
Binary file added Resources/Fonts/IvrixHeVarela-Regular.ttf
Binary file not shown.
Binary file removed Resources/Fonts/MiriamMonoCLM-Bold.ttf
Binary file not shown.
Binary file removed Resources/Fonts/MiriamMonoCLM-BoldOblique.ttf
Binary file not shown.
Binary file removed Resources/Fonts/MiriamMonoCLM-Book.ttf
Binary file not shown.
Binary file removed Resources/Fonts/MiriamMonoCLM-BookOblique.ttf
Binary file not shown.
Loading