Repository navigation
fix(helper): set message subject via IMMessageItem setSubject: on macOS 26 - #376
Conversation
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: needs maintainer review before merge. What this changesThe PR sets native message subjects through setSubject: while preserving the older setMessageSubject: fallback. Example: Send a standalone message or threaded reply with subject “Ämnesrad åäö ✅” on macOS 26.
Review scores
ProductKind: Bug fix · Worth it: Yes · Fix scope: Complete Merge readiness✅ Ready for maintainer review Keep this PR open for landing: it fixes a subject-handling defect still present on main, with no actionable correctness findings. Priority: P2 Before mergeNone. FindingsNone. Agent review detailsHow this fits togetherCLI and RPC requests pass subject text into the injected helper, which constructs native IMCore messages and dispatches them through Messages. flowchart LR
A[CLI or RPC request] --> B[Helper send handler]
B --> C[Shared message builder]
C --> D[Apply item subject]
D --> E[Wrap native message]
E --> F[Messages send]
Technical reviewBest possible solution: Land the focused repair in the existing item finalizer with its compatibility fallback and subject round-trip coverage. Do we have a high-confidence way to reproduce the issue? Current-main source deterministically skips subject assignment when IMMessageItem exposes setSubject: without setMessageSubject:; the supplied native comparison reports base failure and head success on macOS 26.6.2, without an independent reviewer runtime run. Is this the best way to solve the issue? The patch repairs the shared construction owner directly, preserves older selector support, and uses the existing native-test pattern without introducing another sending path. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 22b4da7d72d9. Provenance checked
TestingProof path: shipped entry point. SecurityNone. EvidenceWhat I checked:
Likely related people:
LabelsLabel changes:
Label justifications:
Rating scale6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior. WorkflowClawSweeper edits this one comment on every review. Comment HistoryReview history (1 earlier review cycle)
Reviewed November 4, 2026, 6:30 AM ET / 11:30 UTC (Revision 2). |
|
Updated the PR description with redacted executed terminal/database evidence for Added actual standalone and threaded send-rich runs through the exact head helper on macOS 26.6.2, including a separate recipient. Both subjects persist exactly, both messages have delivery acknowledgments, and the reply stores the standalone message GUID as its parent. The PR body also retains the executed base-fail/head-pass native construction comparison. The evidence excludes phone numbers and other private contact data. @clawsweeper re-review |
|
🦞👀 Re-review progress:
|
|
Recipient-side confirmation added to the PR description: The test operator has now confirmed that the subject lines display correctly on the receiving iPhone. This recipient-side visual confirmation supplements the recorded standalone/threaded send results and preserved subjects above. The parent/reply relationship remains independently verified by the database checks. |
…OS 26 Preserve subjects on standalone messages and threaded replies with the current IMCore item setter (openclaw#376, thanks @webmasu). Co-authored-by: webmasu <299281979+webmasu@users.noreply.github.com>
1c08265 to
4e63281
Compare
Problem
On macOS 26,
IMMessageItemexposes the plain-stringsetSubject:setter and does not respond tosetMessageSubject:. The helper therefore drops the subject on the item-construction path.Change
Use
setSubject:when available and retain the older attributed-string setter as fallback. The regression fixture mirrors the real item type and checks subjects on both the item and its wrapped message, including threaded replies.make test-native-subjectsruns a synthetic IMCore construction probe without resolving a chat or sending.Native runtime evidence on macOS 26.6.2 (25G83)
Ran the same native probe against base
5af52a029b3d027cc064f16ead5ed60b888febfband head1c0826533704b0a3e3182de736f1ef56a7b4984bin the guest:Both runs observed
item_has_setSubject=trueanditem_has_setMessageSubject=false. Body and thread checks passed in every scenario. The test subject was the synthetic stringÄmnesrad åäö ✅.This is a newly executed native IMCore construction comparison, not a live send.
Validation
make test-helper: passes, including the subject and threaded-reply regressions.make lint: Swift format and SwiftLint 0.65.1 pass with zero violations.Executed shipped send-path proof
The release CLI and helper from exact head
1c0826533704b0a3e3182de736f1ef56a7b4984bwere staged separately, hash-checked and loaded into the real Messages process on macOS 26.6.2. Sent one standalone message and one reply to it, first between controlled numbers and then to a separate recipient's iPhone.Actual command shapes, with recipient and body redacted:
Redacted terminal responses and read-only database observations for the separate-recipient run:
{ "standalone": { "response": { "exit": 0, "stdout": { "queued": true, "id": "<MESSAGE_ROW>", "guid": "<MESSAGE_8>", "service": "iMessage", "chatGuid": "any;-;<REDACTED_NUMBER>", "message_id": "<MESSAGE_8>", "messageGuid": "<MESSAGE_8>", "chat_guid": "any;-;<REDACTED_NUMBER>" }, "stderr": "" }, "observed_outgoing_rows": [ { "guid": "<MESSAGE_8>", "service": "iMessage", "is_from_me": 1, "is_sent": 1, "is_delivered": 1, "error": 0, "subject": "Test 4/5: Ämnesrad åäö ✅", "thread_originator_guid": null, "thread_originator_part": null, "balloon_bundle_id": null, "payload_bytes": null, "chat_service": "SMS" } ] }, "threaded": { "response": { "exit": 0, "stdout": { "id": "<MESSAGE_ROW>", "message_id": "<MESSAGE_9>", "messageGuid": "<MESSAGE_9>", "queued": true, "chatGuid": "any;-;<REDACTED_NUMBER>", "service": "iMessage", "chat_guid": "any;-;<REDACTED_NUMBER>", "guid": "<MESSAGE_9>" }, "stderr": "" }, "observed_outgoing_rows": [ { "guid": "<MESSAGE_9>", "service": "iMessage", "is_from_me": 1, "is_sent": 1, "is_delivered": 1, "error": 0, "subject": "Test 5/5: Ämnesrad i svar åäö ✅", "thread_originator_guid": "<MESSAGE_8>", "thread_originator_part": "0:0:77", "balloon_bundle_id": null, "payload_bytes": null, "chat_service": "SMS" } ] } }Both returned GUIDs resolved to outgoing iMessage rows with the exact requested subject,
is_sent=1,is_delivered=1, anderror=0. The reply'sthread_originator_guidexactly equals the standalone message GUID. These are actual shipped-path sends through the real helper; the earlier base-fail/head-pass native construction comparison remains documented above.Production was restored after testing. Personal identifiers, private paths, row IDs and message GUIDs are redacted; matching GUID placeholders retain the parent/reply relationship.
Recipient-side visual confirmation
The test operator has now confirmed that the subject lines display correctly on the receiving iPhone. This recipient-side visual confirmation supplements the recorded standalone/threaded send results and preserved subjects above. The parent/reply relationship remains independently verified by the database checks.