Sync upstream Gemini-CLI v0.8.2 (#838)

This commit is contained in:
tanzhenxin
2025-10-23 09:27:04 +08:00
committed by GitHub
parent 096fabb5d6
commit eb95c131be
644 changed files with 70389 additions and 23709 deletions

View File

@@ -19,6 +19,7 @@ import { promisify } from 'node:util';
import type { Config, SandboxConfig } from '@qwen-code/qwen-code-core';
import { FatalSandboxError } from '@qwen-code/qwen-code-core';
import { ConsolePatcher } from '../ui/utils/ConsolePatcher.js';
import { randomBytes } from 'node:crypto';
const execAsync = promisify(exec);
@@ -188,7 +189,7 @@ export async function start_sandbox(
nodeArgs: string[] = [],
cliConfig?: Config,
cliArgs: string[] = [],
) {
): Promise<number> {
const patcher = new ConsolePatcher({
debugMode: cliConfig?.getDebugMode() || !!process.env['DEBUG'],
stderr: true,
@@ -339,11 +340,17 @@ export async function start_sandbox(
);
}
// spawn child and let it inherit stdio
process.stdin.pause();
sandboxProcess = spawn(config.command, args, {
stdio: 'inherit',
});
await new Promise((resolve) => sandboxProcess?.on('close', resolve));
return;
return new Promise((resolve, reject) => {
sandboxProcess?.on('error', reject);
sandboxProcess?.on('close', (code) => {
process.stdin.resume();
resolve(code ?? 1);
});
});
}
console.error(`hopping into sandbox (command: ${config.command}) ...`);
@@ -424,6 +431,9 @@ export async function start_sandbox(
args.push('-t');
}
// allow access to host.docker.internal
args.push('--add-host', 'host.docker.internal:host-gateway');
// mount current directory as working directory in sandbox (set via --workdir)
args.push('--volume', `${workdir}:${containerWorkdir}`);
@@ -549,20 +559,39 @@ export async function start_sandbox(
}
}
// name container after image, plus numeric suffix to avoid conflicts
// name container after image, plus random suffix to avoid conflicts
const imageName = parseImageName(image);
let index = 0;
const containerNameCheck = execSync(
`${config.command} ps -a --format "{{.Names}}"`,
)
.toString()
.trim();
while (containerNameCheck.includes(`${imageName}-${index}`)) {
index++;
const isIntegrationTest =
process.env['GEMINI_CLI_INTEGRATION_TEST'] === 'true';
let containerName;
if (isIntegrationTest) {
containerName = `gemini-cli-integration-test-${randomBytes(4).toString(
'hex',
)}`;
console.log(`ContainerName: ${containerName}`);
} else {
let index = 0;
const containerNameCheck = execSync(
`${config.command} ps -a --format "{{.Names}}"`,
)
.toString()
.trim();
while (containerNameCheck.includes(`${imageName}-${index}`)) {
index++;
}
containerName = `${imageName}-${index}`;
console.log(`ContainerName (regular): ${containerName}`);
}
const containerName = `${imageName}-${index}`;
args.push('--name', containerName, '--hostname', containerName);
// copy GEMINI_CLI_TEST_VAR for integration tests
if (process.env['GEMINI_CLI_TEST_VAR']) {
args.push(
'--env',
`GEMINI_CLI_TEST_VAR=${process.env['GEMINI_CLI_TEST_VAR']}`,
);
}
// copy GEMINI_API_KEY(s)
if (process.env['GEMINI_API_KEY']) {
args.push('--env', `GEMINI_API_KEY=${process.env['GEMINI_API_KEY']}`);
@@ -805,22 +834,25 @@ export async function start_sandbox(
}
// spawn child and let it inherit stdio
process.stdin.pause();
sandboxProcess = spawn(config.command, args, {
stdio: 'inherit',
});
sandboxProcess.on('error', (err) => {
console.error('Sandbox process error:', err);
});
return new Promise<number>((resolve, reject) => {
sandboxProcess.on('error', (err) => {
console.error('Sandbox process error:', err);
reject(err);
});
await new Promise<void>((resolve) => {
sandboxProcess?.on('close', (code, signal) => {
if (code !== 0) {
process.stdin.resume();
if (code !== 0 && code !== null) {
console.log(
`Sandbox process exited with code: ${code}, signal: ${signal}`,
);
}
resolve();
resolve(code ?? 1);
});
});
} finally {