From 028eed5fe8acbe9c8d4ad86a2d8cd5ba5b24e879 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 16 Jan 2026 06:57:20 +0000 Subject: [PATCH] fix(browser): surface detection details and docs --- docs/tools/browser-linux-troubleshooting.md | 15 +++++++++++ docs/tools/browser.md | 30 ++++++++++++++++++--- src/browser/client.ts | 3 +++ src/browser/routes/agent.shared.ts | 6 ++++- src/browser/routes/basic.ts | 17 ++++++++++++ src/cli/browser-cli-manage.ts | 3 +++ 6 files changed, 70 insertions(+), 4 deletions(-) diff --git a/docs/tools/browser-linux-troubleshooting.md b/docs/tools/browser-linux-troubleshooting.md index 1cf4844fe..07dd12e53 100644 --- a/docs/tools/browser-linux-troubleshooting.md +++ b/docs/tools/browser-linux-troubleshooting.md @@ -112,3 +112,18 @@ curl -s http://127.0.0.1:18791/tabs | `browser.noSandbox` | Add `--no-sandbox` flag (needed for some Linux setups) | `false` | | `browser.attachOnly` | Don't launch browser, only attach to existing | `false` | | `browser.cdpPort` | Chrome DevTools Protocol port | `18800` | + +### Problem: "Chrome extension relay is running, but no tab is connected" + +You’re using the `chrome` profile (extension relay). It expects the Clawdbot +browser extension to be attached to a live tab. + +Fix options: +1. **Use the managed browser:** `clawdbot browser start --browser-profile clawd` + (or set `browser.defaultProfile: "clawd"`). +2. **Use the extension relay:** install the extension, open a tab, and click the + Clawdbot extension icon to attach it. + +Notes: +- The `chrome` profile uses your **system default Chromium browser** when possible. +- Local `clawd` profiles auto-assign `cdpPort`/`cdpUrl`; only set those for remote CDP. diff --git a/docs/tools/browser.md b/docs/tools/browser.md index 07154a3fb..f6cf54b21 100644 --- a/docs/tools/browser.md +++ b/docs/tools/browser.md @@ -14,8 +14,10 @@ control server. Beginner view: - Think of it as a **separate, agent-only browser**. -- It does **not** touch your personal browser profile. +- The `clawd` profile does **not** touch your personal browser profile. - The agent can **open tabs, read pages, click, and type** in a safe lane. +- The default `chrome` profile uses the **system default Chromium browser** via the + extension relay; switch to `clawd` for the isolated managed browser. ## What you get @@ -39,6 +41,14 @@ clawdbot browser --browser-profile clawd snapshot If you get “Browser disabled”, enable it in config (see below) and restart the Gateway. +## Profiles: `clawd` vs `chrome` + +- `clawd`: managed, isolated browser (no extension required). +- `chrome`: extension relay to your **system browser** (requires the Clawdbot + extension to be attached to a tab). + +Set `browser.defaultProfile: "clawd"` if you want managed mode by default. + ## Configuration Browser settings live in `~/.clawdbot/clawdbot.json`. @@ -71,11 +81,21 @@ Notes: - `cdpUrl` defaults to `controlUrl + 1` when unset. - `attachOnly: true` means “never launch a local browser; only attach if it is already running.” - `color` + per-profile `color` tint the browser UI so you can see which profile is active. -- Auto-detect order: default browser if Chromium-based; otherwise Chrome → Brave → Edge → Chromium → Chrome Canary. +- Default profile is `chrome` (extension relay). Use `defaultProfile: "clawd"` for the managed browser. +- Auto-detect order: system default browser if Chromium-based; otherwise Chrome → Brave → Edge → Chromium → Chrome Canary. +- Local `clawd` profiles auto-assign `cdpPort`/`cdpUrl` — set those only for remote CDP. ## Use Brave (or another Chromium-based browser) -Set `browser.executablePath` to override auto-detection: +If your **system default** browser is Chromium-based (Chrome/Brave/Edge/etc), +Clawdbot uses it automatically. Set `browser.executablePath` to override +auto-detection: + +CLI example: + +```bash +clawdbot config set browser.executablePath "/usr/bin/google-chrome" +``` ```json5 // macOS @@ -339,6 +359,10 @@ Playwright. If Playwright isn’t installed, those endpoints return a clear 501 error. ARIA snapshots and basic screenshots still work for clawd-managed Chrome. For the Chrome extension relay driver, ARIA snapshots and screenshots require Playwright. +If you see `Playwright is not available in this gateway build`, install the full +Playwright package (not `playwright-core`) and restart the gateway, or reinstall +Clawdbot with browser support. + ## How it works (internal) High-level flow: diff --git a/src/browser/client.ts b/src/browser/client.ts index 2505f8dc9..eb98e8138 100644 --- a/src/browser/client.ts +++ b/src/browser/client.ts @@ -13,6 +13,9 @@ export type BrowserStatus = { cdpPort: number; cdpUrl?: string; chosenBrowser: string | null; + detectedBrowser?: string | null; + detectedExecutablePath?: string | null; + detectError?: string | null; userDataDir: string | null; color: string; headless: boolean; diff --git a/src/browser/routes/agent.shared.ts b/src/browser/routes/agent.shared.ts index 2b778460d..a09926d70 100644 --- a/src/browser/routes/agent.shared.ts +++ b/src/browser/routes/agent.shared.ts @@ -63,7 +63,11 @@ export async function requirePwAi( jsonError( res, 501, - `Playwright is not available in this gateway build; '${feature}' is unsupported.`, + [ + `Playwright is not available in this gateway build; '${feature}' is unsupported.`, + "Install the full Playwright package (not playwright-core) and restart the gateway, or reinstall with browser support.", + "Docs: /tools/browser#playwright-requirement", + ].join("\n"), ); return null; } diff --git a/src/browser/routes/basic.ts b/src/browser/routes/basic.ts index 2f53ac0ca..4b1fcab5c 100644 --- a/src/browser/routes/basic.ts +++ b/src/browser/routes/basic.ts @@ -1,5 +1,6 @@ import type express from "express"; +import { resolveBrowserExecutableForPlatform } from "../chrome.executables.js"; import { createBrowserProfilesService } from "../profiles-service.js"; import type { BrowserRouteContext } from "../server-context.js"; import { getProfileContext, jsonError, toStringOrEmpty } from "./utils.js"; @@ -36,6 +37,19 @@ export function registerBrowserBasicRoutes(app: express.Express, ctx: BrowserRou ]); const profileState = current.profiles.get(profileCtx.profile.name); + let detectedBrowser: string | null = null; + let detectedExecutablePath: string | null = null; + let detectError: string | null = null; + + try { + const detected = resolveBrowserExecutableForPlatform(current.resolved, process.platform); + if (detected) { + detectedBrowser = detected.kind; + detectedExecutablePath = detected.path; + } + } catch (err) { + detectError = String(err); + } res.json({ enabled: current.resolved.enabled, @@ -48,6 +62,9 @@ export function registerBrowserBasicRoutes(app: express.Express, ctx: BrowserRou cdpPort: profileCtx.profile.cdpPort, cdpUrl: profileCtx.profile.cdpUrl, chosenBrowser: profileState?.running?.exe.kind ?? null, + detectedBrowser, + detectedExecutablePath, + detectError, userDataDir: profileState?.running?.userDataDir ?? null, color: profileCtx.profile.color, headless: current.resolved.headless, diff --git a/src/cli/browser-cli-manage.ts b/src/cli/browser-cli-manage.ts index e5dfd4c56..5b17cef03 100644 --- a/src/cli/browser-cli-manage.ts +++ b/src/cli/browser-cli-manage.ts @@ -47,7 +47,10 @@ export function registerBrowserManageCommands( `cdpPort: ${status.cdpPort}`, `cdpUrl: ${status.cdpUrl ?? `http://127.0.0.1:${status.cdpPort}`}`, `browser: ${status.chosenBrowser ?? "unknown"}`, + `detectedBrowser: ${status.detectedBrowser ?? "unknown"}`, + `detectedPath: ${status.detectedExecutablePath ?? status.executablePath ?? "auto"}`, `profileColor: ${status.color}`, + ...(status.detectError ? [`detectError: ${status.detectError}`] : []), ].join("\n"), ); } catch (err) {