States
Settings › Plugins shows each plugin’s state:
Declared contributions (commands, menus, themes, settings pages, …) are live as soon as the plugin is enabled, before any code is loaded.
Activation
Code is instantiated lazily, when one of the plugin’s commands runs or when an event listed inactivation fires (see Manifest › Activation). On each new instance the IDE calls Plugin::activate; subscribe to events and restore state there. An error from activate fails the activation.
An instance unused for 5 minutes is reclaimed: deactivate runs and the plugin is not running again until its next event. on-schedule activates it when due but does not keep it alive. Keep nothing in memory you can’t rebuild in activate.
Events
Subscribe in code with
host::subscribe(EventKind::…) (it lasts for the session, across idle reclaim) or declare activation = ["on-event:<kind>"] to receive events before first use. host::subscribe_paths(kind, globs) (API 1.3) narrows file-opened, file-saved and files-changed to project-relative globs; the host filters before waking the plugin.
Events arrive in batches at Plugin::handle_events, oldest first, per window. A running plugin gets them within a fraction of a second; an idle one collects them for 2 seconds before it is woken, so frequent events don’t keep it alive.
Kinds are strings, so later IDEs can add kinds without changing the API. An IDE refuses a kind it doesn’t know with invalid; a kind newer than the plugin’s SDK arrives as Event::Other { kind, data } with JSON data. Match the SDK’s event enums with a _ arm.
Background work
Commands, events and activation have 5 seconds. For longer work, open a task:report or is_cancelled renews that budget. The task shows with the IDE’s background tasks.
Storage
host::storage holds at most 64 MiB per plugin, counting the UTF-8 bytes of keys and values. Use plugin_dir() for caches or generated files larger than that. Storage is per plugin, not per version, so an update keeps it.
Settings
A plugin declares its settings with a JSON schema; the IDE generates the page under Settings › Plugins (searchable, with project-level overrides):boolean, string (optionally with enum or multiline), number and integer, each with a default. Read values with host::setting, setting_bool, setting_string or setting_number: you get the user’s value (project over global) or the schema’s default, and a stored value of the wrong type falls back to the default. Subscribe to settings-changed (API 1.4) to react to changes.
API 1.3 adds multiple pages ([[contributes.settings.pages]]), groups, string lists, tables and action buttons that run one of the plugin’s commands. See plugins/README.md and the settings-pages fixture.
Secrets are not settings: declare them with [[contributes.secrets]] (see Permissions and capabilities).
Reload, update and roll back
- Reload while developing: select the plugin in Settings › Plugins and click Reload from disk, or run the Reload Plugins action. Linked plugins are read from their folder, so a rebuild plus reload picks up new code and manifest changes.
- Updates: the IDE checks the marketplace daily. When it finds newer versions of installed plugins it says so once, with Update All; the gear menu has Update All Plugins too. An update that asks for nothing new keeps the existing grants.
- Versions on disk: installed plugins live in
<app-data>/plugins/<id>/<version>/with anactivepointer that is switched only once the new version is in place. If an update’s code fails to start the first time, the IDE rolls back to the previous version automatically and tells you why. Roll Back to<version>in the plugin’s details does it by hand. - Disable and uninstall: disabling stops the code and withdraws its contributions; storage stays. Uninstalling removes the plugin, its storage and its private directory.