jev-ego
September 17, 2026 · View on GitHub
TypeScript browser agent for ego lite — Jev Ultrafast's indexed action space, without Chrome, Playwright, or Browser Harness.
Give it one natural-language goal. A coding agent (or TypeSafe Jev) picks CLICK / TYPE_TEXT / SELECT on a numbered element table. The whole loop — TypeSafe, the text helper, and CDP — runs inside one ego-browser nodejs process.
Who it's for. Every local agent and harness on this machine. Default browser is ego lite through jev-ego. Not a general web-automation SDK; uploads, tabs, dialogs, canvas, shadow DOM, and iframes stay on the ego-browser skill.
The policy matches browser-use/jev-ultrafast. The browser layer is ego lite. An agent can drive the page itself (observe / act) or ask Jev for ranked directions (suggest / step).
The action space
Every observation produces a new element table:
[1] button Change ticket type · Round trip
[2] combobox Where from? · San Francisco
[3] combobox Where to? · empty
[4] textbox Departure · empty
The operations are CLICK, TYPE_TEXT, SELECT, SCROLL_UP, SCROLL_DOWN, WAIT, DONE, and BLOCKED. Only supported operations and targets are offered.
one TypeSafe request
┌───────────────────────────┐
page → element table → operation │
│ click_target │
│ type_text_target │
│ select_target, if present │
└─────────────┬─────────────┘
use the matching target
│
CLICK [7] ─────┤──→ ego lite
TYPE_TEXT [3] ─────┘
↓
small LLM → text → ego lite
Target questions are speculative. If the operation is CLICK, only click_target can execute. Two decisions, one network round trip. Model output never becomes selectors, coordinates, or executable JavaScript.
Why it moves
- One process, one connection. TypeSafe, the text helper, and CDP all run inside ego's Node runtime. There is no Python process and no Browser Harness hop.
- One browser call per snapshot. Visible controls, names, values, and text are read atomically. Post-input settling and the next snapshot share one
Runtime.evaluate. - Guard, geometry, and click in one evaluate. Freshness, visibility, and hit-testing resolve together; click, scroll, and native
<select>mutate in that same call.TYPE_TEXTthen usesInput.insertText. - No screenshots in the agent loop. Jev consumes structured state.
- Short waits, not guesses. After typing into a combobox, wait for visible suggestions, capped at 200 ms. Other interactions wait at most two animation frames or 50 ms.
Agents should prefer the stepper: serve keeps one TaskSpace and page session in a loopback daemon so observe / act / suggest / step skip ego process startup. See skills/jev-ego/SKILL.md.
Read the loop in src/agent.ts and the daemon in docs/design.md.
Commands
| Command | What it does |
|---|---|
jev-ego serve --url URL | Start the loopback daemon on one ego lite TaskSpace |
jev-ego observe | Print the indexed accessibility table |
jev-ego act OP [TARGET] [TEXT] | Agent-chosen CLICK, TYPE_TEXT, SELECT, scroll, or wait |
jev-ego suggest | One TypeSafe request: ranked directions, no click |
jev-ego step | One Jev decision and execution |
jev-ego run --goal TEXT | Bounded autopilot on the open space or a fresh URL |
jev-ego flights / smoke / probe | Google Flights demo, local hotel fixture, CDP-count probe |
jev-ego stop | Finish the TaskSpace and remove the registry file |
Requirements
- macOS with ego lite installed and
ego-browseronPATH(this repo was developed againstego-browser 0.5.0.32) - Node 20+ and pnpm
TYPESAFE_API_KEYfor decisionsTEXT_MODEL_API_KEYforTYPE_TEXT(OpenAI-compatible; OpenRouter +inception/mercury-2.5in the example config)
The default task-space profile is Profile 4 (Agent). Do not sign into personal accounts from that profile. Override with --profile or JEV_PROFILE_ID.
Try it
pnpm install
pnpm build
cp .env.example .env
# Add TYPESAFE_API_KEY and TEXT_MODEL_API_KEY.
Agent stepper (one space, many steps):
pnpm exec jev-ego serve --url https://en.wikipedia.org/wiki/Main_Page \
--goal 'Find and open the Wikipedia article about Gödel’s incompleteness theorems.'
pnpm exec jev-ego observe
pnpm exec jev-ego suggest
pnpm exec jev-ego act CLICK 4
pnpm exec jev-ego step
pnpm exec jev-ego stop
One-shot autopilot:
pnpm exec jev-ego run \
--url https://en.wikipedia.org/wiki/Main_Page \
--goal 'Find and open the Wikipedia article about Gödel’s incompleteness theorems.'
Google Flights example (search only; it never selects or books). Independent checks confirm route, date, and visible options:
pnpm exec jev-ego flights
Local hotel fixture (starts a loopback server, then drives ego lite):
pnpm exec jev-ego smoke
Useful flags: --keep-open, --trace DIR, --output DIR, --profile ID.
jev-ego probe [--url URL] opens a page, takes one snapshot, and prints protocol-call counts. It does not call TypeSafe.
The same policy as a library, from an ego-browser nodejs script:
import { Agent } from "./src/agent.ts";
import { EgoBrowser } from "./src/browser.ts";
const browser = await EgoBrowser.open(url, "Profile 4");
const page = await browser.observe();
const agent = new Agent({ browser, page, goal });
for await (const state of agent.run()) {
console.log(state.elapsed_ms, state.status);
}
await agent.close();
Development
pnpm lint
pnpm test
pnpm build
Tests are offline. Live flights and smoke commands make paid API calls and drive ego lite. Credentials stay in .env.
Evidence and limits
On ego lite 0.5.0.32, a first snapshot after navigation is 3 CDP calls (viewport, focus emulation, one Runtime.evaluate): 2 actions on example.com, 15 on the local hotel fixture.
The stepper daemon keeps that page: observe was 0.11 s after the serve client exited; act TYPE_TEXT / SELECT / CLICK on the hotel fixture were 0.17–0.27 s. jev-ego flights (space 25) finished in 31.6 s wall / 29.1 s decision clock — 11 actions, 15 TypeSafe decisions, 2 text-helper calls, 60 CDP — and passed the independent route/date/results checks. Numbers and the fixture directions table live in docs/performance.md. Do not treat the upstream 7.1 s Chrome number as a jev-ego result.
A DONE choice still requires independent outcome verification. The DOM reader handles common HTML and ARIA controls, not the full accessible-name specification. Shadow roots, frames, canvas, uploads, pop-up tabs, nested scrolling, and arbitrary keyboard widgets remain outside this MVP.
Related
- browser-use/jev-ultrafast — same policy, Chrome via Browser Harness
- TypeSafe Jev — operation + target in one request
- ego lite — the Chromium the agent actually drives
License
MIT. Policy, snapshot, and question text are derived from jev-ultrafast (MIT, Browser Use).