mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-21 18:44:30 -07:00
Fix /chat list not write terminal escape codes directly (#10415)
This commit is contained in:
@@ -29,6 +29,7 @@ import { ExtensionsList } from './views/ExtensionsList.js';
|
||||
import { getMCPServerStatus } from '@google/gemini-cli-core';
|
||||
import { ToolsList } from './views/ToolsList.js';
|
||||
import { McpStatus } from './views/McpStatus.js';
|
||||
import { ChatList } from './views/ChatList.js';
|
||||
|
||||
interface HistoryItemDisplayProps {
|
||||
item: HistoryItem;
|
||||
@@ -140,6 +141,9 @@ export const HistoryItemDisplay: React.FC<HistoryItemDisplayProps> = ({
|
||||
{itemForDisplay.type === 'mcp_status' && (
|
||||
<McpStatus {...itemForDisplay} serverStatus={getMCPServerStatus} />
|
||||
)}
|
||||
{itemForDisplay.type === 'chat_list' && (
|
||||
<ChatList chats={itemForDisplay.chats} />
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { render } from 'ink-testing-library';
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { ChatList } from './ChatList.js';
|
||||
import type { ChatDetail } from '../../types.js';
|
||||
|
||||
const mockChats: ChatDetail[] = [
|
||||
{
|
||||
name: 'chat-1',
|
||||
mtime: '2025-10-02T10:00:00.000Z',
|
||||
},
|
||||
{
|
||||
name: 'another-chat',
|
||||
mtime: '2025-10-01T12:30:00.000Z',
|
||||
},
|
||||
];
|
||||
|
||||
describe('<ChatList />', () => {
|
||||
it('renders correctly with a list of chats', () => {
|
||||
const { lastFrame } = render(<ChatList chats={mockChats} />);
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('renders correctly with no chats', () => {
|
||||
const { lastFrame } = render(<ChatList chats={[]} />);
|
||||
expect(lastFrame()).toContain('No saved conversation checkpoints found.');
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('handles invalid date formats gracefully', () => {
|
||||
const mockChatsWithInvalidDate: ChatDetail[] = [
|
||||
{
|
||||
name: 'bad-date-chat',
|
||||
mtime: 'an-invalid-date-string',
|
||||
},
|
||||
];
|
||||
const { lastFrame } = render(<ChatList chats={mockChatsWithInvalidDate} />);
|
||||
expect(lastFrame()).toContain('(Invalid Date)');
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type React from 'react';
|
||||
import { Box, Text } from 'ink';
|
||||
import { theme } from '../../semantic-colors.js';
|
||||
import type { ChatDetail } from '../../types.js';
|
||||
|
||||
interface ChatListProps {
|
||||
chats: readonly ChatDetail[];
|
||||
}
|
||||
|
||||
export const ChatList: React.FC<ChatListProps> = ({ chats }) => {
|
||||
if (chats.length === 0) {
|
||||
return <Text>No saved conversation checkpoints found.</Text>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Box flexDirection="column">
|
||||
<Text>List of saved conversations:</Text>
|
||||
<Box height={1} />
|
||||
{chats.map((chat) => {
|
||||
const isoString = chat.mtime;
|
||||
const match = isoString.match(
|
||||
/(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})/,
|
||||
);
|
||||
const formattedDate = match
|
||||
? `${match[1]} ${match[2]}`
|
||||
: 'Invalid Date';
|
||||
return (
|
||||
<Box key={chat.name} flexDirection="row">
|
||||
<Text>
|
||||
{' '}- <Text color={theme.text.accent}>{chat.name}</Text>{' '}
|
||||
<Text color={theme.text.secondary}>({formattedDate})</Text>
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
<Box height={1} />
|
||||
<Text color={theme.text.secondary}>Note: Newest last, oldest first</Text>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`<ChatList /> > handles invalid date formats gracefully 1`] = `
|
||||
"List of saved conversations:
|
||||
|
||||
- bad-date-chat (Invalid Date)
|
||||
|
||||
Note: Newest last, oldest first"
|
||||
`;
|
||||
|
||||
exports[`<ChatList /> > renders correctly with a list of chats 1`] = `
|
||||
"List of saved conversations:
|
||||
|
||||
- chat-1 (2025-10-02 10:00:00)
|
||||
- another-chat (2025-10-01 12:30:00)
|
||||
|
||||
Note: Newest last, oldest first"
|
||||
`;
|
||||
|
||||
exports[`<ChatList /> > renders correctly with no chats 1`] = `"No saved conversation checkpoints found."`;
|
||||
Reference in New Issue
Block a user