Browser-extension runtime
createBrowserRuntime() composes the shared core for a Chrome Manifest V3 extension. The extension service worker owns the Cheetah connection and coordinates resources that a normal web page cannot: tabs, windows, content-script calls, downloads, capture, and parser execution. The content script performs page-local DOM work; it is not a second Cheetah client.
This split matters because an extension service worker is deliberately disposable. Chrome may suspend it when idle and reconstruct it later. Cheetah preserves the logical client ID in chrome.storage.local, gives each reconstructed runtime a new instance ID, and uses connection and command identities to reject evidence from an obsolete runtime.
import { createBrowserRuntime } from '@cheetah/browser';
const runtime = await createBrowserRuntime({
serverUrl: 'wss://api.example.com/cheetah/ws',
authToken: await acquireExtensionCredential(),
localPolicySource,
approvalProvider,
stateReporter,
});
const helloAck = await runtime.start();
The product still owns the extension manifest, service-worker bootstrap, content-script and offscreen-document packaging, host permissions, user-facing policy controls, and credential lifecycle. The runtime factory supplies the Cheetah composition inside that host.
What the factory composes
Unless replaced in configuration, the browser runtime creates:
- a
ChromeMV3Facadeover the Chrome tab, window, and download APIs; - a
ChromeIdentityProviderbacked bychrome.storage.local; - a service-worker-to-content-script bridge;
- worker-window and worker-tab trackers;
- a context epoch for distinguishing browser context lifetimes;
- a parser-definition cache backed by
chrome.storage.localand an offscreen parser runner; - a fetch-based resolver for offloaded payload references, enabled by default;
- browser capture support;
- the browser control, page, and worker-overlay action handlers.
Automatic payload decryption remains off unless an encryptor and explicit opt-in are supplied. The server may negotiate the payload base URL, result endpoint, heartbeat, and selected client configuration during the handshake. Applications may replace the WebSocket factory and response sink when embedding the runtime behind another local transport.
The public BrowserRuntimeConfig also exposes the shared timeouts, lease lifetime, telemetry, configuration and state providers, capture and parser overrides, local policy and approval, payload-resolution options, identity override, and handler modules. protocolVersion is an exact-version override; normally the package default is the safer choice.
Startup establishes local listeners before the network edge
Construction allocates the composition but does not start Chrome listeners or connect. On start(), the runtime starts the content-script bridge and both worker trackers before core opens the Cheetah transport. This order lets an accepted command encounter a ready local execution path. If startup fails, the browser wrapper calls its own cleanup path before returning the error.
As with core, one runtime object permits one start attempt and handler registration closes when that attempt begins. Register product handlers or provide handler modules before calling start(). A reconstructed service worker should create a fresh runtime rather than trying to restart the stopped object.
stop() stops the content-script bridge, closes the parser runner when it exposes close(), disposes the trackers, and then stops core. Products must separately remove any listeners or resources they created outside this composition.
Browser control and page actions cross different boundaries
Browser control handlers execute in the service worker through Chrome APIs. They include tab listing and focus, tab and worker-window creation, worker ownership, navigation, tab closure, downloads, and the worker overlay. Chrome permissions and local policy determine which of these can actually run.
Page actions cross the content-script bridge into one targeted tab. Every extension page action requires target.tab_id; only ordinary http: and https: pages are supported by the bridge. Restricted Chrome pages, missing host permission, absent content-script injection, a navigating tab, or a closed target can prevent delivery even though the action was advertised.
The bridge waits for a content script to become ready, polling every 100 ms. Its normal readiness budget is 5 seconds and is capped at 15 seconds. It retries only Chrome's specific pre-delivery “receiving end does not exist” failure, where delivery is known not to have occurred. It does not retry an ambiguous or possibly delivered call. Typical bridge failures distinguish readiness timeout, unsupported page, navigation, missing target, response timeout, cancellation, and delivery error.
The page-side wait_for_element action has its own 5-second default wait, while its extension bridge call allows up to 15 seconds. Those are separate deadlines: one waits for a DOM condition, the other protects the service-worker call.
Worker ownership protects unattended browser resources
A worker tab is not merely a tab carrying a label. It must belong to an explicitly worker-owned, normal, non-incognito window. The trackers reconcile ownership across service worker reconstruction, enforce configured capacities, and prevent marking a window that already contains ordinary user tabs or unmarking a window that still contains worker tabs.
set_worker_overlay adds a page overlay intended to make reserved tabs visible and block accidental interaction. During screenshot capture it can become visually transparent while continuing to block pointer events. The overlay is a user-safety aid, not an authorization boundary; policy and worker ownership checks remain authoritative.
Extension reliability has an honest boundary
Cheetah makes reconstruction, targeting, fencing, and evidence explicit, but Chrome remains an external platform. A successful transport write is not client receipt. A client ACK is not local permission or handler completion. A content-script reply proves only what that action contract reports. Navigation or worker suspension can still interrupt work, and no runtime can roll back a browser side effect that occurred before cancellation became visible.
Use durable product state and reconciliation for effects that must survive browser loss. Use worker ownership for unattended tabs, local policy for the device owner's restrictions, and action-specific results for the evidence actually observed.
See the self-contained Local Mode journey, or continue with a connected environment below.