feat: add Chrome extension browser relay

This commit is contained in:
Peter Steinberger
2026-01-15 04:50:11 +00:00
parent 5fdaef3646
commit ef78b198cb
40 changed files with 2467 additions and 49 deletions

View File

@@ -95,8 +95,10 @@ export function registerBrowserAgentSnapshotRoutes(app: express.Express, ctx: Br
try {
const tab = await profileCtx.ensureTabAvailable(targetId);
let buffer: Buffer;
if (ref || element) {
const pw = await requirePwAi(res, "element/ref screenshot");
const shouldUsePlaywright =
profileCtx.profile.driver === "extension" || !tab.wsUrl || Boolean(ref) || Boolean(element);
if (shouldUsePlaywright) {
const pw = await requirePwAi(res, "screenshot");
if (!pw) return;
const snap = await pw.takeScreenshotViaPlaywright({
cdpUrl: profileCtx.profile.cdpUrl,
@@ -268,16 +270,30 @@ export function registerBrowserAgentSnapshotRoutes(app: express.Express, ctx: Br
});
}
const snap = await snapshotAria({
wsUrl: tab.wsUrl ?? "",
limit,
});
const snap =
profileCtx.profile.driver === "extension" || !tab.wsUrl
? (() => {
// Extension relay doesn't expose per-page WS URLs; run AX snapshot via Playwright CDP session.
// Also covers cases where wsUrl is missing/unusable.
return requirePwAi(res, "aria snapshot").then(async (pw) => {
if (!pw) return null;
return await pw.snapshotAriaViaPlaywright({
cdpUrl: profileCtx.profile.cdpUrl,
targetId: tab.targetId,
limit,
});
});
})()
: snapshotAria({ wsUrl: tab.wsUrl ?? "", limit });
const resolved = await Promise.resolve(snap);
if (!resolved) return;
return res.json({
ok: true,
format,
targetId: tab.targetId,
url: tab.url,
...snap,
...resolved,
});
} catch (err) {
handleRouteError(ctx, res, err);

View File

@@ -111,6 +111,9 @@ export function registerBrowserBasicRoutes(app: express.Express, ctx: BrowserRou
const name = toStringOrEmpty((req.body as { name?: unknown })?.name);
const color = toStringOrEmpty((req.body as { color?: unknown })?.color);
const cdpUrl = toStringOrEmpty((req.body as { cdpUrl?: unknown })?.cdpUrl);
const driver = toStringOrEmpty(
(req.body as { driver?: unknown })?.driver,
) as "clawd" | "extension" | "";
if (!name) return jsonError(res, 400, "name is required");
@@ -120,6 +123,7 @@ export function registerBrowserBasicRoutes(app: express.Express, ctx: BrowserRou
name,
color: color || undefined,
cdpUrl: cdpUrl || undefined,
driver: driver === "extension" ? "extension" : undefined,
});
res.json(result);
} catch (err) {