Profiles and Settings Sync
Purpose and Scope
Profiles and Settings Sync solve a common customization problem: developers often want VS Code to feel different for different work modes, while still carrying important preferences across machines. A profile is a named set of customizations, such as settings, keyboard shortcuts, snippets, tasks, extensions, MCP server entries, and UI state. Settings Sync is the cross-machine mechanism that can synchronize user preferences, installed extensions, UI state, and profiles after sign-in. Together, they let a user maintain a stable default environment, create focused environments for particular projects or audiences, and recover familiar configuration on another machine without manually rebuilding the editor setup.
The repository evidence for this page is intentionally centered on settings as the durable, searchable unit of customization. The workbench migration file registers editor-setting migrations so existing user configuration can continue to mean the right thing after editor option names or structures evolve. The Copilot extension files define a settings search provider that can retrieve and rank settings by natural-language query, which is especially relevant when profiles and sync increase the amount of user configuration a person manages. The code-action type definitions show another settings-adjacent subsystem: configurable editor actions are organized by stable hierarchical kinds that can be filtered by invocation context. Sources: src/vs/workbench/contrib/codeEditor/browser/editorSettingsMigration.ts, extensions/copilot/src/platform/settingsEditor/common/settingsEditorSearchService.ts, src/vs/editor/contrib/codeAction/common/types.ts
Relevant Source Files
src/vs/workbench/contrib/codeEditor/browser/editorSettingsMigration.ts- Registers migrations for editor configuration keys by mapping editor migration items into workbench configuration migrations undereditor.*keys.src/vs/editor/contrib/codeAction/common/types.ts- Defines code action kinds, trigger sources, filtering rules, and auto-apply behavior that are part of the configurable editor experience users carry through settings and profiles.extensions/copilot/src/extension/prompt/vscode-node/settingsEditorSearchServiceImpl.ts- Implements Copilot-backed settings search, including embedding search, LLM-ranked suggestions, authentication checks, limits, progress reporting, and cancellation handling.extensions/copilot/src/extension/prompt/node/settingsEditorSearchResultsSelector.ts- Uses a chat endpoint to select the most relevant settings from embedding candidates, with a fixed timeout and low-temperature request.extensions/copilot/src/extension/prompts/node/settingsEditor/settingsEditorSuggestQueryPrompt.tsx- Defines the prompt contract that asks the model to return setting names only, up to two settings, one per line.extensions/copilot/src/platform/settingsEditor/common/settingsEditorSearchService.ts- Declares theISettingsEditorSearchServiceservice contract and a no-op implementation used when settings search is not provided.
Core Concepts
The official Profiles workflow treats the current configuration as the Default Profile. As a user changes settings, installs extensions, adjusts snippets, changes keyboard shortcuts, or moves UI surfaces, those customizations accumulate in the default environment unless a different profile is active. Creating a profile lets the user copy from a template, copy from another profile, or start from an empty profile. The practical distinction is whether the new profile owns a customization category or falls back to the Default Profile for that category. For example, a documentation profile might include extensions and snippets but reuse the same keyboard shortcuts as the Default Profile.
Settings Sync is related but not identical. Profiles are local organizational units for sets of customizations; sync is the service-level workflow that moves selected categories across signed-in environments. Official documentation lists synchronized categories such as settings, keyboard shortcuts, user snippets, user tasks, UI state, extensions, and profiles. It also calls out an important boundary: extensions are not synchronized to or from remote windows such as SSH, development containers, or WSL. That distinction matters when diagnosing an apparently inconsistent profile, because a local desktop window, a remote workspace, and a web window can share some preferences while intentionally diverging in extension installation behavior.
The settings editor is the bridge between those concepts and day-to-day user action. Users rarely remember the exact key for every preference they included in a profile or synced from another computer. The Copilot settings search provider gives the settings editor a semantic search path: it embeds the user query, finds nearby settings from an index, reports embedding-based results, and optionally asks an LLM to pick the top setting names. That means profile and sync workflows are not only about storing configuration; they also depend on making configuration discoverable after it grows large or becomes distributed across machines. Sources: extensions/copilot/src/extension/prompt/vscode-node/settingsEditorSearchServiceImpl.ts, extensions/copilot/src/extension/prompt/node/settingsEditorSearchResultsSelector.ts, extensions/copilot/src/extension/prompts/node/settingsEditor/settingsEditorSuggestQueryPrompt.tsx
System-to-Code Mapping
At the workbench layer, editor settings are registered as migratable configuration. editorSettingsMigration.ts imports the editor migration list, converts each item into a configuration migration entry whose key is prefixed as editor.${item.key}, and supplies a writer that records new editor.* key-value pairs. This keeps persisted user data resilient when editor settings change internally. For a user, that resilience appears as old settings continuing to work after an update, including settings that may have been copied into a profile or synchronized from another installation. Sources: src/vs/workbench/contrib/codeEditor/browser/editorSettingsMigration.ts
The Copilot settings search implementation is layered around a service identifier, an implementation, a selector, and a prompt. ISettingsEditorSearchService extends the VS Code SettingsSearchProvider shape and defines provideSettingsSearchResults(query, options, progress, token). SettingsEditorSearchServiceImpl handles the operational flow: reject empty queries or non-positive limits, compute a text embedding, load the combined index, select close settings, report embedded results, and optionally produce LLM-ranked results. If embedding computation fails, cancellation is requested, the query has no candidates, or the user cannot use the ranked Copilot path, the implementation reports empty result sets instead of throwing into the settings editor experience. Sources: extensions/copilot/src/platform/settingsEditor/common/settingsEditorSearchService.ts, extensions/copilot/src/extension/prompt/vscode-node/settingsEditorSearchServiceImpl.ts
SettingsEditorSearchResultsSelector is the narrow adapter between retrieved settings and the chat endpoint. It renders SettingsEditorSuggestQueryPrompt, starts an interaction, calls endpoint.makeChatRequest with request name settingsEditorSearchSuggestions, location ChatLocation.Other, and temperature: 0.1, and races the request against a 10 second timeout. Only successful responses are accepted; canceled, timed-out, or failed requests return an empty list. The prompt itself instructs the model to return up to two setting names, one per line, and nothing else. That strict output contract is important because the settings editor expects concrete setting identifiers, not explanatory chat prose. Sources: extensions/copilot/src/extension/prompt/node/settingsEditorSearchResultsSelector.ts, extensions/copilot/src/extension/prompts/node/settingsEditor/settingsEditorSuggestQueryPrompt.tsx
Execution Flow
A typical configuration workflow starts when the user opens the Profiles editor from the preferences menu or the Manage gear. They either continue using the Default Profile, create a new profile from a template, copy an existing profile, or create an empty profile. Once a profile is active, changes to included categories are attributed to that profile, while categories not included in the profile fall back to the Default Profile. If the user then turns on Settings Sync through the Backup and Sync Settings entry or the Accounts menu, selected categories are synchronized after sign-in with a Microsoft or GitHub account.
When the user searches for a setting while customizing a profile, the settings editor can call the provider contract represented by ISettingsEditorSearchService. The implementation first checks simple guardrails: no query and zero or negative limits produce no work. It then computes embeddings with the text3small_512 embedding type and a telemetry correlation id, loads the settings index, and asks the index for the nearest 25 setting candidates. The provider reports these candidates as SettingsSearchResultKind.EMBEDDED, using only setting keys. This first phase is deterministic from the embedding result and local index, so it gives useful answers before any LLM ranking is considered. Sources: extensions/copilot/src/platform/settingsEditor/common/settingsEditorSearchService.ts, extensions/copilot/src/extension/prompt/vscode-node/settingsEditorSearchServiceImpl.ts
The second phase is intentionally conditional. If the settings search request is embeddingsOnly, the provider stops after reporting embedded results. If LLM ranking is allowed, it obtains a Copilot token, rejects free or unauthenticated token states for the ranked path, retrieves the copilot-utility chat endpoint, and creates a SettingsEditorSearchResultsSelector. The selector sends the candidate settings and user query through a prompt that narrows the answer to setting identifiers. This flow keeps the settings editor responsive and bounded: cancellation is checked after expensive steps, timeout protects the ranking call, and every failure mode degrades to empty ranked suggestions instead of blocking settings management.
API and Behavior Reference
| Component | Public or source-level contract | Behavior |
|---|---|---|
ISettingsEditorSearchService | provideSettingsSearchResults(query, options, progress, token): Thenable<void> | Service identifier for a settings search provider that reports results through VS Code progress callbacks. |
NoopSettingsEditorSearchService | Implements ISettingsEditorSearchService | Resolves without reporting results, giving callers a safe fallback. |
SettingsEditorSearchServiceImpl | Implements provideSettingsSearchResults | Uses embeddings first, optionally performs Copilot LLM ranking, and reports empty results on failure or cancellation. |
SettingsEditorSearchResultsSelector | selectTopSearchResults(endpoint, query, settings, token): Promise<string[]> | Renders a prompt and asks a chat endpoint for setting names, bounded by a 10 second timeout. |
SettingsEditorSuggestQueryPrompt | Prompt element with query and settings props | Instructs the model to return up to two setting names, one per line, with no extra prose. |
editorSettingsMigration.ts | Configuration migration registration for editor.* settings | Converts editor migration items into workbench configuration migration entries. |
CodeActionKind and CodeActionTriggerSource | Hierarchical kinds and trigger-source enum | Classify editor actions such as quick fixes, refactors, source actions, organize imports, fix all, save participants, and problems view actions. |
The code-action definitions are not a profile storage API, but they illustrate how editor features expose stable categories that can be filtered and invoked consistently. CodeActionKind defines hierarchical groups such as quickfix, refactor.extract, source.organizeImports, and source.fixAll. CodeActionFilter then decides whether a provider result should be included, excluded, restricted to source actions, or restricted to preferred actions. This kind of stable classification is what makes configurable editor behavior portable: the same user preference can refer to a durable behavior category across profiles, sync boundaries, and updates. Sources: src/vs/editor/contrib/codeAction/common/types.ts
User-Data and Policy Boundaries
Profiles and Settings Sync both operate on user data, so boundaries matter. Official Settings Sync guidance distinguishes machine-specific settings from ordinary user settings, and notes that machine or machine-overridable scopes are not synchronized by default because their values are tied to a particular computer. Official Copilot session-sync guidance adds a separate AI data boundary: chat sessions can sync to a GitHub account by default, can be excluded by repository patterns, and can be controlled by enterprise policy. Treat these as related but separate persistence surfaces. A profile organizes editor customizations; Settings Sync moves selected customization categories; Copilot session sync governs agent and chat session data.
For implementers and contributors, the most concrete repository signal in this source set is graceful degradation. The settings search provider handles missing embeddings, cancellation, no candidates, unauthenticated Copilot states, free-user token states, failed chat requests, and timeouts without making profile or settings editing unusable. That design is important for user-data surfaces because the editor must remain trustworthy even when cloud-assisted features are unavailable. A user should still be able to inspect, change, export, import, and sync settings according to the product rules, while AI ranking remains an enhancement rather than a dependency.
Testing and Contributor Signals
When changing settings behavior, contributors should think in terms of persisted keys, migration safety, search discoverability, and fallback behavior. A change to an editor setting may require migration support so older editor.* values continue to load correctly. A change to settings metadata may affect embedding-index search results and the prompt context sent to Copilot ranking. A change to code-action classification can affect preferences that trigger source actions on save or filter quick fixes in UI entry points. These are cross-cutting editor behaviors, so regressions can show up as broken customization, missing search results, or unexpectedly applied actions. Sources: src/vs/workbench/contrib/codeEditor/browser/editorSettingsMigration.ts, src/vs/editor/contrib/codeAction/common/types.ts, extensions/copilot/src/extension/prompt/vscode-node/settingsEditorSearchServiceImpl.ts
A practical validation path is to exercise the user workflow before reasoning about cloud behavior. Start from a clean or temporary profile, change a visible editor setting, search for related settings using natural language, and verify that embedded results still appear even when LLM ranking is unavailable or canceled. Then test a profile that excludes a category, such as keyboard shortcuts, to confirm the fallback to the Default Profile matches documentation. Finally, if Settings Sync is enabled, verify the synchronized categories in the target environment while remembering the remote-window extension limitation. For deeper reading, continue with settings and keybindings, enterprise policies and AI settings, and Copilot chat session documentation.