feat(deploy): add --fix-accessibility flag + document TCC requirement

macOS invalidates Accessibility permission whenever the app binary
changes (code signature shifts on each build). New --fix-accessibility
flag runs tccutil reset + a sudo sqlite3 TCC grant via SSH after the
.app is synced. Falls back gracefully if sqlite3 grant fails (SIP or
missing sudoers), logging a warning with a pointer to the manual steps.

README documents the symptom, manual fix, sudoers one-time setup,
and bundle ID (com.electron.aetherlauncher).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scott Idem
2026-05-12 14:09:34 -04:00
parent 1f90c819a0
commit ec29a576d5
2 changed files with 73 additions and 7 deletions

View File

@@ -63,6 +63,9 @@ Devices API key section). All laptops share one key per event. Delete it after t
# Update seed.json only (no .app copy — e.g. when rotating the API key):
./deploy/deploy.sh --seed-only all
# Deploy and re-grant Accessibility permission in one pass:
./deploy/deploy.sh --fix-accessibility all
```
The script auto-detects each Mac's CPU architecture, copies the correct `.app` build, writes
@@ -74,6 +77,43 @@ continues, then reports which laptops need a retry.
After the script completes, launch the app on each laptop and confirm it connects and shows
the correct device name in the Launcher UI.
### macOS Accessibility Permission
The launcher sends keystrokes to PowerPoint and Keynote via AppleScript. macOS requires
explicit **Accessibility** access for this. Every time a new `.app` binary is deployed, macOS
invalidates the stored permission because the code signature changes — even when rsync
updates in-place.
**Symptom:** Slide control silently fails; `osascript` eventually returns a permissions error.
**Manual fix** (GUI — always works):
1. System Settings → Privacy & Security → Accessibility
2. Find `aether_launcher` in the list → remove it ( button)
3. Re-add it (+ button → `/Applications/aether_launcher.app`) and toggle it on
**Automated fix** — use the `--fix-accessibility` deploy flag:
```bash
./deploy/deploy.sh --fix-accessibility 01 02 03
./deploy/deploy.sh --build --fix-accessibility all
```
This runs `tccutil reset` (no password required) then attempts a direct TCC database grant
via `sudo sqlite3`. The sqlite3 step requires NOPASSWD sudo on each Mac — one-time setup:
```bash
ssh "speaker ready"@192.168.32.1XX "sudo visudo -f /etc/sudoers.d/aether-tcc"
```
Add this line, then save:
```text
speaker ready ALL=(ALL) NOPASSWD: /usr/bin/sqlite3 /Library/Application\ Support/com.apple.TCC/TCC.db *
```
If the sqlite3 grant fails (SIP enabled, sudoers not configured), the script logs a warning
and falls back gracefully — a fresh permission prompt appears the first time the app uses
accessibility. The `--fix-accessibility` flag can be combined with any other flag.
**Long-term fix:** Code-sign the app with an Apple Developer certificate. A stable signature
means macOS never invalidates the permission on updates. Currently out of scope.
### Adding SSH key to a new laptop (first time only)
```bash