mirror of https://github.com/garrytan/gstack.git
Merge 6e8574bde4 into 2beb636f7c
This commit is contained in:
commit
74ade8e7fc
|
|
@ -369,6 +369,16 @@ export class BrowserManager {
|
|||
console.log(`[browse] Extensions loaded from: ${extensionsDir}`);
|
||||
}
|
||||
|
||||
// Windows: the default headless path launches chrome-headless-shell.exe — a
|
||||
// CONSOLE-subsystem binary that pops a terminal window on every launch. Switch
|
||||
// to Chrome's "new" headless (full chrome.exe, GUI-subsystem → no console
|
||||
// window) by launching non-headless with --headless=new. Other platforms keep
|
||||
// the lighter headless shell (they have no console-window problem).
|
||||
if (process.platform === 'win32' && useHeadless) {
|
||||
launchArgs.push('--headless=new');
|
||||
useHeadless = false;
|
||||
}
|
||||
|
||||
this.browser = await chromium.launch({
|
||||
headless: useHeadless,
|
||||
// On Windows, Chromium's sandbox fails when the server is spawned through
|
||||
|
|
|
|||
|
|
@ -323,9 +323,11 @@ async function startServer(extraEnv?: Record<string, string>): Promise<ServerSta
|
|||
const launcherCode =
|
||||
`const{spawn}=require('child_process');` +
|
||||
`spawn(process.execPath,[${JSON.stringify(NODE_SERVER_SCRIPT)}],` +
|
||||
`{detached:true,stdio:['ignore','ignore','ignore'],env:Object.assign({},process.env,` +
|
||||
// windowsHide: a detached spawn on Windows pops a console window unless
|
||||
// explicitly hidden — this flashed on every daemon (re)start.
|
||||
`{detached:true,windowsHide:true,stdio:['ignore','ignore','ignore'],env:Object.assign({},process.env,` +
|
||||
`${extraEnvStr})}).unref()`;
|
||||
Bun.spawnSync(['node', '-e', launcherCode], { stdio: ['ignore', 'ignore', 'ignore'] });
|
||||
Bun.spawnSync(['node', '-e', launcherCode], { stdio: ['ignore', 'ignore', 'ignore'], windowsHide: true });
|
||||
} else {
|
||||
// macOS/Linux: Bun.spawn().unref() only removes the child from Bun's event
|
||||
// loop — it does NOT call setsid(), so the spawned server stays in the
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { spawn as nodeSpawn } from 'child_process';
|
||||
import { safeUnlink, safeKill, isProcessAlive } from './error-handling';
|
||||
import { writeSecureFile, mkdirSecure } from './file-permissions';
|
||||
|
||||
|
|
@ -68,7 +69,10 @@ export function spawnTerminalAgent(opts: {
|
|||
}
|
||||
const script = opts.scriptPath || resolveTerminalAgentScript();
|
||||
if (!script || !fs.existsSync(script)) return null;
|
||||
const proc = (Bun as any).spawn(['bun', 'run', script], {
|
||||
// Spawn via Node's child_process (not Bun.spawn): Node's `windowsHide` reliably
|
||||
// suppresses the console window on Windows, whereas Bun's does not. Same lifecycle:
|
||||
// an unref'd child so it doesn't hold the parent's event loop open.
|
||||
const proc = nodeSpawn('bun', ['run', script], {
|
||||
cwd: opts.cwd || process.cwd(),
|
||||
env: {
|
||||
...process.env,
|
||||
|
|
@ -77,6 +81,7 @@ export function spawnTerminalAgent(opts: {
|
|||
...(opts.extraEnv || {}),
|
||||
},
|
||||
stdio: ['ignore', 'ignore', 'ignore'],
|
||||
windowsHide: true,
|
||||
});
|
||||
proc.unref?.();
|
||||
return proc.pid ?? null;
|
||||
|
|
|
|||
Loading…
Reference in New Issue