How ego-browser SDK Installs and Injects Helpers into the Global Scope
The ego-browser SDK uses installEgoSdk() in 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
The orchestration begins in [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:
// 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/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):
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 functionsego.learnings— accumulated automation insights- Wrapped task space methods (
createTab,useTaskSpace, etc.) for session state consistency
Practical Usage Examples
Automatic Installation (Standard Usage)
// 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
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
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/package/ego-browser/src/index.ts) |
installEgoSdk implementation; global injection orchestration |
[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/package/ego-browser/src/state.ts) |
Runtime configuration—timeouts, workspace paths |
[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/package/ego-browser/src/ego-errors.ts) |
Error taxonomy for SDK-thrown exceptions |
Summary
installEgoSdk()insrc/index.tsis 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 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/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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →