Change:
Currently if a user has a deprecated extension installed we just render that in the Extensions view. Looking at telemetry we noticed that users this is not a strong signal, and users still have a lot of deprecated extensions installed. Due to that I suggest that we nudge the users more about deprecated extensions. Especially if the deprecated extension has an alternative. As suggests we could show a general depreciation prompt if users have deprecated extensions installed and allowing not to show this prompt again. However I would love if the notification prompt offers the transition to the alternative extension if there is one. So not sure if it would be notification per deprecated extension? What do you think?
I think the notification is a general one guiding users to extensions view to see deprecated extensions. Users can take a necessary action from there.
Ok. It would be nice if the flow is smooth, for example there is an action that opens the correct extension in the Extensions view. But I guess you already have that in mind :)
Yes, there will be an action to list the deprecated extensions.
To verify: Shutdown VS Code Insiders From CLI install extension Open Insiders and wait until you get the prompt <img width="515" alt="image" src="https://user-"

Discussion:
<ins> /*--------------------------------------------------------------------------------------------- *  Copyright (c) Microsoft Corporation. All rights reserved. *  Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { IExtensionsWorkbenchService } from 'vs/workbench/contrib/extensions/common/extensions'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; import { localize } from 'vs/nls'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { SearchExtensionsAction } from 'vs/workbench/contrib/extensions/browser/extensionsActions'; import { distinct } from 'vs/base/common/arrays'; import { Disposable } from 'vs/base/common/lifecycle'; import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil'; export class DeprecatedExtensionsChecker extends Disposable implements IWorkbenchContribution { constructor( @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionManagementService extensionManagementService: IExtensionManagementService, @IStorageService private readonly storageService: IStorageService, @INotificationService private readonly notificationService: INotificationService, @IInstantiationService private readonly instantiationService: IInstantiationService, ) { super(); this.checkForDeprecatedExtensions(); this._register(extensionManagementService.onDidInstallExtensions(e => { const ids: string[] = []; for (const { local } of e) { if (local && extensionsWorkbenchService.local.find(extension => areSameExtensions(extension.identifier, local.identifier))?.deprecationInfo) { ids.push(local.identifier.id.toLowerCase()); } } if (ids.length) { this.setNotifiedDeprecatedExtensions(ids); } })); } private async checkForDeprecatedExtensions(): Promise<void> { if (this.storageService.getBoolean('extensionsAssistant/doNotCheckDeprecated', StorageScope.PROFILE, false)) { return; } const local = await this.extensionsWorkbenchService.queryLocal(); const previouslyNotified = this.getNotifiedDeprecatedExtensions(); const toNotify = local.filter(e => !!e.deprecationInfo).filter(e => !previouslyNotified.includes(e.identifier.id.toLowerCase())); if (toNotify.length) { this.notificationService.prompt( Severity.Warning, localize('deprecated extensions', "You have deprecated extensions installed. We recommend to review them and migrate to alternatives."), [{ label: localize('showDeprecated', "Show Deprecated Extensions"), run: async () => { this.setNotifiedDeprecatedExtensions(toNotify.map(e => e.identifier.id.toLowerCase())); const action = this.instantiationService.createInstance(SearchExtensionsAction, toNotify.map(extension => `@id:${extension.identifier.id}`).join(' ')); try { await action.run(); } finally { action.dispose(); } } }, { label: localize('neverShowAgain', "Don't Show Again"), isSecondary: true, run: () => this.storageService.store('extensionsAssistant/doNotCheckDeprecated', true, StorageScope.PROFILE, StorageTarget.USER) }] ); } } private getNotifiedDeprecatedExtensions(): string[] { return JSON.parse(this.storageService.get('extensionsAssistant/deprecated', StorageScope.PROFILE, '[]')); } private setNotifiedDeprecatedExtensions(notified: string[]): void { this.storageService.store('extensionsAssistant/deprecated', JSON.stringify(distinct([...this.getNotifiedDeprecatedExtensions(), ...notified])), StorageScope.PROFILE, StorageTarget.USER); } } </ins>

import { IStorageService } from 'vs/platform/storage/common/storage'; import { IStringDictionary } from 'vs/base/common/collections'; import { CONTEXT_KEYBINDINGS_EDITOR } from 'vs/workbench/contrib/preferences/common/preferences'; <ins> import { DeprecatedExtensionsChecker } from 'vs/workbench/contrib/extensions/browser/deprecatedExtensionsChecker'; </ins> // Singletons registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService, InstantiationType.Eager /* Auto updates extensions */);

workbenchRegistry.registerWorkbenchContribution(ExtensionEnablementWorkspaceTrustTransitionParticipant, LifecyclePhase.Restored); workbenchRegistry.registerWorkbenchContribution(ExtensionsCompletionItemsProvider, LifecyclePhase.Restored); workbenchRegistry.registerWorkbenchContribution(UnsupportedExtensionsMigrationContrib, LifecyclePhase.Eventually); <ins> workbenchRegistry.registerWorkbenchContribution(DeprecatedExtensionsChecker, LifecyclePhase.Eventually); </ins> if (isWeb) { workbenchRegistry.registerWorkbenchContribution(ExtensionStorageCleaner, LifecyclePhase.Eventually); }