Skip to content

pose/automac

Repository files navigation

.github/workflows/main.yml

automac - Shell scripting for macOS applications

Usage

automac <module> <command>

Background

macOS offers many interactive applications such as the Notes and Safari apps. Unfortunately, the way to interact with those apps programmatically is rather limited and developers are forced to use Applescript or JXA. These automation solutions are hard to debug, develop, and test: There are multiple Stack Overflow posts pointing at JXA being fundamentally broken, undocumented, unsupported and cumbersome.

automac enables shell scripting for macOS applications by doing the JXA heavy lifting and providing a simplified command line interface. Some of its features are: composable standard input and output, an extendable modular system with commands that do one (and only one) thing, and new-line separated JSON output by default. In addition to that, the automac executable is self-contained and doesn't have any dependencies given that it only requires JXA that is already installed as part of every macOS installation.

Examples

For instance, by sending the following command to the macOS Notes app:

$ echo "Hello world" | automac notes create "New Note"
{
  "pcls":"note",
  "body":"...",
  "id":"x-coredata://F123D456-1234-1234-1234-111111111111/ICNote/p1234",
  "name":"New Note",
  "plaintext":"New Note\nHello World "
  ...
}

It will produce the following new note with contents obtained from stdin:

Or by executing this command on Safari:

# Open new Safari tab pointing to example.com
$ automac safari open-tab https://example.com
{
  "url":"https://example.com/",
  "name":"Untitled",
  "index":13,
  "windowId":26971
}

It will result in the following tab to be created using the command line passed URL:

These are some other available commands:

# List all Safari tabs
automac safari list-tabs

# List all Notes
automac notes list

# Retrieve a note by id from the Notes app
automac notes get-by-id x-coredata://F123D456-1234-1234-1234-111111111111/ICNote/p1234

For additional examples see the samples folder.

Installation

autoreconf -fi
./configure
make && make check && make install

To uninstall:

make uninstall

Testing

make check

Note: Testing triggers stateful interactions with macOS Applications. For instance, Creating a note or deleting a note are not side effect free and an end-to-end test require right permissions to be set.

FAQs

What versions of macOS are supported?

Currently, the project has been tested on Big Sur (11.0) and above versions but there are no restrictions for previous macOS versions as long as they support JXA.

Does this module require any native component compilation?

No, everything is scripted and uses macOS osascript for executing commands.

Why is the bundling done by concatenating JavaScript files instead of using a proper bundling solution such like Webpack?

This was done to keep the project simple and dependency free. Webpack could definitely be added if required.

Why does the project do not use TypeScript?

The project is simple and dependency free. TypeScript would add a dependency and a build system.

Are there any other similar tools available?

Hammerspoon provides a similar bridge between macOS but using Lua instead to script automation.