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

@@ -11,20 +11,69 @@ import type {
AuthType,
ChatCompressionSettings,
} from '@qwen-code/qwen-code-core';
import {
DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD,
} from '@qwen-code/qwen-code-core';
import type { CustomTheme } from '../ui/themes/theme.js';
export type SettingsType =
| 'boolean'
| 'string'
| 'number'
| 'array'
| 'object'
| 'enum';
export type SettingsValue =
| boolean
| string
| number
| string[]
| object
| undefined;
/**
* Setting datatypes that "toggle" through a fixed list of options
* (e.g. an enum or true/false) rather than allowing for free form input
* (like a number or string).
*/
export const TOGGLE_TYPES: ReadonlySet<SettingsType | undefined> = new Set([
'boolean',
'enum',
]);
export interface SettingEnumOption {
value: string | number;
label: string;
}
export enum MergeStrategy {
// Replace the old value with the new value. This is the default.
REPLACE = 'replace',
// Concatenate arrays.
CONCAT = 'concat',
// Merge arrays, ensuring unique values.
UNION = 'union',
// Shallow merge objects.
SHALLOW_MERGE = 'shallow_merge',
}
export interface SettingDefinition {
type: 'boolean' | 'string' | 'number' | 'array' | 'object';
type: SettingsType;
label: string;
category: string;
requiresRestart: boolean;
default: boolean | string | number | string[] | object | undefined;
default: SettingsValue;
description?: string;
parentKey?: string;
childKey?: string;
key?: string;
properties?: SettingsSchema;
showInDialog?: boolean;
mergeStrategy?: MergeStrategy;
/** Enum type options */
options?: readonly SettingEnumOption[];
}
export interface SettingsSchema {
@@ -39,7 +88,7 @@ export type DnsResolutionOrder = 'ipv4first' | 'verbatim';
* The structure of this object defines the structure of the `Settings` type.
* `as const` is crucial for TypeScript to infer the most specific types possible.
*/
export const SETTINGS_SCHEMA = {
const SETTINGS_SCHEMA = {
// Maintained for compatibility/criticality
mcpServers: {
type: 'object',
@@ -49,6 +98,7 @@ export const SETTINGS_SCHEMA = {
default: {} as Record<string, MCPServerConfig>,
description: 'Configuration for MCP servers.',
showInDialog: false,
mergeStrategy: MergeStrategy.SHALLOW_MERGE,
},
general: {
@@ -137,6 +187,30 @@ export const SETTINGS_SCHEMA = {
},
},
},
output: {
type: 'object',
label: 'Output',
category: 'General',
requiresRestart: false,
default: {},
description: 'Settings for the CLI output.',
showInDialog: false,
properties: {
format: {
type: 'enum',
label: 'Output Format',
category: 'General',
requiresRestart: false,
default: 'text',
description: 'The format of the CLI output.',
showInDialog: true,
options: [
{ value: 'text', label: 'Text' },
{ value: 'json', label: 'JSON' },
],
},
},
},
ui: {
type: 'object',
@@ -174,6 +248,16 @@ export const SETTINGS_SCHEMA = {
description: 'Hide the window title bar',
showInDialog: true,
},
showStatusInTitle: {
type: 'boolean',
label: 'Show Status in Title',
category: 'UI',
requiresRestart: false,
default: false,
description:
'Show Gemini CLI status and thoughts in the terminal window title',
showInDialog: true,
},
hideTips: {
type: 'boolean',
label: 'Hide Tips',
@@ -192,6 +276,55 @@ export const SETTINGS_SCHEMA = {
description: 'Hide the application banner',
showInDialog: true,
},
hideContextSummary: {
type: 'boolean',
label: 'Hide Context Summary',
category: 'UI',
requiresRestart: false,
default: false,
description:
'Hide the context summary (GEMINI.md, MCP servers) above the input.',
showInDialog: true,
},
footer: {
type: 'object',
label: 'Footer',
category: 'UI',
requiresRestart: false,
default: {},
description: 'Settings for the footer.',
showInDialog: false,
properties: {
hideCWD: {
type: 'boolean',
label: 'Hide CWD',
category: 'UI',
requiresRestart: false,
default: false,
description:
'Hide the current working directory path in the footer.',
showInDialog: true,
},
hideSandboxStatus: {
type: 'boolean',
label: 'Hide Sandbox Status',
category: 'UI',
requiresRestart: false,
default: false,
description: 'Hide the sandbox status indicator in the footer.',
showInDialog: true,
},
hideModelInfo: {
type: 'boolean',
label: 'Hide Model Info',
category: 'UI',
requiresRestart: false,
default: false,
description: 'Hide the model name and context usage in the footer.',
showInDialog: true,
},
},
},
hideFooter: {
type: 'boolean',
label: 'Hide Footer',
@@ -219,6 +352,34 @@ export const SETTINGS_SCHEMA = {
description: 'Show line numbers in the chat.',
showInDialog: true,
},
showCitations: {
type: 'boolean',
label: 'Show Citations',
category: 'UI',
requiresRestart: false,
default: false,
description: 'Show citations for generated text in the chat.',
showInDialog: true,
},
customWittyPhrases: {
type: 'array',
label: 'Custom Witty Phrases',
category: 'UI',
requiresRestart: false,
default: [] as string[],
description: 'Custom witty phrases to display during loading.',
showInDialog: false,
},
enableWelcomeBack: {
type: 'boolean',
label: 'Enable Welcome Back',
category: 'UI',
requiresRestart: false,
default: true,
description:
'Show welcome back dialog when returning to a project with conversation history.',
showInDialog: true,
},
accessibility: {
type: 'object',
label: 'Accessibility',
@@ -361,15 +522,86 @@ export const SETTINGS_SCHEMA = {
description: 'Chat compression settings.',
showInDialog: false,
},
sessionTokenLimit: {
type: 'number',
label: 'Session Token Limit',
category: 'Model',
requiresRestart: false,
default: undefined as number | undefined,
description: 'The maximum number of tokens allowed in a session.',
showInDialog: false,
},
skipNextSpeakerCheck: {
type: 'boolean',
label: 'Skip Next Speaker Check',
category: 'Model',
requiresRestart: false,
default: false,
default: true,
description: 'Skip the next speaker check.',
showInDialog: true,
},
skipLoopDetection: {
type: 'boolean',
label: 'Skip Loop Detection',
category: 'Model',
requiresRestart: false,
default: false,
description: 'Disable all loop detection checks (streaming and LLM).',
showInDialog: true,
},
enableOpenAILogging: {
type: 'boolean',
label: 'Enable OpenAI Logging',
category: 'Model',
requiresRestart: false,
default: false,
description: 'Enable OpenAI logging.',
showInDialog: true,
},
generationConfig: {
type: 'object',
label: 'Generation Configuration',
category: 'Model',
requiresRestart: false,
default: undefined as Record<string, unknown> | undefined,
description: 'Generation configuration settings.',
showInDialog: false,
properties: {
timeout: {
type: 'number',
label: 'Timeout',
category: 'Generation Configuration',
requiresRestart: false,
default: undefined as number | undefined,
description: 'Request timeout in milliseconds.',
parentKey: 'generationConfig',
childKey: 'timeout',
showInDialog: true,
},
maxRetries: {
type: 'number',
label: 'Max Retries',
category: 'Generation Configuration',
requiresRestart: false,
default: undefined as number | undefined,
description: 'Maximum number of retries for failed requests.',
parentKey: 'generationConfig',
childKey: 'maxRetries',
showInDialog: true,
},
disableCacheControl: {
type: 'boolean',
label: 'Disable Cache Control',
category: 'Generation Configuration',
requiresRestart: false,
default: false,
description: 'Disable cache control for DashScope providers.',
parentKey: 'generationConfig',
childKey: 'disableCacheControl',
showInDialog: true,
},
},
},
},
},
@@ -418,6 +650,7 @@ export const SETTINGS_SCHEMA = {
description:
'Additional directories to include in the workspace context. Missing directories will be skipped with a warning.',
showInDialog: false,
mergeStrategy: MergeStrategy.CONCAT,
},
loadMemoryFromIncludeDirectories: {
type: 'boolean',
@@ -446,7 +679,7 @@ export const SETTINGS_SCHEMA = {
description: 'Respect .gitignore files when searching',
showInDialog: true,
},
respectGeminiIgnore: {
respectQwenIgnore: {
type: 'boolean',
label: 'Respect .qwenignore',
category: 'Context',
@@ -497,14 +730,54 @@ export const SETTINGS_SCHEMA = {
'Sandbox execution environment (can be a boolean or a path string).',
showInDialog: false,
},
usePty: {
type: 'boolean',
label: 'Use node-pty for Shell Execution',
shell: {
type: 'object',
label: 'Shell',
category: 'Tools',
requiresRestart: true,
requiresRestart: false,
default: {},
description: 'Settings for shell execution.',
showInDialog: false,
properties: {
enableInteractiveShell: {
type: 'boolean',
label: 'Enable Interactive Shell',
category: 'Tools',
requiresRestart: true,
default: false,
description:
'Use node-pty for an interactive shell experience. Fallback to child_process still applies.',
showInDialog: true,
},
pager: {
type: 'string',
label: 'Pager',
category: 'Tools',
requiresRestart: false,
default: 'cat' as string | undefined,
description:
'The pager command to use for shell output. Defaults to `cat`.',
showInDialog: false,
},
showColor: {
type: 'boolean',
label: 'Show Color',
category: 'Tools',
requiresRestart: false,
default: false,
description: 'Show color in shell output.',
showInDialog: true,
},
},
},
autoAccept: {
type: 'boolean',
label: 'Auto Accept',
category: 'Tools',
requiresRestart: false,
default: false,
description:
'Use node-pty for shell command execution. Fallback to child_process still applies.',
'Automatically accept and execute tool calls that are considered safe (e.g., read-only operations).',
showInDialog: true,
},
core: {
@@ -534,6 +807,17 @@ export const SETTINGS_SCHEMA = {
default: undefined as string[] | undefined,
description: 'Tool names to exclude from discovery.',
showInDialog: false,
mergeStrategy: MergeStrategy.UNION,
},
approvalMode: {
type: 'string',
label: 'Default Approval Mode',
category: 'Tools',
requiresRestart: false,
default: 'default',
description:
'Default approval mode for tool usage. Valid values: plan, default, auto-edit, yolo.',
showInDialog: true,
},
discoveryCommand: {
type: 'string',
@@ -558,11 +842,39 @@ export const SETTINGS_SCHEMA = {
label: 'Use Ripgrep',
category: 'Tools',
requiresRestart: false,
default: false,
default: true,
description:
'Use ripgrep for file content search instead of the fallback implementation. Provides faster search performance.',
showInDialog: true,
},
enableToolOutputTruncation: {
type: 'boolean',
label: 'Enable Tool Output Truncation',
category: 'General',
requiresRestart: true,
default: true,
description: 'Enable truncation of large tool outputs.',
showInDialog: true,
},
truncateToolOutputThreshold: {
type: 'number',
label: 'Tool Output Truncation Threshold',
category: 'General',
requiresRestart: true,
default: DEFAULT_TRUNCATE_TOOL_OUTPUT_THRESHOLD,
description:
'Truncate tool output if it is larger than this many characters. Set to -1 to disable.',
showInDialog: true,
},
truncateToolOutputLines: {
type: 'number',
label: 'Tool Output Truncation Lines',
category: 'General',
requiresRestart: true,
default: DEFAULT_TRUNCATE_TOOL_OUTPUT_LINES,
description: 'The number of lines to keep when truncating tool output.',
showInDialog: true,
},
},
},
@@ -590,7 +902,7 @@ export const SETTINGS_SCHEMA = {
category: 'MCP',
requiresRestart: true,
default: undefined as string[] | undefined,
description: 'A whitelist of MCP servers to allow.',
description: 'A list of MCP servers to allow.',
showInDialog: false,
},
excluded: {
@@ -599,12 +911,20 @@ export const SETTINGS_SCHEMA = {
category: 'MCP',
requiresRestart: true,
default: undefined as string[] | undefined,
description: 'A blacklist of MCP servers to exclude.',
description: 'A list of MCP servers to exclude.',
showInDialog: false,
},
},
},
useSmartEdit: {
type: 'boolean',
label: 'Use Smart Edit',
category: 'Advanced',
requiresRestart: false,
default: false,
description: 'Enable the smart-edit tool instead of the replace tool.',
showInDialog: false,
},
security: {
type: 'object',
label: 'Security',
@@ -623,20 +943,11 @@ export const SETTINGS_SCHEMA = {
description: 'Settings for folder trust.',
showInDialog: false,
properties: {
featureEnabled: {
type: 'boolean',
label: 'Folder Trust Feature',
category: 'Security',
requiresRestart: false,
default: false,
description: 'Enable folder trust feature for enhanced security.',
showInDialog: true,
},
enabled: {
type: 'boolean',
label: 'Folder Trust',
category: 'Security',
requiresRestart: false,
requiresRestart: true,
default: false,
description: 'Setting to track whether Folder trust is enabled.',
showInDialog: true,
@@ -661,6 +972,16 @@ export const SETTINGS_SCHEMA = {
description: 'The currently selected authentication type.',
showInDialog: false,
},
enforcedType: {
type: 'string',
label: 'Enforced Auth Type',
category: 'Advanced',
requiresRestart: true,
default: undefined as AuthType | undefined,
description:
'The required auth type. If this does not match the selected auth type, the user will be prompted to re-authenticate.',
showInDialog: false,
},
useExternal: {
type: 'boolean',
label: 'Use External Auth',
@@ -710,6 +1031,7 @@ export const SETTINGS_SCHEMA = {
default: ['DEBUG', 'DEBUG_MODE'] as string[],
description: 'Environment variables to exclude from project context.',
showInDialog: false,
mergeStrategy: MergeStrategy.UNION,
},
bugCommand: {
type: 'object',
@@ -720,6 +1042,16 @@ export const SETTINGS_SCHEMA = {
description: 'Configuration for the bug report command.',
showInDialog: false,
},
tavilyApiKey: {
type: 'string',
label: 'Tavily API Key',
category: 'Advanced',
requiresRestart: false,
default: undefined as string | undefined,
description:
'The API key for the Tavily API. Required to enable the web_search tool functionality.',
showInDialog: false,
},
},
},
@@ -737,7 +1069,7 @@ export const SETTINGS_SCHEMA = {
label: 'Extension Management',
category: 'Experimental',
requiresRestart: true,
default: false,
default: true,
description: 'Enable extension management features.',
showInDialog: false,
},
@@ -781,6 +1113,7 @@ export const SETTINGS_SCHEMA = {
default: [] as string[],
description: 'List of disabled extensions.',
showInDialog: false,
mergeStrategy: MergeStrategy.UNION,
},
workspacesWithMigrationNudge: {
type: 'array',
@@ -791,135 +1124,34 @@ export const SETTINGS_SCHEMA = {
description:
'List of workspaces for which the migration nudge has been shown.',
showInDialog: false,
mergeStrategy: MergeStrategy.UNION,
},
},
},
contentGenerator: {
type: 'object',
label: 'Content Generator',
category: 'General',
requiresRestart: false,
default: undefined as Record<string, unknown> | undefined,
description: 'Content generator settings.',
showInDialog: false,
properties: {
timeout: {
type: 'number',
label: 'Timeout',
category: 'Content Generator',
requiresRestart: false,
default: undefined as number | undefined,
description: 'Request timeout in milliseconds.',
parentKey: 'contentGenerator',
childKey: 'timeout',
showInDialog: true,
},
maxRetries: {
type: 'number',
label: 'Max Retries',
category: 'Content Generator',
requiresRestart: false,
default: undefined as number | undefined,
description: 'Maximum number of retries for failed requests.',
parentKey: 'contentGenerator',
childKey: 'maxRetries',
showInDialog: true,
},
disableCacheControl: {
type: 'boolean',
label: 'Disable Cache Control',
category: 'Content Generator',
requiresRestart: false,
default: false,
description: 'Disable cache control for DashScope providers.',
parentKey: 'contentGenerator',
childKey: 'disableCacheControl',
showInDialog: true,
},
},
},
enableOpenAILogging: {
type: 'boolean',
label: 'Enable OpenAI Logging',
category: 'General',
requiresRestart: false,
default: false,
description: 'Enable OpenAI logging.',
showInDialog: true,
},
sessionTokenLimit: {
type: 'number',
label: 'Session Token Limit',
category: 'General',
requiresRestart: false,
default: undefined as number | undefined,
description: 'The maximum number of tokens allowed in a session.',
showInDialog: false,
},
systemPromptMappings: {
type: 'object',
label: 'System Prompt Mappings',
category: 'General',
requiresRestart: false,
default: undefined as Record<string, string> | undefined,
description: 'Mappings of system prompts to model names.',
showInDialog: false,
},
tavilyApiKey: {
type: 'string',
label: 'Tavily API Key',
category: 'General',
requiresRestart: false,
default: undefined as string | undefined,
description: 'The API key for the Tavily API.',
showInDialog: false,
},
skipNextSpeakerCheck: {
type: 'boolean',
label: 'Skip Next Speaker Check',
category: 'General',
requiresRestart: false,
default: false,
description: 'Skip the next speaker check.',
showInDialog: true,
},
skipLoopDetection: {
type: 'boolean',
label: 'Skip Loop Detection',
category: 'General',
requiresRestart: false,
default: false,
description: 'Disable all loop detection checks (streaming and LLM).',
showInDialog: true,
},
approvalMode: {
type: 'string',
label: 'Default Approval Mode',
category: 'General',
requiresRestart: false,
default: 'default',
description:
'Default approval mode for tool usage. Valid values: plan, default, auto-edit, yolo.',
showInDialog: true,
},
enableWelcomeBack: {
type: 'boolean',
label: 'Enable Welcome Back',
category: 'UI',
requiresRestart: false,
default: true,
description:
'Show welcome back dialog when returning to a project with conversation history.',
showInDialog: true,
},
} as const;
} as const satisfies SettingsSchema;
export type SettingsSchemaType = typeof SETTINGS_SCHEMA;
export function getSettingsSchema(): SettingsSchemaType {
return SETTINGS_SCHEMA;
}
type InferSettings<T extends SettingsSchema> = {
-readonly [K in keyof T]?: T[K] extends { properties: SettingsSchema }
? InferSettings<T[K]['properties']>
: T[K]['default'] extends boolean
? boolean
: T[K]['default'];
: T[K]['type'] extends 'enum'
? T[K]['options'] extends readonly SettingEnumOption[]
? T[K]['options'][number]['value']
: T[K]['default']
: T[K]['default'] extends boolean
? boolean
: T[K]['default'];
};
export type Settings = InferSettings<typeof SETTINGS_SCHEMA>;
export type Settings = InferSettings<SettingsSchemaType>;
export interface FooterSettings {
hideCWD?: boolean;
hideSandboxStatus?: boolean;
hideModelInfo?: boolean;
}