# How to Run ego-browser Scripts from the Command Line

> Learn how to run ego-browser scripts from the command line using ego-lite. Execute JavaScript heredocs with browser-automation helpers against a managed Chromium instance.

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

---

**ego-browser executes JavaScript heredocs from STDIN, injecting browser-automation helpers and running them against a managed Chromium instance via the command line.**

The citrolabs/ego-lite repository provides **ego-browser** as a standalone CLI tool for browser automation. Running ego-browser scripts from the command line involves piping JavaScript code through STDIN using heredoc syntax, where the runtime automatically injects navigation and interaction helpers without requiring import statements.

## CLI Entry Point and Execution Flow

The entry point is located at **[`package/ego-browser/src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/index.ts)**, which begins with a shebang (`#!/usr/bin/env node`) allowing direct execution from any shell. When the runtime detects a normal CLI context via `isDirectCli()`, it invokes `runMain()` defined in **[`package/ego-browser/src/run.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/run.ts)** to parse arguments, read the script body, and manage the execution lifecycle.

## Passing Scripts via STDIN and Heredoc Syntax

Regular executions expect **no additional arguments**; the entire script body is read from STDIN. The `runMain()` function constructs an execution context using `helpers.helperContext()` and wraps the user code inside an `AsyncFunction`, enabling top-level await support within the heredoc.

A typical invocation uses the `nodejs` sub-command followed by a heredoc:

```bash
ego-browser nodejs <<'EOF'
const task = await useOrCreateTaskSpace('my example')
await openOrReuseTab('https://example.com', { wait: true })
cliLog(await snapshotText())
EOF

```

Inside the heredoc, **ego-browser helpers** such as `useOrCreateTaskSpace`, `openOrReuseTab`, and `cliLog` are available globally without import statements.

## Command-Line Flags for Debugging and Control

The CLI recognizes three special flags defined in [`package/ego-browser/src/run.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/run.ts):

### The --doctor Flag

Passing **`--doctor`** invokes `runDoctor()` to print a diagnostic view of the browser connection, verifying that the ego-lite runtime can communicate with the managed Chromium instance.

### The --reload Flag

Using **`--reload`** forces the next invocation to reset the Chrome DevTools Protocol connection by calling `services.resetConnection()`, ensuring a fresh browser state.

### The --debug-clicks Flag

Setting **`--debug-clicks`** enables verbose logging for click events by setting `process.env.EGO_BROWSER_DEBUG_CLICKS = "1"`, useful for debugging interaction scripts.

## Built-in Helpers and the Execution Context

Helper functions are exported from **[`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts)** and attached to `globalThis` when the SDK installs via `installEgoSdk`. This guarantees the same API surface whether running via CLI or importing as a library. Key helpers include:

- **`useOrCreateTaskSpace(name)`** – Creates an isolated browsing context that inherits login state
- **`openOrReuseTab(url, options)`** – Navigates to a URL or reuses an existing tab
- **`snapshotText()`** – Extracts visible text from the current page
- **`cliLog(...args)`** – Emits output to the terminal immediately

## Output Handling and Buffered Logging

The CLI buffers all standard `console.log` calls and flushes them only after script completion to ensure a clean result stream. To emit output immediately during execution, use **`cliLog()`**, which bypasses the buffer managed by **[`package/ego-browser/src/output-sink.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/output-sink.ts)**. Upon completion, `flushSink()` writes buffered content to STDOUT and the process exits with the appropriate `process.exitCode`.

## Practical Command-Line Examples

### Basic Page Navigation and Text Extraction

```bash
ego-browser nodejs <<'EOF'
const task = await useOrCreateTaskSpace('demo')
await openOrReuseTab('https://example.com', { wait: true })
cliLog('Page title →', await pageInfo().then(p => p.title))
cliLog('Full text →', await snapshotText())
EOF

```

### Interactive Form Submission

```bash
ego-browser nodejs <<'EOF'
await useOrCreateTaskSpace('search')
await openOrReuseTab('https://www.google.com', { wait: true })
await click('input[name="q"]')
await typeText('input[name="q"]', 'ego-browser')
await pressKey('Enter')
await waitForLoad()
cliLog('Results page title:', (await pageInfo()).title)
await captureScreenshot('google-results.png')
EOF

```

### Diagnostic and Connection Reset

```bash

# Check browser health

ego-browser --doctor

# Reset connection before new run

ego-browser --reload
ego-browser nodejs <<'EOF'
await useOrCreateTaskSpace('reset-demo')
await openOrReuseTab('https://example.org')
EOF

```

## Summary

- The CLI entry point at **[`package/ego-browser/src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/index.ts)** uses a Node.js shebang for direct shell invocation
- **`runMain()`** in **[`package/ego-browser/src/run.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/run.ts)** handles argument parsing and executes heredoc scripts from STDIN
- Three diagnostic flags control runtime behavior: **`--doctor`**, **`--reload`**, and **`--debug-clicks`**
- Helper functions inject automatically into the global scope without requiring import statements
- Use **`cliLog()`** for immediate terminal output; standard `console.log` is buffered until script completion

## Frequently Asked Questions

### How do I run an ego-browser script from the command line?

Pipe a JavaScript heredoc to the `ego-browser` binary using the `nodejs` sub-command or direct STDIN. The runtime automatically injects browser automation helpers and executes the code against the managed Chromium instance.

### What is the difference between cliLog and console.log in ego-browser?

`cliLog()` emits output to the terminal immediately, while `console.log` calls are captured by the output sink and buffered until the script finishes executing. Use `cliLog` when you need real-time feedback during long-running automation tasks.

### How do I reset the browser connection between ego-browser runs?

Invoke `ego-browser --reload` before your next script execution. This flag triggers `services.resetConnection()` to drop the existing Chrome DevTools Protocol session and establish a fresh connection.

### What does the --doctor flag do in ego-browser?

The `--doctor` flag runs `runDoctor()` from the runtime to print diagnostic information about the browser connection state, helping verify that the ego-lite environment can successfully communicate with the Chromium backend.