Skip to content

Commit f3c3a15

Browse files
committed
feat(cli): preview --browser-no-gpu for gpu-unstable hosts
1 parent 8821646 commit f3c3a15

3 files changed

Lines changed: 43 additions & 0 deletions

File tree

‎packages/cli/src/commands/preview.ts‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ interface BrowserLaunchOptions {
5050
browserPath?: string;
5151
userDataDir?: string;
5252
remoteDebuggingPort?: number;
53+
browserNoGpu?: boolean;
5354
}
5455

5556
interface StudioLaunchOptions extends BrowserLaunchOptions {
@@ -142,6 +143,12 @@ export default defineCommand({
142143
type: "string",
143144
description: "Chromium remote debugging port (requires --browser-path and --user-data-dir)",
144145
},
146+
"browser-no-gpu": {
147+
type: "boolean",
148+
default: false,
149+
description:
150+
"Launch the opened browser with --disable-gpu (requires --browser-path). For hosts where hardware acceleration crashes the graphics driver (e.g. NVIDIA Xid resets); with the system default browser use --no-open instead.",
151+
},
145152
},
146153
async run({ args }) {
147154
const startPort = parseInt(args.port ?? "3002", 10);
@@ -239,6 +246,14 @@ export default defineCommand({
239246

240247
const noOpen = !args.open;
241248
const browserPath = args["browser-path"] as string | undefined;
249+
const browserNoGpu = !!args["browser-no-gpu"];
250+
if (browserNoGpu && !browserPath) {
251+
clack.log.error(
252+
"--browser-no-gpu requires --browser-path (the system default browser cannot receive Chromium flags — use --no-open on GPU-unstable hosts)",
253+
);
254+
process.exitCode = 1;
255+
return;
256+
}
242257
const userDataDir = args["user-data-dir"] as string | undefined;
243258
let remoteDebuggingPort: number | undefined;
244259
try {
@@ -258,6 +273,7 @@ export default defineCommand({
258273
browserPath,
259274
userDataDir,
260275
remoteDebuggingPort,
276+
browserNoGpu,
261277
});
262278
}
263279

@@ -269,6 +285,7 @@ export default defineCommand({
269285
browserPath,
270286
userDataDir,
271287
remoteDebuggingPort,
288+
browserNoGpu,
272289
});
273290
}
274291

@@ -280,6 +297,7 @@ export default defineCommand({
280297
browserPath,
281298
userDataDir,
282299
remoteDebuggingPort,
300+
browserNoGpu,
283301
});
284302
},
285303
});
@@ -641,6 +659,7 @@ function openStudioBrowser(url: string, projectName: string, options?: BrowserLa
641659
browserPath: options?.browserPath,
642660
userDataDir: options?.userDataDir,
643661
remoteDebuggingPort: options?.remoteDebuggingPort,
662+
disableGpu: options?.browserNoGpu,
644663
});
645664
}
646665

‎packages/cli/src/utils/openBrowser.test.ts‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,3 +158,16 @@ describe("validateRemoteDebuggingPortDeps", () => {
158158
).toBe("--remote-debugging-port requires --browser-path");
159159
});
160160
});
161+
162+
describe("buildBrowserArgs --disable-gpu", () => {
163+
it("appends --disable-gpu before the url when disableGpu is set", () => {
164+
expect(buildBrowserArgs("http://localhost:3002", { disableGpu: true })).toEqual([
165+
"--disable-gpu",
166+
"http://localhost:3002",
167+
]);
168+
});
169+
170+
it("omits --disable-gpu by default", () => {
171+
expect(buildBrowserArgs("http://localhost:3002", {})).toEqual(["http://localhost:3002"]);
172+
});
173+
});

‎packages/cli/src/utils/openBrowser.ts‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ export interface OpenBrowserOptions {
44
browserPath?: string;
55
userDataDir?: string;
66
remoteDebuggingPort?: number;
7+
/**
8+
* Launch the browser with --disable-gpu. For hosts where hardware
9+
* acceleration crashes the graphics driver (wild report: auto-opened
10+
* preview triggered NVIDIA Xid 32 resets on NixOS). Only effective with
11+
* `browserPath` — the `open`-package fallback launches the system default
12+
* browser with no way to pass Chromium flags.
13+
*/
14+
disableGpu?: boolean;
715
}
816

917
export function parseRemoteDebuggingPort(value: string | undefined): number | undefined {
@@ -52,6 +60,9 @@ export function buildBrowserArgs(url: string, options: OpenBrowserOptions): stri
5260
if (options.remoteDebuggingPort !== undefined && options.userDataDir) {
5361
args.push(`--remote-debugging-port=${options.remoteDebuggingPort}`);
5462
}
63+
if (options.disableGpu) {
64+
args.push("--disable-gpu");
65+
}
5566
args.push(url);
5667
return args;
5768
}

0 commit comments

Comments
 (0)