import { Box } from "ink"; import { memo } from "react"; import { COMPACTION_SUMMARY_HEADER } from "../../constants"; import { useTerminalWidth } from "../hooks/useTerminalWidth"; import { BlinkDot } from "./BlinkDot.js"; import { CompactingAnimation } from "./CompactingAnimation"; import { colors } from "./colors.js"; import { Text } from "./Text"; type EventLine = { kind: "event"; id: string; eventType: string; eventData: Record; phase: "running" | "finished"; summary?: string; stats?: { trigger?: string; contextTokensBefore?: number; contextTokensAfter?: number; contextWindow?: number; messagesCountBefore?: number; messagesCountAfter?: number; }; }; /** * EventMessage - Displays compaction events like a tool call * * When running: Shows blinking dot with "Compacting..." * When finished: Shows completed dot with summary */ export const EventMessage = memo(({ line }: { line: EventLine }) => { const columns = useTerminalWidth(); const rightWidth = Math.max(0, columns - 2); // Only handle compaction events for now if (line.eventType !== "compaction") { return ( Event: {line.eventType} ); } const isRunning = line.phase === "running"; // Dot indicator based on phase const dotElement = isRunning ? ( ) : ( ); // Format the args display (message count or fallback) const formatArgs = (): string => { const stats = line.stats; if ( stats?.messagesCountBefore !== undefined && stats?.messagesCountAfter !== undefined ) { return `${stats.messagesCountBefore} → ${stats.messagesCountAfter} messages`; } return "..."; }; const argsDisplay = formatArgs(); return ( {/* Main tool call line */} {dotElement} {isRunning ? ( ) : ( Compact({argsDisplay}) )} {/* Result section (only when finished) - matches CollapsedOutputDisplay format */} {!isRunning && line.summary && ( <> {/* Header line with L-bracket */} {" ⎿ "} {COMPACTION_SUMMARY_HEADER} {/* Empty line for separation */} {/* Summary text - indented with 5 spaces to align */} {" "} {line.summary} )} ); }); EventMessage.displayName = "EventMessage";