Files
letta-code/src/cli/components/CommandMessage.tsx
2026-01-31 19:43:13 -08:00

77 lines
2.2 KiB
TypeScript

import { Box } from "ink";
import { memo } from "react";
import { useTerminalWidth } from "../hooks/useTerminalWidth";
import { BlinkDot } from "./BlinkDot.js";
import { colors } from "./colors.js";
import { MarkdownDisplay } from "./MarkdownDisplay.js";
import { Text } from "./Text";
type CommandLine = {
kind: "command";
id: string;
input: string;
output: string;
phase?: "running" | "finished";
success?: boolean;
dimOutput?: boolean;
};
/**
* CommandMessage - Rich formatting version with two-column layout
* Matches the formatting pattern used by other message types
*
* Features:
* - Two-column layout with left gutter (2 chars) and right content area
* - Proper terminal width calculation and wrapping
* - Markdown rendering for output
* - Consistent symbols (● for command, ⎿ for result)
*/
export const CommandMessage = memo(({ line }: { line: CommandLine }) => {
const columns = useTerminalWidth();
const rightWidth = Math.max(0, columns - 2); // gutter is 2 cols
// Determine dot state based on phase and success
const getDotElement = () => {
if (!line.phase || line.phase === "finished") {
// Show red dot for failed commands, green for successful
if (line.success === false) {
return <Text color={colors.command.error}></Text>;
}
return <Text color={colors.tool.completed}></Text>;
}
if (line.phase === "running") {
return <BlinkDot color={colors.command.running} />;
}
return <Text></Text>;
};
return (
<Box flexDirection="column">
{/* Command input */}
<Box flexDirection="row">
<Box width={2} flexShrink={0}>
{getDotElement()}
<Text> </Text>
</Box>
<Box flexGrow={1} width={rightWidth}>
<Text>{line.input}</Text>
</Box>
</Box>
{/* Command output (if present) */}
{line.output && (
<Box flexDirection="row">
<Box width={5} flexShrink={0}>
<Text>{" ⎿ "}</Text>
</Box>
<Box flexGrow={1} width={Math.max(0, columns - 5)}>
<MarkdownDisplay text={line.output} dimColor={line.dimOutput} />
</Box>
</Box>
)}
</Box>
);
});
CommandMessage.displayName = "CommandMessage";