ExMacOSControl (ExMacOSControl v0.1.2)

View Source

Facade for macOS automation: AppleScript, JavaScript for Automation (JXA), Shortcuts, etc.

This module provides a high-level interface for automating macOS using:

  • AppleScript - Apple's scripting language for macOS automation
  • JXA (JavaScript for Automation) - JavaScript-based alternative to AppleScript
  • Script Files - Execute AppleScript and JXA files from disk with automatic language detection
  • Shortcuts - Execute and list macOS Shortcuts with input parameter support

Examples

# Execute AppleScript
iex> ExMacOSControl.run_applescript(~s(return "Hello, World!"))
{:ok, "Hello, World!"}

# Execute AppleScript with arguments
iex> script = "on run argv\nreturn item 1 of argv\nend run"
iex> ExMacOSControl.run_applescript(script, args: ["test"])
{:ok, "test"}

# Execute JXA
iex> ExMacOSControl.run_javascript("(function() { return 'Hello from JXA!'; })()")
{:ok, "Hello from JXA!"}

# Execute JXA with arguments
iex> ExMacOSControl.run_javascript("function run(argv) { return argv[0]; }", args: ["test"])
{:ok, "test"}

Script Files

# Execute script files with automatic language detection
ExMacOSControl.run_script_file("/path/to/script.applescript")
# => {:ok, "result"}

ExMacOSControl.run_script_file("/path/to/script.js", args: ["arg1", "arg2"])
# => {:ok, "result"}

Shortcuts

# Run a Shortcut
ExMacOSControl.run_shortcut("My Shortcut")
# => :ok

# Run a Shortcut with input
ExMacOSControl.run_shortcut("Process Text", input: "Hello, World!")
# => {:ok, "processed result"}

# List available Shortcuts
ExMacOSControl.list_shortcuts()
# => {:ok, ["Shortcut 1", "Shortcut 2", "My Shortcut"]}

Summary

Functions

Lists all available macOS Shortcuts.

Executes AppleScript code.

Executes AppleScript code with options.

Executes JavaScript for Automation (JXA) code.

Executes JavaScript for Automation (JXA) code with options.

Executes a script file from disk with automatic language detection.

Executes a script file from disk with options.

Executes a macOS Shortcut by name.

Executes a macOS Shortcut by name with input parameters.

Functions

list_shortcuts()

@spec list_shortcuts() :: {:ok, [String.t()]} | {:error, term()}

Lists all available macOS Shortcuts.

Returns

  • {:ok, shortcuts} - Success with list of shortcut names
  • {:error, reason} - Failure (e.g., Shortcuts app not available)

Examples

ExMacOSControl.list_shortcuts()
# => {:ok, ["Shortcut 1", "Shortcut 2", "My Shortcut"]}

# Check if a specific shortcut exists
case ExMacOSControl.list_shortcuts() do
  {:ok, shortcuts} ->
    if "My Shortcut" in shortcuts do
      ExMacOSControl.run_shortcut("My Shortcut")
    end
  {:error, reason} ->
    {:error, reason}
end

run_applescript(script)

@spec run_applescript(String.t()) ::
  {:ok, String.t()} | {:error, ExMacOSControl.Error.t()}

Executes AppleScript code.

Parameters

  • script - The AppleScript code to execute

Returns

  • {:ok, output} - Success with script output
  • {:error, reason} - Failure with error reason

Examples

iex> ExMacOSControl.run_applescript(~s(return "Hello"))
{:ok, "Hello"}

run_applescript(script, opts)

@spec run_applescript(String.t(), ExMacOSControl.Adapter.options()) ::
  {:ok, String.t()} | {:error, ExMacOSControl.Error.t()}

Executes AppleScript code with options.

Options

  • :timeout - Maximum time in milliseconds to wait for script execution
  • :args - List of string arguments to pass to the script

Examples

With timeout option:

ExMacOSControl.run_applescript("delay 1", timeout: 5000)
# => {:ok, ""}

With arguments option:

script = """
on run argv
  return item 1 of argv
end run
"""
ExMacOSControl.run_applescript(script, args: ["hello"])
# => {:ok, "hello"}

With both timeout and args:

ExMacOSControl.run_applescript(script, args: ["test"], timeout: 5000)
# => {:ok, "test"}

run_javascript(script)

@spec run_javascript(String.t()) :: {:ok, String.t()} | {:error, term()}

Executes JavaScript for Automation (JXA) code.

Parameters

  • script - The JXA code to execute

Returns

  • {:ok, output} - Success with script output
  • {:error, reason} - Failure with error reason

Examples

iex> ExMacOSControl.run_javascript("(function() { return 'test'; })()")
{:ok, "test"}

iex> ExMacOSControl.run_javascript("Application('Finder').running()")
{:ok, "true"}

run_javascript(script, opts)

@spec run_javascript(String.t(), ExMacOSControl.Adapter.options()) ::
  {:ok, String.t()} | {:error, term()}

Executes JavaScript for Automation (JXA) code with options.

Parameters

  • script - The JXA code to execute
  • opts - Keyword list of options:
    • :args - List of string arguments to pass to the script

Returns

  • {:ok, output} - Success with script output
  • {:error, reason} - Failure with error reason

Examples

# With arguments
iex> script = "function run(argv) { return argv[0]; }"
iex> ExMacOSControl.run_javascript(script, args: ["hello"])
{:ok, "hello"}

# With multiple arguments
iex> script = "function run(argv) { return argv.join(' '); }"
iex> ExMacOSControl.run_javascript(script, args: ["hello", "world"])
{:ok, "hello world"}

run_script_file(file_path)

@spec run_script_file(String.t()) ::
  {:ok, String.t()} | {:error, ExMacOSControl.Error.t()}

Executes a script file from disk with automatic language detection.

This function executes AppleScript or JavaScript files directly, with automatic language detection based on file extension. It supports all the same options as run_applescript/2 and run_javascript/2, including timeout and argument passing.

Parameters

  • file_path - Absolute or relative path to the script file

Language Detection

The language is automatically detected from the file extension:

  • .scpt, .applescript → AppleScript
  • .js, .jxa → JavaScript

Returns

  • {:ok, output} - Success with script output
  • {:error, reason} - Failure with error reason

Examples

# Execute AppleScript file
ExMacOSControl.run_script_file("/path/to/script.applescript")
# => {:ok, "result"}

# Execute JavaScript file
ExMacOSControl.run_script_file("/path/to/script.js")
# => {:ok, "result"}

run_script_file(file_path, opts)

@spec run_script_file(String.t(), ExMacOSControl.Adapter.options()) ::
  {:ok, String.t()} | {:error, ExMacOSControl.Error.t()}

Executes a script file from disk with options.

This function executes AppleScript or JavaScript files directly, with automatic language detection based on file extension. You can override the language detection and pass arguments and timeout options.

Parameters

  • file_path - Absolute or relative path to the script file
  • opts - Keyword list of options:
    • :language - Explicit language (:applescript or :javascript), overrides detection
    • :timeout - Maximum time in milliseconds to wait for execution
    • :args - List of string arguments to pass to the script

Language Detection

The language is automatically detected from the file extension:

  • .scpt, .applescript → AppleScript
  • .js, .jxa → JavaScript

You can override automatic detection using the :language option.

Returns

  • {:ok, output} - Success with script output
  • {:error, reason} - Failure with error reason

Examples

# Override language detection
ExMacOSControl.run_script_file("/path/to/script.txt", language: :applescript)
# => {:ok, "result"}

# With arguments
ExMacOSControl.run_script_file(
  "/path/to/script.applescript",
  args: ["arg1", "arg2"]
)
# => {:ok, "result"}

# With timeout
ExMacOSControl.run_script_file("/path/to/script.js", timeout: 5000)
# => {:ok, "result"}

# Combined options
ExMacOSControl.run_script_file(
  "/path/to/script.scpt",
  language: :applescript,
  args: ["test"],
  timeout: 10_000
)
# => {:ok, "result"}

run_shortcut(name)

@spec run_shortcut(String.t()) :: :ok | {:ok, String.t()} | {:error, term()}

Executes a macOS Shortcut by name.

Parameters

  • name - The name of the Shortcut to run

Returns

  • :ok - Success with no output
  • {:ok, output} - Success with output from the shortcut
  • {:error, reason} - Failure with error reason

Examples

# Assuming you have a shortcut named "My Shortcut"
ExMacOSControl.run_shortcut("My Shortcut")
# => :ok (if shortcut exists and returns no output)
# => {:ok, "result"} (if shortcut returns output)
# => {:error, reason} (if not found)

run_shortcut(name, opts)

@spec run_shortcut(String.t(), ExMacOSControl.Adapter.options()) ::
  :ok | {:ok, String.t()} | {:error, term()}

Executes a macOS Shortcut by name with input parameters.

Parameters

  • name - The name of the Shortcut to run
  • opts - Keyword list of options:
    • :input - Input data to pass to the shortcut (string, number, map, or list)

Returns

  • :ok - Success with no output
  • {:ok, output} - Success with output from the shortcut
  • {:error, reason} - Failure with error reason

Examples

# With string input
ExMacOSControl.run_shortcut("Process Text", input: "Hello, World!")
# => {:ok, "processed result"}

# With number input
ExMacOSControl.run_shortcut("Calculate", input: 42)
# => {:ok, "84"}

# With map input (serialized as JSON)
ExMacOSControl.run_shortcut("Process Data", input: %{"name" => "John", "age" => 30})
# => {:ok, "result"}

# With list input (serialized as JSON)
ExMacOSControl.run_shortcut("Process Items", input: ["item1", "item2", "item3"])
# => {:ok, "result"}