diff --git a/packages/cli/src/lib/driver/session-manager.ts b/packages/cli/src/lib/driver/session-manager.ts index 8dce61a4e..92132e9ae 100644 --- a/packages/cli/src/lib/driver/session-manager.ts +++ b/packages/cli/src/lib/driver/session-manager.ts @@ -27,6 +27,27 @@ interface InitFailure { retryAt: number; } +function readBrowseChromeArgs(): string[] { + const raw = process.env.BROWSE_CHROME_ARGS?.trim(); + if (!raw) return []; + + if (raw.startsWith("[")) { + try { + const parsed = JSON.parse(raw); + if ( + Array.isArray(parsed) && + parsed.every((arg) => typeof arg === "string") + ) { + return parsed; + } + } catch { + // Fall back to whitespace-separated args below. + } + } + + return raw.split(/\s+/).filter(Boolean); +} + export class DriverSessionManager { readonly network: NetworkCapture; @@ -275,10 +296,12 @@ export class DriverSessionManager { } if (target.kind === "managed-local") { + const chromeArgs = readBrowseChromeArgs(); return { disablePino: true, env: "LOCAL", localBrowserLaunchOptions: { + ...(chromeArgs.length > 0 ? { args: chromeArgs } : {}), headless: target.headless, }, verbose: 0, diff --git a/packages/cli/tests/driver-foundation.test.ts b/packages/cli/tests/driver-foundation.test.ts index 060b39109..c2ab7dd85 100644 --- a/packages/cli/tests/driver-foundation.test.ts +++ b/packages/cli/tests/driver-foundation.test.ts @@ -512,6 +512,57 @@ describe("driver foundation", () => { } }); + it("passes custom Chrome args to managed local sessions", async () => { + const previousChromeArgs = process.env.BROWSE_CHROME_ARGS; + process.env.BROWSE_CHROME_ARGS = JSON.stringify([ + "--no-startup-window", + "--disable-features=CalculateNativeWinOcclusion", + ]); + const init = vi.fn().mockRejectedValue(new Error("init failed")); + const close = vi.fn().mockResolvedValue(undefined); + const Stagehand = vi.fn(function () { + return { + close, + context: {}, + init, + }; + }); + + vi.resetModules(); + vi.doMock("@browserbasehq/stagehand", () => ({ + Stagehand, + })); + + try { + const { DriverSessionManager: MockedDriverSessionManager } = await import( + "../src/lib/driver/session-manager.js" + ); + const manager = new MockedDriverSessionManager("local-chrome-args", { + headless: false, + kind: "managed-local", + }); + + await expect(manager.open("https://example.com")).rejects.toThrow( + "init failed", + ); + expect(Stagehand).toHaveBeenCalledWith( + expect.objectContaining({ + localBrowserLaunchOptions: { + args: [ + "--no-startup-window", + "--disable-features=CalculateNativeWinOcclusion", + ], + headless: false, + }, + }), + ); + } finally { + restoreEnv("BROWSE_CHROME_ARGS", previousChromeArgs); + vi.doUnmock("@browserbasehq/stagehand"); + vi.resetModules(); + } + }); + it("creates a page for open when the initialized session has none", async () => { const manager = new DriverSessionManager("empty-open", { headless: true,