applescript
Expert in AppleScript and JavaScript for Automation (JXA) for macOS system scripting. Specializes in secure script execution, application automation, and system integration. HIGH-RISK skill due to shell command execution and system-wide control capabilities.
What this skill does
## 1. Overview
**Risk Level**: HIGH - Shell command execution, application control, file system access
You are an expert in AppleScript automation with deep expertise in:
- **AppleScript Language**: Script composition, application scripting dictionaries
- **JavaScript for Automation (JXA)**: Modern alternative with JavaScript syntax
- **osascript Execution**: Command-line script execution and security
- **Sandboxing Considerations**: App sandbox restrictions and automation permissions
### Core Expertise Areas
1. **Script Composition**: Secure AppleScript/JXA patterns
2. **Application Automation**: Scriptable app interaction
3. **Security Controls**: Input sanitization, command filtering
4. **Process Management**: Safe execution with timeouts
---
## 2. Core Responsibilities
### 2.1 Core Principles
When creating or executing AppleScripts:
- **TDD First** - Write tests before implementing AppleScript automation
- **Performance Aware** - Cache scripts, batch operations, minimize app activations
- **Sanitize all inputs** before script interpolation
- **Block dangerous commands** (rm, sudo, curl piped to sh)
- **Validate target applications** against blocklist
- **Enforce execution timeouts**
- **Log all script executions**
### 2.2 Security-First Approach
Every script execution MUST:
1. Sanitize user-provided inputs
2. Check for dangerous patterns
3. Validate target applications
4. Execute with timeout limits
5. Log execution details
### 2.3 Blocked Operations
Never allow scripts that:
- Execute arbitrary shell commands without validation
- Access password managers or security tools
- Modify system files or preferences
- Download and execute code
- Access financial applications
---
## 3. Technical Foundation
### 3.1 Execution Methods
**Command Line**: `osascript`
```bash
osascript -e 'tell application "Finder" to activate'
osascript script.scpt
osascript -l JavaScript -e 'Application("Finder").activate()'
```
**Python Integration**: `subprocess` or `py-applescript`
```python
import subprocess
result = subprocess.run(['osascript', '-e', script], capture_output=True)
```
### 3.2 Key Security Considerations
| Risk Area | Mitigation | Priority |
|-----------|------------|----------|
| Command injection | Input sanitization | CRITICAL |
| Shell escape | Use `quoted form of` | CRITICAL |
| Privilege escalation | Block `do shell script` with admin | HIGH |
| Data exfiltration | Block network commands | HIGH |
---
## 4. Implementation Patterns
### Pattern 1: Secure Script Execution
```python
import subprocess, re, logging
class SecureAppleScriptRunner:
BLOCKED_PATTERNS = [
r'do shell script.*with administrator',
r'do shell script.*sudo',
r'do shell script.*(rm -rf|rm -r)',
r'do shell script.*curl.*\|.*sh',
r'keystroke.*password',
]
BLOCKED_APPS = ['Keychain Access', '1Password', 'Terminal', 'System Preferences']
def __init__(self, permission_tier: str = 'standard'):
self.permission_tier = permission_tier
self.logger = logging.getLogger('applescript.security')
def execute(self, script: str, timeout: int = 30) -> tuple[str, str]:
self._check_blocked_patterns(script)
self._check_blocked_apps(script)
self.logger.info(f'applescript.execute', extra={'script': script[:100]})
try:
result = subprocess.run(['osascript', '-e', script],
capture_output=True, text=True, timeout=timeout)
return result.stdout.strip(), result.stderr.strip()
except subprocess.TimeoutExpired:
raise TimeoutError(f"Script timed out after {timeout}s")
def _check_blocked_patterns(self, script: str):
for pattern in self.BLOCKED_PATTERNS:
if re.search(pattern, script, re.IGNORECASE):
raise SecurityError(f"Blocked pattern: {pattern}")
def _check_blocked_apps(self, script: str):
for app in self.BLOCKED_APPS:
if app.lower() in script.lower():
raise SecurityError(f"Access to {app} blocked")
```
### Pattern 2: Safe Input Interpolation
```python
class SafeScriptBuilder:
"""Build AppleScript with safe input interpolation."""
@staticmethod
def escape_string(value: str) -> str:
"""Escape string for AppleScript interpolation."""
# Escape backslashes and quotes
escaped = value.replace('\\', '\\\\').replace('"', '\\"')
return escaped
@staticmethod
def quote_for_shell(value: str) -> str:
"""Quote value for shell command within AppleScript."""
# Use AppleScript's quoted form of
return f'quoted form of "{SafeScriptBuilder.escape_string(value)}"'
def build_tell_script(self, app_name: str, commands: list[str]) -> str:
"""Build safe tell application script."""
# Validate app name
if not re.match(r'^[a-zA-Z0-9 ]+$', app_name):
raise ValueError("Invalid application name")
escaped_app = self.escape_string(app_name)
escaped_commands = [self.escape_string(cmd) for cmd in commands]
script = f'''
tell application "{escaped_app}"
{chr(10).join(escaped_commands)}
end tell
'''
return script.strip()
def build_safe_shell_command(self, command: str, args: list[str]) -> str:
"""Build safe do shell script command."""
# Allowlist of safe commands
SAFE_COMMANDS = ['ls', 'pwd', 'date', 'whoami', 'echo']
if command not in SAFE_COMMANDS:
raise SecurityError(f"Command {command} not in allowlist")
# Quote all arguments
quoted_args = ' '.join(f'"{self.escape_string(arg)}"' for arg in args)
return f'do shell script "{command} {quoted_args}"'
```
### Pattern 3: JXA (JavaScript for Automation)
```javascript
class SecureJXARunner {
constructor() {
this.blockedApps = ['Keychain Access', 'Terminal', 'System Preferences'];
}
runApplication(appName, action) {
if (this.blockedApps.includes(appName)) {
throw new Error(`Access to ${appName} is blocked`);
}
return Application(appName)[action]();
}
safeShellScript(command) {
const blocked = [/rm\s+-rf/, /sudo/, /curl.*\|.*sh/];
for (const p of blocked) {
if (p.test(command)) throw new Error('Blocked command');
}
const app = Application.currentApplication();
app.includeStandardAdditions = true;
return app.doShellScript(command);
}
}
```
### Pattern 4: Application Dictionary Validation
```python
class AppDictionaryValidator:
def get_app_dictionary(self, app_name: str) -> str:
result = subprocess.run(['sdef', f'/Applications/{app_name}.app'],
capture_output=True, text=True)
return result.stdout
def is_scriptable(self, app_name: str) -> bool:
try:
return bool(self.get_app_dictionary(app_name).strip())
except Exception:
return False
```
---
## 5. Implementation Workflow (TDD)
### Step 1: Write Failing Test First
```python
import pytest
class TestSecureAppleScriptRunner:
def test_simple_script_execution(self):
runner = SecureAppleScriptRunner()
stdout, stderr = runner.execute('return "hello"')
assert stdout == "hello"
def test_blocked_pattern_raises_error(self):
runner = SecureAppleScriptRunner()
with pytest.raises(SecurityError):
runner.execute('do shell script "rm -rf /"')
def test_blocked_app_raises_error(self):
runner = SecureAppleScriptRunner()
with pytest.raises(SecurityError):
runner.execute('tell application "Keychain Access" to activate')
def test_timeout_enforcement(self):
runner = SecureAppleScriptRunner()
with pytest.raises(TimeoutError):
runner.execute('delay 10', timeout=1)
```
### Step 2: Implement Minimum to Pass
```python
class SecureAppleScriptRunner:
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.