# How to Contribute to ego-lite: A Complete Guide to the ego-browser SDK

> Learn how to contribute to ego-lite. Follow our guide to clone the repo, set up the Node.js environment, write tests, and submit a PR for the ego-browser SDK.

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

---

**To contribute to ego-lite, clone the repository, set up the Node.js development environment in `package/ego-browser/`, write tests for your changes, and submit a PR following the four design principles and Conventional Commits format.**

The **ego-lite** repository contains the **ego-browser** Node.js SDK that powers the ego-lite Chromium browser for human-agent collaboration. Contributing means extending or fixing the SDK code and its site-learning packs while following the project's architecture, style, and CI requirements. This guide walks through the complete contribution workflow based on the official source code in `citrolabs/ego-lite`.

## Architecture Overview

Understanding the SDK's layered architecture helps you target the right files for your contribution.

| Layer | Description | Key Source |
|-------|-------------|------------|
| **CLI / SDK entry point** | `runMain()` parses the heredoc, injects helpers, and executes the user script | [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts) |
| **Helper surface** | [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts) builds the public API (`click`, `goto`, `snapshot`, task-space helpers, etc.) | [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) |
| **Browser runtime** | Handles the Chrome DevTools Protocol (CDP) connection, session caching, and event buffering | [`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts) |
| **Element resolver** | Resolves CSS, XPath, ARIA, and `@N` refs to backend node IDs | [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts) |
| **State singleton** | Holds mutable runtime data (`send`, `platform`, `sessionCache`, …) | [`src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/state.ts) |
| **Site learnings** | Per-site skill packs (`learnings/<site>/`) contain manifests, node-tools, and browser-tools | `skills/ego-browser/learnings/` |
| **Build & CI** | `scripts/build.mjs` bundles the SDK with esbuild + rollup | `scripts/build.mjs` |

The data flow follows this pattern:

```

heredoc JS → runMain() → helpers.ts → browser-runtime.ts ↔ ego-lite app (CDP) → optional site-learning pack

```

This architecture is documented in [`CONTRIBUTING.md`](https://github.com/citrolabs/ego-lite/blob/main/CONTRIBUTING.md) under the "Architecture Overview" section.

## Setting Up Your Development Environment

Before contributing to ego-lite, configure your local environment with the exact dependency versions and build tooling.

```bash

# Clone the repo and enter the SDK directory

git clone https://github.com/citrolabs/ego-lite.git
cd ego-lite/package/ego-browser

# Install exact dependencies (not semver ranges)

npm ci

# Build the source (produces dist/ and the bundled artifact)

npm run build

# Run the type-checker (no emit)

npm run typecheck

# Execute the full test suite

npm test

```

These commands come directly from the "Local Development Setup" section in [`CONTRIBUTING.md`](https://github.com/citrolabs/ego-lite/blob/main/CONTRIBUTING.md). All builds use `scripts/build.mjs`, which combines esbuild and rollup for the final bundle.

## Where to Contribute: Three Contribution Paths

### 1. Core SDK Development

Modify [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) to add new helpers, fix bugs in [`src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/browser-runtime.ts), or improve selector resolution in [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts). The SDK surface in [`helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/helpers.ts) constructs the public API that agents call: `click()`, `goto()`, `snapshot()`, and task-space operations.

### 2. Site Learning Packs

Create or update learning packs under `skills/ego-browser/learnings/<site>/`. Each pack requires:

- A [`manifest.json`](https://github.com/citrolabs/ego-lite/blob/main/manifest.json) following the schema
- **Node-tools** (server-side execution)
- **Browser-tools** (client-side execution)

### 3. Documentation

Update [`README.md`](https://github.com/citrolabs/ego-lite/blob/main/README.md), [`SKILL.md`](https://github.com/citrolabs/ego-lite/blob/main/SKILL.md), or regenerate API docs via `extract-help-docs.mjs`. Keep [`SKILL.md`](https://github.com/citrolabs/ego-lite/blob/main/SKILL.md) synchronized with SDK changes since agents consume this documentation.

## Writing Tests for Your Changes

Every contribution to ego-lite must include unit test coverage. The project uses Node's built-in test runner (`node --test`).

Stub the CDP layer using `setOverrides()`:

```js
// file: package/ego-browser/test/fill-form.test.mjs
import { strict as assert } from 'node:assert';
import { installEgoSdk } from '../src/index.js';
import { setOverrides } from '../src/helpers.test.mjs';

setOverrides({ /* mock CDP responses */ });

installEgoSdk(globalThis);
await fill('#email', 'alice@example.com');
assert.ok(true, 'fill helper executed without throwing');

```

Run `npm test` to validate your new test passes alongside the existing suite.

## Validating Site Learnings

After modifying any learning pack, run the dedicated validator:

```bash
npm run validate:site-skills   # alias: validate:learnings

```

This ensures [`manifest.json`](https://github.com/citrolabs/ego-lite/blob/main/manifest.json) conforms to the expected shape and all referenced tools exist on disk.

## Creating a New Site Learning Pack

Follow this pattern to add support for a new domain:

```bash

# 1. Copy an existing pack as template

cp -r skills/ego-browser/learnings/github skills/ego-browser/learnings/mynewsite
cd skills/ego-browser/learnings/mynewsite

# 2. Edit manifest.json

{
  "id": "mynewsite",
  "name": "My New Site",
  "domains": ["mynewsite.com"],
  "tools": { "login": "./tools/login.js" },
  "browserTools": { "search": "./browser-tools/search.js" }
}

```

Then validate from the SDK directory:

```bash
cd ../../../../package/ego-browser
npm run validate:site-skills

```

## Testing Changes Locally

Execute your modified SDK against a real browser instance using the CLI bundle:

```js
// Save as demo.js or pass directly via heredoc
await goto('https://example.com')
await waitForLoadState()
console.log(await pageInfo())

```

```bash
node artifacts/ego-browser/index.js <<'JS'
await goto('https://example.com')
await waitForLoadState()
console.log(await pageInfo())
JS

```

This pattern is documented in [`CONTRIBUTING.md`](https://github.com/citrolabs/ego-lite/blob/main/CONTRIBUTING.md) under "Calling the CLI directly." You need an installed ego-lite app for full integration testing.

## Submitting Your Pull Request

Follow these requirements for every contribution to ego-lite:

1. **Branch from `main`** (or `dev` if following the release flow)
2. **Use Conventional Commits**: `feat(ego-browser): add new "fillForm" helper`
3. **Include in your PR description**:
   - **What** changed
   - **Why** it changed
   - **How to verify** the change works

CI automatically runs `npm test` and `npm run validate:site-skills`. All checks must pass before maintainers can merge.

## Key Source Files for Contributors

| File | Purpose |
|------|---------|
| [`package/ego-browser/src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/index.ts) | SDK bootstrap, installs helpers on `globalThis`, wires CLI entry point |
| [`package/ego-browser/src/run.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/run.ts) | Reads stdin, builds async function, injects helpers, executes agent script |
| [`package/ego-browser/src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/helpers.ts) | Constructs public helper surface (`click`, `goto`, task-space ops) |
| [`package/ego-browser/src/browser-runtime.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/browser-runtime.ts) | CDP transport, session caching, event buffering |
| [`package/ego-browser/src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/element-resolver.ts) | Resolves CSS/XPath/ARIA selectors and `@N` refs to backend node IDs |
| [`package/ego-browser/src/state.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/state.ts) | Singleton runtime state (connection, platform info, overrides) |
| [`CONTRIBUTING.md`](https://github.com/citrolabs/ego-lite/blob/main/CONTRIBUTING.md) | Full contribution guide with four design principles |
| [`README.md`](https://github.com/citrolabs/ego-lite/blob/main/README.md) | High-level project overview and quick-start |
| [`SKILL.md`](https://github.com/citrolabs/ego-lite/blob/main/SKILL.md) | Agent-facing usage documentation |
| `scripts/build.mjs` | Build pipeline (esbuild + rollup) |

## Summary

Contributing to ego-lite requires understanding the **ego-browser SDK architecture** and following established patterns:

- Set up with `npm ci` in `package/ego-browser/` and verify with `npm test`
- Target the right layer: **core SDK**, **site learnings**, or **documentation**
- Write unit tests using `setOverrides()` to mock the CDP layer
- Validate learning packs with `npm run validate:site-skills`
- Use **Conventional Commits** and include What/Why/How in PR descriptions
- Ensure CI passes `npm test` and validation before requesting review

## Frequently Asked Questions

### What programming language is the ego-browser SDK written in?

The ego-browser SDK is written in **TypeScript**. The codebase in `package/ego-browser/src/` uses `.ts` files compiled via esbuild and rollup in `scripts/build.mjs`. All contributions should include type annotations and pass `npm run typecheck`.

### Do I need the ego-lite browser app installed to contribute?

No for unit tests, yes for integration testing. The `setOverrides()` helper in `helpers.test.mjs` lets you stub CDP responses for pure SDK development. For end-to-end verification with `node artifacts/ego-browser/index.js`, you need an installed ego-lite application to handle the Chrome DevTools Protocol connection.

### What are the four design principles for ego-lite contributions?

The four design principles are documented in [`CONTRIBUTING.md`](https://github.com/citrolabs/ego-lite/blob/main/CONTRIBUTING.md) section 1.2. Every PR must respect these architectural constraints regarding helper immutability, CDP abstraction, error handling, and backwards compatibility. Read the "Design Principles" section beforeSubmitting substantial changes.

### Can I contribute site learnings without modifying the core SDK?

Yes. Site learning packs in `skills/ego-browser/learnings/` are self-contained with their own [`manifest.json`](https://github.com/citrolabs/ego-lite/blob/main/manifest.json), tools, and browser-tools. Create a new directory, define the manifest schema, implement your tools, and run `npm run validate:site-skills` to verify. These contributions don't require changes to [`src/helpers.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) or other core files.