refactor(settings): migrate api.extensions consumers to api.features strict registry
The app/index.js feature toggle handler and the Settings > Features
list both talked through api.extensions.*, which routes to the v1
tile:extensions:* handlers backed by the legacy SQLite extensions
table plus a runtime windowList shim. Both surfaces collapse onto the
unified feature registry via api.features.*.
Notable behavioural changes callers absorb:
- Add Feature button in Settings > Features is removed. Arbitrary
folder-add wrote to the legacy extensions SQL table, which the
unified registry does not read. Users install/develop features
through the dedicated features-manager UI: tile:features:install
for atproto installs, tile:features:dev-create for local scaffolds.
- Reload button is shown unconditionally now rather than running-only.
Without tile:extensions:windowList we lose the isRunning hint; the
dev-reload IPC reports no active tiles gracefully when a feature
is not currently loaded.
- Datastore-external features toggle via features.enable / .disable
on the registry-backed path. api.extensions.load / .unload never
existed on the preload surface; that code path was already dead.
- Response shapes differ: api.features.list returns { entries: [...] }
with full FeatureRegistryEntry shape, where api.extensions.list
returned { success, data: [...] } with runtime {id, manifest, status}.
Consumer code adapts to the registry entry shape: entry.source.type,
entry.disabled, entry.name.
- browseBtn folder picker switches from api.extensions.pickFolder
returning { success, data: { path } } to api.features.devPickDirectory
returning { path } on success or { canceled: true } on cancel.