Skip to content

plugins: store installed plugins in storage rather than paths#298352

Merged
connor4312 merged 2 commits intomainfrom
connor4312/agent-install-plugin-cleanup
Feb 27, 2026
Merged

plugins: store installed plugins in storage rather than paths#298352
connor4312 merged 2 commits intomainfrom
connor4312/agent-install-plugin-cleanup

Conversation

@connor4312
Copy link
Copy Markdown
Member

This simplifies some things and sets the groundwork for more special things (like updating and disk cleanup) that we'll do with marketplace plugins.

This simplifies some things and sets the groundwork for more special
things (like updating and disk cleanup) that we'll do with marketplace
plugins.
Copilot AI review requested due to automatic review settings February 27, 2026 21:13
@connor4312 connor4312 enabled auto-merge (squash) February 27, 2026 21:13
@connor4312 connor4312 self-assigned this Feb 27, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR shifts “installed marketplace plugins” tracking from chat.plugins.paths configuration to a storage-backed model, and wires that into plugin discovery so marketplace installs can be managed independently of user config.

Changes:

  • Add storage-backed installed plugin tracking to PluginMarketplaceService (observable list + add/remove/enable APIs) and make metadata lookup use that store.
  • Refactor agent plugin discovery into a shared base, and add a new discovery implementation for marketplace-installed plugins.
  • Update install/uninstall flows and UI actions to register/remove plugins via the new installed-plugins storage rather than editing chat.plugins.paths.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/vs/workbench/contrib/chat/test/common/plugins/pluginMarketplaceService.test.ts Updates metadata lookup tests to use storage-backed installed plugins.
src/vs/workbench/contrib/chat/common/plugins/pluginMarketplaceService.ts Introduces storage-backed installed plugin list + APIs; makes metadata lookup synchronous from storage.
src/vs/workbench/contrib/chat/common/plugins/pluginInstallService.ts Updates install contract to register installs in storage; removes uninstall API.
src/vs/workbench/contrib/chat/common/plugins/agentPluginServiceImpl.ts Refactors discovery into an abstract base and adds marketplace-installed discovery.
src/vs/workbench/contrib/chat/common/plugins/agentPluginService.ts Adds remove() to IAgentPlugin to support uninstall/removal from discovery source.
src/vs/workbench/contrib/chat/browser/pluginInstallService.ts Installs now register in IPluginMarketplaceService instead of updating config paths.
src/vs/workbench/contrib/chat/browser/chat.contribution.ts Registers the new MarketplaceAgentPluginDiscovery.
src/vs/workbench/contrib/chat/browser/agentPluginsView.ts Uninstall action now calls plugin.remove() instead of going through IPluginInstallService.
Comments suppressed due to low confidence (3)

src/vs/workbench/contrib/chat/common/plugins/pluginMarketplaceService.ts:129

  • installedPluginsMemento.fromStorage currently accepts any JSON array without validating element shape. If storage is corrupted (e.g. contains null, a non-object, or a pluginUri without proper URI shape), later code can throw when accessing entry.pluginUri or calling toString() in MarketplaceAgentPluginDiscovery. Consider validating each entry and reviving/normalizing pluginUri (e.g. via URI.from(...) / URI.revive(...)) while dropping invalid entries to keep plugin discovery resilient to bad storage.
const installedPluginsMemento = observableMemento<readonly IStoredInstalledPlugin[]>({
	defaultValue: [],
	key: 'chat.plugins.installed.v1',
	toStorage: value => JSON.stringify(value),
	fromStorage: value => {
		const parsed = JSON.parse(value);
		return Array.isArray(parsed) ? parsed : [];
	},
});

src/vs/workbench/contrib/chat/common/plugins/pluginMarketplaceService.ts:350

  • addInstalledPlugin returns early when an entry already exists for pluginUri, which prevents updating persisted metadata (description/version/readmeUri/etc.) for an already-installed plugin. This can leave the installed plugin list showing stale marketplace info. Consider updating the existing entry’s plugin field (while preserving its current enabled state) when the plugin is already present.
	addInstalledPlugin(pluginUri: URI, plugin: IMarketplacePlugin): void {
		const current = this.installedPlugins.get();
		if (current.some(e => isEqual(e.pluginUri, pluginUri))) {
			return;
		}
		this._installedPluginsStore.set([...current, { pluginUri, plugin, enabled: true }], undefined);
	}

src/vs/workbench/contrib/chat/common/plugins/pluginMarketplaceService.ts:361

  • New storage-backed installed plugin behavior (installedPlugins observable + add/remove/enable APIs) doesn’t appear to have unit coverage for persistence across service instances, enable/disable toggling, and removal behavior. Adding tests around these scenarios would help prevent regressions in the new storage contract.
	setInstalledPluginEnabled(pluginUri: URI, enabled: boolean): void {
		const current = this.installedPlugins.get();
		this._installedPluginsStore.set(
			current.map(e => isEqual(e.pluginUri, pluginUri) ? { ...e, enabled } : e),
			undefined,

@connor4312 connor4312 merged commit 3bc832a into main Feb 27, 2026
20 checks passed
@connor4312 connor4312 deleted the connor4312/agent-install-plugin-cleanup branch February 27, 2026 22:37
DonJayamanne pushed a commit that referenced this pull request Mar 2, 2026
* plugins: store installed plugins in storage rather than paths

This simplifies some things and sets the groundwork for more special
things (like updating and disk cleanup) that we'll do with marketplace
plugins.

* fix
@vs-code-engineering vs-code-engineering bot locked and limited conversation to collaborators Apr 13, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants