fix: expand browser executable home paths · openclaw/openclaw@95a2c9b
steipete
·
2026-04-25
·
via Recent Commits to openclaw:main
File tree
extensions/browser/src/browser
| Original file line number | Diff line number | Diff line change |
|---|
@@ -66,6 +66,7 @@ Docs: https://docs.openclaw.ai
|
66 | 66 | ### Fixes |
67 | 67 | |
68 | 68 | - Providers/OpenAI: separate API-key and Codex sign-in onboarding groups, and avoid replaying stale OpenAI Responses reasoning blocks after a model route switch. |
| 69 | +- Browser/config: expand `~` in `browser.executablePath` before Chromium launch, so home-relative custom browser paths no longer fail with `ENOENT`. Fixes #67264. Thanks @Quratulain-bilal. |
69 | 70 | - Discord/subagents: preserve thread-bound completion delivery by keeping the requester-agent announce path primary and falling back to direct thread sends only when the announce produces no visible output. (#71064) Thanks @DolencLuka. |
70 | 71 | - Browser/tool: give Chrome MCP existing-session manage calls a longer default timeout, pass explicit tool timeouts through tab management, and recover stale selected-page MCP sessions instead of forcing a manual reset. Thanks @steipete. |
71 | 72 | - Browser/sandbox: clean up idle tracked tabs opened by primary-agent browser sessions, while preserving active tab reuse and lifecycle cleanup for subagents, cron, and ACP sessions. Fixes #71165. Thanks @dwbutler. |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -219,6 +219,7 @@ See [Plugins](/tools/plugin).
|
219 | 219 | - Local managed `openclaw` profiles auto-assign `cdpPort` and `cdpUrl`; only |
220 | 220 | set `cdpUrl` explicitly for remote CDP. |
221 | 221 | - Auto-detect order: default browser if Chromium-based → Chrome → Brave → Edge → Chromium → Chrome Canary. |
| 222 | +- `browser.executablePath` accepts `~` for your OS home directory. |
222 | 223 | - Control service: loopback only (port derived from `gateway.port`, default `18791`). |
223 | 224 | - `extraArgs` appends extra launch flags to local Chromium startup (for example |
224 | 225 | `--disable-gpu`, window sizing, or debug flags). |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -199,7 +199,7 @@ Browser settings live in `~/.openclaw/openclaw.json`.
|
199 | 199 | |
200 | 200 | If your **system default** browser is Chromium-based (Chrome/Brave/Edge/etc), |
201 | 201 | OpenClaw uses it automatically. Set `browser.executablePath` to override |
202 | | -auto-detection: |
| 202 | +auto-detection. `~` expands to your OS home directory: |
203 | 203 | |
204 | 204 | ```bash |
205 | 205 | openclaw config set browser.executablePath "/usr/bin/google-chrome" |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +import os from "node:os"; |
| 2 | +import path from "node:path"; |
1 | 3 | import { describe, expect, it } from "vitest"; |
2 | 4 | import type { BrowserConfig } from "../config/config.js"; |
3 | 5 | import { resolveUserPath } from "../utils.js"; |
@@ -139,6 +141,30 @@ describe("browser config", () => {
|
139 | 141 | }); |
140 | 142 | }); |
141 | 143 | |
| 144 | +it("expands tilde-prefixed executablePath with the OS home directory", () => { |
| 145 | +const resolved = resolveBrowserConfig({ |
| 146 | +executablePath: " ~/.local/bin/chromium ", |
| 147 | +}); |
| 148 | + |
| 149 | +expect(resolved.executablePath).toBe(path.resolve(os.homedir(), ".local/bin/chromium")); |
| 150 | +}); |
| 151 | + |
| 152 | +it("keeps non-tilde executablePath values unchanged after trimming", () => { |
| 153 | +const resolved = resolveBrowserConfig({ |
| 154 | +executablePath: " ./local-chromium ", |
| 155 | +}); |
| 156 | + |
| 157 | +expect(resolved.executablePath).toBe("./local-chromium"); |
| 158 | +}); |
| 159 | + |
| 160 | +it("normalizes blank executablePath to undefined", () => { |
| 161 | +const resolved = resolveBrowserConfig({ |
| 162 | +executablePath: " ", |
| 163 | +}); |
| 164 | + |
| 165 | +expect(resolved.executablePath).toBeUndefined(); |
| 166 | +}); |
| 167 | + |
142 | 168 | it("normalizes invalid browser tab cleanup numbers to defaults", () => { |
143 | 169 | const resolved = resolveBrowserConfig({ |
144 | 170 | tabCleanup: { |
|
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +import os from "node:os"; |
| 2 | +import path from "node:path"; |
1 | 3 | import { |
2 | 4 | normalizeOptionalString, |
3 | 5 | normalizeOptionalTrimmedStringList, |
@@ -125,6 +127,17 @@ function normalizePositiveInteger(raw: number | undefined, fallback: number): nu
|
125 | 127 | return value <= 0 ? fallback : value; |
126 | 128 | } |
127 | 129 | |
| 130 | +function normalizeExecutablePath(raw: string | undefined): string | undefined { |
| 131 | +const value = normalizeOptionalString(raw); |
| 132 | +if (!value) { |
| 133 | +return undefined; |
| 134 | +} |
| 135 | +if (!/^~(?=$|[\\/])/.test(value)) { |
| 136 | +return value; |
| 137 | +} |
| 138 | +return path.resolve(value.replace(/^~(?=$|[\\/])/, os.homedir())); |
| 139 | +} |
| 140 | + |
128 | 141 | function resolveBrowserTabCleanupConfig( |
129 | 142 | cfg: BrowserConfig | undefined, |
130 | 143 | ): ResolvedBrowserTabCleanupConfig { |
@@ -287,7 +300,7 @@ export function resolveBrowserConfig(
|
287 | 300 | const headless = cfg?.headless === true; |
288 | 301 | const noSandbox = cfg?.noSandbox === true; |
289 | 302 | const attachOnly = cfg?.attachOnly === true; |
290 | | -const executablePath = normalizeOptionalString(cfg?.executablePath); |
| 303 | +const executablePath = normalizeExecutablePath(cfg?.executablePath); |
291 | 304 | const defaultProfileFromConfig = normalizeOptionalString(cfg?.defaultProfile); |
292 | 305 | |
293 | 306 | const legacyCdpPort = rawCdpUrl ? cdpInfo.port : undefined; |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。