Two Startup Paths for the ego-browser Package: CLI vs SDK Explained
The ego-browser package can be started as a direct CLI via runMain() or imported as a module to run installEgoSdk(), as implemented in package/ego-browser/src/index.ts.
The ego-browser entry point from the citrolabs/ego-lite repository dynamically detects its execution context and branches into one of two initialization flows. This dual-mode design allows the same package to function both as a standalone script executor and as a programmable SDK for agent automation.
Detecting the Startup Mode in index.ts
The branching logic resides in [package/ego-browser/src/index.ts](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/index.ts). At runtime, the module checks isDirectCli() to determine whether it was invoked directly from the command line or loaded via import/require.
// Simplified flow from index.ts
if (isDirectCli()) {
runMain(); // CLI execution path
} else {
installEgoSdk(); // SDK installation path
}
Source: index.ts:55-59 (imports) and the conditional block around index.ts:62-66.
Path 1: Direct CLI Execution via runMain()
When ego-browser is executed directly—such as node package/ego-browser/src/index.js or piped input—it follows the CLI startup path. This path:
- Reads JavaScript source code from stdin
- Executes the script within a prepared browser context
- Exits the process with the appropriate status code
The heavy lifting is delegated to runMain(), defined in [package/ego-browser/src/run.ts](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/run.ts).
CLI Usage Example
# Execute a one-liner from stdin
echo "await page.goto('https://example.com'); console.log(await page.title());" \
| node package/ego-browser/src/index.js
Source: Entry point conditional at index.ts:62-63 invoking runMain().
Path 2: Module Import via installEgoSdk()
When ego-browser is imported as a dependency, it follows the SDK startup path. This path:
- Calls
installEgoSdk()to inject helper methods onto a target object (typicallyglobalThis) - Configures structured logging handlers
- Patches the host
egoruntime with additional browser automation utilities - Does not read from stdin or exit the process
This mode is designed for long-running agent processes that programmatically control browser sessions.
SDK Usage Example
// my-automation-script.mjs
import { installEgoSdk } from 'ego-browser';
// Install helpers onto the global object
installEgoSdk(globalThis);
// Helpers are now available without explicit imports
await page.goto('https://example.com');
const title = await page.title();
console.log(`Page title: ${title}`);
// Script continues executing; process does not auto-exit
Source: SDK installation block at index.ts:64-66.
How isDirectCli() Determines the Path
The runtime detection relies on inspecting require.main and process.argv[1] to check if the current module matches the entry point. When true, the CLI path executes; otherwise, the module assumes SDK mode. This heuristic ensures import statements in other files never accidentally trigger runMain().
Summary
runMain()— Activated whenego-browseris run directly as a CLI; reads stdin, executes scripts, and exits.installEgoSdk()— Activated whenego-browseris imported as a module; injects helpers and prepares the runtime for programmatic use.- Both paths originate from [
package/ego-browser/src/index.ts](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/index.ts), withisDirectCli()as the decision gate. - The dual-path architecture is documented in [
AGENTS.md](https://github.com/citrolabs/ego-lite/blob/main/AGENTS.md), which identifiesindex.tsas the entry point with these two startup modes.
Frequently Asked Questions
What triggers the CLI mode versus SDK mode in ego-browser?
CLI mode triggers when the module is executed directly—node package/ego-browser/src/index.js or equivalent—causing isDirectCli() to return true. SDK mode triggers on any import or require statement from another module, where isDirectCli() returns false and installEgoSdk() runs instead.
Can I use ego-browser in a Node.js script without it exiting automatically?
Yes. Import installEgoSdk and call it explicitly. This SDK path does not invoke runMain(), so your script maintains control of the event loop and must manage its own process lifecycle. See the SDK usage example above.
Where is the runMain() function defined?
The runMain() function is implemented in [package/ego-browser/src/run.ts](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/run.ts). It handles stdin reading, script execution, and coordinated exit codes. The entry point imports it at index.ts:55.
Is there documentation explaining these startup paths?
Yes. The repository's [AGENTS.md](https://github.com/citrolabs/ego-lite/blob/main/AGENTS.md) file explicitly states that package/ego-browser/src/index.ts serves as the entry point with two startup paths, though the detailed implementation requires examining the source code directly.
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 →