esc

What Ledge supports

A Ledge supports everything up to the LedgeKit it was built with. Declare the oldest LedgeKit your add-on needs as kit.minAPI, and an older Ledge says it needs an update instead of installing something it can't run.

What each release added

LedgeKitSurfacesCalls, events and fields
0.3.0Sessions: one long-lived program per add-on (protocol 2)
0.5.0settings-page, widgetStored settings, events from controls
0.7.0player-actionAccounts Ledge manages, the settings page's account row
0.8.0playerThe ••• menu entry and Playing Next
0.9.0onEnvironmentChange
0.10.0activityActivity placements
0.11.0lock-screen-row, menu-bar-tile
0.12.0notch-pageThe Markdown editor and .ended
0.13.0onVisibilityChange, dataFolder(), showPage(), openSettings(), holdOpen(_:) and notch-control; activity kind, accessibilityValue and .attention; confirmed buttons and keywords
0.14.0No new add-on API: the ledgekit tool, LedgeKitHost, check, run and shots
0.17.0A widget's compactContent, for pairs side by side
0.16.0ai-toolTools for AI apps: show(tools:), onTool
0.15.0A widget's size: small, medium or large

Set kit.minAPI to the newest row whose features you use. ledgekit check flags anything newer than thekit.minAPI you declared, and every surface page names the release it arrived in, as does each type in the API reference.

A patch release, like 0.14.2 was, changes the tools and the docs but not what an add-on can ask of Ledge, so it isn't a row. Pin it in Package.swift and keep kit.minAPI at its minor's level, like 0.14.0: every Ledge on 0.14.0 runs the add-on.

When Ledge says no

Ledge never half-draws. A surface over a limit, with a repeated id, or not listed in surfaces isn't drawn, and the last good one stays. A call your capabilities don't cover, or made outside the moments Ledge allows, fails with a reason your add-on receives as an error. Either way Ledge writes one line to its log:

log stream --predicate 'subsystem == "app.ledge.macos"' | grep add-on

ledgekit check shows the same refusals without Ledge, and is where to find them first. Handle a refusal rather than assuming a call worked: a user can turn off an add-on's activities or its page in the notch at any time.

On an older Ledge

  • An add-on whose kit.minAPI is newer than the Ledge's LedgeKit shows as needing an update and isn't installed.
  • A capability the Ledge doesn't know isn't an error: the add-on installs and that capability stays off.
  • A placement or field the add-on's LedgeKit doesn't know is sent in a form it can read: an add-on built for 0.12 hears outranked where a newer one hears stale.