Metadata-Version: 2.4
Name: shortcutkit
Version: 1.0.0
Summary: Build, validate, and sign Apple Shortcuts files from Python. All 434 built-in actions and 1,449 Apple app actions, extracted from the Shortcuts engine.
Author: frontboat
License-Expression: MIT
Project-URL: Homepage, https://github.com/frontboat/shortcutkit
Project-URL: Documentation, https://github.com/frontboat/shortcutkit/blob/main/docs/shortcut-file-format.md
Project-URL: Repository, https://github.com/frontboat/shortcutkit.git
Project-URL: Changelog, https://github.com/frontboat/shortcutkit/blob/main/CHANGELOG.md
Keywords: apple,apple-shortcuts,shortcuts,shortcuts-app,workflowkit,workflow,automation,macos,macos-automation,ios,plist
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Dynamic: license-file

# shortcutkit

Build, validate, and sign Apple Shortcuts (`.shortcut`) files from Python.

[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/frontboat/shortcutkit/blob/main/LICENSE)
[![CI](https://img.shields.io/github/actions/workflow/status/frontboat/shortcutkit/ci.yml?branch=main)](https://github.com/frontboat/shortcutkit/actions)

A shortcut that asks your name and says hello:

```python
from shortcutkit import Shortcut, actions, ref, text

s = Shortcut("Greeting")
name = s.action(actions.ASK, WFAskActionPrompt="What's your name?")
s.action(actions.SHOWRESULT, Text=text("Hello, ", ref(name), "!"))

s.write()  # Greeting.shortcut
Shortcut.sign("Greeting.shortcut", "Greeting-signed.shortcut")
```

Open `Greeting-signed.shortcut` and Shortcuts adds it to your library. Shortcuts only imports
signed files, and signing needs a Mac with an iCloud login; everything else runs on any OS.

## Why

The action catalog is extracted from the Shortcuts app's own frameworks, not written by hand,
and one command refreshes it after a macOS update. Earlier libraries kept hand-written lists and
are archived ([python-shortcuts](https://github.com/alexander-akhmetov/python-shortcuts),
[shortcuts-js](https://github.com/joshfarrant/shortcuts-js));
[Cherri](https://github.com/electrikmilk/cherri) is a separate language with its own compiler.

- All 434 built-in actions as constants, so a typo is an `AttributeError`.
- 1,449 actions from Apple's apps: Reminders, Notes, Messages, Settings, and 73 more.
- Third-party app actions, given their descriptor.
- If, Repeat, Repeat with Each, and Choose from Menu blocks.
- A wrong key or value raises `ValueError` before anything is written.
- Pure Python, no dependencies.

A [TypeScript package](https://www.npmjs.com/package/shortcutkit) with the same name and data
adds compile-time checks.

## Install

```bash
pip install shortcutkit   # Python 3.9+
```

## Usage

These examples build on the one at the top.

### Share sheet

```python
from shortcutkit import shortcut_input

s = Shortcut("Page Links", types=["ActionExtension"], input_classes=["WFSafariWebPageContentItem"])
links = s.action(actions.RUNJAVASCRIPTONWEBPAGE, WFInput=shortcut_input(), WFJavaScript="completion(document.links.length)")
s.action(actions.SHOWRESULT, Text=text("Links: ", ref(links)))
```

### Control flow

```python
gid = s.if_(ref(name), "has_any_value")
s.action(actions.SHOWRESULT, Text=text("Hello, ", ref(name)))
s.otherwise(gid)
s.action(actions.SHOWRESULT, Text=text("Hello, stranger"))
s.end_if(gid)
```

### Apple's apps

```python
r = s.action(actions.REMINDERS_CREATE_REMINDER, title=text("Buy milk"), priorityLevel="high")
s.action(actions.NOTES_CREATE_NOTE, name="Shopping", content=text("Added ", ref(r)))
```

### Other apps

Pass the identifier and descriptor yourself; the parameters are not checked.

```python
s.action(
    "com.example.app.CreateNoteIntent",
    AppIntentDescriptor={
        "BundleIdentifier": "com.example.app", "Name": "Example", "TeamIdentifier": "ABCDE12345",
        "AppIntentIdentifier": "CreateNoteIntent", "ActionRequiresAppInstallation": True,
    },
    title=text("Hello"),
    body=ref(name),
)
```

## API

| Export | What it does |
|---|---|
| `Shortcut(name, color=, glyph=, types=, input_classes=)` | A shortcut. |
| `s.action(id, **params)` | Appends an action and returns it. |
| `s.if_(subject, condition, value=None)`, `s.otherwise(gid)`, `s.end_if(gid)` | An If block. |
| `s.repeat_each(items)`, `s.end_repeat_each(gid)` | A Repeat with Each block. |
| `s.repeat_count(n)`, `s.end_repeat_count(gid)` | A Repeat block. |
| `s.choose_from_menu(prompt, items)`, `s.menu_item(gid, title)`, `s.end_menu(gid)` | A Choose from Menu block. |
| `s.write(path=None)` | Writes the unsigned file and returns its path. |
| `Shortcut.sign(src, dst, mode="anyone")` | Signs a file with `shortcuts sign`. |
| `s.to_plist()` | The shortcut as a plist dictionary. |
| `ref(action)` | An action's output. |
| `text(*parts)` | A string with references in it. |
| `variable(name)`, `repeat_item()`, `repeat_index()` | Named and repeat variables. |
| `shortcut_input()`, `clipboard()`, `current_date()`, `ask()`, `device_details()`, `current_app()` | Special variables. |
| `actions`, `ACTIONS`, `get_action(id)` | Action identifiers and their catalog entries. |
| `PARAM_KINDS`, `PARAM_CHOICES`, `PARAM_VARIABLE_TYPES` | What each parameter accepts. |
| `CONDITION`, `ICON_COLORS`, `PROVENANCE` | If conditions, icon colors, and the build the data came from. |

## Documentation

- [Shortcut file format](https://github.com/frontboat/shortcutkit/blob/main/docs/shortcut-file-format.md)
- [Built-in actions](https://github.com/frontboat/shortcutkit/blob/main/docs/builtin-actions-reference.md)
- [Apple app actions](https://github.com/frontboat/shortcutkit/blob/main/docs/apple-app-intents-reference.md)
- [Parameter encodings](https://github.com/frontboat/shortcutkit/blob/main/docs/parameter-encodings.md)
- [How the data was extracted](https://github.com/frontboat/shortcutkit/blob/main/docs/extraction.md),
  and what is still approximate

## Contributing

Issues and pull requests are welcome. See
[`CONTRIBUTING.md`](https://github.com/frontboat/shortcutkit/blob/main/CONTRIBUTING.md).

## License

[MIT](https://github.com/frontboat/shortcutkit/blob/main/LICENSE).
