handle when more than chatAgentRecommendation comes from a single extension (#282911)

* handle when more than chatAgentRecommendation come from a single extension

* bump distro
This commit is contained in:
Josh Spicer
2025-12-11 17:43:54 -08:00
committed by GitHub
parent ca35590272
commit bd1dbe334b
2 changed files with 10 additions and 11 deletions

View File

@@ -1,7 +1,7 @@
{ {
"name": "code-oss-dev", "name": "code-oss-dev",
"version": "1.108.0", "version": "1.108.0",
"distro": "ac62b183885af851634b215f084a75e84d439948", "distro": "30bf5c1b117940f64d2dc13a89612f14618f1c77",
"author": { "author": {
"name": "Microsoft Corporation" "name": "Microsoft Corporation"
}, },

View File

@@ -18,6 +18,8 @@ import { IWorkbenchExtensionManagementService } from '../../../../services/exten
import { CHAT_CATEGORY } from './chatActions.js'; import { CHAT_CATEGORY } from './chatActions.js';
import { IChatSessionRecommendation } from '../../../../../base/common/product.js'; import { IChatSessionRecommendation } from '../../../../../base/common/product.js';
import { ExtensionIdentifier } from '../../../../../platform/extensions/common/extensions.js'; import { ExtensionIdentifier } from '../../../../../platform/extensions/common/extensions.js';
import { ChatAgentLocation } from '../../common/constants.js';
import { IChatService } from '../../common/chatService.js';
const INSTALL_CONTEXT_PREFIX = 'chat.installRecommendationAvailable'; const INSTALL_CONTEXT_PREFIX = 'chat.installRecommendationAvailable';
@@ -34,7 +36,6 @@ export class ChatAgentRecommendation extends Disposable implements IWorkbenchCon
@IContextKeyService private readonly contextKeyService: IContextKeyService, @IContextKeyService private readonly contextKeyService: IContextKeyService,
) { ) {
super(); super();
const recommendations = this.productService.chatSessionRecommendations; const recommendations = this.productService.chatSessionRecommendations;
if (!recommendations?.length || !this.extensionGalleryService.isEnabled()) { if (!recommendations?.length || !this.extensionGalleryService.isEnabled()) {
return; return;
@@ -44,17 +45,17 @@ export class ChatAgentRecommendation extends Disposable implements IWorkbenchCon
this.registerRecommendation(recommendation); this.registerRecommendation(recommendation);
} }
this.refreshInstallAvailability();
const refresh = () => this.refreshInstallAvailability(); const refresh = () => this.refreshInstallAvailability();
this._register(this.extensionManagementService.onProfileAwareDidInstallExtensions(refresh)); this._register(this.extensionManagementService.onProfileAwareDidInstallExtensions(refresh));
this._register(this.extensionManagementService.onProfileAwareDidUninstallExtension(refresh)); this._register(this.extensionManagementService.onProfileAwareDidUninstallExtension(refresh));
this._register(this.extensionManagementService.onDidChangeProfile(refresh)); this._register(this.extensionManagementService.onDidChangeProfile(refresh));
this.refreshInstallAvailability();
} }
private registerRecommendation(recommendation: IChatSessionRecommendation): void { private registerRecommendation(recommendation: IChatSessionRecommendation): void {
const extensionKey = ExtensionIdentifier.toKey(recommendation.extensionId); const extensionKey = ExtensionIdentifier.toKey(recommendation.extensionId);
const commandId = `chat.installRecommendation.${extensionKey}`; const commandId = `chat.installRecommendation.${extensionKey}.${recommendation.name}`;
const availabilityContextId = `${INSTALL_CONTEXT_PREFIX}.${extensionKey}`; const availabilityContextId = `${INSTALL_CONTEXT_PREFIX}.${extensionKey}`;
const availabilityContext = new RawContextKey<boolean>(availabilityContextId, false).bindTo(this.contextKeyService); const availabilityContext = new RawContextKey<boolean>(availabilityContextId, false).bindTo(this.contextKeyService);
this.availabilityContextKeys.set(extensionKey, availabilityContext); this.availabilityContextKeys.set(extensionKey, availabilityContext);
@@ -70,7 +71,6 @@ export class ChatAgentRecommendation extends Disposable implements IWorkbenchCon
f1: false, f1: false,
category: CHAT_CATEGORY, category: CHAT_CATEGORY,
icon: Codicon.extensions, icon: Codicon.extensions,
precondition: ContextKeyExpr.equals(availabilityContextId, true),
menu: [ menu: [
{ {
id: MenuId.ChatNewMenu, id: MenuId.ChatNewMenu,
@@ -84,13 +84,13 @@ export class ChatAgentRecommendation extends Disposable implements IWorkbenchCon
override async run(accessor: ServicesAccessor): Promise<void> { override async run(accessor: ServicesAccessor): Promise<void> {
const commandService = accessor.get(ICommandService); const commandService = accessor.get(ICommandService);
const productService = accessor.get(IProductService); const productService = accessor.get(IProductService);
const chatService = accessor.get(IChatService);
const installPreReleaseVersion = productService.quality !== 'stable'; const installPreReleaseVersion = productService.quality !== 'stable';
await commandService.executeCommand('workbench.extensions.installExtension', recommendation.extensionId, { await commandService.executeCommand('workbench.extensions.installExtension', recommendation.extensionId, {
installPreReleaseVersion installPreReleaseVersion
}); });
await runPostInstallCommand(commandService, chatService, recommendation.postInstallCommand);
await runPostInstallCommand(commandService, recommendation.postInstallCommand);
} }
})); }));
} }
@@ -122,13 +122,12 @@ export class ChatAgentRecommendation extends Disposable implements IWorkbenchCon
} }
} }
async function runPostInstallCommand(commandService: ICommandService, commandId: string | undefined): Promise<void> { async function runPostInstallCommand(commandService: ICommandService, chatService: IChatService, commandId: string | undefined): Promise<void> {
if (!commandId) { if (!commandId) {
return; return;
} }
await waitForCommandRegistration(commandId); await waitForCommandRegistration(commandId);
await chatService.activateDefaultAgent(ChatAgentLocation.Chat);
try { try {
await commandService.executeCommand(commandId); await commandService.executeCommand(commandId);
} catch { } catch {