import { Box, Text, useInput } from "ink";
import { memo, useState } from "react";
import { useProgressIndicator } from "../hooks/useProgressIndicator";
import { useTerminalWidth } from "../hooks/useTerminalWidth";
import { colors } from "./colors";
type Props = {
onApprove: () => void;
onReject: () => void;
isFocused?: boolean;
};
// Horizontal line character for Claude Code style
const SOLID_LINE = "─";
const OptionsRenderer = memo(
({
options,
selectedOption,
}: {
options: Array<{ label: string }>;
selectedOption: number;
}) => {
return (
{options.map((option, index) => {
const isSelected = index === selectedOption;
const color = isSelected ? colors.approval.header : undefined;
return (
{isSelected ? "❯" : " "} {index + 1}. {option.label}
);
})}
);
},
);
OptionsRenderer.displayName = "OptionsRenderer";
/**
* InlineEnterPlanModeApproval - Renders EnterPlanMode approval UI inline
*
* Uses horizontal lines instead of boxes for visual styling.
*/
export const InlineEnterPlanModeApproval = memo(
({ onApprove, onReject, isFocused = true }: Props) => {
const [selectedOption, setSelectedOption] = useState(0);
const columns = useTerminalWidth();
useProgressIndicator();
const options = [
{ label: "Yes, enter plan mode", action: onApprove },
{ label: "No, start implementing now", action: onReject },
];
useInput(
(input, key) => {
if (!isFocused) return;
// CTRL-C: immediately reject (cancel)
if (key.ctrl && input === "c") {
onReject();
return;
}
// ESC: reject (cancel)
if (key.escape) {
onReject();
return;
}
if (key.upArrow) {
setSelectedOption((prev) => Math.max(0, prev - 1));
} else if (key.downArrow) {
setSelectedOption((prev) => Math.min(options.length - 1, prev + 1));
} else if (key.return) {
options[selectedOption]?.action();
} else if (input === "1") {
onApprove();
} else if (input === "2") {
onReject();
}
},
{ isActive: isFocused },
);
// Generate horizontal line
const solidLine = SOLID_LINE.repeat(Math.max(columns - 2, 10));
return (
{/* Top solid line */}
{solidLine}
{/* Header */}
Enter plan mode?
{/* Description */}
Letta Code wants to enter plan mode to explore and design an
implementation approach.
In plan mode, Letta Code will:
· Explore the codebase thoroughly
· Identify existing patterns
· Design an implementation strategy
· Present a plan for your approval
No code changes will be made until you approve the plan.
{/* Options */}
);
},
);
InlineEnterPlanModeApproval.displayName = "InlineEnterPlanModeApproval";