cmux-imessage: review follow-ups (date-ordered previews, NULL rows, stderr drain, terminal error code)

TE
3d ago
+122-24

Fixes the review follow-ups of the Messages mirror reader and sender: #32896 (from the review of #32891) and #32923 (from the review of #32919). The changes stay inside cmux-tui/crates/cmux-imessage, and its public API is unchanged.

What changes

  • Thread order and preview: a thread's preview is now its newest visible message by date, with rowid breaking ties, and threads sort by that date. iCloud backfill gives old messages high rowids, so the old highest-rowid pick could show a stale preview.
  • NULL columns: rows with NULL item_type or associated_message_type (older databases) count as plain messages instead of disappearing.
  • since(): a message joined to more than one chat (an iMessage/SMS pair) comes back once.
  • Send, stderr: SystemRunner drains stderr on a thread while the child runs. A failure that writes more than the pipe buffer no longer stalls until the two-minute timeout. Stop condition: the thread ends when the pipe closes, after the child exits or is killed and reaped.
  • Send, error mapping: only the terminal AppleScript code (... (-1743)) decides it, so a code quoted inside a chat id can't turn invalid_chat into not_permitted.

Left open in #32896, as design changes rather than fixes: paging messages by date instead of rowid, showing stickers and app messages, and live updates for edits and unsends.

Tests

Two commits: the failing tests first (the reader's 3 new tests red on Linux CI; the send tests are red by construction against the old code), then the fixes. Green: 13 reader and 7 send tests, clippy -D warnings clean, rustfmt clean. The stderr test runs a real sh child that writes 300 KB to stderr.

Agent session: agent session

🤖 Generated with Claude Code


Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes review follow-ups from #32896 and #32923 in the Messages mirror reader and sender. The public API is unchanged.

Reader

  • Thread previews and ordering use the newest visible message by date (rowid breaks ties), since iCloud backfill gives old messages high rowids.
  • NULL item_type and associated_message_type columns now count as plain messages instead of disappearing.
  • since() returns a message joined to more than one chat once.

Sender

  • SystemRunner drains stderr on a thread while the child runs, so a failure writing past the pipe buffer no longer stalls until the two-minute timeout.
  • Error mapping reads only the terminal AppleScript code, so a code quoted inside a chat id can't turn invalid_chat into not_permitted.
  • The error-code parse avoids string slicing, keeping the crate panic-free for the new panic ratchet.