The Role of `globalThis.ego` Bindings in ego-lite: How the JavaScript-Host Bridge Works
TLDR: globalThis.ego is the native bridge object that ego-lite injects into the JavaScript environment, enabling all browser automation, task-space management, and CDP communication between agent-written code and the host runtime.
ego-lite, maintained by citrolabs in the citrolabs/ego-lite repository, is designed to run inside a native "ego" host application. That host injects a global ego object onto globalThis, and every high-level helper in the ego-browser package depends on this binding to talk to the host. Understanding the role of globalThis.ego bindings in ego-lite is essential for anyone building browser-automation agents on top of this runtime.
What Is the globalThis.ego Binding?
The globalThis.ego binding is a singleton object that the native ego-lite host makes available to the JavaScript sandbox. It is not a library import or a module export — it is a globally available host API that scripts and helper functions reference directly. All communication between the JavaScript agent layer and the native runtime flows through this object, making it the single most important architectural component in the package.
The binding exposes several categories of functionality:
- CDP messaging —
sendCDPMessage,listTabs, and related methods for Chrome DevTools Protocol automation. - Task-space lifecycle —
createTaskSpace,useTaskSpace,claimTaskSpace, and others for managing isolated browsing contexts. - Utility endpoints —
fetch,snapshot, and host-implemented helpers.
How globalThis.ego Enables CDP Transport
The low-level transport layer in ego-lite relies on globalThis.ego to route every Chrome DevTools Protocol call. The runtime detection happens in [browser-runtime.ts](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/browser-runtime.ts):
export function isBrowserRuntime() {
return Boolean(
globalThis.ego && typeof globalThis.ego.sendCDPMessage === "function",
);
}
Without the globalThis.ego bindings in ego-lite, this check returns false, and the package would fall back to a server-side transport. When the binding is present, every CDP command such as Runtime.evaluate is forwarded through ego.sendCDPMessage. This abstraction lets agent code run identically in both hosted and server modes.
Using globalThis.ego for Task-Space Management
Task-space management is another critical role of the binding. Helpers such as listTaskSpaces, switchTaskSpace, and newTaskSpace retrieve the host API via globalThis.ego and forward calls like ego.listTaskSpaces() or ego.createTaskSpace().
Below is the implementation of listTaskSpaces from [helpers.ts](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts#L108):
export async function listTaskSpaces() {
const ego = globalThis.ego;
if (!ego || typeof ego.listTaskSpaces !== "function") {
throw new Error("listTaskSpaces requires ego.listTaskSpaces");
}
return normalizeTaskSpaces(
assertNoEgoError(await ego.listTaskSpaces(), "listTaskSpaces"),
);
}
Notice the pattern: validate that globalThis.ego exists, call the host method, and normalize the result. This defensive check is the standard practice across all helpers in the package.
Building Facades with helperContext()
The helperContext() function in helpers.ts constructs the public API surface — page, browser, taskSpaces, site, and fetch — and adds the ego binding to each helper set. As shown in the source:
export function helperContext(extra: any = {}) {
const all = {
page: createPageFacade(),
browser: createBrowserFacade(),
taskSpaces: createTaskSpacesFacade(),
site: createSiteFacade(),
fetch: { server: serverFetch, browser: browserFetch },
cdp,
...extra,
};
return { ...all, help: … };
}
This facade construction means agent scripts can call ego methods transparently without manually reaching into globalThis.ego themselves. The facades are thin wrappers that validate the binding, forward the call, and translate raw host results into the ergonomic API exposed to agents.
Practical Code Examples
Listing All Task Spaces
When an agent wants to see the available task spaces, the taskSpaces.list() helper forwards to globalThis.ego.listTaskSpaces():
import { taskSpaces } from 'ego-browser';
async function showSpaces() {
const spaces = await taskSpaces.list(); // → calls globalThis.ego.listTaskSpaces()
console.log(spaces);
}
Sending a Raw CDP Command
The cdp helper injects a session ID automatically by consulting globalThis.ego:
import { cdp } from 'ego-browser';
async function getTitle() {
const result = await cdp('Runtime.evaluate', { expression: 'document.title' });
console.log(result.result.value);
}
Creating an Isolated Task Space
Task-space creation forwards directly to the host runtime:
import { taskSpaces } from 'ego-browser';
async function startWorkspace() {
const space = await taskSpaces.new('my-workspace'); // → ego.createTaskSpace()
console.log('Created task space', space.id);
}
Key Files That Implement the Bridge
| File | Purpose | Link |
|---|---|---|
src/helpers.ts |
Aggregates public helpers; retrieves globalThis.ego for task-space & other APIs. |
helpers.ts |
src/browser-runtime.ts |
Implements low-level CDP transport; checks for globalThis.ego.sendCDPMessage. |
browser-runtime.ts |
src/state.ts |
Holds runtime state (session IDs, timeouts) used by the ego bridge. |
state.ts |
src/ego-errors.ts |
Normalises error objects coming from the ego host. |
ego-errors.ts |
Summary
globalThis.egois the runtime-injected bridge between agent JavaScript code and the native ego-lite host.- It supplies CDP messaging (
sendCDPMessage,listTabs), task-space lifecycle methods (createTaskSpace,useTaskSpace,claimTaskSpace), and utility endpoints (fetch,snapshot). - All high-level helpers in
ego-browserare thin wrappers that validate the presence of the binding, call the corresponding host method, and normalize results. - The primary implementation lives in
browser-runtime.tsandhelpers.ts, with supporting utilities instate.tsandego-errors.ts.
Frequently Asked Questions
Is globalThis.ego available in all JavaScript environments?
No. globalThis.ego exists only when the script runs inside the native ego host application. The isBrowserRuntime() check in browser-runtime.ts verifies that globalThis.ego.sendCDPMessage is a function; if it is not, the package falls back to server-based alternatives.
What happens if globalThis.ego is missing?
Helpers like listTaskSpaces() throw explicit errors such as "listTaskSpaces requires ego.listTaskSpaces". Each helper independently guards against a missing binding, so failures fail fast with clear messages.
Can agent scripts call globalThis.ego directly?
Yes. The helperContext() function exposes the ego binding to each helper set, so agent scripts can call methods like ego.createTaskSpace() directly. When using the provided facades, however, the wrapper handles normalization and error translation for you.
Does the binding support both browser and server fetch modes?
Yes. The fetch facade in helperContext() includes both serverFetch and browserFetch, letting the same codebase adapt depending on whether globalThis.ego is present. The binding itself is what distinguishes the browser runtime from server operations in ego-lite.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →