mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-20 10:10:56 -07:00
feat(ui): Re-apply Dense Tool Output features
This commit is contained in:
@@ -862,7 +862,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
|
||||
const performMemoryRefresh = useCallback(async () => {
|
||||
historyManager.addItem(
|
||||
{
|
||||
type: MessageType.INFO,
|
||||
type: MessageType.VERBOSE,
|
||||
text: 'Refreshing hierarchical memory (GEMINI.md or other context files)...',
|
||||
},
|
||||
Date.now(),
|
||||
@@ -873,7 +873,7 @@ Logging in with Google... Restarting Gemini CLI to continue.
|
||||
|
||||
historyManager.addItem(
|
||||
{
|
||||
type: MessageType.INFO,
|
||||
type: MessageType.VERBOSE,
|
||||
text: `Memory refreshed successfully. ${
|
||||
memoryContent.length > 0
|
||||
? `Loaded ${memoryContent.length} characters from ${fileCount} file(s).`
|
||||
|
||||
@@ -171,6 +171,18 @@ describe('<HistoryItemDisplay />', () => {
|
||||
expect(lastFrame()).toContain('Agent powering down. Goodbye!');
|
||||
});
|
||||
|
||||
it('renders InfoMessage for "debug" type with gear icon', () => {
|
||||
const item: HistoryItem = {
|
||||
...baseItem,
|
||||
type: MessageType.DEBUG,
|
||||
text: 'Debug info',
|
||||
};
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<HistoryItemDisplay {...baseItem} item={item} />,
|
||||
);
|
||||
expect(lastFrame()).toContain('⚙ Debug info');
|
||||
});
|
||||
|
||||
it('should escape ANSI codes in text content', () => {
|
||||
const historyItem: HistoryItem = {
|
||||
id: 1,
|
||||
|
||||
@@ -18,6 +18,7 @@ import { GeminiMessageContent } from './messages/GeminiMessageContent.js';
|
||||
import { CompressionMessage } from './messages/CompressionMessage.js';
|
||||
import { WarningMessage } from './messages/WarningMessage.js';
|
||||
import { Box } from 'ink';
|
||||
import { theme } from '../semantic-colors.js';
|
||||
import { AboutBox } from './AboutBox.js';
|
||||
import { StatsDisplay } from './StatsDisplay.js';
|
||||
import { ModelStatsDisplay } from './ModelStatsDisplay.js';
|
||||
@@ -96,6 +97,27 @@ export const HistoryItemDisplay: React.FC<HistoryItemDisplayProps> = ({
|
||||
color={itemForDisplay.color}
|
||||
/>
|
||||
)}
|
||||
{itemForDisplay.type === 'verbose' && (
|
||||
<InfoMessage
|
||||
text={itemForDisplay.text}
|
||||
icon={itemForDisplay.icon || 'ℹ '}
|
||||
color={theme.text.secondary}
|
||||
/>
|
||||
)}
|
||||
{itemForDisplay.type === 'debug' && (
|
||||
<InfoMessage
|
||||
text={itemForDisplay.text}
|
||||
icon={'⚙ '}
|
||||
color={theme.text.accent}
|
||||
/>
|
||||
)}
|
||||
{itemForDisplay.type === 'trace' && (
|
||||
<InfoMessage
|
||||
text={itemForDisplay.text}
|
||||
icon={'🔍 '}
|
||||
color={theme.text.accent}
|
||||
/>
|
||||
)}
|
||||
{itemForDisplay.type === 'warning' && (
|
||||
<WarningMessage text={itemForDisplay.text} />
|
||||
)}
|
||||
|
||||
@@ -7,13 +7,14 @@
|
||||
import { renderWithProviders } from '../../test-utils/render.js';
|
||||
import { waitFor } from '../../test-utils/async.js';
|
||||
import { MainContent } from './MainContent.js';
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||
import { Box, Text } from 'ink';
|
||||
import type React from 'react';
|
||||
import { useAlternateBuffer } from '../hooks/useAlternateBuffer.js';
|
||||
import { ToolCallStatus } from '../types.js';
|
||||
import { SHELL_COMMAND_NAME } from '../constants.js';
|
||||
import type { UIState } from '../contexts/UIStateContext.js';
|
||||
import type { HistoryItem } from '../types.js';
|
||||
|
||||
// Mock dependencies
|
||||
vi.mock('../contexts/AppContext.js', async () => {
|
||||
@@ -26,6 +27,23 @@ vi.mock('../contexts/AppContext.js', async () => {
|
||||
};
|
||||
});
|
||||
|
||||
const mockSettings = {
|
||||
merged: {
|
||||
output: {
|
||||
verbosity: 'info',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
vi.mock('../contexts/SettingsContext.js', async (importOriginal) => {
|
||||
const actual =
|
||||
await importOriginal<typeof import('../contexts/SettingsContext.js')>();
|
||||
return {
|
||||
...actual,
|
||||
useSettings: () => mockSettings,
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock('../hooks/useAlternateBuffer.js', () => ({
|
||||
useAlternateBuffer: vi.fn(),
|
||||
}));
|
||||
@@ -78,6 +96,11 @@ describe('MainContent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
vi.mocked(useAlternateBuffer).mockReturnValue(false);
|
||||
mockSettings.merged.output.verbosity = 'info';
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('renders in normal buffer mode', async () => {
|
||||
@@ -221,4 +244,38 @@ describe('MainContent', () => {
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
it('filters out verbose items when verbosity is info', async () => {
|
||||
const history: HistoryItem[] = [
|
||||
{ id: 1, type: 'user', text: 'Visible User Message' },
|
||||
{ id: 2, type: 'verbose', text: 'Hidden Verbose Log' },
|
||||
];
|
||||
mockSettings.merged.output.verbosity = 'info';
|
||||
|
||||
const { lastFrame } = renderWithProviders(<MainContent />, {
|
||||
uiState: { ...defaultMockUiState, history } as Partial<UIState>,
|
||||
});
|
||||
await waitFor(() => expect(lastFrame()).toContain('AppHeader'));
|
||||
const output = lastFrame();
|
||||
|
||||
expect(output).toContain('Visible User Message');
|
||||
expect(output).not.toContain('Hidden Verbose Log');
|
||||
});
|
||||
|
||||
it('shows verbose items when verbosity is verbose', async () => {
|
||||
const history: HistoryItem[] = [
|
||||
{ id: 1, type: 'user', text: 'Visible User Message' },
|
||||
{ id: 2, type: 'verbose', text: 'Visible Verbose Log' },
|
||||
];
|
||||
mockSettings.merged.output.verbosity = 'verbose';
|
||||
|
||||
const { lastFrame } = renderWithProviders(<MainContent />, {
|
||||
uiState: { ...defaultMockUiState, history } as Partial<UIState>,
|
||||
});
|
||||
await waitFor(() => expect(lastFrame()).toContain('AppHeader'));
|
||||
const output = lastFrame();
|
||||
|
||||
expect(output).toContain('Visible User Message');
|
||||
expect(output).toContain('Visible Verbose Log');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -20,6 +20,8 @@ import { MAX_GEMINI_MESSAGE_LINES } from '../constants.js';
|
||||
import { useConfirmingTool } from '../hooks/useConfirmingTool.js';
|
||||
import { ToolConfirmationQueue } from './ToolConfirmationQueue.js';
|
||||
import { useConfig } from '../contexts/ConfigContext.js';
|
||||
import { VERBOSITY_MAPPING, Verbosity } from '../types.js';
|
||||
import { useSettings } from '../contexts/SettingsContext.js';
|
||||
|
||||
const MemoizedHistoryItemDisplay = memo(HistoryItemDisplay);
|
||||
const MemoizedAppHeader = memo(AppHeader);
|
||||
@@ -32,6 +34,7 @@ export const MainContent = () => {
|
||||
const { version } = useAppContext();
|
||||
const uiState = useUIState();
|
||||
const config = useConfig();
|
||||
const settings = useSettings();
|
||||
const isAlternateBuffer = useAlternateBuffer();
|
||||
|
||||
const confirmingTool = useConfirmingTool();
|
||||
@@ -53,9 +56,24 @@ export const MainContent = () => {
|
||||
availableTerminalHeight,
|
||||
} = uiState;
|
||||
|
||||
const currentVerbosity =
|
||||
VERBOSITY_MAPPING[settings.merged.output?.verbosity ?? 'info'] ??
|
||||
Verbosity.INFO;
|
||||
|
||||
const filteredHistory = useMemo(
|
||||
() =>
|
||||
uiState.history.filter((item) => {
|
||||
const itemType = item.type;
|
||||
const itemVerbosity =
|
||||
item.verbosity ?? VERBOSITY_MAPPING[itemType] ?? Verbosity.INFO;
|
||||
return itemVerbosity <= currentVerbosity;
|
||||
}),
|
||||
[uiState.history, currentVerbosity],
|
||||
);
|
||||
|
||||
const historyItems = useMemo(
|
||||
() =>
|
||||
uiState.history.map((h) => (
|
||||
filteredHistory.map((h) => (
|
||||
<MemoizedHistoryItemDisplay
|
||||
terminalWidth={mainAreaWidth}
|
||||
availableTerminalHeight={staticAreaMaxItemHeight}
|
||||
@@ -67,7 +85,7 @@ export const MainContent = () => {
|
||||
/>
|
||||
)),
|
||||
[
|
||||
uiState.history,
|
||||
filteredHistory,
|
||||
mainAreaWidth,
|
||||
staticAreaMaxItemHeight,
|
||||
uiState.slashCommands,
|
||||
@@ -116,10 +134,10 @@ export const MainContent = () => {
|
||||
const virtualizedData = useMemo(
|
||||
() => [
|
||||
{ type: 'header' as const },
|
||||
...uiState.history.map((item) => ({ type: 'history' as const, item })),
|
||||
...filteredHistory.map((item) => ({ type: 'history' as const, item })),
|
||||
{ type: 'pending' as const },
|
||||
],
|
||||
[uiState.history],
|
||||
[filteredHistory],
|
||||
);
|
||||
|
||||
const renderItem = useCallback(
|
||||
|
||||
+35
-45
@@ -1,28 +1,5 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`AlternateBufferQuittingDisplay > renders with a tool awaiting confirmation > with_confirming_tool 1`] = `
|
||||
"
|
||||
███ █████████
|
||||
░░░███ ███░░░░░███
|
||||
░░░███ ███ ░░░
|
||||
░░░███░███
|
||||
███░ ░███ █████
|
||||
███░ ░░███ ░░███
|
||||
███░ ░░█████████
|
||||
░░░ ░░░░░░░░░
|
||||
|
||||
Tips for getting started:
|
||||
1. Ask questions, edit files, or run commands.
|
||||
2. Be specific for the best results.
|
||||
3. Create GEMINI.md files to customize your interactions with Gemini.
|
||||
4. /help for more information.
|
||||
|
||||
Action Required (was prompted):
|
||||
|
||||
? confirming_tool Confirming tool description
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`AlternateBufferQuittingDisplay > renders with active and pending tool messages > with_history_and_pending 1`] = `
|
||||
"
|
||||
███ █████████
|
||||
@@ -39,14 +16,21 @@ Tips for getting started:
|
||||
2. Be specific for the best results.
|
||||
3. Create GEMINI.md files to customize your interactions with Gemini.
|
||||
4. /help for more information.
|
||||
╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool1 Description for tool 1 │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯
|
||||
╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool2 Description for tool 2 │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
╭─────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool1 Description for tool 1 │
|
||||
│ │
|
||||
╰─────────────────────────────────────────────────────────────────────────────╯
|
||||
|
||||
╭─────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool2 Description for tool 2 │
|
||||
│ │
|
||||
╰─────────────────────────────────────────────────────────────────────────────╯
|
||||
|
||||
╭─────────────────────────────────────────────────────────────────────────────╮
|
||||
│ o tool3 Description for tool 3 │
|
||||
│ │
|
||||
╰─────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`AlternateBufferQuittingDisplay > renders with empty history and no pending items > empty 1`] = `
|
||||
@@ -83,14 +67,16 @@ Tips for getting started:
|
||||
2. Be specific for the best results.
|
||||
3. Create GEMINI.md files to customize your interactions with Gemini.
|
||||
4. /help for more information.
|
||||
╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool1 Description for tool 1 │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯
|
||||
╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool2 Description for tool 2 │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
╭─────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool1 Description for tool 1 │
|
||||
│ │
|
||||
╰─────────────────────────────────────────────────────────────────────────────╯
|
||||
|
||||
╭─────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool2 Description for tool 2 │
|
||||
│ │
|
||||
╰─────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`AlternateBufferQuittingDisplay > renders with pending items but no history > with_pending_no_history 1`] = `
|
||||
@@ -108,7 +94,12 @@ Tips for getting started:
|
||||
1. Ask questions, edit files, or run commands.
|
||||
2. Be specific for the best results.
|
||||
3. Create GEMINI.md files to customize your interactions with Gemini.
|
||||
4. /help for more information."
|
||||
4. /help for more information.
|
||||
╭─────────────────────────────────────────────────────────────────────────────╮
|
||||
│ o tool3 Description for tool 3 │
|
||||
│ │
|
||||
╰─────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`AlternateBufferQuittingDisplay > renders with user and gemini messages > with_user_gemini_messages 1`] = `
|
||||
@@ -127,9 +118,8 @@ Tips for getting started:
|
||||
2. Be specific for the best results.
|
||||
3. Create GEMINI.md files to customize your interactions with Gemini.
|
||||
4. /help for more information.
|
||||
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
|
||||
> Hello Gemini
|
||||
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
|
||||
✦ Hello User!
|
||||
"
|
||||
|
||||
> Hello Gemini
|
||||
|
||||
✦ Hello User!"
|
||||
`;
|
||||
|
||||
@@ -28,7 +28,8 @@ AppHeader
|
||||
│ Line 20 │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||
ShowMoreLines"
|
||||
ShowMoreLines
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`MainContent > MainContent Tool Output Height Logic > 'ASB mode - Unfocused shell' 1`] = `
|
||||
@@ -53,7 +54,8 @@ AppHeader
|
||||
│ Line 19 █ │
|
||||
│ Line 20 █ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||
ShowMoreLines"
|
||||
ShowMoreLines
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`MainContent > MainContent Tool Output Height Logic > 'Normal mode - Constrained height' 1`] = `
|
||||
@@ -77,7 +79,8 @@ exports[`MainContent > MainContent Tool Output Height Logic > 'Normal mode - Con
|
||||
│ Line 19 │
|
||||
│ Line 20 │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||
ShowMoreLines"
|
||||
ShowMoreLines
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`MainContent > MainContent Tool Output Height Logic > 'Normal mode - Unconstrained height' 1`] = `
|
||||
@@ -101,7 +104,8 @@ exports[`MainContent > MainContent Tool Output Height Logic > 'Normal mode - Unc
|
||||
│ Line 19 │
|
||||
│ Line 20 │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||
ShowMoreLines"
|
||||
ShowMoreLines
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`MainContent > does not constrain height in alternate buffer mode 1`] = `
|
||||
|
||||
@@ -10,236 +10,9 @@ exports[`SettingsDialog > Initial Rendering > should render settings list with v
|
||||
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ ▲ │
|
||||
│ ● Vim Mode false │
|
||||
│ Enable Vim keybindings │
|
||||
│ ● Preview Features (e.g., models) false │
|
||||
│ Enable preview features (e.g., preview models). │
|
||||
│ │
|
||||
│ Enable Auto Update true │
|
||||
│ Enable automatic updates. │
|
||||
│ │
|
||||
│ Enable Prompt Completion false │
|
||||
│ Enable AI-powered prompt completion suggestions while typing. │
|
||||
│ │
|
||||
│ Debug Keystroke Logging false │
|
||||
│ Enable debug logging of keystrokes to the console. │
|
||||
│ │
|
||||
│ Enable Session Cleanup false │
|
||||
│ Enable automatic session cleanup │
|
||||
│ │
|
||||
│ Output Format Text │
|
||||
│ The format of the CLI output. Can be \`text\` or \`json\`. │
|
||||
│ │
|
||||
│ Auto Theme Switching true │
|
||||
│ Automatically switch between default light and dark themes based on terminal backgro… │
|
||||
│ │
|
||||
│ Terminal Background Polling Interval 60 │
|
||||
│ Interval in seconds to poll the terminal background color. │
|
||||
│ │
|
||||
│ ▼ │
|
||||
│ │
|
||||
│ Apply To │
|
||||
│ ● User Settings │
|
||||
│ Workspace Settings │
|
||||
│ System Settings │
|
||||
│ │
|
||||
│ (Use Enter to select, Ctrl+L to reset, Tab to change focus, Esc to close) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`SettingsDialog > Snapshot Tests > should render 'accessibility settings enabled' correctly 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ │
|
||||
│ > Settings │
|
||||
│ │
|
||||
│ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │
|
||||
│ │ Search to filter │ │
|
||||
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ ▲ │
|
||||
│ ● Vim Mode true* │
|
||||
│ Enable Vim keybindings │
|
||||
│ │
|
||||
│ Enable Auto Update true │
|
||||
│ Enable automatic updates. │
|
||||
│ │
|
||||
│ Enable Prompt Completion false │
|
||||
│ Enable AI-powered prompt completion suggestions while typing. │
|
||||
│ │
|
||||
│ Debug Keystroke Logging false │
|
||||
│ Enable debug logging of keystrokes to the console. │
|
||||
│ │
|
||||
│ Enable Session Cleanup false │
|
||||
│ Enable automatic session cleanup │
|
||||
│ │
|
||||
│ Output Format Text │
|
||||
│ The format of the CLI output. Can be \`text\` or \`json\`. │
|
||||
│ │
|
||||
│ Auto Theme Switching true │
|
||||
│ Automatically switch between default light and dark themes based on terminal backgro… │
|
||||
│ │
|
||||
│ Terminal Background Polling Interval 60 │
|
||||
│ Interval in seconds to poll the terminal background color. │
|
||||
│ │
|
||||
│ ▼ │
|
||||
│ │
|
||||
│ Apply To │
|
||||
│ ● User Settings │
|
||||
│ Workspace Settings │
|
||||
│ System Settings │
|
||||
│ │
|
||||
│ (Use Enter to select, Ctrl+L to reset, Tab to change focus, Esc to close) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`SettingsDialog > Snapshot Tests > should render 'all boolean settings disabled' correctly 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ │
|
||||
│ > Settings │
|
||||
│ │
|
||||
│ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │
|
||||
│ │ Search to filter │ │
|
||||
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ ▲ │
|
||||
│ ● Vim Mode false* │
|
||||
│ Enable Vim keybindings │
|
||||
│ │
|
||||
│ Enable Auto Update true* │
|
||||
│ Enable automatic updates. │
|
||||
│ │
|
||||
│ Enable Prompt Completion false* │
|
||||
│ Enable AI-powered prompt completion suggestions while typing. │
|
||||
│ │
|
||||
│ Debug Keystroke Logging false* │
|
||||
│ Enable debug logging of keystrokes to the console. │
|
||||
│ │
|
||||
│ Enable Session Cleanup false │
|
||||
│ Enable automatic session cleanup │
|
||||
│ │
|
||||
│ Output Format Text │
|
||||
│ The format of the CLI output. Can be \`text\` or \`json\`. │
|
||||
│ │
|
||||
│ Auto Theme Switching true │
|
||||
│ Automatically switch between default light and dark themes based on terminal backgro… │
|
||||
│ │
|
||||
│ Terminal Background Polling Interval 60 │
|
||||
│ Interval in seconds to poll the terminal background color. │
|
||||
│ │
|
||||
│ ▼ │
|
||||
│ │
|
||||
│ Apply To │
|
||||
│ ● User Settings │
|
||||
│ Workspace Settings │
|
||||
│ System Settings │
|
||||
│ │
|
||||
│ (Use Enter to select, Ctrl+L to reset, Tab to change focus, Esc to close) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`SettingsDialog > Snapshot Tests > should render 'default state' correctly 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ │
|
||||
│ > Settings │
|
||||
│ │
|
||||
│ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │
|
||||
│ │ Search to filter │ │
|
||||
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ ▲ │
|
||||
│ ● Vim Mode false │
|
||||
│ Enable Vim keybindings │
|
||||
│ │
|
||||
│ Enable Auto Update true │
|
||||
│ Enable automatic updates. │
|
||||
│ │
|
||||
│ Enable Prompt Completion false │
|
||||
│ Enable AI-powered prompt completion suggestions while typing. │
|
||||
│ │
|
||||
│ Debug Keystroke Logging false │
|
||||
│ Enable debug logging of keystrokes to the console. │
|
||||
│ │
|
||||
│ Enable Session Cleanup false │
|
||||
│ Enable automatic session cleanup │
|
||||
│ │
|
||||
│ Output Format Text │
|
||||
│ The format of the CLI output. Can be \`text\` or \`json\`. │
|
||||
│ │
|
||||
│ Auto Theme Switching true │
|
||||
│ Automatically switch between default light and dark themes based on terminal backgro… │
|
||||
│ │
|
||||
│ Terminal Background Polling Interval 60 │
|
||||
│ Interval in seconds to poll the terminal background color. │
|
||||
│ │
|
||||
│ ▼ │
|
||||
│ │
|
||||
│ Apply To │
|
||||
│ ● User Settings │
|
||||
│ Workspace Settings │
|
||||
│ System Settings │
|
||||
│ │
|
||||
│ (Use Enter to select, Ctrl+L to reset, Tab to change focus, Esc to close) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`SettingsDialog > Snapshot Tests > should render 'file filtering settings configured' correctly 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ │
|
||||
│ > Settings │
|
||||
│ │
|
||||
│ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │
|
||||
│ │ Search to filter │ │
|
||||
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ ▲ │
|
||||
│ ● Vim Mode false │
|
||||
│ Enable Vim keybindings │
|
||||
│ │
|
||||
│ Enable Auto Update true │
|
||||
│ Enable automatic updates. │
|
||||
│ │
|
||||
│ Enable Prompt Completion false │
|
||||
│ Enable AI-powered prompt completion suggestions while typing. │
|
||||
│ │
|
||||
│ Debug Keystroke Logging false │
|
||||
│ Enable debug logging of keystrokes to the console. │
|
||||
│ │
|
||||
│ Enable Session Cleanup false │
|
||||
│ Enable automatic session cleanup │
|
||||
│ │
|
||||
│ Output Format Text │
|
||||
│ The format of the CLI output. Can be \`text\` or \`json\`. │
|
||||
│ │
|
||||
│ Auto Theme Switching true │
|
||||
│ Automatically switch between default light and dark themes based on terminal backgro… │
|
||||
│ │
|
||||
│ Terminal Background Polling Interval 60 │
|
||||
│ Interval in seconds to poll the terminal background color. │
|
||||
│ │
|
||||
│ ▼ │
|
||||
│ │
|
||||
│ Apply To │
|
||||
│ ● User Settings │
|
||||
│ Workspace Settings │
|
||||
│ System Settings │
|
||||
│ │
|
||||
│ (Use Enter to select, Ctrl+L to reset, Tab to change focus, Esc to close) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`SettingsDialog > Snapshot Tests > should render 'focused on scope selector' correctly 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ │
|
||||
│ Settings │
|
||||
│ │
|
||||
│ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │
|
||||
│ │ Search to filter │ │
|
||||
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ ▲ │
|
||||
│ Vim Mode false │
|
||||
│ Enable Vim keybindings │
|
||||
│ │
|
||||
@@ -258,57 +31,8 @@ exports[`SettingsDialog > Snapshot Tests > should render 'focused on scope selec
|
||||
│ Output Format Text │
|
||||
│ The format of the CLI output. Can be \`text\` or \`json\`. │
|
||||
│ │
|
||||
│ Auto Theme Switching true │
|
||||
│ Automatically switch between default light and dark themes based on terminal backgro… │
|
||||
│ │
|
||||
│ Terminal Background Polling Interval 60 │
|
||||
│ Interval in seconds to poll the terminal background color. │
|
||||
│ │
|
||||
│ ▼ │
|
||||
│ │
|
||||
│ > Apply To │
|
||||
│ ● 1. User Settings │
|
||||
│ 2. Workspace Settings │
|
||||
│ 3. System Settings │
|
||||
│ │
|
||||
│ (Use Enter to select, Ctrl+L to reset, Tab to change focus, Esc to close) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`SettingsDialog > Snapshot Tests > should render 'mixed boolean and number settings' correctly 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ │
|
||||
│ > Settings │
|
||||
│ │
|
||||
│ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │
|
||||
│ │ Search to filter │ │
|
||||
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ ▲ │
|
||||
│ ● Vim Mode false* │
|
||||
│ Enable Vim keybindings │
|
||||
│ │
|
||||
│ Enable Auto Update false* │
|
||||
│ Enable automatic updates. │
|
||||
│ │
|
||||
│ Enable Prompt Completion false │
|
||||
│ Enable AI-powered prompt completion suggestions while typing. │
|
||||
│ │
|
||||
│ Debug Keystroke Logging false │
|
||||
│ Enable debug logging of keystrokes to the console. │
|
||||
│ │
|
||||
│ Enable Session Cleanup false │
|
||||
│ Enable automatic session cleanup │
|
||||
│ │
|
||||
│ Output Format Text │
|
||||
│ The format of the CLI output. Can be \`text\` or \`json\`. │
|
||||
│ │
|
||||
│ Auto Theme Switching true │
|
||||
│ Automatically switch between default light and dark themes based on terminal backgro… │
|
||||
│ │
|
||||
│ Terminal Background Polling Interval 60 │
|
||||
│ Interval in seconds to poll the terminal background color. │
|
||||
│ Verbose Output History true │
|
||||
│ Show verbose output history. When enabled, output history will include autonomous to… │
|
||||
│ │
|
||||
│ ▼ │
|
||||
│ │
|
||||
@@ -317,12 +41,12 @@ exports[`SettingsDialog > Snapshot Tests > should render 'mixed boolean and numb
|
||||
│ Workspace Settings │
|
||||
│ System Settings │
|
||||
│ │
|
||||
│ (Use Enter to select, Ctrl+L to reset, Tab to change focus, Esc to close) │
|
||||
│ (Use Enter to select, Tab to change focus, Esc to close) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`SettingsDialog > Snapshot Tests > should render 'tools and security settings' correctly 1`] = `
|
||||
exports[`SettingsDialog > Snapshot Tests > should render 'accessibility settings enabled' correctly 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ │
|
||||
│ > Settings │
|
||||
@@ -332,7 +56,10 @@ exports[`SettingsDialog > Snapshot Tests > should render 'tools and security set
|
||||
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ ▲ │
|
||||
│ ● Vim Mode false │
|
||||
│ ● Preview Features (e.g., models) false │
|
||||
│ Enable preview features (e.g., preview models). │
|
||||
│ │
|
||||
│ Vim Mode true* │
|
||||
│ Enable Vim keybindings │
|
||||
│ │
|
||||
│ Enable Auto Update true │
|
||||
@@ -350,11 +77,8 @@ exports[`SettingsDialog > Snapshot Tests > should render 'tools and security set
|
||||
│ Output Format Text │
|
||||
│ The format of the CLI output. Can be \`text\` or \`json\`. │
|
||||
│ │
|
||||
│ Auto Theme Switching true │
|
||||
│ Automatically switch between default light and dark themes based on terminal backgro… │
|
||||
│ │
|
||||
│ Terminal Background Polling Interval 60 │
|
||||
│ Interval in seconds to poll the terminal background color. │
|
||||
│ Verbose Output History true │
|
||||
│ Show verbose output history. When enabled, output history will include autonomous to… │
|
||||
│ │
|
||||
│ ▼ │
|
||||
│ │
|
||||
@@ -363,7 +87,283 @@ exports[`SettingsDialog > Snapshot Tests > should render 'tools and security set
|
||||
│ Workspace Settings │
|
||||
│ System Settings │
|
||||
│ │
|
||||
│ (Use Enter to select, Ctrl+L to reset, Tab to change focus, Esc to close) │
|
||||
│ (Use Enter to select, Tab to change focus, Esc to close) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`SettingsDialog > Snapshot Tests > should render 'all boolean settings disabled' correctly 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ │
|
||||
│ > Settings │
|
||||
│ │
|
||||
│ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │
|
||||
│ │ Search to filter │ │
|
||||
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ ▲ │
|
||||
│ ● Preview Features (e.g., models) false │
|
||||
│ Enable preview features (e.g., preview models). │
|
||||
│ │
|
||||
│ Vim Mode false* │
|
||||
│ Enable Vim keybindings │
|
||||
│ │
|
||||
│ Enable Auto Update true* │
|
||||
│ Enable automatic updates. │
|
||||
│ │
|
||||
│ Enable Prompt Completion false* │
|
||||
│ Enable AI-powered prompt completion suggestions while typing. │
|
||||
│ │
|
||||
│ Debug Keystroke Logging false* │
|
||||
│ Enable debug logging of keystrokes to the console. │
|
||||
│ │
|
||||
│ Enable Session Cleanup false │
|
||||
│ Enable automatic session cleanup │
|
||||
│ │
|
||||
│ Output Format Text │
|
||||
│ The format of the CLI output. Can be \`text\` or \`json\`. │
|
||||
│ │
|
||||
│ Verbose Output History true │
|
||||
│ Show verbose output history. When enabled, output history will include autonomous to… │
|
||||
│ │
|
||||
│ ▼ │
|
||||
│ │
|
||||
│ Apply To │
|
||||
│ ● User Settings │
|
||||
│ Workspace Settings │
|
||||
│ System Settings │
|
||||
│ │
|
||||
│ (Use Enter to select, Tab to change focus, Esc to close) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`SettingsDialog > Snapshot Tests > should render 'default state' correctly 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ │
|
||||
│ > Settings │
|
||||
│ │
|
||||
│ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │
|
||||
│ │ Search to filter │ │
|
||||
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ ▲ │
|
||||
│ ● Preview Features (e.g., models) false │
|
||||
│ Enable preview features (e.g., preview models). │
|
||||
│ │
|
||||
│ Vim Mode false │
|
||||
│ Enable Vim keybindings │
|
||||
│ │
|
||||
│ Enable Auto Update true │
|
||||
│ Enable automatic updates. │
|
||||
│ │
|
||||
│ Enable Prompt Completion false │
|
||||
│ Enable AI-powered prompt completion suggestions while typing. │
|
||||
│ │
|
||||
│ Debug Keystroke Logging false │
|
||||
│ Enable debug logging of keystrokes to the console. │
|
||||
│ │
|
||||
│ Enable Session Cleanup false │
|
||||
│ Enable automatic session cleanup │
|
||||
│ │
|
||||
│ Output Format Text │
|
||||
│ The format of the CLI output. Can be \`text\` or \`json\`. │
|
||||
│ │
|
||||
│ Verbose Output History true │
|
||||
│ Show verbose output history. When enabled, output history will include autonomous to… │
|
||||
│ │
|
||||
│ ▼ │
|
||||
│ │
|
||||
│ Apply To │
|
||||
│ ● User Settings │
|
||||
│ Workspace Settings │
|
||||
│ System Settings │
|
||||
│ │
|
||||
│ (Use Enter to select, Tab to change focus, Esc to close) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`SettingsDialog > Snapshot Tests > should render 'file filtering settings configured' correctly 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ │
|
||||
│ > Settings │
|
||||
│ │
|
||||
│ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │
|
||||
│ │ Search to filter │ │
|
||||
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ ▲ │
|
||||
│ ● Preview Features (e.g., models) false │
|
||||
│ Enable preview features (e.g., preview models). │
|
||||
│ │
|
||||
│ Vim Mode false │
|
||||
│ Enable Vim keybindings │
|
||||
│ │
|
||||
│ Enable Auto Update true │
|
||||
│ Enable automatic updates. │
|
||||
│ │
|
||||
│ Enable Prompt Completion false │
|
||||
│ Enable AI-powered prompt completion suggestions while typing. │
|
||||
│ │
|
||||
│ Debug Keystroke Logging false │
|
||||
│ Enable debug logging of keystrokes to the console. │
|
||||
│ │
|
||||
│ Enable Session Cleanup false │
|
||||
│ Enable automatic session cleanup │
|
||||
│ │
|
||||
│ Output Format Text │
|
||||
│ The format of the CLI output. Can be \`text\` or \`json\`. │
|
||||
│ │
|
||||
│ Verbose Output History true │
|
||||
│ Show verbose output history. When enabled, output history will include autonomous to… │
|
||||
│ │
|
||||
│ ▼ │
|
||||
│ │
|
||||
│ Apply To │
|
||||
│ ● User Settings │
|
||||
│ Workspace Settings │
|
||||
│ System Settings │
|
||||
│ │
|
||||
│ (Use Enter to select, Tab to change focus, Esc to close) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`SettingsDialog > Snapshot Tests > should render 'focused on scope selector' correctly 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ │
|
||||
│ Settings │
|
||||
│ │
|
||||
│ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │
|
||||
│ │ Search to filter │ │
|
||||
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ ▲ │
|
||||
│ Preview Features (e.g., models) false │
|
||||
│ Enable preview features (e.g., preview models). │
|
||||
│ │
|
||||
│ Vim Mode false │
|
||||
│ Enable Vim keybindings │
|
||||
│ │
|
||||
│ Enable Auto Update true │
|
||||
│ Enable automatic updates. │
|
||||
│ │
|
||||
│ Enable Prompt Completion false │
|
||||
│ Enable AI-powered prompt completion suggestions while typing. │
|
||||
│ │
|
||||
│ Debug Keystroke Logging false │
|
||||
│ Enable debug logging of keystrokes to the console. │
|
||||
│ │
|
||||
│ Enable Session Cleanup false │
|
||||
│ Enable automatic session cleanup │
|
||||
│ │
|
||||
│ Output Format Text │
|
||||
│ The format of the CLI output. Can be \`text\` or \`json\`. │
|
||||
│ │
|
||||
│ Verbose Output History true │
|
||||
│ Show verbose output history. When enabled, output history will include autonomous to… │
|
||||
│ │
|
||||
│ ▼ │
|
||||
│ │
|
||||
│ > Apply To │
|
||||
│ ● 1. User Settings │
|
||||
│ 2. Workspace Settings │
|
||||
│ 3. System Settings │
|
||||
│ │
|
||||
│ (Use Enter to select, Tab to change focus, Esc to close) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`SettingsDialog > Snapshot Tests > should render 'mixed boolean and number settings' correctly 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ │
|
||||
│ > Settings │
|
||||
│ │
|
||||
│ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │
|
||||
│ │ Search to filter │ │
|
||||
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ ▲ │
|
||||
│ ● Preview Features (e.g., models) false │
|
||||
│ Enable preview features (e.g., preview models). │
|
||||
│ │
|
||||
│ Vim Mode false* │
|
||||
│ Enable Vim keybindings │
|
||||
│ │
|
||||
│ Enable Auto Update false* │
|
||||
│ Enable automatic updates. │
|
||||
│ │
|
||||
│ Enable Prompt Completion false │
|
||||
│ Enable AI-powered prompt completion suggestions while typing. │
|
||||
│ │
|
||||
│ Debug Keystroke Logging false │
|
||||
│ Enable debug logging of keystrokes to the console. │
|
||||
│ │
|
||||
│ Enable Session Cleanup false │
|
||||
│ Enable automatic session cleanup │
|
||||
│ │
|
||||
│ Output Format Text │
|
||||
│ The format of the CLI output. Can be \`text\` or \`json\`. │
|
||||
│ │
|
||||
│ Verbose Output History true │
|
||||
│ Show verbose output history. When enabled, output history will include autonomous to… │
|
||||
│ │
|
||||
│ ▼ │
|
||||
│ │
|
||||
│ Apply To │
|
||||
│ ● User Settings │
|
||||
│ Workspace Settings │
|
||||
│ System Settings │
|
||||
│ │
|
||||
│ (Use Enter to select, Tab to change focus, Esc to close) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`SettingsDialog > Snapshot Tests > should render 'tools and security settings' correctly 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||
│ │
|
||||
│ > Settings │
|
||||
│ │
|
||||
│ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │
|
||||
│ │ Search to filter │ │
|
||||
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ ▲ │
|
||||
│ ● Preview Features (e.g., models) false │
|
||||
│ Enable preview features (e.g., preview models). │
|
||||
│ │
|
||||
│ Vim Mode false │
|
||||
│ Enable Vim keybindings │
|
||||
│ │
|
||||
│ Enable Auto Update true │
|
||||
│ Enable automatic updates. │
|
||||
│ │
|
||||
│ Enable Prompt Completion false │
|
||||
│ Enable AI-powered prompt completion suggestions while typing. │
|
||||
│ │
|
||||
│ Debug Keystroke Logging false │
|
||||
│ Enable debug logging of keystrokes to the console. │
|
||||
│ │
|
||||
│ Enable Session Cleanup false │
|
||||
│ Enable automatic session cleanup │
|
||||
│ │
|
||||
│ Output Format Text │
|
||||
│ The format of the CLI output. Can be \`text\` or \`json\`. │
|
||||
│ │
|
||||
│ Verbose Output History true │
|
||||
│ Show verbose output history. When enabled, output history will include autonomous to… │
|
||||
│ │
|
||||
│ ▼ │
|
||||
│ │
|
||||
│ Apply To │
|
||||
│ ● User Settings │
|
||||
│ Workspace Settings │
|
||||
│ System Settings │
|
||||
│ │
|
||||
│ (Use Enter to select, Tab to change focus, Esc to close) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
@@ -378,7 +378,10 @@ exports[`SettingsDialog > Snapshot Tests > should render 'various boolean settin
|
||||
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯ │
|
||||
│ │
|
||||
│ ▲ │
|
||||
│ ● Vim Mode true* │
|
||||
│ ● Preview Features (e.g., models) false │
|
||||
│ Enable preview features (e.g., preview models). │
|
||||
│ │
|
||||
│ Vim Mode true* │
|
||||
│ Enable Vim keybindings │
|
||||
│ │
|
||||
│ Enable Auto Update false* │
|
||||
@@ -396,11 +399,8 @@ exports[`SettingsDialog > Snapshot Tests > should render 'various boolean settin
|
||||
│ Output Format Text │
|
||||
│ The format of the CLI output. Can be \`text\` or \`json\`. │
|
||||
│ │
|
||||
│ Auto Theme Switching true │
|
||||
│ Automatically switch between default light and dark themes based on terminal backgro… │
|
||||
│ │
|
||||
│ Terminal Background Polling Interval 60 │
|
||||
│ Interval in seconds to poll the terminal background color. │
|
||||
│ Verbose Output History true │
|
||||
│ Show verbose output history. When enabled, output history will include autonomous to… │
|
||||
│ │
|
||||
│ ▼ │
|
||||
│ │
|
||||
@@ -409,7 +409,7 @@ exports[`SettingsDialog > Snapshot Tests > should render 'various boolean settin
|
||||
│ Workspace Settings │
|
||||
│ System Settings │
|
||||
│ │
|
||||
│ (Use Enter to select, Ctrl+L to reset, Tab to change focus, Esc to close) │
|
||||
│ (Use Enter to select, Tab to change focus, Esc to close) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { renderWithProviders } from '../../../test-utils/render.js';
|
||||
import { DenseToolMessage } from './DenseToolMessage.js';
|
||||
import type { ToolResultDisplay } from '../../types.js';
|
||||
import { ToolCallStatus } from '../../types.js';
|
||||
|
||||
describe('DenseToolMessage', () => {
|
||||
const defaultProps = {
|
||||
callId: 'call-1',
|
||||
name: 'test-tool',
|
||||
description: 'Test description',
|
||||
status: ToolCallStatus.Success,
|
||||
resultDisplay: 'Success result',
|
||||
confirmationDetails: undefined,
|
||||
isFirst: true,
|
||||
};
|
||||
|
||||
it('renders correctly for a successful string result', () => {
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<DenseToolMessage {...defaultProps} />,
|
||||
);
|
||||
const output = lastFrame();
|
||||
expect(output).toContain('test-tool');
|
||||
expect(output).toContain('Test description');
|
||||
expect(output).toContain('→ Success result');
|
||||
});
|
||||
|
||||
it('truncates long string results', () => {
|
||||
const longResult = 'A'.repeat(200);
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<DenseToolMessage {...defaultProps} resultDisplay={longResult} />,
|
||||
);
|
||||
// Remove all whitespace to check the continuous string content truncation
|
||||
const output = lastFrame()?.replace(/\s/g, '');
|
||||
expect(output).toContain('A'.repeat(117) + '...');
|
||||
});
|
||||
|
||||
it('flattens newlines in string results', () => {
|
||||
const multilineResult = 'Line 1\nLine 2';
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<DenseToolMessage {...defaultProps} resultDisplay={multilineResult} />,
|
||||
);
|
||||
const output = lastFrame();
|
||||
expect(output).toContain('→ Line 1 Line 2');
|
||||
});
|
||||
|
||||
it('renders correctly for file diff results', () => {
|
||||
const diffResult = {
|
||||
fileDiff: 'diff content',
|
||||
fileName: 'test.ts',
|
||||
filePath: '/path/to/test.ts',
|
||||
originalContent: 'old content',
|
||||
newContent: 'new content',
|
||||
};
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<DenseToolMessage {...defaultProps} resultDisplay={diffResult} />,
|
||||
);
|
||||
const output = lastFrame();
|
||||
expect(output).toContain('→ Diff applied to test.ts');
|
||||
});
|
||||
|
||||
it('renders correctly for todo updates', () => {
|
||||
const todoResult = {
|
||||
todos: [],
|
||||
};
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<DenseToolMessage {...defaultProps} resultDisplay={todoResult} />,
|
||||
);
|
||||
const output = lastFrame();
|
||||
expect(output).toContain('→ Todos updated');
|
||||
});
|
||||
|
||||
it('renders generic output message for unknown object results', () => {
|
||||
const genericResult = {
|
||||
some: 'data',
|
||||
} as unknown as ToolResultDisplay;
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<DenseToolMessage {...defaultProps} resultDisplay={genericResult} />,
|
||||
);
|
||||
const output = lastFrame();
|
||||
expect(output).toContain('→ Output received');
|
||||
});
|
||||
|
||||
it('renders correctly for error status with string message', () => {
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<DenseToolMessage
|
||||
{...defaultProps}
|
||||
status={ToolCallStatus.Error}
|
||||
resultDisplay="Error occurred"
|
||||
/>,
|
||||
);
|
||||
const output = lastFrame();
|
||||
expect(output).toContain('→ Error occurred');
|
||||
});
|
||||
|
||||
it('renders generic failure message for error status without string message', () => {
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<DenseToolMessage
|
||||
{...defaultProps}
|
||||
status={ToolCallStatus.Error}
|
||||
resultDisplay={undefined}
|
||||
/>,
|
||||
);
|
||||
const output = lastFrame();
|
||||
expect(output).toContain('→ Failed');
|
||||
});
|
||||
|
||||
it('does not render result arrow if resultDisplay is missing', () => {
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<DenseToolMessage
|
||||
{...defaultProps}
|
||||
status={ToolCallStatus.Pending}
|
||||
resultDisplay={undefined}
|
||||
/>,
|
||||
);
|
||||
const output = lastFrame();
|
||||
expect(output).not.toContain('→');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type React from 'react';
|
||||
import { Box, Text } from 'ink';
|
||||
import { ToolCallStatus } from '../../types.js';
|
||||
import type { IndividualToolCallDisplay } from '../../types.js';
|
||||
import { ToolStatusIndicator } from './ToolShared.js';
|
||||
import { theme } from '../../semantic-colors.js';
|
||||
|
||||
interface DenseToolMessageProps extends IndividualToolCallDisplay {
|
||||
isFirst: boolean;
|
||||
}
|
||||
|
||||
interface FileDiffResult {
|
||||
fileDiff: string;
|
||||
fileName: string;
|
||||
}
|
||||
|
||||
export const DenseToolMessage: React.FC<DenseToolMessageProps> = ({
|
||||
name,
|
||||
description,
|
||||
status,
|
||||
resultDisplay,
|
||||
}) => {
|
||||
let denseResult: string | undefined;
|
||||
|
||||
if (status === ToolCallStatus.Success && resultDisplay) {
|
||||
if (typeof resultDisplay === 'string') {
|
||||
const flattened = resultDisplay.replace(/\n/g, ' ').trim();
|
||||
denseResult =
|
||||
flattened.length > 120 ? flattened.slice(0, 117) + '...' : flattened;
|
||||
} else if (typeof resultDisplay === 'object') {
|
||||
if ('fileDiff' in resultDisplay) {
|
||||
denseResult = `Diff applied to ${(resultDisplay as FileDiffResult).fileName}`;
|
||||
} else if ('todos' in resultDisplay) {
|
||||
denseResult = 'Todos updated';
|
||||
} else {
|
||||
// Fallback for AnsiOutput or other objects
|
||||
denseResult = 'Output received';
|
||||
}
|
||||
}
|
||||
} else if (status === ToolCallStatus.Error) {
|
||||
if (typeof resultDisplay === 'string') {
|
||||
const flattened = resultDisplay.replace(/\n/g, ' ').trim();
|
||||
denseResult =
|
||||
flattened.length > 120 ? flattened.slice(0, 117) + '...' : flattened;
|
||||
} else {
|
||||
denseResult = 'Failed';
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Box marginLeft={3} flexDirection="row" flexWrap="wrap">
|
||||
<ToolStatusIndicator status={status} name={name} />
|
||||
<Box maxWidth={25} flexShrink={1} flexGrow={0}>
|
||||
<Text color={theme.text.primary} bold wrap="truncate-end">
|
||||
{name}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box marginLeft={1} flexShrink={1} flexGrow={0}>
|
||||
<Text color={theme.text.secondary} wrap="truncate-end">
|
||||
{description}
|
||||
</Text>
|
||||
</Box>
|
||||
{denseResult && (
|
||||
<Box marginLeft={1} flexGrow={1}>
|
||||
<Text color={theme.text.accent} wrap="wrap">
|
||||
→ {denseResult}
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
@@ -18,6 +18,8 @@ import { isShellTool, isThisShellFocused } from './ToolShared.js';
|
||||
import { ASK_USER_DISPLAY_NAME } from '@google/gemini-cli-core';
|
||||
import { ShowMoreLines } from '../ShowMoreLines.js';
|
||||
import { useUIState } from '../../contexts/UIStateContext.js';
|
||||
import { useSettings } from '../../contexts/SettingsContext.js';
|
||||
import { DenseToolMessage } from './DenseToolMessage.js';
|
||||
|
||||
interface ToolGroupMessageProps {
|
||||
groupId: number;
|
||||
@@ -63,6 +65,8 @@ export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
|
||||
|
||||
const config = useConfig();
|
||||
const { constrainHeight } = useUIState();
|
||||
const { merged: settings } = useSettings();
|
||||
const isVerboseMode = settings.output?.verbosity === 'verbose';
|
||||
|
||||
const isEventDriven = config.isEventDrivenSchedulerEnabled();
|
||||
|
||||
@@ -161,12 +165,25 @@ export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
|
||||
*/
|
||||
width={terminalWidth}
|
||||
paddingRight={TOOL_MESSAGE_HORIZONTAL_MARGIN}
|
||||
marginBottom={1}
|
||||
>
|
||||
{visibleToolCalls.map((tool, index) => {
|
||||
const isConfirming = toolAwaitingApproval?.callId === tool.callId;
|
||||
const isFirst = index === 0;
|
||||
const isShellToolCall = isShellTool(tool.name);
|
||||
|
||||
// Use dense view if not verbose, not a shell tool (for interactivity), and not confirming (needs prompt)
|
||||
const useDenseView =
|
||||
!isVerboseMode &&
|
||||
!isShellToolCall &&
|
||||
tool.status !== ToolCallStatus.Confirming;
|
||||
|
||||
if (useDenseView) {
|
||||
return (
|
||||
<DenseToolMessage key={tool.callId} {...tool} isFirst={isFirst} />
|
||||
);
|
||||
}
|
||||
|
||||
const commonProps = {
|
||||
...tool,
|
||||
availableTerminalHeight: availableTerminalHeightPerToolMessage,
|
||||
@@ -242,22 +259,59 @@ export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
|
||||
})}
|
||||
{
|
||||
/*
|
||||
We have to keep the bottom border separate so it doesn't get
|
||||
drawn over by the sticky header directly inside it.
|
||||
*/
|
||||
(visibleToolCalls.length > 0 || borderBottomOverride !== undefined) && (
|
||||
<Box
|
||||
height={0}
|
||||
width={contentWidth}
|
||||
borderLeft={true}
|
||||
borderRight={true}
|
||||
borderTop={false}
|
||||
borderBottom={borderBottomOverride ?? true}
|
||||
borderColor={borderColor}
|
||||
borderDimColor={borderDimColor}
|
||||
borderStyle="round"
|
||||
/>
|
||||
)
|
||||
We have to keep the bottom border separate so it doesn't get
|
||||
drawn over by the sticky header directly inside it.
|
||||
Only render if the last tool was displayed in full/verbose mode,
|
||||
or if explicitly overridden.
|
||||
*/
|
||||
(() => {
|
||||
if (visibleToolCalls.length === 0) {
|
||||
if (borderBottomOverride !== undefined) {
|
||||
return (
|
||||
<Box
|
||||
height={0}
|
||||
width={contentWidth}
|
||||
borderLeft={true}
|
||||
borderRight={true}
|
||||
borderTop={false}
|
||||
borderBottom={borderBottomOverride}
|
||||
borderColor={borderColor}
|
||||
borderDimColor={borderDimColor}
|
||||
borderStyle="round"
|
||||
/>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const lastTool = visibleToolCalls[visibleToolCalls.length - 1];
|
||||
const isShell = isShellTool(lastTool.name);
|
||||
const isConfirming = lastTool.status === ToolCallStatus.Confirming;
|
||||
|
||||
// Logic: If dense view (not verbose, not shell, not confirming), hide border by default
|
||||
const isDense = !isVerboseMode && !isShell && !isConfirming;
|
||||
let showBottomBorder = !isDense;
|
||||
|
||||
if (borderBottomOverride !== undefined) {
|
||||
showBottomBorder = borderBottomOverride;
|
||||
}
|
||||
|
||||
if (!showBottomBorder) return null;
|
||||
|
||||
return (
|
||||
<Box
|
||||
height={0}
|
||||
width={contentWidth}
|
||||
borderLeft={true}
|
||||
borderRight={true}
|
||||
borderTop={false}
|
||||
borderBottom={true}
|
||||
borderColor={borderColor}
|
||||
borderDimColor={borderDimColor}
|
||||
borderStyle="round"
|
||||
/>
|
||||
);
|
||||
})()
|
||||
}
|
||||
{(borderBottomOverride ?? true) && visibleToolCalls.length > 0 && (
|
||||
<Box paddingX={1}>
|
||||
|
||||
@@ -110,7 +110,7 @@ describe('ToolMessage Sticky Header Regression', () => {
|
||||
|
||||
// Scroll down so that tool-1's header should be stuck
|
||||
await act(async () => {
|
||||
listRef?.scrollBy(5);
|
||||
listRef?.scrollBy(6);
|
||||
});
|
||||
|
||||
// tool-1 header should still be visible because it is sticky
|
||||
@@ -120,10 +120,10 @@ describe('ToolMessage Sticky Header Regression', () => {
|
||||
expect(lastFrame()).toContain('Description for tool-1');
|
||||
// Content lines 1-4 should be scrolled off
|
||||
expect(lastFrame()).not.toContain('c1-01');
|
||||
expect(lastFrame()).not.toContain('c1-04');
|
||||
// Line 6 and 7 should be visible (terminalHeight=5 means only 2 lines of content show below 3-line header)
|
||||
expect(lastFrame()).toContain('c1-06');
|
||||
expect(lastFrame()).not.toContain('c1-05');
|
||||
// Line 7 and 8 should be visible (terminalHeight=5 means only 2 lines of content show below 3-line header)
|
||||
expect(lastFrame()).toContain('c1-07');
|
||||
expect(lastFrame()).toContain('c1-08');
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
|
||||
// Scroll further so tool-1 is completely gone and tool-2's header should be stuck
|
||||
|
||||
+181
-203
@@ -1,260 +1,238 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`<ToolGroupMessage /> > Ask User Filtering > does NOT filter out ask_user when status is Error 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ x Ask User │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Ask User Filtering > does NOT filter out ask_user when status is Success 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ Ask User │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Ask User Filtering > filters out ask_user when status is Confirming 1`] = `""`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Ask User Filtering > filters out ask_user when status is Executing 1`] = `""`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Ask User Filtering > filters out ask_user when status is Pending 1`] = `""`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Ask User Filtering > shows other tools when ask_user is filtered out 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ other-tool A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Border Color Logic > uses gray border when all tools are successful and no shell commands 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ test-tool A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ │
|
||||
│ ✓ another-tool A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ test-tool A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ │
|
||||
│ ✓ another-tool A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Border Color Logic > uses yellow border for shell commands even when successful 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ run_shell_command A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ run_shell_command A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Border Color Logic > uses yellow border when tools are pending 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ o test-tool A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ o test-tool A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Confirmation Handling > renders confirmation with permanent approval disabled 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ? confirm-tool A tool for testing ← │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ Do you want to proceed? │
|
||||
│ Do you want to proceed? │
|
||||
│ │
|
||||
│ ● 1. Allow once │
|
||||
│ 2. Allow for this session │
|
||||
│ 3. No, suggest changes (esc) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ? confirm-tool A tool for testing ← │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ Do you want to proceed? │
|
||||
│ │
|
||||
│ Do you want to proceed? │
|
||||
│ │
|
||||
│ ● 1. Allow once │
|
||||
│ 2. Allow for this session │
|
||||
│ 3. No, suggest changes (esc) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Confirmation Handling > renders confirmation with permanent approval enabled 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ? confirm-tool A tool for testing ← │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ Do you want to proceed? │
|
||||
│ Do you want to proceed? │
|
||||
│ │
|
||||
│ ● 1. Allow once │
|
||||
│ 2. Allow for this session │
|
||||
│ 3. Allow for all future sessions │
|
||||
│ 4. No, suggest changes (esc) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ? confirm-tool A tool for testing ← │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ Do you want to proceed? │
|
||||
│ │
|
||||
│ Do you want to proceed? │
|
||||
│ │
|
||||
│ ● 1. Allow once │
|
||||
│ 2. Allow for this session │
|
||||
│ 3. Allow for all future sessions │
|
||||
│ 4. No, suggest changes (esc) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Confirmation Handling > shows confirmation dialog for first confirming tool only 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ? first-confirm A tool for testing ← │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ Confirm first tool │
|
||||
│ Do you want to proceed? │
|
||||
│ │
|
||||
│ ● 1. Allow once │
|
||||
│ 2. Allow for this session │
|
||||
│ 3. No, suggest changes (esc) │
|
||||
│ │
|
||||
│ │
|
||||
│ ? second-confirm A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Event-Driven Scheduler > hides confirming tools when event-driven scheduler is enabled 1`] = `""`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Event-Driven Scheduler > renders nothing when only tool is in-progress AskUser with borderBottom=false 1`] = `""`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Event-Driven Scheduler > shows only successful tools when mixed with confirming tools 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ success-tool A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ? first-confirm A tool for testing ← │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ Confirm first tool │
|
||||
│ │
|
||||
│ Do you want to proceed? │
|
||||
│ │
|
||||
│ ● 1. Allow once │
|
||||
│ 2. Allow for this session │
|
||||
│ 3. No, suggest changes (esc) │
|
||||
│ │
|
||||
│ │
|
||||
│ ? second-confirm A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders empty tool calls array 1`] = `""`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders header when scrolled 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool-1 Description 1. This is a long description that will need to b… │
|
||||
│──────────────────────────────────────────────────────────────────────────│
|
||||
│ line5 │ █
|
||||
│ │ █
|
||||
│ ✓ tool-2 Description 2 │ █
|
||||
│ │ █
|
||||
│ line1 │ █
|
||||
│ line2 │ █
|
||||
╰──────────────────────────────────────────────────────────────────────────╯ █"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool-1 Description 1. This is a long description that will need to be tr… │
|
||||
│──────────────────────────────────────────────────────────────────────────────│
|
||||
│ │ ▄
|
||||
│ ✓ tool-2 Description 2 │ █
|
||||
│ │ █
|
||||
│ line1 │ █
|
||||
│ line2 │ █
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯ █
|
||||
█"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders mixed tool calls including shell command 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ read_file Read a file │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ │
|
||||
│ ⊷ run_shell_command Run command │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ │
|
||||
│ o write_file Write to file │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ read_file Read a file │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ │
|
||||
│ ⊷ run_shell_command Run command │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ │
|
||||
│ o write_file Write to file │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders multiple tool calls with different statuses 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ successful-tool This tool succeeded │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ │
|
||||
│ o pending-tool This tool is pending │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ │
|
||||
│ x error-tool This tool failed │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ successful-tool This tool succeeded │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ │
|
||||
│ o pending-tool This tool is pending │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ │
|
||||
│ x error-tool This tool failed │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders shell command with yellow border 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ run_shell_command Execute shell command │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ run_shell_command Execute shell command │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders single successful tool call 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ test-tool A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ test-tool A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders tool call awaiting confirmation 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ? confirmation-tool This tool needs confirmation ← │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ Are you sure you want to proceed? │
|
||||
│ Do you want to proceed? │
|
||||
│ │
|
||||
│ ● 1. Allow once │
|
||||
│ 2. Allow for this session │
|
||||
│ 3. No, suggest changes (esc) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ? confirmation-tool This tool needs confirmation ← │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ Are you sure you want to proceed? │
|
||||
│ │
|
||||
│ Do you want to proceed? │
|
||||
│ │
|
||||
│ ● 1. Allow once │
|
||||
│ 2. Allow for this session │
|
||||
│ 3. No, suggest changes (esc) │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders tool call with outputFile 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool-with-file Tool that saved output to file │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ Output too long and was saved to: /path/to/output.txt │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool-with-file Tool that saved output to file │
|
||||
│ │
|
||||
│ Test result │
|
||||
│ Output too long and was saved to: /path/to/output.txt │
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders two tool groups where only the last line of the previous group is visible 1`] = `
|
||||
"╰──────────────────────────────────────────────────────────────────────────╯
|
||||
╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool-2 Description 2 │
|
||||
│ │ ▄
|
||||
│ line1 │ █
|
||||
╰──────────────────────────────────────────────────────────────────────────╯ █"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool-2 Description 2 │
|
||||
│ │
|
||||
│ line1 │ ▄
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯ █
|
||||
█"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders when not focused 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ test-tool A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ test-tool A tool for testing │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders with limited terminal height 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool-with-result Tool with output │
|
||||
│ │
|
||||
│ This is a long result that might need height constraints │
|
||||
│ │
|
||||
│ ✓ another-tool Another tool │
|
||||
│ │
|
||||
│ More output here │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool-with-result Tool with output │
|
||||
│ │
|
||||
│ This is a long result that might need height constraints │
|
||||
│ │
|
||||
│ ✓ another-tool Another tool │
|
||||
│ │
|
||||
│ More output here │
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Golden Snapshots > renders with narrow terminal width 1`] = `
|
||||
"╭──────────────────────────────────╮
|
||||
│ ✓ very-long-tool-name-that-mig… │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────╮
|
||||
│ ✓ very-long-tool-name-that-might-w… │
|
||||
│ │
|
||||
│ Test result │
|
||||
╰──────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`<ToolGroupMessage /> > Height Calculation > calculates available height correctly with multiple tools with results 1`] = `
|
||||
"╭──────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ test-tool A tool for testing │
|
||||
│ │
|
||||
│ Result 1 │
|
||||
│ │
|
||||
│ ✓ test-tool A tool for testing │
|
||||
│ │
|
||||
│ Result 2 │
|
||||
│ │
|
||||
│ ✓ test-tool A tool for testing │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────╯"
|
||||
"╭──────────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ test-tool A tool for testing │
|
||||
│ │
|
||||
│ Result 1 │
|
||||
│ │
|
||||
│ ✓ test-tool A tool for testing │
|
||||
│ │
|
||||
│ Result 2 │
|
||||
│ │
|
||||
│ ✓ test-tool A tool for testing │
|
||||
│ │
|
||||
╰──────────────────────────────────────────────────────────────────────────────╯
|
||||
"
|
||||
`;
|
||||
|
||||
+6
-6
@@ -2,7 +2,7 @@
|
||||
|
||||
exports[`ToolMessage Sticky Header Regression > verifies that ShellToolMessage in a ToolGroupMessage in a ScrollableList has sticky headers 1`] = `
|
||||
"╭────────────────────────────────────────────────────────────────────────╮ █
|
||||
│ ✓ Shell Command Description for Shell Command │ █
|
||||
│ ✓ Shell Command Description for Shell Command │ ▀
|
||||
│ │
|
||||
│ shell-01 │
|
||||
│ shell-02 │"
|
||||
@@ -10,7 +10,7 @@ exports[`ToolMessage Sticky Header Regression > verifies that ShellToolMessage i
|
||||
|
||||
exports[`ToolMessage Sticky Header Regression > verifies that ShellToolMessage in a ToolGroupMessage in a ScrollableList has sticky headers 2`] = `
|
||||
"╭────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ Shell Command Description for Shell Command │ ▄
|
||||
│ ✓ Shell Command Description for Shell Command │
|
||||
│────────────────────────────────────────────────────────────────────────│ █
|
||||
│ shell-06 │ ▀
|
||||
│ shell-07 │"
|
||||
@@ -28,14 +28,14 @@ exports[`ToolMessage Sticky Header Regression > verifies that multiple ToolMessa
|
||||
"╭────────────────────────────────────────────────────────────────────────╮
|
||||
│ ✓ tool-1 Description for tool-1 │ █
|
||||
│────────────────────────────────────────────────────────────────────────│
|
||||
│ c1-06 │
|
||||
│ c1-07 │"
|
||||
│ c1-07 │
|
||||
│ c1-08 │"
|
||||
`;
|
||||
|
||||
exports[`ToolMessage Sticky Header Regression > verifies that multiple ToolMessages in a ToolGroupMessage in a ScrollableList have sticky headers 3`] = `
|
||||
"│ │
|
||||
│ ✓ tool-2 Description for tool-2 │
|
||||
│────────────────────────────────────────────────────────────────────────│
|
||||
│ c2-10 │
|
||||
╰────────────────────────────────────────────────────────────────────────╯ █"
|
||||
╰────────────────────────────────────────────────────────────────────────╯
|
||||
█"
|
||||
`;
|
||||
|
||||
@@ -8,7 +8,7 @@ import type {
|
||||
HistoryItemWithoutId,
|
||||
IndividualToolCallDisplay,
|
||||
} from '../types.js';
|
||||
import { ToolCallStatus } from '../types.js';
|
||||
import { ToolCallStatus, Verbosity } from '../types.js';
|
||||
import { useCallback, useReducer, useRef, useEffect } from 'react';
|
||||
import type { AnsiOutput, Config, GeminiClient } from '@google/gemini-cli-core';
|
||||
import { isBinary, ShellExecutionService } from '@google/gemini-cli-core';
|
||||
@@ -480,10 +480,14 @@ export const useShellCommandProcessor = (
|
||||
resultDisplay: finalOutput,
|
||||
};
|
||||
|
||||
// Add the complete, contextual result to the local UI history.
|
||||
// We skip this for cancelled commands because useGeminiStream handles the
|
||||
// immediate addition of the cancelled item to history to prevent flickering/duplicates.
|
||||
if (finalStatus !== ToolCallStatus.Canceled) {
|
||||
addItemToHistory(
|
||||
{
|
||||
type: 'tool_group',
|
||||
verbosity: Verbosity.INFO,
|
||||
tools: [finalToolDisplay],
|
||||
} as HistoryItemWithoutId,
|
||||
userMessageTimestamp,
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
type WaitingToolCall,
|
||||
type CancelledToolCall,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { ToolCallStatus } from '../types.js';
|
||||
import { ToolCallStatus, Verbosity } from '../types.js';
|
||||
|
||||
describe('toolMapping', () => {
|
||||
beforeEach(() => {
|
||||
@@ -274,5 +274,27 @@ describe('toolMapping', () => {
|
||||
expect(result.tools[0].resultDisplay).toBeUndefined();
|
||||
expect(result.tools[0].status).toBe(ToolCallStatus.Pending);
|
||||
});
|
||||
|
||||
it('sets verbosity to INFO for client-initiated tools', () => {
|
||||
const toolCall: ScheduledToolCall = {
|
||||
status: 'scheduled',
|
||||
request: { ...mockRequest, isClientInitiated: true },
|
||||
tool: mockTool,
|
||||
invocation: mockInvocation,
|
||||
};
|
||||
const result = mapToDisplay(toolCall);
|
||||
expect(result.verbosity).toBe(Verbosity.INFO);
|
||||
});
|
||||
|
||||
it('sets verbosity to undefined (defaulting to VERBOSE) for autonomous tools', () => {
|
||||
const toolCall: ScheduledToolCall = {
|
||||
status: 'scheduled',
|
||||
request: { ...mockRequest, isClientInitiated: false },
|
||||
tool: mockTool,
|
||||
invocation: mockInvocation,
|
||||
};
|
||||
const result = mapToDisplay(toolCall);
|
||||
expect(result.verbosity).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
} from '@google/gemini-cli-core';
|
||||
import {
|
||||
ToolCallStatus,
|
||||
Verbosity,
|
||||
type HistoryItemToolGroup,
|
||||
type IndividualToolCallDisplay,
|
||||
} from '../types.js';
|
||||
@@ -54,6 +55,9 @@ export function mapToDisplay(
|
||||
): HistoryItemToolGroup {
|
||||
const toolCalls = Array.isArray(toolOrTools) ? toolOrTools : [toolOrTools];
|
||||
const { borderTop, borderBottom } = options;
|
||||
const isClientInitiated = toolCalls.some(
|
||||
(tc) => tc.request.isClientInitiated,
|
||||
);
|
||||
|
||||
const toolDisplays = toolCalls.map((call): IndividualToolCallDisplay => {
|
||||
let description: string;
|
||||
@@ -129,6 +133,7 @@ export function mapToDisplay(
|
||||
|
||||
return {
|
||||
type: 'tool_group',
|
||||
verbosity: isClientInitiated ? Verbosity.INFO : undefined,
|
||||
tools: toolDisplays,
|
||||
borderTop,
|
||||
borderBottom,
|
||||
|
||||
@@ -8,7 +8,12 @@ import { describe, it, expect } from 'vitest';
|
||||
import { act } from 'react';
|
||||
import { renderHook } from '../../test-utils/render.js';
|
||||
import { useHistory } from './useHistoryManager.js';
|
||||
import type { HistoryItem } from '../types.js';
|
||||
import type {
|
||||
HistoryItem,
|
||||
HistoryItemWithoutId,
|
||||
IndividualToolCallDisplay,
|
||||
HistoryItemToolGroup,
|
||||
} from '../types.js';
|
||||
|
||||
describe('useHistoryManager', () => {
|
||||
it('should initialize with an empty history', () => {
|
||||
@@ -255,4 +260,67 @@ describe('useHistoryManager', () => {
|
||||
expect(result.current.history[0].type).toBe('info');
|
||||
});
|
||||
});
|
||||
|
||||
it('should store all items regardless of verbosity level (filtering is done at render time)', () => {
|
||||
// @ts-expect-error - verbosity prop was removed, but we want to ensure it's ignored if passed by mistake
|
||||
const { result } = renderHook(() => useHistory({ verbosity: 'info' }));
|
||||
const timestamp = Date.now();
|
||||
const verboseItem: HistoryItemWithoutId = {
|
||||
type: 'verbose',
|
||||
text: 'Hidden detail',
|
||||
verbosity: 3, // Verbosity.VERBOSE
|
||||
};
|
||||
|
||||
act(() => {
|
||||
result.current.addItem(verboseItem, timestamp);
|
||||
});
|
||||
|
||||
expect(result.current.history).toHaveLength(1);
|
||||
expect(result.current.history[0]).toEqual(
|
||||
expect.objectContaining({
|
||||
text: 'Hidden detail',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it('should merge consecutive tool_group items', () => {
|
||||
const { result } = renderHook(() => useHistory());
|
||||
const timestamp = Date.now();
|
||||
const toolGroup1: HistoryItemWithoutId = {
|
||||
type: 'tool_group',
|
||||
tools: [{ callId: '1', name: 'tool-a' } as IndividualToolCallDisplay],
|
||||
};
|
||||
const toolGroup2: HistoryItemWithoutId = {
|
||||
type: 'tool_group',
|
||||
tools: [{ callId: '2', name: 'tool-b' } as IndividualToolCallDisplay],
|
||||
};
|
||||
const userMessage: HistoryItemWithoutId = {
|
||||
type: 'user',
|
||||
text: 'hello',
|
||||
};
|
||||
const toolGroup3: HistoryItemWithoutId = {
|
||||
type: 'tool_group',
|
||||
tools: [{ callId: '3', name: 'tool-c' } as IndividualToolCallDisplay],
|
||||
};
|
||||
|
||||
act(() => {
|
||||
result.current.addItem(toolGroup1, timestamp);
|
||||
result.current.addItem(toolGroup2, timestamp + 1);
|
||||
result.current.addItem(userMessage, timestamp + 2);
|
||||
result.current.addItem(toolGroup3, timestamp + 3);
|
||||
});
|
||||
|
||||
expect(result.current.history).toHaveLength(3);
|
||||
expect(result.current.history[0].type).toBe('tool_group');
|
||||
const firstItem = result.current.history[0] as HistoryItemToolGroup;
|
||||
expect(firstItem.tools).toHaveLength(2);
|
||||
expect(firstItem.tools[0].name).toBe('tool-a');
|
||||
expect(firstItem.tools[1].name).toBe('tool-b');
|
||||
|
||||
expect(result.current.history[1].type).toBe('user');
|
||||
|
||||
const thirdItem = result.current.history[2] as HistoryItemToolGroup;
|
||||
expect(thirdItem.type).toBe('tool_group');
|
||||
expect(thirdItem.tools).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -66,16 +66,30 @@ export function useHistory({
|
||||
const newItem: HistoryItem = { ...itemData, id } as HistoryItem;
|
||||
|
||||
setHistory((prevHistory) => {
|
||||
if (prevHistory.length > 0) {
|
||||
const lastItem = prevHistory[prevHistory.length - 1];
|
||||
// Prevent adding duplicate consecutive user messages
|
||||
if (
|
||||
lastItem.type === 'user' &&
|
||||
newItem.type === 'user' &&
|
||||
lastItem.text === newItem.text
|
||||
) {
|
||||
return prevHistory; // Don't add the duplicate
|
||||
}
|
||||
const lastItem =
|
||||
prevHistory.length > 0 ? prevHistory[prevHistory.length - 1] : null;
|
||||
|
||||
// If the last item and the new item are both tool groups, merge them.
|
||||
if (
|
||||
lastItem &&
|
||||
lastItem.type === 'tool_group' &&
|
||||
newItem.type === 'tool_group'
|
||||
) {
|
||||
const updatedLastItem: HistoryItem = {
|
||||
...lastItem,
|
||||
tools: [...lastItem.tools, ...newItem.tools],
|
||||
};
|
||||
return [...prevHistory.slice(0, -1), updatedLastItem];
|
||||
}
|
||||
|
||||
// Prevent adding duplicate consecutive user messages
|
||||
if (
|
||||
lastItem &&
|
||||
lastItem.type === 'user' &&
|
||||
newItem.type === 'user' &&
|
||||
lastItem.text === newItem.text
|
||||
) {
|
||||
return prevHistory; // Don't add the duplicate
|
||||
}
|
||||
return [...prevHistory, newItem];
|
||||
});
|
||||
@@ -83,36 +97,38 @@ export function useHistory({
|
||||
// Record UI-specific messages, but don't do it if we're actually loading
|
||||
// an existing session.
|
||||
if (!isResuming && chatRecordingService) {
|
||||
// Safe access to text property
|
||||
const content = itemData.text || '';
|
||||
|
||||
switch (itemData.type) {
|
||||
case 'compression':
|
||||
case 'verbose':
|
||||
case 'info':
|
||||
chatRecordingService?.recordMessage({
|
||||
model: undefined,
|
||||
type: 'info',
|
||||
content: itemData.text ?? '',
|
||||
content: content || '',
|
||||
});
|
||||
break;
|
||||
case 'warning':
|
||||
chatRecordingService?.recordMessage({
|
||||
model: undefined,
|
||||
type: 'warning',
|
||||
content: itemData.text ?? '',
|
||||
content: content || '',
|
||||
});
|
||||
break;
|
||||
case 'error':
|
||||
chatRecordingService?.recordMessage({
|
||||
model: undefined,
|
||||
type: 'error',
|
||||
content: itemData.text ?? '',
|
||||
content: content || '',
|
||||
});
|
||||
break;
|
||||
case 'user':
|
||||
case 'gemini':
|
||||
case 'gemini_content':
|
||||
// Core conversation recording handled by GeminiChat.
|
||||
// User messages are recorded by the input handler
|
||||
break;
|
||||
default:
|
||||
// Ignore the rest.
|
||||
// Other types might not need recording or are recorded elsewhere
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -128,7 +144,6 @@ export function useHistory({
|
||||
* rendering all history items in <Static /> for performance reasons. Only use
|
||||
* if ABSOLUTELY NECESSARY
|
||||
*/
|
||||
//
|
||||
const updateItem = useCallback(
|
||||
(
|
||||
id: number,
|
||||
|
||||
@@ -19,7 +19,7 @@ import type {
|
||||
import type { PartListUnion } from '@google/genai';
|
||||
import { type ReactNode } from 'react';
|
||||
|
||||
export type { ThoughtSummary, SkillDefinition };
|
||||
export type { ThoughtSummary, SkillDefinition, ToolResultDisplay };
|
||||
|
||||
export enum AuthState {
|
||||
// Attempting to authenticate or re-authenticate
|
||||
@@ -101,6 +101,7 @@ export const emptyIcon = ' ';
|
||||
|
||||
export interface HistoryItemBase {
|
||||
text?: string; // Text content for user/gemini/info/error messages
|
||||
verbosity?: Verbosity;
|
||||
}
|
||||
|
||||
export type HistoryItemUser = HistoryItemBase & {
|
||||
@@ -135,6 +136,23 @@ export type HistoryItemWarning = HistoryItemBase & {
|
||||
text: string;
|
||||
};
|
||||
|
||||
export type HistoryItemVerbose = HistoryItemBase & {
|
||||
type: 'verbose';
|
||||
text: string;
|
||||
icon?: string;
|
||||
color?: string;
|
||||
};
|
||||
|
||||
export type HistoryItemDebug = HistoryItemBase & {
|
||||
type: 'debug';
|
||||
text: string;
|
||||
};
|
||||
|
||||
export type HistoryItemTrace = HistoryItemBase & {
|
||||
type: 'trace';
|
||||
text: string;
|
||||
};
|
||||
|
||||
export type HistoryItemAbout = HistoryItemBase & {
|
||||
type: 'about';
|
||||
cliVersion: string;
|
||||
@@ -318,6 +336,9 @@ export type HistoryItemWithoutId =
|
||||
| HistoryItemInfo
|
||||
| HistoryItemError
|
||||
| HistoryItemWarning
|
||||
| HistoryItemVerbose
|
||||
| HistoryItemDebug
|
||||
| HistoryItemTrace
|
||||
| HistoryItemAbout
|
||||
| HistoryItemHelp
|
||||
| HistoryItemToolGroup
|
||||
@@ -335,11 +356,16 @@ export type HistoryItemWithoutId =
|
||||
| HistoryItemChatList
|
||||
| HistoryItemHooksList;
|
||||
|
||||
export type HistoryItemType = HistoryItemWithoutId['type'];
|
||||
|
||||
export type HistoryItem = HistoryItemWithoutId & { id: number };
|
||||
|
||||
// Message types used by internal command feedback (subset of HistoryItem types)
|
||||
export enum MessageType {
|
||||
INFO = 'info',
|
||||
VERBOSE = 'verbose',
|
||||
DEBUG = 'debug',
|
||||
TRACE = 'trace',
|
||||
ERROR = 'error',
|
||||
WARNING = 'warning',
|
||||
USER = 'user',
|
||||
@@ -360,10 +386,52 @@ export enum MessageType {
|
||||
HOOKS_LIST = 'hooks_list',
|
||||
}
|
||||
|
||||
export enum Verbosity {
|
||||
ERROR = 0,
|
||||
WARN = 1,
|
||||
INFO = 2,
|
||||
VERBOSE = 3,
|
||||
DEBUG = 4,
|
||||
TRACE = 5,
|
||||
}
|
||||
|
||||
export const VERBOSITY_MAPPING: Record<HistoryItemType, Verbosity> = {
|
||||
error: Verbosity.ERROR,
|
||||
warning: Verbosity.WARN,
|
||||
info: Verbosity.INFO,
|
||||
user: Verbosity.INFO,
|
||||
gemini: Verbosity.INFO,
|
||||
gemini_content: Verbosity.INFO,
|
||||
tool_group: Verbosity.INFO,
|
||||
user_shell: Verbosity.INFO,
|
||||
about: Verbosity.INFO,
|
||||
stats: Verbosity.INFO,
|
||||
model_stats: Verbosity.INFO,
|
||||
tool_stats: Verbosity.INFO,
|
||||
model: Verbosity.INFO,
|
||||
quit: Verbosity.INFO,
|
||||
extensions_list: Verbosity.INFO,
|
||||
tools_list: Verbosity.INFO,
|
||||
skills_list: Verbosity.INFO,
|
||||
agents_list: Verbosity.INFO,
|
||||
mcp_status: Verbosity.INFO,
|
||||
chat_list: Verbosity.INFO,
|
||||
hooks_list: Verbosity.INFO,
|
||||
help: Verbosity.INFO,
|
||||
verbose: Verbosity.VERBOSE,
|
||||
compression: Verbosity.VERBOSE,
|
||||
debug: Verbosity.DEBUG,
|
||||
trace: Verbosity.TRACE,
|
||||
};
|
||||
|
||||
// Simplified message structure for internal feedback
|
||||
export type Message =
|
||||
| {
|
||||
type: MessageType.INFO | MessageType.ERROR | MessageType.USER;
|
||||
type:
|
||||
| MessageType.INFO
|
||||
| MessageType.VERBOSE
|
||||
| MessageType.ERROR
|
||||
| MessageType.USER;
|
||||
content: string; // Renamed from text for clarity in this context
|
||||
timestamp: Date;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user