BiDiSense is a collection of paste-and-run snippets that make coding agents detect script direction and render RTL and LTR correctly. Cursor is the first host. The current snippet watches Agent messages, the live prompt, user history, Markdown Preview, lists, and tables independently, while keeping code blocks left-to-right.
Built for people who write mixed bidirectional text (Persian, Arabic, Hebrew, and English) inside AI coding tools whose UI assumes a single direction.
Note
Unofficial. BiDiSense is not affiliated with Cursor or Anysphere. It injects CSS and observers through Chromium DevTools snippets, so a host UI update can break selectors until the snippet is adjusted.
- Per-message direction — each Agent reply is scored on its own script and flipped to RTL or LTR without forcing the whole thread.
- Live prompt — the composer follows the script you are typing, including IME composition.
- User history — previous human messages keep the direction they were written in.
- Markdown Preview — document body, lists, and tables are detected separately.
- Code stays LTR — fenced blocks, inline code, and Monaco/editor surfaces keep
direction: ltr. - Safe re-run — running the snippet again tears down previous observers, listeners, and injected styles before applying a new runtime.
- Readable RTL type — Vazirmatn is applied to Agent and preview prose (install the font on your system for best results).
- Open Cursor.
- Open Developer Tools: Help → Toggle Developer Tools.
- Open the Sources tab.
- Open Snippets in the left sidebar (use the
>>overflow menu if it is hidden). - Click New snippet and name it, for example
cursor-smart-rtl. - Paste the entire
cursor.jsfile. - Save:
Ctrl+S(Linux/Windows) orCmd+S(macOS). - Run it: right-click inside the snippet and choose Run.
The snippet stays saved in DevTools, but you must run it again after Cursor restarts or the window reloads unless you add a separate startup hook.
A purple console banner (RTL Fix + Smart Preview + Smart Agent Applied) confirms the runtime is active.
Re-run is idempotent. To remove the effect without restarting Cursor, reload the window (Developer: Reload Window) or close DevTools after a full Cursor restart so the injected style and observers are gone.
The snippet injects a stylesheet, then a MutationObserver plus input listeners:
- Collect strong Arabic vs Latin characters in the relevant node.
- Assign
data-cursor-smart-*attributes (rtl/ltr) per surface. - CSS
[data-…]rules setdirectionand alignment. Code selectors win with!importantso editors never flip.
Selector names track Cursor's DOM (markdown-root, aislash-editor-input, tiptap.ProseMirror, …). When Cursor ships a UI rewrite, those names are the first thing to update.
| Host | Status |
|---|---|
| Cursor (Chromium DevTools snippets) | Supported (cursor.js v7.0.0) |
| VS Code, Windsurf, other agents | Planned as additional snippets |
Font: Vazirmatn is referenced by name. Install it locally if RTL prose looks like the system fallback.
cursor.js Cursor DevTools snippet
media/ README logos
docs/github-rulesets.md Recommended GitHub branch rules
.cursor/rules/ Agent workflow for this repo
.github/ CI, PR template, issue templates, CODEOWNERS
Contributions are welcome. Please read the Contributing Guide before opening an issue or pull request.
Short version:
- Do not push to
master. Open a PR. - Branch names:
feat/001-short-description(alsofix,bugfix,imp,docs,chore, …). - Sign commits with GPG as
Emad Helmi <s.emad.helmi@gmail.com>. - Keep
cursor.jsa single pasteable file.
See SECURITY.md for how to report a vulnerability privately.
MIT © 2026 Emad Helmi
If this project is helpful, you may wish to give it a 🌟