# Understanding the Helper Context Architecture and Page/Browser Facades in ego-browser

> Explore the ego-browser helper context architecture and its page/browser facades. Gain a Playwright-style API for AI agents to control browser tabs, navigation, and task isolation.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: architecture
- Published: 2026-07-24

---

**The ego-browser helper context architecture bundles six specialized facades—page, browser, taskSpaces, site, fetch, and cdp—into a single object that provides AI agents with a Playwright-style API for controlling browser tabs, navigation, and task isolation while keeping low-level Chrome DevTools Protocol (CDP) plumbing encapsulated.**

The `ego-browser` package within the `citrolabs/ego-lite` repository implements a modular helper context architecture that bridges raw CDP operations and high-level agent scripting. Defined primarily in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts), the `helperContext` function assembles lightweight facade objects that expose browser automation capabilities through an ergonomic, Playwright-inspired interface, allowing agents to drive the embedded browser without managing protocol complexity directly.

## The `helperContext` Entry Point

At the heart of the system lies the `helperContext` function (lines 22‑50 in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)). This factory function constructs a single context object that aggregates multiple facades, merges any **extra helpers** supplied by the caller, and attaches a `help` method that prints JSDoc‑derived documentation.

```typescript
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: (...names: string[]) => { /* prints documentation */ },
  };
}

```

The runtime entry point ([`src/run.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/run.ts)) injects this object into the agent’s script scope, making all façade methods globally available.

## Core Facades Overview

The helper context exposes six distinct facades, each responsible for a specific domain of browser interaction:

| Facade | Purpose | Creator Function | Key Capabilities |
|--------|---------|------------------|------------------|
| **`page`** | Playwright‑style page API | `createPageFacade()` (lines 64‑84) | Navigation, locator creation, input actions, screenshots |
| **`browser`** | Tab‑level control | `createBrowserFacade()` (lines 73‑83) | Listing, switching, opening, and closing tabs |
| **`taskSpaces`** | Task‑space lifecycle management | `createTaskSpacesFacade()` (lines 85‑97) | Isolated session handling, ownership claims |
| **`site`** | Site‑skill data access | `createSiteFacade()` (lines 99‑107) | Learned automation skills, tool execution |
| **`fetch`** | Network abstraction | Inline (lines 28‑31) | Server‑side and browser‑origin HTTP requests |
| **`cdp`** | Raw CDP command dispatcher | Re‑exported (lines 27‑28) | Direct protocol access via [`src/cdp-eval.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/cdp-eval.ts) |

## How the Page Facade Works

The `createPageFacade()` function builds a thin wrapper around lower‑level drivers (`nav`, `pointer`, `keyboard`, `waits`, `observe`, etc.), exposing a comprehensive page automation API.

### Navigation and State

Methods such as `goto`, `reload`, `info`, `url`, and `title` delegate directly to [`src/driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/nav.ts), providing high‑level navigation controls that automatically handle timeouts and load states.

```typescript
// Navigation with automatic wait handling
await page.goto('https://example.com');
await page.waitForLoadState('networkidle');
const currentUrl = await page.url();

```

### Locator API and Element Interaction

The `locator` method returns a **strict locator object** created by `createLocator()` (defined in [`src/driver/locator.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/locator.ts), lines 20‑112). This object implements actions like `click`, `fill`, `press`, and `hover` by forwarding to the corresponding driver modules ([`src/driver/pointer.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/pointer.ts) for mouse actions, [`src/driver/keyboard.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/keyboard.ts) for text input).

Convenience getters such as `getByRole`, `getByText`, `getByLabel`, and `getByPlaceholder` build selector strings using internal `textSelector` and `roleSelector` helpers before returning a configured locator. All locator methods automatically wait for elements to reach a stable state, mirroring Playwright’s auto‑awaiting behavior.

```typescript
// Using convenience getters and locator chains
const loginBtn = page.getByText('Log in');
await loginBtn.click();

const items = page.locator('ul > li')
  .filter({ hasText: /Item \d+/ })
  .nth(0);
await items.click();

```

### Utility Methods

The facade also exposes `evaluate` for JavaScript execution, `screenshot` and `snapshot` for visual capture, `setDefaultTimeout` for adjusting the global `state.defaultTimeout`, and direct access to `keyboard` and `mouse` helpers.

## How the Browser Facade Works

The `createBrowserFacade()` provides tab‑level control by re‑exporting primitives from [`src/driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/nav.ts). Unlike the page facade’s element‑focused API, this facade manages the browser’s tab lifecycle.

Key methods include:

- **`listTabs`** – Returns an array of open tabs
- **`currentTab`** – Gets the active tab identifier
- **`switchTab`** – Changes the active context to a specific tab
- **`openOrReuseTab`** – Opens a new tab or reuses an existing one matching a URL pattern
- **`closeTab`** – Closes a specific tab
- **`ensureRealTab`** – Validates that a tab exists and is accessible
- **`iframeTarget`** – Returns the CDP target for iframe traversal

```typescript
// Managing multiple tabs
await browser.openOrReuseTab('https://news.ycombinator.com');
const tabs = await browser.listTabs();
await browser.switchTab(await browser.currentTab());

```

## Supporting Facades

### Task Spaces

The `taskSpaces` facade manages isolated task‑space lifecycles, allowing agents to create sandboxed sessions. It exposes `list`, `switch`, `new`, `useOrCreate`, `claim`, `complete`, `handOff`, `takeOver`, and `waitForAgentControl` for ownership and state management.

```typescript
const space = await taskSpaces.useOrCreate('my-session');
await space.claim();  // Take ownership if user-owned
await taskSpaces.complete(space.id, { keep: true });

```

### Site Skills and Fetch

The `site` facade provides access to learned automation skills via `skills`, `skillsForUrl`, and `runTool`, enabling agents to execute predefined workflows for specific domains. The `fetch` facade offers dual interfaces—`fetch.server` for server‑side requests and `fetch.browser` for browser‑origin network calls—abstracting HTTP concerns away from CDP details.

### Direct CDP Access

For scenarios requiring protocol‑level control, the `cdp` facade (exported from [`src/cdp-eval.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/cdp-eval.ts)) exposes a direct command dispatcher, allowing raw CDP message construction while maintaining the context’s structural benefits.

## Architecture Flow: From CDP to Agent

The helper context architecture follows a layered delegation pattern:

1. **Low‑level drivers** ([`src/driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/nav.ts), [`src/driver/pointer.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/pointer.ts), [`src/driver/keyboard.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/keyboard.ts), [`src/driver/locator.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/locator.ts)) interact directly with the CDP bridge via `ego.sendCDPMessage`.

2. **Higher‑level helpers** ([`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)) compose these drivers into coherent facades that group related operations by domain (page interaction vs. tab management).

3. **`helperContext`** bundles the facades with raw `cdp` access, optional custom helpers, and documentation utilities.

4. **Runtime injection** ([`src/run.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/run.ts)) places this context into the agent’s execution scope, presenting a unified,Playwright‑style surface while keeping CDP complexity encapsulated.

## Summary

- The **helper context** in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) acts as the central factory, assembling six specialized facades into a single object for agent consumption.

- **Page facade** (`createPageFacade`) wraps navigation drivers and the locator system to provide auto‑awaiting element interaction and screenshots.

- **Browser facade** (`createBrowserFacade`) exposes tab management primitives from [`src/driver/nav.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/nav.ts) for multi‑tab workflows.

- **Supporting facades** handle task isolation (`taskSpaces`), learned automation (`site`), network requests (`fetch`), and raw protocol access (`cdp`).

- All operations route through low‑level drivers that communicate via CDP, ensuring the agent API remains stable while underlying protocol details stay isolated.

## Frequently Asked Questions

### What is the difference between the page and browser facades in ego-browser?

The **page facade** focuses on document‑level interactions within the current tab—navigation, element location via `getBy*` methods, and input actions—while the **browser facade** handles tab‑level control such as opening new tabs, switching contexts, and listing available targets. Use `page` for manipulating content and `browser` for managing windows and tabs.

### How does the helper context handle element waiting and timeout configuration?

The helper context implements **auto‑awaiting** at the driver level, particularly within the locator system in [`src/driver/locator.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/driver/locator.ts). When you call methods like `click()` or `fill()` on a locator, it automatically waits for the element to become stable and actionable. You can adjust global timeout behavior using `page.setDefaultTimeout()`, which updates the shared `state.defaultTimeout` variable accessed by all waiting operations.

### What are task spaces and when should agents use them?

**Task spaces** are isolated execution environments managed by the `taskSpaces` facade (lines 85‑97 in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)). Agents should use them when performing multi‑step workflows that require state isolation, ownership handoff between agents, or cleanup guarantees. Methods like `claim()` and `handOff()` manage concurrent access, ensuring that only one agent controls a specific task space at a time.

### Can I extend the helper context with custom functionality?

Yes. The `helperContext` function accepts an `extra` parameter (defaulting to an empty object) that spreads into the final context object. Pass custom utilities or domain‑specific helpers when initializing the context, and they will be available alongside the built‑in facades. The `help()` method also indexes these extra helpers if they include JSDoc comments, making custom extensions discoverable to agents.