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

@@ -2,12 +2,14 @@
# deploy.sh — Deploy Aether Native Launcher to onsite Mac laptops
#
# USAGE:
# ./deploy.sh <num> [num ...] Deploy to one or more laptops (e.g. 03 04 05)
# ./deploy.sh all Deploy to all laptops in devices.conf
# ./deploy.sh --seed-only <num> Update seed.json only — skip .app copy
# ./deploy.sh <num> [num ...] Deploy to one or more laptops (e.g. 03 04 05)
# ./deploy.sh all Deploy to all laptops in devices.conf
# ./deploy.sh --seed-only <num> Update seed.json only — skip .app copy
# ./deploy.sh --seed-only all
# ./deploy.sh --build <num> [num ...] Build first (npm run package:mac), then deploy
# ./deploy.sh --build <num> [num ...] Build first (npm run package:mac), then deploy
# ./deploy.sh --build all
# ./deploy.sh --fix-accessibility <num> [num ...] Re-grant macOS Accessibility permission after .app update
# ./deploy.sh --fix-accessibility all (requires NOPASSWD sudo for sqlite3 — see README)
#
# REQUIRES:
# event.env — copy from event.env.example and fill in AETHER_API_KEY
@@ -27,7 +29,10 @@ BUILD_DIR="$SCRIPT_DIR/../builds"
SEED_ONLY=false
BUILD_FIRST=false
FIX_ACCESSIBILITY=false
TARGETS=()
# Bundle ID as embedded in Info.plist by electron-packager (no --app-bundle-id override)
BUNDLE_ID="com.electron.aetherlauncher"
usage() {
grep '^#' "$0" | grep -v '^#!/' | sed 's/^# \{0,1\}//'
@@ -38,9 +43,10 @@ if [[ $# -eq 0 ]]; then usage; fi
while [[ $# -gt 0 ]]; do
case "$1" in
--seed-only) SEED_ONLY=true ;;
--build) BUILD_FIRST=true ;;
--help|-h) usage ;;
--seed-only) SEED_ONLY=true ;;
--build) BUILD_FIRST=true ;;
--fix-accessibility) FIX_ACCESSIBILITY=true ;;
--help|-h) usage ;;
all) TARGETS+=("all") ;;
*) TARGETS+=("$1") ;;
esac
@@ -162,6 +168,26 @@ deploy_laptop() {
}
EOF
# ── Accessibility permission ───────────────────────────────────────────
if [[ "$FIX_ACCESSIBILITY" == "true" ]]; then
echo " Resetting Accessibility permission (tccutil)..."
if ssh "$SSH_USER@$ip" "tccutil reset Accessibility $BUNDLE_ID" 2>/dev/null; then
echo " tccutil reset OK."
else
echo " WARNING: tccutil reset failed (non-fatal)."
fi
echo " Granting Accessibility via TCC database (requires NOPASSWD sudo)..."
# shellcheck disable=SC2016
TCC_SQL="INSERT OR REPLACE INTO access(service,client,client_type,auth_value,auth_reason,auth_version) VALUES('kTCCServiceAccessibility','$BUNDLE_ID',0,2,4,1);"
if ssh "$SSH_USER@$ip" "sudo sqlite3 '/Library/Application Support/com.apple.TCC/TCC.db' \"$TCC_SQL\"" 2>/dev/null; then
echo " ✓ Accessibility granted."
else
echo " WARNING: TCC grant failed — manual re-authorization required."
echo " See README: macOS Accessibility Permission."
fi
fi
# ── Verify ─────────────────────────────────────────────────────────────
echo " Verifying..."
ssh "$SSH_USER@$ip" "cat ~/seed.json"