From 4fe2ba84078d0344256ee62b4df9a102692c100b Mon Sep 17 00:00:00 2001 From: Elijah King Date: Mon, 13 Apr 2026 15:37:22 -0700 Subject: [PATCH 1/5] onboarding: include theme preview SVGs in build output The theme preview SVGs were not bundled in desktop or web builds, causing blank theme cards for users running built products. Fixes #309380 --- build/gulpfile.vscode.ts | 1 + build/gulpfile.vscode.web.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/build/gulpfile.vscode.ts b/build/gulpfile.vscode.ts index 080d97f3197cf..1e216b7f5ad92 100644 --- a/build/gulpfile.vscode.ts +++ b/build/gulpfile.vscode.ts @@ -97,6 +97,7 @@ const vscodeResourceIncludes = [ // Welcome 'out-build/vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.{svg,png}', + 'out-build/vs/workbench/contrib/welcomeOnboarding/browser/media/*.svg', // Sessions 'out-build/vs/sessions/contrib/chat/browser/media/*.svg', diff --git a/build/gulpfile.vscode.web.ts b/build/gulpfile.vscode.web.ts index 3e6b29adfe9fa..9af2afecb38ba 100644 --- a/build/gulpfile.vscode.web.ts +++ b/build/gulpfile.vscode.web.ts @@ -74,6 +74,7 @@ export const vscodeWebResourceIncludes = [ // Welcome 'out-build/vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.{svg,png}', + 'out-build/vs/workbench/contrib/welcomeOnboarding/browser/media/*.svg', // Extensions 'out-build/vs/workbench/contrib/extensions/browser/media/{theme-icon.png,language-icon.svg}', From 1c425f74f2ecb0275f3119e5ac0a97c2fc600716 Mon Sep 17 00:00:00 2001 From: Elijah King Date: Mon, 13 Apr 2026 16:01:33 -0700 Subject: [PATCH 2/5] onboarding: trigger chat setup after sign-in to resolve entitlements After the user signs in through the onboarding walkthrough, trigger the full chat setup flow in the background (sign-up, extension install, entitlement resolution) so the 'Finish Setup' status bar indicator is resolved by the time onboarding completes. Uses disableChatViewReveal and DefaultSetup strategy to avoid showing dialogs or popping the chat panel during onboarding. Fixes #309529 --- .../browser/onboardingVariationA.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/welcomeOnboarding/browser/onboardingVariationA.ts b/src/vs/workbench/contrib/welcomeOnboarding/browser/onboardingVariationA.ts index fb0013c37aeaf..e405ec26cf3a3 100644 --- a/src/vs/workbench/contrib/welcomeOnboarding/browser/onboardingVariationA.ts +++ b/src/vs/workbench/contrib/welcomeOnboarding/browser/onboardingVariationA.ts @@ -30,7 +30,8 @@ import { IQuickInputService } from '../../../../platform/quickinput/common/quick import { IFileService } from '../../../../platform/files/common/files.js'; import { IPathService } from '../../../services/path/common/pathService.js'; import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js'; -import { InstallChatEvent, InstallChatClassification } from '../../chat/browser/chatSetup/chatSetup.js'; +import { InstallChatEvent, InstallChatClassification, ChatSetupStrategy } from '../../chat/browser/chatSetup/chatSetup.js'; +import { ICommandService } from '../../../../platform/commands/common/commands.js'; import { OnboardingStepId, ONBOARDING_STEPS, @@ -135,6 +136,7 @@ export class OnboardingVariationA extends Disposable implements IOnboardingServi @IFileService private readonly fileService: IFileService, @IPathService private readonly pathService: IPathService, @ITelemetryService private readonly telemetryService: ITelemetryService, + @ICommandService private readonly commandService: ICommandService, ) { super(); @@ -544,6 +546,11 @@ export class OnboardingVariationA extends Disposable implements IOnboardingServi if (account) { this._userSignedIn = true; this.telemetryService.publicLog2('commandCenter.chatInstall', { installResult: 'installed', installDuration: watch.elapsed(), signUpErrorCode: undefined, provider }); + // Run chat setup in the background (sign-up, extension install, entitlement resolution) + this.commandService.executeCommand('workbench.action.chat.triggerSetup', undefined, { + disableChatViewReveal: true, + setupStrategy: ChatSetupStrategy.DefaultSetup, + }); this._nextStep(); } } catch (error) { @@ -575,6 +582,10 @@ export class OnboardingVariationA extends Disposable implements IOnboardingServi if (account) { this._userSignedIn = true; this.telemetryService.publicLog2('commandCenter.chatInstall', { installResult: 'installed', installDuration: watch.elapsed(), signUpErrorCode: undefined, provider }); + this.commandService.executeCommand('workbench.action.chat.triggerSetup', undefined, { + disableChatViewReveal: true, + setupStrategy: ChatSetupStrategy.DefaultSetup, + }); this._nextStep(); } } catch (error) { From 84c57e3cd34c666727e5fef1cf3f91cfc98694da Mon Sep 17 00:00:00 2001 From: Elijah King Date: Mon, 13 Apr 2026 16:25:34 -0700 Subject: [PATCH 3/5] onboarding: add Extension Marketplace keybinding tip to extensions step Shows Cmd+Shift+X (Ctrl+Shift+X on Windows/Linux) in the extensions step subtitle so users know how to browse the full marketplace. Fixes #309617 --- .../browser/onboardingVariationA.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/vs/workbench/contrib/welcomeOnboarding/browser/onboardingVariationA.ts b/src/vs/workbench/contrib/welcomeOnboarding/browser/onboardingVariationA.ts index e405ec26cf3a3..1d4973c90845c 100644 --- a/src/vs/workbench/contrib/welcomeOnboarding/browser/onboardingVariationA.ts +++ b/src/vs/workbench/contrib/welcomeOnboarding/browser/onboardingVariationA.ts @@ -364,6 +364,8 @@ export class OnboardingVariationA extends Disposable implements IOnboardingServi this._renderAgentSessionsSubtitle(this.subtitleEl); } else if (stepId === OnboardingStepId.Personalize) { this._renderPersonalizeSubtitle(this.subtitleEl); + } else if (stepId === OnboardingStepId.Extensions) { + this._renderExtensionsSubtitle(this.subtitleEl); } else { this.subtitleEl.textContent = getOnboardingStepSubtitle(stepId); } @@ -757,6 +759,20 @@ export class OnboardingVariationA extends Disposable implements IOnboardingServi ); } + private _renderExtensionsSubtitle(container: HTMLElement): void { + clearNode(container); + const modifier = isMacintosh ? 'Cmd' : 'Ctrl'; + container.append( + localize('onboarding.extensions.subtitle.prefix', "Install extensions to enhance your workflow. Press "), + this._createKbd(localize({ key: 'onboarding.extensions.subtitle.modifier', comment: ['Keyboard modifier key'] }, "{0}", modifier)), + '+', + this._createKbd(localize('onboarding.extensions.subtitle.shift', "Shift")), + '+', + this._createKbd(localize('onboarding.extensions.subtitle.x', "X")), + localize('onboarding.extensions.subtitle.suffix', " to browse the Extension Marketplace."), + ); + } + private _createThemeCard(parent: HTMLElement, theme: IOnboardingThemeOption, allCards: HTMLElement[]): void { const card = this._registerStepFocusable(append(parent, $('div.onboarding-a-theme-card'))); allCards.push(card); From c6b7d69e48430ba15f3f473207b8b3622e397dbe Mon Sep 17 00:00:00 2001 From: Elijah King Date: Mon, 13 Apr 2026 16:32:48 -0700 Subject: [PATCH 4/5] onboarding: screenreader accessibility fixes - Add aria-label to extension install buttons with extension name (#309382) - Make feature cards (Local, Cloud, CLI, Inline) tabbable with role/aria-label (#309525) - Add ARIA alerts on theme, keymap, extension install, and AI preference actions (#309521) Fixes #309382 Fixes #309521 Fixes #309525 --- .../browser/onboardingVariationA.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/vs/workbench/contrib/welcomeOnboarding/browser/onboardingVariationA.ts b/src/vs/workbench/contrib/welcomeOnboarding/browser/onboardingVariationA.ts index c9117b6055fe7..9c2dcb921ed4a 100644 --- a/src/vs/workbench/contrib/welcomeOnboarding/browser/onboardingVariationA.ts +++ b/src/vs/workbench/contrib/welcomeOnboarding/browser/onboardingVariationA.ts @@ -32,6 +32,7 @@ import { IPathService } from '../../../services/path/common/pathService.js'; import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js'; import { InstallChatEvent, InstallChatClassification, ChatSetupStrategy } from '../../chat/browser/chatSetup/chatSetup.js'; import { ICommandService } from '../../../../platform/commands/common/commands.js'; +import { IAccessibilityService } from '../../../../platform/accessibility/common/accessibility.js'; import { OnboardingStepId, ONBOARDING_STEPS, @@ -137,6 +138,7 @@ export class OnboardingVariationA extends Disposable implements IOnboardingServi @IPathService private readonly pathService: IPathService, @ITelemetryService private readonly telemetryService: ITelemetryService, @ICommandService private readonly commandService: ICommandService, + @IAccessibilityService private readonly accessibilityService: IAccessibilityService, ) { super(); @@ -756,6 +758,7 @@ export class OnboardingVariationA extends Disposable implements IOnboardingServi } pill.classList.add('selected'); pill.setAttribute('aria-checked', 'true'); + this.accessibilityService.alert(localize('onboarding.keymap.selected.alert', "{0} keyboard mapping selected", keymap.label)); })); } const selectedKeymapIndex = keymapOptions.findIndex(k => k.id === this.selectedKeymapId); @@ -822,6 +825,7 @@ export class OnboardingVariationA extends Disposable implements IOnboardingServi } card.classList.add('selected'); card.setAttribute('aria-checked', 'true'); + this.accessibilityService.alert(localize('onboarding.theme.selected.alert', "{0} theme selected", theme.label)); })); this.stepDisposables.add(addDisposableListener(card, EventType.KEY_DOWN, (e: KeyboardEvent) => { @@ -868,6 +872,7 @@ export class OnboardingVariationA extends Disposable implements IOnboardingServi const installBtn = this._registerStepFocusable(append(row, $('button.onboarding-a-ext-install'))); installBtn.type = 'button'; installBtn.textContent = localize('onboarding.ext.install', "Install"); + installBtn.setAttribute('aria-label', localize('onboarding.ext.install.aria', "Install {0}", ext.name)); this.stepDisposables.add(addDisposableListener(installBtn, EventType.CLICK, () => { this._logAction('installExtension', undefined, ext.id); @@ -877,6 +882,8 @@ export class OnboardingVariationA extends Disposable implements IOnboardingServi () => { installBtn.textContent = localize('onboarding.ext.installed', "Installed"); installBtn.classList.add('installed'); + installBtn.setAttribute('aria-label', localize('onboarding.ext.installed.aria', "{0} installed", ext.name)); + this.accessibilityService.alert(localize('onboarding.ext.installed.alert', "{0} has been installed", ext.name)); }, () => { installBtn.textContent = localize('onboarding.ext.install', "Install"); @@ -1095,6 +1102,7 @@ export class OnboardingVariationA extends Disposable implements IOnboardingServi c.setAttribute('aria-checked', c.dataset.id === option.id ? 'true' : 'false'); } this._applyAiPreference(option.id); + this.accessibilityService.alert(localize('onboarding.aiPref.selected.alert', "{0} selected", option.label)); })); } const selectedAiIndex = ONBOARDING_AI_PREFERENCE_OPTIONS.findIndex(o => o.id === this.selectedAiMode); @@ -1175,7 +1183,10 @@ export class OnboardingVariationA extends Disposable implements IOnboardingServi } private _createFeatureCard(parent: HTMLElement, icon: ThemeIcon, title: string, description?: string): HTMLElement { - const card = append(parent, $('div.onboarding-a-feature-card')); + const card = this._registerStepFocusable(append(parent, $('div.onboarding-a-feature-card'))); + card.setAttribute('tabindex', '0'); + card.setAttribute('role', 'group'); + card.setAttribute('aria-label', title); const iconCol = append(card, $('div.onboarding-a-feature-icon')); iconCol.appendChild(renderIcon(icon)); const textCol = append(card, $('div.onboarding-a-feature-text')); From 4f49dbf42dda2faa5d70c05c9ee78e3a7f735c5a Mon Sep 17 00:00:00 2001 From: Elijah King Date: Tue, 14 Apr 2026 11:07:31 -0700 Subject: [PATCH 5/5] onboarding: add SVG resources to esbuild pipeline --- build/next/index.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/next/index.ts b/build/next/index.ts index 93c7a035c0635..3b530ea1e5184 100644 --- a/build/next/index.ts +++ b/build/next/index.ts @@ -278,6 +278,7 @@ const desktopResourcePatterns = [ // Media - images 'vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.svg', 'vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.png', + 'vs/workbench/contrib/welcomeOnboarding/browser/media/*.svg', 'vs/workbench/contrib/extensions/browser/media/{theme-icon.png,language-icon.svg}', 'vs/workbench/services/extensionManagement/common/media/*.svg', 'vs/workbench/services/extensionManagement/common/media/*.png', @@ -337,6 +338,7 @@ const serverWebResourcePatterns = [ // Media - images 'vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.svg', 'vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.png', + 'vs/workbench/contrib/welcomeOnboarding/browser/media/*.svg', 'vs/workbench/contrib/extensions/browser/media/*.svg', 'vs/workbench/contrib/extensions/browser/media/*.png', 'vs/workbench/services/extensionManagement/common/media/*.svg', @@ -363,6 +365,7 @@ const webResourcePatterns = [ // Media - images 'vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.svg', 'vs/workbench/contrib/welcomeGettingStarted/common/media/**/*.png', + 'vs/workbench/contrib/welcomeOnboarding/browser/media/*.svg', 'vs/workbench/contrib/extensions/browser/media/*.svg', 'vs/workbench/contrib/extensions/browser/media/*.png', 'vs/workbench/services/extensionManagement/common/media/*.svg',