openclaw - 💡(How to fix) Fix iMessage: use attributed-body formatting for approval prompts (bold headers and labels) [1 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Follow-up to #85952 (iMessage thumb approval reactions). The approval payload text comes from the SDK's buildExecApprovalPendingReplyPayload / buildPluginApprovalPendingReplyPayload, which emit plain text. sendMessageIMessage already runs extractMarkdownFormatRuns() over outbound text and ships native attributed-body runs to recipients on macOS 15+ / iOS 18+, so any **bold** / __italic__ / ~~strike~~ / <u>underline</u> markers in the payload render natively on iMessage.

Today the approval prompts render as plain text on iMessage, e.g.:

ℹ️ Plugin approval required
Title: Fastmail: get_email
Description: Read email body (untrusted content)
Tool: fastmail_get_email
Plugin: fastmail-cli
Agent: lobster-mail
ID: plugin:8d5075f3-a972-4190-97d9-8b3c1b921b06

React with:

👍 Allow Once
👎 Deny

Expires in: 120s
Reply with: /approve plugin:8d5075f3-… allow-once|allow-always|deny

Root Cause

Follow-up to #85952 (iMessage thumb approval reactions). The approval payload text comes from the SDK's buildExecApprovalPendingReplyPayload / buildPluginApprovalPendingReplyPayload, which emit plain text. sendMessageIMessage already runs extractMarkdownFormatRuns() over outbound text and ships native attributed-body runs to recipients on macOS 15+ / iOS 18+, so any **bold** / __italic__ / ~~strike~~ / <u>underline</u> markers in the payload render natively on iMessage.

Today the approval prompts render as plain text on iMessage, e.g.:

ℹ️ Plugin approval required
Title: Fastmail: get_email
Description: Read email body (untrusted content)
Tool: fastmail_get_email
Plugin: fastmail-cli
Agent: lobster-mail
ID: plugin:8d5075f3-a972-4190-97d9-8b3c1b921b06

React with:

👍 Allow Once
👎 Deny

Expires in: 120s
Reply with: /approve plugin:8d5075f3-… allow-once|allow-always|deny

Fix Action

Fixed

Code Example

ℹ️ Plugin approval required
Title: Fastmail: get_email
Description: Read email body (untrusted content)
Tool: fastmail_get_email
Plugin: fastmail-cli
Agent: lobster-mail
ID: plugin:8d5075f3-a972-4190-97d9-8b3c1b921b06

React with:

👍 Allow Once
👎 Deny

Expires in: 120s
Reply with: /approve plugin:8d5075f3-… allow-once|allow-always|deny
RAW_BUFFERClick to expand / collapse

Context

Follow-up to #85952 (iMessage thumb approval reactions). The approval payload text comes from the SDK's buildExecApprovalPendingReplyPayload / buildPluginApprovalPendingReplyPayload, which emit plain text. sendMessageIMessage already runs extractMarkdownFormatRuns() over outbound text and ships native attributed-body runs to recipients on macOS 15+ / iOS 18+, so any **bold** / __italic__ / ~~strike~~ / <u>underline</u> markers in the payload render natively on iMessage.

Today the approval prompts render as plain text on iMessage, e.g.:

ℹ️ Plugin approval required
Title: Fastmail: get_email
Description: Read email body (untrusted content)
Tool: fastmail_get_email
Plugin: fastmail-cli
Agent: lobster-mail
ID: plugin:8d5075f3-a972-4190-97d9-8b3c1b921b06

React with:

👍 Allow Once
👎 Deny

Expires in: 120s
Reply with: /approve plugin:8d5075f3-… allow-once|allow-always|deny

Proposal

Layer iMessage-specific markdown around the payload returned by the SDK so the header line and field labels render bold / underlined on recent Apple clients, while keeping the SDK output channel-agnostic.

Candidate enhancement points:

  • Bold the header line (**ℹ️ Plugin approval required** / **⚠️ Exec approval required**).
  • Bold the field labels (**Title:**, **Tool:**, **Plugin:**, **Agent:**, **ID:**).
  • Bold the React with: heading and the action labels (**👍 Allow Once**, **👎 Deny**).
  • Possibly underline the Reply with: /approve … line so it visually reads as the manual-fallback command.

Implementation sketch

The cleanest seam is the iMessage render block in extensions/imessage/src/approval-native.ts:

  • buildIMessageExecPendingPayload
  • buildIMessagePluginPendingPayload
  • appendIMessageReactionHint / addIMessageApprovalReactionHintToText

These currently call the SDK payload builders, run replaceApprovalIdPlaceholder, then append/insert the plain-text reaction hint. Wrap the targeted lines in **…** after the SDK call but before the channel send. sendMessageIMessageextractMarkdownFormatRuns() already handles the rest.

For the forwarding (mode: \"targets\") path, the SDK builds the payload on the gateway side and the channel send still runs extractMarkdownFormatRuns(), so the iMessage-side wrap of the rendered text in approval-native.ts covers both forwarding and native delivery.

Non-goals

  • Inline interactive buttons (iMessage has no equivalent UI).
  • Changing the SDK's payload format — keep markdown out of the canonical text so other channels (Slack, Discord, etc.) aren't affected.
  • Link cards or rich previews.

Test plan

  • Add an extensions/imessage/src/approval-native.test.ts case asserting the iMessage exec/plugin payloads contain **ID:** (or whichever label is targeted) so a future SDK rendering change doesn't silently drop the formatting.
  • Live verification: trigger a plugin approval to an iMessage approver on macOS 15+ / iOS 18+, confirm the header / labels render bold; trigger one to an older-OS recipient (or via SMS bridge) and confirm the markers strip cleanly to plain text per the existing extractMarkdownFormatRuns() behavior.

Related

  • #85952 — iMessage thumb approval reactions (this is the follow-up scope explicitly deferred there).
  • openclaw#85477 — WhatsApp thumb approval reactions (mirror).

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING