fix(browser): detect more Linux Chromium installs (#48563)

Co-authored-by: Catalin Lupuleti <105351510+lupuletic@users.noreply.github.com>
This commit is contained in:
Peter Steinberger
2026-04-25 09:11:30 +01:00
parent 0da58302cf
commit 5ac36c9719
4 changed files with 53 additions and 1 deletions

View File

@@ -13,6 +13,7 @@ Docs: https://docs.openclaw.ai
### Fixes
- Browser/Linux: detect Chromium-based installs under `/opt/google`, `/opt/brave.com`, `/usr/lib/chromium`, and `/usr/lib/chromium-browser` before asking users to set `browser.executablePath`. (#48563) Thanks @lupuletic.
- MCP/CLI: retire bundled MCP runtimes at the end of one-shot `openclaw agent` and `openclaw infer model run` gateway/local executions, so repeated scripted runs do not accumulate stdio MCP child processes. Fixes #71457.
- OpenAI/Codex image generation: canonicalize legacy `openai-codex.baseUrl` values such as `https://chatgpt.com/backend-api` to the Codex Responses backend before calling `gpt-image-2`, matching the chat transport. Fixes #71460.
- Control UI: make `/usage` use the fresh context snapshot for context percentage, and include cache-write tokens in the Usage overview cache-hit denominator. Fixes #47885. Thanks @imwyvern and @Ante042.

View File

@@ -561,7 +561,9 @@ You can override with `browser.executablePath`.
Platforms:
- macOS: checks `/Applications` and `~/Applications`.
- Linux: looks for `google-chrome`, `brave`, `microsoft-edge`, `chromium`, etc.
- Linux: checks common Chrome/Brave/Edge/Chromium locations under `/usr/bin`,
`/snap/bin`, `/opt/google`, `/opt/brave.com`, `/usr/lib/chromium`, and
`/usr/lib/chromium-browser`.
- Windows: checks common install locations.
## Control API (optional)

View File

@@ -555,14 +555,18 @@ export function findChromeExecutableLinux(): BrowserExecutable | null {
{ kind: "chrome", path: "/usr/bin/google-chrome" },
{ kind: "chrome", path: "/usr/bin/google-chrome-stable" },
{ kind: "chrome", path: "/usr/bin/chrome" },
{ kind: "chrome", path: "/opt/google/chrome/chrome" },
{ kind: "brave", path: "/usr/bin/brave-browser" },
{ kind: "brave", path: "/usr/bin/brave-browser-stable" },
{ kind: "brave", path: "/usr/bin/brave" },
{ kind: "brave", path: "/snap/bin/brave" },
{ kind: "brave", path: "/opt/brave.com/brave/brave-browser" },
{ kind: "edge", path: "/usr/bin/microsoft-edge" },
{ kind: "edge", path: "/usr/bin/microsoft-edge-stable" },
{ kind: "chromium", path: "/usr/bin/chromium" },
{ kind: "chromium", path: "/usr/bin/chromium-browser" },
{ kind: "chromium", path: "/usr/lib/chromium/chromium" },
{ kind: "chromium", path: "/usr/lib/chromium-browser/chromium-browser" },
{ kind: "chromium", path: "/snap/bin/chromium" },
];
@@ -575,6 +579,7 @@ export function findGoogleChromeExecutableLinux(): BrowserExecutable | null {
"/usr/bin/google-chrome-stable",
"/usr/bin/google-chrome-beta",
"/usr/bin/google-chrome-unstable",
"/opt/google/chrome/chrome",
"/snap/bin/google-chrome",
]);
}

View File

@@ -15,6 +15,7 @@ import {
decorateOpenClawProfile,
diagnoseChromeCdp,
ensureProfileCleanExit,
findChromeExecutableLinux,
findChromeExecutableMac,
findChromeExecutableWindows,
formatChromeCdpDiagnostic,
@@ -295,6 +296,38 @@ describe("browser chrome helpers", () => {
exists.mockRestore();
});
it("finds common Linux Chromium package paths", () => {
for (const target of [
"/usr/lib/chromium/chromium",
"/usr/lib/chromium-browser/chromium-browser",
]) {
const exists = mockExistsSync((pathValue) => pathValue === target);
const exe = findChromeExecutableLinux();
expect(exe).toEqual({ kind: "chromium", path: target });
exists.mockRestore();
}
});
it("finds common Linux /opt Chrome and Brave paths", () => {
const cases = [
{ kind: "chrome", path: "/opt/google/chrome/chrome" },
{ kind: "brave", path: "/opt/brave.com/brave/brave-browser" },
] as const;
for (const candidate of cases) {
const exists = mockExistsSync((pathValue) => pathValue === candidate.path);
const exe = findChromeExecutableLinux();
expect(exe).toEqual(candidate);
exists.mockRestore();
}
});
it("returns null when no Chrome candidate exists on Linux", () => {
const exists = vi.spyOn(fs, "existsSync").mockReturnValue(false);
expect(findChromeExecutableLinux()).toBeNull();
exists.mockRestore();
});
it("picks the first existing Chrome candidate on Windows", () => {
vi.stubEnv("LOCALAPPDATA", "C:\\Users\\Test\\AppData\\Local");
const exists = mockExistsSync((pathStr) => {
@@ -665,6 +698,17 @@ describe("chrome executables", () => {
path: "/usr/bin/google-chrome-unstable",
});
});
it("finds Linux Google Chrome under /opt", () => {
vi.spyOn(fs, "existsSync").mockImplementation((candidate) => {
return String(candidate) === "/opt/google/chrome/chrome";
});
expect(resolveGoogleChromeExecutableForPlatform("linux")).toEqual({
kind: "chrome",
path: "/opt/google/chrome/chrome",
});
});
});
describe("browser chrome launch args", () => {