addon.json
The manifest names the add-on, describes it in the Store, says what it shows and what it needs, and tells Ledge which program to run.
Fields
| Field | Required | Rules |
|---|---|---|
id | Yes | Permanent. 1 to 64 lowercase letters, digits and hyphens. Never change it after publishing |
version | Yes | Three whole numbers separated by dots, like 1.2.0. Ledge won't install an older version over a newer one |
protocolVersion | Yes | 2 for a session. 1 is the older one-run-per-request worker |
name | Yes | The name in the Store and Settings. Can't be blank |
summary | Yes | One line under the name in the Store |
description | Yes | What it does, a sentence or two |
author | Yes | Who made it. Shown when Ledge asks you to trust it. Can't be blank |
capabilities | Yes | What it asks Ledge for, from the list below. No repeats; can be empty |
executable | Yes | The program's file name in the package. No folders, slashes or control characters |
icon | No | A PNG written Assets/Icon.png. Without it, Ledge uses a standard icon |
surfaces | No | What it shows, from the list below. Ledge draws nothing that isn't listed |
kit.minAPI | No | The LedgeKit it was built with, like 0.13.0. An older Ledge marks it as needing an update instead of installing it |
minLedge | No | The oldest Ledge that runs it, like 0.3.0 |
minMacOS | No | The oldest macOS it needs, like 15.0, when that's newer than Ledge's own |
category | No | Its Store section: AI, Productivity, Media, Capture, Files or System |
creator | No | name, and optionally url and avatar, shown on its Store page |
source | No | repository and license, an SPDX name like MIT |
keywords | No | Up to 20 search words of up to 40 characters |
Surfaces
Each one has its own page. An add-on sends a surface only after listing it here; Ledge refuses and logs anything else.
| Surface | What Ledge draws | Since |
|---|---|---|
settings-page | The add-on's page in Settings | 0.5.0 |
widget | A tile on the Widgets page of the open notch | 0.5.0 |
player-action | A button in Ledge's players | 0.7.0 |
player | A ••• menu entry and Playing Next | 0.8.0 |
activity | Live activities beside the notch | 0.10.0 |
lock-screen-row | A pill on the lock screen | 0.11.0 |
menu-bar-tile | Rows in the menu bar panel | 0.11.0 |
notch-page | A tab of its own in the open notch | 0.12.0 |
Capabilities
A capability is something the add-on asks Ledge to do for it. Ledge lists them when it asks you to trust the add-on, and grants only the ones it knows. A name Ledge doesn't know isn't an error: the package still installs, and that capability stays off, so an add-on built for a newer Ledge still loads.
| Capability | What it allows |
|---|---|
hud | Messages in the notch with LedgeHost.notify |
clipboard-write | Putting text on the clipboard with LedgeHost.copy |
notch-control | Opening the add-on's page and keeping the notch open, with LedgeHost.showPage and holdOpen. 0.13.0 |
spotify-library | Asking Ledge to read and change your Spotify Liked Songs, through the account broker. The add-on never gets a token |
notification-banners | Receiving the text of visible notification banners, which Ledge reads with Accessibility access |
apple-music-queue | Reading and reordering Apple Music's Playing Next |
apple-music-controls | Changing favourites and adding songs to Apple Music playlists |
Settings, the environment and opening links need no capability.
A full example
{
"id": "timer",
"version": "1.1.0",
"protocolVersion": 2,
"name": "Timer",
"summary": "A countdown beside your notch",
"description": "Start a countdown from the menu bar or the add-on's page.",
"author": "Ledge examples",
"capabilities": ["hud"],
"executable": "Timer",
"icon": "Assets/Icon.png",
"surfaces": ["settings-page", "activity", "lock-screen-row", "menu-bar-tile"],
"kit": { "minAPI": "0.13.0" },
"category": "Productivity",
"creator": { "name": "Ledge examples" },
"source": { "repository": "https://github.com/your-account/timer" }
}The icon
A real PNG, no larger than 2048 by 2048 pixels and 4 MB. Packages in the Store must include Assets/Icon.png, and you must own it or have permission to use it.
Validation errors
AddOnManifest.validate(), which Ledge also runs, throws a ManifestValidationError. The CLI prints the same message:
| Error | Message |
|---|---|
invalidField(name) | Invalid manifest field: name. |
unsupportedProtocol(n) | Unsupported protocol version: n. Supported: 1 and 2. |
unsupportedCapability(c) | Malformed capability name: c. |