# How ego-browser SDK Installs and Injects Helpers into the Global Scope

> Discover how the ego-browser SDK installs and injects helpers into the global scope using installEgoSdk() for instant access to browser automation methods without imports.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: how-to-guide
- Published: 2026-08-29

---

**The ego-browser SDK uses `installEgoSdk()` in [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts) to automatically inject a suite of browser automation helpers into `globalThis` when loaded as a library, making methods like `page.goto()` and `browser.listTabs()` instantly available without explicit imports.**

The **ego-browser SDK** is the runtime foundation of the **ego-lite** browser automation framework. When you load your automation scripts, the SDK transparently wires up a complete API surface—page controls, browser management, task spaces, and more—directly onto the global object. This deep dive examines the exact mechanism that makes this "zero-import" developer experience possible.

## The Entry Point: `installEgoSdk` in [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts)

The orchestration begins in [[`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/index.ts), specifically lines 44-65. When the module detects it's being loaded as a library (not via CLI), it invokes `installEgoSdk()` automatically:

```typescript
// From src/index.ts - automatic installation path
if (require.main !== module) {
  installEgoSdk();
}

```

This unconditional auto-install is what eliminates the need for manual setup in most user scripts.

## Step-by-Step Installation Flow

### 1. Target Selection

By default, `installEgoSdk` targets **`globalThis`**, but accepts any object as the `target` parameter. This flexibility enables sandboxed testing environments or custom runtime containers.

### 2. Helper Context Assembly

The `helperContext()` function (defined in [[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts), lines 22-35) constructs a façade object grouping all public helpers:

| Helper Category | Key Methods |
|---------------|-------------|
| `page` | `goto()`, `locator()`, `waitFor()`, `evaluate()` |
| `browser` | `listTabs()`, `createTab()`, `closeTab()` |
| `taskSpaces` | `useOrCreate()`, `list()`, `cleanup()` |
| `site` | Domain-specific navigation utilities |
| `fetch` | HTTP requests with SDK integration |
| `cdp` | Chrome DevTools Protocol access |

### 3. Legacy Global Cleanup

Before injection, the SDK scrubs legacy helper names to prevent namespace collisions (lines 52-56). Legacy identifiers like `click` and `goto` are explicitly deleted from the target object.

### 4. Readiness Wrapper Application

Most helpers are wrapped with `wrapReady`, which defers execution until an optional `ready` promise resolves. This ensures the underlying browser runtime is fully initialized before any automation command executes. Synchronous helpers—notably `help`—bypass this wrapper for immediate availability (lines 63-67).

### 5. Non-Enumerable Property Definition

Helpers are attached via `Object.defineProperty` with precise configuration (lines 67-73):

```typescript
Object.defineProperty(target, helperName, {
  value: wrappedHelper,
  writable: true,
  enumerable: false,  // Hidden from for...in loops
  configurable: true
});

```

This design choice keeps the helpers operationally global while preventing them from polluting enumerations of `globalThis`.

### 6. Console Redirection

SDK output capture begins at lines 80-86, where `console.log` is overridden to route through a buffered sink or host-provided logger. This ensures all automation output is controllable and testable.

### 7. Runtime Integration

If the target already contains an `ego` object (the native host runtime), the SDK enhances it with:

- `ego.helpers` — map of all injected helper functions
- `ego.learnings` — accumulated automation insights
- Wrapped task space methods (`createTab`, `useTaskSpace`, etc.) for session state consistency

## Practical Usage Examples

### Automatic Installation (Standard Usage)

```typescript
// No installation code needed—SDK auto-injects on import
// File: my-script.js
await page.goto("https://example.com");
await page.locator("button#submit").click();
const title = await page.locator("h1").textContent();
console.log(`Page title: ${title}`);

```

### Manual Installation with Custom Target

```typescript
import { installEgoSdk } from "ego-browser";

const isolatedScope = {};
installEgoSdk(isolatedScope);

// Helpers exist only on the custom object
await isolatedScope.page.goto("https://example.org");
await isolatedScope.browser.listTabs();

```

### Custom Readiness Signal and Logging

```typescript
import { installEgoSdk } from "ego-browser";

// Simulate async infrastructure warmup
const readySignal = new Promise<void>(resolve => {
  setTimeout(resolve, 500);
});

installEgoSdk(globalThis, {
  ready: readySignal,
  cliLog: (...args) => {
    process.stderr.write(`[SDK] ${args.join(" ")}\n`);
  }
});

// Helpers await readySignal before executing
await page.goto("https://example.com");

```

## Core Source Files Reference

| File | Responsibility |
|------|---------------|
| [[`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/index.ts) | `installEgoSdk` implementation; global injection orchestration |
| [[`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) | `helperContext()` definition; helper façade assembly |
| [[`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/state.ts) | Runtime configuration—timeouts, workspace paths |
| [[`src/run.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/run.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/run.ts) | Script execution harness; helper injection trigger |
| [[`src/ego-errors.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/ego-errors.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/ego-errors.ts) | Error taxonomy for SDK-thrown exceptions |

## Summary

- **`installEgoSdk()`** in [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts) is the sole entry point for SDK bootstrapping, invoked automatically when loaded as a library.
- **`helperContext()`** assembles the complete helper API from discrete functional domains (page, browser, taskSpaces, etc.).
- **Legacy cleanup, readiness wrapping, and non-enumerable properties** ensure clean, predictable global injection without namespace pollution.
- **Console redirection and runtime integration** complete the SDK initialization, unifying output capture and host communication.

## Frequently Asked Questions

### Can I prevent automatic global injection?

No built-in flag exists to disable auto-installation when importing the SDK as a library. However, you can import individual helpers directly from [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) and avoid the global-target path entirely. For test isolation, pass a custom target object to `installEgoSdk(sandbox)` instead of `globalThis`.

### What happens if helpers conflict with existing globals?

The SDK proactively deletes known legacy names (`click`, `goto`, etc.) from the target before injection. For unknown conflicts, `Object.defineProperty` with `writable: true` allows subsequent code to overwrite SDK helpers if necessary, though this is discouraged.

### How do I await SDK readiness before executing commands?

Pass a `ready` promise in the options parameter: `installEgoSdk(globalThis, { ready: myInitPromise })`. All wrapped helpers (page, browser, taskSpaces) will automatically queue until this promise resolves. Synchronous helpers like `help()` execute immediately regardless of readiness state.

### Where is the best place to customize helper behavior?

Runtime customization belongs in [[`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts)](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/state.ts), which exports the `state` object holding default timeouts and workspace configuration. For helper-level changes, extend or replace the corresponding function in `helperContext()` before calling `installEgoSdk`.