# What Is globalThis.ego.sendCDPMessage in ego-lite? The CDP Transport Bridge

> Understand globalThis.ego.sendCDPMessage, the CDP transport bridge in ego-lite. Learn how it enables sending Chrome DevTools Protocol commands and receiving responses.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: deep-dive
- Published: 2026-07-31

---

**`globalThis.ego.sendCDPMessage` is the low-level transport bridge that allows the ego-lite JavaScript harness to send Chrome DevTools Protocol (CDP) commands to the underlying Chromium browser and receive asynchronous responses.**

The ego-lite repository provides a JavaScript harness for automating browser interactions within the closed-source *ego lite* application. At the heart of this system lies **`globalThis.ego.sendCDPMessage`**, the critical interface that enables the harness to communicate with the embedded Chromium instance via the Chrome DevTools Protocol.

## Runtime Detection and Environment Verification

Before issuing commands, the harness verifies it is running inside the ego-lite browser environment. The `isBrowserRuntime()` function in [`package/ego-browser/src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/browser-runtime.ts) (lines 25-28) performs this check by confirming that `globalThis.ego` exists and exposes the `sendCDPMessage` function.

Individual driver modules perform additional capability checks. For example, [`src/driver/pointer.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/pointer.ts) and [`src/driver/keyboard.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/keyboard.ts) validate availability using:

```typescript
return Boolean((globalThis as any).ego?.sendCDPMessage);

```

This pattern ensures that automation scripts degrade gracefully when CDP capabilities are unavailable.

## Message Structure and Transport Flow

When the harness executes browser commands, it constructs standardized CDP message envelopes and transmits them via the global transport function.

### Constructing the CDP Payload

In [`package/ego-browser/src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/browser-runtime.ts) (lines 44-53), the system builds a JSON payload containing:

- An incrementing **`id`** for request-response correlation
- The CDP **`method`** name (e.g., `Page.navigate`)
- Optional **`params`** for the command arguments
- An optional **`sessionId`** for targeting specific browser sessions

### The Transport Mechanism

The constructed payload is handed to the host via `globalThis.ego.sendCDPMessage(payload)` (lines 70-71). According to the source code, the host forwards this request over a WebSocket-like channel to the actual Chrome instance. The host later calls back into the harness using `onCDPMessage` for successful responses or `onSendCDPMessageError` for transport failures.

### Response Handling

Incoming messages are parsed in the `handleMessage` function (lines 39-50). The implementation distinguishes between:

- **Command responses**: Messages containing an `id` resolve the corresponding pending Promise with the result
- **Events**: Messages without an `id` are treated as unsolicited events, such as page lifecycle notifications or dialog triggers

## Implementation in browser-runtime.ts

The [`package/ego-browser/src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/browser-runtime.ts) file implements the complete CDP transport layer. It defines:

- **`isBrowserRuntime()`**: Confirms the ego-lite environment is active
- **`rawCdp()`**: Wraps message construction and transport invocation
- **`handleMessage()`**: Parses incoming CDP traffic and manages Promise resolution

This architecture ensures that higher-level helpers for navigation, clicking, typing, and snapshotting operate without directly handling protocol details.

## Practical Usage Examples

While most automation uses high-level abstractions, understanding the full stack reveals how `globalThis.ego.sendCDPMessage` enables every browser interaction.

### High-Level Navigation

```typescript
// Example: navigate to a URL using the high‑level helper (which ultimately calls sendCDPMessage)
await nav.goto('https://example.com');

// Under the hood:
await rawCdp('Page.navigate', { url: 'https://example.com' });

```

### JavaScript Evaluation

```typescript
// Example: evaluate JavaScript in the page context
import { js } from './cdp-eval.js';
const result = await js('document.title');

```

Both `nav.goto` and `js` eventually invoke `rawCdp`, which creates the payload and calls `globalThis.ego.sendCDPMessage` (lines 70-71).

### Low-Level Direct Access

```typescript
// Low‑level direct use (rare, but possible)
const payload = JSON.stringify({ id: 1, method: 'Runtime.evaluate', params: { expression: '2+2' } });
globalThis.ego.sendCDPMessage(payload);

```

## Integration Across Helper Modules

The transport function integrates throughout the codebase. Files like [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) pull `globalThis.ego` into local constants for convenience, while [`src/cdp-eval.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/cdp-eval.ts) provides the public `cdp` and `js` helpers that rely on this mechanism. The driver modules in `src/driver/` use capability checks to conditionally expose functionality based on `sendCDPMessage` availability.

## Summary

- **`globalThis.ego.sendCDPMessage`** is the core transport function enabling CDP communication between the ego-lite harness and the Chromium browser.
- **Runtime detection** via `isBrowserRuntime()` in [`package/ego-browser/src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/browser-runtime.ts) ensures the function exists before use.
- **Message envelopes** include incrementing IDs, method names, parameters, and optional session IDs for structured command execution.
- **Bidirectional flow** sends commands to the browser via the host's WebSocket-like channel and receives responses through `onCDPMessage` callbacks.
- **Abstraction layers** in `rawCdp` and high-level helpers allow automation without protocol-level complexity.

## Frequently Asked Questions

### What protocol does ego-lite use to control the browser?

The ego-lite harness uses the **Chrome DevTools Protocol (CDP)**, a JSON-based protocol originally designed for Chrome DevTools. The `globalThis.ego.sendCDPMessage` function serves as the transport layer that marshals these CDP commands from the JavaScript harness to the underlying Chromium instance running inside the ego-lite application.

### Is globalThis.ego.sendCDPMessage available in all JavaScript environments?

No. This function is only available when code executes inside the *ego lite* application's embedded browser environment. The `isBrowserRuntime()` check in [`package/ego-browser/src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/browser-runtime.ts) explicitly verifies that `globalThis.ego` exists and exposes the `sendCDPMessage` function before attempting communication. Standard browsers and Node.js contexts will fail this validation.

### How does ego-lite handle asynchronous CDP responses?

The system maintains a map of pending Promises keyed by the unique `id` assigned to each outgoing message. When `handleMessage` in [`package/ego-browser/src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/browser-runtime.ts) (lines 39-50) receives a response containing a matching `id`, it resolves the corresponding Promise with the result. Messages lacking an `id` field are treated as unsolicited events, such as console logs or page load notifications.

### Can I use sendCDPMessage directly instead of high-level helpers?

While technically possible, direct usage is discouraged for most automation tasks. The `rawCdp` function in [`package/ego-browser/src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/browser-runtime.ts) provides a safer wrapper that handles JSON serialization, ID generation, and Promise management. Direct calls to `globalThis.ego.sendCDPMessage` require manual payload construction with `JSON.stringify` and manual management of asynchronous response handling through the callback system.