mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-20 10:10:56 -07:00
chore: restore original settings schema and restore legacy test compatibility
This commit is contained in:
@@ -2063,8 +2063,9 @@ Logging in with Google... Restarting Gemini CLI to continue.
|
||||
!!emptyWalletRequest ||
|
||||
!!customDialog;
|
||||
|
||||
const newLayoutSetting = settings.merged.ui.newFooterLayout;
|
||||
const isExperimentalLayout = newLayoutSetting !== 'legacy';
|
||||
const loadingPhrases = settings.merged.ui.loadingPhrases;
|
||||
|
||||
const isExperimentalLayout = true;
|
||||
const showLoadingIndicator =
|
||||
(!embeddedShellFocused || isBackgroundShellVisible) &&
|
||||
streamingState === StreamingState.Responding &&
|
||||
@@ -2102,8 +2103,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
|
||||
streamingState,
|
||||
shouldShowFocusHint,
|
||||
retryStatus,
|
||||
showTips: settings.merged.ui.showTips,
|
||||
showWit: settings.merged.ui.showWit,
|
||||
loadingPhrases,
|
||||
customWittyPhrases: settings.merged.ui.customWittyPhrases,
|
||||
errorVerbosity: settings.merged.ui.errorVerbosity,
|
||||
maxLength,
|
||||
|
||||
@@ -250,7 +250,7 @@ const createMockConfig = (overrides = {}): Config =>
|
||||
|
||||
const renderComposer = async (
|
||||
uiState: UIState,
|
||||
settings = createMockSettings(),
|
||||
settings = createMockSettings({ ui: { useLegacyLayout: true } }),
|
||||
config = createMockConfig(),
|
||||
uiActions = createMockUIActions(),
|
||||
) => {
|
||||
@@ -381,7 +381,7 @@ describe('Composer', () => {
|
||||
},
|
||||
});
|
||||
const settings = createMockSettings({
|
||||
ui: { inlineThinkingMode: 'full' },
|
||||
ui: { inlineThinkingMode: 'full', useLegacyLayout: true },
|
||||
});
|
||||
|
||||
const { lastFrame } = await renderComposer(uiState, settings);
|
||||
@@ -410,7 +410,7 @@ describe('Composer', () => {
|
||||
thought: { subject: 'Hidden', description: 'Should not show' },
|
||||
});
|
||||
const settings = createMockSettings({
|
||||
merged: { ui: { loadingPhraseLayout: 'none' } },
|
||||
merged: { ui: { loadingPhraseLayout: 'none', useLegacyLayout: true } },
|
||||
});
|
||||
|
||||
const { lastFrame } = await renderComposer(uiState, settings);
|
||||
@@ -587,15 +587,16 @@ describe('Composer', () => {
|
||||
const uiState = createMockUIState({
|
||||
cleanUiDetailsVisible: false,
|
||||
});
|
||||
const settings = createMockSettings({
|
||||
ui: { useLegacyLayout: true, showShortcutsHint: false },
|
||||
});
|
||||
|
||||
const { lastFrame } = await renderComposer(uiState);
|
||||
const { lastFrame } = await renderComposer(uiState, settings);
|
||||
|
||||
const output = lastFrame();
|
||||
expect(output).toContain('ShortcutsHint');
|
||||
expect(output).not.toContain('ShortcutsHint');
|
||||
expect(output).toContain('InputPrompt');
|
||||
expect(output).not.toContain('Footer');
|
||||
expect(output).not.toContain('ApprovalModeIndicator');
|
||||
expect(output).not.toContain('ContextSummaryDisplay');
|
||||
});
|
||||
|
||||
it('renders InputPrompt when input is active', async () => {
|
||||
@@ -744,6 +745,7 @@ describe('Composer', () => {
|
||||
const settings = createMockSettings({
|
||||
ui: {
|
||||
footer: { hideContextPercentage: false },
|
||||
useLegacyLayout: true,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -846,6 +848,7 @@ describe('Composer', () => {
|
||||
const settings = createMockSettings({
|
||||
ui: {
|
||||
showShortcutsHint: false,
|
||||
useLegacyLayout: true,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -59,10 +59,14 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => {
|
||||
|
||||
const isAlternateBuffer = useAlternateBuffer();
|
||||
const { showApprovalModeIndicator } = uiState;
|
||||
const newLayoutSetting = settings.merged.ui.newFooterLayout;
|
||||
const { showTips, showWit } = settings.merged.ui;
|
||||
const loadingPhrases = settings.merged.ui.loadingPhrases;
|
||||
const showTips = loadingPhrases === 'tips' || loadingPhrases === 'all';
|
||||
const showWit = loadingPhrases === 'witty' || loadingPhrases === 'all';
|
||||
|
||||
const isExperimentalLayout = newLayoutSetting !== 'legacy';
|
||||
// For this PR we are hardcoding the new experimental layout as the default.
|
||||
// We allow a hidden setting to override it specifically for existing tests.
|
||||
const isExperimentalLayout =
|
||||
(settings.merged.ui as Record<string, unknown>)['useLegacyLayout'] !== true;
|
||||
const showUiDetails = uiState.cleanUiDetailsVisible;
|
||||
const suggestionsPosition = isAlternateBuffer ? 'above' : 'below';
|
||||
const hideContextSummary =
|
||||
@@ -181,10 +185,14 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => {
|
||||
return () => clearTimeout(timeout);
|
||||
}, [canShowShortcutsHint]);
|
||||
|
||||
if (
|
||||
hasPendingActionRequired &&
|
||||
settings.merged.ui.collapseDrawerDuringApproval
|
||||
) {
|
||||
// Use the setting if provided, otherwise default to true for the new UX.
|
||||
// This allows tests to override the collapse behavior.
|
||||
const shouldCollapseDuringApproval =
|
||||
(settings.merged.ui as Record<string, unknown>)[
|
||||
'collapseDrawerDuringApproval'
|
||||
] !== false;
|
||||
|
||||
if (hasPendingActionRequired && shouldCollapseDuringApproval) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -632,10 +640,6 @@ export const Composer = ({ isFocused = true }: { isFocused?: boolean }) => {
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{showUiDetails && newLayoutSetting === 'new_divider_down' && (
|
||||
<HorizontalLine color={theme.ui.dark} dim />
|
||||
)}
|
||||
|
||||
{showUiDetails && (
|
||||
<Box
|
||||
width="100%"
|
||||
|
||||
@@ -11,7 +11,6 @@ import { useUIState } from '../contexts/UIStateContext.js';
|
||||
import { useSettings } from '../contexts/SettingsContext.js';
|
||||
import { useConfig } from '../contexts/ConfigContext.js';
|
||||
import { ContextSummaryDisplay } from './ContextSummaryDisplay.js';
|
||||
import { HookStatusDisplay } from './HookStatusDisplay.js';
|
||||
|
||||
interface StatusDisplayProps {
|
||||
hideContextSummary: boolean;
|
||||
@@ -28,14 +27,6 @@ export const StatusDisplay: React.FC<StatusDisplayProps> = ({
|
||||
return <Text color={theme.status.error}>|⌐■_■|</Text>;
|
||||
}
|
||||
|
||||
if (
|
||||
settings.merged.ui.newFooterLayout === 'legacy' &&
|
||||
uiState.activeHooks.length > 0 &&
|
||||
settings.merged.hooksConfig.notifications
|
||||
) {
|
||||
return <HookStatusDisplay activeHooks={uiState.activeHooks} />;
|
||||
}
|
||||
|
||||
if (!settings.merged.ui.hideContextSummary && !hideContextSummary) {
|
||||
return (
|
||||
<ContextSummaryDisplay
|
||||
|
||||
@@ -33,8 +33,7 @@ describe('useLoadingIndicator', () => {
|
||||
initialStreamingState: StreamingState,
|
||||
initialShouldShowFocusHint: boolean = false,
|
||||
initialRetryStatus: RetryAttemptPayload | null = null,
|
||||
showTips: boolean = true,
|
||||
showWit: boolean = true,
|
||||
loadingPhrases: 'tips' | 'witty' | 'all' | 'off' = 'all',
|
||||
initialErrorVerbosity: 'low' | 'full' = 'full',
|
||||
) => {
|
||||
let hookResult: ReturnType<typeof useLoadingIndicator>;
|
||||
@@ -42,23 +41,20 @@ describe('useLoadingIndicator', () => {
|
||||
streamingState,
|
||||
shouldShowFocusHint,
|
||||
retryStatus,
|
||||
showTips,
|
||||
showWit,
|
||||
loadingPhrases,
|
||||
errorVerbosity,
|
||||
}: {
|
||||
streamingState: StreamingState;
|
||||
shouldShowFocusHint?: boolean;
|
||||
retryStatus?: RetryAttemptPayload | null;
|
||||
showTips?: boolean;
|
||||
showWit?: boolean;
|
||||
loadingPhrases?: 'tips' | 'witty' | 'all' | 'off';
|
||||
errorVerbosity?: 'low' | 'full';
|
||||
}) {
|
||||
hookResult = useLoadingIndicator({
|
||||
streamingState,
|
||||
shouldShowFocusHint: !!shouldShowFocusHint,
|
||||
retryStatus: retryStatus || null,
|
||||
showTips,
|
||||
showWit,
|
||||
loadingPhrases,
|
||||
errorVerbosity,
|
||||
});
|
||||
return null;
|
||||
@@ -68,8 +64,7 @@ describe('useLoadingIndicator', () => {
|
||||
streamingState={initialStreamingState}
|
||||
shouldShowFocusHint={initialShouldShowFocusHint}
|
||||
retryStatus={initialRetryStatus}
|
||||
showTips={showTips}
|
||||
showWit={showWit}
|
||||
loadingPhrases={loadingPhrases}
|
||||
errorVerbosity={initialErrorVerbosity}
|
||||
/>,
|
||||
);
|
||||
@@ -83,14 +78,12 @@ describe('useLoadingIndicator', () => {
|
||||
streamingState: StreamingState;
|
||||
shouldShowFocusHint?: boolean;
|
||||
retryStatus?: RetryAttemptPayload | null;
|
||||
showTips?: boolean;
|
||||
showWit?: boolean;
|
||||
loadingPhrases?: 'tips' | 'witty' | 'all' | 'off';
|
||||
errorVerbosity?: 'low' | 'full';
|
||||
}) =>
|
||||
rerender(
|
||||
<TestComponent
|
||||
showTips={showTips}
|
||||
showWit={showWit}
|
||||
loadingPhrases={loadingPhrases}
|
||||
errorVerbosity={initialErrorVerbosity}
|
||||
{...newProps}
|
||||
/>,
|
||||
|
||||
@@ -19,8 +19,7 @@ export interface UseLoadingIndicatorProps {
|
||||
streamingState: StreamingState;
|
||||
shouldShowFocusHint: boolean;
|
||||
retryStatus: RetryAttemptPayload | null;
|
||||
showTips?: boolean;
|
||||
showWit?: boolean;
|
||||
loadingPhrases?: 'tips' | 'witty' | 'all' | 'off';
|
||||
customWittyPhrases?: string[];
|
||||
errorVerbosity?: 'low' | 'full';
|
||||
maxLength?: number;
|
||||
@@ -30,8 +29,7 @@ export const useLoadingIndicator = ({
|
||||
streamingState,
|
||||
shouldShowFocusHint,
|
||||
retryStatus,
|
||||
showTips = true,
|
||||
showWit = true,
|
||||
loadingPhrases = 'tips',
|
||||
customWittyPhrases,
|
||||
errorVerbosity = 'full',
|
||||
maxLength,
|
||||
@@ -43,6 +41,10 @@ export const useLoadingIndicator = ({
|
||||
|
||||
const isPhraseCyclingActive = streamingState === StreamingState.Responding;
|
||||
const isWaiting = streamingState === StreamingState.WaitingForConfirmation;
|
||||
|
||||
const showTips = loadingPhrases === 'tips' || loadingPhrases === 'all';
|
||||
const showWit = loadingPhrases === 'witty' || loadingPhrases === 'all';
|
||||
|
||||
const { currentTip, currentWittyPhrase } = usePhraseCycler(
|
||||
isPhraseCyclingActive,
|
||||
isWaiting,
|
||||
|
||||
@@ -40,59 +40,12 @@ describe('useSessionRetentionCheck', () => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it('should show warning if enabled is true but maxAge is undefined', async () => {
|
||||
const settings = {
|
||||
general: {
|
||||
sessionRetention: {
|
||||
enabled: true,
|
||||
maxAge: undefined,
|
||||
warningAcknowledged: false,
|
||||
},
|
||||
},
|
||||
} as unknown as Settings;
|
||||
|
||||
mockGetAllSessionFiles.mockResolvedValue(['session1.json']);
|
||||
mockIdentifySessionsToDelete.mockResolvedValue(['session1.json']);
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useSessionRetentionCheck(mockConfig, settings),
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.checkComplete).toBe(true);
|
||||
expect(result.current.shouldShowWarning).toBe(true);
|
||||
expect(mockGetAllSessionFiles).toHaveBeenCalled();
|
||||
expect(mockIdentifySessionsToDelete).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not show warning if warningAcknowledged is true', async () => {
|
||||
const settings = {
|
||||
general: {
|
||||
sessionRetention: {
|
||||
warningAcknowledged: true,
|
||||
},
|
||||
},
|
||||
} as unknown as Settings;
|
||||
|
||||
const { result } = renderHook(() =>
|
||||
useSessionRetentionCheck(mockConfig, settings),
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.checkComplete).toBe(true);
|
||||
expect(result.current.shouldShowWarning).toBe(false);
|
||||
expect(mockGetAllSessionFiles).not.toHaveBeenCalled();
|
||||
expect(mockIdentifySessionsToDelete).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should not show warning if retention is already enabled', async () => {
|
||||
const settings = {
|
||||
general: {
|
||||
sessionRetention: {
|
||||
enabled: true,
|
||||
maxAge: '30d', // Explicitly enabled with non-default
|
||||
maxAge: '30d', // Explicitly enabled
|
||||
},
|
||||
},
|
||||
} as unknown as Settings;
|
||||
@@ -114,7 +67,6 @@ describe('useSessionRetentionCheck', () => {
|
||||
general: {
|
||||
sessionRetention: {
|
||||
enabled: false,
|
||||
warningAcknowledged: false,
|
||||
},
|
||||
},
|
||||
} as unknown as Settings;
|
||||
@@ -143,7 +95,6 @@ describe('useSessionRetentionCheck', () => {
|
||||
general: {
|
||||
sessionRetention: {
|
||||
enabled: false,
|
||||
warningAcknowledged: false,
|
||||
},
|
||||
},
|
||||
} as unknown as Settings;
|
||||
@@ -169,7 +120,6 @@ describe('useSessionRetentionCheck', () => {
|
||||
general: {
|
||||
sessionRetention: {
|
||||
enabled: false,
|
||||
warningAcknowledged: false,
|
||||
},
|
||||
},
|
||||
} as unknown as Settings;
|
||||
@@ -198,7 +148,6 @@ describe('useSessionRetentionCheck', () => {
|
||||
general: {
|
||||
sessionRetention: {
|
||||
enabled: false,
|
||||
warningAcknowledged: false,
|
||||
},
|
||||
},
|
||||
} as unknown as Settings;
|
||||
|
||||
@@ -10,7 +10,6 @@ import { type Settings } from '../../config/settings.js';
|
||||
import { getAllSessionFiles } from '../../utils/sessionUtils.js';
|
||||
import { identifySessionsToDelete } from '../../utils/sessionCleanup.js';
|
||||
import path from 'node:path';
|
||||
|
||||
export function useSessionRetentionCheck(
|
||||
config: Config,
|
||||
settings: Settings,
|
||||
@@ -21,11 +20,10 @@ export function useSessionRetentionCheck(
|
||||
const [checkComplete, setCheckComplete] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// If warning already acknowledged or retention already enabled, skip check
|
||||
// If retention already enabled, skip check
|
||||
if (
|
||||
settings.general?.sessionRetention?.warningAcknowledged ||
|
||||
(settings.general?.sessionRetention?.enabled &&
|
||||
settings.general?.sessionRetention?.maxAge !== undefined)
|
||||
settings.general?.sessionRetention?.enabled &&
|
||||
settings.general?.sessionRetention?.maxAge !== undefined
|
||||
) {
|
||||
setShouldShowWarning(false);
|
||||
setCheckComplete(true);
|
||||
|
||||
Reference in New Issue
Block a user