Skip to content

feat: add local service detection and reliable SMS fallback#133

Merged
steipete merged 4 commits into
mainfrom
pr-132-reliable
May 31, 2026
Merged

feat: add local service detection and reliable SMS fallback#133
steipete merged 4 commits into
mainfrom
pr-132-reliable

Conversation

@steipete
Copy link
Copy Markdown
Collaborator

Summary

Proof

  • autoreview clean on full branch against origin/main
  • make lint
  • make test

ranaroussi and others added 4 commits May 29, 2026 19:54
Adds local (chat.db-backed) messaging-service intelligence to `imsg send`
and SIP-free `--local` modes to the bridge-backed intro commands, so common
availability/account/contact lookups work without disabling SIP or running
`imsg launch`. Motivated by daemon/headless use where SIP must stay enabled.

send:
- Auto service resolution in `--service auto`: for direct (`--to`) phone/email
  sends, infer iMessage vs SMS from local chat.db history before sending.
  Chat-target sends and explicit `--service` are unchanged.
- iMessage->SMS fallback: on a failed iMessage send to a phone-number
  recipient, automatically retry over SMS. On by default; add `--no-sms-fallback`
  to disable. Never engages for chat targets or email recipients.

whois:
- New `--local` flag: infer the preferred service (imessage/sms/unknown) from
  local chat.db history instead of the IMCore bridge. No SIP required. Unknown
  handles (no local history) are reported honestly as "unknown".

account:
- New `--local` flag: list iMessage account login(s) recorded in local chat.db,
  ranked by chat count. No SIP required. Reflects accounts observed in history
  rather than the live signed-in account.

nickname:
- New `--local` flag: return the local AddressBook contact name for a handle.
  Clearly relabeled as `local_contact_name` with a caveat that this is NOT the
  iMessage-shared nickname (which remains bridge-only).

core:
- MessageStore.preferredService(forHandle:) ports mac_messages_mcp's
  availability heuristic (handle.service + non-errored message history) with
  phone-format candidate expansion (bare / country-coded / +-prefixed).
- MessageStore.localAccounts() enumerates distinct account_login/account_id
  from chat.db. Both are schema-guarded and degrade gracefully.

All new behavior is additive and SIP-free; existing bridge/RPC/send paths are
unchanged (verified: other MessageSendOptions call sites use chat targets, so
SMS fallback never triggers there). 21 new tests; full suite 309 passing.
swift-format lint clean.
@clawsweeper
Copy link
Copy Markdown

clawsweeper Bot commented May 31, 2026

ClawSweeper status: review started.

I am starting a fresh review of this pull request: feat: add local service detection and reliable SMS fallback This is item 1/1 in the current shard. Shard 0/1.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

@steipete steipete merged commit b264900 into main May 31, 2026
2 checks passed
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: da74ce3df8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +493 to +494
if includeAnyForSMS, !trimmed.isEmpty {
candidates = ["SMS;-;\(trimmed)", "any;-;\(trimmed)", "any;+;\(trimmed)"]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Normalize SMS bridge lookup candidates

When an RPC direct send is service:auto and local history marks the recipient as SMS via region normalization (for example to:"07700 900000", region:"GB" with an existing chat stored as SMS;-;+447700900000), handleSend switches effectiveService to SMS but this exact bridge lookup only tries identifiers built from the raw recipient. In that case directChatInfo stays nil, so transport:"bridge" incorrectly reports no existing chat and auto transport skips the ready bridge path, even though the local SMS chat is present.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants