/** * Companion display card — shown by /buddy (no args). * Mirrors official vc8 component: bordered box with sprite, stats, last reaction. */ import React from 'react'; import { Box, Text } from '@anthropic/ink'; import { useInput } from '@anthropic/ink'; import { renderSprite } from './sprites.js'; import { RARITY_COLORS, RARITY_STARS, STAT_NAMES, type Companion } from './types.js'; const CARD_WIDTH = 40; const CARD_PADDING_X = 2; function StatBar({ name, value }: { name: string; value: number }) { const clamped = Math.max(0, Math.min(100, value)); const filled = Math.round(clamped / 10); const bar = '\u2588'.repeat(filled) + '\u2591'.repeat(10 - filled); return ( {name.padEnd(10)} {bar} {String(value).padStart(3)} ); } export function CompanionCard({ companion, lastReaction, onDone, }: { companion: Companion; lastReaction?: string; onDone?: (result?: string, options?: { display?: string }) => void; }) { const color = RARITY_COLORS[companion.rarity]; const stars = RARITY_STARS[companion.rarity]; const sprite = renderSprite(companion, 0); // Press any key to dismiss useInput( () => { onDone?.(undefined, { display: 'skip' }); }, { isActive: onDone !== undefined }, ); return ( {/* Header: rarity + species */} {stars} {companion.rarity.toUpperCase()} {companion.species.toUpperCase()} {/* Shiny indicator */} {companion.shiny && ( {'\u2728'} SHINY {'\u2728'} )} {/* Sprite */} {sprite.map((line, i) => ( {line} ))} {/* Name */} {companion.name} {/* Personality */} "{companion.personality}" {/* Stats */} {STAT_NAMES.map(name => ( ))} {/* Last reaction */} {lastReaction && ( last said {lastReaction} )} ); }