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}`);
|
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({
|
this.browser = await chromium.launch({
|
||||||
headless: useHeadless,
|
headless: useHeadless,
|
||||||
// On Windows, Chromium's sandbox fails when the server is spawned through
|
// 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 launcherCode =
|
||||||
`const{spawn}=require('child_process');` +
|
`const{spawn}=require('child_process');` +
|
||||||
`spawn(process.execPath,[${JSON.stringify(NODE_SERVER_SCRIPT)}],` +
|
`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()`;
|
`${extraEnvStr})}).unref()`;
|
||||||
Bun.spawnSync(['node', '-e', launcherCode], { stdio: ['ignore', 'ignore', 'ignore'] });
|
Bun.spawnSync(['node', '-e', launcherCode], { stdio: ['ignore', 'ignore', 'ignore'], windowsHide: true });
|
||||||
} else {
|
} else {
|
||||||
// macOS/Linux: Bun.spawn().unref() only removes the child from Bun's event
|
// 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
|
// loop — it does NOT call setsid(), so the spawned server stays in the
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
*/
|
*/
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
import { spawn as nodeSpawn } from 'child_process';
|
||||||
import { safeUnlink, safeKill, isProcessAlive } from './error-handling';
|
import { safeUnlink, safeKill, isProcessAlive } from './error-handling';
|
||||||
import { writeSecureFile, mkdirSecure } from './file-permissions';
|
import { writeSecureFile, mkdirSecure } from './file-permissions';
|
||||||
|
|
||||||
|
|
@ -68,7 +69,10 @@ export function spawnTerminalAgent(opts: {
|
||||||
}
|
}
|
||||||
const script = opts.scriptPath || resolveTerminalAgentScript();
|
const script = opts.scriptPath || resolveTerminalAgentScript();
|
||||||
if (!script || !fs.existsSync(script)) return null;
|
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(),
|
cwd: opts.cwd || process.cwd(),
|
||||||
env: {
|
env: {
|
||||||
...process.env,
|
...process.env,
|
||||||
|
|
@ -77,6 +81,7 @@ export function spawnTerminalAgent(opts: {
|
||||||
...(opts.extraEnv || {}),
|
...(opts.extraEnv || {}),
|
||||||
},
|
},
|
||||||
stdio: ['ignore', 'ignore', 'ignore'],
|
stdio: ['ignore', 'ignore', 'ignore'],
|
||||||
|
windowsHide: true,
|
||||||
});
|
});
|
||||||
proc.unref?.();
|
proc.unref?.();
|
||||||
return proc.pid ?? null;
|
return proc.pid ?? null;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue