diff --git a/libs/cua-driver/scripts/uninstall.sh b/libs/cua-driver/scripts/uninstall.sh index ab12948e55..6dcf761e94 100755 --- a/libs/cua-driver/scripts/uninstall.sh +++ b/libs/cua-driver/scripts/uninstall.sh @@ -67,6 +67,7 @@ set -euo pipefail # flag flows through without edits. # ---------------------------------------------------------------------- USE_RUST_BACKEND=1 +RESET_TCC=0 FORWARDED_ARGS=() PASSTHROUGH=0 while [[ $# -gt 0 ]]; do @@ -77,6 +78,7 @@ while [[ $# -gt 0 ]]; do --experimental-rust) shift ;; # legacy alias for default Rust path --backend=rust) shift ;; --backend=swift) USE_RUST_BACKEND=0; shift ;; + --reset-tcc) RESET_TCC=1; shift ;; # also revoke TCC grants (opt-in) --backend=*) printf 'error: unknown backend %q; supported: swift, rust\n' "${1#*=}" >&2 exit 2 @@ -103,6 +105,34 @@ fi # ---------------------------------------------------------------------- log() { printf '==> %s\n' "$*"; } +# Opt-in TCC revocation (`--reset-tcc`). Off by default: the bundle id +# com.trycua.driver is shared with the retired Swift driver, and keeping +# grants across a reinstall avoids a re-prompt — so wiping privacy state +# is a deliberate, explicit choice, not a side effect of uninstall. +# When the flag is set, revoke Accessibility + Screen-Recording + +# Automation for com.trycua.driver. macOS-only; no-op elsewhere. +maybe_reset_tcc() { + [[ "$RESET_TCC" == "1" ]] || return 0 + if [[ "$OS" != "Darwin" ]]; then + log "--reset-tcc is macOS-only; nothing to revoke on $OS" + return 0 + fi + if ! command -v tccutil >/dev/null 2>&1; then + log "--reset-tcc: tccutil not found; skipping" + return 0 + fi + log "revoking TCC grants for com.trycua.driver (--reset-tcc)" + log " note: com.trycua.driver is shared with the retired Swift driver;" + log " this clears grants for both. The next launch will re-prompt." + for SVC in Accessibility ScreenCapture AppleEvents; do + if tccutil reset "$SVC" com.trycua.driver >/dev/null 2>&1; then + log " reset $SVC" + else + log " $SVC: nothing to reset (or reset failed)" + fi + done +} + # Resolve a symlink target to an absolute path. realpath -e fails when # the target is missing — we want to inspect dangling symlinks too (a # leftover from a half-removed install should still be cleaned up), so @@ -477,14 +507,16 @@ PY fi # --- Closing message --- + maybe_reset_tcc if [[ "$OS" == "Darwin" ]]; then - cat << 'FINALUNMSG' - -cua-driver uninstalled. + echo "" + echo "cua-driver uninstalled." + if [[ "$RESET_TCC" != "1" ]]; then + cat << 'FINALUNMSG' TCC grants (Accessibility + Screen Recording) remain in System -Settings > Privacy & Security. Reset them explicitly if you want a -clean re-install flow: +Settings > Privacy & Security. Reset them explicitly — or re-run with +--reset-tcc — if you want a clean re-install flow: tccutil reset Accessibility com.trycua.driver tccutil reset ScreenCapture com.trycua.driver @@ -494,6 +526,7 @@ clean re-install flow: Swift driver, skip this step and let macOS keep the grants — the next Swift launch will re-use them.) FINALUNMSG + fi else cat << 'FINALUNMSG' @@ -715,14 +748,18 @@ else log "claude CLI not found (skipping Claude MCP CLI cleanup)" fi -cat << 'FINALUNMSG' +maybe_reset_tcc -cua-driver uninstalled. +echo "" +echo "cua-driver uninstalled." +if [[ "$RESET_TCC" != "1" ]]; then + cat << 'FINALUNMSG' TCC grants (Accessibility + Screen Recording) remain in System -Settings > Privacy & Security. Reset them explicitly if you want a -clean re-install flow: +Settings > Privacy & Security. Reset them explicitly — or re-run with +--reset-tcc — if you want a clean re-install flow: tccutil reset Accessibility com.trycua.driver tccutil reset ScreenCapture com.trycua.driver FINALUNMSG +fi