diff --git a/src/errors.ts b/src/errors.ts index feece95..62b3185 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -7,6 +7,8 @@ export const ERR_MACOS_UNSUPPORTED_VERSION = "Require macOS version 11 or later"; export const ERR_MACOS_UNABLE_UPDATE_SYSTEM_DEFAULTS = "Unable to update system defaults"; +export const ERR_MACOS_UNABLE_UPDATE_VOICE_OVER_SANDBOXED_DEFAULTS = + "Unable to update VoiceOver sandboxed defaults - SIP might not be disabled"; export const ERR_MACOS_UNABLE_TO_VERIFY_SIP = "Unable to verify macOS SIP status"; export const ERR_MACOS_UNABLE_TO_WRITE_DATABASE_FILE = diff --git a/src/macOS/enableAppleScriptControlSandboxedDefaults.ts b/src/macOS/enableAppleScriptControlSandboxedDefaults.ts new file mode 100644 index 0000000..c4be227 --- /dev/null +++ b/src/macOS/enableAppleScriptControlSandboxedDefaults.ts @@ -0,0 +1,26 @@ +import { execSync } from "child_process"; +import { getPlatformVersionMajor } from "./getPlatformVersionMajor"; +import { ERR_MACOS_UNABLE_UPDATE_VOICE_OVER_SANDBOXED_DEFAULTS } from "../errors"; + +const VOICE_OVER_APPLESCRIPT_ENABLED_PLUTIL = + "plutil -replace SCREnableAppleScript -bool true ~/Library/Group\\ Containers/group.com.apple.VoiceOver/Library/Preferences/com.apple.VoiceOver4/default.plist"; + +export function enableAppleScriptControlSandboxedDefaults(): void { + const platformMajor = getPlatformVersionMajor(); + + // For MacOS 14 Sonoma (Darwin 23) and earlier VoiceOver preferences are set via system defaults. + if (platformMajor < 24) { + return; + } + + // From MacOS 15 Sequoia (Darwin 24) VoiceOver preferences are sandboxed. + try { + execSync(VOICE_OVER_APPLESCRIPT_ENABLED_PLUTIL, { encoding: "utf8" }); + + return; + } catch (e) { + throw new Error( + `${ERR_MACOS_UNABLE_UPDATE_VOICE_OVER_SANDBOXED_DEFAULTS}\n\n${e.message}` + ); + } +} diff --git a/src/macOS/enableAppleScriptControlSystemDefaults.ts b/src/macOS/enableAppleScriptControlSystemDefaults.ts index 1bffb85..e6892f6 100644 --- a/src/macOS/enableAppleScriptControlSystemDefaults.ts +++ b/src/macOS/enableAppleScriptControlSystemDefaults.ts @@ -5,28 +5,17 @@ import { ERR_MACOS_UNABLE_UPDATE_SYSTEM_DEFAULTS } from "../errors"; const VOICE_OVER_APPLESCRIPT_ENABLED_DEFAULTS = "defaults write com.apple.VoiceOver4/default SCREnableAppleScript -bool true"; -const VOICE_OVER_APPLESCRIPT_ENABLED_PLUTIL = - "plutil -replace SCREnableAppleScript -bool true ~/Library/Group\\ Containers/group.com.apple.VoiceOver/Library/Preferences/com.apple.VoiceOver4/default.plist"; - export function enableAppleScriptControlSystemDefaults(): void { const platformMajor = getPlatformVersionMajor(); - // For MacOS 14 Sonoma (Darwin 23) and earlier VoiceOver preferences are set via system defaults. - if (platformMajor < 24) { - try { - execSync(VOICE_OVER_APPLESCRIPT_ENABLED_DEFAULTS, { encoding: "utf8" }); - - return; - } catch (e) { - throw new Error( - `${ERR_MACOS_UNABLE_UPDATE_SYSTEM_DEFAULTS}\n\n${e.message}` - ); - } + // From MacOS 15 Sequoia (Darwin 24) VoiceOver preferences are sandboxed. + if (platformMajor >= 24) { + return; } - // From MacOS 15 Sequoia (Darwin 24) VoiceOver preferences are sandboxed. + // For MacOS 14 Sonoma (Darwin 23) and earlier VoiceOver preferences are set via system defaults. try { - execSync(VOICE_OVER_APPLESCRIPT_ENABLED_PLUTIL, { encoding: "utf8" }); + execSync(VOICE_OVER_APPLESCRIPT_ENABLED_DEFAULTS, { encoding: "utf8" }); return; } catch (e) { diff --git a/src/macOS/setup.ts b/src/macOS/setup.ts index a7b44ad..35f30d4 100644 --- a/src/macOS/setup.ts +++ b/src/macOS/setup.ts @@ -3,6 +3,7 @@ import { macOSRecord } from "@guidepup/record"; import chalk from "chalk"; import { checkVersion } from "./checkVersion"; import { enableAppleScriptControlSystemDefaults } from "./enableAppleScriptControlSystemDefaults"; +import { enableAppleScriptControlSandboxedDefaults } from "./enableAppleScriptControlSandboxedDefaults"; import { disableSplashScreenSystemDefaults } from "./disableSplashScreenSystemDefaults"; import { disableDictationInputAutoEnable } from "./disableDictationInputAutoEnable"; import { isSipEnabled } from "./isSipEnabled"; @@ -61,6 +62,7 @@ export async function setup(): Promise { if (!isSipEnabled() && !(await enabledDbFile())) { writeDatabaseFile(); + enableAppleScriptControlSandboxedDefaults(); return; }