in codex-cli/src/components/singlepass-cli-app.tsx [208:284]
function InputPrompt({
message,
onSubmit,
onCtrlC,
}: {
message: string;
onSubmit: (val: string) => void;
onCtrlC?: () => void;
}) {
const [value, setValue] = useState("");
const [history] = useState(() => loadPromptHistory());
const [historyIndex, setHistoryIndex] = useState<number | null>(null);
const [draftInput, setDraftInput] = useState<string>("");
const [, setShowDirInfo] = useState(false);
useInput((input, key) => {
if ((key.ctrl && (input === "c" || input === "C")) || input === "\u0003") {
// Ctrl+C pressed – treat as interrupt
if (onCtrlC) {
onCtrlC();
} else {
process.exit(0);
}
} else if (key.return) {
if (value.trim() !== "") {
// Save to history (front of list)
const updated =
history[history.length - 1] === value ? history : [...history, value];
savePromptHistory(updated.slice(-50));
}
onSubmit(value.trim());
} else if (key.upArrow) {
if (history.length > 0) {
if (historyIndex == null) {
setDraftInput(value);
}
let newIndex: number;
if (historyIndex == null) {
newIndex = history.length - 1;
} else {
newIndex = Math.max(0, historyIndex - 1);
}
setHistoryIndex(newIndex);
setValue(history[newIndex] ?? "");
}
} else if (key.downArrow) {
if (historyIndex == null) {
return;
}
const newIndex = historyIndex + 1;
if (newIndex >= history.length) {
setHistoryIndex(null);
setValue(draftInput);
} else {
setHistoryIndex(newIndex);
setValue(history[newIndex] ?? "");
}
} else if (input === "/context" || input === ":context") {
setShowDirInfo(true);
}
});
return (
<Box flexDirection="column">
<Box>
<Text>{message}</Text>
<TextInput
value={value}
onChange={setValue}
placeholder="Type here…"
showCursor
focus
/>
</Box>
</Box>
);
}