* refactor(editor): show the preview affordance only after rich mode faults
Proactively classifying every Source-view markdown tab scanned content
nobody was looking at in Rich mode. The toggle and banner now read a
stored per-tab fault instead, recorded once Rich mode actually falls
back, so Source-view tabs never scan speculatively.
* docs(editor): state the fault-tracking constraints in present tense
* fix(editor): register the open-preview banner string
verify:localization-extraction failed because the rich-markdown
fallback banner's "Open preview" button called translate() with a
key never added to en.json.
* fix(editor): document isolated store harness cast
* fix(editor): stop the rich markdown editor from mangling dollar-heavy files
Opening a markdown file full of dollar amounts in rich mode reformatted it
on load, and any save then rewrote the whole file:
- marked emits an `escape` inline token for `\$`, `\*`, `\_`, `\[`; Tiptap's
markdown parser has no case for it, so the escaped character was deleted
from the document as soon as the file opened. The marked facade now
rewrites escape tokens to text tokens, in place, so table cells keep them
too.
- the inline-math tokenizer treated any same-line `$...$` pair as LaTeX, so
"from $10 to $20" or "entered 2021 at $0" became a KaTeX atom whose text
was trimmed. It now requires Pandoc-style boundaries: both `$` must touch
the formula and the closing `$` must not be followed by a digit.
- the source-preserving reconcile mis-applied any edit at the end of a file
whose source ends with a newline: getMarkdown never emits one, so the
end-of-document hunk landed one character late, failed the round-trip
proof, and fell back to canonical output for the entire file, rewriting
every `\$`, `&` and table in it. It now patches the newline-stripped
bodies and re-attaches the source's trailing newline run.
* fix(editor): round-trip escapes as atoms and narrow the end-of-file reconcile
Review findings on the first commit, all reproduced with the real serializer:
- Rewriting marked's `escape` token to text kept the character on load but
the serializer never re-escapes, so `\# x` came back as `# x` and became a
heading on the next open; `\$x\$` became inline math. Replace the facade
rewrite with an inline atom node that owns the escape token and renders
`\` + character, so escapes round-trip byte for byte in every container.
- The body-strip reconcile ran for every trailing-newline shape. A source
ending in a blank line parses to a trailing empty paragraph, so canonical
ends in `\n\n` too; stripping and re-attaching there duplicated the
paragraph, failed the branch-6 proof, and canonicalized the whole file.
Only strip when the source ends in exactly one newline that canonical
lacks; every other shape patches correctly whole, as on main.
- Canonical fallbacks now keep the source's single trailing newline.
- The inline-math regex allowed neither a soft line break inside a formula
nor a trailing LaTeX line break; both are valid and upstream accepted
them. Drop the newline and backslash exclusions and the dead `.trim()`.
* fix(editor): carry escapes as a mark so emphasis and links stay continuous
Second-round review of the atom approach: Tiptap's serializer closes every
active mark before a non-text inline node and reopens it after, so an
escape atom inside bold split the run (`**cost \$5 total**` came back as
`**cost **\$**5 total**`, which no longer parses as bold), a link containing
an escape became two links, and find/replace was disabled on any match
touching an escape because atoms are read-only.
The escape is now a non-inclusive mark on ordinary text. A mark's markdown
is one prefix for the whole run, so `getMarkdown` is wrapped to rewrite
marked text as `\X` per character before the manager serializes; inside a
code mark the character is emitted bare, and `& < >` are left to the
serializer's entity encoding. The mark is registered after `Markdown`
because that extension's onBeforeCreate installs the getMarkdown being
wrapped.
Also restores tiptap-marked-facade.ts to the base branch: the previous
commit meant to remove the escape-token rewrite there but restored the
file from the branch's own HEAD, leaving a dead override in the diff.
* fix(editor): retry the whole-text patch and refuse escaped dollars as math closers
Second-round review findings that survived the mark rewrite:
- A source whose last line is whitespace only (`Last.\n \n`) has a trailing
run of one newline, so the body strip ran, landed the end hunk after the
spaces, failed the branch-6 proof, and canonicalized the whole file where
the base branch had patched it correctly. The body strip is now the first
attempt and the whole-text patch the second, so no file does worse than
before; the extra round trip only runs when the first attempt fails.
- `costs $5 to \$x here` parsed as inline math with latex `5 to \`, because
the tokenizer accepted an escaped `\$` as the closing delimiter. Escaped
characters are now consumed inside the formula and cannot close it.
- The escaped-dollar test passed on the base branch for the wrong reason
(the `\$` was deleted before the math tokenizer ran); it now also asserts
the bytes round-trip, and a new test pins escapes as ordinary searchable
text.
* fix(editor): keep table pipes, link destinations and display math faithful to source
Pre-existing serializer defects the review catalogued, now fixed in one
place: a serializer-fidelity extension that wraps getMarkdown and rewrites
the document JSON into its source form before Tiptap serializes it. The
escaped-character mark's per-character expansion moves there too.
- `\|` inside a table cell: marked unescapes it per cell before inline
lexing, so the cell held a bare `|` that split the row on the next load
and truncated it. Text inside tableCell/tableHeader now escapes `|`,
code spans included, since the cell split happens before code lexing.
- `\)` inside a link or image destination came back bare and ended the
destination early. Parentheses in destinations are escaped again.
(Angle-bracket destinations are not an option: Orca's raw-HTML pass would
placeholder them before parsing.) Image alt text escapes `[ ] \`, and
link/image titles escape `"`.
- `$$` anywhere in a paragraph split it, because marked ends a paragraph
wherever a block tokenizer's `start` points and upstream used
`indexOf('$$')`. Display math now only starts at a line start.
# Conflicts:
# src/renderer/src/components/editor/rich-markdown-extensions.ts
* fix(editor): accept indented display math with inner dollars, escape pipes in cell attributes
Review comments on the previous commit:
- Display math whose body holds a `$` (`$$\n\$5\n$$`) fell back to prose
because the body pattern refused every dollar; it now runs to the
closing `$$`.
- Display math indented by spaces or a tab no longer opened, because the
line-start check wanted `$$` right after the newline. The start pattern
tolerates the indent, and points marked at the newline rather than the
first `$` so the indent does not stay behind in the paragraph.
- `|` inside a link or image attribute in a table cell was still written
bare, so the row split on the next load. The cell context now reaches
destinations, titles and alt text as well as text.
# Conflicts:
# src/renderer/src/components/editor/rich-markdown-extensions.ts
* style(editor): format merged markdown extensions
* fix(editor): remove duplicate block math tokenizer
* fix(editor): restore inline math import
* fix(editor): avoid duplicate escape extension and preserve EOF shape
* fix(editor): keep existing source-preserving serializer active
* fix(editor): preserve baseline link and escape serializer behavior
* chore(editor): satisfy merged markdown lint rules
* fix(editor): retain escaped punctuation metadata during serialization
* fix(editor): keep escaped mark fallback neutral
* fix(editor): route marked escape tokens through rich markdown mark
* chore(editor): satisfy escape mark lint
* fix(editor): preserve escaped markdown entities through fast serialization
* fix(editor): normalize escaped dollar amounts
* chore(editor): satisfy serializer lint
* fix(editor): preserve nested markdown destinations and escaped entities
* chore(editor): satisfy destination serializer lint
* fix(editor): force source serialization for escaped entity marks
* fix(editor): retain balanced markdown destinations
* fix(editor): preserve escaped mark serialization in plain blocks
* fix(editor): normalize plain escaped money text
* fix(editor): keep table and display math dollar escapes
* chore(editor): remove unused escape helper
* fix(editor): retain raw link and image destinations
* chore(editor): satisfy raw destination lint
* fix(editor): admit comments inside image alt text
* fix(editor): keep plain money escapes out of math recovery
* fix(editor): preserve currency escapes in tables and formatted text
* chore(editor): remove diagnostics and satisfy serializer lint
* fix(editor): scope currency escape recovery to escaped source
* fix(editor): scope escape encoding to text nodes
* test(editor): keep stored preview fault aligned with saved content
* test(editor): cover destination repairs and remove unused serializer (#21532)
* fix(editor): honor edited markdown destinations
* refactor(editor): remove unused markdown serializer shim
* test(editor): cover saved preview and destination repairs
* test(editor): detect raw destination escape regressions
* test(editor): verify save position across hidden Electron clients
* perf(editor): scan fence lines without substring allocations
* fix(editor): match fence suffix whitespace rules
* fix(editor): match fence suffix whitespace rules
* fix(editor): match parser fence whitespace
* fix(editor): keep reconciliation cache contract
* fix(editor): preserve rich-mode validation option
* test(editor): cover source-mode validation skip
* fix(editor): keep rich mode classifier within lint limit
* test(editor): select rich copy ranges through Playwright
* fix(editor): wrap long rich markdown code lines
* test(e2e): retry rich selection before clipboard assertions
---------
Co-authored-by: Frederic Barthelemy <git@fbartho.com>
Co-authored-by: averydev <averybloom@gmail.com>
Orca
中文 · 日本語 · 한국어 · Español · Français · Português
The AI Orchestrator for 100x builders.
Run Codex, ClaudeCode, OpenCode or Pi side-by-side — each in its own worktree, tracked in one place.
Download Orca
Features
Also in the box:
- Quick open — Search across worktrees, files, agents, commands, and repo context without leaving your flow.
- Account switcher & usage tracking — See Claude and Codex usage and rate-limit resets, and hot-swap accounts without re-logging in.
- Rich repo previews — Preview Markdown, images, PDFs, and repo docs in the workspace.
- Computer Use — Let agents operate desktop apps and visible UI when a workflow needs real interaction.
- Notifications and unread state — Know when an agent finishes or needs attention, then mark threads unread to come back later.
- And many, many more — we ship daily, so this list is perpetually behind. The changelog is the real feature list.
Supported Agents
Works with any CLI agent — if it runs in a terminal, it runs in Orca.
Claude Code
Codex
Grok
Cursor
GitHub Copilot
OpenCode
MiMo Code
Amp
OpenClaude
Antigravity
Pi
oh-my-pi
Hermes Agent
Devin
Goose
Auggie
Autohand Code
Charm
Cline
Codebuff
Command Code
Continue
Droid
Kilocode
Kimi
Kiro
Mistral Vibe
Qwen Code
Rovo Dev
+ any CLI agent
Install
Desktop — macOS, Windows, Linux
- Download from onOrca.dev
- Or grab a build directly: macOS Apple Silicon · macOS Intel · Windows (.exe) · Linux AppImage · All builds
- Running
orca serveon a headless Linux server? See the headless Linux server guide.
Or via a package manager:
# macOS (Homebrew)
brew install --cask stablyai/orca/orca
# Arch Linux (AUR) — or stably-orca-git to build from source
yay -S stably-orca-bin
Mobile Companion — iOS, Android
Pair with your desktop app to monitor and steer your agents from your phone.
- iOS: Download on the App Store or join TestFlight
- Android: Download APK 0.0.48 · Install guide
Community & Support
-
Discord: Join the community on Discord.
-
Twitter / X: Follow @orca_build for updates and announcements.
-
WeChat: Scan to join the Orca community WeChat group 8. Group 8 may be full; if so, scan the Group 9 QR code instead.
-
Feedback & Ideas: We ship fast. Missing something? Request a new feature.
-
Privacy: See the privacy & telemetry docs for what anonymous usage data Orca collects and how to opt out.
-
Show Support: Star this repo to follow along with our daily ships.
Developing
Want to contribute or run locally? See our CONTRIBUTING.md guide.
The relay that pairs the mobile app with a desktop host is also in this repository under
cloud/, with a separate pnpm workspace and setup guide.
Signed Builds
Windows code signing sponored/provided by SignPath.io, certificate by SignPath Foundation.
License
Orca is free and open source under the MIT License.












