feat(shell): enable interactive commands with virtual terminal (#6694)

This commit is contained in:
Gal Zahavi
2025-09-11 13:27:27 -07:00
committed by GitHub
parent 8969a232ec
commit 181898cb5d
43 changed files with 2345 additions and 324 deletions
@@ -11,6 +11,31 @@ import { ToolMessage } from './ToolMessage.js';
import { StreamingState, ToolCallStatus } from '../../types.js';
import { Text } from 'ink';
import { StreamingContext } from '../../contexts/StreamingContext.js';
import type { AnsiOutput } from '@google/gemini-cli-core';
vi.mock('../TerminalOutput.js', () => ({
TerminalOutput: function MockTerminalOutput({
cursor,
}: {
cursor: { x: number; y: number } | null;
}) {
return (
<Text>
MockCursor:({cursor?.x},{cursor?.y})
</Text>
);
},
}));
vi.mock('../AnsiOutput.js', () => ({
AnsiOutputText: function MockAnsiOutputText({ data }: { data: AnsiOutput }) {
// Simple serialization for snapshot stability
const serialized = data
.map((line) => line.map((token) => token.text || '').join(''))
.join('\n');
return <Text>MockAnsiOutput:{serialized}</Text>;
},
}));
// Mock child components or utilities if they are complex or have side effects
vi.mock('../GeminiRespondingSpinner.js', () => ({
@@ -181,4 +206,26 @@ describe('<ToolMessage />', () => {
// We can at least ensure it doesn't have the high emphasis indicator.
expect(lowEmphasisFrame()).not.toContain('←');
});
it('renders AnsiOutputText for AnsiOutput results', () => {
const ansiResult: AnsiOutput = [
[
{
text: 'hello',
fg: '#ffffff',
bg: '#000000',
bold: false,
italic: false,
underline: false,
dim: false,
inverse: false,
},
],
];
const { lastFrame } = renderWithContext(
<ToolMessage {...baseProps} resultDisplay={ansiResult} />,
StreamingState.Idle,
);
expect(lastFrame()).toContain('MockAnsiOutput:hello');
});
});