# Ego-Lite Helper Context Injection Architecture: How Agent Scripts Access the Unified API

> Discover the ego-lite helper context injection architecture. Learn how agent scripts access the unified API via centralized helperContext() for SDK or CLI execution.

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

---

**Ego-Lite injects a unified helper context into agent scripts through a centralized `helperContext()` function that assembles facade objects and custom helpers, then distributes them via two entry points: `installEgoSdk()` for SDK embedding and `executionContext()` for CLI execution.**

The helper context injection architecture in [ego-lite](https://github.com/citrolabs/ego-lite) ensures that every agent script—whether run as an embedded SDK or a standalone CLI script—receives an identical, well-documented set of automation helpers. This design eliminates API divergence and provides a single source of truth for all agent-facing functionality.

## The Core: `helperContext()` in [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts)

The architecture centers on [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts), where the `helperContext()` function builds the complete helper surface that agents consume.

```ts
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[]) => { /* returns JSDoc-based documentation */ },
  };
}

```

This function performs four key operations:

- **Creates facade objects** (`createPageFacade`, `createBrowserFacade`, `createTaskSpacesFacade`, `createSiteFacade`) that wrap low-level driver modules
- **Exposes core utilities** including `cdp` (Chrome DevTools Protocol access) and a dual-mode `fetch` (server-side and browser-side)
- **Merges custom helpers** from the `extra` parameter, enabling project-specific extensions
- **Attaches a `help` utility** that dynamically extracts documentation from JSDoc comments at runtime

The facades delegate to specialized driver modules in `src/driver/*` (pointer, keyboard, navigation, etc.), providing a Playwright-style API without exposing implementation complexity.

## Two Injection Paths: SDK and CLI

Ego-Lite maintains API consistency by routing both execution modes through the same `helperContext()` function.

### SDK Injection via `installEgoSdk()`

When the ego-lite binary embeds the library, [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts) provides the `installEgoSdk()` function:

```ts
export function installEgoSdk(target = globalThis, options = {}) {
  const context = options.context || helpers.helperContext();
  // Each helper is defined on the target (global) object as non-enumerable, writable
  Object.defineProperties(target, Object.fromEntries(
    Object.entries(context).map(([key, value]) => [
      key,
      { value, writable: true, enumerable: false, configurable: true }
    ])
  ));
}

```

This approach makes helpers globally available inside the embedded browser runtime while keeping them non-enumerable to avoid polluting iteration over global properties.

### CLI Injection via `executionContext()`

For heredoc scripts executed from the command line, [`src/run.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/run.ts) implements `executionContext()`:

```ts
export async function executionContext() {
  const agentHelpers = await helpers.loadAgentHelpers();
  const context = helpers.helperContext(agentHelpers);
  // The returned object becomes the script's global scope
  return context;
}

```

Both paths guarantee identical helper availability because they invoke the same core function.

## Extending Helpers with [`agent_helpers.js`](https://github.com/citrolabs/ego-lite/blob/main/agent_helpers.js)

The architecture supports custom helpers through a dynamic loading mechanism. When `helperContext()` receives the `extra` parameter populated by `loadAgentHelpers()`, project-specific functions merge into the context.

```js
// File: skills/ego-browser/agent_helpers.js
export async function myCustomHelper(arg) {
  const info = await page.info();
  console.log('Current URL:', info.url, 'Argument:', arg);
}

```

Scripts can then call these custom helpers directly:

```ts
// Available in both SDK and CLI contexts
await page.goto('https://example.com');
await taskSpaces.useOrCreate('my-space');
await myCustomHelper('custom argument');  // From agent_helpers.js

```

The `loadAgentHelpers()` function locates this file via the `agentWorkspace` state managed in [`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts).

## Runtime Behavior and Sequencing

Two additional mechanisms ensure reliable execution:

- **`wrapReady`** – Wraps async helpers to await an optional `ready` promise, preventing premature calls before the runtime initializes
- **Non-enumerable global properties** – In SDK mode, helpers attach to `globalThis` without appearing in `Object.keys(globalThis)` or `for...in` loops

## Summary

- **`helperContext()`** in [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) is the single source of truth for all agent-facing helpers
- **Facade pattern** isolates agents from driver implementation details while providing familiar Playwright-style APIs
- **Dual entry points** (`installEgoSdk` and `executionContext`) guarantee identical helper availability across SDK and CLI execution
- **Dynamic helper loading** via [`agent_helpers.js`](https://github.com/citrolabs/ego-lite/blob/main/agent_helpers.js) enables project extensions without core modifications
- **Non-enumerable global injection** preserves JavaScript runtime semantics in embedded contexts

## Frequently Asked Questions

### What is the helper context injection architecture in ego-lite?

The helper context injection architecture in ego-lite is a centralized system where `helperContext()` assembles automation helpers (page, browser, taskSpaces, site, fetch, cdp) into a single object, then distributes them through `installEgoSdk()` for embedded SDK usage or `executionContext()` for CLI scripts. Both paths use the same core function to prevent API divergence.

### How does ego-lite make helper functions available globally to agent scripts?

For SDK embedding, `installEgoSdk()` uses `Object.defineProperties()` to attach helpers to `globalThis` as non-enumerable, writable values. For CLI execution, `executionContext()` returns the helper context object as the script's global scope. Both approaches expose the same method signatures and behavior.

### Can I add custom helper functions to ego-lite's agent context?

Yes. Create an [`agent_helpers.js`](https://github.com/citrolabs/ego-lite/blob/main/agent_helpers.js) file in your agent workspace and export functions. `loadAgentHelpers()` dynamically imports this file and passes its exports to `helperContext()` as the `extra` parameter, merging your custom functions into the unified context alongside built-in facades.

### What are the facade objects in ego-lite's helper context?

The facades are `page`, `browser`, `taskSpaces`, and `site`—thin wrapper objects created by `createPageFacade()`, `createBrowserFacade()`, `createTaskSpacesFacade()`, and `createSiteFacade()`. They expose high-level methods like `page.goto()` and `browser.listTabs()` while delegating to low-level driver modules in `src/driver/*`.