|
|
|
The Effect-TS native Node.js Extension Host for LandβποΈ
VS Code's extension host is a single
Node.jsevent loop. One hungPromiseblocks 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."
@codeeditorland/cocoonβπ¦
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:
- Host VS Code Extensions - Run existing VS Code extensions unmodified
through a comprehensive API shim layer that mirrors
vscode.d.ts. - Provide Fiber-Level Isolation - Each extension runs in its own supervised
Effect-TSfiber with independent lifecycle, cancellation tokens, and error boundaries. - Enforce Process Hardening - Patch
process.exit, block native modules, intercept uncaught exceptions, and terminate if the parentMountainprocess exits. - Bridge via gRPC & WebSocket - Communicate with
MountainthroughgRPC(Vineprotocol on port:50052) and withSkythrough aWebSocketJSON-RPC transport with cryptographic authentication.
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.
| 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 |
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
| 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 |
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
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(Vineprotocol on port:50052),WebSocket(JSON-RPCwith cryptographic auth toSky)
Mountainlaunches Cocoon with initialization data.- Cocoon's
Main.tsbootstraps:PatchProcesshardens the environment,Effect/Bootstrap.tsorchestrates initialization (environment detection, configuration,gRPCconnection, module interceptor, extension registry, health checks), andService/Mapping.tsbuilds the mainAppLayer. ExtHostExtensionServiceactivates an extension, which receives avscodeAPI object fromAPIFactory.- The extension calls
vscode.window.showInformationMessage("Hello"). - The call is routed to the
Windowservice, which creates anEffectsending ashowMessagegRPCrequest toMountain. Mountain'sVinelayer receives the request and dispatches it to the native UI handler.Mountaindisplays the native OS notification and awaits interaction.- The result flows back via
gRPCresponse, completing theEffectand resolving the extension'sPromise.
- Node.js v18 or later
- pnpm (monorepo package manager)
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.
| 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.
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.
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 |
- Main Entry Point
- Application bootstrap and layer composition
- Effect Services
- Lifecycle orchestration (
Bootstrap.ts,Extension.ts,Module/Interceptor.ts)
- Lifecycle orchestration (
- Service Mapping
- Dependency injection container and
AppLayer
- Dependency injection container and
- gRPC Client
MountaingRPCclient operations
- gRPC Server
Vineprotocol server with bidirectional streaming
- WebSocket Server
JSON-RPCWebSocketserver forSkytransport
- TypeConverter
- DTO serialization for
gRPCtransport
- DTO serialization for
- Architecture Overview - Internal module structure
- Why Effect-TS - Design rationale for
Effect-TS - Why gRPC - Design rationale for
gRPC - Land Documentation - Complete documentation index
- Wind π¬οΈ - Service layer (correlated frontend element)
- Worker βοΈ - Service worker for caching and offline support
- Vine πΏ -
gRPCprotocol definition - Grove π³ -
Rust/WASMextension host - Mountain β°οΈ - Native desktop
shell and
gRPCbackend
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.
See
CHANGELOG.md
for a history of changes specific to Cocoon π¦.
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.
|
|
|
|
|
Project Maintainers: Source Open (Source/Open@editor.land) | GitHub Repository | Report an Issue | Security Policy