sync gemini-cli 0.1.17

Co-Authored-By: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
Yiheng Xu
2025-08-05 16:44:06 +08:00
235 changed files with 16997 additions and 3736 deletions

View File

@@ -38,7 +38,6 @@ import { AuthInProgress } from './components/AuthInProgress.js';
import { EditorSettingsDialog } from './components/EditorSettingsDialog.js';
import { ShellConfirmationDialog } from './components/ShellConfirmationDialog.js';
import { Colors } from './colors.js';
import { Help } from './components/Help.js';
import { loadHierarchicalGeminiMemory } from '../config/config.js';
import { LoadedSettings } from '../config/settings.js';
import { Tips } from './components/Tips.js';
@@ -60,7 +59,7 @@ import {
FlashFallbackEvent,
logFlashFallback,
AuthType,
type OpenFiles,
type IdeContext,
ideContext,
} from '@qwen-code/qwen-code-core';
import { validateAuthMethod } from '../config/auth.js';
@@ -83,11 +82,12 @@ import {
isGenericQuotaExceededError,
UserTierId,
} from '@qwen-code/qwen-code-core';
import { checkForUpdates } from './utils/updateCheck.js';
import { UpdateObject } from './utils/updateCheck.js';
import ansiEscapes from 'ansi-escapes';
import { OverflowProvider } from './contexts/OverflowContext.js';
import { ShowMoreLines } from './components/ShowMoreLines.js';
import { PrivacyNotice } from './privacy/PrivacyNotice.js';
import { setUpdateHandler } from '../utils/handleAutoUpdate.js';
import { appEvents, AppEvent } from '../utils/events.js';
const CTRL_EXIT_PROMPT_DURATION_MS = 1000;
@@ -110,15 +110,16 @@ export const AppWrapper = (props: AppProps) => (
const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
const isFocused = useFocus();
useBracketedPaste();
const [updateMessage, setUpdateMessage] = useState<string | null>(null);
const [updateInfo, setUpdateInfo] = useState<UpdateObject | null>(null);
const { stdout } = useStdout();
const nightly = version.includes('nightly');
const { history, addItem, clearItems, loadHistory } = useHistory();
useEffect(() => {
checkForUpdates().then(setUpdateMessage);
}, []);
const cleanup = setUpdateHandler(addItem, setUpdateInfo);
return cleanup;
}, [addItem]);
const { history, addItem, clearItems, loadHistory } = useHistory();
const {
consoleMessages,
handleNewMessage,
@@ -144,7 +145,6 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
const [geminiMdFileCount, setGeminiMdFileCount] = useState<number>(0);
const [debugMessage, setDebugMessage] = useState<string>('');
const [showHelp, setShowHelp] = useState<boolean>(false);
const [themeError, setThemeError] = useState<string | null>(null);
const [authError, setAuthError] = useState<string | null>(null);
const [editorError, setEditorError] = useState<string | null>(null);
@@ -169,13 +169,15 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
const [modelSwitchedFromQuotaError, setModelSwitchedFromQuotaError] =
useState<boolean>(false);
const [userTier, setUserTier] = useState<UserTierId | undefined>(undefined);
const [openFiles, setOpenFiles] = useState<OpenFiles | undefined>();
const [ideContextState, setIdeContextState] = useState<
IdeContext | undefined
>();
const [isProcessing, setIsProcessing] = useState<boolean>(false);
useEffect(() => {
const unsubscribe = ideContext.subscribeToOpenFiles(setOpenFiles);
const unsubscribe = ideContext.subscribeToIdeContext(setIdeContextState);
// Set the initial value
setOpenFiles(ideContext.getOpenFilesContext());
setIdeContextState(ideContext.getIdeContext());
return unsubscribe;
}, []);
@@ -230,14 +232,19 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
} = useAuthCommand(settings, setAuthError, config);
useEffect(() => {
if (settings.merged.selectedAuthType) {
if (settings.merged.selectedAuthType && !settings.merged.useExternalAuth) {
const error = validateAuthMethod(settings.merged.selectedAuthType);
if (error) {
setAuthError(error);
openAuthDialog();
}
}
}, [settings.merged.selectedAuthType, openAuthDialog, setAuthError]);
}, [
settings.merged.selectedAuthType,
settings.merged.useExternalAuth,
openAuthDialog,
setAuthError,
]);
// Sync user tier from config when authentication changes
useEffect(() => {
@@ -273,6 +280,7 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
config.getFileService(),
settings.merged,
config.getExtensionContextFilePaths(),
settings.merged.memoryImportFormat || 'tree', // Use setting or default to 'tree'
config.getFileFilteringOptions(),
);
@@ -396,6 +404,7 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
// Switch model for future use but return false to stop current retry
config.setModel(fallbackModel);
config.setFallbackMode(true);
logFlashFallback(
config,
new FlashFallbackEvent(config.getContentGeneratorConfig().authType!),
@@ -462,7 +471,6 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
clearItems,
loadHistory,
refreshStatic,
setShowHelp,
setDebugMessage,
openThemeDialog,
openAuthDialog,
@@ -484,7 +492,6 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
config.getGeminiClient(),
history,
addItem,
setShowHelp,
config,
setDebugMessage,
handleSlashCommand,
@@ -568,7 +575,12 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
if (Object.keys(mcpServers || {}).length > 0) {
handleSlashCommand(newValue ? '/mcp desc' : '/mcp nodesc');
}
} else if (key.ctrl && input === 'e' && ideContext) {
} else if (
key.ctrl &&
input === 'e' &&
config.getIdeMode() &&
ideContextState
) {
setShowIDEContextDetail((prev) => !prev);
} else if (key.ctrl && (input === 'c' || input === 'C')) {
handleExit(ctrlCPressedOnce, setCtrlCPressedOnce, ctrlCTimerRef);
@@ -754,9 +766,6 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
return (
<StreamingContext.Provider value={streamingState}>
<Box flexDirection="column" width="90%">
{/* Move UpdateNotification outside Static so it can re-render when updateMessage changes */}
{updateMessage && <UpdateNotification message={updateMessage} />}
{/*
* The Static component is an Ink intrinsic in which there can only be 1 per application.
* Because of this restriction we're hacking it slightly by having a 'header' item here to
@@ -789,6 +798,7 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
item={h}
isPending={false}
config={config}
commands={slashCommands}
/>
)),
]}
@@ -816,9 +826,9 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
</Box>
</OverflowProvider>
{showHelp && <Help commands={slashCommands} />}
<Box flexDirection="column" ref={mainControlsRef}>
{/* Move UpdateNotification to render update notification above input area */}
{updateInfo && <UpdateNotification message={updateInfo.message} />}
{startupWarnings.length > 0 && (
<Box
borderStyle="round"
@@ -943,7 +953,7 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
</Text>
) : (
<ContextSummaryDisplay
openFiles={openFiles}
ideContext={ideContextState}
geminiMdFileCount={geminiMdFileCount}
contextFileNames={contextFileNames}
mcpServers={config.getMcpServers()}
@@ -963,7 +973,12 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
</Box>
</Box>
{showIDEContextDetail && (
<IDEContextDetailDisplay openFiles={openFiles} />
<IDEContextDetailDisplay
ideContext={ideContextState}
detectedIdeDisplay={config
.getIdeClient()
.getDetectedIdeDisplayName()}
/>
)}
{showErrorDetails && (
<OverflowProvider>