How ego-lite Helpers Are Exposed in SDK Mode: A Complete Technical Guide

When ego-lite operates as a library (SDK mode), the installEgoSdk function in src/index.ts automatically attaches public helper functions—including page, browser, taskSpaces, site, fetch, cdp, and evaluate—to the target object (by default globalThis), making them available as non-enumerable global properties.

The citrolabs/ego-lite repository provides a browser automation framework that functions both as a CLI tool and a programmatic SDK. Understanding how these helpers are exposed in SDK mode is essential for developers integrating ego-lite into existing Node.js applications or test suites.

The Helper Context Architecture

Before installation occurs, ego-lite aggregates its functionality into a single helper context that serves as the source of truth for both CLI and SDK usage.

Creating the Unified Helper Surface

In src/helpers.ts, the helperContext() function constructs an object containing all façades and low-level utilities:

// src/helpers.ts – lines 22-30
export function helperContext(extra: any = {}) {
  const all = {
    page: createPageFacade(),
    browser: createBrowserFacade(),
    taskSpaces: createTaskSpacesFacade(),
    site: createSiteFacade(),
    fetch: { server: serverFetch, browser: browserFetch },
    cdp,
    ...extra,
  };
  // ...
}

This centralizes Playwright-style methods from createPageFacade, browser tab management from createBrowserFacade, task-space utilities, site-specific skills, and network fetching capabilities into one cohesive API surface.

SDK Installation Mechanism

The transition from module import to usable global API happens through a conditional installation process that detects the runtime environment.

Automatic vs Manual Installation

At the bottom of src/index.ts, the module determines whether it is running as a direct CLI or being required as a library:

// src/index.ts – line 64
if (isDirectCli()) {
  // CLI entrypoint
} else {
  installEgoSdk(); // ← SDK path
}

This automatic installation means simply importing the package exposes the helpers globally. Developers can also call installEgoSdk() manually with a custom target object for scoped usage.

Property Attachment Strategy

The installEgoSdk function iterates over the helper context and defines properties on the target object using Object.defineProperty:

// src/index.ts – lines 62-73
for (const [name, value] of Object.entries(context)) {
  const exposed = SYNC_HELPERS.has(name)
    ? value
    : wrapReady(value, readySignal, () => readyError, [name]);
  Object.defineProperty(target, name, {
    value: exposed,
    writable: true,
    configurable: true,
    enumerable: false,
  });
}

Synchronous helpers (such as help) are exposed directly, while asynchronous helpers are wrapped by wrapReady to ensure they wait for the optional "ready" signal before execution. All properties are defined as non-enumerable to avoid polluting for...in loops while remaining writable and configurable for flexibility.

The Global API Surface

After SDK installation completes, the following identifiers become available on the global object (or your specified target):

  • page – Playwright-style page façade providing goto, locator, waitForSelector, and other DOM interaction methods.
  • browser – Tab management façade exposing listTabs, switchTab, and openOrReuseTab.
  • taskSpaces – Task-space management façade with useOrCreate, claim, switch, and complete methods.
  • site – Learned site-skill façade offering skills, runTool, and learnContext for intelligent automation.
  • fetch – Network façade containing both fetch.server and fetch.browser for isomorphic HTTP requests.
  • cdp and evaluate – Low-level Chrome DevTools Protocol helpers for direct browser control.

These globals represent the same objects that the CLI injects into script execution contexts, ensuring perfect parity between SDK and CLI environments.

Usage Examples

Standard Global Installation

When requiring ego-lite as a dependency, helpers attach to globalThis automatically:

// example-sdk-usage.js
const { installEgoSdk } = require('ego-browser');

// installEgoSdk() is normally called automatically on import, but shown here for clarity
installEgoSdk();

(async () => {
  // Page helpers
  await page.goto('https://example.com');
  console.log(await page.title());

  // Browser helpers
  const tabs = await browser.listTabs();
  console.log('Open tabs:', tabs.length);

  // Task-space helpers
  const ts = await taskSpaces.useOrCreate('my-space');
  console.log('Running in task space', ts.name);

  // Site-skill helpers
  const skills = await site.skills('https://example.com');
  console.log('Available skills:', skills);
})();

Scoped Target Installation

For environments where global pollution is undesirable, pass a specific target object:

const { installEgoSdk } = require('ego-browser');
const myEnv = {};

installEgoSdk(myEnv); // helpers attach to myEnv instead of globalThis

(async () => {
  await myEnv.page.goto('https://example.com');
  console.log(await myEnv.page.title());
})();

Summary

  • src/helpers.ts defines the unified helper context through helperContext(), aggregating façades for pages, browsers, task spaces, and network operations.
  • src/index.ts implements installEgoSdk, which conditionally executes on module load (when not in CLI mode) and attaches helpers to the target object.
  • Helpers are attached as non-enumerable, writable, and configurable properties using Object.defineProperty.
  • Synchronous helpers expose directly while asynchronous helpers wrap with wrapReady to respect the ready signal.
  • The resulting API surface matches the CLI environment exactly, providing page, browser, taskSpaces, site, fetch, cdp, and evaluate on the global scope by default.

Frequently Asked Questions

Can I prevent ego-lite from automatically polluting the global scope?

Yes. Instead of relying on the automatic installation in src/index.ts, explicitly import installEgoSdk and pass your own target object. This scopes all helpers to that specific object rather than globalThis, keeping your global namespace clean while still providing access to the full SDK functionality.

What is the difference between the SYNC_HELPERS set and regular helpers?

The SYNC_HELPERS set (which includes help) contains utilities that can execute immediately without waiting for the browser connection or "ready" signal. All other helpers—such as page, browser, and taskSpaces—are wrapped by wrapReady, meaning they delay execution until the underlying Playwright connection establishes and the ready signal fires, preventing premature API calls.

How do I access low-level Chrome DevTools Protocol methods?

The cdp and evaluate helpers are exposed directly on the global object (or your target) alongside the high-level façades. These provide raw access to browser internals and arbitrary JavaScript execution within the page context, useful when the Playwright-style abstractions need to be bypassed for specialized automation tasks.

Why are the helper properties non-enumerable?

The enumerable: false setting in Object.defineProperty ensures that ego-lite helpers do not appear in for...in loops or Object.keys() enumeration. This design choice prevents the automation APIs from interfering with application logic that iterates over global properties, while still making the helpers accessible as direct property references (e.g., globalThis.page).

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 →