Skip to content

fix(chat): align messages with their text direction

MacroscopeApp / Macroscope - UI Consistency failed Aug 19, 2026 in 2m 41s

UI Consistency: 1 issue found

apps/web/src/components/ChatMarkdown.tsx — the new dir="auto" on the .chat-markdown root allows the container to resolve to rtl, but the markdown layout rules in apps/web/src/index.css are still written entirely with physical LTR properties. For RTL messages this breaks list geometry (padding-left gutter on ul/ol/footnote ol while list-style: outside markers paint past the right edge), the task-list checkbox offset (margin: … calc(-1 * var(--list-gutter)) pulls the box into the text instead of the gutter), and the blockquote rule (border-left + padding-left ends up opposite the right-aligned text). Fix is to move those specific markdown rules to logical properties (padding-inline-start, margin-inline-start/end, border-inline-start, text-align: start).

An inline comment has been posted on the dir="auto" line with the affected selectors and the expected fix.

Details

Note

Your check run agent prompt is: .macroscope/check-run-agents/ui-consistency.md
More information about how Check Run Agents work can be found in our Help Center.

Scope reviewed: apps/web/src/components/ChatMarkdown.tsx, apps/web/src/components/chat/MessagesTimeline.test.tsx, plus apps/web/src/index.css as the owning stylesheet for the .chat-markdown selectors the diff makes direction-sensitive. Mobile changes were read for context only and not targeted.

Checks performed:

  • Confirmed the dir="ltr" escapes on MarkdownCodeBlock, <pre> (including the error-boundary and Suspense fallbacks), and <code> are applied after the prop spread, so they cannot be overridden by upstream props; code surfaces and the codeblock header chrome stay LTR as intended.
  • Verified no :dir() rules, logical properties, or prior dir attributes existed in apps/web/src before this PR (only StartTruncatedPath's dir="rtl" truncation trick), so .chat-markdown styling was written under an LTR-only assumption.
  • Traced every .chat-markdown rule in index.css for physical direction dependencies: ul/ol padding-left, footnote ol padding-left, li.task-list-item input[type="checkbox"] negative left margin, blockquote border-left/padding-left, th/td text-align: left, and the link underline background-position: left bottom.
  • Reviewed the other ChatMarkdown consumers (MessagesTimeline, ProposedPlanCard, PullRequestMarkdown, FilePreviewPanel) — they all inherit the same dir="auto" behavior, so the fix belongs in the shared markdown stylesheet rather than at any call site.
  • The added MessagesTimeline tests cover attribute emission only; they do not exercise the RTL layout regression described above.

🔍 Agent activity — 1 tool call

💭 I'm checking the web app changes, focusing on ChatMarkdown.tsx and its related test file to see what was modified. I'm checking consistency around the dir="auto" RTL detection on the markdown container, making sure the forced dir="ltr" on pre/code blocks doesn't conflict with other markdown elements like tables, and verifying the prop spread order so dir="ltr" properly overrides for code blocks while inline code with file link chips is handled separately. I'm also worried that existing CSS in index.css might use physical-direction properties like padding-left, border-left, or margin-left for lists and blockquotes, which would break layout under RTL instead of mirroring correctly with logical properties. I want to grep the chat-markdown selectors in index.css to check for these physical-direction rules, and also consider whether ChatMarkdown is reused elsewhere (tooltips, plan panels, diff views) where the dir="auto" behavior could have unintended effects. I'm noticing the CSS relies on physical left/right properties rather than logical ones, so with dir="auto" on RTL messages, list markers would shift to the right side while padding-left stays fixed on the left—creating a mismatch where the indentation doesn't follow the markers properly. This does seem like a legitimate finding worth flagging — switching to logical properties like padding-inline-start, border-inline-start, and margin-inline-start would prevent RTL messages from breaking, and index.css is in scope for this review. I should verify the exact lines for ol/ul/blockquote/task-list styling and check whether dir="auto" is genuinely new behavior by searching for prior usage in the web app. I'm also considering whether dir="ltr" on inline code elements is intentional (it seems fine), whether the dir prop placement after the spread in pre elements could cause override issues (it shouldn't), and whether the MarkdownCodeBlock's dir="ltr" affects the copy button geometry (looks fine). There's one more nuance around chat-markdown pre styling I want to check. The overflow-x: auto on chat-markdown pre combined with dir="ltr" correctly fixes scroll direction to start from the left. I'm also checking whether MarkdownTable's text-align: left should instead use text-align: start for RTL support, and confirming that shiki code blocks inherit dir="ltr" properly through their parent container — which they do. I want to trace through MessagesTimeline to see how user messages render ChatMarkdown and whether dir="auto" affects text alignment appropriately for RTL content, and check other consumers of ChatMarkdown like tooltips or fixed-width panels where this direction handling might cause issues — though these seem likely fine. I should also check if there's already an existing direction utility in the web codebase I should be using instead. Mobile has its own resolveTextDirection helper while web relies on native dir="auto" — that's a minor inconsistency but acceptable since native dir="auto" works fine for web. Now I want to look at how the ordered list renderer in ChatMarkdown handles the list gutter spacing via inline styles. I'm confirming that the physical padding/margin properties on lists, blockquotes, and checkboxes cause problems under RTL direction—since these are left-based properties, they don't flip with dir="auto", so markers and checkboxes end up misaligned or clipped against the wrong edge of the container. This is a real visual regression for the exact use case this PR is meant to support, like Hebrew messages containing lists. I should also check whether other components using .chat-markdown with dir="auto" might be similarly affected, so I'll search for other usages across the codebase. I'm checking whether the dir="auto" change stays consistent across other markdown surfaces like PR cards and file previews, and wondering if the composer textarea or collapsed message previews might now look inconsistent since they're outside this diff. I also want to verify that the code renderer's dir="ltr" is applied uniformly to all code elements. Now I'm thinking about whether other chrome inside chat-markdown—table footers, details/summary markers, file chips, footnote backrefs—would flip undesirably in RTL, though that flipping might actually be fine. The real concern is the scroll-fade mask on table containers, since a mask-image pointing "to right" would end up on the wrong side in RTL, so I want to check that CSS. I'll focus on the main finding: the newly added dir="auto" on the ChatMarkdown root breaks physical-direction CSS rules for lists, blockquotes, and task-list checkboxes within .chat-markdown. This is a concrete regression directly caused by the changed line, so it's worth reporting. The simplest fix is switching those CSS rules to logical properties like padding-inline-start, border-inline-start, and margin-inline-start for the relevant selectors, plus text-align: start for table cells. I'm also weighing whether other things qualify as findings — the mobile/web direction-detection inconsistency doesn't really count since web can't easily replicate the mobile heuristic, and the repeated dir="ltr" fallbacks are just minor duplication, not worth flagging. One more possible issue worth considering is whether file path chips rendered without explicit dir="ltr" could visually reverse inside RTL prose. Since path separators are neutral characters, a path made of Latin letters should still render left-to-right even without an explicit direction attribute, though trailing punctuation could shift position slightly — minor enough to skip. I'll also skip checking the footnote reference links and file-link chips for now, and instead look at whether the message bubble styling around line 1799-1830 in MessagesTimeline clips RTL list markers due to overflow settings. I'm checking whether the user message bubble container clips overflow, since that affects whether the marker placement bug actually shows visually or gets hidden by the bubble's styling. Thinking through the RTL specifics more: with padding-left set but padding-right zero, markers would overflow past the right edge into the parent's space while the left gutter sits empty, breaking indentation on both sides — a real regression for RTL lists. The task checkbox's negative left margin and mismatched right margin also look problematic in RTL, worth flagging in a comment, and now I'm figuring out where to post these inline review notes. Since index.css isn't part of the diff, GitHub only lets me comment on changed lines, so I'll attach my note to the dir="auto" line in ChatMarkdown.tsx at line 1812, which matches the diff hunk. I'm weighing whether to also flag the blanket dir="ltr" on all <code> elements, but that edge case for intentionally RTL inline code seems minor enough to skip. I also want to check whether index.css already has logical-property handling like padding-inline or :dir(rtl) selectors that might already address this. I've confirmed the app was entirely LTR before, aside from one unrelated dir="rtl" trick used for path truncation. This makes the finding solid: dir="auto" introduces RTL rendering into markdown whose CSS assumes physical-LTR throughout, so I'm leaning toward failing the check on this genuine regression risk. Before the PR, RTL text rendered with mixed bidi but lists still kept left-aligned markers and gutters; after the PR, lists flip to right-aligned markers with the gutter on the left, which is visibly broken for the exact content this change targets. The blockquote case (border on the left of right-aligned text) feels more minor but worth noting. I'll post one inline comment on ChatMarkdown.tsx covering this, and since the fix spans into index.css as well, I'll describe the needed selector changes in text rather than provide a diff, since it's a cross-file fix. Now I want to check whether anything on the mobile side is affected too. Nothing touches web there. The MessagesTimeline.test.tsx changes look fine, and dir="auto" shouldn't interfere with the copy handler or message hover chrome. I'm also checking the MarkdownCodeBlock's dir="ltr" div nested inside a potentially RTL .chat-markdown container — that's fine since it's explicitly forced LTR. The ScrollArea table container isn't part of this diff, so I'll skip it. I'll finalize the review as a failure, with the comment body explaining the issue and fix, anchored at ChatMarkdown.tsx line 1812.

1. modify_pr — One finding: the new dir="auto" on the .chat-markdown root makes RTL messages render against markdown CSS that is written entirely with physical LTR properties, so lists, task lists, and blockquotes lay out incorrectly for exactly the Hebrew/Arabic content this PR targets. Details inline.


Agent Credits: 75 credits