mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-23 19:44:30 -07:00
118 lines
3.0 KiB
TypeScript
118 lines
3.0 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2025 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
import React from 'react';
|
|
import { Box, Text } from 'ink';
|
|
import { ToolCallStatus } from '../../types.js';
|
|
import { GeminiRespondingSpinner } from '../GeminiRespondingSpinner.js';
|
|
import {
|
|
SHELL_COMMAND_NAME,
|
|
SHELL_NAME,
|
|
TOOL_STATUS,
|
|
} from '../../constants.js';
|
|
import { theme } from '../../semantic-colors.js';
|
|
import { SHELL_TOOL_NAME } from '@google/gemini-cli-core';
|
|
|
|
export const STATUS_INDICATOR_WIDTH = 3;
|
|
|
|
export type TextEmphasis = 'high' | 'medium' | 'low';
|
|
|
|
type ToolStatusIndicatorProps = {
|
|
status: ToolCallStatus;
|
|
name: string;
|
|
};
|
|
|
|
export const ToolStatusIndicator: React.FC<ToolStatusIndicatorProps> = ({
|
|
status,
|
|
name,
|
|
}) => {
|
|
const isShell =
|
|
name === SHELL_COMMAND_NAME ||
|
|
name === SHELL_NAME ||
|
|
name === SHELL_TOOL_NAME;
|
|
const statusColor = isShell ? theme.ui.symbol : theme.status.warning;
|
|
|
|
return (
|
|
<Box minWidth={STATUS_INDICATOR_WIDTH}>
|
|
{status === ToolCallStatus.Pending && (
|
|
<Text color={theme.status.success}>{TOOL_STATUS.PENDING}</Text>
|
|
)}
|
|
{status === ToolCallStatus.Executing && (
|
|
<GeminiRespondingSpinner
|
|
spinnerType="toggle"
|
|
nonRespondingDisplay={TOOL_STATUS.EXECUTING}
|
|
/>
|
|
)}
|
|
{status === ToolCallStatus.Success && (
|
|
<Text color={theme.status.success} aria-label={'Success:'}>
|
|
{TOOL_STATUS.SUCCESS}
|
|
</Text>
|
|
)}
|
|
{status === ToolCallStatus.Confirming && (
|
|
<Text color={statusColor} aria-label={'Confirming:'}>
|
|
{TOOL_STATUS.CONFIRMING}
|
|
</Text>
|
|
)}
|
|
{status === ToolCallStatus.Canceled && (
|
|
<Text color={statusColor} aria-label={'Canceled:'} bold>
|
|
{TOOL_STATUS.CANCELED}
|
|
</Text>
|
|
)}
|
|
{status === ToolCallStatus.Error && (
|
|
<Text color={theme.status.error} aria-label={'Error:'} bold>
|
|
{TOOL_STATUS.ERROR}
|
|
</Text>
|
|
)}
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
type ToolInfoProps = {
|
|
name: string;
|
|
description: string;
|
|
status: ToolCallStatus;
|
|
emphasis: TextEmphasis;
|
|
};
|
|
|
|
export const ToolInfo: React.FC<ToolInfoProps> = ({
|
|
name,
|
|
description,
|
|
status,
|
|
emphasis,
|
|
}) => {
|
|
const nameColor = React.useMemo<string>(() => {
|
|
switch (emphasis) {
|
|
case 'high':
|
|
return theme.text.primary;
|
|
case 'medium':
|
|
return theme.text.primary;
|
|
case 'low':
|
|
return theme.text.secondary;
|
|
default: {
|
|
const exhaustiveCheck: never = emphasis;
|
|
return exhaustiveCheck;
|
|
}
|
|
}
|
|
}, [emphasis]);
|
|
return (
|
|
<Box overflow="hidden" height={1} flexGrow={1} flexShrink={1}>
|
|
<Text strikethrough={status === ToolCallStatus.Canceled} wrap="truncate">
|
|
<Text color={nameColor} bold>
|
|
{name}
|
|
</Text>{' '}
|
|
<Text color={theme.text.secondary}>{description}</Text>
|
|
</Text>
|
|
</Box>
|
|
);
|
|
};
|
|
|
|
export const TrailingIndicator: React.FC = () => (
|
|
<Text color={theme.text.primary} wrap="truncate">
|
|
{' '}
|
|
←
|
|
</Text>
|
|
);
|