How ego-lite's `help()` Function Uses Runtime JSDoc Parsing for Live API Documentation
The help() function in ego-lite is powered by JSDoc comments extracted at build time, embedded as JSON into the runtime bundle, and parsed on-demand when agents call help().
The ego-lite browser automation framework exposes a help() helper that lets agents discover available APIs without leaving the execution context. Unlike typical documentation systems that read source files at runtime, this implementation pre-compiles JSDoc metadata during the build process and injects it directly into the bundle. This design works within browser sandbox constraints while delivering accurate, up-to-date documentation derived from source code annotations.
Build-Time JSDoc Extraction with Acorn
The documentation pipeline starts in scripts/build.mjs, where the entire bundle is parsed using the Acorn JavaScript parser. The build script walks the AST to collect JSDoc comments attached to every exported helper function.
Once collected, this documentation is serialized to JSON and injected into src/help-runtime.ts by replacing the placeholder __EGO_EMBEDDED_HELP_DOCS__. This transformation happens before the TypeScript compiler processes the file, ensuring the final JavaScript bundle contains a complete, self-contained documentation payload.
The placeholder replacement is documented in the file header comment of src/help-runtime.ts, which warns that any manual edits to the placeholder will be overwritten during subsequent builds.
Embedded Documentation Storage
The constant EMBEDDED_DOCS_JSON at line 26 of src/help-runtime.ts holds the injected JSON string. This string contains an array of HelperDoc objects, each representing a single exported function with its JSDoc-derived metadata:
{
name: 'click',
signature: 'click(selector, options?)',
description: 'Click the element matching the selector',
params: [
{ name: 'selector', type: 'string', description: 'CSS selector' },
{ name: 'options', type: 'object', optional: true }
],
returns: null,
async: false
}
The build-time injection approach eliminates filesystem dependencies. Since ego-lite runs from an ego:// URL inside a browser sandbox without readable source access, pre-embedding the documentation is the only viable architecture.
Runtime JSDoc Parsing and Caching
When the runtime initializes, the embedded JSON remains unparsed until first use. The function parseEmbeddedDocs() (lines 88-96) handles the initial JSON parse and constructs a Map<string, HelperDoc> for fast lookups.
Caching occurs in two stages:
- Parsed JSON cache — The
Mapis built once and stored in module scope (lines 28-30) - Getter memoization —
getDocsMap()(lines 79-86) ensures repeated calls return the same map instance
This lazy parsing strategy keeps startup overhead minimal for agents that never invoke help().
The Public help() API Surface
The help() method exposed to agents is constructed by helperContext() in src/helpers.ts (lines 22-49). This factory builds a façade object containing all helper functions plus the special help method at line 44:
// From src/helpers.ts
help: (...names: string[]) => helpRuntime(all, ...names)
helpRuntime() (lines 30-55 in src/help-runtime.ts) implements the query logic:
| Call Pattern | Return Value |
|---|---|
help() |
Array of all HelperDoc objects |
help('click') |
Single HelperDoc for named helper |
help('click', 'type') |
Array of matching HelperDoc objects |
help('page') |
Plain-text overview string for façade objects |
help('nonexistent') |
Error string indicating unknown helper |
The façade-aware routing distinguishes between function helpers (returning structured docs) and object façades like "page" or "locator" (returning pre-written summaries from an internal FACADE_HELP mapping).
Formatting Human-Readable Output
Raw HelperDoc objects are converted to markdown-style strings by formatHelp() (lines 57-77). The formatter constructs output sections:
// Example formatted output from formatHelp(clickDoc)
console.log(formatHelp(clickDoc));
/*
Click the element matching the selector
@param selector: string — CSS selector of the element to click
@param options?: object — Click options (button, clickCount, ...)
@returns: Promise<void>
click(selector, options?)
*/
The formatter handles optional parameters with ? notation, includes type annotations from JSDoc @param tags, and preserves @returns documentation when present.
Why This Architecture Enables "Runtime" JSDoc
The term "runtime JSDoc parsing" describes this system accurately despite the build-time extraction step. From the agent's perspective, documentation queries resolve dynamically during execution. The key distinction: the runtime parses pre-generated JSON rather than source files.
This design satisfies three constraints simultaneously:
- Security — No filesystem access required inside the browser sandbox
- Freshness — Documentation always matches the compiled bundle version
- Performance — Single JSON parse with cached Map lookup for subsequent queries
Practical Usage Examples
Agents interact with help() through the context object:
// List all available helpers
const all = await help();
// → [ { name: 'click', ... }, { name: 'type', ... }, ... ]
// Get documentation for specific helpers
const [clickDoc, typeDoc] = await help('click', 'type');
// Access formatted string directly
console.log(formatHelp(await help('navigate')));
// Query a façade overview
console.log(await help('page'));
// → "The page object provides methods for navigation, evaluation, and screenshot capture..."
The async signature accommodates potential future extensions, though current implementations resolve synchronously from cached data.
Summary
scripts/build.mjsextracts JSDoc using Acorn and injects JSON intosrc/help-runtime.tsEMBEDDED_DOCS_JSONholds the serialized documentation string at line 26parseEmbeddedDocs()andgetDocsMap()implement lazy parsing with Map cachinghelpRuntime()routes queries to single docs, arrays, façade overviews, or error stringsformatHelp()converts structured docs to readable markdown-style output- The architecture enables runtime documentation discovery without filesystem access
Frequently Asked Questions
Does help() read source files from disk at runtime?
No. The runtime never accesses source files. All documentation is embedded as JSON during the build process in scripts/build.mjs. This allows help() to function inside browser sandboxes where the ego:// protocol provides no readable file access.
What happens if I call help() multiple times?
The embedded JSON is parsed only on first invocation. getDocsMap() caches the resulting Map<string, HelperDoc> in module scope, making subsequent calls O(1) lookups without re-parsing.
Can help() document custom helper functions I add?
Only if your custom helpers are exported from the main bundle and annotated with JSDoc comments that the Acorn parser in scripts/build.mjs can discover. The build-time extraction limits runtime extensibility but ensures documentation accuracy.
Why does help('page') return a string instead of a HelperDoc object?
Façade objects like "page" and "locator" are compound objects containing multiple methods rather than single functions. helpRuntime() routes these to FACADE_HELP, a hardcoded mapping of overview strings, because their JSDoc spans multiple underlying functions with no single representative signature.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →