openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
1,423 lines • 50.8 kB
TypeScript
import { _ as SsrFPolicy, b as AnyAgentTool, h as OpenClawPluginService, l as OpenClawPluginApi, m as GatewayRequestHandlers, t as definePluginEntry, v as OpenClawPluginToolContext, y as OpenClawPluginToolFactory } from "../../agent-harness-runtime-pGCreG_J.js";
import { $i as BrowserConfig, ea as BrowserProfileConfig, ki as OpenClawConfig } from "../../install-security-scan.types-CwuFCGpV.js";
import "../../plugin-config-runtime-XvM_MVXG.js";
import "../../config-contracts-XvM_MVXG.js";
import "../../runtime-store-C4GPD5jg.js";
import "../../plugin-state-runtime-D242UiXR.js";
import { Type } from "typebox";
import { z } from "zod";
import { resolveExistingPathsWithinRoot } from "@openclaw/fs-safe/advanced";
import "@openclaw/fs-safe/path";
import { Server } from "node:http";
import { lookup } from "node:dns";
import { Command } from "commander";
import { WebSocket } from "ws";
import { ChildProcess } from "node:child_process";
import "@openclaw/fs-safe/durability";
import "@openclaw/fs-safe/store";
import "@openclaw/fs-safe/atomic";
import { ConnectOverCDPTransport } from "playwright-core";
import "@modelcontextprotocol/sdk/client/index.js";
import "@modelcontextprotocol/sdk/client/stdio.js";
import "@openclaw/fs-safe/json";
import { Express } from "express";
//#region src/plugin-sdk/browser-cdp.d.ts
/**
* Redacts credentials and known sensitive tokens from CDP URLs before logs or diagnostics.
*/
export declare function redactCdpUrl(cdpUrl: string | null | undefined): string | null | undefined;
//#endregion
//#region extensions/browser/src/browser/constants.d.ts
/** Default JavaScript evaluation permission for managed browser actions. */
export declare const DEFAULT_BROWSER_EVALUATE_ENABLED = true;
/** Default color for the managed OpenClaw browser profile. */
export declare const DEFAULT_OPENCLAW_BROWSER_COLOR = "#FF4500";
/** Default managed profile name shown to users. */
export declare const DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME = "openclaw";
/** Default maximum AI snapshot text size. */
export declare const DEFAULT_AI_SNAPSHOT_MAX_CHARS = 40000;
//#endregion
//#region extensions/browser/src/browser/config.d.ts
/** Browser config after defaults, derived ports, and profile defaults are applied. */
type ResolvedBrowserConfig = {
enabled: boolean;
evaluateEnabled: boolean;
controlPort: number;
cdpPortRangeStart: number;
cdpPortRangeEnd: number;
cdpProtocol: "http" | "https";
cdpHost: string;
cdpIsLoopback: boolean;
remoteCdpTimeoutMs: number;
remoteCdpHandshakeTimeoutMs: number;
localLaunchTimeoutMs: number;
localCdpReadyTimeoutMs: number;
actionTimeoutMs: number;
color: string;
executablePath?: string;
headless: boolean;
headlessSource?: "config" | "default";
noSandbox: boolean;
attachOnly: boolean;
defaultProfile: string;
profiles: Record<string, BrowserProfileConfig>;
tabCleanup: ResolvedBrowserTabCleanupConfig;
ssrfPolicy?: SsrFPolicy;
extraArgs: string[];
/** Default loopback port for extension-driver relay servers. */
extensionRelayDefaultPort: number;
/** Assigned loopback relay port per extension-driver profile (no explicit cdpPort). */
extensionRelayPorts: Record<string, number>;
/** Extension relay authentication compatibility policy. */
extensionRelay: {
allowLegacyAuth: boolean;
};
/** Per-profile process-only Basic credentials for internal browser clients. */
extensionRelayInternalTokens: Record<string, string>;
/** Host-local HMAC key last adopted by the relay lifecycle, not raw config resolution. */
extensionRelayToken?: string;
};
/** Normalized tab-cleanup settings for session-owned browser tabs. */
type ResolvedBrowserTabCleanupConfig = {
enabled: boolean;
idleMinutes: number;
maxTabsPerSession: number;
sweepMinutes: number;
};
/** Runtime browser profile settings resolved from global and profile config. */
type ResolvedBrowserProfile = {
name: string;
cdpPort: number;
cdpUrl: string;
cdpHost: string;
cdpIsLoopback: boolean;
userDataDir?: string;
mcpCommand?: string;
mcpArgs?: string[];
color: string;
driver: "openclaw" | "existing-session" | "extension";
executablePath?: string;
headless: boolean;
headlessSource?: "profile" | "config" | "default";
attachOnly: boolean;
};
/** Source that determined managed Chrome headless mode. */
type ManagedBrowserHeadlessSource = "request" | "env" | "profile" | "config" | "linux-display-fallback" | "default";
/** Resolve raw browser config into runtime browser defaults. */
export declare function resolveBrowserConfig(cfg: BrowserConfig | undefined, rootConfig?: OpenClawConfig): ResolvedBrowserConfig;
/** Resolve one configured browser profile by name. */
export declare function resolveProfile(resolved: ResolvedBrowserConfig, profileName: string): ResolvedBrowserProfile | null;
//#endregion
//#region extensions/browser/src/browser/profile-capabilities.d.ts
type BrowserProfileMode = "local-managed" | "local-existing-session" | "local-extension" | "remote-cdp";
type BrowserProfileCapabilities = {
mode: BrowserProfileMode;
isRemote: boolean;
/** Browser process reads paths from the same filesystem as OpenClaw. */
browserFilesystemLocal: boolean;
/** Profile uses the Chrome DevTools MCP server (existing-session driver). */
usesChromeMcp: boolean;
usesPersistentPlaywright: boolean;
supportsPerTabWs: boolean;
supportsJsonTabEndpoints: boolean;
supportsReset: boolean;
supportsManagedTabLimit: boolean;
supportsBatchActions: boolean;
supportsDownloads: boolean;
supportsPdf: boolean;
supportsRequests: boolean;
supportsErrors: boolean;
supportsPageText: boolean;
supportsEmulation: boolean;
requiresCompleteTargetEnumeration: boolean;
};
/** Return feature capabilities for a resolved browser profile. */
export declare function getBrowserProfileCapabilities(profile: ResolvedBrowserProfile): BrowserProfileCapabilities;
//#endregion
//#region extensions/browser/src/browser-tool.schema.d.ts
declare const BROWSER_ACT_KINDS: readonly ["batch", "click", "clickCoords", "type", "press", "hover", "scrollIntoView", "drag", "select", "fill", "resize", "wait", "evaluate", "close"];
declare const BROWSER_TOOL_ACTIONS: readonly ["doctor", "status", "start", "stop", "profiles", "importprofile", "tabs", "open", "focus", "close", "snapshot", "screenshot", "navigate", "console", "requests", "errors", "text", "emulate", "pdf", "download", "waitfordownload", "upload", "dialog", "act"];
type BrowserToolCapabilities = {
actions: readonly (typeof BROWSER_TOOL_ACTIONS)[number][];
actKinds: readonly (typeof BROWSER_ACT_KINDS)[number][];
tabBound: boolean;
};
//#endregion
//#region extensions/browser/src/browser/download-types.d.ts
/** Metadata for a browser download saved under the configured output root. */
type BrowserDownloadResult = {
url: string;
suggestedFilename: string;
path: string;
};
//#endregion
//#region extensions/browser/src/browser/screenshot-annotate.d.ts
interface AnnotationBox {
x: number;
y: number;
width: number;
height: number;
}
interface AnnotationItem {
ref: string;
number: number;
role: string;
name?: string;
box: AnnotationBox;
}
//#endregion
//#region extensions/browser/src/browser/client-actions-types.d.ts
/** Generic success result for action endpoints. */
type BrowserActionOk = {
ok: true;
};
/** Per-action result returned by a browser batch. */
type BrowserBatchActionResult = {
ok: boolean;
error?: string;
navigated?: true;
url?: string;
};
/** Summary returned when a batch cannot safely continue on its original page. */
type BrowserBatchAbort = {
reason: "navigation" | "closed";
afterAction: number;
url: string;
skipped: number;
};
/** Success result carrying the affected tab and optional URL. */
type BrowserActionTabResult = {
ok: true;
targetId: string;
url?: string;
download?: BrowserDownloadResult;
};
/** Success result carrying a filesystem output path. */
type BrowserActionPathResult = {
ok: true;
path: string;
targetId: string;
url?: string;
labels?: boolean;
labelsCount?: number;
labelsSkipped?: number;
truncated?: boolean;
/**
* Per-ref bounding boxes when labels=true. Coordinates are in the
* captured image's space (viewport / fullpage / element-relative).
* Omitted when empty.
*/
annotations?: AnnotationItem[];
};
//#endregion
//#region extensions/browser/src/browser/client-actions.types.d.ts
/**
* Browser action request types.
*
* Defines the closed action union accepted by browser-control `/act` routes and
* reused by the Browser agent tool.
*/
/** Form field descriptor used by fill actions. */
type BrowserFormField = {
ref: string;
type: string;
value?: string | number | boolean;
};
/** Normalized browser action request sent to the control server. */
type BrowserActRequest = {
kind: "click";
ref?: string;
selector?: string;
targetId?: string;
doubleClick?: boolean;
button?: string;
modifiers?: string[];
delayMs?: number;
timeoutMs?: number;
} | {
kind: "clickCoords";
x: number;
y: number;
targetId?: string;
doubleClick?: boolean;
button?: string;
delayMs?: number;
timeoutMs?: number;
} | {
kind: "type";
ref?: string;
selector?: string;
text: string;
targetId?: string;
submit?: boolean;
slowly?: boolean;
timeoutMs?: number;
} | {
kind: "press";
key: string;
targetId?: string;
delayMs?: number;
} | {
kind: "hover";
ref?: string;
selector?: string;
targetId?: string;
timeoutMs?: number;
} | {
kind: "scrollIntoView";
ref?: string;
selector?: string;
targetId?: string;
timeoutMs?: number;
} | {
kind: "drag";
startRef?: string;
startSelector?: string;
endRef?: string;
endSelector?: string;
targetId?: string;
timeoutMs?: number;
} | {
kind: "select";
ref?: string;
selector?: string;
values: string[];
targetId?: string;
timeoutMs?: number;
} | {
kind: "fill";
fields: BrowserFormField[];
targetId?: string;
timeoutMs?: number;
} | {
kind: "resize";
width: number;
height: number;
targetId?: string;
} | {
kind: "wait";
timeMs?: number;
text?: string;
textGone?: string;
selector?: string;
url?: string;
loadState?: "load" | "domcontentloaded" | "networkidle";
fn?: string;
targetId?: string;
timeoutMs?: number;
} | {
kind: "evaluate";
fn: string;
ref?: string;
targetId?: string;
timeoutMs?: number;
} | {
kind: "close";
targetId?: string;
} | {
kind: "batch";
actions: BrowserActRequest[];
targetId?: string;
stopOnError?: boolean;
};
//#endregion
//#region extensions/browser/src/browser/client-actions-core.d.ts
type BrowserActResponse = {
ok: true;
targetId: string;
url?: string;
result?: unknown;
results?: BrowserBatchActionResult[];
aborted?: BrowserBatchAbort;
blockedByDialog?: boolean;
browserState?: unknown;
/** Download info when a click/batch/evaluate action triggers a browser download. */
downloads?: BrowserDownloadResult[];
};
/** Navigate a browser tab through the control server. */
export declare function browserNavigate(baseUrl: string | undefined, opts: {
url: string;
targetId?: string;
timeoutMs?: number;
profile?: string;
signal?: AbortSignal;
}): Promise<BrowserActionTabResult>;
/** Arm a one-shot browser dialog handler. */
export declare function browserArmDialog(baseUrl: string | undefined, opts: {
accept: boolean;
promptText?: string;
dialogId?: string;
targetId?: string;
timeoutMs?: number;
profile?: string;
signal?: AbortSignal;
}): Promise<BrowserActionOk>;
/** Arm or execute a browser file chooser upload. */
export declare function browserArmFileChooser(baseUrl: string | undefined, opts: {
paths: string[];
ref?: string;
inputRef?: string;
element?: string;
targetId?: string;
timeoutMs?: number;
profile?: string;
signal?: AbortSignal;
}): Promise<BrowserActionOk>;
/** Execute one normalized browser action request. */
export declare function browserAct(baseUrl: string | undefined, req: BrowserActRequest, opts?: {
profile?: string;
timeoutMs?: number;
signal?: AbortSignal;
}): Promise<BrowserActResponse>;
/** Capture a screenshot through the browser control server. */
export declare function browserScreenshotAction(baseUrl: string | undefined, opts: {
targetId?: string;
fullPage?: boolean;
ref?: string;
element?: string;
type?: "png" | "jpeg";
labels?: boolean;
timeoutMs?: number;
profile?: string;
signal?: AbortSignal;
}): Promise<BrowserActionPathResult>;
//#endregion
//#region extensions/browser/src/browser/pw-session-contracts.d.ts
type BrowserConsoleMessage = {
type: string;
text: string;
timestamp: string;
location?: {
url?: string;
lineNumber?: number;
columnNumber?: number;
};
};
//#endregion
//#region extensions/browser/src/browser/extension-relay/owner-protocol.d.ts
declare const relayOwnerStatus: z.ZodObject<{
ready: z.ZodBoolean;
allowLegacyAuth: z.ZodBoolean;
identity: z.ZodNullable<z.ZodObject<{
browserVersion: z.ZodString;
userAgent: z.ZodString;
extensionVersion: z.ZodString;
}, z.core.$strict>>;
generation: z.ZodNumber;
}, z.core.$strict>;
type RelayOwnerStatus = z.infer<typeof relayOwnerStatus>;
//#endregion
//#region extensions/browser/src/browser/extension-relay/owner-client.d.ts
type RelayOperationReference = {
resolve: () => Promise<string | undefined>;
release: () => Promise<void>;
openTransport: () => Promise<ConnectOverCDPTransport>;
};
/** Client resources are leases on one socket and one proved listener lifetime. */
declare class RelayOwnerClient {
private readonly ws;
private readonly pending;
private readonly streams;
private profileAdmission;
private sequence;
private closed;
private retirementAcknowledged;
private closing;
private constructor();
private invalidate;
static connect(params: {
port: number;
profile: string;
token: string;
signal: AbortSignal;
}): Promise<RelayOwnerClient>;
adoptProfileLease(assertCurrent: () => void): void;
get connected(): boolean;
assertCurrent(): void;
private request;
status(timeoutMs?: number): Promise<RelayOwnerStatus>;
capture(targetId: string, assertOperationCurrent?: () => void): Promise<RelayOperationReference>;
private openStream;
openTransport(ref?: string): Promise<ConnectOverCDPTransport>;
prepareIngress(ws: WebSocket): Promise<() => void>;
close(): Promise<void>;
}
//#endregion
//#region extensions/browser/src/browser/client-actions-observe.d.ts
/** Read browser console messages for a tab. */
export declare function browserConsoleMessages(baseUrl: string | undefined, opts?: {
level?: string;
targetId?: string;
profile?: string;
signal?: AbortSignal;
}): Promise<{
ok: true;
messages: BrowserConsoleMessage[];
targetId: string;
url?: string;
}>;
/** Save the current page as PDF through browser control. */
export declare function browserPdfSave(baseUrl: string | undefined, opts?: {
targetId?: string;
profile?: string;
signal?: AbortSignal;
}): Promise<BrowserActionPathResult>;
//#endregion
//#region extensions/browser/src/browser/client.types.d.ts
type BrowserCdpLookup = typeof lookup;
/** Browser transport backing the selected profile. */
type BrowserTransport = "cdp" | "chrome-mcp" | "extension";
type BrowserHeadlessSource = "request" | "env" | "profile" | "config" | "linux-display-fallback" | "default";
type BrowserGraphicsAcceleration = "hardware" | "software" | "unknown";
type BrowserGraphicsDevice = {
vendorId: number;
deviceId: number;
vendor: string;
device: string;
driverVendor: string;
driverVersion: string;
};
type BrowserVideoDecodeCapability = {
profile: string;
minResolution: {
width: number;
height: number;
};
maxResolution: {
width: number;
height: number;
};
};
type BrowserVideoEncodeCapability = {
profile: string;
maxResolution: {
width: number;
height: number;
};
maxFramerateNumerator: number;
maxFramerateDenominator: number;
};
type BrowserGraphicsDiagnostics = {
status: "available";
observedAt: number;
acceleration: BrowserGraphicsAcceleration;
renderer: string | null;
vendor: string | null;
version: string | null;
backend: string | null;
devices: BrowserGraphicsDevice[];
featureStatus: Record<string, string>;
disabledFeatures: Array<{
feature: string;
status: string;
}>;
driverBugWorkarounds: string[];
videoDecoding: BrowserVideoDecodeCapability[];
videoEncoding: BrowserVideoEncodeCapability[];
} | {
status: "unavailable";
observedAt: number;
reason: string;
};
type BrowserTabOwnership = {
status: "durable";
nativeTargetId: string;
profileFingerprint: string;
browserInstanceFingerprint: string;
} | {
status: "non-durable";
reason: "explicit-cdp-url-required" | "target-marker-not-unique" | "target-marker-lookup-failed" | "target-lookup-failed" | "browser-identity-unavailable" | "browser-identity-lookup-failed";
};
/** Browser status response returned by the control server. */
type BrowserStatus = {
enabled: boolean;
profile?: string;
driver?: "openclaw" | "existing-session" | "extension";
transport?: BrowserTransport;
running: boolean;
cdpReady?: boolean;
cdpHttp?: boolean;
/**
* For Chrome MCP existing-session profiles, true only if a page-level tool
* round-trip (`list_pages`) completes; for managed CDP profiles, mirrors
* `cdpReady`. Distinguishes "transport handshake passed" from "page tools
* are actually usable".
*/
pageReady?: boolean;
pid: number | null;
cdpPort: number | null;
cdpUrl?: string | null;
chosenBrowser: string | null;
detectedBrowser?: string | null;
detectedExecutablePath?: string | null;
detectError?: string | null;
userDataDir: string | null;
color: string;
headless: boolean;
headlessSource?: BrowserHeadlessSource;
noSandbox?: boolean;
executablePath?: string | null;
attachOnly: boolean;
/**
* Cached process-lifetime diagnostics for a locally launched managed browser.
* Passive status calls never launch a browser to populate this field.
*/
graphics?: BrowserGraphicsDiagnostics | null;
};
/** Browser tab record exposed by tab listing and tab mutation endpoints. */
type BrowserTab = {
/** Best handle for agents to pass back as targetId: label, then tabId, then raw targetId. */
suggestedTargetId?: string;
targetId: string;
/** Stable, human-friendly tab handle for this profile runtime (for example t1). */
tabId?: string;
/** Optional user-assigned tab label. */
label?: string;
title: string;
url: string;
/** Listing-time observation; unavailable URLs stay redacted, not implicitly trusted. */
urlUnavailableReason?: "navigation_blocked" | "navigation_check_failed";
wsUrl?: string;
/** Internal CDP lookup pin paired with wsUrl; omitted from model-facing summaries. */
wsLookup?: BrowserCdpLookup;
type?: string;
};
/** Availability and page enumeration returned by the tab-list boundary. */
type BrowserTabsResult = {
running: true;
tabs: BrowserTab[];
} | {
running: false;
tabs: [];
};
/** Internal tab-open result. Browser tools must remove internal metadata before model output. */
type BrowserOpenResult = BrowserTab & {
ownership?: BrowserTabOwnership;
resolvedProfile?: string;
};
/** ARIA snapshot node exposed in structured snapshot responses. */
type SnapshotAriaNode = {
ref: string;
role: string;
name: string;
value?: string;
description?: string;
backendDOMNodeId?: number;
depth: number;
};
//#endregion
//#region extensions/browser/src/browser/doctor.d.ts
type BrowserDoctorCheckStatus = "pass" | "warn" | "fail" | "info";
/** One browser doctor check result. */
type BrowserDoctorCheck = {
id: string;
label: string;
status: BrowserDoctorCheckStatus;
summary: string;
fixHint?: string;
};
/** Browser doctor report returned by browser-control clients. */
type BrowserDoctorReport = {
ok: boolean;
profile: string;
transport: BrowserTransport;
checks: BrowserDoctorCheck[];
status: BrowserStatus;
};
//#endregion
//#region extensions/browser/src/browser/client.d.ts
type BrowserClientTimeoutOptions = {
timeoutMs?: number;
signal?: AbortSignal;
};
type BrowserClientProfileOptions = BrowserClientTimeoutOptions & {
profile?: string;
};
/** Profile status record returned by browser profile listing. */
type ProfileStatus = {
name: string;
transport?: BrowserTransport;
cdpPort: number | null;
cdpUrl: string | null;
color: string;
driver: "openclaw" | "existing-session" | "extension";
running: boolean;
tabCount: number;
isDefault: boolean;
isRemote: boolean;
missingFromConfig?: boolean;
reconcileReason?: string | null;
};
/** Result returned when a managed browser profile directory is reset. */
type BrowserResetProfileResult = {
ok: true;
moved: boolean;
from: string;
to?: string;
};
/** Snapshot response returned by browserSnapshot. */
type SnapshotResult = {
ok: true;
format: "aria";
targetId: string;
url: string;
nodes: SnapshotAriaNode[];
truncated?: boolean;
blockedByDialog?: boolean;
browserState?: unknown;
} | {
ok: true;
format: "ai";
targetId: string;
url: string;
snapshot: string;
truncated?: boolean;
newElements?: number;
refs?: Record<string, {
role: string;
name?: string;
nth?: number;
}>;
stats?: {
lines: number;
chars: number;
refs: number;
interactive: number;
};
labels?: boolean;
labelsCount?: number;
labelsSkipped?: number;
/**
* Per-ref bounding boxes when labels=true. Coordinates are in the
* captured image's space. Omitted when empty.
*/
annotations?: AnnotationItem[];
imagePath?: string;
imageType?: "png" | "jpeg";
blockedByDialog?: boolean;
browserState?: unknown;
};
/** Read browser-control status for the selected profile. */
export declare function browserStatus(baseUrl?: string, opts?: BrowserClientProfileOptions): Promise<BrowserStatus>;
/** Run browser doctor checks for the selected profile. */
export declare function browserDoctor(baseUrl?: string, opts?: {
profile?: string;
deep?: boolean;
signal?: AbortSignal;
}): Promise<BrowserDoctorReport>;
/** List configured browser profiles and their current status. */
export declare function browserProfiles(baseUrl?: string, opts?: BrowserClientTimeoutOptions): Promise<ProfileStatus[]>;
/** Start the selected browser profile. */
export declare function browserStart(baseUrl?: string, opts?: BrowserClientProfileOptions): Promise<void>;
/** Stop the selected browser profile. */
export declare function browserStop(baseUrl?: string, opts?: BrowserClientProfileOptions): Promise<void>;
/** Reset the selected managed browser profile directory. */
export declare function browserResetProfile(baseUrl?: string, opts?: {
profile?: string;
}): Promise<BrowserResetProfileResult>;
/** Result returned after creating a browser profile. */
type BrowserCreateProfileResult = {
ok: true;
profile: string;
transport?: BrowserTransport;
cdpPort: number | null;
cdpUrl: string | null;
userDataDir: string | null;
color: string;
isRemote: boolean;
};
/** Create and persist a browser profile. */
export declare function browserCreateProfile(baseUrl: string | undefined, opts: {
name: string;
color?: string;
cdpUrl?: string;
userDataDir?: string;
driver?: "openclaw" | "existing-session";
}): Promise<BrowserCreateProfileResult>;
/** Result returned after deleting a browser profile. */
type BrowserDeleteProfileResult = {
ok: true;
profile: string;
deleted: boolean;
};
/** Delete a configured browser profile. */
export declare function browserDeleteProfile(baseUrl: string | undefined, profile: string): Promise<BrowserDeleteProfileResult>;
export declare function browserTabs(baseUrl?: string, opts?: BrowserClientProfileOptions): Promise<BrowserTabsResult>;
/** Open a new tab in the selected browser profile. */
export declare function browserOpenTab(baseUrl: string | undefined, url: string, opts?: {
profile?: string;
label?: string;
timeoutMs?: number;
signal?: AbortSignal;
}): Promise<BrowserOpenResult>;
/** Focus an existing browser tab. */
export declare function browserFocusTab(baseUrl: string | undefined, targetId: string, opts?: BrowserClientProfileOptions): Promise<{
ok: true;
targetId?: string;
}>;
/** Close an existing browser tab. */
export declare function browserCloseTab(baseUrl: string | undefined, targetId: string, opts?: BrowserClientProfileOptions): Promise<{
ok: true;
targetId?: string;
}>;
/** Execute legacy index-based tab actions. */
export declare function browserTabAction(baseUrl: string | undefined, opts: {
action: "list" | "new" | "close" | "select";
index?: number;
profile?: string;
}): Promise<unknown>;
/** Capture an ARIA or AI snapshot for the selected tab. */
export declare function browserSnapshot(baseUrl: string | undefined, opts: {
format?: "aria" | "ai";
targetId?: string;
limit?: number;
maxChars?: number;
refs?: "role" | "aria";
interactive?: boolean;
compact?: boolean;
depth?: number;
selector?: string;
frame?: string;
labels?: boolean;
urls?: boolean;
mode?: "efficient";
profile?: string;
timeoutMs?: number;
signal?: AbortSignal;
}): Promise<SnapshotResult>;
//#endregion
//#region extensions/browser/src/browser/errors.d.ts
/** Stable machine-readable browser error reasons. */
declare const BROWSER_ERROR_REASONS: {
readonly noDisplayForHeadedProfile: "no_display_for_headed_profile";
readonly navigationBlocked: "navigation_blocked";
};
declare const NO_DISPLAY_HEADLESS_SOURCES: readonly ["request", "env", "profile", "config", "default"];
type BrowserNoDisplayErrorDetails = {
profile: string;
requestedHeadless: false;
headlessSource: (typeof NO_DISPLAY_HEADLESS_SOURCES)[number];
displayPresent: false;
};
type BrowserNoDisplayErrorMetadata = {
reason: typeof BROWSER_ERROR_REASONS.noDisplayForHeadedProfile;
details: BrowserNoDisplayErrorDetails;
};
type BrowserErrorMetadata = BrowserNoDisplayErrorMetadata | {
reason: typeof BROWSER_ERROR_REASONS.navigationBlocked;
};
type WithBrowserErrorMetadata<T> = T | (T & BrowserErrorMetadata);
type BrowserErrorResponse = WithBrowserErrorMetadata<{
status: number;
message: string;
}>;
//#endregion
//#region extensions/browser/src/browser/paths.d.ts
/** Default root directory for browser upload inputs. */
export declare const DEFAULT_UPLOAD_DIR: string;
//#endregion
//#region extensions/browser/src/browser/cdp.helpers.d.ts
type CloseTrackedCdpTargetResult = {
status: "cancelled" | "closed" | "missing" | "ownership-mismatch";
} | {
status: "unavailable";
reason: Extract<BrowserTabOwnership, {
status: "non-durable";
}>["reason"] | "target-close-failed";
};
//#endregion
//#region extensions/browser/src/browser/session-tab-route.d.ts
type BrowserSessionTabRoute = {
kind: "browser-control";
baseUrl?: string;
} | {
kind: "node-proxy";
nodeId: string;
closeTarget: (tab: {
targetId: string;
profile?: string;
ownership?: BrowserTabOwnership;
}) => Promise<CloseTrackedCdpTargetResult>;
};
//#endregion
//#region extensions/browser/src/browser/session-tab-store.d.ts
declare const browserSessionTabRecordSchema: z.ZodObject<{
version: z.ZodLiteral<1>;
sessionKey: z.ZodString;
nativeTargetId: z.ZodString;
profile: z.ZodString;
profileAliases: z.ZodOptional<z.ZodArray<z.ZodString>>;
profileFingerprint: z.ZodString;
browserInstanceFingerprint: z.ZodString;
interactionTargetKind: z.ZodEnum<{
native: "native";
opaque: "opaque";
}>;
trackedAt: z.ZodNumber;
lastUsedAt: z.ZodNumber;
cleanupRequestedAt: z.ZodOptional<z.ZodNumber>;
cleanupAttemptToken: z.ZodOptional<z.ZodString>;
cleanupKind: z.ZodOptional<z.ZodEnum<{
lifecycle: "lifecycle";
sweep: "sweep";
}>>;
}, z.core.$loose>;
type BrowserSessionTabRecord = z.infer<typeof browserSessionTabRecordSchema>;
//#endregion
//#region extensions/browser/src/browser/session-tab-registry.d.ts
type SessionTabParams = {
sessionKey?: string;
targetId?: string;
nativeTargetId?: string;
route?: BrowserSessionTabRoute;
profile?: string;
profileAliases?: Array<string | undefined>;
ownership?: BrowserTabOwnership;
aliases?: Array<string | undefined>;
};
type DurableTab = BrowserSessionTabRecord & {
kind: "durable";
storageKey: string;
};
type CloseTab = (tab: {
targetId: string;
nativeTargetId?: string;
baseUrl?: string;
route?: BrowserSessionTabRoute;
profile?: string;
}) => Promise<void>;
type CloseParams = {
closeTab?: CloseTab;
closeDurableTab?: (tab: DurableTab, options: {
shouldClose: () => boolean;
}) => Promise<CloseTrackedCdpTargetResult>;
getResolvedBrowserConfig?: () => ResolvedBrowserConfig | null | Promise<ResolvedBrowserConfig | null>;
onWarn?: (message: string) => void;
};
/** Starts tracking a browser tab for later session cleanup. */
export declare function trackSessionBrowserTab(params: SessionTabParams & {
now?: number;
}): void;
/** Removes a browser tab from session cleanup tracking. */
export declare function untrackSessionBrowserTab(params: SessionTabParams): void;
/** Closes and untracks tabs for the supplied session keys. */
export declare function closeTrackedBrowserTabsForSessions(params: CloseParams & {
sessionKeys: Array<string | undefined>;
now?: number;
}): Promise<number>;
//#endregion
//#region extensions/browser/src/browser-tool.screenshot.d.ts
type BrowserScreenshotOptions = {
agentId?: string;
agentDir?: string;
workspaceDir?: string;
activeModel?: {
provider?: string;
model?: string;
};
screenshotResultMode?: "image" | "path";
persistScreenshot?: (params: {
sourcePath: string;
type: "png" | "jpeg";
targetId?: string;
}) => Promise<string>;
mediaScope?: {
sessionKey?: string;
channel?: string;
chatType?: string;
};
};
//#endregion
//#region extensions/browser/src/browser-tool.d.ts
/** Create the Browser tool exposed to agents. */
export declare function createBrowserTool(opts?: BrowserScreenshotOptions & {
sandboxBridgeUrl?: string;
allowHostControl?: boolean;
agentSessionKey?: string;
runToolBinding?: unknown;
toolCapabilities?: BrowserToolCapabilities;
}): AnyAgentTool;
//#endregion
//#region extensions/browser/src/attached-browser-tool-runtime.d.ts
type AttachedBrowserToolRuntime = {
tool: AnyAgentTool;
dispose: () => Promise<void>;
};
type CreateAttachedBrowserToolRuntimeParams = {
cdpUrl: string;
ensureAttachTarget: () => Promise<void>;
agentSessionKey?: string;
agentDir?: string;
workspaceDir: string;
};
/** Create a normal Browser agent tool pinned to one raw, attach-only CDP profile. */
export declare function createAttachedBrowserToolRuntime(params: CreateAttachedBrowserToolRuntimeParams): Promise<AttachedBrowserToolRuntime>;
//#endregion
//#region extensions/browser/src/browser/chrome-mcp-contracts.d.ts
type ChromeMcpPageProbe = {
timeoutMs?: () => number;
onResult: (tabCount: number | null) => void;
};
//#endregion
//#region extensions/browser/src/browser/chrome.executables.d.ts
/** Browser executable candidate with product metadata and filesystem path. */
type BrowserExecutable = {
kind: "brave" | "canary" | "chromium" | "chrome" | "custom" | "edge";
path: string;
};
/** Resolve the Google Chrome executable for a named platform when available. */
export declare function resolveGoogleChromeExecutableForPlatform(platform: NodeJS.Platform): BrowserExecutable | null;
/** Read a browser executable version from platform metadata or a command-line probe. */
export declare function readBrowserVersion(executablePath: string): string | null;
/** Parse a major browser version from a raw version string. */
export declare function parseBrowserMajorVersion(rawVersion: string | null | undefined): number | null;
//#endregion
//#region extensions/browser/src/browser/chrome.d.ts
/** Running managed Chrome process and resolved control metadata. */
type RunningChrome = {
pid: number;
exe: BrowserExecutable;
userDataDir: string;
cdpPort: number;
startedAt: number;
proc: ChildProcess;
headless?: boolean;
headlessSource?: ManagedBrowserHeadlessSource;
graphicsDiagnostics?: BrowserGraphicsDiagnostics;
graphicsDiagnosticsPending?: Promise<BrowserGraphicsDiagnostics>;
};
//#endregion
//#region extensions/browser/src/browser/extension-relay/relay-protocol.d.ts
/**
* Wire protocol between the extension relay server and the OpenClaw Chrome
* extension. The extension owns tab eligibility/access, attaches chrome.debugger,
* and forwards CDP traffic. All CDP target semantics (Target.* synthesis for
* Playwright) live server-side in the bridge.
*/
/** Tab snapshot reported by the extension for tabs currently accessible to OpenClaw. */
type RelayTabInfo = {
tabId: number;
url: string;
title: string;
active: boolean;
};
//#endregion
//#region extensions/browser/src/browser/extension-relay/relay-bridge.d.ts
/** Minimal socket seam so tests can drive the bridge without real WebSockets. */
type BridgeSocket = {
send: (data: string) => void;
close: (code?: number, reason?: string) => void;
};
/** Browser identity reported by the paired extension. */
type ExtensionIdentity = {
userAgent: string;
browserVersion: string;
extensionVersion: string;
};
/**
* One relay bridge per extension-driver profile. Accepts at most one extension
* connection (a newer one replaces the old — MV3 workers restart freely) and
* any number of CDP clients (pw-session caches one per cdpUrl in practice).
*/
declare class ExtensionRelayBridge {
private extension;
extensionGeneration: number;
private readonly extensionCandidates;
private readonly clients;
private readonly tabs;
/** Browser-level sessions created by Playwright for page-scoped CDP access. */
private readonly browserSessions;
private readonly sessions;
private readonly pendingExtension;
private nextSeq;
private nextSessionOrdinal;
private nextExtensionCandidateOrdinal;
private latestPromotedCandidateOrdinal;
private pingTimer;
private missedPongs;
private readonly onStateChange?;
private readonly connectionEvents;
constructor(opts?: {
onStateChange?: () => void;
});
/** True once an extension socket completed its hello handshake. */
get extensionConnected(): boolean;
/** Wait for an authenticated extension hello without polling its CDP endpoint. */
waitForExtensionConnection(signal: AbortSignal, timeoutMs: number): Promise<boolean>;
/** Identity of the paired browser, when connected. */
get identity(): ExtensionIdentity | null;
/** Tabs currently reported as accessible by the extension. */
accessibleTabs(): RelayTabInfo[];
/** Capture the exact extension connection and tab instance for one browser operation. */
captureOperationTarget(targetId: string): ((() => string | undefined) & {
isCurrent: () => boolean;
}) | undefined;
/**
* DevTools-style descriptors for `/json/list`: RelayTabInfo plus the `id`
* and `type` fields CDP discovery clients expect. `id` is the live debugger
* targetId once a tab is attached; before that it is the same `tab-<tabId>`
* discovery-only placeholder; native attachment never fabricates an identity.
* No per-target webSocketDebuggerUrl: all CDP traffic multiplexes over the
* single browser endpoint (`/cdp`).
*/
devtoolsTargetDescriptors(): Array<RelayTabInfo & {
id: string;
type: string;
}>;
/** Number of connected CDP clients (diagnostics). */
get cdpClientCount(): number;
/** Wire up a newly accepted extension WebSocket. */
attachExtensionSocket(socket: BridgeSocket): {
onMessage: (raw: string) => void;
onClose: () => void;
};
private handleExtensionMessage;
private handleExtensionGone;
private startPing;
private stopPing;
private sendToExtension;
private callExtension;
private syncTabs;
private withAttachedTab;
private ensureTabAttached;
private targetInfoForTab;
private enumerateTargetInfos;
private announceAttachedTab;
/** Wire up a newly accepted CDP client WebSocket. */
attachCdpClientSocket(socket: BridgeSocket): {
onMessage: (raw: string) => void;
onClose: () => Promise<void>;
};
/**
* Release a tab only after its last pending or delivered logical claimant leaves.
*/
private detachUnusedAttachments;
private retireAttachment;
private respond;
private respondError;
private tabByTargetId;
private createTarget;
private handleCdpRequest;
private handleSessionScopedRequest;
private handleBrowserScopedRequest;
/** Close all sockets and reject pending work (relay shutdown). */
dispose(): void;
}
//#endregion
//#region extensions/browser/src/browser/extension-relay/relay-server.d.ts
type ExtensionRelayHandle = {
ownership: "owned";
port: number;
token: string;
allowLegacyAuth: boolean;
/** Process-only Basic credential for OpenClaw's own CDP client. Never persisted or printed. */
internalToken: string;
bridge: ExtensionRelayBridge;
close: () => Promise<void>;
};
//#endregion
//#region extensions/browser/src/browser/extension-relay/relay-access.d.ts
type BorrowedRelayAccess = {
ownership: "borrowed";
port: number;
token: string;
/** The requesting profile's policy; the listener's policy is never changed. */
allowLegacyAuth: boolean;
client: RelayOwnerClient;
close: () => Promise<void>;
};
type ExtensionRelayResource = ExtensionRelayHandle | BorrowedRelayAccess;
//#endregion
//#region extensions/browser/src/browser/server-context.types.d.ts
type BrowserTabTargetOptions = BrowserOperationOptions & {
/** Resolve only the raw target-id namespace for an id already selected internally. */
exactTargetId?: true;
};
/** Runtime state for a single profile's Chrome instance. */
type ProfileRuntimeState = {
profile: ResolvedBrowserProfile;
running: RunningChrome | null;
managedLaunchFailure?: {
consecutiveFailures: number;
lastFailureAt: number;
cooldownUntil?: number;
lastError: string;
};
/** Sticky tab selection when callers omit targetId (keeps snapshot+act consistent). */
lastTargetId?: string | null;
/** Stable, user-facing tab aliases scoped to this profile runtime. */
tabAliases?: {
nextTabNumber: number;
byTargetId: Record<string, {
tabId: string;
label?: string;
url?: string;
}>;
};
};
/** Runtime state for the Browser control server. */
type BrowserServerState = {
server?: Server | null;
port: number;
resolved: ResolvedBrowserConfig;
profiles: Map<string, ProfileRuntimeState>;
/** Running extension relay servers keyed by profile name (extension driver). */
extensionRelays?: Map<string, ExtensionRelayResource>;
stopTrackedTabCleanup?: () => void;
stopUnhandledRejectionHandler?: () => void;
};
type BrowserOperationOptions = {
signal?: AbortSignal;
timeoutMs?: number;
};
type EnsureTabAvailableOptions = BrowserOperationOptions & {
/** Allow a target-id-only tab when the caller can continue through Playwright. */
allowPlaywrightFallback?: boolean;
};
type BrowserProfileActions = {
ensureBrowserAvailable: (opts?: {
headless?: boolean;
signal?: AbortSignal;
}) => Promise<void>;
ensureTabAvailable: (targetId?: string, options?: EnsureTabAvailableOptions) => Promise<BrowserTab>;
isHttpReachable: (timeoutMs?: number, signal?: AbortSignal) => Promise<boolean>;
isTransportAvailable: (timeoutMs?: number, signal?: AbortSignal, pageProbe?: ChromeMcpPageProbe) => Promise<boolean>;
isReachable: (timeoutMs?: number, options?: {
ephemeral?: boolean;
signal?: AbortSignal;
}) => Promise<boolean>;
listTabs: (options?: BrowserOperationOptions) => Promise<BrowserTab[]>;
openTab: (url: string, opts?: {
label?: string;
signal?: AbortSignal;
timeoutMs?: number;
}) => Promise<BrowserOpenResult>;
labelTab: (targetId: string, label: string) => Promise<BrowserTab>;
focusTab: (targetId: string, options?: BrowserTabTargetOptions) => Promise<void>;
closeTab: (targetId: string, options?: BrowserTabTargetOptions) => Promise<string>;
stopRunningBrowser: () => Promise<{
stopped: boolean;
}>;
resetProfile: () => Promise<{
moved: boolean;
from: string;
to?: string;
}>;
};
/** Profile-aware operations exposed to Browser route handlers. */
type BrowserRouteContext = {
state: () => BrowserServerState;
forProfile: (profileName?: string) => ProfileContext;
listProfiles: () => Promise<ProfileStatus$1[]>;
mapTabError: (err: unknown) => BrowserErrorResponse | null;
} & BrowserProfileActions;
/** Operations scoped to a single resolved Browser profile. */
type ProfileContext = {
profile: ResolvedBrowserProfile;
} & BrowserProfileActions;
/** Status payload returned by Browser profile listing. */
type ProfileStatus$1 = {
name: string;
transport: BrowserTransport;
cdpPort: number | null;
cdpUrl: string | null;
color: string;
driver: ResolvedBrowserProfile["driver"];
running: boolean;
tabCount: number;
isDefault: boolean;
isRemote: boolean;
missingFromConfig?: boolean;
reconcileReason?: string | null;
};
/** Inputs for creating a Browser route context. */
type ContextOptions = {
getState: () => BrowserServerState | null;
onEnsureAttachTarget?: (profile: ResolvedBrowserProfile) => Promise<void>;
refreshConfigFromDisk?: boolean;
};
//#endregion
//#region extensions/browser/src/browser/server-context.d.ts
/** Creates the Browser route context used by control-server route handlers. */
export declare function createBrowserRouteContext(opts: ContextOptions): BrowserRouteContext;
//#endregion
//#region extensions/browser/src/browser/bridge-server.d.ts
/** Running bridge server details returned to callers that manage its lifecycle. */
type BrowserBridge = {
server: Server;
port: number;
baseUrl: string;
state: BrowserServerState;
};
type ResolvedNoVncObserver = {
noVncPort: number;
password?: string;
};
/** Start an authenticated loopback browser bridge and register browser routes. */
export declare function startBrowserBridgeServer(params: {
resolved: ResolvedBrowserConfig;
host?: string;
port?: number;
authToken?: string;
authPassword?: string;
onEnsureAttachTarget?: (profile: ProfileContext["profile"]) => Promise<void>;
resolveSandboxNoVncToken?: (token: string) => ResolvedNoVncObserver | null;
}): Promise<BrowserBridge>;
/** Stop a browser bridge server and clear its ephemeral port auth. */
export declare function stopBrowserBridgeServer(server: Server): Promise<void>;
//#endregion
//#region extensions/browser/src/node-host/invoke-browser.d.ts
/** Executes a serialized browser.proxy command and returns a serialized result payload. */
export declare function runBrowserProxyCommand(paramsJSON?: string | null, command?: string, invocationSignal?: AbortSignal): Promise<string>;
//#endregion
//#region extensions/browser/src/browser/request-policy.d.ts
type BrowserRequestProfileParams = {
query?: Record<string, unknown>;
body?: unknown;
profile?: string | null;
};
/** Normalizes route paths so mutation-policy checks compare stable slash forms. */
export declare function normalizeBrowserRequestPath(value: string): string;
/** Returns true when a control request mutates persistent browser profile state. */
export declare function isPersistentBrowserProfileMutation(method: string, path: string): boolean;
/** Resolves the requested profile from query, body, or route defaults. */
export declare function resolveRequestedBrowserProfile(params: BrowserRequestProfileParams): string | undefined;
//#endregion
//#region extensions/browser/src/browser/control-auth.d.ts
/** Auth material accepted by browser-control HTTP middleware and clients. */
type BrowserControlAuth = {
token?: string;
password?: string;
};
/** Resolve browser-control auth material from config and environment. */
export declare function resolveBrowserControlAuth(cfg?: OpenClawConfig, env?: NodeJS.ProcessEnv): BrowserControlAuth;
/** Ensure browser-control auth exists, generating and persisting it when allowed. */
export declare function ensureBrowserControlAuth(params: {
cfg: OpenClawConfig;
env?: NodeJS.ProcessEnv;
}): Promise<{
auth: BrowserControlAuth;
generatedToken?: string;
}>;
//#endregion
//#region extensions/browser/src/browser/trash.d.ts
/** Moves a path to trash only when it lives under allowed Browser roots. */
export declare function movePathToTrash(targetPath: string): Promise<string>;
//#endregion
//#region extensions/browser/src/browser-control-state.d.ts
export declare function getBrowserControlState(): BrowserServerState | null;
/** Create a route context bound to the current shared browser runtime. */
export declare function createBrowserControlContext(): BrowserRouteContext;
//#endregion
//#region extensions/browser/src/control-service.d.ts
/** Starts Browser control without binding the HTTP server when config enables it. */
export declare function startBrowserControlServiceFromConfig(): Promise<BrowserServerState | null>;
/** Stops the in-process Browser control service runtime. */
export declare function stopBrowserControlService(): Promise<void>;
//#endregion
//#region extensions/browser/src/browser/runtime-lifecycle.d.ts
type CreateBrowserRuntimeStateParams = {
resolved: BrowserServerState["resolved"];
port: number;
server?: Server | null;
onWarn: (message: string) => void;
};
/** Creates Browser server state and starts runtime-wide cleanup handlers. */
export declare function createBrowserRuntimeState(params: CreateBrowserRuntimeStateParams): Promise<BrowserServerState>;
/** Stops Browser profiles, the optional HTTP server, and loaded Playwright state. */
type StopBrowserRuntimeParams = {
current: BrowserServerState | null;
/** Public API compatibility; cleanup is intentionally pinned to `current`. */
getState: () => BrowserServerState | null;
clearState: () => void;
closeServer?: boolean;
onWarn: (message: string) => void;
};
/** Stops Browser profiles, the optional HTTP server, and loaded Playwright state. */
export declare function stopBrowserRuntime(params: StopBrowserRuntimeParams): Promise<void>;
//#endregion
//#region extensions/browser/src/browser/routes/types.d.ts
/**
* Minimal browser route HTTP types.
*
* Keeps route modules decoupled from Express-specific request/response types so
* the same handlers can run through HTTP and in-process dispatch.
*/
/** Request shape consumed by browser route handlers. */
type BrowserRequest = {
params: Record<string, string>;
query: Record<string, unknown>;
body?: unknown;
/**
* Optional abort signal for in-process dispatch. This lets callers enforce
* timeouts and (where supported) cancel long-running operations.
*/
signal?: AbortSignal;
};
/** Response shape used by browser route handlers. */
type BrowserResponse = {
status: (code: number) => BrowserResponse;
json: (body: unknown) => void;
};
/** Async route handler signature shared by HTTP and in-process dispatch. */
type BrowserRouteHandler = (req: BrowserRequest, res: BrowserResponse) => void | Promise<void>;
/** Minimal registrar interface implemented by HTTP and test dispatchers. */
type BrowserRouteRegistrar = {
get: (path: string, handler: BrowserRouteHandler) => void;
post: (path: string, handler: BrowserRouteHandler) => void;
delete: (path: string, handler: BrowserRouteHandler) => void;
};
//#endregion
//#region extensions/browser/src/browser/routes/index.d.ts
/** Register every browser control route group. */
export declare function registerBrowserRoutes(app: BrowserRouteRegistrar, ctx: BrowserRouteContext): void;
//#endregion
//#region extensions/browser/src/browser/routes/dispatcher.d.ts
type BrowserDispatchRequest = {
method: "GET" | "POST" | "DELETE";
path: string;
query?: Record<string, unknown>;
body?: unknown;
signal?: AbortSignal;
};
type BrowserDispatchResponse = {
status: number;
body: unknown;
};
/** Create an in-process dispatcher for registered browser routes. */
export declare function createBrowserRouteDispatcher(ctx: BrowserRouteContext): {
dispatch: (req: BrowserDispatchRequest) => Promise<BrowserDispatchResponse>;
};
//#endregion
//#region extensions/browser/src/browser/server-middleware.d.ts
/** Installs common Browser control-server middleware. */
export declare function installBrowserCommonMiddleware(app: Express): void;
/** Installs optional token/password auth for Browser control-server requests. */
export declare function installBrowserAuthMiddleware(app: Express, auth: {
token?: string;
password?: string;
}): void;
//#endregion
//#region extensions/browser/src/browser/form-fields.d.ts
type BrowserFormFieldValue = NonNullable<BrowserFormField["value"]>;
/** Normalize a form field value to the types accepted by fill actions. */
export declare function normalizeBrowserFormFieldValue(value: unknown): BrowserFormFieldValue | undefined;
export declare function normalizeBrowserFormField(record: Record<string, unknown>, index: number): BrowserFormField;
//#endregion
//#region extensions/browser/src/cli/browser-cli.d.ts
/** Registers the Browser CLI command and its lazy-loaded subcommand groups. */
export declare function registerBrowserCli(program: Command, argv?: string[], pluginRoot?: string): void;
//#endregion
//#region extensions/browser/src/plugin-service.d.ts
/** Creates the Browser plugin service registered by the plugin entrypoint. */
export declare function createBrowserPluginService(params: {
stopOnDemand: () => Promise<void>;
}): OpenClawPluginService;
//#endregion
//#region extensions/browser/src/gateway/browser-request.d.ts
/** Handles one browser.request gateway call and streams a success/error response. */
export declare function handleBrowserGatewayRequest({ params, respond, context }: Parameters<GatewayRequestHandlers["browser.request"]>[0]): Promise<void>;
/** Gateway request handler map contributed by the Browser plugin. */
export declare const browserHandlers: GatewayRequestHandlers;
//#endregion
export { type AttachedBrowserToolRuntime, type BrowserBridge, type BrowserCreateProfileResult, type BrowserDeleteProfileResult, type BrowserDoctorCheck, type BrowserDoctorReport, type BrowserExecutable, type BrowserFormField, type BrowserResetProfileResult, type BrowserRouteRegistrar, type BrowserServerState, type BrowserStatus, type BrowserTab, type BrowserTransport, type CreateAttachedBrowserToolRuntimeParams, type OpenClawPluginApi, type OpenClawPluginToolContext, type OpenClawPluginToolFactory, type ProfileStatus, type ResolvedBrowserConfig, type ResolvedBrowserProfile, type SnapshotResult, definePluginEntry, resolveExistingPathsWithinRoot };