@nanocollective/nanocoder
Version:
A local-first CLI coding agent that brings the power of agentic coding tools like Claude Code and Gemini CLI to local models or controlled APIs like OpenRouter
58 lines • 2.99 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { Box, Text, useInput } from 'ink';
import SelectInput from 'ink-select-input';
import { useRef, useState } from 'react';
import TextInput from '../components/text-input.js';
import { useTerminalWidth } from '../hooks/useTerminalWidth.js';
import { useTheme } from '../hooks/useTheme.js';
export default function QuestionPrompt({ question, onAnswer, }) {
const { colors } = useTheme();
const boxWidth = useTerminalWidth();
const answeredRef = useRef(false);
const [isFreeformMode, setIsFreeformMode] = useState(false);
const [freeformValue, setFreeformValue] = useState('');
// Build option items for SelectInput
const items = question.options.map(opt => ({
label: opt,
value: opt,
}));
if (question.allowFreeform) {
items.push({
label: 'Type custom answer...',
value: '__freeform__',
});
}
const submitAnswer = (answer) => {
if (answeredRef.current)
return;
answeredRef.current = true;
onAnswer(answer);
};
const handleSelect = (item) => {
if (item.value === '__freeform__') {
setIsFreeformMode(true);
return;
}
submitAnswer(item.value);
};
const handleFreeformSubmit = (value) => {
if (value.trim()) {
submitAnswer(value.trim());
}
};
// Handle escape to cancel (resolves with decline message)
useInput((_input, key) => {
if (key.escape) {
if (isFreeformMode) {
// Go back to option selection
setIsFreeformMode(false);
setFreeformValue('');
}
else {
submitAnswer('User declined to answer');
}
}
});
return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Box, { flexDirection: "row", marginBottom: 1, backgroundColor: colors.base, width: boxWidth, padding: 1, borderStyle: "bold", borderLeft: true, borderRight: false, borderTop: false, borderBottom: false, borderLeftColor: colors.secondary, children: [_jsx(Text, { color: colors.tool, bold: true, children: "?" }), _jsxs(Text, { color: colors.text, children: [" ", question.question] })] }), isFreeformMode ? (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: colors.secondary, children: '> ' }), _jsx(TextInput, { value: freeformValue, onChange: setFreeformValue, onSubmit: handleFreeformSubmit })] }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.secondary, children: "Press Enter to submit, Escape to go back" }) })] })) : (_jsxs(Box, { flexDirection: "column", children: [_jsx(SelectInput, { items: items, onSelect: handleSelect }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.secondary, children: "Press Escape to cancel" }) })] }))] }));
}
//# sourceMappingURL=question-prompt.js.map