Implementation:Openclaw Openclaw Chrome Extension Background
| Knowledge Sources | |
|---|---|
| Domains | Browser_Automation, Chrome_Extension, WebSocket_Relay |
| Last Updated | 2026-02-06 12:00 GMT |
Overview
Service worker for the OpenClaw Chrome Extension that relays Chrome DevTools Protocol (CDP) messages between the local Gateway relay server and browser tabs via WebSocket.
Description
The background.js service worker is the core runtime component of the OpenClaw Chrome Extension. It establishes a WebSocket connection to the local Gateway relay server (default port 18792) and bridges Chrome's Debugger API to the relay. This enables the Gateway's browser automation tool to control browser tabs remotely through the Chrome DevTools Protocol without requiring a standalone Chromium instance.
The module manages tab attachment state, session routing, child target tracking, and connection lifecycle including reconnection and error handling. Badge icons provide visual feedback on connection status (ON, OFF, connecting, error).
Usage
This service worker runs automatically when the Chrome Extension is loaded. Users click the extension toolbar button to attach/detach the active tab to the CDP relay. The Gateway then sends CDP commands (navigation, DOM queries, script evaluation) through the relay WebSocket, and this background script forwards them to the appropriate browser tab via the Chrome Debugger API.
Code Reference
Source Location
- Repository: Openclaw_Openclaw
- File: assets/chrome-extension/background.js
- Lines: 1-438
Signature
// Key exported/global functions:
async function ensureRelayConnection()
// Establishes WebSocket to ws://127.0.0.1:{port}/extension with preflight HTTP check.
// Installs debugger listeners on first connection.
async function attachTab(tabId, opts = {})
// Attaches Chrome Debugger API (protocol 1.3) to a tab, registers session, and
// sends Target.attachedToTarget event to relay.
// Returns: { sessionId: string, targetId: string }
async function detachTab(tabId, reason)
// Detaches debugger from tab, sends Target.detachedFromTarget to relay,
// cleans up session maps.
async function connectOrToggleForActiveTab()
// Main action handler: toggles attach/detach on the active tab.
async function handleForwardCdpCommand(msg)
// Dispatches a CDP command from the relay to the correct tab's debugger session.
// Special handling for Runtime.enable, Target.createTarget, Target.closeTarget,
// Target.activateTarget.
function onDebuggerEvent(source, method, params)
// Forwards CDP events from Chrome Debugger to the relay WebSocket.
function sendToRelay(payload)
// Sends JSON payload to the relay WebSocket.
async function onRelayMessage(text)
// Parses incoming relay messages: handles ping/pong, request/response matching,
// and forwardCDPCommand dispatch.
Import
// This is a Chrome Extension service worker — loaded via manifest.json:
// "background": { "service_worker": "background.js" }
// No explicit import; runs as the extension's background script.
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| relayPort | number (chrome.storage.local) | No | Port for the local relay server (default 18792) |
| toolbar click | chrome.action.onClicked | Yes | User clicks extension icon to attach/detach tab |
| relay WebSocket messages | JSON over WebSocket | Yes | CDP commands from the Gateway relay server |
| Chrome Debugger events | chrome.debugger.onEvent | Yes | CDP events emitted by attached browser tabs |
Outputs
| Name | Type | Description |
|---|---|---|
| forwardCDPEvent | JSON over WebSocket | CDP events forwarded to relay (Target.attachedToTarget, DOM events, etc.) |
| forwardCDPCommand results | JSON over WebSocket | CDP command responses returned to relay |
| Badge state | chrome.action badge | Visual ON/OFF/connecting/error indicator per tab |
| Action title | chrome.action title | Tooltip describing current connection state |
Usage Examples
Extension Activation Flow
// 1. User clicks the extension toolbar icon on a browser tab
// chrome.action.onClicked fires → connectOrToggleForActiveTab()
// 2. If not connected to relay, establishes WebSocket:
// HTTP HEAD http://127.0.0.1:18792/ (preflight check)
// WebSocket ws://127.0.0.1:18792/extension
// 3. Attaches Chrome Debugger to the tab:
// chrome.debugger.attach({ tabId }, '1.3')
// chrome.debugger.sendCommand({ tabId }, 'Target.getTargetInfo')
// 4. Sends Target.attachedToTarget event to relay with sessionId + targetInfo
// 5. Gateway can now send CDP commands like:
// { id: 1, method: 'forwardCDPCommand',
// params: { sessionId: 'cb-tab-1', method: 'Page.navigate',
// params: { url: 'https://example.com' } } }
// 6. background.js forwards via chrome.debugger.sendCommand and returns result
Custom Relay Port
// Port is configured via the options page and stored in chrome.storage.local:
await chrome.storage.local.set({ relayPort: 19000 })
// background.js reads it on each connection attempt:
// getRelayPort() → validates range 1-65535, defaults to 18792