mirror of
https://github.com/google-gemini/gemini-cli
synced 2026-04-21 13:37:17 +00:00
fix(cli): route SEA relaunch flags through NODE_OPTIONS
This commit is contained in:
parent
22fb83320e
commit
f590a2c55e
4 changed files with 132 additions and 24 deletions
|
|
@ -9,6 +9,7 @@
|
|||
import { spawn } from 'node:child_process';
|
||||
import os from 'node:os';
|
||||
import v8 from 'node:v8';
|
||||
import { buildRelaunchSpawnSpec } from './src/utils/relaunchSpawnSpec.js';
|
||||
|
||||
// --- Global Entry Point ---
|
||||
|
||||
|
|
@ -74,17 +75,14 @@ async function run() {
|
|||
// --- Lightweight Parent Process / Daemon ---
|
||||
// We avoid importing heavy dependencies here to save ~1.5s of startup time.
|
||||
|
||||
const nodeArgs: string[] = [...process.execArgv];
|
||||
const scriptArgs = process.argv.slice(2);
|
||||
|
||||
const memoryArgs = await getMemoryNodeArgs();
|
||||
nodeArgs.push(...memoryArgs);
|
||||
|
||||
const script = process.argv[1];
|
||||
nodeArgs.push(script);
|
||||
nodeArgs.push(...scriptArgs);
|
||||
|
||||
const newEnv = { ...process.env, GEMINI_CLI_NO_RELAUNCH: 'true' };
|
||||
const { args: relaunchArgs, env: newEnv } = buildRelaunchSpawnSpec({
|
||||
additionalNodeArgs: memoryArgs,
|
||||
additionalScriptArgs: [],
|
||||
argv: process.argv,
|
||||
env: process.env,
|
||||
execArgv: process.execArgv,
|
||||
});
|
||||
const RELAUNCH_EXIT_CODE = 199;
|
||||
let latestAdminSettings: unknown = undefined;
|
||||
|
||||
|
|
@ -97,7 +95,7 @@ async function run() {
|
|||
const runner = () => {
|
||||
process.stdin.pause();
|
||||
|
||||
const child = spawn(process.execPath, nodeArgs, {
|
||||
const child = spawn(process.execPath, relaunchArgs, {
|
||||
stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
|
||||
env: newEnv,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import {
|
|||
writeToStderr,
|
||||
type AdminControlsSettings,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { buildRelaunchSpawnSpec } from './relaunchSpawnSpec.js';
|
||||
|
||||
export async function relaunchOnExitCode(runner: () => Promise<number>) {
|
||||
while (true) {
|
||||
|
|
@ -43,19 +44,13 @@ export async function relaunchAppInChildProcess(
|
|||
let latestAdminSettings = remoteAdminSettings;
|
||||
|
||||
const runner = () => {
|
||||
// process.argv is [node, script, ...args]
|
||||
// We want to construct [ ...nodeArgs, script, ...scriptArgs]
|
||||
const script = process.argv[1];
|
||||
const scriptArgs = process.argv.slice(2);
|
||||
|
||||
const nodeArgs = [
|
||||
...process.execArgv,
|
||||
...additionalNodeArgs,
|
||||
script,
|
||||
...additionalScriptArgs,
|
||||
...scriptArgs,
|
||||
];
|
||||
const newEnv = { ...process.env, GEMINI_CLI_NO_RELAUNCH: 'true' };
|
||||
const { args: nodeArgs, env: newEnv } = buildRelaunchSpawnSpec({
|
||||
additionalNodeArgs,
|
||||
additionalScriptArgs,
|
||||
argv: process.argv,
|
||||
env: process.env,
|
||||
execArgv: process.execArgv,
|
||||
});
|
||||
|
||||
// The parent process should not be reading from stdin while the child is running.
|
||||
process.stdin.pause();
|
||||
|
|
|
|||
57
packages/cli/src/utils/relaunchSpawnSpec.test.ts
Normal file
57
packages/cli/src/utils/relaunchSpawnSpec.test.ts
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright 2026 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { buildRelaunchSpawnSpec } from './relaunchSpawnSpec.js';
|
||||
|
||||
describe('buildRelaunchSpawnSpec', () => {
|
||||
it('preserves node-style relaunch arguments for source installs', () => {
|
||||
const { args, env } = buildRelaunchSpawnSpec({
|
||||
additionalNodeArgs: ['--max-old-space-size=4096'],
|
||||
additionalScriptArgs: ['--model', 'gemini-2.5-pro'],
|
||||
argv: ['/usr/bin/node', '/app/cli.js', 'command', '--verbose'],
|
||||
env: { PATH: '/usr/bin' },
|
||||
execArgv: ['--inspect=9229'],
|
||||
});
|
||||
|
||||
expect(args).toEqual([
|
||||
'--inspect=9229',
|
||||
'--max-old-space-size=4096',
|
||||
'/app/cli.js',
|
||||
'--model',
|
||||
'gemini-2.5-pro',
|
||||
'command',
|
||||
'--verbose',
|
||||
]);
|
||||
expect(env).toMatchObject({
|
||||
GEMINI_CLI_NO_RELAUNCH: 'true',
|
||||
PATH: '/usr/bin',
|
||||
});
|
||||
expect(env['NODE_OPTIONS']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('moves node flags into NODE_OPTIONS for standalone binaries', () => {
|
||||
const { args, env } = buildRelaunchSpawnSpec({
|
||||
additionalNodeArgs: ['--max-old-space-size=4096'],
|
||||
additionalScriptArgs: ['--model', 'gemini-2.5-pro'],
|
||||
argv: ['/tmp/gemini', '/tmp/gemini', '--verbose'],
|
||||
env: {
|
||||
IS_BINARY: 'true',
|
||||
NODE_OPTIONS: '--trace-warnings',
|
||||
PATH: '/usr/bin',
|
||||
},
|
||||
execArgv: ['--inspect=9229'],
|
||||
});
|
||||
|
||||
expect(args).toEqual(['--model', 'gemini-2.5-pro', '--verbose']);
|
||||
expect(env).toMatchObject({
|
||||
GEMINI_CLI_NO_RELAUNCH: 'true',
|
||||
IS_BINARY: 'true',
|
||||
NODE_OPTIONS: '--trace-warnings --max-old-space-size=4096',
|
||||
PATH: '/usr/bin',
|
||||
});
|
||||
});
|
||||
});
|
||||
58
packages/cli/src/utils/relaunchSpawnSpec.ts
Normal file
58
packages/cli/src/utils/relaunchSpawnSpec.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* @license
|
||||
* Copyright 2026 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
export interface BuildRelaunchSpawnSpecParams {
|
||||
additionalNodeArgs: string[];
|
||||
additionalScriptArgs: string[];
|
||||
argv: string[];
|
||||
env: NodeJS.ProcessEnv;
|
||||
execArgv: string[];
|
||||
}
|
||||
|
||||
export interface RelaunchSpawnSpec {
|
||||
args: string[];
|
||||
env: NodeJS.ProcessEnv;
|
||||
}
|
||||
|
||||
export function buildRelaunchSpawnSpec({
|
||||
additionalNodeArgs,
|
||||
additionalScriptArgs,
|
||||
argv,
|
||||
env,
|
||||
execArgv,
|
||||
}: BuildRelaunchSpawnSpecParams): RelaunchSpawnSpec {
|
||||
const scriptArgs = argv.slice(2);
|
||||
const newEnv: NodeJS.ProcessEnv = {
|
||||
...env,
|
||||
GEMINI_CLI_NO_RELAUNCH: 'true',
|
||||
};
|
||||
|
||||
if (env['IS_BINARY'] === 'true') {
|
||||
if (additionalNodeArgs.length > 0) {
|
||||
newEnv['NODE_OPTIONS'] = [newEnv['NODE_OPTIONS'], ...additionalNodeArgs]
|
||||
.filter(Boolean)
|
||||
.join(' ');
|
||||
}
|
||||
|
||||
return {
|
||||
args: [...additionalScriptArgs, ...scriptArgs],
|
||||
env: newEnv,
|
||||
};
|
||||
}
|
||||
|
||||
const script = argv[1];
|
||||
|
||||
return {
|
||||
args: [
|
||||
...execArgv,
|
||||
...additionalNodeArgs,
|
||||
script,
|
||||
...additionalScriptArgs,
|
||||
...scriptArgs,
|
||||
],
|
||||
env: newEnv,
|
||||
};
|
||||
}
|
||||
Loading…
Reference in a new issue