Quick start
Write an add-on in Swift with LedgeKit, package it as a .ledgeaddon folder, and load it into your own Ledge.
What you need
- macOS 14 Sonoma or later
- Swift 6, from Xcode or the Swift toolchain
- Ledge, to load and try your add-on
LedgeKit is public, so you don't need a GitHub account to use it. To check your toolchain, clone it and run its tests:
git clone https://github.com/Ammyy9908/LedgeKit.git
cd LedgeKit
swift test1. Lay out the package
An add-on is an ordinary Swift package with a manifest and an icon beside it:
my-addon/
├── Package.swift
├── addon.json
├── Assets/
│ └── Icon.png
├── Sources/
│ └── MyAddOn/
│ └── main.swift
├── Tests/
└── README.md2. Depend on LedgeKit
Pin the released SDK to an exact version, so the build is the same on every machine:
// swift-tools-version: 6.0
import PackageDescription
let package = Package(
name: "MyAddOn",
platforms: [.macOS(.v14)],
dependencies: [
.package(url: "https://github.com/Ammyy9908/LedgeKit.git", exact: "0.1.0")
],
targets: [
.executableTarget(name: "MyAddOn", dependencies: ["LedgeKit"])
]
)While you work on LedgeKit itself, you can point at a checkout instead with .package(path: "../LedgeKit").
3. Write the worker
AddOnWorker.run reads Ledge's request, calls your handler and writes the response. Your code only answers the request:
import LedgeKit
@main
struct MyAddOn {
static func main() async {
await AddOnWorker.run { request in
// Check the operation and inputs before doing anything.
guard ["read", "write"].contains(request.operation) else {
return AddOnResponse(value: nil, error: "Unsupported operation.")
}
return AddOnResponse(value: request.liked ?? false)
}
}
}The worker covers the request, the response and the limits Ledge enforces.
4. Describe it in addon.json
{
"id": "my-addon",
"version": "1.0.0",
"protocolVersion": 1,
"name": "My Add-on",
"summary": "One line for the Store",
"description": "A sentence or two about what it does.",
"author": "Your name",
"capabilities": ["spotify-library"],
"executable": "MyAddOn",
"icon": "Assets/Icon.png"
}Check it with the ledgekit CLI. Every field is described in addon.json.
5. Build and package
Build a release binary, then copy it into a folder with the manifest and icon. The executable's file name must match executable in the manifest.
swift test
swift build -c release
bin="$(swift build -c release --show-bin-path)"
mkdir -p MyAddOn.ledgeaddon/Assets
cp "$bin/MyAddOn" MyAddOn.ledgeaddon/
cp addon.json MyAddOn.ledgeaddon/
cp Assets/Icon.png MyAddOn.ledgeaddon/Assets/
codesign --force --sign - MyAddOn.ledgeaddon/MyAddOn6. Load it into Ledge
In Ledge, open Settings → Add-on Store, choose Load Add-on… and pick MyAddOn.ledgeaddon. Ledge checks the package and asks you to trust it.
For a complete add-on to copy from, read Spotify Likes in LedgeAddOns. It has tests that run without a Spotify account, and a script that builds the package.