fix: render text formatting on the RPC send bridge path#143
Conversation
handleSend forwarded text and file to the IMCore bridge but never the attributed-text format ranges, so direct/handle sends came through plain even on macOS 15+ — only `send-rich` (and the RPC `sendRich` handler) honored formatting. The OpenClaw gateway's `message` tool uses the plain `send` method for handle targets, so its bold/italic notifications silently lost styling. Thread the format ranges through handleSend -> sendViaBridge -> the bridge sendMessage action, accepting `formatting` (the key OpenClaw emits) alongside `text_formatting`/`textFormatting` for parity with `sendRich`. Bridge transport only; AppleScript sends stay plain. Adds tests covering the threaded ranges and the no-formatting case.
|
Codex review: needs changes before merge. Reviewed June 23, 2026, 12:02 AM ET / 04:02 UTC. Summary Reproducibility: yes. Source inspection shows current main drops formatting before the bridge call, and the PR body provides live before/after output from a real macOS bridge setup; I did not run a live Messages reproduction in this read-only review. Review metrics: 3 noteworthy metrics.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Next step before merge
Security Review findings
Review detailsBest possible solution: Merge the bridge formatting forwarding and regression tests after removing or maintainer-accepting the changelog entry and confirming the normal lint/test gates. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows current main drops formatting before the bridge call, and the PR body provides live before/after output from a real macOS bridge setup; I did not run a live Messages reproduction in this read-only review. Is this the best way to solve the issue? Yes. Reusing the existing bridge Full review comments:
Overall correctness: patch is correct AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 1e1ca9f1e297. Label changesLabel justifications:
Evidence reviewedAcceptance criteria:
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
|
|
@clawsweeper re-review with updated proof |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
Maintainer validation complete on macOS with Swift 6.4:
The contributor supplied live before/after bridge proof in the PR body. I am explicitly accepting the focused unreleased changelog entry here because the fix is user-visible and the maintainer workflow requires it; it also preserves contributor credit. |
Problem
handleSend(RPC methodsend) forwardstextandfileto the IMCore bridge but never the attributed-text format ranges. So direct/handle sends come through plain even on macOS 15+ — onlysend-rich(CLI) and the RPCsendRichhandler honor formatting.This bites the OpenClaw gateway: its
messagetool routes plain handle targets (to: +1…) through thesendmethod and puts format ranges in aformattingparam. imsg'ssendignores it, so**bold**/*italic*notifications silently lose styling. Replies render correctly only because the gateway routes those throughsendRich.Fix
Thread the format ranges through
handleSend→sendViaBridge→ the bridgesendMessageaction, mirroring whatsendRichalready does. Acceptformatting(the key OpenClaw'smessagetool emits) alongsidetext_formatting/textFormattingfor parity withhandleSendRich.Tests
rpcSendThreadsTextFormattingToBridge— asserts ranges from theformattingkey reachinvokeBridgeastextFormatting.rpcSendWithoutFormattingOmitsTextFormatting— asserts notextFormattingkey when none is supplied.All
RPCServerBridgetests pass (7/7, no regressions).End-to-end proof (real device, macOS 15+, IMCore bridge v2)
Same RPC
sendcall — methodsend, bareformattingkey,transport: bridge, same self-chat ([email protected]) — run through both binaries. Only the binary differs. Verified by reading back theattributedBodyMessages persisted inchat.dband decoding the attribute runs.Request (identical except the binary that serves it):
{"method":"send","params":{"to":"[email protected]","transport":"bridge", "text":"… bold test …","formatting":[{"start":0,"length":N,"styles":["bold"]}]}}BEFORE — unfixed
/opt/homebrew/bin/imsg(0.11.1):AFTER — this branch's release build (
bin/imsg):The unfixed
sendpersists no bold attribute; the fixedsendpersists__kIMTextBoldAttributeNameover exactly the requested range.send-richalready produced this; the fix brings the plainsendpath (the one OpenClaw'smessagetool uses forto:handle targets) to parity. (Lobster is a headless Mac, so this is decoded persisted styling rather than a UI screenshot.)