# Site Learnings manifest.json Format in ego-lite: Schema, Examples, and Directory Layout

> Explore the site learnings manifest.json format in ego-lite. Understand its schema, see examples, and learn about the directory layout for organized site configurations.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: api-reference
- Published: 2026-07-28

---

**TLDR:** The site learnings [`manifest.json`](https://github.com/citrolabs/ego-lite/blob/main/manifest.json) in the `citrolabs/ego-lite` repository is a typed configuration file located under `skills/ego-browser/learnings/<site-id>/` that declares a site’s domains, documentation notes, Node.js tools, and browser tools, while the directory layout uses `notes/`, `tools/`, and `browser-tools/` subfolders to organize each learning.

In the `citrolabs/ego-lite` project, a *site learning* packages site-specific automation logic into a discoverable folder structure. Each learning is defined by a [`manifest.json`](https://github.com/citrolabs/ego-lite/blob/main/manifest.json) file that follows a strict schema, enabling the ego-browser runtime to register tools automatically. Understanding the **site learnings manifest.json format and directory structure** is essential for extending the browser with new site-specific capabilities.

## Site Learning Directory Layout

All site learnings live under `skills/ego-browser/learnings/<site-id>/`. The `<site-id>` acts as the folder name and matches the `id` declared inside the learning’s [`manifest.json`](https://github.com/citrolabs/ego-lite/blob/main/manifest.json).

### Standard Folder Structure

```text
skills/
└─ ego-browser/
   └─ learnings/
      └─ <site-id>/
         ├─ manifest.json
         ├─ notes/
         │   └─ overview.md
         ├─ tools/
         │   └─ <tool>.js
         └─ browser-tools/
             └─ <tool>.js

```

The `google` learning follows this layout inside `skills/ego-browser/learnings/google/`, and the X learning follows it inside `skills/ego-browser/learnings/x-com/`. The ego-browser runtime discovers each learning by scanning these directories and parsing their [`manifest.json`](https://github.com/citrolabs/ego-lite/blob/main/manifest.json) files.

## manifest.json Schema and Format

The [`manifest.json`](https://github.com/citrolabs/ego-lite/blob/main/manifest.json) schema is flat and typed. Every property is a top-level key in the JSON object.

### Top-Level Properties

- `id` — **string**. Short identifier used to reference the learning (e.g., `"google"`).
- `name` — **string**. Human-readable name displayed in help output (e.g., `"Google Search"`).
- `domains` — **array[string]**. Hostnames (and optional wildcards) that trigger this learning.
- `notes` — **array[string]**. Relative paths to Markdown files that document the learning.
- `nodeTools` — **object**. Tools that run in the Node.js context.
- `browserTools` — **object**. Tools that run in the browser via CDP.

### Tool Entry Shape

According to the `citrolabs/ego-lite` source analysis, both `nodeTools` and `browserTools` share the same shape. Every named tool entry declares the following fields:

- `description` — **string** explaining what the tool does.
- `path` — **string** representing the source file path relative to the learning directory.
- `callable` — **string** naming the exported function to invoke inside the file given by `path`.
- `args` — **object** containing JSON-Schema-like argument definitions with `type`, `required`, and `description`.
- `returns` — **object** describing the return type and its meaning.

## Real-World manifest.json Examples

### Google Search manifest.json

The Google learning manifest at [`skills/ego-browser/learnings/google/manifest.json`](https://github.com/citrolabs/ego-lite/blob/main/skills/ego-browser/learnings/google/manifest.json) defines one `nodeTool` and one `browserTool`.

```json
{
  "id": "google",
  "name": "Google Search",
  "domains": ["google.com", "*.google.com", "www.google.com"],
  "notes": ["notes/overview.md"],
  "nodeTools": {
    "search_and_extract": {
      "description": "Perform a Google search and extract top organic results.",
      "path": "tools/search-extract.js",
      "callable": "searchAndExtract",
      "args": {
        "query": {"type":"string","required":true,"description":"Search query string."},
        "maxResults": {"type":"integer","required":false,"description":"Maximum number of results to extract."}
      },
      "returns": {"type":"array","description":"Array of {title, url, snippet} objects."}
    }
  },
  "browserTools": {
    "get_autocomplete_suggestions": {
      "description": "Get autocomplete suggestions for the current search query.",
      "path": "browser-tools/autocomplete.js",
      "args": {},
      "returns": {"type":"array","description":"Array of suggestion strings."}
    }
  }
}

```

### X (Twitter) manifest.json

The X learning manifest at [`skills/ego-browser/learnings/x-com/manifest.json`](https://github.com/citrolabs/ego-lite/blob/main/skills/ego-browser/learnings/x-com/manifest.json) illustrates multiple notes and tools.

```json
{
  "id": "x-com",
  "name": "X (Twitter)",
  "domains": ["x.com", "*.x.com", "twitter.com", "*.twitter.com"],
  "notes": ["notes/overview.md", "notes/timeline.md"],
  "nodeTools": {
    "get_timeline_posts": { … },
    "search_users": { … }
  },
  "browserTools": {
    "post_from_active_element": { … }
  }
}

```

## How Tool Declarations Map to Source Files

The ego-browser runtime uses the [`manifest.json`](https://github.com/citrolabs/ego-lite/blob/main/manifest.json) `path` and `callable` fields to locate and execute code.

For the Google learning, `nodeTools.search_and_extract` points to [`tools/search-extract.js`](https://github.com/citrolabs/ego-lite/blob/main/tools/search-extract.js) and expects the exported function `searchAndExtract`. The browser-side equivalent `browserTools.get_autocomplete_suggestions` points to [`browser-tools/autocomplete.js`](https://github.com/citrolabs/ego-lite/blob/main/browser-tools/autocomplete.js) and runs in the page context via CDP. This mapping is automatic once the manifest is parsed.

## Invoking Site Learning Tools from Scripts

Agents interact with registered tools through asynchronous JavaScript calls.

### Calling a nodeTool

The following snippet invokes the Google `search_and_extract` tool from an ego-browser Node.js script.

```javascript
const results = await search_and_extract({
  query: 'openai chatgpt',
  maxResults: 5
});
console.log(results);

```

The runtime resolves the tool name to the exported `searchAndExtract` function declared in [`manifest.json`](https://github.com/citrolabs/ego-lite/blob/main/manifest.json) and implemented in [`skills/ego-browser/learnings/google/tools/search-extract.js`](https://github.com/citrolabs/ego-lite/blob/main/skills/ego-browser/learnings/google/tools/search-extract.js).

### Calling a browserTool After Navigation

This example calls a browser-side tool after navigating to Google.

```javascript
await nav('https://www.google.com/search?q=ego+lite');
const suggestions = await get_autocomplete_suggestions();
console.log('Autocomplete suggestions:', suggestions);

```

Because `get_autocomplete_suggestions` is registered under `browserTools`, it executes inside the browser context and returns an array of strings.

### Accessing Learning Notes Programmatically

Notes listed in the `notes` array are Markdown files that agents can read for context.

```javascript
const overview = await readFile('notes/overview.md');
console.log(overview);

```

The [`notes/overview.md`](https://github.com/citrolabs/ego-lite/blob/main/notes/overview.md) path is relative to the learning folder, so the runtime loads [`skills/ego-browser/learnings/google/notes/overview.md`](https://github.com/citrolabs/ego-lite/blob/main/skills/ego-browser/learnings/google/notes/overview.md) for the Google learning.

## Summary

- Site learnings reside under `skills/ego-browser/learnings/<site-id>/` and are anchored by a [`manifest.json`](https://github.com/citrolabs/ego-lite/blob/main/manifest.json) file.
- The **site learnings manifest.json format** specifies `id`, `name`, `domains`, `notes`, `nodeTools`, and `browserTools`.
- `nodeTools` map to Node.js scripts under `tools/` and require a `callable` export name.
- `browserTools` map to browser-side scripts under `browser-tools/` and execute via CDP.
- Markdown documentation lives under `notes/` and can be read by agents for contextual guidance.

## Frequently Asked Questions

### What is the exact file path for a site learning manifest.json?

Each site learning is stored under `skills/ego-browser/learnings/<site-id>/manifest.json`. For example, the Google manifest is located at [`skills/ego-browser/learnings/google/manifest.json`](https://github.com/citrolabs/ego-lite/blob/main/skills/ego-browser/learnings/google/manifest.json), and the X manifest is at [`skills/ego-browser/learnings/x-com/manifest.json`](https://github.com/citrolabs/ego-lite/blob/main/skills/ego-browser/learnings/x-com/manifest.json).

### How do nodeTools differ from browserTools in ego-lite?

`nodeTools` run in the Node.js context and are sourced from `tools/`. `browserTools` run inside the browser page via CDP and are sourced from `browser-tools/`. According to the `citrolabs/ego-lite` source analysis, both entries share the same schema shape, including `description`, `path`, `callable`, `args`, and `returns`.

### What fields are required in every site learnings manifest.json?

Every manifest must include `id`, `name`, `domains`, `notes`, `nodeTools`, and `browserTools`. While `nodeTools` and `browserTools` can be empty objects, the keys themselves must be present at the top level for the ego-browser runtime to parse the learning correctly.

### Can I use wildcards in the domains array?

Yes. The `domains` array supports wildcard patterns such as `*.google.com` and `*.x.com`. These patterns allow a single learning to match multiple subdomains without listing every hostname explicitly.