fix(browser): default to chrome extension takeover
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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" },
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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`,
|
||||
|
||||
@@ -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<string, BrowserProfileConfig>;
|
||||
|
||||
Reference in New Issue
Block a user