Repository navigation
fix(imsg-react): tapbacks on a macOS 27 gateway - #138
Conversation
On macOS 27.0.1 every tapback failed. Four things, measured on the Mac:
- The consent check read ~/Library/Application Support/com.apple.TCC/TCC.db,
which 27 no longer has, so it always refused ("cannot confirm the
Automation grant"). With no file, it now asks macOS through
AEDeterminePermissionToAutomateTarget with askUserIfNeeded=false, which
answers and never prompts. A TCC.db that exists still decides.
- Bubbles no longer carry the six tapback actions (they offer Tapback
Details…, Reply…, Copy...), so the bubble search found nothing to press and
could not page (it pages with a live bubble's actions). On 27 it now uses
Edit ▸ Tapback Last Message…, which opens the Tapback Picker on the
conversation's newest message with the six as buttons of the same names.
The picker names its message; nothing is pressed unless that is the
target's text. chat.db still decides success. No click or AX press
selects an older bubble, so an older message is refused (not-last, 65).
- A System Events click on that menu item can block until the picker
closes; it is sent from AppleScript under `ignoring application
responses`. The button is pressed by its action name, AXPress.
- A bubble label spanning lines never parsed (`.` in the label regex).
Each run appends its outcome code and exit status to ~/.blip/react.log on
the Mac (no GUID, no text; rotated at 64 KB).
Verified: a thumbs-up on the newest message of a 1:1 landed in chat.db
(type 2001, 16.9 s). test_react.py 60 pass, bun test 750 pass.
|
Merged, thank you Ian. This is the one that matters for me personally: my gateway is on macOS 27.2 with no per-user TCC.db, so the old consent check could never pass and tapbacks were dead here. On my Mac the new check now answers macOS 27, granted, and nothing prompted. The safety story is right too: the picker is pressed only when its own "Message, " label matches the target, an older message is refused before Messages is touched, and the probe asks with askUserIfNeeded=false. 750 tests, 60 react tests and every bridge test green; installed on my Mac. Your "not addressed" note (a non-zero imsg-react with a reason on stderr never reaches Blip's status line) is worth an issue of its own if you have a minute; I have not looked at it yet. |
LR-T: blip, change-log, weekly-notes, #138, tapbacks, macos-27, ianswope LR-D: blip Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BeRMdPWNC2myz9U8hEeeCi
|
Thanks Fred, and thanks for Blip itself. I use it all day and really love it, so it's a pleasure to help where I can. Glad this one brought tapbacks back on your 27.2 gateway too. On the status-line note: I found the cause, so I'll send a PR instead of an issue. The imsg-react run lived in the view that started it, and the popout and the window are both destroyed on close. On a 27 gateway a run takes 15 to 75 seconds, so closing Blip mid-run took the run and its failure with it. The fix moves the run into BarWidget and holds a failure per conversation until a view showing it picks it up. It's deployed here; I'm confirming it on a real failure before I open the PR. |
WHAT: the imsg-react Process moves from BlipView to BarWidget (runTapback, reactProc; one run at a time), which outlives the popout and the window. Every exit emits tapbackExited(chat, ok); a failure waits in tapbackFailures[chat] (memory only, reason text, no message content) until a view showing that conversation takes it, now or when it is next opened. The not-started guard (sawExit) moves with it, same pattern. imsg-react on macOS 27 runs the newest-message check before Messages is touched, so an older target is refused in about a second without raising Messages. From Ian Swope (github.com/ianswope, X @ianfs), the 'not addressed' note on #138. WHY: a run takes 15-75 s on a 27 gateway; closing Blip mid-run destroyed the view's Process, and its stderr reason never reached the status line. VERIFIED: merged with main, bun 750 pass, test_react.py OK, every bridge test. door one-way; Fred approved 2026-10-07. LR-T: blip, tapbacks, imsg-react, barwidget, process-lifetime, macos-27, ianswope LR-D: blip LR-R: #139 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BeRMdPWNC2myz9U8hEeeCi
On a macOS 27.0.1 gateway every outgoing tapback failed. Four causes, each measured on the Mac:
system_events_consentreads the per-userTCC.db, which macOS 27 no longer has (the folder is gone), so it always answered "cannot confirm the Automation grant" even thoughimsg-read's System Events calls succeed. With no file it now asks macOS viaAEDeterminePermissionToAutomateTarget(..., askUserIfNeeded=false), which answers and never prompts (System Events is launched hidden through LaunchServices first; the API answers -600 for a target that isn't running). ATCC.dbthat exists still decides, unchanged.Tapback Details…,Reply…,Attach Sticker…,Copy,Share…,Delete…, none of the six. The bubble search therefore found nothing and could not even page (no-bubbles: it pages with a live bubble's actions). On 27,imsg-reactuses Edit ▸ Tapback Last Message… instead, which opens the Tapback Picker on the conversation's newest message with buttons namedHeart,Thumbs up,Thumbs down,Ha ha!,Exclamation mark,Question mark. The picker labels its message (Message, <text>); nothing is pressed unless that matches the target.chat.dbstill decides success.Neither an AX press, a CGEvent click nor a System Events
click atselects an older bubble (the item stays "Tapback Last Message…"), and arrow keys don't move the picker, so on 27 only the newest message can take a tapback. An older one is refused up front (not-last, exit 65) without touching Messages.clickon that menu item can block until the picker closes (seen by index and by name), so it is sent from AppleScript underignoring application responses. The button is pressed by its action name,AXPress(pressis only the description).parseLabelused., so a bubble whose text spans lines never matched (not-rendered). Also affects 26.Each run appends
<time> <code> exit=<n>to~/.blip/react.logon the Mac (no GUID or text, rotated at 64 KB), which is how the last two causes were found. README's tapbacks section gains a paragraph on 27.Verified
chat.db(type 2001, 16.9 s),react.log:added exit=0.test_react.py: 60 pass (new: no-TCC.db consent answers, picker route, not-last refusal before any UI, picker on another message presses nothing, failed menu click presses nothing, 27 skips the bubble search, 26 path unchanged).bun test: 750 pass.Not addressed
On the failed runs no error reached Blip's status line, although
imsg-reactexited non-zero with a reason on stderr. Not investigated here.