ego-lite CLI Entry Point vs installEgoSdk: How the Runtime Chooses Its Mode
The ego-lite CLI entry point functions as a conditional router that either executes a one-off script via runMain() when invoked directly from the command line, or bootstraps the full SDK environment via installEgoSdk() when imported as a library module.
The citrolabs/ego-lite repository implements a dual-mode architecture in package/ego-browser/src/index.ts that adapts its behavior based on the execution context. Understanding the relationship between the ego-lite CLI entry point and the installEgoSdk command reveals how the same codebase powers both standalone browser automation scripts and embedded runtime environments.
Execution Mode Detection
The entry point determines its operating mode through the isDirectCli() function (lines 75-79), which compares process.argv[1] against import.meta.url. When these values match, the script recognizes itself as the main module of a Node.js process and activates CLI mode. The file includes a shebang (#!/usr/bin/env node) to enable direct execution as a system binary.
// Conceptual representation of the detection logic in index.ts
if (isDirectCli()) {
// CLI mode: runMain() is invoked
} else {
// SDK mode: installEgoSdk() is invoked
}
The CLI Path: Direct Script Execution
When isDirectCli() returns true, the entry point invokes runMain(), imported from ./run.js (lines 58-60). This orchestrator executes the provided script against the browser runtime and returns an exit status code that the process stores in process.exitCode. Any errors encountered during execution are written to stderr (lines 60-61), ensuring proper error propagation in shell pipelines.
This path is designed for short-lived, heredoc-style invocations where users pipe JavaScript directly into the binary:
# Execute a script via the CLI entry point
echo "await page.goto('https://example.com'); console.log('Done');" |
node package/ego-browser/dist/out/index.js
The SDK Path: Runtime Installation
When the module is imported rather than executed directly, the else branch (line 64) calls installEgoSdk(). This function (lines 44-67 and 71-75) transforms the host environment into a fully-featured browser automation runtime by injecting helper functions, configuring output handling, and extending the host's ego object.
Building the Helper Context
The installation begins by constructing a helper context via helpers.helperContext() (line 51). The function removes legacy global definitions to prevent conflicts, then exposes each helper method onto the provided target object—typically globalThis. This injection makes browser automation primitives available globally within the host environment.
Configuring the Buffered Log Sink
The SDK replaces the native console.log implementation with a buffered sink (lines 75-81) to ensure output is captured correctly across asynchronous boundaries and short-lived execution contexts. This mechanism prevents log loss during rapid tab creation and destruction cycles common in automation workflows.
Developers can override this behavior by providing a custom cliLog function in the options parameter:
import { installEgoSdk } from 'package/ego-browser/src/index.js';
// Install with custom logging
installEgoSdk(globalThis, {
cliLog: (...args) => remoteLogger.log(...args)
});
Wrapping the Host Ego Object
If an ego object exists on the target, installEgoSdk wraps its tab-creation and task-space methods using wrapCreateTab and wrapInvalidating. It then exposes additional ego methods via exposeEgoMethods, decorating the host object with the full runtime API required for sophisticated browser orchestration.
Practical Implementation Examples
Running Standalone Scripts
Use the CLI entry point for one-off automation tasks without setting up a host application:
# Navigate and capture screenshot via CLI
echo "
await page.goto('https://github.com/citrolabs/ego-lite');
await page.screenshot({ path: 'ego-lite.png' });
" | node package/ego-browser/dist/out/index.js
Embedding in Host Applications
Import the module to install the SDK within a long-running Node.js process:
// host.js - Embedded runtime setup
import { installEgoSdk } from 'package/ego-browser/src/index.js';
// Install all helpers globally
installEgoSdk(globalThis);
// Runtime is now ready for automation
await page.goto('https://example.com');
console.log('Navigation complete');
Summary
- Dual-mode architecture: The
package/ego-browser/src/index.tsfile serves as both a CLI binary and a library entry point, selecting behavior viaisDirectCli(). - CLI execution: Direct invocations route to
runMain()(imported from./run.js) for immediate script execution with proper exit code handling. - SDK installation: Library usage triggers
installEgoSdk(), which builds a helper context, configures buffered logging, and exposes browser automation APIs onto the global scope. - Extensible logging: The SDK supports custom log sinks through the
cliLogoption, allowing integration with external logging systems.
Frequently Asked Questions
What determines whether ego-lite runs in CLI mode or SDK mode?
The isDirectCli() function checks if process.argv[1] matches import.meta.url. When they match, the script is the entry point and executes runMain(); otherwise, it calls installEgoSdk() to initialize the library mode.
How does installEgoSdk modify the global environment?
The function exposes helper methods onto the target object (usually globalThis), replaces console.log with a buffered output sink, and wraps existing ego object methods to add runtime capabilities. It also cleans up legacy global definitions to prevent namespace pollution.
Can I customize the logging behavior when using installEgoSdk?
Yes. Pass a cliLog function in the options object when calling installEgoSdk(target, { cliLog: customFn }). Your custom function will receive all console output instead of the default buffered sink, enabling integration with remote loggers or UI components.
Where is the script execution logic located for CLI mode?
The actual execution logic resides in package/ego-browser/src/run.ts, which exports the runMain function. This module handles the browser session lifecycle, script evaluation, and error handling when ego-lite operates as a command-line tool.
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 →