# Understanding `helperContext()` and Its Facades in ego-browser Agent Scripts

> Discover how helperContext() injects a Playwright-like API into ego-browser agent scripts. Learn about its facades for page automation, tab management, and more.

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

---

**The `helperContext()` function in ego-browser serves as the central factory that injects a Playwright-like API surface into every agent script, including facades for page automation, browser tab management, task spaces, site skills, network fetching, and Chrome DevTools protocol access.**

When you write automation scripts for citrolabs/ego-lite, you don't interact with raw CDP commands directly. Instead, the runtime calls `helperContext()` to build a curated set of **facades**—lightweight wrapper objects that expose browser capabilities through a clean, promise-based interface. This design lets you write concise, readable agent code while maintaining access to low-level primitives when necessary.

## What `helperContext()` Does

Located at [[`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts#L822), `helperContext()` is the **single source of truth** for all helper functions available in ego-browser agent scripts. It aggregates multiple facade creators, merges them into one context object, and optionally blends in custom helpers supplied by the caller.

The function signature supports extensibility:

```javascript
function helperContext(extra?: Record<string, any>): HelperContext

```

When invoked, it returns an object containing all built-in facades. If you pass an `extra` object, its properties are shallow-merged into the result—allowing your custom utilities to coexist with the official API.

## The Seven Core Facades

Each facade isolates a specific automation domain. Below is the complete breakdown of what `helperContext()` injects into your scripts:

### page

The **page** facade provides Playwright-style page operations: navigation, element locating, waiting, screenshots, and more. It is constructed by [`createPageFacade()`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts#L684) and represents the most frequently used surface.

```javascript
// Typical page operations in an agent script
await page.goto('https://news.ycombinator.com');
const story = page.getByText('Show HN').first();
await story.click();
await waitForLoadState('networkidle');

```

Under the hood, calls route through [[`src/driver/page.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/page.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/locator.ts) and its related modules for locator resolution and navigation.

### browser

The **browser** facade handles tab lifecycle management—listing, switching, opening, and closing tabs. This abstracts the complexity of CDP's Target domain into simple method calls.

```javascript
const tabs = await browser.listTabs();
await browser.openOrReuseTab('https://github.com/citrolabs/ego-lite');
await browser.switchTab(tabs[0].id);
await browser.closeTab(tabs[1].id);

```

Implementation resides in the driver layer, with [[`src/driver/browser.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/browser.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/nav.ts) providing the underlying functionality.

### taskSpaces

The **taskSpaces** facade manages isolated task-space lifecycles: creation, claiming, switching, completion, and hand-off between agents. This enables multi-step workflows where different automation phases run in separate contexts.

```javascript
const ts = await taskSpaces.useOrCreate('my-workspace');
await taskSpaces.claim(ts.id);
await taskSpaces.waitForAgentControl(ts.id, { timeout: 5000 });

```

The driver implementation is found in [[`src/driver/taskspace.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/taskspace.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/taskspace.ts) or related test files demonstrating the lifecycle logic.

### site

The **site** facade connects to ego-browser's learning system, exposing site-specific skills and tools learned from prior automation sessions.

```javascript
const skill = await site.skills('https://example.com');
await site.runTool('exampleSite', 'login', { username: 'bob', password: 'secret' });

```

This integrates with [[`src/learning/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/learning/index.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/learning/index.ts) to retrieve and execute learned behaviors.

### fetch

The **fetch** facade provides network request capabilities from two contexts:

- **`fetch.server`** — Node-side HTTP requests
- **`fetch.browser`** — In-browser `fetch` execution

```javascript
const data = await fetch.browser('https://api.example.com/data', { method: 'GET' });
console.log(await data.json());

```

These directly reference the exported `serverFetch` and `browserFetch` functions within [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts).

### cdp

The **cdp** facade exposes raw Chrome DevTools Protocol access when you need capabilities not covered by higher-level APIs. It is re-exported from [[`src/cdp-eval.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/cdp-eval.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/cdp-eval.ts).

```javascript
const result = await cdp('Runtime.evaluate', { expression: 'navigator.userAgent' });
console.log(result.result.value);

```

### help

The **help** facade provides interactive documentation. It first consults the [`FACADE_HELP`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts#L809) map for quick one-liner descriptions, falling back to runtime-generated JSDoc help when needed.

```javascript
console.log(help('page'));        // Concise description from FACADE_HELP
console.log(help('page.goto'));   // Detailed method documentation

```

## How Facades Connect to Driver Modules

The facade pattern in ego-browser creates a clean separation:

| Layer | Responsibility | Example Files |
|-------|---------------|---------------|
| **Facade** | User-facing API with domain-specific methods | `createPageFacade()`, `createBrowserFacade()` in [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts) |
| **Driver** | Low-level CDP orchestration and state management | [`src/driver/page.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/page.ts), [`src/driver/browser.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/browser.ts), [`src/driver/taskspace.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/taskspace.ts) |
| **CDP Eval** | Direct Chrome DevTools Protocol transmission | [`src/cdp-eval.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/cdp-eval.ts) |

When you call `page.goto()`, the facade translates this to driver calls, which ultimately serialize CDP commands through the browser connection. This three-tier architecture keeps agent scripts simple while preserving full control for advanced use cases.

## Extending `helperContext()` with Custom Helpers

The `extra` parameter enables environment customization without forking the codebase:

```javascript
// When invoking helperContext programmatically
const context = helperContext({
  myUtility: async (selector) => {
    // Custom helper available alongside built-in facades
    return page.locator(selector).count();
  }
});

// Now available in scripts as `myUtility()`

```

This shallow-merge approach ensures your additions don't conflict with core facade names while still appearing in the same lexical scope.

## Summary

- **`helperContext()`** at [`helpers.ts:L822`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts#L822) is the centralized factory for all ego-browser agent script capabilities
- **Seven facades** cover the full automation surface: `page`, `browser`, `taskSpaces`, `site`, `fetch`, `cdp`, and `help`
- Each facade delegates to **driver modules** in `src/driver/` for actual CDP operations
- **`FACADE_HELP`** provides built-in documentation accessible via the `help` facade
- **Extensibility via `extra` parameter** allows custom helpers to integrate seamlessly

## Frequently Asked Questions

### How do I access the raw CDP connection if a facade doesn't expose what I need?

Use the `cdp` facade directly. It accepts CDP domain and method names plus parameters, returning the raw protocol response. For example: `await cdp('DOM.querySelector', { nodeId: 1, selector: 'div' })`. This bypasses all abstraction layers and communicates straight with Chrome.

### Can I use `helperContext()` outside of CLI-run scripts?

Yes. When importing ego-browser as a module, call `helperContext()` directly and pass the result to your script functions. The `extra` parameter lets you inject dependencies or mocks for testing. The same facades work identically whether invoked through CLI or programmatically.

### What's the difference between `fetch.server` and `fetch.browser`?

`fetch.server` executes requests from the Node.js process running ego-browser, bypassing browser security policies and cookies. `fetch.browser` executes `fetch()` inside the actual page context, inheriting cookies, CORS rules, and the page's network isolation. Choose `fetch.server` for API calls that don't need browser state; use `fetch.browser` when you need the page's authenticated session.

### Where are the facade implementations actually defined?

Each facade has a dedicated creator function in [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts): `createPageFacade()` at line 684, `createBrowserFacade()`, `createTaskSpacesFacade()`, and `createSiteFacade()` follow later in the same file. These functions return plain objects whose methods close over the internal driver state.