Plugins that wanted a built-in app action (toggle the browser panel, open
Settings) faked its keyboard shortcut with a synthetic KeyboardEvent; that
silently breaks when the user rebinds or unbinds the shortcut
(browser-toggle catalog plugin).
- ctx.runAction(id) runs the same handler the keybinding dispatcher and
palette use: useKeybinds publishes its handler table through
registerBuiltinActionRunner, read at call time, so bindings never matter
- allowlist of view/navigation actions only (PLUGIN_APP_ACTIONS, typed
PluginAppActionId union); destructive / privileged ids are refused
- result-shaped, never throws: { ok: true } or { ok: false, reason:
'unknown' | 'denied' | 'unavailable', error } plus a console warning
- ctx.listActions() lists allowed ids with localized labels
- docs: API section, allowlist table, migration-table row; SDK exports