palyra-browserd automation daemon. It provides a secure, local-only relay mechanism to capture page state, take screenshots, and execute remote actions within the context of a specific browser session.
Purpose and Scope
The extension serves as a “Relay Companion” for human-in-the-loop workflows where an AI agent needs to observe or interact with a tab that is already open in the user’s primary browser, rather than a headless instance. It is intentionally narrow in scope, focusing on safe page captures and a specific set ofRelayAction types.
Sources: apps/browser-extension/README.md#1-14, apps/browser-extension/manifest.json#1-22
Architecture and Data Flow
The extension consists of three primary components: the Background Service Worker, the Content Script, and the Popup UI. Communication with the Palyra ecosystem is strictly limited to loopback addresses to ensure data sovereignty.Component Interaction Diagram
This diagram illustrates how the extension components interact with each other and the externalpalyra-browserd daemon.
Title: Extension Component and Relay Flow
Sources: apps/browser-extension/background.js#159-173, apps/browser-extension/background.js#120-128, apps/browser-extension/manifest.json#10-14
Core Components
1. Content Script (content_script.js)
The content script is injected dynamically into the active tab to perform DOM inspection and text extraction. It is designed to be non-destructive and avoids materializing large strings like outerHTML or innerText directly to prevent memory spikes.
collectDomSnapshotCapped: Iteratively traverses the DOM tree to build a serialized HTML string. It uses astackbased approach and acreateCappedBufferto ensure the output does not exceed themaxDomByteslimit defined in the relay configuration. apps/browser-extension/content_script.js#98-151collectVisibleTextCapped: Uses aTreeWalker(NodeFilter.SHOW_TEXT) to extract human-readable text from the page, applying normalization and length capping. apps/browser-extension/content_script.js#159-182- Message Listener: Listens for the
palyra.collect_snapshotmessage type to trigger extraction. apps/browser-extension/content_script.js#184-208
2. Background Service Worker (background.js)
The background script acts as the orchestrator. It manages the extension state (stored in chrome.storage.local), handles relay requests, and captures screenshots.
captureCurrentTabContext: Coordinates the injection of the content script and retrieves the DOM/Text snapshot. apps/browser-extension/background.js#117-142captureScreenshot: Utilizeschrome.tabs.captureVisibleTabto grab a PNG data URL of the current viewport. It includes a safety check againstmaxScreenshotBytes; if the image is too large, the payload is omitted to prevent transport errors. apps/browser-extension/background.js#144-157dispatchRelayAction: Performs the authenticated HTTP POST to thepalyra-browserdrelay endpoint. It attaches thesession_id,extension_id, and therelayToken(as a Bearer token). apps/browser-extension/background.js#159-187
3. Utility Library (lib.mjs)
Shared logic for validation and normalization used by both the background and popup scripts.
validateOpenTabUrl: Ensures that anyOPEN_TABrequest targets a URL that matches the user-definedopenTabAllowlist. It specifically rejects URLs containing credentials (username/password) to prevent phishing or confusion attacks. apps/browser-extension/lib.mjs#126-192clampUtf8Bytes: A binary-search-based truncation utility that ensures strings are cut at valid UTF-8 boundaries without splitting multi-byte characters. apps/browser-extension/lib.mjs#28-50
Relay Actions and Protocol
The extension communicates withpalyra-browserd via the RelayAction interface. This allows the extension to act as a proxy for the agent.
Supported Relay Actions
| Action Kind | Description | Implementation |
|---|---|---|
OPEN_TAB | Opens a new URL in the user’s browser, subject to allowlist. | runRelayOpenTab apps/browser-extension/background.js#189-200 |
CAPTURE_SELECTION | Requests a specific element’s content via CSS selector. | runRelayCaptureSelection apps/browser-extension/background.js#202-214 |
SEND_PAGE_SNAPSHOT | Pushes the current tab’s DOM, URL, and title to the daemon. | runRelaySendPageSnapshot (inferred) apps/browser-extension/README.md#13 |
Data Model Mapping
This diagram maps the extension’s internal configuration and logic to the gRPC service definitions in the daemon. Title: Extension State to BrowserService Mapping Sources: apps/browser-extension/background.js#19-30, schemas/proto/palyra/v1/browser.proto#35, apps/browser-extension/background.js#159-165Security Model
The extension implements several layers of security to protect the user’s local environment:- Loopback Enforcement: The
relayBaseUrlis strictly validated to ensure it only targets127.0.0.1,localhost, or::1. This prevents the extension from leaking data to remote relay servers. apps/browser-extension/lib.mjs#81-83 - Relay Tokens: Communication requires a short-lived “Relay Token” minted by the Palyra Console. This token is stored in extension local storage and never persisted to disk in plain text by the daemon. apps/browser-extension/README.md#31-41
- Resource Bounding: All captures (DOM, Text, Screenshots) are subject to hard byte limits (
MAX_DOM_SNAPSHOT_BYTES_DEFAULT, etc.) to prevent OOM conditions or denial-of-service via massive page structures. apps/browser-extension/lib.mjs#7-12 - Navigation Guardrails: The
open_tabaction is restricted by a configurable prefix allowlist (defaulting tohttps://and local addresses). apps/browser-extension/lib.mjs#2-6, apps/browser-extension/lib.mjs#126-192