This commit is contained in:
alex wiesner
2026-04-09 11:31:06 +01:00
parent 8fec8e28f4
commit 18245c778e
155 changed files with 16206 additions and 2980 deletions

View File

@@ -11,6 +11,7 @@ import {
nextTabAfterAnswer,
normalizeQuestions,
summarizeAnswers,
wrapPrefixedText,
} from "./question-core.mjs";
interface QuestionOption {
@@ -220,6 +221,32 @@ async function runQuestionFlow(ctx: any, questions: Question[]): Promise<Questio
const question = currentQuestion();
const options = currentOptions();
function addWrapped(text: string, color: string, firstPrefix = "", continuationPrefix = firstPrefix) {
for (const line of wrapPrefixedText(text, width, firstPrefix, continuationPrefix)) {
add(theme.fg(color, line));
}
}
function addWrappedOption(option: QuestionOption, index: number, selected: boolean) {
const firstPrefix = `${selected ? "> " : " "}${index + 1}. `;
const continuationPrefix = " ".repeat(firstPrefix.length);
addWrapped(option.label, selected ? "accent" : "text", firstPrefix, continuationPrefix);
if (option.description) {
addWrapped(option.description, "muted", " ");
}
}
function addWrappedReviewAnswer(questionLabel: string, value: string) {
const firstPrefix = ` ${questionLabel}: `;
const continuationPrefix = " ".repeat(firstPrefix.length);
const wrapped = wrapPrefixedText(value, width, firstPrefix, continuationPrefix);
for (let index = 0; index < wrapped.length; index += 1) {
const prefix = index === 0 ? firstPrefix : continuationPrefix;
const line = wrapped[index]!;
add(theme.fg("muted", prefix) + theme.fg("text", line.slice(prefix.length)));
}
}
add(theme.fg("accent", "─".repeat(width)));
if (isMulti) {
@@ -247,19 +274,14 @@ async function runQuestionFlow(ctx: any, questions: Question[]): Promise<Questio
}
if (inputMode && question) {
add(theme.fg("text", ` ${question.prompt}`));
addWrapped(question.prompt, "text", " ");
lines.push("");
for (let index = 0; index < options.length; index += 1) {
const option = options[index]!;
const prefix = index === optionIndex ? theme.fg("accent", "> ") : " ";
add(prefix + theme.fg(index === optionIndex ? "accent" : "text", `${index + 1}. ${option.label}`));
if (option.description) {
add(` ${theme.fg("muted", option.description)}`);
}
addWrappedOption(options[index]!, index, index === optionIndex);
}
lines.push("");
add(theme.fg("muted", " Your answer:"));
for (const line of editor.render(width - 2)) {
for (const line of editor.render(Math.max(1, width - 2))) {
add(` ${line}`);
}
} else if (isMulti && currentTab === questions.length) {
@@ -269,7 +291,7 @@ async function runQuestionFlow(ctx: any, questions: Question[]): Promise<Questio
const answer = answers.get(reviewQuestion.id);
if (!answer) continue;
const label = answer.wasCustom ? `(wrote) ${answer.label}` : `${answer.index}. ${answer.label}`;
add(`${theme.fg("muted", ` ${reviewQuestion.label}: `)}${theme.fg("text", label)}`);
addWrappedReviewAnswer(reviewQuestion.label, label);
}
lines.push("");
if (allQuestionsAnswered(questions, answers)) {
@@ -278,15 +300,10 @@ async function runQuestionFlow(ctx: any, questions: Question[]): Promise<Questio
add(theme.fg("warning", " All questions must be answered before submit"));
}
} else if (question) {
add(theme.fg("text", ` ${question.prompt}`));
addWrapped(question.prompt, "text", " ");
lines.push("");
for (let index = 0; index < options.length; index += 1) {
const option = options[index]!;
const prefix = index === optionIndex ? theme.fg("accent", "> ") : " ";
add(prefix + theme.fg(index === optionIndex ? "accent" : "text", `${index + 1}. ${option.label}`));
if (option.description) {
add(` ${theme.fg("muted", option.description)}`);
}
addWrappedOption(options[index]!, index, index === optionIndex);
}
}