From 4275ed68a2d3fdcf3beafadc6b0a5ae337713ddb Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 15 Jan 2026 08:50:08 +0000 Subject: [PATCH] fix(browser): default to chrome extension takeover --- CHANGELOG.md | 1 + docs/cli/browser.md | 9 ++++----- docs/gateway/configuration.md | 2 +- docs/tools/browser.md | 10 +++++----- docs/tools/index.md | 2 +- src/browser/config.test.ts | 26 ++++++++++++++------------ src/browser/config.ts | 8 +++++++- src/browser/constants.ts | 1 + src/browser/profiles-service.ts | 3 ++- src/config/types.browser.ts | 2 +- 10 files changed, 37 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e7496c7f..a4c2929eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ - Agents: stabilize sub-agent announce status from runtime outcomes and normalize Result/Notes. (#835) — thanks @roshanasingh4. - Apps: use canonical main session keys from gateway defaults across macOS/iOS/Android to avoid creating bare `main` sessions. - Browser: ship a built-in `chrome` profile for extension relay and start the relay automatically when running locally. +- Browser: default `browser.defaultProfile` to `chrome` (existing Chrome takeover mode). - Embedded runner: suppress raw API error payloads from replies. (#924) — thanks @grp06. - Auth: normalize Claude Code CLI profile mode to oauth and auto-migrate config. (#855) — thanks @sebslight. - Daemon: clear persisted launchd disabled state before bootstrap (fixes `daemon install` after uninstall). (#849) — thanks @ndraiman. diff --git a/docs/cli/browser.md b/docs/cli/browser.md index 826362c03..8ba2bc237 100644 --- a/docs/cli/browser.md +++ b/docs/cli/browser.md @@ -23,11 +23,10 @@ Related: ## Quick start (local) ```bash -clawdbot browser status -clawdbot browser start -clawdbot browser tabs -clawdbot browser open https://example.com -clawdbot browser snapshot +clawdbot browser --browser-profile chrome tabs +clawdbot browser --browser-profile clawd start +clawdbot browser --browser-profile clawd open https://example.com +clawdbot browser --browser-profile clawd snapshot ``` ## Profiles diff --git a/docs/gateway/configuration.md b/docs/gateway/configuration.md index 32670dc36..72fad3653 100644 --- a/docs/gateway/configuration.md +++ b/docs/gateway/configuration.md @@ -2357,7 +2357,7 @@ Defaults: enabled: true, controlUrl: "http://127.0.0.1:18791", // cdpUrl: "http://127.0.0.1:18792", // legacy single-profile override - defaultProfile: "clawd", + defaultProfile: "chrome", profiles: { clawd: { cdpPort: 18800, color: "#FF4500" }, work: { cdpPort: 18801, color: "#0066CC" }, diff --git a/docs/tools/browser.md b/docs/tools/browser.md index c42a243c5..0f6bc2e5e 100644 --- a/docs/tools/browser.md +++ b/docs/tools/browser.md @@ -30,10 +30,10 @@ agent automation and verification. ## Quick start ```bash -clawdbot browser status -clawdbot browser start -clawdbot browser open https://example.com -clawdbot browser snapshot +clawdbot browser --browser-profile clawd status +clawdbot browser --browser-profile clawd start +clawdbot browser --browser-profile clawd open https://example.com +clawdbot browser --browser-profile clawd snapshot ``` If you get “Browser disabled”, enable it in config (see below) and restart the @@ -49,7 +49,7 @@ Browser settings live in `~/.clawdbot/clawdbot.json`. enabled: true, // default: true controlUrl: "http://127.0.0.1:18791", cdpUrl: "http://127.0.0.1:18792", // defaults to controlUrl + 1 - defaultProfile: "clawd", + defaultProfile: "chrome", color: "#FF4500", headless: false, noSandbox: false, diff --git a/docs/tools/index.md b/docs/tools/index.md index 3aa017389..103c9ac26 100644 --- a/docs/tools/index.md +++ b/docs/tools/index.md @@ -239,7 +239,7 @@ Notes: - Requires `browser.enabled=true` (default is `true`; set `false` to disable). - Uses `browser.controlUrl` unless `controlUrl` is passed explicitly. - All actions accept optional `profile` parameter for multi-instance support. -- When `profile` is omitted, uses `browser.defaultProfile` (defaults to "clawd"). +- When `profile` is omitted, uses `browser.defaultProfile` (defaults to "chrome"). - Profile names: lowercase alphanumeric + hyphens only (max 64 chars). - Port range: 18800-18899 (~100 profiles max). - Remote profiles are attach-only (no start/stop/reset). diff --git a/src/browser/config.test.ts b/src/browser/config.test.ts index a63b34fa2..a07e11655 100644 --- a/src/browser/config.test.ts +++ b/src/browser/config.test.ts @@ -10,14 +10,15 @@ describe("browser config", () => { expect(resolved.color).toBe("#FF4500"); expect(shouldStartLocalBrowserServer(resolved)).toBe(true); const profile = resolveProfile(resolved, resolved.defaultProfile); - expect(profile?.cdpPort).toBe(18800); - expect(profile?.cdpUrl).toBe("http://127.0.0.1:18800"); - expect(profile?.cdpIsLoopback).toBe(true); + expect(profile?.name).toBe("chrome"); + expect(profile?.driver).toBe("extension"); + expect(profile?.cdpPort).toBe(18792); + expect(profile?.cdpUrl).toBe("http://127.0.0.1:18792"); - const chrome = resolveProfile(resolved, "chrome"); - expect(chrome?.driver).toBe("extension"); - expect(chrome?.cdpPort).toBe(18792); - expect(chrome?.cdpUrl).toBe("http://127.0.0.1:18792"); + const clawd = resolveProfile(resolved, "clawd"); + expect(clawd?.driver).toBe("clawd"); + expect(clawd?.cdpPort).toBe(18800); + expect(clawd?.cdpUrl).toBe("http://127.0.0.1:18800"); }); it("derives default ports from CLAWDBOT_GATEWAY_PORT when unset", () => { @@ -26,14 +27,14 @@ describe("browser config", () => { try { const resolved = resolveBrowserConfig(undefined); expect(resolved.controlPort).toBe(19003); - const profile = resolveProfile(resolved, resolved.defaultProfile); - expect(profile?.cdpPort).toBe(19012); - expect(profile?.cdpUrl).toBe("http://127.0.0.1:19012"); - const chrome = resolveProfile(resolved, "chrome"); expect(chrome?.driver).toBe("extension"); expect(chrome?.cdpPort).toBe(19004); expect(chrome?.cdpUrl).toBe("http://127.0.0.1:19004"); + + const clawd = resolveProfile(resolved, "clawd"); + expect(clawd?.cdpPort).toBe(19012); + expect(clawd?.cdpUrl).toBe("http://127.0.0.1:19012"); } finally { if (prev === undefined) { delete process.env.CLAWDBOT_GATEWAY_PORT; @@ -80,7 +81,7 @@ describe("browser config", () => { controlUrl: "http://127.0.0.1:18791", cdpUrl: "http://example.com:9222", }); - const profile = resolveProfile(resolved, resolved.defaultProfile); + const profile = resolveProfile(resolved, "clawd"); expect(profile?.cdpPort).toBe(9222); expect(profile?.cdpUrl).toBe("http://example.com:9222"); expect(profile?.cdpIsLoopback).toBe(false); @@ -127,5 +128,6 @@ describe("browser config", () => { }, }); expect(resolveProfile(resolved, "chrome")).toBe(null); + expect(resolved.defaultProfile).toBe("clawd"); }); }); diff --git a/src/browser/config.ts b/src/browser/config.ts index fc4742e48..28d44b74f 100644 --- a/src/browser/config.ts +++ b/src/browser/config.ts @@ -7,6 +7,7 @@ import { DEFAULT_CLAWD_BROWSER_COLOR, DEFAULT_CLAWD_BROWSER_CONTROL_URL, DEFAULT_CLAWD_BROWSER_ENABLED, + DEFAULT_BROWSER_DEFAULT_PROFILE_NAME, DEFAULT_CLAWD_BROWSER_PROFILE_NAME, } from "./constants.js"; import { CDP_PORT_RANGE_START, getUsedPorts } from "./profiles.js"; @@ -182,7 +183,7 @@ export function resolveBrowserConfig(cfg: BrowserConfig | undefined): ResolvedBr const attachOnly = cfg?.attachOnly === true; const executablePath = cfg?.executablePath?.trim() || undefined; - const defaultProfile = cfg?.defaultProfile ?? DEFAULT_CLAWD_BROWSER_PROFILE_NAME; + const defaultProfileFromConfig = cfg?.defaultProfile?.trim() || undefined; // Use legacy cdpUrl port for backward compatibility when no profiles configured const legacyCdpPort = rawCdpUrl ? cdpInfo.port : undefined; const profiles = ensureDefaultChromeExtensionProfile( @@ -190,6 +191,11 @@ export function resolveBrowserConfig(cfg: BrowserConfig | undefined): ResolvedBr controlPort, ); const cdpProtocol = cdpInfo.parsed.protocol === "https:" ? "https" : "http"; + const defaultProfile = + defaultProfileFromConfig ?? + (profiles[DEFAULT_BROWSER_DEFAULT_PROFILE_NAME] + ? DEFAULT_BROWSER_DEFAULT_PROFILE_NAME + : DEFAULT_CLAWD_BROWSER_PROFILE_NAME); return { enabled, diff --git a/src/browser/constants.ts b/src/browser/constants.ts index 15b55a505..3e8cb60d2 100644 --- a/src/browser/constants.ts +++ b/src/browser/constants.ts @@ -2,6 +2,7 @@ export const DEFAULT_CLAWD_BROWSER_ENABLED = true; export const DEFAULT_CLAWD_BROWSER_CONTROL_URL = "http://127.0.0.1:18791"; export const DEFAULT_CLAWD_BROWSER_COLOR = "#FF4500"; export const DEFAULT_CLAWD_BROWSER_PROFILE_NAME = "clawd"; +export const DEFAULT_BROWSER_DEFAULT_PROFILE_NAME = "chrome"; export const DEFAULT_AI_SNAPSHOT_MAX_CHARS = 80_000; export const DEFAULT_AI_SNAPSHOT_EFFICIENT_MAX_CHARS = 10_000; export const DEFAULT_AI_SNAPSHOT_EFFICIENT_DEPTH = 6; diff --git a/src/browser/profiles-service.ts b/src/browser/profiles-service.ts index 75118ca17..92db90861 100644 --- a/src/browser/profiles-service.ts +++ b/src/browser/profiles-service.ts @@ -4,6 +4,7 @@ import path from "node:path"; import type { BrowserProfileConfig, ClawdbotConfig } from "../config/config.js"; import { loadConfig, writeConfigFile } from "../config/config.js"; import { deriveDefaultBrowserCdpPortRange } from "../config/port-defaults.js"; +import { DEFAULT_BROWSER_DEFAULT_PROFILE_NAME } from "./constants.js"; import { resolveClawdUserDataDir } from "./chrome.js"; import { parseHttpUrl, resolveProfile } from "./config.js"; import { @@ -134,7 +135,7 @@ export function createBrowserProfilesService(ctx: BrowserRouteContext) { throw new Error(`profile "${name}" not found`); } - const defaultProfile = cfg.browser?.defaultProfile ?? "clawd"; + const defaultProfile = cfg.browser?.defaultProfile ?? DEFAULT_BROWSER_DEFAULT_PROFILE_NAME; if (name === defaultProfile) { throw new Error( `cannot delete the default profile "${name}"; change browser.defaultProfile first`, diff --git a/src/config/types.browser.ts b/src/config/types.browser.ts index e937a9f07..f287c8fdd 100644 --- a/src/config/types.browser.ts +++ b/src/config/types.browser.ts @@ -31,7 +31,7 @@ export type BrowserConfig = { noSandbox?: boolean; /** If true: never launch; only attach to an existing browser. Default: false */ attachOnly?: boolean; - /** Default profile to use when profile param is omitted. Default: "clawd" */ + /** Default profile to use when profile param is omitted. Default: "chrome" */ defaultProfile?: string; /** Named browser profiles with explicit CDP ports or URLs. */ profiles?: Record;