fix(ios): preserve single newlines as visible line breaks in chat#98222
fix(ios): preserve single newlines as visible line breaks in chat#98222mansourMP wants to merge 1 commit into
Conversation
…enclaw#98028) Convert single \n to \n\n in ChatMarkdownPreprocessor.normalize() so assistant responses render with visible line breaks rather than collapsing into a single blob of text. Previously, single newlines passed through to AttributedString(markdown:) which follows CommonMark rules where lone \n is a soft break (space). The fix uses a lookahead/lookbehind regex to match \n not adjacent to another \n, preserving existing \n\n paragraph breaks. Co-Authored-By: Claude <[email protected]>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Codex review: needs real behavior proof before merge. Reviewed June 30, 2026, 1:03 PM ET / 17:03 UTC. Summary PR surface: Other +56. Total +56 across 2 files. Reproducibility: no. high-confidence live iOS reproduction was run for the original bug. The PR regression is source-visible: its shared normalize change rewrites isolated newlines and its own test now expects blank lines inside a fenced code block. Review metrics: 1 noteworthy metric.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Land a single renderer-level newline fix that preserves cleaned Markdown and code-block content, includes focused Swift coverage, and has redacted iOS simulator or device proof. Do we have a high-confidence way to reproduce the issue? No high-confidence live iOS reproduction was run for the original bug. The PR regression is source-visible: its shared normalize change rewrites isolated newlines and its own test now expects blank lines inside a fenced code block. Is this the best way to solve the issue? No, not as submitted. The best fix is a renderer-level hard-break transform that leaves cleaned Markdown unchanged and skips code/fence-sensitive content, followed by visible iOS proof. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against a75431c586ce. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Other +56. Total +56 across 2 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
Thanks @mansourMP for working on this. The underlying issue has been fixed by #98304, merged as commit 47845e1. This PR targeted the right symptom, but it changed the shared Markdown normalization path by turning isolated newlines into paragraph breaks globally. The landed fix keeps normalized Markdown stable and applies the newline preservation only in the chat display renderer, with coverage for code fences, tables, block Markdown, existing hard breaks, and plain prose. Closing this as superseded by #98304. |
What Problem This Solves
Fixes #98028 — Assistant responses in the iOS app render as a single blob of text because line breaks are silently collapsed. For example, a multi-line assistant reply like:
…would display as "Line one Line two Line three", making formatted responses, code explanations, and lists unreadable.
Why This Change Was Made
The root cause is in
ChatMarkdownPreprocessor.normalize(): single\ncharacters passed through unchanged, then SwiftUI'sAttributedString(markdown:)followed CommonMark rules where a lone\nis a soft break rendered as a space. Only\n\n(paragraph break) or\n(hard break with trailing spaces) produce visible line breaks.The fix adds a single regex replacement that converts isolated
\nto\n\nusing lookahead/lookbehind ((?<!\n)\n(?!\n)), so existing\n\nparagraph breaks are preserved untouched.User Impact
\n\nparagraph breaks remain unchanged (no quadruple-spacing)Evidence
ChatMarkdownPreprocessortests pass🤖 Generated with Claude Code
Co-Authored-By: Claude [email protected]