Plugin Registry
The plugin registry is a JSON manifest hosted at github.com/TableProApp/plugins. TablePro fetches it to populate Settings > Plugins > Browse and to handle auto-install when a user selects a database type with no loaded driver.Manifest Format
The registry file (plugins.json):
Entry Fields
Either
downloadURL/sha256 (flat fields) or the binaries array is required. When binaries is present, the app picks the matching architecture. Flat fields act as fallback for older app versions.Example Entry
A complete entry for the Oracle driver plugin:databaseTypeIds Mapping
ThedatabaseTypeIds field tells the app which registry plugin to install when a user picks a database type that has no loaded driver.
Publishing a Plugin
Tag the commit and push:Auto-Install Flow
1
User selects a database type with no loaded driver
2
App fetches registry, finds plugin by databaseTypeIds
3
Downloads ZIP, verifies SHA-256
4
Extracts bundle, verifies code signature, loads plugin
Plugin Compatibility
Every plugin binary declares the PluginKit version it was built against (pluginKitVersion). The app declares two values in PluginManager.swift:
currentPluginKitVersion: the version the running app ships.minimumCompatiblePluginKitVersion: the oldest version the app still loads.
[minimum, current] loads under the app and the runtime fills in any newer requirement from its default. The app accepts that whole range instead of an exact match.
When you change PluginKit:
- Additive change (a new requirement with a default, a new field on a non-frozen type): leave both versions alone. Installed plugins keep loading; the registry needs no re-publish.
- Breaking change (a removed or changed requirement, a frozen-layout change, a requirement without a default): raise
currentPluginKitVersionandminimumCompatiblePluginKitVersiontogether, then runscripts/release-all-plugins.sh <newVersion>so the registry carries binaries for the new version before the app ships.
pluginKitVersion is in the app’s range, so an additive bump is served by the existing binaries with no re-publish. After a breaking bump, scripts/check-registry-readiness.py --floor <min> --current <current> (run by the app release workflow) fails the release until every database driver has a compatible binary, so the app never ships ahead of its plugins.
If a connection’s driver is installed but its binary predates a breaking bump, opening the connection refreshes the registry and updates the driver in the background, then proceeds. The app does not block on this; if a compatible binary is not published yet, the connection reports that it is updating and retries on its own (on a timer and when the network returns), so no quit and reopen is needed.
The manifest is served through jsDelivr (cdn.jsdelivr.net/gh/TableProApp/plugins@main/plugins.json) and purged on each publish, so a new binary is visible within seconds rather than waiting out a CDN cache.
Drivers that most users reach for are bundled inside the app and ship in lockstep, so they never depend on the registry. Reserve registry-only distribution for the long tail, where a short, non-blocking update on first connect is acceptable.
Theme Distribution
Themes use the same manifest format withcategory: "theme". Key differences from driver plugins:
- Pure JSON data, no executable code
- No code signing required
- No
.tablepluginbundle - ZIP contains
.jsonfiles (validThemeDefinition) - Installed to
~/Library/Application Support/TablePro/Themes/Registry/ - Theme packs (multiple themes in one ZIP) are supported
