How to Create and Validate Site-Specific Learnings with manifest.json in ego-lite

The ego-lite repository lets you define site-specific learnings by creating a manifest.json file under skills/ego-browser/learnings/<site>/ and running npm run validate:site-skills to enforce schema compliance.

Each learning in the citrolabs/ego-lite ecosystem is a self-contained package that teaches browser-automation agents how to interact with specific websites. You manage these learnings through a structured manifest.json file that declares domains, documentation notes, and executable tools. This guide walks through the exact structure, validation rules, and commands needed to create and verify site-specific learnings.

Understanding the manifest.json Structure

Every site-specific learning lives in its own directory under skills/ego-browser/learnings/<site>/. The manifest.json file inside that directory must declare these core fields:

  • id: Must match the directory name (e.g., "x-com" for .../learnings/x-com).
  • name: Human-readable site name displayed in logs and interfaces.
  • domains: Array of host patterns the learning applies to.
  • notes: Array of Markdown file paths documenting the learning.
  • nodeTools: Server-side JavaScript utilities imported via Node that agents can invoke.
  • browserTools: Client-side JavaScript utilities executed in the browser context.

Step-by-Step Guide to Creating a Site-Specific Learning

Setting Up the Directory Structure

Create a new directory under skills/ego-browser/learnings/ using a kebab-case identifier. Inside, establish this layout:


skills/ego-browser/learnings/example/
├── manifest.json
├── notes/
│   └── overview.md
├── tools/
│   └── search-items.js
└── browser-tools/
    └── click-first.js

The id field in your manifest.json must exactly match the directory name (example in this case).

Defining Required Fields in manifest.json

At minimum, your manifest.json must include the required identity fields and domain declarations:

{
  "id": "example",
  "name": "Example.com",
  "domains": ["example.com", "*.example.com"],
  "notes": ["notes/overview.md"]
}

Domain patterns must follow strict host string rules: no protocol, no trailing dots, and only a single leading *. if using wildcards. The validation engine in src/learning/validate-learning-format.ts uses the isValidDomain function to enforce these constraints.

Adding Node Tools and Browser Tools

Tools are categorized by execution context. nodeTools run server-side and require a callable export name, while browserTools execute in the browser context.

{
  "nodeTools": {
    "search_items": {
      "description": "Search items on Example.com and return titles.",
      "path": "tools/search-items.js",
      "callable": "searchItems",
      "args": {
        "query": {
          "type": "string",
          "required": true,
          "description": "Search query."
        }
      },
      "returns": {
        "type": "array",
        "description": "Array of result titles."
      }
    }
  },
  "browserTools": {
    "click_first_result": {
      "description": "Clicks the first search result.",
      "path": "browser-tools/click-first.js",
      "args": {},
      "returns": {
        "type": "object",
        "description": "Metadata about the clicked element."
      }
    }
  }
}

Validation Requirements and Checks

The schema enforcement engine resides in src/learning/validate-learning-format.ts. When you invoke validation, the system performs these seven checks:

  1. Structural validation: Confirms manifest.json is valid JSON and contains required fields (id, name, domains).
  2. Domain validation: Verifies each domain pattern is a valid host string using the isValidDomain function.
  3. Note validation: Ensures each entry in notes points to a Markdown file inside notes/ via the isNotePath helper, and contains no temporary snapshot references (@123 or ref=123).
  4. Tool map validation: Validates that nodeTools and browserTools entries have safe names (checked by isSafeToolName), descriptions, and correct relative paths (tools/*.js or browser-tools/*.js). Node tools must declare a callable property. This logic is handled by validateToolMap and validateToolSchema.
  5. Argument and return schema validation: Each tool's args and returns objects must specify supported types (string, number, integer, boolean, array, object) with non-empty descriptions, verified by validateValueSchema.
  6. File existence verification: The requireFile function confirms every referenced tool file exists on disk.
  7. Temporary reference rejection: Any tool or note containing snapshot temporary references triggers an error, encouraging stable locators.

How to Validate Your Learning

Command Line Validation

Run the npm script defined in the project to check all site learnings:

npm run validate:site-skills

This executes src/scripts/validate-site-skills.ts, printing either "All site learnings are valid" or a detailed list of errors.

Programmatic Validation

Import the validation function directly from the learning module:

import { validateSiteSkills } from 'package/ego-browser/src/learning/index.js';

const errors = await validateSiteSkills();
if (errors.length) {
  console.error('Learning validation failed:', errors);
  process.exit(1);
}

The validateSiteSkills function is re-exported from src/learning/index.ts alongside validateLearning and validateLearnings.

Using Validated Learnings in Agents

Once validated, agents access site tools through the runSiteTool helper:

// Inside an ego-browser agent script
const results = await runSiteTool('example', 'search_items', { query: 'hello world' });
console.log('Found titles:', results);

The harness automatically loads all validated learnings at startup, making tools available under their declared IDs.

Summary

  • Site-specific learnings reside in skills/ego-browser/learnings/<site>/ with a mandatory manifest.json file.
  • The manifest must declare id, name, domains, and may include notes, nodeTools, and browserTools.
  • Validation enforces domain format rules, file existence, argument schemas, and prohibits temporary snapshot references via src/learning/validate-learning-format.ts.
  • Run npm run validate:site-skills to check all learnings, or import validateSiteSkills from src/learning/index.ts for programmatic checks.
  • Validated learnings are automatically loaded by the harness and accessible via runSiteTool(siteId, toolName, args).

Frequently Asked Questions

What happens if my domain pattern includes a protocol like https://?

The validator rejects the pattern. According to isValidDomain in src/learning/validate-learning-format.ts, domain patterns must not include protocols or trailing dots. Use bare hostnames like "example.com" or "*.example.com" instead.

Can I reference TypeScript files directly in the tools path?

No. The path property under nodeTools and browserTools must point to compiled JavaScript files using the tools/*.js or browser-tools/*.js pattern. The requireFile check verifies physical file existence, so ensure your build process outputs .js files to these locations.

Why does validation fail when I include @123 in my note paths?

Temporary snapshot references like @123 or ref=123 are explicitly rejected by the validation engine to prevent brittle locators. The check at lines 27-35 of validate-learning-format.ts treats these as errors, requiring you to use stable identifiers before the learning can pass validation.

How do I share a learning across multiple domain variations?

Include all relevant patterns in the domains array. For example, ["example.com", "*.example.com", "subdomain.example.com"] covers the root domain, all subdomains via wildcard, and specific subdomains. Each pattern undergoes independent validation by isValidDomain to ensure proper formatting.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →