Workbench User Interface

Purpose and Scope

The VS Code workbench is the top-level application shell around code editing. In product terms, it includes the title bar, activity bar, primary and secondary side bars, editor groups, panel, and status bar. This page explains that user-facing layout and connects it to repository seams that participate in opening the UI, rendering editor-adjacent controls, persisting user state, and letting language or AI features contribute visible actions. The goal is not to document every workbench class, but to orient contributors and extension authors to the places where UI concepts cross into code in this source slice.

Sources: cli/src/bin/code/main.rs, src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingCodeEditorIntegration.ts

The official user interface documentation describes a layout optimized around the editor: side bars expose project context, the panel holds output and terminal-style views, the activity bar switches view containers, and the status bar summarizes project and file state. The source evidence here shows how that model is entered and extended. The Rust code launcher decides whether a command should start the desktop workbench, serve web, operate tunnels, or run agent-oriented subcommands. Once inside the workbench, editor integrations such as chat editing attach overlays, view zones, diff renderers, menus, accessibility signals, and decorations to the code editor surface.

Sources: cli/src/bin/code/main.rs, src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingCodeEditorIntegration.ts

Core UI Model

The workbench layout should be understood as a set of coordinated regions rather than a single widget. The editor group is the main region for text editors, diff editors, webviews, and notebook-like experiences. Side bars and the panel provide contextual views that can be shown, hidden, moved, or replaced by extension contributions. The status bar and activity bar are compact but important navigation and feedback surfaces. Extension documentation uses the same vocabulary when describing view containers, tree views, webviews, and status bar items, which is why contributors should preserve those terms when naming commands, tests, settings, and documentation.

Sources: src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingCodeEditorIntegration.ts

Editor integrations often need to behave like workbench features without owning the whole shell. chatEditingCodeEditorIntegration.ts is a good example: it imports ICodeEditor, overlay widget types, view zones, diff viewer components, editor decorations, selections, ranges, menu toolbars, editor services, SCM quick-diff colors, and accessibility signals. That combination shows a common pattern for workbench UI features: render visible editor affordances, use platform services for commands and accessibility, and connect to workbench services only for lifecycle, editor identity, and navigation. The feature appears in the editor region, but it still participates in the broader workbench command and theming systems.

Sources: src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingCodeEditorIntegration.ts

Relevant Source Files

  • src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingCodeEditorIntegration.ts - Implements an editor-region integration for chat editing by wiring code editor widgets, diff rendering, decorations, menu toolbar behavior, editor services, SCM colors, and accessibility signals into a workbench contribution.
  • src/vs/workbench/contrib/chat/common/editing/chatCodeMapperService.ts - Defines the code-mapping service contract used by chat editing providers to turn code blocks into text edits or notebook cell edits.
  • src/vs/code/electron-utility/sharedProcess/contrib/userDataProfilesCleaner.ts - Shows shared-process user data profile cleanup scheduled shortly after startup, which supports profile-backed workbench state hygiene.
  • src/vs/editor/contrib/codeAction/common/types.ts - Defines code action kinds, trigger sources, filtering, and auto-apply options that feed editor lightbulbs, quick fixes, source actions, and problems-view flows.
  • cli/src/bin/code/main.rs - Provides the public code command entrypoint that parses standalone and integrated CLI modes, starts the desktop workbench for normal launches, and routes server, tunnel, version, extension, and agent commands.
  • extensions/copilot/src/extension/completions-core/vscode-node/extension/src/codeReferencing/index.ts - Controls Copilot public code reference engagement tracking based on authentication token capabilities, showing how an extension feature can be enabled or disabled at runtime.

System-to-Code Mapping

A normal desktop launch begins outside the TypeScript workbench in the Rust CLI. The entrypoint collects raw process arguments, tries legacy parsing, determines whether it is running as an integrated or standalone CLI, prepares launcher paths, installs logging through a command context, and then routes commands. When there is no subcommand, or when extension and status commands need to forward arguments to the desktop, the launcher builds base Code arguments and starts Code. This keeps command-line behavior separate from workbench rendering while still allowing code ., extension management, status reporting, web serving, tunnels, and agent commands to share one executable.

Sources: cli/src/bin/code/main.rs

Once the application shell is running, features usually integrate through services and contribution contracts. Chat code mapping is intentionally service-shaped: providers register with registerCodeMapperProvider, expose a displayName, and implement mapCode against a request, response, and cancellation token. The request carries code blocks, optional chat request metadata, an optional chat session resource, and a location string. The response accepts text edits by resource and notebook edits by resource. This contract lets a workbench feature collect generated code and apply it to editor or notebook surfaces without hard-coding one UI path for every provider.

Sources: src/vs/workbench/contrib/chat/common/editing/chatCodeMapperService.ts

Code actions are another editor-to-workbench bridge. The type definitions distinguish quick fixes, refactors, notebook actions, source actions, organize imports, fix all, and surround-with refactors. They also record where an action was triggered, including lightbulb, quick fix hover, problems view, source action, on-save participants, and refactor preview. Filtering helpers decide whether a provided or concrete action should appear for a requested kind, whether source actions are included, and whether only preferred actions should be returned. These rules are important for UI consistency because the same action provider can surface through multiple workbench affordances.

Sources: src/vs/editor/contrib/codeAction/common/types.ts

Execution Flow and Lifecycle

Workbench state is not only the layout that users see; it also depends on background services that keep user data coherent. UserDataProfilesCleaner runs in the Electron utility shared process and schedules userDataProfilesService.cleanUp() with a RunOnceScheduler after ten seconds. That small lifecycle hook matters because profiles influence which settings, extensions, and UI customizations a user sees. By keeping cleanup out of immediate startup and scheduling it once, the workbench can prioritize launch while still maintaining profile data after initialization.

Sources: src/vs/code/electron-utility/sharedProcess/contrib/userDataProfilesCleaner.ts

Runtime capability checks also shape visible workbench behavior. The Copilot code referencing component registers for token changes unless running in tests, reads whether public code quote support is enabled, disposes existing subscriptions when disabled, and creates a CodeRefEngagementTracker when enabled. From a UI perspective, that means a contribution can be present in the extension codebase but remain inactive until authentication and entitlement data allow it. Contributors should model similar feature toggles as lifecycle-managed disposables so the workbench can enable, disable, and clean up UI-adjacent behavior predictably.

Sources: extensions/copilot/src/extension/completions-core/vscode-node/extension/src/codeReferencing/index.ts

API Components and Contracts

The most concrete public-style contract in this source set is the code mapper service. ICodeMapperCodeBlock names the generated code, its target URI, and optional markdown before the block. ICodeMapperRequest groups one or more code blocks with optional chat request metadata. ICodeMapperResponse exposes two callbacks: textEdit(resource, textEdit[]) and notebookEdit(resource, edit[]). ICodeMapperProvider.mapCode returns an optional result containing an optional error message. CodeMapperService.mapCode iterates registered providers, awaits the first provider, respects cancellation, and returns undefined when no provider can map the request.

Sources: src/vs/workbench/contrib/chat/common/editing/chatCodeMapperService.ts

ComponentContract or behaviorUI relevance
CodeActionKindHierarchical kinds such as quickfix, refactor.extract, source.organizeImports, and source.fixAllDetermines which commands appear in lightbulbs, source action menus, and related editor affordances
CodeActionTriggerSourceNames triggers including lightbulb, problems view, save participants, and quick fix hover windowPreserves context when the same action system is invoked from different workbench surfaces
ICodeMapperService.registerCodeMapperProviderRegisters a provider and returns an IDisposable that removes itLets chat editing providers join and leave the workbench lifecycle cleanly
UserDataProfilesCleanerSchedules profile cleanup ten seconds after constructionMaintains profile-backed UI state without blocking initial workbench launch
CodeReference.registerSubscribes to Copilot token changes outside testsActivates or deactivates code reference tracking according to runtime entitlement

Implementation Details

The chat editing integration demonstrates how dense editor UI features are assembled from smaller primitives. Overlay widgets can place controls on top of the editor. View zones can reserve vertical space inside the editor flow. Diff components and line renderers can show generated changes in a way that matches other compare experiences. Decoration collections, minimap and overview ruler colors, and tracked range stickiness make edits visible across scrolling and model changes. Menu toolbars connect editor-local UI to command contributions, while accessibility signals ensure changes are not only visual. That mix is typical for workbench features that must feel native.

Sources: src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingCodeEditorIntegration.ts

The filtering code in types.ts is similarly important because it prevents noisy or unsafe action presentation. Source actions are excluded unless explicitly requested, which keeps broad operations such as organize imports and fix all from appearing in contexts that only asked for local quick fixes. Excludes can remove whole branches of the action hierarchy unless the include kind is more specific. Preferred-only filtering supports flows where the UI should highlight a single recommended action rather than every possible command. These details turn provider output into a predictable workbench experience.

Sources: src/vs/editor/contrib/codeAction/common/types.ts

Testing and Automation Signals

Although this source set does not include the smoke-test page objects themselves, it exposes the seams that reliable UI automation normally targets. The CLI entrypoint provides launch modes and command routing that can be exercised before the window appears. Editor integrations expose deterministic lifecycle points through disposables, registered providers, editor services, and cancellation tokens. Code actions carry explicit trigger-source names, which are useful for asserting that a command was invoked from a lightbulb, hover, problems view, or save participant. Copilot code referencing avoids token subscription registration in test runtime mode, reducing background variability for tests.

Sources: cli/src/bin/code/main.rs, src/vs/editor/contrib/codeAction/common/types.ts, extensions/copilot/src/extension/completions-core/vscode-node/extension/src/codeReferencing/index.ts

When adding or reviewing workbench UI features, start by identifying the region involved: editor group, side bar, panel, activity bar, status bar, or background lifecycle. Then find the service or contribution contract that lets the feature enter that region without bypassing lifecycle management. Prefer disposables for registration, cancellation tokens for long-running work, typed trigger sources for UI-originated actions, and delayed background cleanup for noncritical startup tasks. For adjacent topics, read the pages on Basic Editing, Chat View, Settings and Keybindings, Extension Authoring Overview, and Command Line Interface.