Path: blob/main/src/vs/workbench/contrib/chat/browser/claudePluginRecommendations.ts
13401 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { Disposable } from '../../../../base/common/lifecycle.js';6import { localize } from '../../../../nls.js';7import { INotificationService, NeverShowAgainScope, Severity } from '../../../../platform/notification/common/notification.js';8import { IWorkbenchContribution } from '../../../common/contributions.js';9import { IExtensionsWorkbenchService } from '../../extensions/common/extensions.js';10import { IChatService } from '../common/chatService/chatService.js';11import { IPluginMarketplaceService } from '../common/plugins/pluginMarketplaceService.js';1213export class AgentPluginRecommendations extends Disposable implements IWorkbenchContribution {14static readonly ID = 'workbench.contrib.agentPluginRecommendations';1516private _hasNotified = false;1718constructor(19@IChatService private readonly _chatService: IChatService,20@IPluginMarketplaceService private readonly _pluginMarketplaceService: IPluginMarketplaceService,21@INotificationService private readonly _notificationService: INotificationService,22@IExtensionsWorkbenchService private readonly _extensionsWorkbenchService: IExtensionsWorkbenchService,23) {24super();2526this._register(this._chatService.onDidSubmitRequest(() => {27if (!this._hasNotified) {28this._hasNotified = true;29this._checkForRecommendedPlugins();30}31}));32}3334private _checkForRecommendedPlugins(): void {35const recommended = this._pluginMarketplaceService.recommendedPlugins.get();36if (recommended.size === 0) {37return;38}3940// Build a set of installed plugin keys ("name@marketplace") from41// storage without triggering any network fetch.42const installedKeys = new Set<string>();43for (const entry of this._pluginMarketplaceService.installedPlugins.get()) {44const key = `${entry.plugin.name}@${entry.plugin.marketplace}`;45installedKeys.add(key);46}4748let uninstalledCount = 0;49for (const key of recommended) {50if (!installedKeys.has(key)) {51uninstalledCount++;52}53}5455if (uninstalledCount === 0) {56return;57}5859this._notificationService.prompt(60Severity.Info,61uninstalledCount === 162? localize('agentPluginRecommendation.one', "This workspace recommends 1 agent plugin.")63: localize('agentPluginRecommendation.many', "This workspace recommends {0} agent plugins.", uninstalledCount),64[{65label: localize('showPlugins', "Show Plugins"),66run: () => {67this._extensionsWorkbenchService.openSearch('@agentPlugins @recommended');68}69}],70{71neverShowAgain: {72id: 'agentPluginRecommendations.dismissed',73scope: NeverShowAgainScope.WORKSPACE,74isSecondary: true,75}76}77);78}79}808182