Application Startup Handshake: How Mountain, Cocoon, Sky, and Wind Bootstrap
The complete end-to-end process from launching the native binary to a fully initialized editor with running extensions.
Application Startup Handshake
When you double-click the Land editor, four components boot in a carefully ordered sequence. Each must finish its phase before the next can proceed. This document traces the exact path from process launch to a stable, interactive editor.
Phase 1: Mountain Starts the Native Process
The entry point is Mountain/Source/Binary/Main/Entry.rs. The main function creates a Tauri Builder and configures a .setup() hook. Inside that hook:
AppStateis created and registered with Tauri as the central state store.MountainEnvironmentis instantiated. This struct implements every abstract service trait fromCommon— filesystem, terminal, clipboard, configuration, and more.AppRuntimewraps the environment. This is the engine that executesActionEffects: declarative descriptions of work with typed error channels and deterministic resource cleanup.- A
tokiobackground task is spawned to handle post-setup initialization.
The background task then runs three operations in sequence:
handlers::config::InitializeConfigurationloads allsettings.jsonfiles from disk intoAppState.ExtensionManagementscans extension directories, reads manifests, and populates the extension list inAppState.vine::server::Initializestarts the gRPC server that will listen for connections from Cocoon.
Finally, handlers::process_management::InitializeCocoon is called. This executes LaunchAndManageCocoonSidecar from ProcessManagement/CocoonManagement.rs.
Phase 2: The Cocoon Sidecar Spawns
LaunchAndManageCocoonSidecar constructs a detailed environment block for the child process, including VSCODE_PARENT_PID for automatic shutdown if Mountain exits. It then spawns:
node ./Element/Cocoon/Scripts/cocoon/bootstrap-fork.jsCocoon is now a separate Node.js process. Its first action is hardening: PatchProcess patches process.exit, pipes console.log to Mountain, and registers an uncaught exception handler. Then IpcProvider starts Cocoon’s gRPC client.
Upon successful connection to Mountain’s Vine gRPC server, Cocoon sends the $initialHandshake notification and waits for the response.
Phase 3: The Handshake
Mountain receives $initialHandshake. This is the signal to proceed. Mountain calls InitializationData from ProcessManagement/InitializationData.rs, gathering:
- Workspace path and folder list
- Extension manifest data
- Configuration snapshots
- Feature flags and tier settings
This payload is sent back to Cocoon via initExtensionHost gRPC request. Cocoon receives it and creates the InitDataLayer, then runs FullAppInitialization. Two critical things happen inside that effect:
RequireInterceptoris installed. This patches both CJSrequire()and ESMimportso calls to thevscodemodule are intercepted and routed to the correct, extension-specific API instance.ExtensionHostProvideris resolved. It activates extensions matching the*(workspace) activation event.
At this point, extensions can begin registering language providers, tree views, and commands.
Phase 4: The UI Loads
While the handshake is happening, the main Tauri window opens and loads index.html. The preload script at Wind/Source/Preload.ts executes first. It shims the window.vscode global with Tauri-backed implementations for ipcRenderer and process. This is the bridge that allows the VS Code workbench code to run inside Tauri’s WebView instead of Electron.
The main UI script then:
- Waits for the DOM to be ready.
- Creates the master
AppLayer, which composes all Wind services (LiveClipboardService,LiveDialogService,LiveEditorService, etc.). - Converts the
Layerto aRuntimeand resolves core services. - Instantiates the VS Code
Workbenchclass:new Workbench(...). - Calls
Workbench.startup(), which renders the Activity Bar, Status Bar, Side Bar, Editor Part, and all other UI components.
The three processes are now running and communicating:
| Process | Technology | IPC Path |
|---|---|---|
| Mountain | Rust/Tauri | gRPC server + Tauri commands |
| Cocoon | Node.js | gRPC client (Vine protocol) |
| Wind/Sky | TypeScript | Tauri IPC (invoke system) |
Two independent IPC paths exist by design. Tauri IPC handles native work: files, terminals, clipboard, search, and configuration work. Vine gRPC handles extension-host startup, document notifications, language provider requests, cancellation, and streaming routes.
Why This Sequence Matters
The startup order is not arbitrary. Mountain must be fully initialized before Cocoon spawns, because Cocoon needs configuration and extension data to bootstrap. The handshake ensures Cocoon does not start activating extensions until Mountain is ready to receive proxied API calls. The UI loads in parallel with the handshake, but the workbench cannot render useful state until both Mountain and Cocoon have completed their initialization.
This is the foundational workflow. Every user action — opening a file, running a command, triggering a language feature — flows through the state established here.
