imessage: harden echo filter normalization

The self-chat echo filter matches outbound text against what chat.db
stores on round-trip. Three divergence sources caused false negatives
and duplicate bubbles:

- Signature suffix: "\nSent by Claude" is appended on send, but the
  \n may not round-trip identically through attributedBody
- Emoji variation selectors (U+FE00-FE0F) and ZWJ (U+200D): chat.db
  can add or drop these on emoji characters
- Smart quotes: macOS auto-substitutes straight quotes on the way in

Strip/normalize all three in echoKey() before the existing whitespace
collapse.

Fixes #1024
This commit is contained in:
Kenneth Lien
2026-03-26 23:12:19 -07:00
parent c29338f276
commit 8dfc279258

View File

@@ -418,7 +418,14 @@ const ECHO_WINDOW_MS = 15000
const echo = new Map<string, number>()
function echoKey(raw: string): string {
return raw.trim().replace(/\s+/g, ' ').slice(0, 120)
return raw
.replace(/\s*Sent by Claude\s*$/, '') // strip signature before \s collapse eats the \n
.replace(/[\u200d\ufe00-\ufe0f]/g, '') // ZWJ + emoji variation selectors (chat.db adds/drops these)
.replace(/[\u2018\u2019]/g, "'") // smart → straight single quote
.replace(/[\u201c\u201d]/g, '"') // smart → straight double quote
.trim()
.replace(/\s+/g, ' ')
.slice(0, 120)
}
function trackEcho(chatGuid: string, key: string): void {