diff --git a/packages/cli/src/ui/components/shared/Card.test.tsx b/packages/cli/src/ui/components/shared/Card.test.tsx index 60bf7ce4cd..b5dc0c5d86 100644 --- a/packages/cli/src/ui/components/shared/Card.test.tsx +++ b/packages/cli/src/ui/components/shared/Card.test.tsx @@ -8,55 +8,55 @@ import { render } from '../../../test-utils/render.js'; import { Card } from './Card.js'; import { Text } from 'ink'; import { describe, it, expect } from 'vitest'; +import { ToolCallStatus } from '../../types.js'; describe('Card', () => { it.each([ { - variant: 'warning', + status: ToolCallStatus.Pending, title: 'Gemini CLI update available', suffix: '0.26.0 → 0.27.0', prefix: true, body: 'Installed via Homebrew. Please update with "brew upgrade gemini-cli".', }, { - variant: 'information', + status: ToolCallStatus.Canceled, title: 'Delegate to agent', suffix: "Delegating to agent 'cli_help'", prefix: true, body: '🤖💭 Execution limit reached (ERROR_NO_COMPLETE_TASK_CALL). Attempting one final recovery turn with a grace period.', }, { - variant: 'error', + status: ToolCallStatus.Error, title: 'Error', suffix: '429 You exceeded your current quota', prefix: true, body: 'Go to https://aistudio.google.com/apikey to upgrade your quota tier, or submit a quota increase request in https://ai.google.dev/gemini-api/docs/rate-limits', }, { - variant: 'confirmation', + status: ToolCallStatus.Confirming, title: 'Shell', suffix: 'node -v && which gemini', prefix: true, body: "ls /usr/local/bin | grep 'xattr'", }, { - variant: 'success', + status: ToolCallStatus.Success, title: 'ReadFolder', suffix: '/usr/local/bin', prefix: true, body: 'Listed 39 item(s).', }, ] as const)( - 'renders a $variant card with prefix=$prefix', - ({ variant, title, suffix, prefix, body }) => { + 'renders a $status card with prefix=$prefix', + ({ status, title, suffix, prefix, body }) => { const { lastFrame } = render( - + {body} , ); const output = lastFrame(); - expect(output).toMatchSnapshot(); }, ); diff --git a/packages/cli/src/ui/components/shared/Card.tsx b/packages/cli/src/ui/components/shared/Card.tsx index 06face2625..7d22a20808 100644 --- a/packages/cli/src/ui/components/shared/Card.tsx +++ b/packages/cli/src/ui/components/shared/Card.tsx @@ -7,7 +7,8 @@ import type React from 'react'; import { Box, Text } from 'ink'; import { theme } from '../../semantic-colors.js'; -import { TOOL_STATUS } from '../../constants.js'; +import { ToolStatusIndicator } from '../messages/ToolShared.js'; +import { ToolCallStatus } from '../../types.js'; /** * Props for the Card component. @@ -22,55 +23,39 @@ export interface CardProps { /** The content to be displayed inside the card. */ children?: React.ReactNode; /** The styling and intent of the card. */ - variant?: 'information' | 'success' | 'warning' | 'error' | 'confirmation'; + status?: ToolCallStatus; } export const Card: React.FC = ({ - variant = 'information', + status = ToolCallStatus.Pending, title, prefix = true, suffix, children, }) => { const getColors = () => { - switch (variant) { - case 'error': - return { border: theme.status.error, text: theme.status.error }; - case 'warning': - return { border: theme.status.warning, text: theme.status.warning }; - case 'success': - return { border: theme.status.success, text: theme.status.success }; - case 'confirmation': + switch (status) { + case ToolCallStatus.Pending: + return { border: theme.border.default, text: theme.text.accent }; + case ToolCallStatus.Confirming: return { border: theme.border.focused, text: theme.text.link }; - case 'information': - return { border: theme.border.default, text: theme.text.primary }; + case ToolCallStatus.Error: + return { border: theme.status.error, text: theme.status.error }; + case ToolCallStatus.Success: + return { border: theme.border.default, text: theme.status.success }; + case ToolCallStatus.Canceled: + return { border: theme.status.warning, text: theme.status.warning }; + case ToolCallStatus.Executing: + return { border: theme.border.default, text: theme.status.success }; default: return { border: theme.border.default, text: theme.text.primary }; } }; - const getGlyph = () => { - switch (variant) { - case 'error': - return TOOL_STATUS.ERROR; - case 'success': - return TOOL_STATUS.SUCCESS; - case 'warning': - return TOOL_STATUS.WARNING; - case 'confirmation': - return TOOL_STATUS.CONFIRMING; - case 'information': - return TOOL_STATUS.INFORMATION; - default: - return TOOL_STATUS.INFORMATION; - } - }; - const colors = getColors(); - const glyph = getGlyph(); return ( - + {/* Top border section */} = ({ gap={1} justifyContent="flex-start" > - {prefix && {glyph}} + {/* TODO: Use shared ToolStatusIndicator component */} + + {prefix && } + {title} diff --git a/packages/cli/src/ui/components/shared/__snapshots__/Card.test.tsx.snap b/packages/cli/src/ui/components/shared/__snapshots__/Card.test.tsx.snap index 85204eb523..885c31ba59 100644 --- a/packages/cli/src/ui/components/shared/__snapshots__/Card.test.tsx.snap +++ b/packages/cli/src/ui/components/shared/__snapshots__/Card.test.tsx.snap @@ -1,38 +1,33 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`Card > renders a 'confirmation' card with prefix=true 1`] = ` -"╭ ? Shell node -v && which gemini ─────────────────────────────────────────────────────────────────╮ -│ ls /usr/local/bin | grep 'xattr' │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ -" +exports[`Card > renders a 'Canceled' card with prefix=true 1`] = ` +"╭ - Delegate to agent Delegating to agent 'cli_help' ──────────────────────────────────────────────╮ +│ 🤖💭 Execution limit reached (ERROR_NO_COMPLETE_TASK_CALL). Attempting one final recovery turn │ +│ with a grace period. │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────╯" `; -exports[`Card > renders a 'error' card with prefix=true 1`] = ` -"╭ x Error 429 You exceeded your current quota ─────────────────────────────────────────────────────╮ -│ Go to https://aistudio.google.com/apikey to upgrade your quota tier, or submit a quota increase │ -│ request in https://ai.google.dev/gemini-api/docs/rate-limits │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ -" +exports[`Card > renders a 'Confirming' card with prefix=true 1`] = ` +"╭ ? Shell node -v && which gemini ─────────────────────────────────────────────────────────────────╮ +│ ls /usr/local/bin | grep 'xattr' │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────╯" `; -exports[`Card > renders a 'information' card with prefix=true 1`] = ` -"╭ ℹ Delegate to agent Delegating to agent 'cli_help' ──────────────────────────────────────────────╮ -│ 🤖💭 Execution limit reached (ERROR_NO_COMPLETE_TASK_CALL). Attempting one final recovery turn │ -│ with a grace period. │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ -" +exports[`Card > renders a 'Error' card with prefix=true 1`] = ` +"╭ x Error 429 You exceeded your current quota ─────────────────────────────────────────────────────╮ +│ Go to https://aistudio.google.com/apikey to upgrade your quota tier, or submit a quota increase │ +│ request in https://ai.google.dev/gemini-api/docs/rate-limits │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────╯" `; -exports[`Card > renders a 'success' card with prefix=true 1`] = ` -"╭ ✓ ReadFolder /usr/local/bin ─────────────────────────────────────────────────────────────────────╮ -│ Listed 39 item(s). │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ -" +exports[`Card > renders a 'Pending' card with prefix=true 1`] = ` +"╭ o Gemini CLI update available 0.26.0 → 0.27.0 ───────────────────────────────────────────────────╮ +│ Installed via Homebrew. Please update with "brew upgrade gemini-cli". │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────╯" `; -exports[`Card > renders a 'warning' card with prefix=true 1`] = ` -"╭ ⚠ Gemini CLI update available 0.26.0 → 0.27.0 ───────────────────────────────────────────────────╮ -│ Installed via Homebrew. Please update with "brew upgrade gemini-cli". │ -╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ -" +exports[`Card > renders a 'Success' card with prefix=true 1`] = ` +"╭ ✓ ReadFolder /usr/local/bin ─────────────────────────────────────────────────────────────────────╮ +│ Listed 39 item(s). │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────╯" `;