Best Practices for Writing Stable Site Skills in ego-lite

Follow the fixed folder layout, use stable selectors and URLs, avoid pixel coordinates and secrets, and validate with npm run validate:site-skills to create resilient site learning packs that withstand browser updates and layout changes.

The ego-browser harness drives the closed-source ego lite browser, enabling AI agents to interact with web pages through reusable site skills (also called learnings). These learning packs, stored in skills/ego-browser/learnings/<site>/, serve as reusable maps that agents use to navigate and manipulate websites programmatically. Writing stable site skills requires strict adherence to structural conventions and hard constraints defined in the CONTRIBUTING.md guide to ensure reliability across browser versions and UI redesigns.

Understanding the Site Learning Pack Structure

Every site learning pack follows a rigid directory convention that the runtime discovers automatically. This uniformity enables validation, testing, and consistent agent behavior.

Fixed Folder Layout Convention

Each learning pack must live under skills/ego-browser/learnings/<site>/ and contain exactly four artifact types:

  • manifest.json – Declares domains, tools, and schemas
  • notes/*.md – Human-readable documentation
  • tools/*.js – Node-side utilities executed in the CLI process
  • browser-tools/*.js – Scripts injected into the browser context

The runtime loader (src/learning/index.ts) discovers packs by this specific shape. The validator (src/learning/validate-learning-format.ts) relies on this layout to locate and check every artifact automatically. Deviating from this structure causes the validation step to fail before the skill can load.

The Manifest as Single Source of Truth

The manifest.json file defines the contract between the agent and the site. It must declare id, name, domains, notes, nodeTools, and browserTools. Every tool requires explicit parameter schemas with type, required, and description fields.

This manifest powers the runSiteTool and runSiteBrowserTool helpers. Proper schemas enable automatic validation and generate actionable error messages when agents invoke tools incorrectly. Refer to the x-com manifest.json for a production example.

Hard Constraints for Stable Site Skills

The CONTRIBUTING.md document defines non-negotiable constraints that prevent fragility and security vulnerabilities.

Stable URLs and Selectors Only

Stable site skills rely exclusively on canonical URLs and resilient DOM selectors. Use CSS selectors targeting ARIA roles, data-testid attributes, or semantic HTML rather than generated class names or positional XPath expressions.

Selectors depending on dynamic IDs or auto-generated classes break whenever the site redeploys, causing flaky automation. Stable selectors make learning packs resilient to minor UI redesigns and enable faster re-snapshotting when layouts change.

No Pixel Coordinates or Geometry-Based Actions

Never embed absolute pixel coordinates or geometry-based click coordinates in tools. Pixel-based actions fail when DPI settings, window sizes, or responsive layouts change. The ego-lite runtime provides logical element references (loc= or @N syntax) that adapt automatically to viewport variations.

Security: No Hard-Coded Secrets

Do not hard-code API keys, cookies, session tokens, or credentials in tool scripts or markdown notes. Hard-coded secrets expose sensitive data to any agent loading the skill, violating security policies and potentially leaking private user information across sessions.

Designing for Reusability and Maintenance

Stable site skills function as reusable site maps rather than brittle, task-specific scripts.

Capture Site Shape, Not Specific Tasks

Write notes and tools that describe how the site is built—documenting DOM hierarchies, ARIA roles, and data-testid attributes—rather than encoding a single user workflow. This approach creates a composable "map" that agents can use to construct varied task flows dynamically.

The help() function exposed by agents parses JSDoc and markdown notes at runtime. Comprehensive documentation in notes/*.md files ensures that help() reflects the actual DOM structure, enabling agents to reason about page state correctly.

Naming and API Consistency

Use camelCase for public helper functions and lead with verbs for asynchronous actions (e.g., runSiteTool, ensureSession). This convention aligns with the helper surface defined in src/helpers.ts, making the API discoverable and predictable across different site learning packs.

Validation and Testing

Automated checks prevent broken skills from reaching production.

Automated Validation

Run npm run validate:site-skills after modifying any learning pack. This command invokes the validator (src/learning/validate-learning-format.ts) to check manifest syntax, required fields, and file existence. The validator guarantees that the learning pack can be loaded by the runtime before code review.

Behavior Testing with Stubs

Add at least one behavior test in test/site-skills.test.js or similar files. Use __testing.setOverrides() or a FakeEgo double to stub Chrome DevTools Protocol (CDP) calls, isolating tests from live browser dependencies.

Testing protects against regressions when the runtime evolves, particularly when snapshot formats or helper implementations change. Stubbing CDP calls ensures tests remain fast and deterministic while verifying tool logic.

Summary

  • Structure: Maintain the fixed folder layout (manifest.json, notes/, tools/, browser-tools/) so the runtime and validator can discover your pack.
  • Selectors: Use stable CSS selectors based on ARIA roles or data attributes; avoid generated classes and pixel coordinates.
  • Security: Never commit API keys, cookies, or tokens to learning pack files.
  • Documentation: Write notes that capture site architecture (DOM shape) rather than single workflows to maximize reusability.
  • Quality Gates: Run npm run validate:site-skills and add behavior tests using __testing.setOverrides() before submitting changes.

Frequently Asked Questions

What is the required folder structure for a site learning pack?

Every pack must reside under skills/ego-browser/learnings/<site>/ and contain manifest.json, notes/*.md, tools/*.js, and browser-tools/*.js. The runtime loader (src/learning/index.ts) discovers packs by this specific shape, and the validator (src/learning/validate-learning-format.ts) enforces it strictly.

Why should I avoid using generated CSS class names in selectors?

Generated class names (e.g., div.css-1a2b3c) change on every deployment or build, causing tools to fail when the site updates. Stable selectors using ARIA roles, data-testid attributes, or semantic HTML remain valid across UI redesigns, ensuring your stable site skills continue functioning.

How do I test site skills without a live browser?

Use the __testing.setOverrides() API or a FakeEgo test double to stub CDP calls in your test files. This approach isolates logic from browser state, allowing fast, deterministic validation of tool behavior without requiring a live Chrome instance.

Where should I document the DOM structure for a site?

Document site architecture in notes/*.md files within the learning pack. These markdown files serve as the knowledge base for the help() function and future contributors. Keep them synchronized with the actual DOM implementation to ensure agents receive accurate guidance when parsing page structure.

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 →