Skip to content

fix(desktop): list markers and quote border follow RTL message direction - #44628

Closed
Adolanium wants to merge 1 commit into
NousResearch:mainfrom
Adolanium:fix/desktop-rtl-list-markers
Closed

fix(desktop): list markers and quote border follow RTL message direction#44628
Adolanium wants to merge 1 commit into
NousResearch:mainfrom
Adolanium:fix/desktop-rtl-list-markers

Conversation

@Adolanium

Copy link
Copy Markdown
Contributor

What does this PR do?

Follow-up to #44596. The plaintext rules resolve text direction per line, but list markers and the blockquote border are box chrome whose side is driven by the CSS direction property, which #44596 deliberately never sets. The visible result in an RTL conversation: a Hebrew/Arabic list renders its numbers stranded at the far left edge while the items sit at the right (screenshot below), and an RTL quote keeps its border on the left.

CSS alone cannot close this gap: :dir() matches only the HTML dir attribute, never unicode-bidi: plaintext resolution, so there is no selector that can move a marker based on resolved content direction. This PR uses the smallest possible hook instead, with no JS logic:

  • ul, ol and blockquote carry dir="auto", so the browser's native first-strong algorithm resolves their box direction from content. Markers, list padding (Tailwind Typography already uses padding-inline-start) and the quote border follow it; the plaintext rules from feat(desktop): auto-detect RTL/bidi text direction in chat #44596 keep owning per-line text direction inside, unchanged.
  • inline code carries dir="ltr": the HTML auto algorithm skips descendants that carry their own dir, so a list item that starts with npm install ... followed by a Hebrew explanation still resolves RTL. This is the same no-vote contract the CSS isolate in feat(desktop): auto-detect RTL/bidi text direction in chat #44596 already gives inline code at the text level, extended to the attribute level. It also pins inline code LTR redundantly with that CSS, so nothing changes visually.
  • the blockquote border moves from border-l-2/pl-3 to the logical border-s-2/ps-3 so it can follow.

Marker side is resolved per list, not per item (the first-strong scan covers the list's content), which matches how RTL word processors lay out mixed lists. LTR lists resolve ltr and render byte-identically to current main. Fenced code is unaffected: it renders through the code plugin's CodeCard path, which #44596 already pins LTR.

Related Issue

Follow-up to #44596 / #44150 (the merged change notes "list-indent stays LTR"; this addresses the user-visible artifact of that for lists inside RTL messages, not app chrome).

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • apps/desktop/src/components/assistant-ui/markdown-text.tsx: dir="auto" on the ul/ol/blockquote overrides, dir="ltr" on the inlineCode override, logical border/padding on blockquote
  • apps/desktop/src/components/assistant-ui/block-direction.test.tsx: pins the contract: list/quote blocks carry dir="auto", inline code carries dir="ltr" (and so never votes), plain prose blocks stay attribute-free for the plaintext CSS

How to Test

  1. cd apps/desktop && npx vitest run --environment jsdom src/components/assistant-ui/block-direction.test.tsx - 4 passed
  2. npm run typecheck - clean; npx eslint on both touched files - clean
  3. Manual: ask for a Hebrew answer with a numbered list - markers render on the right, against the text
  4. Ask for list items that each start with a command in backticks followed by a Hebrew explanation - markers stay on the right (code does not vote on direction) and the commands keep their internal order
  5. Ask for a Hebrew blockquote - the border renders on the right
  6. English lists and quotes - identical to current main (dir="auto" resolves ltr)

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run pytest tests/ -q and all tests pass (renderer-only change; desktop vitest suite run instead)
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: Windows 11, dev build (npm run dev)

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A (rendering only)
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

Screenshots / Logs

Same Hebrew reply (numbered list of code-first steps, blockquote, English list control) on current main and with this change:

Before (current main):
rtl-list-before

After:
rtl-list-after

unicode-bidi:plaintext (NousResearch#44596) resolves text direction per line, but
list markers and the blockquote border are box chrome driven by the CSS
direction property, which plaintext never sets, so an RTL list renders
its numbers stranded at the far left edge. CSS cannot close this gap
(:dir() only reads the dir attribute, never plaintext resolution), so
ul/ol/blockquote carry dir="auto" and the browser resolves their box
direction natively while the plaintext rules keep owning the text.
Inline code carries dir="ltr", which HTML's auto algorithm skips,
matching the no-vote contract the CSS isolate already gives it.
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/tui Terminal UI (ui-tui/ + tui_gateway/) labels Jun 12, 2026
@Adolanium

Copy link
Copy Markdown
Contributor Author

@OutThisLife this is the direct follow-up to #44596 (thanks for merging that one). Same RTL direction handling, but for the parts #44596 didn't cover. List markers and blockquote borders are controlled by box direction (CSS direction) rather than per-line text direction, so they still render on the wrong side in Hebrew/Arabic messages. Before/after are in the description above.

It's a small change (border-s-2 instead of border-l-2, dir="auto" on the containers), so LTR isn't affected, and there are 4 tests covering both directions. Mind taking a look when you have a sec?

@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #47841 (#47841). Your commit was cherry-picked onto current main with your authorship preserved in git log (f4100f4). Thanks for the clean follow-up to the RTL bidi work — the attribute-hook approach and the contract tests were spot on.

waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
@Adolanium
Adolanium deleted the fix/desktop-rtl-list-markers branch August 6, 2026 05:09
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tui Terminal UI (ui-tui/ + tui_gateway/) P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants