Back to home@haythamat

dsh-client-ui-rtl

Right-to-left text direction for the DeepSeek Harness Web client

Stars
0
Language
JavaScript
Created
Aug 27, 2026
Updated
Aug 27, 2026
GitHub repo

Introduction

dsh-client-ui-rtl

Right-to-left text direction for the DeepSeek Harness Web client.

The client renders left-to-right by default. Arabic, Hebrew, Persian, Urdu and other right-to-left content therefore arrives correct as text but wrong on screen: bullets sit on the left, table columns run the wrong way, and any sentence mixing Latin and RTL words is reordered against its meaning.

This package marks right-to-left content as it renders, and leaves everything else alone.

Before and after

An Arabic answer mixing English technical terms:

BeforeAfter
Arabic answer rendered left-to-right, bullets and table misalignedThe same answer rendered right-to-left

A short prompt opening with a Latin product name — the case dir="auto" gets wrong:

BeforeAfter
Arabic prompt reordered because it begins with an English wordThe same prompt rendered right-to-left

Install

dsh plugin --profile web add github:haythamat/dsh-client-ui-rtl

Restart dsh web afterwards. The package ships its own patch layer, so no configuration file needs editing.

How direction is decided

Direction is decided by script dominance, not by the first strong character in the block. dir="auto" reads only the first strong character, which fails on technical writing in Arabic and Hebrew — a sentence opening with a product name such as Git or GitHub is laid out left-to-right and every word after it is misordered.

Instead, each element's text is weighed by words, not characters. Words matter because right-to-left words are short while Latin technical terms are long: اشرح لي ال Agentic AI is eight Arabic characters against nine Latin ones, but three Arabic words against two Latin ones. When right-to-left words are at least as common, the element is marked dir="rtl". Blocks with no right-to-left words are never touched, so a bilingual session keeps its English messages left-to-right.

Elements are judged on the text they hold directly, not on their descendants, so a wrapper containing many children is not flipped on account of its contents. Tables and lists are the exception: they are judged on their whole subtree, because column order and list markers only reorder when the container itself flips.

What is left alone

code, pre, kbd, samp, var, form controls, and embedded media are never marked — their direction is meaningful as authored. An element carrying a dir attribute this package did not set is also left as it is, which is the escape hatch if the heuristic gets something wrong.

Streaming

A MutationObserver watches for added nodes and changed text, batched to one pass per animation frame, so assistant messages are corrected as they stream rather than only on load. Elements are reconciled rather than marked once: a block whose balance shifts while it streams has its direction withdrawn or applied to match.

Attribute mutations are deliberately not observed, since this package writes attributes and watching them would feed its own writes back in.

Model Experience

None, as the package contributes browser presentation only; nothing here reaches a model request.

KV Cache effect

None; this package neither assembles nor sends a provider request.

Known Limitations and Deferred Work

  • Presentation only, not layout — the shell itself stays left-to-right. The sidebar remains on the left and controls keep their positions. Mirroring the application shell belongs in a separate package occupying the layout slots.
  • The browser title is independentDSH_CLIENT_TITLE selects title text at build time rather than through a UI slot.
  • Dominance is a heuristic — a block that is evenly balanced between scripts resolves to right-to-left.

License

MIT