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

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 (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 and src/driver/keyboard.ts validate availability using:

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 (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 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

// 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

// 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

// 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 pull globalThis.ego into local constants for convenience, while 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 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 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 (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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →