# How the Ego-Lite Keyboard Helper Works: fillInput, typeText, pressKey, and dispatchKey Explained

> Explore the Ego-Lite keyboard helper API including fillInput, typeText, pressKey, and dispatchKey. Understand how it simplifies Chrome DevTools Protocol input events for efficient automation.

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

---

**The Ego-Lite keyboard helper is a thin CDP wrapper that converts high-level typing commands into Chrome DevTools Protocol `Input.dispatchKeyEvent` calls.**

The keyboard helper lives in the `citrolabs/ego-lite` repository and provides agents with a robust interface for simulating user input. Located at [`package/ego-browser/src/driver/keyboard.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/keyboard.ts), it abstracts the complexity of Chrome DevTools Protocol (CDP) into four intuitive methods that handle everything from filling form fields to dispatching raw key events.

## Architecture Overview

The helper operates as a **driver-layer abstraction** over the CDP **Input** domain. Rather than requiring agents to manually construct CDP payloads, the helper exposes `fillInput`, `typeText`, `pressKey`, and `dispatchKey` methods that internally translate requests into `Input.dispatchKeyEvent` commands sent via the runtime's `ego.sendCDPMessage` transport.

All keyboard operations follow a three-phase pipeline:

1. **Element Resolution** – The [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts) module converts user-friendly locators (CSS selectors, XPath, or role-based queries) into concrete CDP object IDs.
2. **Focus Management** – The target element receives a focus command to ensure subsequent key events target the correct input field.
3. **Event Dispatch** – The helper generates `keyDown` and `keyUp` events (or uses `Input.insertText` shortcuts when supported) through the low-level `dispatchKeyEvent` implementation found at lines 530-532 of the keyboard driver.

## The Four Core Methods

### fillInput

The `fillInput` method combines element resolution, clearing, and typing into a single operation. It accepts a locator string and a text value, resolves the target element, clears any existing value, and then streams the new text character by character.

Under the hood, it leverages `dispatchKeyEvent` for each character or falls back to `Input.insertText` when the browser runtime supports the optimization.

```javascript
// Fill a search box using a CSS selector
await fillInput('css:#search-field', 'Ego Lite automation');

```

### typeText

The `typeText` method provides a lighter alternative when you already have focus on the correct element. It skips the clearing phase and immediately begins dispatching keystrokes.

This helper is ideal for appending content to existing inputs or typing into elements already focused by previous actions. Like `fillInput`, it calls `dispatchKeyEvent` for every character in the provided string.

```javascript
// Type into the currently focused element
await typeText('Hello, World!');

```

### pressKey

The `pressKey` method simulates a single physical key press by dispatching paired `keyDown` and `keyUp` events for a specific virtual-key code. Use this for non-printable keys like **Enter**, **Tab**, **ArrowLeft**, or **Escape** that don't produce text characters but trigger application behavior.

```javascript
// Submit a form by pressing Enter
await pressKey('Enter');

// Navigate with arrow keys
await pressKey('ArrowDown');

```

### dispatchKey

The `dispatchKey` method exposes the raw CDP interface for advanced use cases. It accepts a complete CDP payload object and forwards it directly to `Input.dispatchKeyEvent`, bypassing the high-level abstractions.

This is the foundation upon which all other helpers are built, located at lines 530-532 of [`keyboard.ts`](https://github.com/citrolabs/ego-lite/blob/main/keyboard.ts).

```javascript
// Send a raw CDP key event with specific modifiers
await dispatchKey({
  type: 'keyDown',
  windowsVirtualKeyCode: 0x41, // 'A' key
  code: 'KeyA',
  key: 'a',
  modifiers: 2 // Shift key
});

```

## Error Handling and Retry Logic

When CDP calls fail due to session interruption or network latency, the keyboard helper detects timeout errors by matching the message pattern **"CDP request timed out: Input.dispatchKeyEvent"** (line 672). The driver automatically retries the operation according to the library's retry policy before surfacing the error to the calling agent.

This ensures that transient browser disconnections don't fail entire automation sequences, providing resilience for long-running tasks.

## Practical Implementation Examples

Here is a complete workflow demonstrating the keyboard helper methods in context:

```javascript
// Navigate and fill a login form
await fillInput('css:#username', 'admin');
await fillInput('css:#password', 'secret123');

// Submit with Enter key
await pressKey('Enter');

// Wait for navigation, then type a search query
await typeText('keyboard automation');
await pressKey('Enter');

// Send a custom keyboard shortcut (Ctrl+A)
await dispatchKey({
  type: 'keyDown',
  code: 'ControlLeft',
  key: 'Control',
  windowsVirtualKeyCode: 17
});
await dispatchKey({
  type: 'keyDown',
  code: 'KeyA',
  key: 'a',
  windowsVirtualKeyCode: 65
});
await dispatchKey({ type: 'keyUp', code: 'KeyA', key: 'a', windowsVirtualKeyCode: 65 });
await dispatchKey({ type: 'keyUp', code: 'ControlLeft', key: 'Control', windowsVirtualKeyCode: 17 });

```

## Key Implementation Files

Understanding the keyboard helper requires familiarity with these specific files in the repository:

- **[`package/ego-browser/src/driver/keyboard.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/keyboard.ts)** – Contains the implementations of `fillInput`, `typeText`, `pressKey`, and the low-level `dispatchKeyEvent` dispatcher.
- **[`package/ego-browser/src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/element-resolver.ts)** – Handles the translation of user-friendly locators into CDP element references required by the keyboard methods.
- **[`skills/ego-browser/SKILL.md`](https://github.com/citrolabs/ego-lite/blob/main/skills/ego-browser/SKILL.md)** – Documents the public API surface for agent developers, listing available keyboard helpers and their signatures.
- **`package/ego-browser/src/driver/keyboard.test.mjs`** – Validates that CDP calls are correctly formatted and that retry logic handles timeout scenarios properly.

## Summary

- The **keyboard helper** acts as a high-level interface to Chrome DevTools Protocol input commands, residing in [`package/ego-browser/src/driver/keyboard.ts`](https://github.com/citrolabs/ego-lite/blob/main/package/ego-browser/src/driver/keyboard.ts).
- **`fillInput`** resolves elements by selector, clears existing values, and types new text using `dispatchKeyEvent`.
- **`typeText`** streams characters to the currently focused element without clearing existing content.
- **`pressKey`** sends discrete down/up events for single virtual keys like Enter or Arrow keys.
- **`dispatchKey`** provides raw access to CDP payloads, serving as the foundation for all other methods at lines 530-532.
- The system implements automatic retry logic when detecting "CDP request timed out: Input.dispatchKeyEvent" errors (line 672).
- Element resolution and focus management are decoupled into [`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts), ensuring consistent behavior across all input methods.

## Frequently Asked Questions

### What is the difference between fillInput and typeText?

**`fillInput`** combines three operations: it resolves an element using a selector, clears any existing value in that element, and then types the provided text. **`typeText`** only performs the typing action on the currently focused element without clearing content or resolving selectors. Use `fillInput` when targeting specific form fields by ID or CSS selector, and use `typeText` when the cursor is already positioned in the correct input field.

### How does the keyboard helper handle CDP timeouts?

The helper monitors CDP responses for the specific error message "CDP request timed out: Input.dispatchKeyEvent" (as implemented at line 672 of [`keyboard.ts`](https://github.com/citrolabs/ego-lite/blob/main/keyboard.ts)). When detected, the driver automatically retries the request according to the library's retry policy before re-attaching the session if necessary. This ensures that transient network issues or brief browser disconnections don't terminate automation workflows.

### Can I use dispatchKey to simulate complex keyboard shortcuts?

Yes. While `pressKey` handles single keys, **`dispatchKey`** accepts complete CDP payload objects allowing you to construct complex chord sequences. You must manually dispatch individual `keyDown` and `keyUp` events for each key in the combination (such as Control, Alt, or Shift) in the correct order, providing full control over modifier states and timing that higher-level helpers abstract away.

### Where does the keyboard helper resolve element selectors?

Element resolution occurs in **[`src/element-resolver.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/element-resolver.ts)**, which converts user-friendly locators like `css:#input` or XPath expressions into CDP object IDs that the browser runtime understands. This resolver is shared across the keyboard helper methods, ensuring that `fillInput` and other locator-dependent functions consistently interpret selectors before focusing elements and dispatching key events.