cmux-imessage: read-only Messages database reader for the opt-in Messages mirror
Leo's ask: "i mean like obviously we already are in an imessage type zone im saying like actual imessage chats with contacts/group chats" ... "hm. could we mirror it?"
This is the first step of an opt-in, off-by-default Messages mirror in cmux NEXT: a read-only reader of the macOS Messages database. It adds no UI and nothing calls it yet. The daemon ops and the page come in the next PR.
What it does
New crate cmux-tui/crates/cmux-imessage:
Reader::open(path)opens~/Library/Messages/chat.dbwithSQLITE_OPEN_READ_ONLY. It never writes. A TCC denial (no Full Disk Access) returnsNotPermitted, a missing fileMissing, and a database without the Messages tablesSchema.threads(limit): 1:1 and group chats, newest activity first. Each one carries its title (the group name, else the participants),is_group, its participants and a last-message preview.messages(chat_id, before_rowid, limit): one thread's messages, oldest first, paged back by rowid. Text comes frommessage.text, or is decoded from theattributedBodytypedstream that recent macOS versions use instead. Attachment names and MIME types are included; tapbacks and group events are left out.since(rowid, limit)andlatest_rowid(): the watermark that live updates will use.
Nothing leaves the Mac. The crate has no network code, and attachment files are never copied.
Tests
Two commits: the failing tests against stubs (9 of 10 red), then the reader (10 of 10 green, clippy -D warnings clean). The fixture databases are built from the Messages schema: group naming and fallback, preview skipping tapbacks, attributedBody short/long/unicode/garbage, paging, the watermark across chats, and the missing/schema/not-permitted errors.
Follow-ups (next PRs): the daemon resource messages.mirror.* with a file-watch change event, the webview page and the off-by-default setting; then sending through Messages.app. Contact names are a follow-up too.
Agent session: agent session
🤖 Generated with Claude Code
![Autofix with [code]smith](https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark-3x.png)
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Adds the cmux-imessage crate: a read-only reader of the macOS Messages database (~/Library/Messages/chat.db) that backs an opt-in, off-by-default Messages mirror in cmux NEXT. Nothing calls it yet; the daemon resource, live-update file watcher, and UI come in the next PRs.
New Features
- Opens with
SQLITE_OPEN_READ_ONLY, never writes, never copies attachment files, and has no network code. - Maps a TCC denial to
NotPermittedso the UI can ask for Full Disk Access, a missing file toMissing, and an unfamiliar schema toSchema. - Lists 1:1 and group threads newest-first with participants, group names, and a last-message preview; skips tapbacks and group events.
- Pages a thread's messages oldest-first by rowid, decoding text from the
attributedBodytypedstream whenmessage.textis empty; includes attachment names and MIME types. - Provides
since()andlatest_rowid()as the watermark live updates will use. - Tested against fixture databases built from the Messages schema, covering group naming,
attributedBodyvariants, paging, the watermark, and all three open errors.