feat(chat-ui): syntax-highlighted code blocks and native tables in chat markdown#100207
Conversation
|
Codex review: needs maintainer review before merge. Reviewed July 5, 2026, 2:33 PM ET / 18:33 UTC. Summary PR surface: Other +1747. Total +1747 across 14 files. Reproducibility: not applicable. as a bug reproduction path: this is a feature PR. Source comparison shows current main lacks the native code/table renderer, and the contributor provided exact-head simulator/build proof for the changed behavior. Review metrics: 2 noteworthy metrics.
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:
Mantis proof suggestion Risk before merge
Maintainer options:
Next step before merge
Maintainer decision needed
Security Review detailsBest possible solution: Land the Apple chat Markdown renderer after remaining exact-head CI completes and a maintainer accepts the Swift Markdown dependency and native rendering direction; keep broader Android and iOS header/table follow-up tracked in the linked items. Do we have a high-confidence way to reproduce the issue? Not applicable as a bug reproduction path: this is a feature PR. Source comparison shows current main lacks the native code/table renderer, and the contributor provided exact-head simulator/build proof for the changed behavior. Is this the best way to solve the issue? Yes for implementation shape, pending maintainer product acceptance: Swift Markdown owns the GFM structure/source ranges, prose stays on the existing AttributedString path, and native bounded views handle code and tables. The main safer alternative is to defer dependency adoption, but the PR has focused limits, tests, license notices, and proof. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against d7e2096dc78e. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Other +1747. Total +1747 across 14 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
Review history (10 earlier review cycles; latest 8 shown)
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e43ccc109b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| while cursor < lines.count { | ||
| let line = lines[cursor] | ||
| let trimmed = line.trimmingCharacters(in: .whitespaces) | ||
| guard !trimmed.isEmpty, line.contains("|") else { break } |
There was a problem hiding this comment.
Use GFM row boundaries for table bodies
When a table body is followed by a normal one-cell row without | (valid GFM and already implied by the padding behavior), this guard stops the table early and renders that row as prose; conversely a following blockquote/list/heading that contains | is swallowed as a data row. The GFM row boundary is a blank line or another block-level structure, not pipe presence, so assistant tables with omitted trailing cells or markdown blocks immediately after a table render incorrectly.
Useful? React with 👍 / 👎.
c5c0d23 to
327b360
Compare
327b360 to
6907971
Compare
|
@openclaw-mantis visual task: verify native OpenClaw iOS chat rendering for a syntax-highlighted fenced Swift code block and a two-column GFM table in light and dark appearance. Use synthetic content only. Also check unknown-language fallback and termination/relaunch history restore. Exact head |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6907971bde
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ], | ||
| dependencies: [ | ||
| .package(url: "https://github.com/steipete/ElevenLabsKit", exact: "0.1.1"), | ||
| .package(url: "https://github.com/swiftlang/swift-markdown", exact: "0.8.0"), |
There was a problem hiding this comment.
Add license files for the new iOS dependencies
Because the iOS app consumes OpenClawChatUI from the shared OpenClawKit package (apps/ios/project.yml:78-80), adding swift-markdown here also adds swift-markdown and its swift-cmark transitive dependency to the iOS app. The scoped iOS guide requires maintaining apps/ios/Resources/Licenses/ when iOS dependencies change (apps/ios/AGENTS.md:16-23), and LicenseDocumentLoader only surfaces bundled .txt files from that directory; there are currently no license entries for these new third-party packages, so the Settings Licenses screen will omit required acknowledgements.
Useful? React with 👍 / 👎.
|
Land-ready proof for exact head
All current ClawSweeper findings are resolved on this head: dependency notices are bundled, release-owned changelog edits are gone, and native code/table cards use label-semantic text instead of inheriting the white user-bubble foreground. No screenshot was uploaded because the proof was run against a local-only gateway and the textual behavior evidence is sufficient for this native renderer change. |
|
🦞🧹 I asked ClawSweeper to review this item again. |
167422d to
7acb9fb
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7acb9fb25b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| case let .code(code): | ||
| ChatCodeBlockView(block: code, textColor: self.textColor) | ||
| case let .table(table): | ||
| ChatMarkdownTableView(table: table, textColor: self.textColor) |
There was a problem hiding this comment.
Use card text colors for native chat blocks
When this renderer is used for user messages, self.textColor is OpenClawChatTheme.userText (.white) from ChatMessageViews, but the new code/table views draw their own OpenClawChatTheme.subtleCard background instead of the red user bubble. In light mode that card background is light, so user-sent fenced code or tables render white-on-light and become hard to read; pass a label/card-appropriate foreground for these native block backgrounds or avoid overriding their foreground with the bubble text color.
Useful? React with 👍 / 👎.
7acb9fb to
7f2c74c
Compare
…n shared chat markdown (#100195)
889d4bd to
6fcacbc
Compare
|
@clawsweeper re-review All current findings are fixed on exact head |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Merged via squash.
|
…at markdown (openclaw#100207) * feat(chat-ui): syntax-highlighted code blocks and native GFM tables in shared chat markdown (openclaw#100195) * chore(chat-ui): sync native i18n inventory * fix(chat-ui): harden native markdown rendering * refactor(chat-ui): split HTML block patterns * refactor(chat-ui): parse markdown blocks with swift-markdown * style(chat-ui): satisfy SwiftFormat lint * fix(ios): bundle markdown dependency licenses * style(ios): normalize markdown license file * fix(ios): keep native markdown cards legible
What Problem This Solves
Assistant messages in the shared Apple chat UI rendered fenced code without syntax highlighting and GFM tables as raw pipe characters because the whole message went through one
AttributedString(markdown:)/Textpass that does not provide either surface.Part of #100195. Addresses the table portion of #98290.
Why This Change Was Made
The renderer now uses Swift Markdown's GFM AST to extract only top-level fenced code and tables before display. Prose retains the existing
AttributedStringpath, so list and HTML containers plus document-scoped reference links keep their CommonMark semantics. Completed fenced blocks use a bounded single-pass highlighter for Swift, Kotlin, TypeScript/JavaScript, Python, Bash, and JSON; unknown, incomplete, oversized, or overlong blocks stay readable and unstyled. Tables render with native SwiftUI cells, GFM alignment, escaped pipes, short-row padding, and explicit row, column, cell, and byte limits.The parser dependency is pinned to Swift Markdown 0.8.0, the current stable Swift.org implementation backed by cmark-gfm. Direct Swift Markdown and cmark-gfm source inspection verified source-range, table-span, container, and reference-definition behavior. Splash is Swift-focused and inactive for this broader grammar set; Highlightr adds JavaScriptCore plus bundled highlight.js grammars/themes for a six-language chat subset. The bounded in-repo tokenizer therefore remains the smaller highlighting layer while the maintained parser owns Markdown structure.
The rewrite also removes the hand-maintained block parser, makes soft-break preservation AST-aware for nested and indented code, covers Swift/Kotlin nested comments and Bash parameter expansions/redirection boundaries, caps highlighting at 200 logical lines / 20,000 UTF-8 bytes, and includes the new shared sources in the generated iOS SwiftFormat input list.
User Impact
iOS and macOS chat show readable syntax-highlighted code cards and native aligned tables. Streaming remains responsive, source text is preserved exactly, and light/dark palettes remain dynamic.
Evidence
swift test --package-path apps/shared/OpenClawKit --filter 'ChatMarkdownBlockSegmenterTests|ChatCodeHighlighterTests|ChatMarkdownDisplayPreprocessorTests'— 72/72 passed.swift test -q --package-path apps/shared/OpenClawKit— 321/321 passed.swift build --package-path apps/macos --scratch-path /tmp/openclaw-macos-100207-ast-build— passed.scripts/ios-run.sh— Xcode simulator build passed, then installed and launched the Debug app on iPhone 17 / iOS 26.5.pnpm check:changed— passed on Blacksmith Testboxtbx_01kwsksh96m5cfea4z9pak2a3y(apps,docs, andtoolinglanes; 5 Vitest shards passed).