fix(runtime): hide cli child windows by default
This commit is contained in:
parent
d5f87a286a
commit
5610e13b98
2 changed files with 39 additions and 6 deletions
|
|
@ -242,12 +242,16 @@ export function killTrackedCliProcesses(signal: NodeJS.Signals = 'SIGKILL'): voi
|
|||
}
|
||||
}
|
||||
|
||||
/** Merge CLI_ENV_DEFAULTS into spawn/exec options.env (or process.env if absent). */
|
||||
function withCliEnv<T extends { env?: NodeJS.ProcessEnv | Record<string, string | undefined> }>(
|
||||
options: T
|
||||
): T {
|
||||
/** Apply shared CLI process defaults without overriding explicit caller choices. */
|
||||
function withCliProcessDefaults<
|
||||
T extends {
|
||||
env?: NodeJS.ProcessEnv | Record<string, string | undefined>;
|
||||
windowsHide?: boolean;
|
||||
},
|
||||
>(options: T): T & { windowsHide: boolean } {
|
||||
return {
|
||||
...options,
|
||||
windowsHide: options.windowsHide ?? true,
|
||||
env: { ...(options.env ?? process.env), ...CLI_ENV_DEFAULTS },
|
||||
};
|
||||
}
|
||||
|
|
@ -270,7 +274,7 @@ export async function execCli(
|
|||
);
|
||||
}
|
||||
const target = binaryPath;
|
||||
const opts = withCliEnv(options);
|
||||
const opts = withCliProcessDefaults(options);
|
||||
const directLauncher = resolveDirectWindowsLauncher(target);
|
||||
if (directLauncher) {
|
||||
const result = await execFileAsync(
|
||||
|
|
@ -316,7 +320,7 @@ export function spawnCli(
|
|||
args: string[],
|
||||
options: SpawnOptions = {}
|
||||
): ReturnType<typeof spawn> {
|
||||
const opts = withCliEnv(options);
|
||||
const opts = withCliProcessDefaults(options);
|
||||
const directLauncher = resolveDirectWindowsLauncher(binaryPath);
|
||||
if (directLauncher) {
|
||||
const directOpts = { ...opts };
|
||||
|
|
|
|||
|
|
@ -134,6 +134,18 @@ describe('cli child process helpers', () => {
|
|||
expect(result).toEqual({} as any);
|
||||
});
|
||||
|
||||
it('hides spawned CLI windows by default but preserves explicit opt-out', () => {
|
||||
setPlatform('win32');
|
||||
const spawnMock = child.spawn as unknown as Mock;
|
||||
spawnMock.mockReturnValue({} as any);
|
||||
|
||||
spawnCli('C:\\bin\\claude.exe', ['--version']);
|
||||
expect(spawnMock.mock.calls[0][2]).toMatchObject({ windowsHide: true });
|
||||
|
||||
spawnCli('C:\\bin\\claude.exe', ['--version'], { windowsHide: false });
|
||||
expect(spawnMock.mock.calls[1][2]).toMatchObject({ windowsHide: false });
|
||||
});
|
||||
|
||||
it('falls back to shell when spawn throws EINVAL', () => {
|
||||
setPlatform('win32');
|
||||
const error: any = new Error('spawn EINVAL');
|
||||
|
|
@ -296,6 +308,23 @@ describe('cli child process helpers', () => {
|
|||
expect(result.stdout).toBe('ok');
|
||||
});
|
||||
|
||||
it('hides exec CLI windows by default but preserves explicit opt-out', async () => {
|
||||
setPlatform('win32');
|
||||
const execFileMock = child.execFile as unknown as Mock;
|
||||
execFileMock.mockImplementation(
|
||||
(_cmd: string, _args: string[], _opts: unknown, cb: ExecCallback) => {
|
||||
cb(null, 'ok', '');
|
||||
return {} as any;
|
||||
}
|
||||
);
|
||||
|
||||
await execCli('C:\\bin\\claude.exe', ['--version']);
|
||||
expect(execFileMock.mock.calls[0][2]).toMatchObject({ windowsHide: true });
|
||||
|
||||
await execCli('C:\\bin\\claude.exe', ['--version'], { windowsHide: false });
|
||||
expect(execFileMock.mock.calls[1][2]).toMatchObject({ windowsHide: false });
|
||||
});
|
||||
|
||||
it('skips straight to shell for Windows cmd launchers', async () => {
|
||||
setPlatform('win32');
|
||||
const execFileMock = child.execFile as unknown as Mock;
|
||||
|
|
|
|||
Loading…
Reference in a new issue