/**
* Companion display card — shown by /buddy (no args).
* Mirrors official vc8 component: bordered box with sprite, stats, last reaction.
*/
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}
)}
);
}