Merge tag 'v0.1.21' of github.com:google-gemini/gemini-cli into chore/sync-gemini-cli-v0.1.21

This commit is contained in:
mingholy.lmh
2025-08-20 22:24:50 +08:00
163 changed files with 8812 additions and 4098 deletions

View File

@@ -36,6 +36,8 @@ import { getCliVersion } from '../utils/version.js';
import { loadSandboxConfig } from './sandboxConfig.js';
import { resolvePath } from '../utils/resolvePath.js';
import { isWorkspaceTrusted } from './trustedFolders.js';
// Simple console logger for now - replace with actual logger if available
const logger = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -58,6 +60,7 @@ export interface CliArgs {
showMemoryUsage: boolean | undefined;
show_memory_usage: boolean | undefined;
yolo: boolean | undefined;
approvalMode: string | undefined;
telemetry: boolean | undefined;
checkpointing: boolean | undefined;
telemetryTarget: string | undefined;
@@ -68,7 +71,6 @@ export interface CliArgs {
experimentalAcp: boolean | undefined;
extensions: string[] | undefined;
listExtensions: boolean | undefined;
ideModeFeature: boolean | undefined;
openaiLogging: boolean | undefined;
openaiApiKey: string | undefined;
openaiBaseUrl: string | undefined;
@@ -153,6 +155,12 @@ export async function parseArguments(): Promise<CliArgs> {
'Automatically accept all actions (aka YOLO mode, see https://www.youtube.com/watch?v=xvFZjo5PgG0 for more details)?',
default: false,
})
.option('approval-mode', {
type: 'string',
choices: ['default', 'auto_edit', 'yolo'],
description:
'Set the approval mode: default (prompt for approval), auto_edit (auto-approve edit tools), yolo (auto-approve all tools)',
})
.option('telemetry', {
type: 'boolean',
description:
@@ -205,10 +213,6 @@ export async function parseArguments(): Promise<CliArgs> {
type: 'boolean',
description: 'List all available extensions and exit.',
})
.option('ide-mode-feature', {
type: 'boolean',
description: 'Run in IDE mode?',
})
.option('proxy', {
type: 'string',
description:
@@ -246,6 +250,11 @@ export async function parseArguments(): Promise<CliArgs> {
'Cannot use both --prompt (-p) and --prompt-interactive (-i) together',
);
}
if (argv.yolo && argv.approvalMode) {
throw new Error(
'Cannot use both --yolo (-y) and --approval-mode together. Use --approval-mode=yolo instead.',
);
}
return true;
}),
)
@@ -319,6 +328,7 @@ export async function loadCliConfig(
extensions: Extension[],
sessionId: string,
argv: CliArgs,
cwd: string = process.cwd(),
): Promise<Config> {
const debugMode =
argv.debug ||
@@ -329,12 +339,11 @@ export async function loadCliConfig(
const memoryImportFormat = settings.memoryImportFormat || 'tree';
const ideMode = settings.ideMode ?? false;
const ideModeFeature =
argv.ideModeFeature ?? settings.ideModeFeature ?? false;
const folderTrustFeature = settings.folderTrustFeature ?? false;
const folderTrustSetting = settings.folderTrust ?? false;
const folderTrustSetting = settings.folderTrust ?? true;
const folderTrust = folderTrustFeature && folderTrustSetting;
const trustedFolder = folderTrust ? isWorkspaceTrusted() : true;
const allExtensions = annotateActiveExtensions(
extensions,
@@ -374,7 +383,7 @@ export async function loadCliConfig(
(e) => e.contextFiles,
);
const fileService = new FileDiscoveryService(process.cwd());
const fileService = new FileDiscoveryService(cwd);
const fileFiltering = {
...DEFAULT_MEMORY_FILE_FILTERING_OPTIONS,
@@ -387,7 +396,7 @@ export async function loadCliConfig(
// Call the (now wrapper) loadHierarchicalGeminiMemory which calls the server's version
const { memoryContent, fileCount } = await loadHierarchicalGeminiMemory(
process.cwd(),
cwd,
settings.loadMemoryFromIncludeDirectories ? includeDirectories : [],
debugMode,
fileService,
@@ -399,20 +408,59 @@ export async function loadCliConfig(
let mcpServers = mergeMcpServers(settings, activeExtensions);
const question = argv.promptInteractive || argv.prompt || '';
const approvalMode =
argv.yolo || false ? ApprovalMode.YOLO : ApprovalMode.DEFAULT;
// Determine approval mode with backward compatibility
let approvalMode: ApprovalMode;
if (argv.approvalMode) {
// New --approval-mode flag takes precedence
switch (argv.approvalMode) {
case 'yolo':
approvalMode = ApprovalMode.YOLO;
break;
case 'auto_edit':
approvalMode = ApprovalMode.AUTO_EDIT;
break;
case 'default':
approvalMode = ApprovalMode.DEFAULT;
break;
default:
throw new Error(
`Invalid approval mode: ${argv.approvalMode}. Valid values are: yolo, auto_edit, default`,
);
}
} else {
// Fallback to legacy --yolo flag behavior
approvalMode =
argv.yolo || false ? ApprovalMode.YOLO : ApprovalMode.DEFAULT;
}
const interactive =
!!argv.promptInteractive || (process.stdin.isTTY && question.length === 0);
// In non-interactive and non-yolo mode, exclude interactive built in tools.
const extraExcludes =
!interactive && approvalMode !== ApprovalMode.YOLO
? [ShellTool.Name, EditTool.Name, WriteFileTool.Name]
: undefined;
// In non-interactive mode, exclude tools that require a prompt.
const extraExcludes: string[] = [];
if (!interactive && !argv.experimentalAcp) {
switch (approvalMode) {
case ApprovalMode.DEFAULT:
// In default non-interactive mode, all tools that require approval are excluded.
extraExcludes.push(ShellTool.Name, EditTool.Name, WriteFileTool.Name);
break;
case ApprovalMode.AUTO_EDIT:
// In auto-edit non-interactive mode, only tools that still require a prompt are excluded.
extraExcludes.push(ShellTool.Name);
break;
case ApprovalMode.YOLO:
// No extra excludes for YOLO mode.
break;
default:
// This should never happen due to validation earlier, but satisfies the linter
break;
}
}
const excludeTools = mergeExcludeTools(
settings,
activeExtensions,
extraExcludes,
extraExcludes.length > 0 ? extraExcludes : undefined,
);
const blockedMcpServers: Array<{ name: string; extensionName: string }> = [];
@@ -450,7 +498,7 @@ export async function loadCliConfig(
sessionId,
embeddingModel: DEFAULT_GEMINI_EMBEDDING_MODEL,
sandbox: sandboxConfig,
targetDir: process.cwd(),
targetDir: cwd,
includeDirectories,
loadMemoryFromIncludeDirectories:
settings.loadMemoryFromIncludeDirectories || false,
@@ -498,21 +546,20 @@ export async function loadCliConfig(
process.env.https_proxy ||
process.env.HTTP_PROXY ||
process.env.http_proxy,
cwd: process.cwd(),
cwd,
fileDiscoveryService: fileService,
bugCommand: settings.bugCommand,
model: argv.model || settings.model || DEFAULT_GEMINI_MODEL,
extensionContextFilePaths,
maxSessionTurns: settings.maxSessionTurns ?? -1,
sessionTokenLimit: settings.sessionTokenLimit ?? -1,
experimentalAcp: argv.experimentalAcp || false,
experimentalZedIntegration: argv.experimentalAcp || false,
listExtensions: argv.listExtensions || false,
extensions: allExtensions,
blockedMcpServers,
noBrowser: !!process.env.NO_BROWSER,
summarizeToolOutput: settings.summarizeToolOutput,
ideMode,
ideModeFeature,
enableOpenAILogging:
(typeof argv.openaiLogging === 'undefined'
? settings.enableOpenAILogging
@@ -537,6 +584,7 @@ export async function loadCliConfig(
folderTrustFeature,
folderTrust,
interactive,
trustedFolder,
});
}