automating-mac-apps
SKILL.md
Automating macOS Apps (Apple Events, AppleScript, JXA)
Technology Status
JXA and AppleScript are legacy (last major updates: 2015-2016). Modern alternatives:
- PyXA: Active Python automation (see installation below)
- Shortcuts App: Visual workflow builder
- Swift/Objective-C: Production-ready automation
macOS Sequoia 15 Notes
Test scripts on target macOS due to:
- Stricter TCC permissions
- Enhanced Apple Events security
- Sandbox improvements
Core framing (use this mental model)
- Apple Events: The underlying inter-process communication (IPC) transport for macOS automation.
- AppleScript: The original DSL (Domain-Specific Language) for Apple Events: best for discovery, dictionaries, and quick prototypes.
- JXA (JavaScript for Automation): A JavaScript binding to the Apple Events layer: best for data handling, JSON, and maintainable logic.
- ObjC Bridge: JavaScript access to Objective-C frameworks (Foundation, AppKit) for advanced macOS capabilities beyond app dictionaries.
When to use which
- Use AppleScript for discovery, dictionary exploration, UI scripting, and quick one-offs.
- Use JXA for robust logic, JSON pipelines, integration with Python/Node, and long-lived automation.
- Hybrid pattern (recommended): discover in AppleScript, implement in JXA for production use.
When to use this skill
- Foundation for app-specific skills (Calendar, Notes, Mail, Keynote, Excel, Reminders).
- Run the automation warm-up scripts before first automation to surface macOS permission prompts.
- Use as the base reference for permissions, shell integration, and UI scripting fallbacks.
Workflow (default)
- Identify target app + dictionary using Script Editor.
- Prototype a minimal command that works.
- Example:
tell application "Finder" to get name of first item in desktop
- Example:
- Decide language using the rules above.
- Harden: add error handling, timeouts, and permission checks.
- JXA:
try { ... } catch (e) { console.log('Error:', e.message); } - AppleScript:
try ... on error errMsg ... end try
- JXA:
- Validate: run a read-only command and check outputs.
- Example:
osascript -e 'tell application "Finder" to get name of home' - Confirm: Output matches expected (e.g., user home folder name)
- Example:
- Integrate via
osascriptfor CLI or pipeline use. - UI scripting fallback only when the dictionary is missing/incomplete.
- Example UI Script:
tell application "System Events" to click button 1 of window 1 of process "App" - Example JXA:
Application('System Events').processes.byName('App').windows[0].buttons[0].click()
- Example UI Script:
Validation Checklist
- Automation/Accessibility permissions granted (System Settings > Privacy & Security)
- App is running:
Application("App").running()returns true - State checked before acting (e.g., folder exists)
- Dictionary method used (not UI scripting)
- Delays/retries added for UI operations
- Read-only test command succeeds
- Output matches expected values
Automation permission warm-up
- Use before first automation run or after macOS updates to surface prompts:
- All apps at once:
skills/automating-mac-apps/scripts/request_automation_permissions.sh(or.py). - Per-app:
skills/automating-<app>/scripts/set_up_<app>_automation.{sh,py}(calendar, notes, mail, keynote, excel, reminders). - Voice Memos (no dictionary):
skills/automating-voice-memos/scripts/set_up_voice_memos_automation.shto activate app + check data paths; enable Accessibility + consider Full Disk Access.
- All apps at once:
- Run from the same host you intend to automate with (Terminal vs Python) so the correct app gets Automation approval.
- Each script runs read-only AppleScript calls (list accounts/calendars/folders, etc.) to request Terminal/Python control; click “Allow” when prompted.
Modern Python Alternatives to JXA
PyXA (Python for macOS Automation) - Preferred for new projects:
PyXA Features
- Active development (v0.2.3+), modern Python syntax
- App automation: Safari, Calendar, Reminders, Mail, Music
- UI scripting, clipboard, notifications, AppleScript integration
- Method chaining:
app.lists().reminders().title()
PyXA Installation {#pyxa-installation}
# Install PyXA
pip install mac-pyxa
# Or with pip3 explicitly
pip3 install mac-pyxa
# Requirements:
# - Python 3.10+ (check with: python3 --version)
# - macOS 12+ (Monterey or later recommended)
# - PyObjC is installed automatically as a dependency
# Verify installation
python3 -c "import PyXA; print(f'PyXA {PyXA.__version__} installed successfully')"
Note: All app-specific skills in this plugin that show PyXA examples assume PyXA is installed. See this section for installation.
PyXA Example (Safari Automation)
import PyXA
# Launch Safari and navigate
safari = PyXA.Safari()
safari.activate()
safari.open_location("https://example.com")
# Get current tab URL
current_url = safari.current_tab.url
print(f"Current URL: {current_url}")
PyXA Example (Reminders)
import PyXA
reminders = PyXA.Reminders()
work_list = reminders.lists().by_name("Work")
# Add new reminder
new_reminder = work_list.reminders().push({
"name": "Review PyXA documentation",
"body": "Explore modern macOS automation options"
})
PyXA Official Resources:
- Documentation: https://skaplanofficial.github.io/PyXA/
- GitHub: https://github.com/SKaplanOfficial/PyXA
- Community: Active Discord and GitHub discussions
PyObjC (Python-Objective-C Bridge) - For Low-Level macOS Integration:
PyObjC Capabilities
- Direct Framework Access: AppKit, Foundation, and all macOS frameworks
- Apple Events: Send Apple Events via Scripting Bridge
- Script Execution: Run AppleScript or JXA from Python
- System APIs: Direct access to CalendarStore, AddressBook, SystemEvents
Installation
pip install pyobjc
# Installs bridges for major frameworks
PyObjC Example (AppleScript Execution)
from Foundation import NSAppleScript
# Execute AppleScript from Python
script_source = '''
tell application "Safari"
return URL of current tab
end tell
'''
script = NSAppleScript.alloc().initWithSource_(script_source)
result, error = script.executeAndReturnError_(None)
if error:
print(f"Error: {error}")
else:
print(f"Current Safari URL: {result.stringValue()}")
PyObjC Example (App Control via Scripting Bridge)
from ScriptingBridge import SBApplication
# Control Mail app
mail = SBApplication.applicationWithBundleIdentifier_("com.apple.Mail")
inbox = mail.inboxes()[0] # Access first inbox
# Get unread message count
unread_count = inbox.unreadCount()
print(f"Unread messages: {unread_count}")
PyObjC Official Resources:
- Documentation: https://pyobjc.readthedocs.io
- Examples: Extensive GitHub repositories with code samples
JXA Status
JXA has no updates since 2016. Use PyXA for new projects when possible.
When Not to Use
- Cross-platform automation (use Selenium/Playwright for web)
- Full UI testing (use XCUITest or Appium)
- Environments blocking Automation/Accessibility permissions
- Non-macOS platforms
- Simple shell scripting tasks (use Bash directly)
Related Skills
- App-specific automation (create
automating-[app]skills as needed) ci-cd-tccfor advanced permission management in automated environmentsmastering-applescriptfor AppleScript-focused workflows
Security Best Practices
Permission Management:
- Request minimal required permissions to reduce security risks
- Use code signing for production scripts (Developer ID certificate)
- Store credentials securely (Keychain, not hardcoded)
- Validate all inputs to prevent injection attacks
Official Apple Security Guidance:
Output expectations
- Keep examples minimal and runnable.
- JSON Output: For CLI pipelines, use
JSON.stringify(result)in JXA.- Example:
console.log(JSON.stringify({files: files, count: files.length}))
- Example:
- Exit Codes: Ensure
osascriptexits with 0 for success, non-zero for failure.
What to load
Tier 1: Essentials (Start Here)
- JXA Syntax & Patterns:
automating-mac-apps/references/basics.md - AppleScript Basics:
automating-mac-apps/references/applescript-basics.md - Cookbook (Common Recipes):
automating-mac-apps/references/recipes.md
Tier 2: Advanced & Production
- JXA Cookbook (Condensed):
automating-mac-apps/references/cookbook.md - Performance Patterns:
automating-mac-apps/references/applescript-performance.md - CI/CD & Permissions:
automating-mac-apps/references/ci-cd-tcc.md - Shell Environment:
automating-mac-apps/references/shell-environment.md - UI Scripting Inspector:
automating-mac-apps/references/ui-scripting-inspector.md
Tier 3: Specialized & Reference
- PyXA Core API Reference (complete class/method docs):
automating-mac-apps/references/pyxa-core-api-reference.md - PyXA Basics:
automating-mac-apps/references/pyxa-basics.md(Modern Python automation fundamentals) - AppleScript → PyXA Conversion:
automating-mac-apps/references/applescript-to-pyxa-conversion.md(Migration guide with examples) - Translation Checklist (AppleScript → JXA):
automating-mac-apps/references/translation-checklist.md(Comprehensive guide with examples and pitfalls) - JXA Helpers Library:
automating-mac-apps/references/helpers.js whoseBatching Patterns:automating-mac-apps/references/whos-batching.md- Dictionary Strategies:
automating-mac-apps/references/dictionary-strategies.md - ASObjC Helpers:
automating-mac-apps/references/applescript-asobjc.md
Related Skills:
web-browser-automation: Complete browser automation guide (Chrome, Edge, Brave, Arc)
Weekly Installs
17
First Seen
Feb 1, 2026
Security Audits
Installed on
openclaw15
claude-code14
opencode13
cursor8
codex8
gemini-cli7