Skip to content

Commit 01667d8

Browse files
eli-w-kingcwebster-99Copilotjoshspicer
authored
vscode onboarding (#307262)
* feat: welcome onboarding walkthrough variations A/B/C/D * improve onboarding: sign-in CTA, keyboard mapping, skeleton themes, extensions step * fix theme colors, keyboard mapping hint, clickable session cards, extension styling in B * feat: add Variation E - in-context UI tour with spotlight overlay * polish: cleaner theme skeletons, keyboard mapping pills, and session cards * fix tour alignment: ID-based targeting, centered popovers, welcome tab setup * tour: add sign-in as final step * removed variations * updated layout to match sessions experience * refined * Feature clean up and polish * Refactor onboarding layout and styles for improved user experience * updated ghe button * removed other variations. changed command to Welcome Onboarding 2026 * removed keyboard maps for cursor and windsurf, added more theme options * added support for other ides * Add telemetry * Addressing code review comments * Remove 2 extension reccs and add setting to control onboarding * Remove button click from feature cards and update command category * - Removed the preview properties from IOnboardingThemeOption and related theme options. - Deleted IOnboardingKeymapOption interface and ONBOARDING_KEYMAP_OPTIONS array. - Consolidated AI collaboration preferences into a single enum and options array. - Added new SVG files for theme previews: dark 2026, high contrast dark, high contrast light, light 2026, solarized dark, and solarized light. * Refine agent sessions step and footer layout - Rename Background Agents to Copilot CLI - Move video tutorials link to bottom of content area (above footer) - Move sign-in nudge button to footer left with visible border - Remove agents tutorial link and sessions-docs separator - Add footerLeft container for last-step footer elements - Remove unused _renderSignInNudge method - Make doc-link icon inherit link color * Refactor onboarding service and update startup page * Resolve merge conflicts, move theme options to product.json, default onboarding setting to false Agent-Logs-Url: https://github.com/microsoft/vscode/sessions/da410dab-8ffb-4cc5-9afd-6e968b0c5ed6 Co-authored-by: cwebster-99 <60238438+cwebster-99@users.noreply.github.com> * Update src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.contribution.ts * Update src/vs/workbench/contrib/welcomeGettingStarted/browser/startupPage.ts Co-authored-by: Josh Spicer <23246594+joshspicer@users.noreply.github.com> * Fix timing for onboarding widget on startup * update distro to microsoft/vscode-distro@84f56fc * pass --skip-welcome --------- Co-authored-by: cwebster-99 <cowebster@microsoft.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: cwebster-99 <60238438+cwebster-99@users.noreply.github.com> Co-authored-by: Josh Spicer <23246594+joshspicer@users.noreply.github.com>
1 parent 46fe42c commit 01667d8

19 files changed

+2845
-4
lines changed

build/lib/i18n.resources.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,10 @@
294294
"name": "vs/workbench/contrib/welcomeGettingStarted",
295295
"project": "vscode-workbench"
296296
},
297+
{
298+
"name": "vs/workbench/contrib/welcomeOnboarding",
299+
"project": "vscode-workbench"
300+
},
297301
{
298302
"name": "vs/workbench/contrib/welcomePage",
299303
"project": "vscode-workbench"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "code-oss-dev",
33
"version": "1.116.0",
4-
"distro": "8c8cff4b820485d6eae5cdf5bf0e1f30f7dbb995",
4+
"distro": "84f56fc18b7c65a62bf54eb70db2d4d24378a0d2",
55
"author": {
66
"name": "Microsoft Corporation"
77
},

product.json

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,125 @@
156156
"GitHub.copilot-chat"
157157
]
158158
},
159+
"onboardingKeymaps": [
160+
{
161+
"id": "vscode",
162+
"label": "VS Code",
163+
"description": "Default keyboard mapping"
164+
},
165+
{
166+
"id": "sublime",
167+
"label": "Sublime Text",
168+
"extensionId": "ms-vscode.sublime-keybindings",
169+
"description": "Keyboard mapping from Sublime Text"
170+
},
171+
{
172+
"id": "intellij",
173+
"label": "IntelliJ / JetBrains",
174+
"extensionId": "k--kato.intellij-idea-keybindings",
175+
"description": "Keyboard mapping from IntelliJ IDEA"
176+
},
177+
{
178+
"id": "vim",
179+
"label": "Vim",
180+
"extensionId": "vscodevim.vim",
181+
"description": "Vim modal editing"
182+
},
183+
{
184+
"id": "eclipse",
185+
"label": "Eclipse",
186+
"extensionId": "alphabotsec.vscode-eclipse-keybindings",
187+
"description": "Keyboard mapping from Eclipse"
188+
},
189+
{
190+
"id": "notepadpp",
191+
"label": "Notepad++",
192+
"extensionId": "ms-vscode.notepadplusplus-keybindings",
193+
"description": "Keyboard mapping from Notepad++"
194+
}
195+
],
196+
"onboardingExtensions": [
197+
{
198+
"id": "ms-vscode-remote.remote-containers",
199+
"name": "Dev Containers",
200+
"publisher": "Microsoft",
201+
"description": "Develop inside a container with a full-featured editor",
202+
"icon": "remote-explorer"
203+
},
204+
{
205+
"id": "ms-azuretools.vscode-docker",
206+
"name": "Docker",
207+
"publisher": "Microsoft",
208+
"description": "Build, manage, and deploy containerized applications",
209+
"icon": "package"
210+
},
211+
{
212+
"id": "dbaeumer.vscode-eslint",
213+
"name": "ESLint",
214+
"publisher": "Microsoft",
215+
"description": "Find and fix problems in your JavaScript code",
216+
"icon": "lightbulb"
217+
},
218+
{
219+
"id": "GitHub.vscode-pull-request-github",
220+
"name": "GitHub Pull Requests",
221+
"publisher": "GitHub",
222+
"description": "Review and manage GitHub pull requests and issues",
223+
"icon": "git-pull-request"
224+
},
225+
{
226+
"id": "ms-python.python",
227+
"name": "Python",
228+
"publisher": "Microsoft",
229+
"description": "Rich Python language support with IntelliSense and debugging",
230+
"icon": "symbol-misc"
231+
},
232+
{
233+
"id": "ms-vscode-remote.remote-ssh",
234+
"name": "Remote - SSH",
235+
"publisher": "Microsoft",
236+
"description": "Open folders and files on a remote machine via SSH",
237+
"icon": "remote"
238+
}
239+
],
240+
"onboardingThemes": [
241+
{
242+
"id": "dark-2026",
243+
"label": "Dark 2026",
244+
"themeId": "Dark 2026",
245+
"type": "dark"
246+
},
247+
{
248+
"id": "hc-dark",
249+
"label": "Dark High Contrast",
250+
"themeId": "Default High Contrast",
251+
"type": "hcDark"
252+
},
253+
{
254+
"id": "solarized-dark",
255+
"label": "Solarized Dark",
256+
"themeId": "Solarized Dark",
257+
"type": "dark"
258+
},
259+
{
260+
"id": "light-2026",
261+
"label": "Light 2026",
262+
"themeId": "Light 2026",
263+
"type": "light"
264+
},
265+
{
266+
"id": "hc-light",
267+
"label": "Light High Contrast",
268+
"themeId": "Default High Contrast Light",
269+
"type": "hcLight"
270+
},
271+
{
272+
"id": "solarized-light",
273+
"label": "Solarized Light",
274+
"themeId": "Solarized Light",
275+
"type": "light"
276+
}
277+
],
159278
"builtInExtensionsEnabledWithAutoUpdates": [
160279
"GitHub.copilot-chat"
161280
]

src/vs/base/common/product.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,10 @@ export interface IProductConfiguration {
236236

237237
readonly extensionConfigurationPolicy?: IStringDictionary<IPolicy>;
238238

239+
readonly onboardingKeymaps?: readonly IProductOnboardingKeymap[];
240+
readonly onboardingExtensions?: readonly IProductOnboardingExtension[];
241+
readonly onboardingThemes?: readonly IProductOnboardingTheme[];
242+
239243
readonly embedded?: IEmbeddedProductConfiguration;
240244

241245
/**
@@ -250,6 +254,28 @@ export interface IProductConfiguration {
250254
};
251255
}
252256

257+
export interface IProductOnboardingKeymap {
258+
readonly id: string;
259+
readonly label: string;
260+
readonly extensionId?: string;
261+
readonly description: string;
262+
}
263+
264+
export interface IProductOnboardingExtension {
265+
readonly id: string;
266+
readonly name: string;
267+
readonly publisher: string;
268+
readonly description: string;
269+
readonly icon: string;
270+
}
271+
272+
export interface IProductOnboardingTheme {
273+
readonly id: string;
274+
readonly label: string;
275+
readonly themeId: string;
276+
readonly type: 'dark' | 'light' | 'hcDark' | 'hcLight';
277+
}
278+
253279
export type IEmbeddedProductConfiguration = Pick<IProductConfiguration,
254280
'nameShort' |
255281
'nameLong' |

src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.contribution.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,13 @@ configurationRegistry.registerConfiguration({
337337
default: false,
338338
deprecationMessage: localize('deprecationMessage', "Deprecated, use the global `workbench.reduceMotion`."),
339339
description: localize('workbench.welcomePage.preferReducedMotion', "When enabled, reduce motion in welcome page.")
340+
},
341+
'workbench.welcomePage.experimentalOnboarding': {
342+
scope: ConfigurationScope.APPLICATION,
343+
type: 'boolean',
344+
default: true,
345+
tags: ['experimental'],
346+
description: localize('workbench.welcomePage.experimentalOnboarding', "When enabled, show the new onboarding experience instead of the classic walkthrough on first launch.")
340347
}
341348
}
342349
});

src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,7 @@ export class GettingStartedPage extends EditorPane {
994994
const telemetryNotice = $('p.telemetry-notice');
995995
this.buildTelemetryFooter(telemetryNotice);
996996
footer.appendChild(telemetryNotice);
997-
} else if (!this.productService.openToWelcomeMainPage && this.showFeaturedWalkthrough && this.storageService.isNew(StorageScope.APPLICATION)) {
997+
} else if (!this.productService.openToWelcomeMainPage && this.showFeaturedWalkthrough && this.storageService.isNew(StorageScope.APPLICATION) && !this.configurationService.getValue<boolean>('workbench.welcomePage.experimentalOnboarding')) {
998998
const firstSessionDateString = this.storageService.get(firstSessionDateStorageKey, StorageScope.APPLICATION) || new Date().toUTCString();
999999
const daysSinceFirstSession = ((+new Date()) - (+new Date(firstSessionDateString))) / 1000 / 60 / 60 / 24;
10001000
const fistContentBehaviour = daysSinceFirstSession < 1 ? 'openToFirstCategory' : 'index';

src/vs/workbench/contrib/welcomeGettingStarted/browser/startupPage.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import { IContextKeyService } from '../../../../platform/contextkey/common/conte
3131
import { AuxiliaryBarMaximizedContext } from '../../../common/contextkeys.js';
3232
import { mainWindow } from '../../../../base/browser/window.js';
3333
import { getActiveElement } from '../../../../base/browser/dom.js';
34+
import { IOnboardingService } from '../../welcomeOnboarding/common/onboardingService.js';
35+
import { ONBOARDING_STORAGE_KEY } from '../../welcomeOnboarding/common/onboardingTypes.js';
3436

3537
export const restoreWalkthroughsConfigurationKey = 'workbench.welcomePage.restorableWalkthroughs';
3638
export type RestoreWalkthroughsConfigurationValue = { folder: string; category?: string; step?: string };
@@ -78,7 +80,6 @@ export class StartupPageEditorResolverContribution extends Disposable implements
7880
export class StartupPageRunnerContribution extends Disposable implements IWorkbenchContribution {
7981

8082
static readonly ID = 'workbench.contrib.startupPageRunner';
81-
8283
constructor(
8384
@IConfigurationService private readonly configurationService: IConfigurationService,
8485
@IEditorService private readonly editorService: IEditorService,
@@ -91,9 +92,16 @@ export class StartupPageRunnerContribution extends Disposable implements IWorkbe
9192
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
9293
@IStorageService private readonly storageService: IStorageService,
9394
@INotificationService private readonly notificationService: INotificationService,
94-
@IContextKeyService private readonly contextKeyService: IContextKeyService
95+
@IContextKeyService private readonly contextKeyService: IContextKeyService,
96+
@IOnboardingService private readonly onboardingService: IOnboardingService,
9597
) {
9698
super();
99+
100+
// Show onboarding overlay immediately (before waiting for lifecycle restore)
101+
if (!this.environmentService.skipWelcome && this.configurationService.getValue<boolean>('workbench.welcomePage.experimentalOnboarding')) {
102+
this.tryShowOnboarding();
103+
}
104+
97105
this.run().then(undefined, onUnexpectedError);
98106
this._register(this.editorService.onDidCloseEditor((e) => {
99107
if (e.editor instanceof GettingStartedInput) {
@@ -225,6 +233,20 @@ export class StartupPageRunnerContribution extends Disposable implements IWorkbe
225233

226234
return true; // do not steal focus
227235
}
236+
237+
private tryShowOnboarding(): void {
238+
if (this.storageService.get(ONBOARDING_STORAGE_KEY, StorageScope.PROFILE)) {
239+
return; // onboarding already completed
240+
}
241+
242+
// Show the onboarding overlay on top of the welcome page
243+
this.onboardingService.show();
244+
245+
// Mark onboarding as completed when dismissed
246+
this._register(this.onboardingService.onDidDismiss(() => {
247+
this.storageService.store(ONBOARDING_STORAGE_KEY, true, StorageScope.PROFILE, StorageTarget.USER);
248+
}));
249+
}
228250
}
229251

230252
function isStartupPageEnabled(configurationService: IConfigurationService, contextService: IWorkspaceContextService, environmentService: IWorkbenchEnvironmentService) {
Lines changed: 16 additions & 0 deletions
Loading
Lines changed: 16 additions & 0 deletions
Loading
Lines changed: 16 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)