CodeVetter · Repo Unpack · Behavior traces
microsoft/vscode
Three flows were walked end-to-end in source: desktop cold start, renderer workbench bring-up, and extension activation/RPC. Startup is heavily instrumented with perf.mark() checkpoints (code/didStartMain … code/didOpenFirstWindow). The workbench uses phased lifecycle (Starting→Ready→Restored→Eventually) so contributions register against phases rather than blocking startup. Extension activation is lazy and event-driven; the extension host is spawned through a main-process IPC channel and bridges API calls via RPCProtocol proxies.
- Desktop cold start (ordered): src/main.ts top-level → configurePortable → parseCLIArgs → configureCommandlineSwitchesSync(readArgvConfigSync) → app.enableSandbox (or append 'no-sandbox') → app.setPath('userData') → protocol.registerSchemesAsPrivileged → app.once('ready') → onReady → startup() sets VSCODE_NLS_CONFIG/VSCODE_CODE_CACHE_PATH → bootstrapESM() → import('./vs/code/electron-main/main.js').
- Main-process startup (ordered): CodeMain.main → startup → createServices (ServiceCollection + InstantiationService) → initServices (mkdir user-data dirs, stateService.init, configurationService.initialize, userDataProfilesMainService.init) → claimInstance (nodeIPCServe on mainIPCHandle + write mainLockfile) → createInstance(CodeApplication).startup().
- App startup inside CodeApplication (ordered): ElectronIPCServer → resolveMachineId/resolveSqmId/resolveDevDeviceId → setupSharedProcess → initServices → ErrorTelemetry → ElectronAgentHostStarter + AgentHostProcessManager → initChannels → setupProtocolUrlHandlers → lifecycleMainService.phase=Ready → openFirstWindow → phase=AfterWindowOpen → afterWindowOpen → Eventually phase scheduled on idle (2.5–5s).
- Renderer workbench bring-up (ordered): workbench.desktop.main.ts barrel → electron-browser workbench.ts → BrowserMain/BrowserWorkbench open() → initServices → new Workbench(parent, options, serviceCollection) → startup() → initServices merges getSingletonServiceDescriptors() → Registry.as(WorkbenchExtensions.Workbench).start(accessor) and EditorFactory registry start → WorkbenchContextKeysHandler → renderWorkbench → createWorkbenchLayout → layout() → restore(lifecycleService).
- Workbench contributions are phase-gated: WorkbenchContributionsRegistry maps WorkbenchPhase.BlockStartup/BlockRestore/AfterRestored/Eventually onto ILifecycleService LifecyclePhase.Starting/Ready/Restored/Eventually and tracks per-contribution creation timings.
- Extension activation (ordered): an event such as file open triggers fileService.onWillActivateFileSystemProvider → AbstractExtensionService.activateByEvent(`onFileSystem:${scheme}`) → the LockableExtensionDescriptionRegistry finds matching extensions → ExtensionRunningLocationTracker picks a host → LazyCreateExtensionHostManager spawns the host via the 'extensionHostStarter' IPC channel → bootstrap-fork → extHostExtensionService loads the extension module and calls activate() with the API built by createApiFactoryAndRegisterActors.
- Extension API creation (ordered): ExtensionHostMain establishes IExtHostRpcService → ErrorHandler.installEarlyHandler forwards unexpected errors to MainThreadErrors → createApiFactoryAndRegisterActors(accessor) registers all ExtHostContext actors and returns the apiFactory that produces the `vscode` module namespace per-extension (gated by ExtensionsProposedApi for proposed APIs).
- Terminal spawn (ordered): terminal contrib in renderer → PtyHostService → ElectronPtyHostStarter launches a utility process running ptyHostMain.ts → PtyService accepts IPC requests on the 'localPty' channel → terminalProcess.ts spawns the shell (node-pty semantics), with LocalReconnectConstants supporting reconnection.
- CLI tunnel flow (ordered): `code tunnel` → clap parse in bin/code/main.rs → tunnels.rs → AppMutex(TUNNEL_CLI_LOCK_NAME) → singleton server (singleton_server) → DevTunnels host via @microsoft/dev-tunnels-equivalent Rust SDK → code_server/spawn of serve-web control server on CONTROL_PORT, with legal banner and machine_status reporting.
- Save flow (ordered): editor commands → ITextFileService.save → TextFileEditorModel.save → TextFileSaveParticipant chain (progress notification + participants like format/trim) → FileService.writeFile → DiskFileSystemProvider (direct in desktop; over LOCAL_FILE_SYSTEM_CHANNEL_NAME when proxied) → versioned write + backup integration via workingCopy services.