refactor: rename to openclaw

This commit is contained in:
Peter Steinberger
2026-01-30 03:15:10 +01:00
parent 4583f88626
commit 9a7160786a
2357 changed files with 16688 additions and 16788 deletions

View File

@@ -1,10 +1,13 @@
import fs from "node:fs";
import path from "node:path";
import { DEFAULT_CLAWD_BROWSER_COLOR, DEFAULT_CLAWD_BROWSER_PROFILE_NAME } from "./constants.js";
import {
DEFAULT_OPENCLAW_BROWSER_COLOR,
DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME,
} from "./constants.js";
function decoratedMarkerPath(userDataDir: string) {
return path.join(userDataDir, ".clawd-profile-decorated");
return path.join(userDataDir, ".openclaw-profile-decorated");
}
function safeReadJson(filePath: string): Record<string, unknown> | null {
@@ -118,12 +121,12 @@ export function isProfileDecorated(
* Best-effort profile decoration (name + lobster-orange). Chrome preference keys
* vary by version; we keep this conservative and idempotent.
*/
export function decorateClawdProfile(
export function decorateOpenClawProfile(
userDataDir: string,
opts?: { name?: string; color?: string },
) {
const desiredName = opts?.name ?? DEFAULT_CLAWD_BROWSER_PROFILE_NAME;
const desiredColor = (opts?.color ?? DEFAULT_CLAWD_BROWSER_COLOR).toUpperCase();
const desiredName = opts?.name ?? DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME;
const desiredColor = (opts?.color ?? DEFAULT_OPENCLAW_BROWSER_COLOR).toUpperCase();
const desiredColorInt = parseHexRgbToSignedArgbInt(desiredColor);
const localStatePath = path.join(userDataDir, "Local State");

View File

@@ -6,15 +6,18 @@ import path from "node:path";
import { afterEach, describe, expect, it, vi } from "vitest";
import {
decorateClawdProfile,
decorateOpenClawProfile,
ensureProfileCleanExit,
findChromeExecutableMac,
findChromeExecutableWindows,
isChromeReachable,
resolveBrowserExecutableForPlatform,
stopClawdChrome,
stopOpenClawChrome,
} from "./chrome.js";
import { DEFAULT_CLAWD_BROWSER_COLOR, DEFAULT_CLAWD_BROWSER_PROFILE_NAME } from "./constants.js";
import {
DEFAULT_OPENCLAW_BROWSER_COLOR,
DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME,
} from "./constants.js";
async function readJson(filePath: string): Promise<Record<string, unknown>> {
const raw = await fsp.readFile(filePath, "utf-8");
@@ -28,9 +31,9 @@ describe("browser chrome profile decoration", () => {
});
it("writes expected name + signed ARGB seed to Chrome prefs", async () => {
const userDataDir = await fsp.mkdtemp(path.join(os.tmpdir(), "moltbot-chrome-test-"));
const userDataDir = await fsp.mkdtemp(path.join(os.tmpdir(), "openclaw-chrome-test-"));
try {
decorateClawdProfile(userDataDir, { color: DEFAULT_CLAWD_BROWSER_COLOR });
decorateOpenClawProfile(userDataDir, { color: DEFAULT_OPENCLAW_BROWSER_COLOR });
const expectedSignedArgb = ((0xff << 24) | 0xff4500) >> 0;
@@ -39,8 +42,8 @@ describe("browser chrome profile decoration", () => {
const infoCache = profile.info_cache as Record<string, unknown>;
const def = infoCache.Default as Record<string, unknown>;
expect(def.name).toBe(DEFAULT_CLAWD_BROWSER_PROFILE_NAME);
expect(def.shortcut_name).toBe(DEFAULT_CLAWD_BROWSER_PROFILE_NAME);
expect(def.name).toBe(DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME);
expect(def.shortcut_name).toBe(DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME);
expect(def.profile_color_seed).toBe(expectedSignedArgb);
expect(def.profile_highlight_color).toBe(expectedSignedArgb);
expect(def.default_avatar_fill_color).toBe(expectedSignedArgb);
@@ -56,7 +59,7 @@ describe("browser chrome profile decoration", () => {
expect(autogeneratedTheme.color).toBe(expectedSignedArgb);
const marker = await fsp.readFile(
path.join(userDataDir, ".clawd-profile-decorated"),
path.join(userDataDir, ".openclaw-profile-decorated"),
"utf-8",
);
expect(marker.trim()).toMatch(/^\d+$/);
@@ -66,15 +69,15 @@ describe("browser chrome profile decoration", () => {
});
it("best-effort writes name when color is invalid", async () => {
const userDataDir = await fsp.mkdtemp(path.join(os.tmpdir(), "moltbot-chrome-test-"));
const userDataDir = await fsp.mkdtemp(path.join(os.tmpdir(), "openclaw-chrome-test-"));
try {
decorateClawdProfile(userDataDir, { color: "lobster-orange" });
decorateOpenClawProfile(userDataDir, { color: "lobster-orange" });
const localState = await readJson(path.join(userDataDir, "Local State"));
const profile = localState.profile as Record<string, unknown>;
const infoCache = profile.info_cache as Record<string, unknown>;
const def = infoCache.Default as Record<string, unknown>;
expect(def.name).toBe(DEFAULT_CLAWD_BROWSER_PROFILE_NAME);
expect(def.name).toBe(DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME);
expect(def.profile_color_seed).toBeUndefined();
} finally {
await fsp.rm(userDataDir, { recursive: true, force: true });
@@ -82,7 +85,7 @@ describe("browser chrome profile decoration", () => {
});
it("recovers from missing/invalid preference files", async () => {
const userDataDir = await fsp.mkdtemp(path.join(os.tmpdir(), "moltbot-chrome-test-"));
const userDataDir = await fsp.mkdtemp(path.join(os.tmpdir(), "openclaw-chrome-test-"));
try {
await fsp.mkdir(path.join(userDataDir, "Default"), { recursive: true });
await fsp.writeFile(path.join(userDataDir, "Local State"), "{", "utf-8"); // invalid JSON
@@ -92,7 +95,7 @@ describe("browser chrome profile decoration", () => {
"utf-8",
);
decorateClawdProfile(userDataDir, { color: DEFAULT_CLAWD_BROWSER_COLOR });
decorateOpenClawProfile(userDataDir, { color: DEFAULT_OPENCLAW_BROWSER_COLOR });
const localState = await readJson(path.join(userDataDir, "Local State"));
expect(typeof localState.profile).toBe("object");
@@ -105,7 +108,7 @@ describe("browser chrome profile decoration", () => {
});
it("writes clean exit prefs to avoid restore prompts", async () => {
const userDataDir = await fsp.mkdtemp(path.join(os.tmpdir(), "moltbot-chrome-test-"));
const userDataDir = await fsp.mkdtemp(path.join(os.tmpdir(), "openclaw-chrome-test-"));
try {
ensureProfileCleanExit(userDataDir);
const prefs = await readJson(path.join(userDataDir, "Default", "Preferences"));
@@ -117,14 +120,14 @@ describe("browser chrome profile decoration", () => {
});
it("is idempotent when rerun on an existing profile", async () => {
const userDataDir = await fsp.mkdtemp(path.join(os.tmpdir(), "moltbot-chrome-test-"));
const userDataDir = await fsp.mkdtemp(path.join(os.tmpdir(), "openclaw-chrome-test-"));
try {
decorateClawdProfile(userDataDir, { color: DEFAULT_CLAWD_BROWSER_COLOR });
decorateClawdProfile(userDataDir, { color: DEFAULT_CLAWD_BROWSER_COLOR });
decorateOpenClawProfile(userDataDir, { color: DEFAULT_OPENCLAW_BROWSER_COLOR });
decorateOpenClawProfile(userDataDir, { color: DEFAULT_OPENCLAW_BROWSER_COLOR });
const prefs = await readJson(path.join(userDataDir, "Default", "Preferences"));
const profile = prefs.profile as Record<string, unknown>;
expect(profile.name).toBe(DEFAULT_CLAWD_BROWSER_PROFILE_NAME);
expect(profile.name).toBe(DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME);
} finally {
await fsp.rm(userDataDir, { recursive: true, force: true });
}
@@ -231,26 +234,26 @@ describe("browser chrome helpers", () => {
await expect(isChromeReachable("http://127.0.0.1:12345", 50)).resolves.toBe(false);
});
it("stopClawdChrome no-ops when process is already killed", async () => {
it("stopOpenClawChrome no-ops when process is already killed", async () => {
const proc = { killed: true, exitCode: null, kill: vi.fn() };
await stopClawdChrome(
await stopOpenClawChrome(
{
proc,
cdpPort: 12345,
} as unknown as Parameters<typeof stopClawdChrome>[0],
} as unknown as Parameters<typeof stopOpenClawChrome>[0],
10,
);
expect(proc.kill).not.toHaveBeenCalled();
});
it("stopClawdChrome sends SIGTERM and returns once CDP is down", async () => {
it("stopOpenClawChrome sends SIGTERM and returns once CDP is down", async () => {
vi.stubGlobal("fetch", vi.fn().mockRejectedValue(new Error("down")));
const proc = { killed: false, exitCode: null, kill: vi.fn() };
await stopClawdChrome(
await stopOpenClawChrome(
{
proc,
cdpPort: 12345,
} as unknown as Parameters<typeof stopClawdChrome>[0],
} as unknown as Parameters<typeof stopOpenClawChrome>[0],
10,
);
expect(proc.kill).toHaveBeenCalledWith("SIGTERM");

View File

@@ -14,12 +14,15 @@ import {
resolveBrowserExecutableForPlatform,
} from "./chrome.executables.js";
import {
decorateClawdProfile,
decorateOpenClawProfile,
ensureProfileCleanExit,
isProfileDecorated,
} from "./chrome.profile-decoration.js";
import type { ResolvedBrowserConfig, ResolvedBrowserProfile } from "./config.js";
import { DEFAULT_CLAWD_BROWSER_COLOR, DEFAULT_CLAWD_BROWSER_PROFILE_NAME } from "./constants.js";
import {
DEFAULT_OPENCLAW_BROWSER_COLOR,
DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME,
} from "./constants.js";
const log = createSubsystemLogger("browser").child("chrome");
@@ -31,7 +34,7 @@ export {
resolveBrowserExecutableForPlatform,
} from "./chrome.executables.js";
export {
decorateClawdProfile,
decorateOpenClawProfile,
ensureProfileCleanExit,
isProfileDecorated,
} from "./chrome.profile-decoration.js";
@@ -57,7 +60,7 @@ function resolveBrowserExecutable(resolved: ResolvedBrowserConfig): BrowserExecu
return resolveBrowserExecutableForPlatform(resolved, process.platform);
}
export function resolveClawdUserDataDir(profileName = DEFAULT_CLAWD_BROWSER_PROFILE_NAME) {
export function resolveOpenClawUserDataDir(profileName = DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME) {
return path.join(CONFIG_DIR, "browser", profileName, "user-data");
}
@@ -150,7 +153,7 @@ export async function isChromeCdpReady(
return await canOpenWebSocket(wsUrl, handshakeTimeoutMs);
}
export async function launchClawdChrome(
export async function launchOpenClawChrome(
resolved: ResolvedBrowserConfig,
profile: ResolvedBrowserProfile,
): Promise<RunningChrome> {
@@ -166,13 +169,13 @@ export async function launchClawdChrome(
);
}
const userDataDir = resolveClawdUserDataDir(profile.name);
const userDataDir = resolveOpenClawUserDataDir(profile.name);
fs.mkdirSync(userDataDir, { recursive: true });
const needsDecorate = !isProfileDecorated(
userDataDir,
profile.name,
(profile.color ?? DEFAULT_CLAWD_BROWSER_COLOR).toUpperCase(),
(profile.color ?? DEFAULT_OPENCLAW_BROWSER_COLOR).toUpperCase(),
);
// First launch to create preference files if missing, then decorate and relaunch.
@@ -246,20 +249,20 @@ export async function launchClawdChrome(
if (needsDecorate) {
try {
decorateClawdProfile(userDataDir, {
decorateOpenClawProfile(userDataDir, {
name: profile.name,
color: profile.color,
});
log.info(`🦞 clawd browser profile decorated (${profile.color})`);
log.info(`🦞 openclaw browser profile decorated (${profile.color})`);
} catch (err) {
log.warn(`clawd browser profile decoration failed: ${String(err)}`);
log.warn(`openclaw browser profile decoration failed: ${String(err)}`);
}
}
try {
ensureProfileCleanExit(userDataDir);
} catch (err) {
log.warn(`clawd browser clean-exit prefs failed: ${String(err)}`);
log.warn(`openclaw browser clean-exit prefs failed: ${String(err)}`);
}
const proc = spawnOnce();
@@ -283,7 +286,7 @@ export async function launchClawdChrome(
const pid = proc.pid ?? -1;
log.info(
`🦞 clawd browser started (${exe.kind}) profile "${profile.name}" on 127.0.0.1:${profile.cdpPort} (pid ${pid})`,
`🦞 openclaw browser started (${exe.kind}) profile "${profile.name}" on 127.0.0.1:${profile.cdpPort} (pid ${pid})`,
);
return {
@@ -296,7 +299,7 @@ export async function launchClawdChrome(
};
}
export async function stopClawdChrome(running: RunningChrome, timeoutMs = 2500) {
export async function stopOpenClawChrome(running: RunningChrome, timeoutMs = 2500) {
const proc = running.proc;
if (proc.killed) return;
try {

View File

@@ -12,7 +12,7 @@ function isAbsoluteHttp(url: string): boolean {
function enhanceBrowserFetchError(url: string, err: unknown, timeoutMs: number): Error {
const hint = isAbsoluteHttp(url)
? "If this is a sandboxed session, ensure the sandbox browser is running and try again."
: `Start (or restart) the Moltbot gateway (Moltbot.app menubar, or \`${formatCliCommand("moltbot gateway")}\`) and try again.`;
: `Start (or restart) the OpenClaw gateway (OpenClaw.app menubar, or \`${formatCliCommand("openclaw gateway")}\`) and try again.`;
const msg = String(err);
const msgLower = msg.toLowerCase();
const looksLikeTimeout =
@@ -23,10 +23,10 @@ function enhanceBrowserFetchError(url: string, err: unknown, timeoutMs: number):
msgLower.includes("aborterror");
if (looksLikeTimeout) {
return new Error(
`Can't reach the clawd browser control service (timed out after ${timeoutMs}ms). ${hint}`,
`Can't reach the openclaw browser control service (timed out after ${timeoutMs}ms). ${hint}`,
);
}
return new Error(`Can't reach the clawd browser control service. ${hint} (${msg})`);
return new Error(`Can't reach the openclaw browser control service. ${hint} (${msg})`);
}
async function fetchHttpJson<T>(

View File

@@ -161,7 +161,7 @@ export async function browserCreateProfile(
name: string;
color?: string;
cdpUrl?: string;
driver?: "clawd" | "extension";
driver?: "openclaw" | "extension";
},
): Promise<BrowserCreateProfileResult> {
return await fetchBrowserJson<BrowserCreateProfileResult>(

View File

@@ -16,17 +16,17 @@ describe("browser config", () => {
expect(profile?.cdpPort).toBe(18792);
expect(profile?.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");
const openclaw = resolveProfile(resolved, "openclaw");
expect(openclaw?.driver).toBe("openclaw");
expect(openclaw?.cdpPort).toBe(18800);
expect(openclaw?.cdpUrl).toBe("http://127.0.0.1:18800");
expect(resolved.remoteCdpTimeoutMs).toBe(1500);
expect(resolved.remoteCdpHandshakeTimeoutMs).toBe(3000);
});
it("derives default ports from CLAWDBOT_GATEWAY_PORT when unset", () => {
const prev = process.env.CLAWDBOT_GATEWAY_PORT;
process.env.CLAWDBOT_GATEWAY_PORT = "19001";
it("derives default ports from OPENCLAW_GATEWAY_PORT when unset", () => {
const prev = process.env.OPENCLAW_GATEWAY_PORT;
process.env.OPENCLAW_GATEWAY_PORT = "19001";
try {
const resolved = resolveBrowserConfig(undefined);
expect(resolved.controlPort).toBe(19003);
@@ -35,21 +35,21 @@ describe("browser config", () => {
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");
const openclaw = resolveProfile(resolved, "openclaw");
expect(openclaw?.cdpPort).toBe(19012);
expect(openclaw?.cdpUrl).toBe("http://127.0.0.1:19012");
} finally {
if (prev === undefined) {
delete process.env.CLAWDBOT_GATEWAY_PORT;
delete process.env.OPENCLAW_GATEWAY_PORT;
} else {
process.env.CLAWDBOT_GATEWAY_PORT = prev;
process.env.OPENCLAW_GATEWAY_PORT = prev;
}
}
});
it("derives default ports from gateway.port when env is unset", () => {
const prev = process.env.CLAWDBOT_GATEWAY_PORT;
delete process.env.CLAWDBOT_GATEWAY_PORT;
const prev = process.env.OPENCLAW_GATEWAY_PORT;
delete process.env.OPENCLAW_GATEWAY_PORT;
try {
const resolved = resolveBrowserConfig(undefined, { gateway: { port: 19011 } });
expect(resolved.controlPort).toBe(19013);
@@ -58,14 +58,14 @@ describe("browser config", () => {
expect(chrome?.cdpPort).toBe(19014);
expect(chrome?.cdpUrl).toBe("http://127.0.0.1:19014");
const clawd = resolveProfile(resolved, "clawd");
expect(clawd?.cdpPort).toBe(19022);
expect(clawd?.cdpUrl).toBe("http://127.0.0.1:19022");
const openclaw = resolveProfile(resolved, "openclaw");
expect(openclaw?.cdpPort).toBe(19022);
expect(openclaw?.cdpUrl).toBe("http://127.0.0.1:19022");
} finally {
if (prev === undefined) {
delete process.env.CLAWDBOT_GATEWAY_PORT;
delete process.env.OPENCLAW_GATEWAY_PORT;
} else {
process.env.CLAWDBOT_GATEWAY_PORT = prev;
process.env.OPENCLAW_GATEWAY_PORT = prev;
}
}
});
@@ -97,7 +97,7 @@ describe("browser config", () => {
const resolved = resolveBrowserConfig({
cdpUrl: "http://example.com:9222",
});
const profile = resolveProfile(resolved, "clawd");
const profile = resolveProfile(resolved, "openclaw");
expect(profile?.cdpIsLoopback).toBe(false);
});
@@ -105,7 +105,7 @@ describe("browser config", () => {
const resolved = resolveBrowserConfig({
cdpUrl: "http://example.com:9222",
});
const profile = resolveProfile(resolved, "clawd");
const profile = resolveProfile(resolved, "openclaw");
expect(profile?.cdpPort).toBe(9222);
expect(profile?.cdpUrl).toBe("http://example.com:9222");
expect(profile?.cdpIsLoopback).toBe(false);
@@ -143,10 +143,10 @@ describe("browser config", () => {
it("does not add the built-in chrome extension profile if the derived relay port is already used", () => {
const resolved = resolveBrowserConfig({
profiles: {
clawd: { cdpPort: 18792, color: "#FF4500" },
openclaw: { cdpPort: 18792, color: "#FF4500" },
},
});
expect(resolveProfile(resolved, "chrome")).toBe(null);
expect(resolved.defaultProfile).toBe("clawd");
expect(resolved.defaultProfile).toBe("openclaw");
});
});

View File

@@ -1,4 +1,4 @@
import type { BrowserConfig, BrowserProfileConfig, MoltbotConfig } from "../config/config.js";
import type { BrowserConfig, BrowserProfileConfig, OpenClawConfig } from "../config/config.js";
import {
deriveDefaultBrowserCdpPortRange,
deriveDefaultBrowserControlPort,
@@ -6,11 +6,11 @@ import {
} from "../config/port-defaults.js";
import { resolveGatewayPort } from "../config/paths.js";
import {
DEFAULT_CLAWD_BROWSER_COLOR,
DEFAULT_CLAWD_BROWSER_ENABLED,
DEFAULT_OPENCLAW_BROWSER_COLOR,
DEFAULT_OPENCLAW_BROWSER_ENABLED,
DEFAULT_BROWSER_EVALUATE_ENABLED,
DEFAULT_BROWSER_DEFAULT_PROFILE_NAME,
DEFAULT_CLAWD_BROWSER_PROFILE_NAME,
DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME,
} from "./constants.js";
import { CDP_PORT_RANGE_START, getUsedPorts } from "./profiles.js";
@@ -39,7 +39,7 @@ export type ResolvedBrowserProfile = {
cdpHost: string;
cdpIsLoopback: boolean;
color: string;
driver: "clawd" | "extension";
driver: "openclaw" | "extension";
};
function isLoopbackHost(host: string) {
@@ -57,9 +57,9 @@ function isLoopbackHost(host: string) {
function normalizeHexColor(raw: string | undefined) {
const value = (raw ?? "").trim();
if (!value) return DEFAULT_CLAWD_BROWSER_COLOR;
if (!value) return DEFAULT_OPENCLAW_BROWSER_COLOR;
const normalized = value.startsWith("#") ? value : `#${value}`;
if (!/^#[0-9a-fA-F]{6}$/.test(normalized)) return DEFAULT_CLAWD_BROWSER_COLOR;
if (!/^#[0-9a-fA-F]{6}$/.test(normalized)) return DEFAULT_OPENCLAW_BROWSER_COLOR;
return normalized.toUpperCase();
}
@@ -94,7 +94,7 @@ export function parseHttpUrl(raw: string, label: string) {
}
/**
* Ensure the default "clawd" profile exists in the profiles map.
* Ensure the default "openclaw" profile exists in the profiles map.
* Auto-creates it with the legacy CDP port (from browser.cdpUrl) or first port if missing.
*/
function ensureDefaultProfile(
@@ -104,8 +104,8 @@ function ensureDefaultProfile(
derivedDefaultCdpPort?: number,
): Record<string, BrowserProfileConfig> {
const result = { ...profiles };
if (!result[DEFAULT_CLAWD_BROWSER_PROFILE_NAME]) {
result[DEFAULT_CLAWD_BROWSER_PROFILE_NAME] = {
if (!result[DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME]) {
result[DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME] = {
cdpPort: legacyCdpPort ?? derivedDefaultCdpPort ?? CDP_PORT_RANGE_START,
color: defaultColor,
};
@@ -116,7 +116,7 @@ function ensureDefaultProfile(
/**
* Ensure a built-in "chrome" profile exists for the Chrome extension relay.
*
* Note: this is a Moltbot browser profile (routing config), not a Chrome user profile.
* Note: this is an OpenClaw browser profile (routing config), not a Chrome user profile.
* It points at the local relay CDP endpoint (controlPort + 1).
*/
function ensureDefaultChromeExtensionProfile(
@@ -128,7 +128,7 @@ function ensureDefaultChromeExtensionProfile(
const relayPort = controlPort + 1;
if (!Number.isFinite(relayPort) || relayPort <= 0 || relayPort > 65535) return result;
// Avoid adding the built-in profile if the derived relay port is already used by another profile
// (legacy single-profile configs may use controlPort+1 for clawd CDP).
// (legacy single-profile configs may use controlPort+1 for openclaw/openclaw CDP).
if (getUsedPorts(result).has(relayPort)) return result;
result.chrome = {
driver: "extension",
@@ -139,9 +139,9 @@ function ensureDefaultChromeExtensionProfile(
}
export function resolveBrowserConfig(
cfg: BrowserConfig | undefined,
rootConfig?: MoltbotConfig,
rootConfig?: OpenClawConfig,
): ResolvedBrowserConfig {
const enabled = cfg?.enabled ?? DEFAULT_CLAWD_BROWSER_ENABLED;
const enabled = cfg?.enabled ?? DEFAULT_OPENCLAW_BROWSER_ENABLED;
const evaluateEnabled = cfg?.evaluateEnabled ?? DEFAULT_BROWSER_EVALUATE_ENABLED;
const gatewayPort = resolveGatewayPort(rootConfig);
const controlPort = deriveDefaultBrowserControlPort(gatewayPort ?? DEFAULT_BROWSER_CONTROL_PORT);
@@ -196,7 +196,7 @@ export function resolveBrowserConfig(
defaultProfileFromConfig ??
(profiles[DEFAULT_BROWSER_DEFAULT_PROFILE_NAME]
? DEFAULT_BROWSER_DEFAULT_PROFILE_NAME
: DEFAULT_CLAWD_BROWSER_PROFILE_NAME);
: DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME);
return {
enabled,
@@ -232,7 +232,7 @@ export function resolveProfile(
let cdpHost = resolved.cdpHost;
let cdpPort = profile.cdpPort ?? 0;
let cdpUrl = "";
const driver = profile.driver === "extension" ? "extension" : "clawd";
const driver = profile.driver === "extension" ? "extension" : "openclaw";
if (rawProfileUrl) {
const parsed = parseHttpUrl(rawProfileUrl, `browser.profiles.${profileName}.cdpUrl`);

View File

@@ -1,7 +1,7 @@
export const DEFAULT_CLAWD_BROWSER_ENABLED = true;
export const DEFAULT_OPENCLAW_BROWSER_ENABLED = true;
export const DEFAULT_BROWSER_EVALUATE_ENABLED = true;
export const DEFAULT_CLAWD_BROWSER_COLOR = "#FF4500";
export const DEFAULT_CLAWD_BROWSER_PROFILE_NAME = "clawd";
export const DEFAULT_OPENCLAW_BROWSER_COLOR = "#FF4500";
export const DEFAULT_OPENCLAW_BROWSER_PROFILE_NAME = "openclaw";
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;

View File

@@ -65,7 +65,7 @@ export async function stopBrowserControlService(): Promise<void> {
}
}
} catch (err) {
logService.warn(`clawd browser stop failed: ${String(err)}`);
logService.warn(`openclaw browser stop failed: ${String(err)}`);
}
state = null;

View File

@@ -231,9 +231,9 @@ export async function ensureChromeExtensionRelayServer(opts: {
case "Browser.getVersion":
return {
protocolVersion: "1.3",
product: "Chrome/Moltbot-Extension-Relay",
product: "Chrome/OpenClaw-Extension-Relay",
revision: "0",
userAgent: "Moltbot-Extension-Relay",
userAgent: "OpenClaw-Extension-Relay",
jsVersion: "V8",
};
case "Browser.setDownloadBehavior":
@@ -318,7 +318,7 @@ export async function ensureChromeExtensionRelayServer(opts: {
(req.method === "GET" || req.method === "PUT")
) {
const payload: Record<string, unknown> = {
Browser: "Moltbot/extension-relay",
Browser: "OpenClaw/extension-relay",
"Protocol-Version": "1.3",
};
// Only advertise the WS URL if a real extension is connected.

View File

@@ -21,11 +21,11 @@ vi.mock("./trash.js", () => ({
}));
vi.mock("./chrome.js", () => ({
resolveClawdUserDataDir: vi.fn(() => "/tmp/clawd-test/clawd/user-data"),
resolveOpenClawUserDataDir: vi.fn(() => "/tmp/openclaw-test/openclaw/user-data"),
}));
import { loadConfig, writeConfigFile } from "../config/config.js";
import { resolveClawdUserDataDir } from "./chrome.js";
import { resolveOpenClawUserDataDir } from "./chrome.js";
import { movePathToTrash } from "./trash.js";
function createCtx(resolved: BrowserServerState["resolved"]) {
@@ -101,9 +101,9 @@ describe("BrowserProfilesService", () => {
vi.mocked(loadConfig).mockReturnValue({
browser: {
defaultProfile: "clawd",
defaultProfile: "openclaw",
profiles: {
clawd: { cdpPort: 18800, color: "#FF4500" },
openclaw: { cdpPort: 18800, color: "#FF4500" },
remote: { cdpUrl: "http://10.0.0.42:9222", color: "#0066CC" },
},
},
@@ -127,18 +127,18 @@ describe("BrowserProfilesService", () => {
vi.mocked(loadConfig).mockReturnValue({
browser: {
defaultProfile: "clawd",
defaultProfile: "openclaw",
profiles: {
clawd: { cdpPort: 18800, color: "#FF4500" },
openclaw: { cdpPort: 18800, color: "#FF4500" },
work: { cdpPort: 18801, color: "#0066CC" },
},
},
});
const tempDir = fs.mkdtempSync(path.join("/tmp", "clawd-profile-"));
const tempDir = fs.mkdtempSync(path.join("/tmp", "openclaw-profile-"));
const userDataDir = path.join(tempDir, "work", "user-data");
fs.mkdirSync(path.dirname(userDataDir), { recursive: true });
vi.mocked(resolveClawdUserDataDir).mockReturnValue(userDataDir);
vi.mocked(resolveOpenClawUserDataDir).mockReturnValue(userDataDir);
const service = createBrowserProfilesService(ctx);
const result = await service.deleteProfile("work");

View File

@@ -1,11 +1,11 @@
import fs from "node:fs";
import path from "node:path";
import type { BrowserProfileConfig, MoltbotConfig } from "../config/config.js";
import type { BrowserProfileConfig, OpenClawConfig } 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 { resolveOpenClawUserDataDir } from "./chrome.js";
import { parseHttpUrl, resolveProfile } from "./config.js";
import {
allocateCdpPort,
@@ -21,7 +21,7 @@ export type CreateProfileParams = {
name: string;
color?: string;
cdpUrl?: string;
driver?: "clawd" | "extension";
driver?: "openclaw" | "extension";
};
export type CreateProfileResult = {
@@ -93,7 +93,7 @@ export function createBrowserProfilesService(ctx: BrowserRouteContext) {
};
}
const nextConfig: MoltbotConfig = {
const nextConfig: OpenClawConfig = {
...cfg,
browser: {
...cfg.browser,
@@ -153,7 +153,7 @@ export function createBrowserProfilesService(ctx: BrowserRouteContext) {
// ignore
}
const userDataDir = resolveClawdUserDataDir(name);
const userDataDir = resolveOpenClawUserDataDir(name);
const profileDir = path.dirname(userDataDir);
if (fs.existsSync(profileDir)) {
await movePathToTrash(profileDir);
@@ -162,7 +162,7 @@ export function createBrowserProfilesService(ctx: BrowserRouteContext) {
}
const { [name]: _removed, ...remainingProfiles } = profiles;
const nextConfig: MoltbotConfig = {
const nextConfig: OpenClawConfig = {
...cfg,
browser: {
...cfg.browser,

View File

@@ -13,7 +13,7 @@ import {
describe("profile name validation", () => {
it("accepts valid lowercase names", () => {
expect(isValidProfileName("clawd")).toBe(true);
expect(isValidProfileName("openclaw")).toBe(true);
expect(isValidProfileName("work")).toBe(true);
expect(isValidProfileName("my-profile")).toBe(true);
expect(isValidProfileName("test123")).toBe(true);
@@ -109,7 +109,7 @@ describe("getUsedPorts", () => {
it("extracts ports from profile configs", () => {
const profiles = {
clawd: { cdpPort: 18792 },
openclaw: { cdpPort: 18792 },
work: { cdpPort: 18793 },
personal: { cdpPort: 18795 },
};
@@ -147,7 +147,7 @@ describe("port collision prevention", () => {
// Raw config shows empty - no ports used
expect(usedFromRaw.size).toBe(0);
// But resolved config has implicit clawd at 18800
// But resolved config has implicit openclaw at 18800
const resolved = resolveBrowserConfig({});
const usedFromResolved = getUsedPorts(resolved.profiles);
expect(usedFromResolved.has(CDP_PORT_RANGE_START)).toBe(true);
@@ -165,7 +165,7 @@ describe("port collision prevention", () => {
// Raw config: first allocation gets 18800
expect(buggyAllocatedPort).toBe(CDP_PORT_RANGE_START);
// Resolved config: includes implicit clawd at 18800
// Resolved config: includes implicit openclaw at 18800
const resolved = resolveBrowserConfig(rawConfig.browser);
const fixedUsedPorts = getUsedPorts(resolved.profiles);
const fixedAllocatedPort = allocateCdpPort(fixedUsedPorts);
@@ -238,7 +238,7 @@ describe("getUsedColors", () => {
it("extracts and uppercases colors from profile configs", () => {
const profiles = {
clawd: { color: "#ff4500" },
openclaw: { color: "#ff4500" },
work: { color: "#0066CC" },
};
const used = getUsedColors(profiles);

View File

@@ -69,7 +69,7 @@ export function getUsedPorts(
}
export const PROFILE_COLORS = [
"#FF4500", // Orange-red (clawd default)
"#FF4500", // Orange-red (openclaw default)
"#0066CC", // Blue
"#00AA00", // Green
"#9933FF", // Purple

View File

@@ -1,8 +1,8 @@
import { describe, it } from "vitest";
import { isTruthyEnvValue } from "../infra/env.js";
const LIVE = isTruthyEnvValue(process.env.LIVE) || isTruthyEnvValue(process.env.CLAWDBOT_LIVE_TEST);
const CDP_URL = process.env.CLAWDBOT_LIVE_BROWSER_CDP_URL?.trim() || "";
const LIVE = isTruthyEnvValue(process.env.LIVE) || isTruthyEnvValue(process.env.OPENCLAW_LIVE_TEST);
const CDP_URL = process.env.OPENCLAW_LIVE_BROWSER_CDP_URL?.trim() || "";
const describeLive = LIVE && CDP_URL ? describe : describe.skip;
async function waitFor(

View File

@@ -22,7 +22,7 @@ import {
function buildTempDownloadPath(fileName: string): string {
const id = crypto.randomUUID();
const safeName = fileName.trim() ? fileName.trim() : "download.bin";
return path.join("/tmp/moltbot/downloads", `${id}-${safeName}`);
return path.join("/tmp/openclaw/downloads", `${id}-${safeName}`);
}
function createPageDownloadWaiter(page: Page, timeoutMs: number) {

View File

@@ -427,11 +427,11 @@ export async function screenshotWithLabelsViaPlaywright(opts: {
try {
if (boxes.length > 0) {
await page.evaluate((labels) => {
const existing = document.querySelectorAll("[data-moltbot-labels]");
const existing = document.querySelectorAll("[data-openclaw-labels]");
existing.forEach((el) => el.remove());
const root = document.createElement("div");
root.setAttribute("data-moltbot-labels", "1");
root.setAttribute("data-openclaw-labels", "1");
root.style.position = "fixed";
root.style.left = "0";
root.style.top = "0";
@@ -445,7 +445,7 @@ export async function screenshotWithLabelsViaPlaywright(opts: {
for (const label of labels) {
const box = document.createElement("div");
box.setAttribute("data-moltbot-labels", "1");
box.setAttribute("data-openclaw-labels", "1");
box.style.position = "absolute";
box.style.left = `${label.x}px`;
box.style.top = `${label.y}px`;
@@ -455,7 +455,7 @@ export async function screenshotWithLabelsViaPlaywright(opts: {
box.style.boxSizing = "border-box";
const tag = document.createElement("div");
tag.setAttribute("data-moltbot-labels", "1");
tag.setAttribute("data-openclaw-labels", "1");
tag.textContent = label.ref;
tag.style.position = "absolute";
tag.style.left = `${label.x}px`;
@@ -482,7 +482,7 @@ export async function screenshotWithLabelsViaPlaywright(opts: {
} finally {
await page
.evaluate(() => {
const existing = document.querySelectorAll("[data-moltbot-labels]");
const existing = document.querySelectorAll("[data-openclaw-labels]");
existing.forEach((el) => el.remove());
})
.catch(() => {});

View File

@@ -66,7 +66,7 @@ export async function responseBodyViaPlaywright(opts: {
cleanup();
reject(
new Error(
`Response not found for url pattern "${pattern}". Run '${formatCliCommand("moltbot browser requests")}' to inspect recent network activity.`,
`Response not found for url pattern "${pattern}". Run '${formatCliCommand("openclaw browser requests")}' to inspect recent network activity.`,
),
);
}, timeout);

View File

@@ -217,7 +217,7 @@ export function registerBrowserAgentActRoutes(
403,
[
"wait --fn is disabled by config (browser.evaluateEnabled=false).",
"Docs: /gateway/configuration#browser-clawd-managed-browser",
"Docs: /gateway/configuration#browser-openclaw-managed-browser",
].join("\n"),
);
}
@@ -257,7 +257,7 @@ export function registerBrowserAgentActRoutes(
403,
[
"act:evaluate is disabled by config (browser.evaluateEnabled=false).",
"Docs: /gateway/configuration#browser-clawd-managed-browser",
"Docs: /gateway/configuration#browser-openclaw-managed-browser",
].join("\n"),
);
}

View File

@@ -112,7 +112,7 @@ export function registerBrowserAgentDebugRoutes(
const pw = await requirePwAi(res, "trace stop");
if (!pw) return;
const id = crypto.randomUUID();
const dir = "/tmp/moltbot";
const dir = "/tmp/openclaw";
await fs.mkdir(dir, { recursive: true });
const tracePath = out.trim() || path.join(dir, `browser-trace-${id}.zip`);
await pw.traceStopViaPlaywright({

View File

@@ -127,7 +127,7 @@ export function registerBrowserBasicRoutes(app: BrowserRouteRegistrar, ctx: Brow
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"
| "openclaw"
| "extension"
| "";

View File

@@ -6,11 +6,11 @@ import { createBrowserRouteContext } from "./server-context.js";
vi.mock("./chrome.js", () => ({
isChromeCdpReady: vi.fn(async () => true),
isChromeReachable: vi.fn(async () => true),
launchClawdChrome: vi.fn(async () => {
launchOpenClawChrome: vi.fn(async () => {
throw new Error("unexpected launch");
}),
resolveClawdUserDataDir: vi.fn(() => "/tmp/clawd"),
stopClawdChrome: vi.fn(async () => {}),
resolveOpenClawUserDataDir: vi.fn(() => "/tmp/openclaw"),
stopOpenClawChrome: vi.fn(async () => {}),
}));
describe("browser server-context ensureTabAvailable", () => {
@@ -78,7 +78,7 @@ describe("browser server-context ensureTabAvailable", () => {
cdpPort: 18792,
color: "#00AA00",
},
clawd: { cdpPort: 18800, color: "#FF4500" },
openclaw: { cdpPort: 18800, color: "#FF4500" },
},
},
profiles: new Map(),
@@ -135,7 +135,7 @@ describe("browser server-context ensureTabAvailable", () => {
cdpPort: 18792,
color: "#00AA00",
},
clawd: { cdpPort: 18800, color: "#FF4500" },
openclaw: { cdpPort: 18800, color: "#FF4500" },
},
},
profiles: new Map(),
@@ -182,7 +182,7 @@ describe("browser server-context ensureTabAvailable", () => {
cdpPort: 18792,
color: "#00AA00",
},
clawd: { cdpPort: 18800, color: "#FF4500" },
openclaw: { cdpPort: 18800, color: "#FF4500" },
},
},
profiles: new Map(),

View File

@@ -5,15 +5,15 @@ import type { BrowserServerState } from "./server-context.js";
vi.mock("./chrome.js", () => ({
isChromeCdpReady: vi.fn(async () => true),
isChromeReachable: vi.fn(async () => true),
launchClawdChrome: vi.fn(async () => {
launchOpenClawChrome: vi.fn(async () => {
throw new Error("unexpected launch");
}),
resolveClawdUserDataDir: vi.fn(() => "/tmp/clawd"),
stopClawdChrome: vi.fn(async () => {}),
resolveOpenClawUserDataDir: vi.fn(() => "/tmp/openclaw"),
stopOpenClawChrome: vi.fn(async () => {}),
}));
function makeState(
profile: "remote" | "clawd",
profile: "remote" | "openclaw",
): BrowserServerState & { profiles: Map<string, { lastTargetId?: string | null }> } {
return {
// biome-ignore lint/suspicious/noExplicitAny: test stub
@@ -38,7 +38,7 @@ function makeState(
cdpPort: 443,
color: "#00AA00",
},
clawd: { cdpPort: 18800, color: "#FF4500" },
openclaw: { cdpPort: 18800, color: "#FF4500" },
},
},
profiles: new Map(),
@@ -272,12 +272,12 @@ describe("browser server-context tab selection state", () => {
global.fetch = fetchMock;
const { createBrowserRouteContext } = await import("./server-context.js");
const state = makeState("clawd");
const state = makeState("openclaw");
const ctx = createBrowserRouteContext({ getState: () => state });
const clawd = ctx.forProfile("clawd");
const openclaw = ctx.forProfile("openclaw");
const opened = await clawd.openTab("https://created.example");
const opened = await openclaw.openTab("https://created.example");
expect(opened.targetId).toBe("CREATED");
expect(state.profiles.get("clawd")?.lastTargetId).toBe("CREATED");
expect(state.profiles.get("openclaw")?.lastTargetId).toBe("CREATED");
});
});

View File

@@ -4,9 +4,9 @@ import { appendCdpPath, createTargetViaCdp, getHeadersWithAuth, normalizeCdpWsUr
import {
isChromeCdpReady,
isChromeReachable,
launchClawdChrome,
resolveClawdUserDataDir,
stopClawdChrome,
launchOpenClawChrome,
resolveOpenClawUserDataDir,
stopOpenClawChrome,
} from "./chrome.js";
import type { ResolvedBrowserProfile } from "./config.js";
import { resolveProfile } from "./config.js";
@@ -285,7 +285,7 @@ function createProfileContext(
if (await isReachable(600)) return;
// Relay server is up, but no attached tab yet. Prompt user to attach.
throw new Error(
`Chrome extension relay is running, but no tab is connected. Click the Moltbot Chrome extension icon on a tab to attach it (profile "${profile.name}").`,
`Chrome extension relay is running, but no tab is connected. Click the OpenClaw Chrome extension icon on a tab to attach it (profile "${profile.name}").`,
);
}
@@ -301,7 +301,7 @@ function createProfileContext(
: `Browser attachOnly is enabled and profile "${profile.name}" is not running.`,
);
}
const launched = await launchClawdChrome(current.resolved, profile);
const launched = await launchOpenClawChrome(current.resolved, profile);
attachRunning(launched);
return;
}
@@ -312,7 +312,7 @@ function createProfileContext(
// HTTP responds but WebSocket fails - port in use by something else
if (!profileState.running) {
throw new Error(
`Port ${profile.cdpPort} is in use for profile "${profile.name}" but not by moltbot. ` +
`Port ${profile.cdpPort} is in use for profile "${profile.name}" but not by openclaw. ` +
`Run action=reset-profile profile=${profile.name} to kill the process.`,
);
}
@@ -330,10 +330,10 @@ function createProfileContext(
);
}
await stopClawdChrome(profileState.running);
await stopOpenClawChrome(profileState.running);
setProfileRunning(null);
const relaunched = await launchClawdChrome(current.resolved, profile);
const relaunched = await launchOpenClawChrome(current.resolved, profile);
attachRunning(relaunched);
if (!(await isReachable(600))) {
@@ -351,7 +351,7 @@ function createProfileContext(
if (profile.driver === "extension") {
throw new Error(
`tab not found (no attached Chrome tabs for profile "${profile.name}"). ` +
"Click the Moltbot Browser Relay toolbar icon on the tab you want to control (badge ON).",
"Click the OpenClaw Browser Relay toolbar icon on the tab you want to control (badge ON).",
);
}
await openTab("about:blank");
@@ -464,7 +464,7 @@ function createProfileContext(
}
const profileState = getProfileState();
if (!profileState.running) return { stopped: false };
await stopClawdChrome(profileState.running);
await stopOpenClawChrome(profileState.running);
setProfileRunning(null);
return { stopped: true };
};
@@ -479,7 +479,7 @@ function createProfileContext(
`reset-profile is only supported for local profiles (profile "${profile.name}" is remote).`,
);
}
const userDataDir = resolveClawdUserDataDir(profile.name);
const userDataDir = resolveOpenClawUserDataDir(profile.name);
const profileState = getProfileState();
const httpReachable = await isHttpReachable(300);

View File

@@ -94,9 +94,9 @@ vi.mock("../config/config.js", async (importOriginal) => {
color: "#FF4500",
attachOnly: cfgAttachOnly,
headless: true,
defaultProfile: "clawd",
defaultProfile: "openclaw",
profiles: {
clawd: { cdpPort: testPort + 1, color: "#FF4500" },
openclaw: { cdpPort: testPort + 1, color: "#FF4500" },
},
},
}),
@@ -108,20 +108,20 @@ const launchCalls = vi.hoisted(() => [] as Array<{ port: number }>);
vi.mock("./chrome.js", () => ({
isChromeCdpReady: vi.fn(async () => reachable),
isChromeReachable: vi.fn(async () => reachable),
launchClawdChrome: vi.fn(async (_resolved: unknown, profile: { cdpPort: number }) => {
launchOpenClawChrome: vi.fn(async (_resolved: unknown, profile: { cdpPort: number }) => {
launchCalls.push({ port: profile.cdpPort });
reachable = true;
return {
pid: 123,
exe: { kind: "chrome", path: "/fake/chrome" },
userDataDir: "/tmp/clawd",
userDataDir: "/tmp/openclaw",
cdpPort: profile.cdpPort,
startedAt: Date.now(),
proc,
};
}),
resolveClawdUserDataDir: vi.fn(() => "/tmp/clawd"),
stopClawdChrome: vi.fn(async () => {
resolveOpenClawUserDataDir: vi.fn(() => "/tmp/openclaw"),
stopOpenClawChrome: vi.fn(async () => {
reachable = false;
}),
}));
@@ -200,8 +200,8 @@ describe("browser control server", () => {
testPort = await getFreePort();
cdpBaseUrl = `http://127.0.0.1:${testPort + 1}`;
prevGatewayPort = process.env.CLAWDBOT_GATEWAY_PORT;
process.env.CLAWDBOT_GATEWAY_PORT = String(testPort - 2);
prevGatewayPort = process.env.OPENCLAW_GATEWAY_PORT;
process.env.OPENCLAW_GATEWAY_PORT = String(testPort - 2);
// Minimal CDP JSON endpoints used by the server.
let putNewCalls = 0;
@@ -254,9 +254,9 @@ describe("browser control server", () => {
vi.unstubAllGlobals();
vi.restoreAllMocks();
if (prevGatewayPort === undefined) {
delete process.env.CLAWDBOT_GATEWAY_PORT;
delete process.env.OPENCLAW_GATEWAY_PORT;
} else {
process.env.CLAWDBOT_GATEWAY_PORT = prevGatewayPort;
process.env.OPENCLAW_GATEWAY_PORT = prevGatewayPort;
}
const { stopBrowserControlServer } = await import("./server.js");
await stopBrowserControlServer();

View File

@@ -93,9 +93,9 @@ vi.mock("../config/config.js", async (importOriginal) => {
color: "#FF4500",
attachOnly: cfgAttachOnly,
headless: true,
defaultProfile: "clawd",
defaultProfile: "openclaw",
profiles: {
clawd: { cdpPort: testPort + 1, color: "#FF4500" },
openclaw: { cdpPort: testPort + 1, color: "#FF4500" },
},
},
}),
@@ -107,20 +107,20 @@ const launchCalls = vi.hoisted(() => [] as Array<{ port: number }>);
vi.mock("./chrome.js", () => ({
isChromeCdpReady: vi.fn(async () => reachable),
isChromeReachable: vi.fn(async () => reachable),
launchClawdChrome: vi.fn(async (_resolved: unknown, profile: { cdpPort: number }) => {
launchOpenClawChrome: vi.fn(async (_resolved: unknown, profile: { cdpPort: number }) => {
launchCalls.push({ port: profile.cdpPort });
reachable = true;
return {
pid: 123,
exe: { kind: "chrome", path: "/fake/chrome" },
userDataDir: "/tmp/clawd",
userDataDir: "/tmp/openclaw",
cdpPort: profile.cdpPort,
startedAt: Date.now(),
proc,
};
}),
resolveClawdUserDataDir: vi.fn(() => "/tmp/clawd"),
stopClawdChrome: vi.fn(async () => {
resolveOpenClawUserDataDir: vi.fn(() => "/tmp/openclaw"),
stopOpenClawChrome: vi.fn(async () => {
reachable = false;
}),
}));
@@ -198,8 +198,8 @@ describe("browser control server", () => {
testPort = await getFreePort();
cdpBaseUrl = `http://127.0.0.1:${testPort + 1}`;
prevGatewayPort = process.env.CLAWDBOT_GATEWAY_PORT;
process.env.CLAWDBOT_GATEWAY_PORT = String(testPort - 2);
prevGatewayPort = process.env.OPENCLAW_GATEWAY_PORT;
process.env.OPENCLAW_GATEWAY_PORT = String(testPort - 2);
// Minimal CDP JSON endpoints used by the server.
let putNewCalls = 0;
@@ -252,9 +252,9 @@ describe("browser control server", () => {
vi.unstubAllGlobals();
vi.restoreAllMocks();
if (prevGatewayPort === undefined) {
delete process.env.CLAWDBOT_GATEWAY_PORT;
delete process.env.OPENCLAW_GATEWAY_PORT;
} else {
process.env.CLAWDBOT_GATEWAY_PORT = prevGatewayPort;
process.env.OPENCLAW_GATEWAY_PORT = prevGatewayPort;
}
const { stopBrowserControlServer } = await import("./server.js");
await stopBrowserControlServer();

View File

@@ -92,9 +92,9 @@ vi.mock("../config/config.js", async (importOriginal) => {
color: "#FF4500",
attachOnly: cfgAttachOnly,
headless: true,
defaultProfile: "clawd",
defaultProfile: "openclaw",
profiles: {
clawd: { cdpPort: testPort + 1, color: "#FF4500" },
openclaw: { cdpPort: testPort + 1, color: "#FF4500" },
},
},
}),
@@ -106,20 +106,20 @@ const launchCalls = vi.hoisted(() => [] as Array<{ port: number }>);
vi.mock("./chrome.js", () => ({
isChromeCdpReady: vi.fn(async () => reachable),
isChromeReachable: vi.fn(async () => reachable),
launchClawdChrome: vi.fn(async (_resolved: unknown, profile: { cdpPort: number }) => {
launchOpenClawChrome: vi.fn(async (_resolved: unknown, profile: { cdpPort: number }) => {
launchCalls.push({ port: profile.cdpPort });
reachable = true;
return {
pid: 123,
exe: { kind: "chrome", path: "/fake/chrome" },
userDataDir: "/tmp/clawd",
userDataDir: "/tmp/openclaw",
cdpPort: profile.cdpPort,
startedAt: Date.now(),
proc,
};
}),
resolveClawdUserDataDir: vi.fn(() => "/tmp/clawd"),
stopClawdChrome: vi.fn(async () => {
resolveOpenClawUserDataDir: vi.fn(() => "/tmp/openclaw"),
stopOpenClawChrome: vi.fn(async () => {
reachable = false;
}),
}));
@@ -197,8 +197,8 @@ describe("browser control server", () => {
testPort = await getFreePort();
_cdpBaseUrl = `http://127.0.0.1:${testPort + 1}`;
prevGatewayPort = process.env.CLAWDBOT_GATEWAY_PORT;
process.env.CLAWDBOT_GATEWAY_PORT = String(testPort - 2);
prevGatewayPort = process.env.OPENCLAW_GATEWAY_PORT;
process.env.OPENCLAW_GATEWAY_PORT = String(testPort - 2);
// Minimal CDP JSON endpoints used by the server.
let putNewCalls = 0;
@@ -251,9 +251,9 @@ describe("browser control server", () => {
vi.unstubAllGlobals();
vi.restoreAllMocks();
if (prevGatewayPort === undefined) {
delete process.env.CLAWDBOT_GATEWAY_PORT;
delete process.env.OPENCLAW_GATEWAY_PORT;
} else {
process.env.CLAWDBOT_GATEWAY_PORT = prevGatewayPort;
process.env.OPENCLAW_GATEWAY_PORT = prevGatewayPort;
}
const { stopBrowserControlServer } = await import("./server.js");
await stopBrowserControlServer();
@@ -308,11 +308,11 @@ describe("backward compatibility (profile parameter)", () => {
testPort = await getFreePort();
_cdpBaseUrl = `http://127.0.0.1:${testPort + 1}`;
prevGatewayPort = process.env.CLAWDBOT_GATEWAY_PORT;
process.env.CLAWDBOT_GATEWAY_PORT = String(testPort - 2);
prevGatewayPort = process.env.OPENCLAW_GATEWAY_PORT;
process.env.OPENCLAW_GATEWAY_PORT = String(testPort - 2);
prevGatewayPort = process.env.CLAWDBOT_GATEWAY_PORT;
process.env.CLAWDBOT_GATEWAY_PORT = String(testPort - 2);
prevGatewayPort = process.env.OPENCLAW_GATEWAY_PORT;
process.env.OPENCLAW_GATEWAY_PORT = String(testPort - 2);
vi.stubGlobal(
"fetch",
@@ -350,9 +350,9 @@ describe("backward compatibility (profile parameter)", () => {
vi.unstubAllGlobals();
vi.restoreAllMocks();
if (prevGatewayPort === undefined) {
delete process.env.CLAWDBOT_GATEWAY_PORT;
delete process.env.OPENCLAW_GATEWAY_PORT;
} else {
process.env.CLAWDBOT_GATEWAY_PORT = prevGatewayPort;
process.env.OPENCLAW_GATEWAY_PORT = prevGatewayPort;
}
const { stopBrowserControlServer } = await import("./server.js");
await stopBrowserControlServer();
@@ -368,8 +368,8 @@ describe("backward compatibility (profile parameter)", () => {
profile?: string;
};
expect(status.running).toBe(false);
// Should use default profile (clawd)
expect(status.profile).toBe("clawd");
// Should use default profile (openclaw)
expect(status.profile).toBe("openclaw");
});
it("POST /start without profile uses default profile", async () => {
@@ -382,7 +382,7 @@ describe("backward compatibility (profile parameter)", () => {
profile?: string;
};
expect(result.ok).toBe(true);
expect(result.profile).toBe("clawd");
expect(result.profile).toBe("openclaw");
});
it("POST /stop without profile uses default profile", async () => {
@@ -397,7 +397,7 @@ describe("backward compatibility (profile parameter)", () => {
profile?: string;
};
expect(result.ok).toBe(true);
expect(result.profile).toBe("clawd");
expect(result.profile).toBe("openclaw");
});
it("GET /tabs without profile uses default profile", async () => {
@@ -439,18 +439,18 @@ describe("backward compatibility (profile parameter)", () => {
profiles: Array<{ name: string }>;
};
expect(Array.isArray(result.profiles)).toBe(true);
// Should at least have the default clawd profile
expect(result.profiles.some((p) => p.name === "clawd")).toBe(true);
// Should at least have the default openclaw profile
expect(result.profiles.some((p) => p.name === "openclaw")).toBe(true);
});
it("GET /tabs?profile=clawd returns tabs for specified profile", async () => {
it("GET /tabs?profile=openclaw returns tabs for specified profile", async () => {
const { startBrowserControlServerFromConfig } = await import("./server.js");
await startBrowserControlServerFromConfig();
const base = `http://127.0.0.1:${testPort}`;
await realFetch(`${base}/start`, { method: "POST" });
const result = (await realFetch(`${base}/tabs?profile=clawd`).then((r) => r.json())) as {
const result = (await realFetch(`${base}/tabs?profile=openclaw`).then((r) => r.json())) as {
running: boolean;
tabs: unknown[];
};
@@ -458,14 +458,14 @@ describe("backward compatibility (profile parameter)", () => {
expect(Array.isArray(result.tabs)).toBe(true);
});
it("POST /tabs/open?profile=clawd opens tab in specified profile", async () => {
it("POST /tabs/open?profile=openclaw opens tab in specified profile", async () => {
const { startBrowserControlServerFromConfig } = await import("./server.js");
await startBrowserControlServerFromConfig();
const base = `http://127.0.0.1:${testPort}`;
await realFetch(`${base}/start`, { method: "POST" });
const result = (await realFetch(`${base}/tabs/open?profile=clawd`, {
const result = (await realFetch(`${base}/tabs/open?profile=openclaw`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ url: "https://example.com" }),

View File

@@ -92,9 +92,9 @@ vi.mock("../config/config.js", async (importOriginal) => {
color: "#FF4500",
attachOnly: cfgAttachOnly,
headless: true,
defaultProfile: "clawd",
defaultProfile: "openclaw",
profiles: {
clawd: { cdpPort: testPort + 1, color: "#FF4500" },
openclaw: { cdpPort: testPort + 1, color: "#FF4500" },
},
},
}),
@@ -106,20 +106,20 @@ const launchCalls = vi.hoisted(() => [] as Array<{ port: number }>);
vi.mock("./chrome.js", () => ({
isChromeCdpReady: vi.fn(async () => reachable),
isChromeReachable: vi.fn(async () => reachable),
launchClawdChrome: vi.fn(async (_resolved: unknown, profile: { cdpPort: number }) => {
launchOpenClawChrome: vi.fn(async (_resolved: unknown, profile: { cdpPort: number }) => {
launchCalls.push({ port: profile.cdpPort });
reachable = true;
return {
pid: 123,
exe: { kind: "chrome", path: "/fake/chrome" },
userDataDir: "/tmp/clawd",
userDataDir: "/tmp/openclaw",
cdpPort: profile.cdpPort,
startedAt: Date.now(),
proc,
};
}),
resolveClawdUserDataDir: vi.fn(() => "/tmp/clawd"),
stopClawdChrome: vi.fn(async () => {
resolveOpenClawUserDataDir: vi.fn(() => "/tmp/openclaw"),
stopOpenClawChrome: vi.fn(async () => {
reachable = false;
}),
}));
@@ -197,8 +197,8 @@ describe("browser control server", () => {
testPort = await getFreePort();
_cdpBaseUrl = `http://127.0.0.1:${testPort + 1}`;
prevGatewayPort = process.env.CLAWDBOT_GATEWAY_PORT;
process.env.CLAWDBOT_GATEWAY_PORT = String(testPort - 2);
prevGatewayPort = process.env.OPENCLAW_GATEWAY_PORT;
process.env.OPENCLAW_GATEWAY_PORT = String(testPort - 2);
// Minimal CDP JSON endpoints used by the server.
let putNewCalls = 0;
@@ -251,9 +251,9 @@ describe("browser control server", () => {
vi.unstubAllGlobals();
vi.restoreAllMocks();
if (prevGatewayPort === undefined) {
delete process.env.CLAWDBOT_GATEWAY_PORT;
delete process.env.OPENCLAW_GATEWAY_PORT;
} else {
process.env.CLAWDBOT_GATEWAY_PORT = prevGatewayPort;
process.env.OPENCLAW_GATEWAY_PORT = prevGatewayPort;
}
const { stopBrowserControlServer } = await import("./server.js");
await stopBrowserControlServer();
@@ -285,11 +285,11 @@ describe("profile CRUD endpoints", () => {
testPort = await getFreePort();
_cdpBaseUrl = `http://127.0.0.1:${testPort + 1}`;
prevGatewayPort = process.env.CLAWDBOT_GATEWAY_PORT;
process.env.CLAWDBOT_GATEWAY_PORT = String(testPort - 2);
prevGatewayPort = process.env.OPENCLAW_GATEWAY_PORT;
process.env.OPENCLAW_GATEWAY_PORT = String(testPort - 2);
prevGatewayPort = process.env.CLAWDBOT_GATEWAY_PORT;
process.env.CLAWDBOT_GATEWAY_PORT = String(testPort - 2);
prevGatewayPort = process.env.OPENCLAW_GATEWAY_PORT;
process.env.OPENCLAW_GATEWAY_PORT = String(testPort - 2);
vi.stubGlobal(
"fetch",
@@ -305,9 +305,9 @@ describe("profile CRUD endpoints", () => {
vi.unstubAllGlobals();
vi.restoreAllMocks();
if (prevGatewayPort === undefined) {
delete process.env.CLAWDBOT_GATEWAY_PORT;
delete process.env.OPENCLAW_GATEWAY_PORT;
} else {
process.env.CLAWDBOT_GATEWAY_PORT = prevGatewayPort;
process.env.OPENCLAW_GATEWAY_PORT = prevGatewayPort;
}
const { stopBrowserControlServer } = await import("./server.js");
await stopBrowserControlServer();
@@ -348,11 +348,11 @@ describe("profile CRUD endpoints", () => {
await startBrowserControlServerFromConfig();
const base = `http://127.0.0.1:${testPort}`;
// "clawd" already exists as the default profile
// "openclaw" already exists as the default profile
const result = await realFetch(`${base}/profiles/create`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "clawd" }),
body: JSON.stringify({ name: "openclaw" }),
});
expect(result.status).toBe(409);
const body = (await result.json()) as { error: string };
@@ -413,8 +413,8 @@ describe("profile CRUD endpoints", () => {
await startBrowserControlServerFromConfig();
const base = `http://127.0.0.1:${testPort}`;
// clawd is the default profile
const result = await realFetch(`${base}/profiles/clawd`, {
// openclaw is the default profile
const result = await realFetch(`${base}/profiles/openclaw`, {
method: "DELETE",
});
expect(result.status).toBe(400);

View File

@@ -92,9 +92,9 @@ vi.mock("../config/config.js", async (importOriginal) => {
color: "#FF4500",
attachOnly: cfgAttachOnly,
headless: true,
defaultProfile: "clawd",
defaultProfile: "openclaw",
profiles: {
clawd: { cdpPort: testPort + 1, color: "#FF4500" },
openclaw: { cdpPort: testPort + 1, color: "#FF4500" },
},
},
}),
@@ -106,20 +106,20 @@ const launchCalls = vi.hoisted(() => [] as Array<{ port: number }>);
vi.mock("./chrome.js", () => ({
isChromeCdpReady: vi.fn(async () => reachable),
isChromeReachable: vi.fn(async () => reachable),
launchClawdChrome: vi.fn(async (_resolved: unknown, profile: { cdpPort: number }) => {
launchOpenClawChrome: vi.fn(async (_resolved: unknown, profile: { cdpPort: number }) => {
launchCalls.push({ port: profile.cdpPort });
reachable = true;
return {
pid: 123,
exe: { kind: "chrome", path: "/fake/chrome" },
userDataDir: "/tmp/clawd",
userDataDir: "/tmp/openclaw",
cdpPort: profile.cdpPort,
startedAt: Date.now(),
proc,
};
}),
resolveClawdUserDataDir: vi.fn(() => "/tmp/clawd"),
stopClawdChrome: vi.fn(async () => {
resolveOpenClawUserDataDir: vi.fn(() => "/tmp/openclaw"),
stopOpenClawChrome: vi.fn(async () => {
reachable = false;
}),
}));
@@ -197,8 +197,8 @@ describe("browser control server", () => {
testPort = await getFreePort();
_cdpBaseUrl = `http://127.0.0.1:${testPort + 1}`;
prevGatewayPort = process.env.CLAWDBOT_GATEWAY_PORT;
process.env.CLAWDBOT_GATEWAY_PORT = String(testPort - 2);
prevGatewayPort = process.env.OPENCLAW_GATEWAY_PORT;
process.env.OPENCLAW_GATEWAY_PORT = String(testPort - 2);
// Minimal CDP JSON endpoints used by the server.
let putNewCalls = 0;
@@ -251,9 +251,9 @@ describe("browser control server", () => {
vi.unstubAllGlobals();
vi.restoreAllMocks();
if (prevGatewayPort === undefined) {
delete process.env.CLAWDBOT_GATEWAY_PORT;
delete process.env.OPENCLAW_GATEWAY_PORT;
} else {
process.env.CLAWDBOT_GATEWAY_PORT = prevGatewayPort;
process.env.OPENCLAW_GATEWAY_PORT = prevGatewayPort;
}
const { stopBrowserControlServer } = await import("./server.js");
await stopBrowserControlServer();

View File

@@ -92,9 +92,9 @@ vi.mock("../config/config.js", async (importOriginal) => {
color: "#FF4500",
attachOnly: cfgAttachOnly,
headless: true,
defaultProfile: "clawd",
defaultProfile: "openclaw",
profiles: {
clawd: { cdpPort: testPort + 1, color: "#FF4500" },
openclaw: { cdpPort: testPort + 1, color: "#FF4500" },
},
},
}),
@@ -106,20 +106,20 @@ const launchCalls = vi.hoisted(() => [] as Array<{ port: number }>);
vi.mock("./chrome.js", () => ({
isChromeCdpReady: vi.fn(async () => reachable),
isChromeReachable: vi.fn(async () => reachable),
launchClawdChrome: vi.fn(async (_resolved: unknown, profile: { cdpPort: number }) => {
launchOpenClawChrome: vi.fn(async (_resolved: unknown, profile: { cdpPort: number }) => {
launchCalls.push({ port: profile.cdpPort });
reachable = true;
return {
pid: 123,
exe: { kind: "chrome", path: "/fake/chrome" },
userDataDir: "/tmp/clawd",
userDataDir: "/tmp/openclaw",
cdpPort: profile.cdpPort,
startedAt: Date.now(),
proc,
};
}),
resolveClawdUserDataDir: vi.fn(() => "/tmp/clawd"),
stopClawdChrome: vi.fn(async () => {
resolveOpenClawUserDataDir: vi.fn(() => "/tmp/openclaw"),
stopOpenClawChrome: vi.fn(async () => {
reachable = false;
}),
}));
@@ -197,8 +197,8 @@ describe("browser control server", () => {
testPort = await getFreePort();
cdpBaseUrl = `http://127.0.0.1:${testPort + 1}`;
prevGatewayPort = process.env.CLAWDBOT_GATEWAY_PORT;
process.env.CLAWDBOT_GATEWAY_PORT = String(testPort - 2);
prevGatewayPort = process.env.OPENCLAW_GATEWAY_PORT;
process.env.OPENCLAW_GATEWAY_PORT = String(testPort - 2);
// Minimal CDP JSON endpoints used by the server.
let putNewCalls = 0;
@@ -251,9 +251,9 @@ describe("browser control server", () => {
vi.unstubAllGlobals();
vi.restoreAllMocks();
if (prevGatewayPort === undefined) {
delete process.env.CLAWDBOT_GATEWAY_PORT;
delete process.env.OPENCLAW_GATEWAY_PORT;
} else {
process.env.CLAWDBOT_GATEWAY_PORT = prevGatewayPort;
process.env.OPENCLAW_GATEWAY_PORT = prevGatewayPort;
}
const { stopBrowserControlServer } = await import("./server.js");
await stopBrowserControlServer();
@@ -409,9 +409,9 @@ describe("browser control server", () => {
headless: true,
noSandbox: false,
attachOnly: true,
defaultProfile: "clawd",
defaultProfile: "openclaw",
profiles: {
clawd: { cdpPort: testPort + 1, color: "#FF4500" },
openclaw: { cdpPort: testPort + 1, color: "#FF4500" },
},
},
onEnsureAttachTarget: ensured,

View File

@@ -33,7 +33,7 @@ export async function startBrowserControlServerFromConfig(): Promise<BrowserServ
const s = app.listen(port, "127.0.0.1", () => resolve(s));
s.once("error", reject);
}).catch((err) => {
logServer.error(`clawd browser server failed to bind 127.0.0.1:${port}: ${String(err)}`);
logServer.error(`openclaw browser server failed to bind 127.0.0.1:${port}: ${String(err)}`);
return null;
});
@@ -80,7 +80,7 @@ export async function stopBrowserControlServer(): Promise<void> {
}
}
} catch (err) {
logServer.warn(`clawd browser stop failed: ${String(err)}`);
logServer.warn(`openclaw browser stop failed: ${String(err)}`);
}
if (current.server) {