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

> Discover how ego-lite helpers are exposed in SDK mode. Learn how installEgoSdk attaches key functions like page, browser, and fetch to globalThis for easy access in your projects.

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

---

**When ego-lite operates as a library (SDK mode), the `installEgoSdk` function in [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/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`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts), the `helperContext()` function constructs an object containing all façades and low-level utilities:

```typescript
// 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`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts), the module determines whether it is running as a direct CLI or being required as a library:

```typescript
// 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`:

```typescript
// 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:

```javascript
// 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:

```javascript
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`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)** defines the unified helper context through `helperContext()`, aggregating façades for pages, browsers, task spaces, and network operations.
- **[`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/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`](https://github.com/citrolabs/ego-lite/blob/main/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`).