Skip to content

CodeEditorLand/Cocoon

Cocoonβ€πŸ¦‹

Last-commit
Issues
Star
Downloads

The Effect-TS native Node.js Extension Host for Landβ€πŸžοΈ

VS Code's extension host is a single Node.js event loop. One hung Promise blocks every other extension. There is no way to cancel an in-flight operation, no back-pressure, no preemption.

"Every extension runs in its own supervised fiber. One crash doesn't take down the rest."

License: CC0-1.0 NPM Version Node.js Version Effect Version

@codeeditorland/cocoonβ€πŸ“¦


Overview

Cocoon is the Node.js/Effect-TS extension host for the Land Code Editor. It hosts existing VS Code extensions in a supervised Effect-TS fiber environment, faithfully replicating the VS Code Extension Host API. It complements Grove (Rust/WASM) by providing the Node.js hosting environment, allowing Land to leverage the vast VS Code extension ecosystem while adding fiber-level supervision, structured concurrency, and resource safety.

VS Code's extension host is a single Node.js event loop - one hung Promise blocks every other extension. Cocoon solves this by giving each extension its own Effect-TS fiber with cancellation, back-pressure, and preemption. A crash in one extension doesn't bring down the rest.

Cocoon is engineered to:

  1. Host VS Code Extensions - Run existing VS Code extensions unmodified through a comprehensive API shim layer that mirrors vscode.d.ts.
  2. Provide Fiber-Level Isolation - Each extension runs in its own supervised Effect-TS fiber with independent lifecycle, cancellation tokens, and error boundaries.
  3. Enforce Process Hardening - Patch process.exit, block native modules, intercept uncaught exceptions, and terminate if the parent Mountain process exits.
  4. Bridge via gRPC & WebSocket - Communicate with Mountain through gRPC (Vine protocol on port :50052) and with Sky through a WebSocket JSON-RPC transport with cryptographic authentication.

Key Featuresβ€πŸ”

Effect-TS Fiber Supervision - Every extension activation runs in its own Effect fiber with structured concurrency. Cancellation propagates cleanly through the fiber tree, hung operations are preemptible, and fiber crashes are trapped at the supervision boundary rather than taking down the host process.

Full vscode API Shimming - The APIFactory service constructs a complete vscode API object with namespaces for window, workspace, commands, languages, debug, scm, tasks, env, extensions, authentication, tests, and comments. Extension code runs against this shim without modification.

Process Security Hardening - The PatchProcess module runs before any extension activates, intercepting process.exit, process.crash, native module loads, uncaught exceptions, and unhandled rejections. A configurable SecurityPolicy controls exit permissions, memory limits, network access, file system access, and child process spawning.

Code Generation Pipeline - The Codegen module walks the VS Code extension-host source tree (Wind) and emits IExtHost*Upstream schemas grounded in real upstream source, reusing every Wind extractor and resolver verbatim.

Multi-Transport Communications - gRPC (Vine protocol to Mountain), WebSocket JSON-RPC (to Sky with hex-secret auth via URL param, Sec-WebSocket-Protocol, or X-Land-Secret header), and IPC (buffered multi-channel RPC for local communication).

Bidirectional Streaming - The gRPC server implements the Vine protocol with bidirectional streaming, allowing Mountain to push notifications and events into Cocoon asynchronously without polling.

Telemetry & Observability - PostHog event buffering and batching with identity management, plus OTLP fire-and-forget span export for distributed tracing. Tree-shaken from production builds via esbuild define substitution.

Dual-Layer Debug Server - An HTTP inspection surface (:9934) matching Mountain's DebugServer wire protocol, supporting /health, /layers, /execute (eval in extension host scope), and /extensions endpoints for runtime introspection.


Core Architecture Principlesβ€πŸ—οΈ

Principle Description Key Components
Fiber Isolation Each extension is a separate Effect fiber with its own supervision tree, cancellation scope, and error channel. Failures don't cascade. Effect/Extension.ts, Effect/Bootstrap.ts, Effect/Module/Interceptor.ts
API Surface Parity Implement the full VS Code extension API (vscode.d.ts) so extensions port seamlessly between Cocoon and Grove. Services/API/Factory/, Services/Handler/VscodeAPI/*, Services/Extension/Host/
Defense in Depth Process-level hardening (PatchProcess) + Effect-TS error boundaries + configurable SecurityPolicy + platform-native sandboxing (future). PatchProcess/Patcher.ts, PatchProcess/Security.ts, PatchProcess/Validator.ts
Transport Flexibility Multiple communication channels (gRPC, WebSocket, IPC) for different deployment topologies, each behind a typed interface. Services/gRPC/Server/, Services/Mountain/gRPC/Client.ts, Bootstrap/WebSocket/Server.ts, IPC/Channel.ts

System Architecture

Cocoon operates as a standalone Node.js process orchestrated by and communicating with Mountain.

graph LR
    classDef mountain fill:#f0d0ff,stroke:#9b59b6,stroke-width:2px,color:#2c0050;
    classDef cocoon   fill:#d0d8ff,stroke:#4a6fa5,stroke-width:2px,color:#001050;
    classDef effectts fill:#d4f5d4,stroke:#27ae60,stroke-width:1px,color:#0a3a0a;
    classDef vscode   fill:#ebebeb,stroke:#888,stroke-width:1px,stroke-dasharray:5 5,color:#333;
    classDef ipc      fill:#fff3c0,stroke:#f39c12,stroke-width:1px,stroke-dasharray:5 5,color:#5a3e00;

    subgraph COCOON["Cocoon πŸ¦‹ - Node.js Extension Host Sidecar"]
        direction TB
        subgraph BOOT["Bootstrap/ - Startup"]
            PatchProcess["PatchProcess/ - Process Hardening πŸ”’"]:::cocoon
            MainEntry["Bootstrap/Implementation/Cocoon/Main.ts πŸš€"]:::effectts
            AppLayer["Service/Mapping.ts - AppLayer 🧩"]:::effectts
        end
        subgraph EFFECTS["Effect/ - Lifecycle Orchestration"]
            BootstrapEff["Effect/Bootstrap.ts ⚑"]:::effectts
            ExtEff["Effect/Extension.ts"]:::effectts
            ModInterceptor["Effect/Module/Interceptor.ts\n(require/import patch)"]:::effectts
        end
        subgraph SERVICES["Services/ - vscode API Shims"]
            APIFactory["Services/API/Factory - vscode object 🏭"]:::cocoon
            ExtHostSvc["Services/Extension/Host"]:::cocoon
            WindowSvc["Services/Window Β· Workspace Β· Command Β· Terminal"]:::cocoon
            WebviewSvc["WebviewPanel/ - Panel lifecycle 🌐"]:::cocoon
        end
        subgraph TRANSPORT["IPC/ + gRPC Transport"]
            IPCChannel["IPC/Channel.ts - multi-channel RPC πŸ“‘"]:::ipc
            GRPCClient["Services/Mountain/gRPC/Client.ts 🌿"]:::ipc
            GRPCServer["Services/gRPC/Server/ - Vine impl πŸ”Œ"]:::ipc
        end
        subgraph SUPPORT["Support Modules"]
            TypeConverter["TypeConverter/ - DTO serialization πŸ”„"]:::cocoon
            Platform["Platform/ - OS/env abstraction πŸ’»"]:::cocoon
            Telemetry["Telemetry/ - PostHog + OTLP πŸ“Š"]:::cocoon
            Generated["Generated/RouteManifest.ts πŸ—ΊοΈ"]:::cocoon
        end

        PatchProcess --> MainEntry
        MainEntry --> AppLayer
        AppLayer --> BootstrapEff
        BootstrapEff --> ExtEff
        BootstrapEff --> ModInterceptor
        AppLayer --> SERVICES
        SERVICES --> TypeConverter
        APIFactory --> ExtHostSvc
        ExtHostSvc --> GRPCClient
        GRPCClient --> IPCChannel
        GRPCServer --> IPCChannel
        AppLayer -.-> Platform
        AppLayer -.-> Telemetry
        AppLayer -.-> Generated
    end

    subgraph MOUNTAIN["Mountain ⛰️ - Rust/Tauri Backend"]
        VineGRPC["Vine gRPC Server 🌿"]:::mountain
    end

    subgraph EXT["VS Code Extensions πŸ“¦"]
        ExtCode["Extension Code πŸ“œ"]:::vscode
    end

    APIFactory -- injects vscode API --> ExtCode
    ExtCode -- API calls --> SERVICES
    GRPCClient <-- gRPC :50052 --> VineGRPC
    GRPCServer <-- notifications --> VineGRPC
Loading

Key Components

Component Path Description
Main Entry Source/Bootstrap/Implementation/Cocoon/Main.ts Primary entry point composing all Effect-TS layers, establishing gRPC connection, handshake with Mountain
Bootstrap Source/Effect/Bootstrap.ts Lean async bootstrap orchestrating initialization stages: environment detection, configuration, gRPC connection, module interceptor, extension registry, health checks
Service Mapping Source/Service/Mapping.ts Dependency injection container wiring all services into the main AppLayer
APIFactory Source/Services/API/Factory/Service.ts Constructs the vscode API object that extensions receive
Extension Host Source/Services/Extension/Host/Service.ts Manages extension activation and lifecycle with module interception and API injection
IPC Channel Source/IPC/Channel.ts Multi-channel RPC system management with advanced message routing
gRPC Client Source/Services/Mountain/gRPC/Client.ts Effect-TS wrapper for Mountain gRPC operations
gRPC Server Source/Services/gRPC/Server/Service.ts Cocoon's gRPC server implementing the Vine protocol with bidirectional streaming
WebSocket Server Source/Bootstrap/WebSocket/Server.ts JSON-RPC WebSocket server for Sky↔Cocoon direct transport with cryptographic authentication
PatchProcess Source/PatchProcess/ Process hardening: patches process.exit, handles exceptions, enforces security policy
TypeConverter Source/TypeConverter/ Pure functions to serialize TypeScript types into plain DTOs for gRPC transport
Codegen Source/Codegen/ Code generation pipeline walking VS Code extension-host source to emit IExtHost*Upstream schemas
Platform Source/Platform/ Platform abstraction layer providing OS, environment, and process info as Effect-TS service
WebviewPanel Source/WebviewPanel/ Webview panel factory, implementation, and serializer managing lifecycle and state
Telemetry Source/Telemetry/ PostHog and OTLP telemetry bridges with event buffering and identity management
Debug Server Source/Debug/Server.ts HTTP inspection surface (:9934) for /health, /layers, /execute, /extensions runtime introspection
Generated Source/Generated/RouteManifest.ts Auto-generated route manifest enumerating Mountain-side RPC methods

Project Structureβ€πŸ—ΊοΈ

Element/Cocoon/
β”œβ”€β”€ Source/
β”‚   β”œβ”€β”€ Bootstrap/                 # Startup and initialization
β”‚   β”‚   β”œβ”€β”€ Implementation/Cocoon/ # Main entry point (Main.ts)
β”‚   β”‚   └── WebSocket/             # WebSocket server for Sky transport
β”‚   β”œβ”€β”€ Codegen/                   # VS Code extension-host codegen pipeline
β”‚   β”‚   β”œβ”€β”€ Emit/Emit/Ext/Host/    # Schema emission
β”‚   β”‚   β”œβ”€β”€ Extract/               # Decorator extraction and file filtering
β”‚   β”‚   β”œβ”€β”€ Run/Ext/Host/          # Codegen runner
β”‚   β”‚   └── Type/Ext/Host/         # Decorator record types
β”‚   β”œβ”€β”€ Configuration/             # ESBuild and Mountain configuration
β”‚   β”‚   β”œβ”€β”€ ESBuild/               # ESBuild configs (Bootstrap, Cocoon, Target)
β”‚   β”‚   └── Mountain/              # Mountain integration config
β”‚   β”œβ”€β”€ Debug/                     # Dual-layer HTTP inspection server
β”‚   β”œβ”€β”€ Effect/                    # Effect-TS lifecycle orchestration
β”‚   β”‚   └── Module/                # Module interceptor (require/import patches)
β”‚   β”œβ”€β”€ Generated/                 # Auto-generated route manifest
β”‚   β”œβ”€β”€ Integration/               # Mountain client integration
β”‚   β”œβ”€β”€ Interfaces/                # Service interfaces (I* pattern)
β”‚   β”‚   └── I/                     # Configuration, Error, Extension, FileSystem,
β”‚   β”‚       IAPI/Factory/          #   ModuleInterceptor, MountainClient,
β”‚   β”‚       IGRPC/Server/          #   Performance, Security, Terminal
β”‚   β”œβ”€β”€ IPC/                       # Multi-channel RPC system
β”‚   β”‚   └── Message/               # Message serialization, deserialization,
β”‚   β”‚                              #   batching, validation, types, VSBuffer
β”‚   β”œβ”€β”€ Orchestration/             # Legacy service orchestration
β”‚   β”œβ”€β”€ PatchProcess/              # Process hardening and security enforcement
β”‚   β”œβ”€β”€ Platform/                  # OS, environment, logging abstraction
β”‚   β”œβ”€β”€ Service/                   # Service wiring (AppLayer mapping)
β”‚   β”œβ”€β”€ Services/                  # VS Code API shim services
β”‚   β”‚   β”œβ”€β”€ API/Factory/           # vscode API object construction
β”‚   β”‚   β”œβ”€β”€ Extension/Host/        # Extension activation and lifecycle
β”‚   β”‚   β”œβ”€β”€ Extensions/            # Extension scanner
β”‚   β”‚   β”œβ”€β”€ gRPC/Server/           # Vine gRPC protocol implementation
β”‚   β”‚   β”œβ”€β”€ Handler/               # API request routing and dispatch
β”‚   β”‚   β”‚   └── VscodeAPI/         # Individual vscode namespace handlers:
β”‚   β”‚   β”‚       Authentication/, Commands/, Comments/, Debug/, Env/,
β”‚   β”‚   β”‚       Extensions/, Languages/, Scm/, Tasks/, Tests/,
β”‚   β”‚   β”‚       Window/, Workspace/
β”‚   β”‚   β”œβ”€β”€ Mountain/gRPC/         # gRPC client for Mountain communication
β”‚   β”‚   └── Window/                # Window service (dialogs, output, status bar,
β”‚   β”‚                              #   webview panels, terminals, text documents)
β”‚   β”œβ”€β”€ Telemetry/                 # PostHog + OTLP telemetry bridges
β”‚   β”œβ”€β”€ TypeConverter/             # DTO serialization for gRPC transport
β”‚   β”œβ”€β”€ Utility/                   # Shared utilities (events, globs, logging)
β”‚   └── WebviewPanel/              # Webview panel lifecycle management
└── Scripts/                       # Build and codegen scripts
    └── compile-grpc-protocol.js   # gRPC protocol compilation

In the Land Project

Cocoon operates as a standalone Node.js process orchestrated by Mountain. It provides the Node.js extension runtime environment that allows existing VS Code extensions to run unmodified within Land. It complements Grove (Rust/WASM) as the second extension host, together providing the two execution environments for Land's extension model:

Host Language Runtime Isolation
Cocoon TypeScript, JavaScript Node.js via Effect-TS Fiber-level supervision + process hardening
Grove Rust, WASM WASMtime Hardware-enforced via capability model
  • Depends on: Mountain (gRPC host), @codeeditorland/output (VS Code platform code), Wind (extraction pipeline for codegen)
  • Consumed by: VS Code extensions running in Land
  • Protocol: gRPC (Vine protocol on port :50052), WebSocket (JSON-RPC with cryptographic auth to Sky)

Interaction Flow: vscode.window.showInformationMessage

  1. Mountain launches Cocoon with initialization data.
  2. Cocoon's Main.ts bootstraps: PatchProcess hardens the environment, Effect/Bootstrap.ts orchestrates initialization (environment detection, configuration, gRPC connection, module interceptor, extension registry, health checks), and Service/Mapping.ts builds the main AppLayer.
  3. ExtHostExtensionService activates an extension, which receives a vscode API object from APIFactory.
  4. The extension calls vscode.window.showInformationMessage("Hello").
  5. The call is routed to the Window service, which creates an Effect sending a showMessage gRPC request to Mountain.
  6. Mountain's Vine layer receives the request and dispatches it to the native UI handler.
  7. Mountain displays the native OS notification and awaits interaction.
  8. The result flows back via gRPC response, completing the Effect and resolving the extension's Promise.

Getting Startedβ€πŸš€

Prerequisites

  • Node.js v18 or later
  • pnpm (monorepo package manager)

Build / Install

Cocoon is developed as a core component of the Land project. It is built as part of the monorepo and requires the Bundle=true build variable, which triggers the Rest element to prepare the necessary VS Code platform code.

Key Dependencies

Package Purpose
effect (v3.21.3) Core library for the entire application structure
@effect/platform (v0.96.1) Effect-TS platform abstractions
@effect/platform-node (v0.107.0) Node.js-specific Effect-TS platform
@grpc/grpc-js (v1.14.4) gRPC communication
@grpc/proto-loader (v0.8.1) .proto file loading for gRPC
@codeeditorland/output (v0.0.1) Compiled VS Code platform code from Land/Dependency
google-protobuf & protobufjs Protocol buffers for gRPC

Debugging Cocoon: Attach a standard Node.js debugger. Mountain must launch Cocoon with debug flags (e.g., --inspect-brk=PORT_NUMBER). Logs from Cocoon are automatically piped to Mountain's console via the PatchProcess module.


Securityβ€πŸ”’

Cocoon enforces security at multiple layers:

Layer Mechanism
Process Hardening PatchProcess/Patcher.ts runs before any extension: blocks process.crash(), intercepts process.exit() (unless SecurityPolicy.AllowExit), blocks native module loads (Module._load("natives")), sets Error.stackTraceLimit=100
Exception Boundaries uncaughtException and unhandledRejection handlers trap orphaned errors to stderr; gRPC RPC takes over error forwarding once connected
Parent Liveness TerminateOnParentExit monitors VSCODE_PID and exits cleanly if the parent Mountain process dies
SecurityPolicy Configurable policy controlling exit permissions, memory limits (MaxMemoryMB), network access (AllowNetwork), child process spawning (AllowChildProcesses), file system access validation, and environment variable restrictions
Runtime Validation Validator service runs continuous security validation: file system access checks, network access checks, memory usage monitoring, suspicious behavior detection, and audit trail generation
Module Interception Module/Interceptor patches require/import to control which modules extensions can load; the vscode API object is injected through this interceptor
WebSocket Auth Cryptographic authentication via timingSafeEqual hex secret comparison: accepted through URL ?secret=, Sec-WebSocket-Protocol header, or X-Land-Secret header
Memory Enforcement Soft memory limit using v8.setFlagsFromString("--max-old-space-size=…"); configurable per-extension via SecurityPolicy.MaxMemoryMB

Future platform-native layers: Windows Job Objects / AppContainer, Linux seccomp via libseccomp, and macOS sandbox via sandbox-exec.


Compatibility

Cocoon is designed to be compatible with:

Target Integration
Grove Shares VS Code API surface, activation semantics, and manifest parsing for seamless extension porting
VS Code Implements vscode.d.ts type definitions; existing extensions run unmodified
Mountain Integrates via gRPC using the Vine protocol on port :50052 with bidirectional streaming
Sky Direct WebSocket JSON-RPC transport with cryptographic authentication
Output Consumes compiled VS Code platform code from @codeeditorland/output

API Reference


Related Documentation


Licenseβ€βš–οΈ

This project is released into the public domain under the Creative Commons CC0 Universal license. You are free to use, modify, distribute, and build upon this work for any purpose, without any restrictions. For the full legal text, see the LICENSE file.


Changelogβ€πŸ“œ

See CHANGELOG.md for a history of changes specific to Cocoon πŸ¦‹.


Funding & Acknowledgementsβ€πŸ™πŸ»

This project is funded through NGI0 Commons Fund, a fund established by NLnet with financial support from the European Commission's Next Generation Internet program, under grant agreement No 101135429.

Land PlayForm NLnet NGI0 Commons Fund

Project Maintainers: Source Open (Source/Open@editor.land) | GitHub Repository | Report an Issue | Security Policy

About

Cocoonβ€πŸ¦‹β€+ Editorβ€πŸžοΈ

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

Packages

 
 
 

Contributors