How Ego‑Lite Distinguishes Between CLI Mode and SDK Mode at Runtime
Ego‑Lite detects its execution context by checking whether package/ego-browser/src/index.ts is the entry script or an imported module, routing to runMain() for CLI mode or installEgoSdk() for SDK mode.
The citrolabs/ego-lite repository provides a lightweight browser automation runtime that adapts its behavior based on how the code is invoked. When the entry point at package/ego-browser/src/index.ts is executed directly, it operates as a command-line tool; when imported as a library, it exposes the runtime as an embeddable SDK.
Runtime Mode Detection Mechanism
The runtime distinguishes between CLI mode and SDK mode by evaluating whether the current file represents the application’s entry point. In CommonJS environments, this corresponds to the check require.main === module; in ES Module contexts, an equivalent determination identifies whether the file was imported or executed directly.
When package/ego-browser/src/index.ts is the entry script, the runtime immediately invokes CLI mode by calling runMain(). Conversely, if another module imports the file, the runtime enters SDK mode and exposes installEgoSdk() for the host application to initialize manually.
CLI Mode: Direct Execution with runMain()
In CLI mode, the runMain() function orchestrates the execution of automation scripts provided via STDIN. This function reads JavaScript code from standard input, constructs a helper context using the shared infrastructure, and immediately executes the supplied script for ad‑hoc automation tasks.
The stream processing logic resides in package/ego-browser/src/run.ts, which runMain() delegates to for consuming input and invoking the appropriate helpers. This design allows users to pipe scripts directly into the runtime without writing a custom entry point.
echo "await nav('https://example.com');" | node -e "import('./package/ego-browser/src/index.js').then(m => m.runMain())"
SDK Mode: Library Integration with installEgoSdk()
When imported as a module, ego‑lite exposes SDK mode through the installEgoSdk(globalThis) function. Instead of executing a script automatically, this function installs the Ego SDK onto the provided global object, exposing methods like nav, click, and js without assuming control of the execution flow.
This mode is utilized by the closed‑source Ego Lite application and other host programs that embed the runtime. The host supplies its own global object—typically globalThis—and manually initializes the SDK to make automation helpers available within its own managed context.
import { installEgoSdk } from './package/ego-browser/src/index.js';
// The host supplies its own global (e.g., the Ego Lite app)
installEgoSdk(globalThis);
// Now helpers like `nav`, `click`, `js` are available on the global object
await globalThis.nav('https://example.com');
Shared Infrastructure Across Both Modes
Both execution paths rely on identical underlying components to ensure consistent automation behavior. The helper context built in package/ego-browser/src/helpers.ts provides the same API surface regardless of invocation method, while package/ego-browser/src/browser-runtime.ts handles the core Chrome DevTools Protocol (CDP) transport and session management.
This architectural approach guarantees that scripts written for CLI mode execute identically when run through SDK mode, as both utilize the same browser automation primitives and context isolation strategies.
Summary
- Mode Detection: Ego‑Lite checks if
package/ego-browser/src/index.tsis the entry script to determine whether to invokerunMain()(CLI) or exportinstallEgoSdk()(SDK). - CLI Operation: Reads JavaScript from STDIN and executes immediately via
runMain(), utilizingpackage/ego-browser/src/run.tsfor stream handling. - SDK Operation: Registers helpers on a provided global object through
installEgoSdk(), enabling embedding in host applications like the Ego Lite app. - Unified Runtime: Both modes share
package/ego-browser/src/helpers.tsfor context construction andpackage/ego-browser/src/browser-runtime.tsfor CDP communication.
Frequently Asked Questions
How does ego‑lite detect if it's running in CLI mode?
Ego‑lite checks whether the current module is the application entry point using require.main === module in CommonJS or an equivalent ES Module check. When this condition is true, the runtime calls runMain() to process STDIN; otherwise, it exports installEgoSdk() for library usage.
What is the difference between runMain() and installEgoSdk()?
runMain() is activated in CLI mode and immediately reads JavaScript code from STDIN, builds a helper context, and executes the script. installEgoSdk() is called in SDK mode and attaches the automation API to a provided global object without executing any script, allowing host applications to control when and how helpers are invoked.
Can I use ego‑lite helpers in a custom host application?
Yes, by importing installEgoSdk from package/ego-browser/src/index.ts and passing your desired global object—typically globalThis—you can expose all ego‑lite helpers within your application's runtime environment. This pattern is used by the Ego Lite app to integrate the automation SDK into its own execution context.
Is the underlying browser runtime the same for both CLI and SDK modes?
Yes, both modes utilize package/ego-browser/src/browser-runtime.ts for CDP transport and session handling, and both construct their execution context using package/ego-browser/src/helpers.ts. This ensures that automation scripts behave identically regardless of whether they are piped through the CLI or executed within an embedded SDK context.
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 →