diff --git a/packages/cli/src/ui/components/ConfigInitDisplay.test.tsx b/packages/cli/src/ui/components/ConfigInitDisplay.test.tsx index ed4a60a1de..3c98080823 100644 --- a/packages/cli/src/ui/components/ConfigInitDisplay.test.tsx +++ b/packages/cli/src/ui/components/ConfigInitDisplay.test.tsx @@ -6,6 +6,7 @@ import { act } from 'react'; import { render } from '../../test-utils/render.js'; +import { waitFor } from '../../test-utils/async.js'; import { ConfigInitDisplay } from './ConfigInitDisplay.js'; import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { AppEvent } from '../../utils/events.js'; @@ -63,7 +64,7 @@ describe('ConfigInitDisplay', () => { const { lastFrame } = render(); // Wait for listener to be registered - await vi.waitFor(() => { + await waitFor(() => { if (!listener) throw new Error('Listener not registered yet'); }); @@ -84,7 +85,42 @@ describe('ConfigInitDisplay', () => { }); // Wait for the UI to update - await vi.waitFor(() => { + await waitFor(() => { + expect(lastFrame()).toMatchSnapshot(); + }); + }); + + it('truncates list of waiting servers if too many', async () => { + let listener: ((clients?: Map) => void) | undefined; + mockOn.mockImplementation((event, fn) => { + if (event === AppEvent.McpClientUpdate) { + listener = fn; + } + }); + + const { lastFrame } = render(); + + await waitFor(() => { + if (!listener) throw new Error('Listener not registered yet'); + }); + + const mockClientConnecting = { + getStatus: () => MCPServerStatus.CONNECTING, + } as McpClient; + + const clients = new Map([ + ['s1', mockClientConnecting], + ['s2', mockClientConnecting], + ['s3', mockClientConnecting], + ['s4', mockClientConnecting], + ['s5', mockClientConnecting], + ]); + + act(() => { + listener!(clients); + }); + + await waitFor(() => { expect(lastFrame()).toMatchSnapshot(); }); }); @@ -99,7 +135,7 @@ describe('ConfigInitDisplay', () => { const { lastFrame } = render(); - await vi.waitFor(() => { + await waitFor(() => { if (!listener) throw new Error('Listener not registered yet'); }); @@ -110,7 +146,7 @@ describe('ConfigInitDisplay', () => { }); } - await vi.waitFor(() => { + await waitFor(() => { expect(lastFrame()).toMatchSnapshot(); }); }); diff --git a/packages/cli/src/ui/components/ConfigInitDisplay.tsx b/packages/cli/src/ui/components/ConfigInitDisplay.tsx index 8180bbe8de..59529dc96d 100644 --- a/packages/cli/src/ui/components/ConfigInitDisplay.tsx +++ b/packages/cli/src/ui/components/ConfigInitDisplay.tsx @@ -21,12 +21,28 @@ export const ConfigInitDisplay = () => { return; } let connected = 0; - for (const client of clients.values()) { + const connecting: string[] = []; + for (const [name, client] of clients.entries()) { if (client.getStatus() === MCPServerStatus.CONNECTED) { connected++; + } else { + connecting.push(name); } } - setMessage(`Connecting to MCP servers... (${connected}/${clients.size})`); + + if (connecting.length > 0) { + const maxDisplay = 3; + const displayedServers = connecting.slice(0, maxDisplay).join(', '); + const remaining = connecting.length - maxDisplay; + const suffix = remaining > 0 ? `, +${remaining} more` : ''; + setMessage( + `Connecting to MCP servers... (${connected}/${clients.size}) - Waiting for: ${displayedServers}${suffix}`, + ); + } else { + setMessage( + `Connecting to MCP servers... (${connected}/${clients.size})`, + ); + } }; appEvents.on(AppEvent.McpClientUpdate, onChange); diff --git a/packages/cli/src/ui/components/__snapshots__/ConfigInitDisplay.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/ConfigInitDisplay.test.tsx.snap index 9c7b7cc0d7..f858877be0 100644 --- a/packages/cli/src/ui/components/__snapshots__/ConfigInitDisplay.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/ConfigInitDisplay.test.tsx.snap @@ -10,7 +10,12 @@ exports[`ConfigInitDisplay > renders initial state 1`] = ` Spinner Initializing..." `; +exports[`ConfigInitDisplay > truncates list of waiting servers if too many 1`] = ` +" +Spinner Connecting to MCP servers... (0/5) - Waiting for: s1, s2, s3, +2 more" +`; + exports[`ConfigInitDisplay > updates message on McpClientUpdate event 1`] = ` " -Spinner Connecting to MCP servers... (1/2)" +Spinner Connecting to MCP servers... (1/2) - Waiting for: server2" `;