microsoft/vscode
Data moves through explicit service boundaries. On disk, IFileService is the single funnel: scheme-based IFileSystemProviders are registered for file:, vscode-userdata:, vscode-remote:, in-memory and IndexedDB backends. Settings flow through a layered ConfigurationService (defaults → policy → user → workspace → folder) fed by NativePolicyService/FilePolicyService/MultiplexPolicyService. Workbench state persists through IStorageService whose desktop implementation proxies reads/writes to the main-process StorageMainService over the 'storage' IPC channel. Secrets go through ISecretStorageService → IEncryptionService → OS keyring. Extension APIs are pure RPC: extHost.* objects are registered as addressable ExtHostContext instances and call MainContext.MainThread* proxies over the extension-host protocol. Telemetry is appended in the shared process via a 'telemetryAppender' channel.
- FileService.registerProvider(scheme, provider) is the input boundary for all file IO: main registers DiskFileSystemProvider for 'file' and FileUserDataProvider for 'vscode-userdata'; the workbench additionally registers IndexedDB, in-memory, HTML File System Access, and remote providers.
- Desktop workbench persistence goes over IPC: StorageDatabaseChannel wrapping IStorageMainService/StorageMainService is registered on the 'storage' channel for both renderer and shared-process clients; main-process state itself uses StateService with SaveStrategy.DELAYED.
- Configuration is layered: ConfigurationService is constructed with the default profile's settingsResource, the FileService, and an IPolicyService that multiplexes OS-native policies (registry/plist via NativePolicyService) and file policies (Linux system path or --policy-file), plus separate native/file managed-settings services for Copilot policy.
- Extension-host RPC is symmetric: createApiFactoryAndRegisterActors registers ~40 ExtHostContext.* actors (ExtHostCommands, ExtHostDocuments, ExtHostTerminalService, ExtHostChatAgents2, ExtHostMpcService…) and obtains MainContext.MainThread* proxies; shapes are declared in extHost.protocol.ts and marshalled by RPCProtocol.
- Secrets flow: extension secret storage calls ISecretStorageService → IEncryptionService which picks an OS keyring provider (gnome-libsecret/kwallet via Electron safeStorage, or Windows/macOS stores) with an explicit 'use weaker encryption' plaintext fallback and a --use-inmemory-secretstorage argv.json escape hatch.
- Telemetry is funneled to the shared process: the main-process TelemetryService uses a TelemetryAppenderClient over the shared-process 'telemetryAppender' channel; PII paths are computed via getPiiPathsFromEnvironment and the 1DS SDK packages are dependencies.
- Text file persistence path: dirty TextFileEditorModel instances are saved through TextFileService with TextFileSaveParticipant hooks (e.g., format-on-save, trim) before FileService.writeFile hits the disk provider; working-copy backups are handled separately by workingCopyBackupService.
- Remote authority flow: workbench asks IRemoteAuthorityResolverService to resolve 'vscode-remote://…' authorities; resolution is delegated to a resolver extension in the extension host, after which RemoteAgentService channels (file system, terminals, extension management, extension host) run over the remote socket via IRemoteSocketFactoryService.
- URL/protocol input boundary: vscode:// deep links are received by ElectronURLListener in the main process, routed via the 'url' channel and URLHandlerRouter to window or extension handlers; initial protocol URLs are captured before the first window opens.
- Extension scanning/activation data flow: ExtensionsScannerService (main) + ExtensionsProfileScannerService feed ExtensionDescriptionRegistry in the workbench; ImplicitActivationEvents computes activation events, ExtensionRunningLocationTracker assigns local/remote/web-worker locations, and deltas stream through _onDidChangeExtensions.