| … | … | @@ -873,6 +877,65 @@ function ArtifactTemplateCard(props: { | |
| 881 | + | readonly text: string; | |
| 882 | + | readonly markdownStyles: MarkdownStyleSet; | |
| 883 | + | }) { | |
| 884 | + | const sourceAst = useMemo(() => parseMarkdown(props.text, { gfm: true }), [props.text]); | |
🟠 High threads/ThreadFeed.tsx:884
An oversized or otherwise unparseable message throws from NitroMarkdownMessage and crashes the mobile render instead of showing the markdown error state. parseMarkdown throws parser failures, including input_too_large above its 10 MB default, so this direct call must route failures through the existing markdown error handling rather than letting them escape render.
🤖 Copy this AI Prompt to have your agent fix this:
| 1 | In file @apps/mobile/src/features/threads/ThreadFeed.tsx around line 884: |
| 2 | |
| 3 | An oversized or otherwise unparseable message throws from `NitroMarkdownMessage` and crashes the mobile render instead of showing the markdown error state. `parseMarkdown` throws parser failures, including `input_too_large` above its 10 MB default, so this direct call must route failures through the existing markdown error handling rather than letting them escape render. |
| … | … | @@ -286,6 +293,7 @@ function NativeTable(props: { | |
| 286 | 293 | )} | |
| 287 | 294 | textStyle={props.textStyle} | |
| 288 | 295 | onLinkPress={props.onLinkPress} | |
| 296 | + | direction={resolveTextDirection(nodeText(cell))} | |
🟡 Medium src/NativeMarkdownBlock.tsx:296
A cell like `npm install` שלום עולם is rendered left-aligned even though its prose is RTL: nodeText(cell) includes the leading code_inline text, so resolveTextDirection returns LTR and NativeMarkdownSelectableText applies textAlign: "left". Use the markdown-prose resolver that skips inline code, as is done when deriving document direction.
🤖 Copy this AI Prompt to have your agent fix this:
| 1 | In file @apps/mobile/modules/t3-markdown-text/src/NativeMarkdownBlock.tsx around line 296: |
| 2 | |
| 3 | A cell like `` `npm install` שלום עולם `` is rendered left-aligned even though its prose is RTL: `nodeText(cell)` includes the leading `code_inline` text, so `resolveTextDirection` returns LTR and `NativeMarkdownSelectableText` applies `textAlign: "left"`. Use the markdown-prose resolver that skips inline code, as is done when deriving document direction. |
| … | … | @@ -1830,6 +1834,25 @@ function hastPlainTextDeep(node: unknown): string { | |
| 1846 | + | if (!("children" in node) || !Array.isArray(node.children)) return ""; | |
| 1847 | + | let text = ""; | |
| 1848 | + | for (const child of node.children) text += hastProseText(child); | |
| 1849 | + | return text; | |
🟡 Medium components/ChatMarkdown.tsx:1847
hastProseText classifies a container with an English paragraph followed by a Hebrew paragraph as LTR, so its border and markers render on the left instead of the RTL side. The loop concatenates descendant text without preserving block boundaries; join child results with a separator before direction scoring.
| 1 | return node.children.map(hastProseText).join(" "); |
Also found in 1 other location(s)
packages/shared/src/textDirection.ts:111
resolveMarkdownProseDirectionconcatenates text nodes withchunks.join("")and therefore removes block/inline boundaries before word scoring. For a document with one paragraphEnglishfollowed by a paragraphעברית עברית, it classifiesEnglishעברית עבריתas LTR, whereas the prose with its paragraph separator (English עברית עברית) meets the RTL rule. Markdown nodes must be separated when collected so separate words do not become a mixed word and give the message the wrong base direction.
🤖 Copy this AI Prompt to have your agent fix this:
| 1 | In file @apps/web/src/components/ChatMarkdown.tsx around lines 1847-1849: |
| 2 | |
| 3 | `hastProseText` classifies a container with an `English` paragraph followed by a Hebrew paragraph as LTR, so its border and markers render on the left instead of the RTL side. The loop concatenates descendant text without preserving block boundaries; join child results with a separator before direction scoring. |
| 4 | |
| 5 | Also found in 1 other location(s): |
| 6 | - packages/shared/src/textDirection.ts:111 -- `resolveMarkdownProseDirection` concatenates text nodes with `chunks.join("")` and therefore removes block/inline boundaries before word scoring. For a document with one paragraph `English` followed by a paragraph `עברית עברית`, it classifies `Englishעברית עברית` as LTR, whereas the prose with its paragraph separator (`English עברית עברית`) meets the RTL rule. Markdown nodes must be separated when collected so separate words do not become a mixed word and give the message the wrong base direction. |
| … | … | @@ -0,0 +1,112 @@ | |
| 95 | + | const text = (node.content ?? "").slice(0, remainingCodeUnits).replace(GITHUB_ALERT_MARKER, ""); | |
| 96 | + | chunks.push(text); | |
| 97 | + | return remainingCodeUnits - text.length; | |
| 98 | + | } | |
🟡 Medium src/textDirection.ts:94
collectMarkdownProse can traverse and accumulate an unbounded markdown tree, so MAX_MARKDOWN_PROSE_CODE_UNITS does not bound rendering work for repeated [!NOTE] markers. Because remainingCodeUnits is decremented by the post-removal length, each marker consumes zero budget; decrement it by the original text length before removing markers.
| 1 | if (node.type === "text") { |
| 2 | const text = (node.content ?? "").slice(0, remainingCodeUnits); |
| 3 | const prose = text.replace(GITHUB_ALERT_MARKER, ""); |
| 4 | chunks.push(prose); |
| 5 | return remainingCodeUnits - text.length; |
| 6 | } |
🤖 Copy this AI Prompt to have your agent fix this:
| 1 | In file @packages/shared/src/textDirection.ts around lines 94-98: |
| 2 | |
| 3 | `collectMarkdownProse` can traverse and accumulate an unbounded markdown tree, so `MAX_MARKDOWN_PROSE_CODE_UNITS` does not bound rendering work for repeated `[!NOTE]` markers. Because `remainingCodeUnits` is decremented by the post-removal length, each marker consumes zero budget; decrement it by the original text length before removing markers. |