feat(cli): add loading state to new agents notification (#19190)

This commit is contained in:
Sehoon Shon
2026-02-16 01:43:25 -05:00
committed by GitHub
parent d1ca8c0c80
commit bb7bb11736
2 changed files with 52 additions and 6 deletions

View File

@@ -7,6 +7,8 @@
import { describe, it, expect, vi } from 'vitest';
import { renderWithProviders as render } from '../../test-utils/render.js';
import { NewAgentsNotification } from './NewAgentsNotification.js';
import { waitFor } from '../../test-utils/async.js';
import { act } from 'react';
describe('NewAgentsNotification', () => {
const mockAgents = [
@@ -54,4 +56,28 @@ describe('NewAgentsNotification', () => {
expect(frame).toMatchSnapshot();
unmount();
});
it('shows processing state when an option is selected', async () => {
const asyncOnSelect = vi.fn(
() =>
new Promise<void>(() => {
// Never resolve
}),
);
const { lastFrame, stdin, unmount } = render(
<NewAgentsNotification agents={mockAgents} onSelect={asyncOnSelect} />,
);
// Press Enter to select the first option
await act(async () => {
stdin.write('\r');
});
await waitFor(() => {
expect(lastFrame()).toContain('Processing...');
});
unmount();
});
});

View File

@@ -4,6 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
import { useState } from 'react';
import { Box, Text } from 'ink';
import { type AgentDefinition } from '@google/gemini-cli-core';
import { theme } from '../semantic-colors.js';
@@ -11,6 +12,7 @@ import {
RadioButtonSelect,
type RadioSelectItem,
} from './shared/RadioButtonSelect.js';
import { CliSpinner } from './CliSpinner.js';
export enum NewAgentsChoice {
ACKNOWLEDGE = 'acknowledge',
@@ -19,13 +21,15 @@ export enum NewAgentsChoice {
interface NewAgentsNotificationProps {
agents: AgentDefinition[];
onSelect: (choice: NewAgentsChoice) => void;
onSelect: (choice: NewAgentsChoice) => void | Promise<void>;
}
export const NewAgentsNotification = ({
agents,
onSelect,
}: NewAgentsNotificationProps) => {
const [isProcessing, setIsProcessing] = useState(false);
const options: Array<RadioSelectItem<NewAgentsChoice>> = [
{
label: 'Acknowledge and Enable',
@@ -39,6 +43,15 @@ export const NewAgentsNotification = ({
},
];
const handleSelect = async (choice: NewAgentsChoice) => {
setIsProcessing(true);
try {
await onSelect(choice);
} finally {
setIsProcessing(false);
}
};
// Limit display to 5 agents to avoid overflow, show count for rest
const MAX_DISPLAYED_AGENTS = 5;
const displayAgents = agents.slice(0, MAX_DISPLAYED_AGENTS);
@@ -85,11 +98,18 @@ export const NewAgentsNotification = ({
</Box>
</Box>
<RadioButtonSelect
items={options}
onSelect={onSelect}
isFocused={true}
/>
{isProcessing ? (
<Box>
<CliSpinner />
<Text color={theme.text.primary}> Processing...</Text>
</Box>
) : (
<RadioButtonSelect
items={options}
onSelect={handleSelect}
isFocused={true}
/>
)}
</Box>
</Box>
);