mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-21 18:44:30 -07:00
fix(cli): Make IDE trust listener also listen to IDE status changes a… (#9783)
This commit is contained in:
@@ -27,6 +27,7 @@ import { useConfig } from '../contexts/ConfigContext.js';
|
||||
import { useSettings } from '../contexts/SettingsContext.js';
|
||||
import process from 'node:process';
|
||||
import { type UseHistoryManagerReturn } from '../hooks/useHistoryManager.js';
|
||||
import { IdeTrustChangeDialog } from './IdeTrustChangeDialog.js';
|
||||
|
||||
interface DialogManagerProps {
|
||||
addItem: UseHistoryManagerReturn['addItem'];
|
||||
@@ -43,14 +44,7 @@ export const DialogManager = ({ addItem }: DialogManagerProps) => {
|
||||
uiState;
|
||||
|
||||
if (uiState.showIdeRestartPrompt) {
|
||||
return (
|
||||
<Box borderStyle="round" borderColor={theme.status.warning} paddingX={1}>
|
||||
<Text color={theme.status.warning}>
|
||||
Workspace trust has changed. Press 'r' to restart Gemini to
|
||||
apply the changes.
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
return <IdeTrustChangeDialog reason={uiState.ideTrustRestartReason} />;
|
||||
}
|
||||
if (uiState.showWorkspaceMigrationDialog) {
|
||||
return (
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { vi, describe, it, expect, beforeEach } from 'vitest';
|
||||
import * as processUtils from '../../utils/processUtils.js';
|
||||
import { renderWithProviders } from '../../test-utils/render.js';
|
||||
import { IdeTrustChangeDialog } from './IdeTrustChangeDialog.js';
|
||||
|
||||
describe('IdeTrustChangeDialog', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('renders the correct message for CONNECTION_CHANGE', () => {
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<IdeTrustChangeDialog reason="CONNECTION_CHANGE" />,
|
||||
);
|
||||
|
||||
const frameText = lastFrame();
|
||||
expect(frameText).toContain(
|
||||
'Workspace trust has changed due to a change in the IDE connection.',
|
||||
);
|
||||
expect(frameText).toContain("Press 'r' to restart Gemini");
|
||||
});
|
||||
|
||||
it('renders the correct message for TRUST_CHANGE', () => {
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<IdeTrustChangeDialog reason="TRUST_CHANGE" />,
|
||||
);
|
||||
|
||||
const frameText = lastFrame();
|
||||
expect(frameText).toContain(
|
||||
'Workspace trust has changed due to a change in the IDE trust.',
|
||||
);
|
||||
expect(frameText).toContain("Press 'r' to restart Gemini");
|
||||
});
|
||||
|
||||
it('renders a generic message and logs an error for NONE reason', () => {
|
||||
const consoleErrorSpy = vi
|
||||
.spyOn(console, 'error')
|
||||
.mockImplementation(() => {});
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<IdeTrustChangeDialog reason="NONE" />,
|
||||
);
|
||||
|
||||
const frameText = lastFrame();
|
||||
expect(frameText).toContain('Workspace trust has changed.');
|
||||
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
||||
'IdeTrustChangeDialog rendered with unexpected reason "NONE"',
|
||||
);
|
||||
});
|
||||
|
||||
it('calls relaunchApp when "r" is pressed', () => {
|
||||
const relaunchAppSpy = vi.spyOn(processUtils, 'relaunchApp');
|
||||
const { stdin } = renderWithProviders(
|
||||
<IdeTrustChangeDialog reason="NONE" />,
|
||||
);
|
||||
|
||||
stdin.write('r');
|
||||
|
||||
expect(relaunchAppSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('calls relaunchApp when "R" is pressed', () => {
|
||||
const relaunchAppSpy = vi.spyOn(processUtils, 'relaunchApp');
|
||||
const { stdin } = renderWithProviders(
|
||||
<IdeTrustChangeDialog reason="CONNECTION_CHANGE" />,
|
||||
);
|
||||
|
||||
stdin.write('R');
|
||||
|
||||
expect(relaunchAppSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('does not call relaunchApp when another key is pressed', async () => {
|
||||
const relaunchAppSpy = vi.spyOn(processUtils, 'relaunchApp');
|
||||
const { stdin } = renderWithProviders(
|
||||
<IdeTrustChangeDialog reason="CONNECTION_CHANGE" />,
|
||||
);
|
||||
|
||||
stdin.write('a');
|
||||
|
||||
// Give it a moment to ensure no async actions are triggered
|
||||
await new Promise((resolve) => setTimeout(resolve, 50));
|
||||
|
||||
expect(relaunchAppSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { Box, Text } from 'ink';
|
||||
import { theme } from '../semantic-colors.js';
|
||||
import { useKeypress } from '../hooks/useKeypress.js';
|
||||
import { relaunchApp } from '../../utils/processUtils.js';
|
||||
import { type RestartReason } from '../hooks/useIdeTrustListener.js';
|
||||
|
||||
interface IdeTrustChangeDialogProps {
|
||||
reason: RestartReason;
|
||||
}
|
||||
|
||||
export const IdeTrustChangeDialog = ({ reason }: IdeTrustChangeDialogProps) => {
|
||||
useKeypress(
|
||||
(key) => {
|
||||
if (key.name === 'r' || key.name === 'R') {
|
||||
relaunchApp();
|
||||
}
|
||||
},
|
||||
{ isActive: true },
|
||||
);
|
||||
|
||||
let message = 'Workspace trust has changed.';
|
||||
if (reason === 'NONE') {
|
||||
// This should not happen, but provides a fallback and a debug log.
|
||||
console.error(
|
||||
'IdeTrustChangeDialog rendered with unexpected reason "NONE"',
|
||||
);
|
||||
} else if (reason === 'CONNECTION_CHANGE') {
|
||||
message =
|
||||
'Workspace trust has changed due to a change in the IDE connection.';
|
||||
} else if (reason === 'TRUST_CHANGE') {
|
||||
message = 'Workspace trust has changed due to a change in the IDE trust.';
|
||||
}
|
||||
|
||||
return (
|
||||
<Box borderStyle="round" borderColor={theme.status.warning} paddingX={1}>
|
||||
<Text color={theme.status.warning}>
|
||||
{message} Press 'r' to restart Gemini to apply the changes.
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user