DSH RTL + Vazirmatn
English | فارسی
A persistent DeepSeek Harness plugin that adds right-to-left layout and the Vazirmatn typeface to the web UI — without forking the harness.
Why
The DSH web UI ships as a left-to-right, system-font interface. For Persian — or any RTL language — that means mirrored layouts and font inconsistencies out of the box. This plugin is a self-contained, reversible layer: one loader row, the font bundled inside the client bundle, no external font CDN, and no edits to DSH itself.
Features
- Three direction modes, cycled from a sidebar switch and remembered per browser: full RTL, chat-only RTL, and LTR.
- Vazirmatn is bundled (variable, weights 100–900, WOFF2 inlined in
client.js), so Persian text renders identically on every machine, offline, without a flash of missing font. - Code stays left-to-right: code blocks, inline code, terminal output, and editors keep their natural reading order inside an RTL transcript.
- Content follows its language: every chat row and text block is RTL for Persian and LTR for English. The direction is decided by the share of RTL letters in the block — not by its first character — so an English tool log stays left-aligned and a Persian sentence that opens with an English term stays right-aligned, in every layout mode.
- Chat-only mode is surgical: it mirrors the transcript and the composer's text field through stable host hooks, and deliberately leaves the conversation header and the composer's button row untouched.
- RTL repairs for host chrome that is positioned physically: markdown indents, the composer's trailing-control auto margin, text padding, scrollbar clearance, and the Windows titlebar sidebar buttons.
- Clean lifecycle: disabling the bundle removes its stylesheet, the
dirattribute, and the mode marker, restoring the previous state.
Modes
| Mode | What mirrors |
|---|---|
RTL |
The whole interface (dir="rtl" on the document). |
Chat RTL |
The message transcript and the composer text field only. |
LTR |
Nothing — Vazirmatn still applies. |
The switch sits beside Settings in the sidebar footer; each click advances the mode. The choice is
stored in localStorage under @local/dsh-rtl-vazirmatn:mode.
Layout mode and content direction are independent: the mode decides how the surrounding chrome is mirrored, while each transcript block picks RTL or LTR from its own text in every mode.
Screenshot
The mirrored chat header in full RTL mode:

Install
Requires a DeepSeek Harness build with profile support (the desktop app or dsh web).
- Clone this repository into a stable folder.
- In DSH, open Settings → Plugins and install the bundle from that folder. When working with
the agent, the equivalent is the
plugin_managerinstall action with the folder path. - The RTL layout with Vazirmatn row appears and the interface applies the plugin immediately. If a previously installed copy was replaced, reload the page once so the fresh client bundle is fetched.
Manual alternative: add a link: dependency for this folder to the profile package.json and list
the package in dsh.profile.bundles, then restart DSH.
How it works
Direction
Full mode sets dir="rtl" on <html>; flex rows, inline flow, form controls, and scrollbars
mirror from it. Chat-only mode never touches the document: it applies direction: rtl to two host
elements that stay stable across DSH releases:
[data-chat-flow]— the message column;[data-input-scroll]— the composer's text field.
Content direction
Inside the transcript, each chat row ([data-chat-node-key]), trajectory row
([data-trajectory-row-key]), step row, and markdown block (p, li, headings, blockquotes,
table cells) receives its own dir. A small mutation observer re-evaluates blocks as messages
stream in and compares the number of RTL-script letters (Arabic/Persian, Hebrew, Syriac) with the
number of Latin letters: the block is RTL when RTL letters are at least half of them. The first
character never decides, so second grep for «تمام عرض» stays LTR while
فایل را با npm run build بساز is RTL. Code, inline code, terminals, and editors are excluded from
the scan, and the composer text field follows its draft the same way.
Typeface
client.js embeds a variable Vazirmatn WOFF2 as a data: URI and overrides the theme's text-font
variables (--dsh-font-family-text, --dsw-font-family). Code and terminal font variables are
left alone, so monospace surfaces keep their stacks. Nothing is fetched at runtime.
RTL repairs
A few host surfaces are positioned with physical margin-left/left values. The plugin targets
them by their shipped CSS-module class names for the composer row and the Windows titlebar, and by
stable data attributes elsewhere. If DSH rebuilds those class names, the affected rule simply stops
matching and the layout falls back to the plain mirrored default instead of breaking.
Lifecycle
Everything is registered through the plugin context: the stylesheet is a package-owned <style>
element removed on dispose, and the dir / data-dsh-rtl attributes are restored to their
pre-activation values.
Project layout
| Path | Role |
|---|---|
client.template.js |
Browser plugin source; contains the font placeholder. |
client.js |
Generated bundle served by DSH under /plugins, with the font inlined. |
index.js |
Host half of the bundle; registers nothing. |
cordis.patch.yml |
Loader row inserted by the bundle. |
locale/ |
Plugin Manager display metadata (en, fa). |
assets/Vazirmatn-Variable.woff2 |
Source font. |
tools/build-client.mjs |
Dependency-free build step (PowerShell alternative included). |
docs/ |
Screenshots. |
Development
node tools/build-client.mjs
node --check client.js
client.js is generated: edit client.template.js (including the CSS inside it) and rebuild. After
rebuilding an installed copy, restart the loader entry — disable and enable the plugin, or reload
the page — so the browser fetches the fresh bundle.
The build has no dependencies; it only inlines the WOFF2 as base64.
Compatibility
Built and tested against DeepSeek Harness 0.2.2-rc.1 (desktop, Windows, Chromium). The bundle
uses the documented client-plugin contract: a dsh.client manifest, a ./client export, and the
window.__ModuleLoader__.load factory.
License
MIT © 2026 Pourii. The bundled Vazirmatn font is © Saber Rastikerdar and contributors, licensed
under SIL OFL 1.1 — see OFL.txt and AUTHORS.txt.
No comments yet. Be the first to write one.