mirror of
http://10.0.2.1:3031/sauer/claude-code.git
synced 2026-06-30 20:26:58 +10:00
645 lines
80 KiB
TypeScript
645 lines
80 KiB
TypeScript
|
|
import { c as _c } from "react/compiler-runtime";
|
||
|
|
import type { Base64ImageSource, ImageBlockParam } from '@anthropic-ai/sdk/resources/messages.mjs';
|
||
|
|
import React, { Suspense, use, useCallback, useMemo, useRef, useState } from 'react';
|
||
|
|
import { useSettings } from '../../../hooks/useSettings.js';
|
||
|
|
import { useTerminalSize } from '../../../hooks/useTerminalSize.js';
|
||
|
|
import { stringWidth } from '../../../ink/stringWidth.js';
|
||
|
|
import { useTheme } from '../../../ink.js';
|
||
|
|
import { useKeybindings } from '../../../keybindings/useKeybinding.js';
|
||
|
|
import { type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, logEvent } from '../../../services/analytics/index.js';
|
||
|
|
import { useAppState } from '../../../state/AppState.js';
|
||
|
|
import type { Question } from '../../../tools/AskUserQuestionTool/AskUserQuestionTool.js';
|
||
|
|
import { AskUserQuestionTool } from '../../../tools/AskUserQuestionTool/AskUserQuestionTool.js';
|
||
|
|
import { type CliHighlight, getCliHighlightPromise } from '../../../utils/cliHighlight.js';
|
||
|
|
import type { PastedContent } from '../../../utils/config.js';
|
||
|
|
import type { ImageDimensions } from '../../../utils/imageResizer.js';
|
||
|
|
import { maybeResizeAndDownsampleImageBlock } from '../../../utils/imageResizer.js';
|
||
|
|
import { cacheImagePath, storeImage } from '../../../utils/imageStore.js';
|
||
|
|
import { logError } from '../../../utils/log.js';
|
||
|
|
import { applyMarkdown } from '../../../utils/markdown.js';
|
||
|
|
import { isPlanModeInterviewPhaseEnabled } from '../../../utils/planModeV2.js';
|
||
|
|
import { getPlanFilePath } from '../../../utils/plans.js';
|
||
|
|
import type { PermissionRequestProps } from '../PermissionRequest.js';
|
||
|
|
import { QuestionView } from './QuestionView.js';
|
||
|
|
import { SubmitQuestionsView } from './SubmitQuestionsView.js';
|
||
|
|
import { useMultipleChoiceState } from './use-multiple-choice-state.js';
|
||
|
|
const MIN_CONTENT_HEIGHT = 12;
|
||
|
|
const MIN_CONTENT_WIDTH = 40;
|
||
|
|
// Lines used by chrome around the content area (nav bar, title, footer, help text, etc.)
|
||
|
|
const CONTENT_CHROME_OVERHEAD = 15;
|
||
|
|
export function AskUserQuestionPermissionRequest(props) {
|
||
|
|
const $ = _c(4);
|
||
|
|
const settings = useSettings();
|
||
|
|
if (settings.syntaxHighlightingDisabled) {
|
||
|
|
let t0;
|
||
|
|
if ($[0] !== props) {
|
||
|
|
t0 = <AskUserQuestionPermissionRequestBody {...props} highlight={null} />;
|
||
|
|
$[0] = props;
|
||
|
|
$[1] = t0;
|
||
|
|
} else {
|
||
|
|
t0 = $[1];
|
||
|
|
}
|
||
|
|
return t0;
|
||
|
|
}
|
||
|
|
let t0;
|
||
|
|
if ($[2] !== props) {
|
||
|
|
t0 = <Suspense fallback={<AskUserQuestionPermissionRequestBody {...props} highlight={null} />}><AskUserQuestionWithHighlight {...props} /></Suspense>;
|
||
|
|
$[2] = props;
|
||
|
|
$[3] = t0;
|
||
|
|
} else {
|
||
|
|
t0 = $[3];
|
||
|
|
}
|
||
|
|
return t0;
|
||
|
|
}
|
||
|
|
function AskUserQuestionWithHighlight(props) {
|
||
|
|
const $ = _c(4);
|
||
|
|
let t0;
|
||
|
|
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||
|
|
t0 = getCliHighlightPromise();
|
||
|
|
$[0] = t0;
|
||
|
|
} else {
|
||
|
|
t0 = $[0];
|
||
|
|
}
|
||
|
|
const highlight = use(t0);
|
||
|
|
let t1;
|
||
|
|
if ($[1] !== highlight || $[2] !== props) {
|
||
|
|
t1 = <AskUserQuestionPermissionRequestBody {...props} highlight={highlight} />;
|
||
|
|
$[1] = highlight;
|
||
|
|
$[2] = props;
|
||
|
|
$[3] = t1;
|
||
|
|
} else {
|
||
|
|
t1 = $[3];
|
||
|
|
}
|
||
|
|
return t1;
|
||
|
|
}
|
||
|
|
function AskUserQuestionPermissionRequestBody(t0) {
|
||
|
|
const $ = _c(115);
|
||
|
|
const {
|
||
|
|
toolUseConfirm,
|
||
|
|
onDone,
|
||
|
|
onReject,
|
||
|
|
highlight
|
||
|
|
} = t0;
|
||
|
|
let t1;
|
||
|
|
if ($[0] !== toolUseConfirm.input) {
|
||
|
|
t1 = AskUserQuestionTool.inputSchema.safeParse(toolUseConfirm.input);
|
||
|
|
$[0] = toolUseConfirm.input;
|
||
|
|
$[1] = t1;
|
||
|
|
} else {
|
||
|
|
t1 = $[1];
|
||
|
|
}
|
||
|
|
const result = t1;
|
||
|
|
let t2;
|
||
|
|
if ($[2] !== result.data || $[3] !== result.success) {
|
||
|
|
t2 = result.success ? result.data.questions || [] : [];
|
||
|
|
$[2] = result.data;
|
||
|
|
$[3] = result.success;
|
||
|
|
$[4] = t2;
|
||
|
|
} else {
|
||
|
|
t2 = $[4];
|
||
|
|
}
|
||
|
|
const questions = t2;
|
||
|
|
const {
|
||
|
|
rows: terminalRows
|
||
|
|
} = useTerminalSize();
|
||
|
|
const [theme] = useTheme();
|
||
|
|
let maxHeight = 0;
|
||
|
|
let maxWidth = 0;
|
||
|
|
const maxAllowedHeight = Math.max(MIN_CONTENT_HEIGHT, terminalRows - CONTENT_CHROME_OVERHEAD);
|
||
|
|
if ($[5] !== highlight || $[6] !== maxAllowedHeight || $[7] !== maxHeight || $[8] !== maxWidth || $[9] !== questions || $[10] !== theme) {
|
||
|
|
for (const q of questions) {
|
||
|
|
const hasPreview = q.options.some(_temp);
|
||
|
|
if (hasPreview) {
|
||
|
|
const maxPreviewContentLines = Math.max(1, maxAllowedHeight - 11);
|
||
|
|
let maxPreviewBoxHeight = 0;
|
||
|
|
for (const opt_0 of q.options) {
|
||
|
|
if (opt_0.preview) {
|
||
|
|
const rendered = applyMarkdown(opt_0.preview, theme, highlight);
|
||
|
|
const previewLines = rendered.split("\n");
|
||
|
|
const isTruncated = previewLines.length > maxPreviewContentLines;
|
||
|
|
const displayedLines = isTruncated ? maxPreviewContentLines : previewLines.length;
|
||
|
|
maxPreviewBoxHeight = Math.max(maxPreviewBoxHeight, displayedLines + (isTruncated ? 1 : 0) + 2);
|
||
|
|
for (const line of previewLines) {
|
||
|
|
maxWidth = Math.max(maxWidth, stringWidth(line));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const rightPanelHeight = maxPreviewBoxHeight + 2;
|
||
|
|
const leftPanelHeight = q.options.length + 2;
|
||
|
|
const sideByHeight = Math.max(leftPanelHeight, rightPanelHeight);
|
||
|
|
maxHeight = Math.max(maxHeight, sideByHeight + 7);
|
||
|
|
} else {
|
||
|
|
maxHeight = Math.max(maxHeight, q.options.length + 3 + 7);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
$[5] = highlight;
|
||
|
|
$[6] = maxAllowedHeight;
|
||
|
|
$[7] = maxHeight;
|
||
|
|
$[8] = maxWidth;
|
||
|
|
$[9] = questions;
|
||
|
|
$[10] = theme;
|
||
|
|
$[11] = maxHeight;
|
||
|
|
} else {
|
||
|
|
maxHeight = $[11];
|
||
|
|
}
|
||
|
|
const t3 = Math.min(Math.max(maxHeight, MIN_CONTENT_HEIGHT), maxAllowedHeight);
|
||
|
|
const t4 = Math.max(maxWidth, MIN_CONTENT_WIDTH);
|
||
|
|
let t5;
|
||
|
|
if ($[12] !== t3 || $[13] !== t4) {
|
||
|
|
t5 = {
|
||
|
|
globalContentHeight: t3,
|
||
|
|
globalContentWidth: t4
|
||
|
|
};
|
||
|
|
$[12] = t3;
|
||
|
|
$[13] = t4;
|
||
|
|
$[14] = t5;
|
||
|
|
} else {
|
||
|
|
t5 = $[14];
|
||
|
|
}
|
||
|
|
const {
|
||
|
|
globalContentHeight,
|
||
|
|
globalContentWidth
|
||
|
|
} = t5;
|
||
|
|
const metadataSource = result.success ? result.data.metadata?.source : undefined;
|
||
|
|
let t6;
|
||
|
|
if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
|
||
|
|
t6 = {};
|
||
|
|
$[15] = t6;
|
||
|
|
} else {
|
||
|
|
t6 = $[15];
|
||
|
|
}
|
||
|
|
const [pastedContentsByQuestion, setPastedContentsByQuestion] = useState(t6);
|
||
|
|
const nextPasteIdRef = useRef(0);
|
||
|
|
let t7;
|
||
|
|
if ($[16] === Symbol.for("react.memo_cache_sentinel")) {
|
||
|
|
t7 = function onImagePaste(questionText, base64Image, mediaType, filename, dimensions, _sourcePath) {
|
||
|
|
nextPasteIdRef.current = nextPasteIdRef.current + 1;
|
||
|
|
const pasteId = nextPasteIdRef.current;
|
||
|
|
const newContent = {
|
||
|
|
id: pasteId,
|
||
|
|
type: "image",
|
||
|
|
content: base64Image,
|
||
|
|
mediaType: mediaType || "image/png",
|
||
|
|
filename: filename || "Pasted image",
|
||
|
|
dimensions
|
||
|
|
};
|
||
|
|
cacheImagePath(newContent);
|
||
|
|
storeImage(newContent);
|
||
|
|
setPastedContentsByQuestion(prev => ({
|
||
|
|
...prev,
|
||
|
|
[questionText]: {
|
||
|
|
...(prev[questionText] ?? {}),
|
||
|
|
[pasteId]: newContent
|
||
|
|
}
|
||
|
|
}));
|
||
|
|
};
|
||
|
|
$[16] = t7;
|
||
|
|
} else {
|
||
|
|
t7 = $[16];
|
||
|
|
}
|
||
|
|
const onImagePaste = t7;
|
||
|
|
let t8;
|
||
|
|
if ($[17] === Symbol.for("react.memo_cache_sentinel")) {
|
||
|
|
t8 = (questionText_0, id) => {
|
||
|
|
setPastedContentsByQuestion(prev_0 => {
|
||
|
|
const questionContents = {
|
||
|
|
...(prev_0[questionText_0] ?? {})
|
||
|
|
};
|
||
|
|
delete questionContents[id];
|
||
|
|
return {
|
||
|
|
...prev_0,
|
||
|
|
[questionText_0]: questionContents
|
||
|
|
};
|
||
|
|
});
|
||
|
|
};
|
||
|
|
$[17] = t8;
|
||
|
|
} else {
|
||
|
|
t8 = $[17];
|
||
|
|
}
|
||
|
|
const onRemoveImage = t8;
|
||
|
|
let t9;
|
||
|
|
if ($[18] !== pastedContentsByQuestion) {
|
||
|
|
t9 = Object.values(pastedContentsByQuestion).flatMap(_temp2).filter(_temp3);
|
||
|
|
$[18] = pastedContentsByQuestion;
|
||
|
|
$[19] = t9;
|
||
|
|
} else {
|
||
|
|
t9 = $[19];
|
||
|
|
}
|
||
|
|
const allImageAttachments = t9;
|
||
|
|
const toolPermissionContextMode = useAppState(_temp4);
|
||
|
|
const isInPlanMode = toolPermissionContextMode === "plan";
|
||
|
|
let t10;
|
||
|
|
if ($[20] !== isInPlanMode) {
|
||
|
|
t10 = isInPlanMode ? getPlanFilePath() : undefined;
|
||
|
|
$[20] = isInPlanMode;
|
||
|
|
$[21] = t10;
|
||
|
|
} else {
|
||
|
|
t10 = $[21];
|
||
|
|
}
|
||
|
|
const planFilePath = t10;
|
||
|
|
const state = useMultipleChoiceState();
|
||
|
|
const {
|
||
|
|
currentQuestionIndex,
|
||
|
|
answers,
|
||
|
|
questionStates,
|
||
|
|
isInTextInput,
|
||
|
|
nextQuestion,
|
||
|
|
prevQuestion,
|
||
|
|
updateQuestionState,
|
||
|
|
setAnswer,
|
||
|
|
setTextInputMode
|
||
|
|
} = state;
|
||
|
|
const currentQuestion = currentQuestionIndex < (questions?.length || 0) ? questions?.[currentQuestionIndex] : null;
|
||
|
|
const isInSubmitView = currentQuestionIndex === (questions?.length || 0);
|
||
|
|
let t11;
|
||
|
|
if ($[22] !== answers || $[23] !== questions) {
|
||
|
|
t11 = questions?.every(q_0 => q_0?.question && !!answers[q_0.question]) ?? false;
|
||
|
|
$[22] = answers;
|
||
|
|
$[23] = questions;
|
||
|
|
$[24] = t11;
|
||
|
|
} else {
|
||
|
|
t11 = $[24];
|
||
|
|
}
|
||
|
|
const allQuestionsAnswered = t11;
|
||
|
|
const hideSubmitTab = questions.length === 1 && !questions[0]?.multiSelect;
|
||
|
|
let t12;
|
||
|
|
if ($[25] !== isInPlanMode || $[26] !== metadataSource || $[27] !== onDone || $[28] !== onReject || $[29] !== questions.length || $[30] !== toolUseConfirm) {
|
||
|
|
t12 = () => {
|
||
|
|
if (metadataSource) {
|
||
|
|
logEvent("tengu_ask_user_question_rejected", {
|
||
|
|
source: metadataSource as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||
|
|
questionCount: questions.length,
|
||
|
|
isInPlanMode,
|
||
|
|
interviewPhaseEnabled: isInPlanMode && isPlanModeInterviewPhaseEnabled()
|
||
|
|
});
|
||
|
|
}
|
||
|
|
onDone();
|
||
|
|
onReject();
|
||
|
|
toolUseConfirm.onReject();
|
||
|
|
};
|
||
|
|
$[25] = isInPlanMode;
|
||
|
|
$[26] = metadataSource;
|
||
|
|
$[27] = onDone;
|
||
|
|
$[28] = onReject;
|
||
|
|
$[29] = questions.length;
|
||
|
|
$[30] = toolUseConfirm;
|
||
|
|
$[31] = t12;
|
||
|
|
} else {
|
||
|
|
t12 = $[31];
|
||
|
|
}
|
||
|
|
const handleCancel = t12;
|
||
|
|
let t13;
|
||
|
|
if ($[32] !== allImageAttachments || $[33] !== answers || $[34] !== isInPlanMode || $[35] !== metadataSource || $[36] !== onDone || $[37] !== questions || $[38] !== toolUseConfirm) {
|
||
|
|
t13 = async () => {
|
||
|
|
const questionsWithAnswers = questions.map(q_1 => {
|
||
|
|
const answer = answers[q_1.question];
|
||
|
|
if (answer) {
|
||
|
|
return `- "${q_1.question}"\n Answer: ${answer}`;
|
||
|
|
}
|
||
|
|
return `- "${q_1.question}"\n (No answer provided)`;
|
||
|
|
}).join("\n");
|
||
|
|
const feedback = `The user wants to clarify these questions.
|
||
|
|
This means they may have additional information, context or questions for you.
|
||
|
|
Take their response into account and then reformulate the questions if appropriate.
|
||
|
|
Start by asking them what they would like to clarify.
|
||
|
|
|
||
|
|
Questions asked:\n${questionsWithAnswers}`;
|
||
|
|
if (metadataSource) {
|
||
|
|
logEvent("tengu_ask_user_question_respond_to_claude", {
|
||
|
|
source: metadataSource as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||
|
|
questionCount: questions.length,
|
||
|
|
isInPlanMode,
|
||
|
|
interviewPhaseEnabled: isInPlanMode && isPlanModeInterviewPhaseEnabled()
|
||
|
|
});
|
||
|
|
}
|
||
|
|
const imageBlocks = await convertImagesToBlocks(allImageAttachments);
|
||
|
|
onDone();
|
||
|
|
toolUseConfirm.onReject(feedback, imageBlocks && imageBlocks.length > 0 ? imageBlocks : undefined);
|
||
|
|
};
|
||
|
|
$[32] = allImageAttachments;
|
||
|
|
$[33] = answers;
|
||
|
|
$[34] = isInPlanMode;
|
||
|
|
$[35] = metadataSource;
|
||
|
|
$[36] = onDone;
|
||
|
|
$[37] = questions;
|
||
|
|
$[38] = toolUseConfirm;
|
||
|
|
$[39] = t13;
|
||
|
|
} else {
|
||
|
|
t13 = $[39];
|
||
|
|
}
|
||
|
|
const handleRespondToClaude = t13;
|
||
|
|
let t14;
|
||
|
|
if ($[40] !== allImageAttachments || $[41] !== answers || $[42] !== isInPlanMode || $[43] !== metadataSource || $[44] !== onDone || $[45] !== questions || $[46] !== toolUseConfirm) {
|
||
|
|
t14 = async () => {
|
||
|
|
const questionsWithAnswers_0 = questions.map(q_2 => {
|
||
|
|
const answer_0 = answers[q_2.question];
|
||
|
|
if (answer_0) {
|
||
|
|
return `- "${q_2.question}"\n Answer: ${answer_0}`;
|
||
|
|
}
|
||
|
|
return `- "${q_2.question}"\n (No answer provided)`;
|
||
|
|
}).join("\n");
|
||
|
|
const feedback_0 = `The user has indicated they have provided enough answers for the plan interview.
|
||
|
|
Stop asking clarifying questions and proceed to finish the plan with the information you have.
|
||
|
|
|
||
|
|
Questions asked and answers provided:\n${questionsWithAnswers_0}`;
|
||
|
|
if (metadataSource) {
|
||
|
|
logEvent("tengu_ask_user_question_finish_plan_interview", {
|
||
|
|
source: metadataSource as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||
|
|
questionCount: questions.length,
|
||
|
|
isInPlanMode,
|
||
|
|
interviewPhaseEnabled: isInPlanMode && isPlanModeInterviewPhaseEnabled()
|
||
|
|
});
|
||
|
|
}
|
||
|
|
const imageBlocks_0 = await convertImagesToBlocks(allImageAttachments);
|
||
|
|
onDone();
|
||
|
|
toolUseConfirm.onReject(feedback_0, imageBlocks_0 && imageBlocks_0.length > 0 ? imageBlocks_0 : undefined);
|
||
|
|
};
|
||
|
|
$[40] = allImageAttachments;
|
||
|
|
$[41] = answers;
|
||
|
|
$[42] = isInPlanMode;
|
||
|
|
$[43] = metadataSource;
|
||
|
|
$[44] = onDone;
|
||
|
|
$[45] = questions;
|
||
|
|
$[46] = toolUseConfirm;
|
||
|
|
$[47] = t14;
|
||
|
|
} else {
|
||
|
|
t14 = $[47];
|
||
|
|
}
|
||
|
|
const handleFinishPlanInterview = t14;
|
||
|
|
let t15;
|
||
|
|
if ($[48] !== allImageAttachments || $[49] !== isInPlanMode || $[50] !== metadataSource || $[51] !== onDone || $[52] !== questionStates || $[53] !== questions || $[54] !== toolUseConfirm) {
|
||
|
|
t15 = async answersToSubmit => {
|
||
|
|
if (metadataSource) {
|
||
|
|
logEvent("tengu_ask_user_question_accepted", {
|
||
|
|
source: metadataSource as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||
|
|
questionCount: questions.length,
|
||
|
|
answerCount: Object.keys(answersToSubmit).length,
|
||
|
|
isInPlanMode,
|
||
|
|
interviewPhaseEnabled: isInPlanMode && isPlanModeInterviewPhaseEnabled()
|
||
|
|
});
|
||
|
|
}
|
||
|
|
const annotations = {};
|
||
|
|
for (const q_3 of questions) {
|
||
|
|
const answer_1 = answersToSubmit[q_3.question];
|
||
|
|
const notes = questionStates[q_3.question]?.textInputValue;
|
||
|
|
const selectedOption = answer_1 ? q_3.options.find(opt_1 => opt_1.label === answer_1) : undefined;
|
||
|
|
const preview = selectedOption?.preview;
|
||
|
|
if (preview || notes?.trim()) {
|
||
|
|
annotations[q_3.question] = {
|
||
|
|
...(preview && {
|
||
|
|
preview
|
||
|
|
}),
|
||
|
|
...(notes?.trim() && {
|
||
|
|
notes: notes.trim()
|
||
|
|
})
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const updatedInput = {
|
||
|
|
...toolUseConfirm.input,
|
||
|
|
answers: answersToSubmit,
|
||
|
|
...(Object.keys(annotations).length > 0 && {
|
||
|
|
annotations
|
||
|
|
})
|
||
|
|
};
|
||
|
|
const contentBlocks = await convertImagesToBlocks(allImageAttachments);
|
||
|
|
onDone();
|
||
|
|
toolUseConfirm.onAllow(updatedInput, [], undefined, contentBlocks && contentBlocks.length > 0 ? contentBlocks : undefined);
|
||
|
|
};
|
||
|
|
$[48] = allImageAttachments;
|
||
|
|
$[49] = isInPlanMode;
|
||
|
|
$[50] = metadataSource;
|
||
|
|
$[51] = onDone;
|
||
|
|
$[52] = questionStates;
|
||
|
|
$[53] = questions;
|
||
|
|
$[54] = toolUseConfirm;
|
||
|
|
$[55] = t15;
|
||
|
|
} else {
|
||
|
|
t15 = $[55];
|
||
|
|
}
|
||
|
|
const submitAnswers = t15;
|
||
|
|
let t16;
|
||
|
|
if ($[56] !== answers || $[57] !== pastedContentsByQuestion || $[58] !== questions.length || $[59] !== setAnswer || $[60] !== submitAnswers) {
|
||
|
|
t16 = (questionText_1, label, textInput, t17) => {
|
||
|
|
const shouldAdvance = t17 === undefined ? true : t17;
|
||
|
|
let answer_2;
|
||
|
|
const isMultiSelect = Array.isArray(label);
|
||
|
|
if (isMultiSelect) {
|
||
|
|
answer_2 = label.join(", ");
|
||
|
|
} else {
|
||
|
|
if (textInput) {
|
||
|
|
const questionImages = Object.values(pastedContentsByQuestion[questionText_1] ?? {}).filter(_temp5);
|
||
|
|
answer_2 = questionImages.length > 0 ? `${textInput} (Image attached)` : textInput;
|
||
|
|
} else {
|
||
|
|
if (label === "__other__") {
|
||
|
|
const questionImages_0 = Object.values(pastedContentsByQuestion[questionText_1] ?? {}).filter(_temp6);
|
||
|
|
answer_2 = questionImages_0.length > 0 ? "(Image attached)" : label;
|
||
|
|
} else {
|
||
|
|
answer_2 = label;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
const isSingleQuestion = questions.length === 1;
|
||
|
|
if (!isMultiSelect && isSingleQuestion && shouldAdvance) {
|
||
|
|
const updatedAnswers = {
|
||
|
|
...answers,
|
||
|
|
[questionText_1]: answer_2
|
||
|
|
};
|
||
|
|
submitAnswers(updatedAnswers).catch(logError);
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
setAnswer(questionText_1, answer_2, shouldAdvance);
|
||
|
|
};
|
||
|
|
$[56] = answers;
|
||
|
|
$[57] = pastedContentsByQuestion;
|
||
|
|
$[58] = questions.length;
|
||
|
|
$[59] = setAnswer;
|
||
|
|
$[60] = submitAnswers;
|
||
|
|
$[61] = t16;
|
||
|
|
} else {
|
||
|
|
t16 = $[61];
|
||
|
|
}
|
||
|
|
const handleQuestionAnswer = t16;
|
||
|
|
let t17;
|
||
|
|
if ($[62] !== answers || $[63] !== handleCancel || $[64] !== submitAnswers) {
|
||
|
|
t17 = function handleFinalResponse(value) {
|
||
|
|
if (value === "cancel") {
|
||
|
|
handleCancel();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
if (value === "submit") {
|
||
|
|
submitAnswers(answers).catch(logError);
|
||
|
|
}
|
||
|
|
};
|
||
|
|
$[62] = answers;
|
||
|
|
$[63] = handleCancel;
|
||
|
|
$[64] = submitAnswers;
|
||
|
|
$[65] = t17;
|
||
|
|
} else {
|
||
|
|
t17 = $[65];
|
||
|
|
}
|
||
|
|
const handleFinalResponse = t17;
|
||
|
|
const maxIndex = hideSubmitTab ? (questions?.length || 1) - 1 : questions?.length || 0;
|
||
|
|
let t18;
|
||
|
|
if ($[66] !== currentQuestionIndex || $[67] !== prevQuestion) {
|
||
|
|
t18 = () => {
|
||
|
|
if (currentQuestionIndex > 0) {
|
||
|
|
prevQuestion();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
$[66] = currentQuestionIndex;
|
||
|
|
$[67] = prevQuestion;
|
||
|
|
$[68] = t18;
|
||
|
|
} else {
|
||
|
|
t18 = $[68];
|
||
|
|
}
|
||
|
|
const handleTabPrev = t18;
|
||
|
|
let t19;
|
||
|
|
if ($[69] !== currentQuestionIndex || $[70] !== maxIndex || $[71] !== nextQuestion) {
|
||
|
|
t19 = () => {
|
||
|
|
if (currentQuestionIndex < maxIndex) {
|
||
|
|
nextQuestion();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
$[69] = currentQuestionIndex;
|
||
|
|
$[70] = maxIndex;
|
||
|
|
$[71] = nextQuestion;
|
||
|
|
$[72] = t19;
|
||
|
|
} else {
|
||
|
|
t19 = $[72];
|
||
|
|
}
|
||
|
|
const handleTabNext = t19;
|
||
|
|
let t20;
|
||
|
|
if ($[73] !== handleTabNext || $[74] !== handleTabPrev) {
|
||
|
|
t20 = {
|
||
|
|
"tabs:previous": handleTabPrev,
|
||
|
|
"tabs:next": handleTabNext
|
||
|
|
};
|
||
|
|
$[73] = handleTabNext;
|
||
|
|
$[74] = handleTabPrev;
|
||
|
|
$[75] = t20;
|
||
|
|
} else {
|
||
|
|
t20 = $[75];
|
||
|
|
}
|
||
|
|
const t21 = !(isInTextInput && !isInSubmitView);
|
||
|
|
let t22;
|
||
|
|
if ($[76] !== t21) {
|
||
|
|
t22 = {
|
||
|
|
context: "Tabs",
|
||
|
|
isActive: t21
|
||
|
|
};
|
||
|
|
$[76] = t21;
|
||
|
|
$[77] = t22;
|
||
|
|
} else {
|
||
|
|
t22 = $[77];
|
||
|
|
}
|
||
|
|
useKeybindings(t20, t22);
|
||
|
|
if (currentQuestion) {
|
||
|
|
let t23;
|
||
|
|
if ($[78] !== currentQuestion.question) {
|
||
|
|
t23 = (base64, mediaType_0, filename_0, dims, path) => onImagePaste(currentQuestion.question, base64, mediaType_0, filename_0, dims, path);
|
||
|
|
$[78] = currentQuestion.question;
|
||
|
|
$[79] = t23;
|
||
|
|
} else {
|
||
|
|
t23 = $[79];
|
||
|
|
}
|
||
|
|
let t24;
|
||
|
|
if ($[80] !== currentQuestion.question || $[81] !== pastedContentsByQuestion) {
|
||
|
|
t24 = pastedContentsByQuestion[currentQuestion.question] ?? {};
|
||
|
|
$[80] = currentQuestion.question;
|
||
|
|
$[81] = pastedContentsByQuestion;
|
||
|
|
$[82] = t24;
|
||
|
|
} else {
|
||
|
|
t24 = $[82];
|
||
|
|
}
|
||
|
|
let t25;
|
||
|
|
if ($[83] !== currentQuestion.question) {
|
||
|
|
t25 = id_0 => onRemoveImage(currentQuestion.question, id_0);
|
||
|
|
$[83] = currentQuestion.question;
|
||
|
|
$[84] = t25;
|
||
|
|
} else {
|
||
|
|
t25 = $[84];
|
||
|
|
}
|
||
|
|
let t26;
|
||
|
|
if ($[85] !== answers || $[86] !== currentQuestion || $[87] !== currentQuestionIndex || $[88] !== globalContentHeight || $[89] !== globalContentWidth || $[90] !== handleCancel || $[91] !== handleFinishPlanInterview || $[92] !== handleQuestionAnswer || $[93] !== handleRespondToClaude || $[94] !== handleTabNext || $[95] !== handleTabPrev || $[96] !== hideSubmitTab || $[97] !== nextQuestion || $[98] !== planFilePath || $[99] !== questionStates || $[100] !== questions || $[101] !== setTextInputMode || $[102] !== t23 || $[103] !== t24 || $[104] !== t25 || $[105] !== updateQuestionState) {
|
||
|
|
t26 = <><QuestionView question={currentQuestion} questions={questions} currentQuestionIndex={currentQuestionIndex} answers={answers} questionStates={questionStates} hideSubmitTab={hideSubmitTab} minContentHeight={globalContentHeight} minContentWidth={globalContentWidth} planFilePath={planFilePath} onUpdateQuestionState={updateQuestionState} onAnswer={handleQuestionAnswer} onTextInputFocus={setTextInputMode} onCancel={handleCancel} onSubmit={nextQuestion} onTabPrev={handleTabPrev} onTabNext={handleTabNext} onRespondToClaude={handleRespondToClaude} onFinishPlanInterview={handleFinishPlanInterview} onImagePaste={t23} pastedContents={t24} onRemoveImage={t25} /></>;
|
||
|
|
$[85] = answers;
|
||
|
|
$[86] = currentQuestion;
|
||
|
|
$[87] = currentQuestionIndex;
|
||
|
|
$[88] = globalContentHeight;
|
||
|
|
$[89] = globalContentWidth;
|
||
|
|
$[90] = handleCancel;
|
||
|
|
$[91] = handleFinishPlanInterview;
|
||
|
|
$[92] = handleQuestionAnswer;
|
||
|
|
$[93] = handleRespondToClaude;
|
||
|
|
$[94] = handleTabNext;
|
||
|
|
$[95] = handleTabPrev;
|
||
|
|
$[96] = hideSubmitTab;
|
||
|
|
$[97] = nextQuestion;
|
||
|
|
$[98] = planFilePath;
|
||
|
|
$[99] = questionStates;
|
||
|
|
$[100] = questions;
|
||
|
|
$[101] = setTextInputMode;
|
||
|
|
$[102] = t23;
|
||
|
|
$[103] = t24;
|
||
|
|
$[104] = t25;
|
||
|
|
$[105] = updateQuestionState;
|
||
|
|
$[106] = t26;
|
||
|
|
} else {
|
||
|
|
t26 = $[106];
|
||
|
|
}
|
||
|
|
return t26;
|
||
|
|
}
|
||
|
|
if (isInSubmitView) {
|
||
|
|
let t23;
|
||
|
|
if ($[107] !== allQuestionsAnswered || $[108] !== answers || $[109] !== currentQuestionIndex || $[110] !== globalContentHeight || $[111] !== handleFinalResponse || $[112] !== questions || $[113] !== toolUseConfirm.permissionResult) {
|
||
|
|
t23 = <><SubmitQuestionsView questions={questions} currentQuestionIndex={currentQuestionIndex} answers={answers} allQuestionsAnswered={allQuestionsAnswered} permissionResult={toolUseConfirm.permissionResult} minContentHeight={globalContentHeight} onFinalResponse={handleFinalResponse} /></>;
|
||
|
|
$[107] = allQuestionsAnswered;
|
||
|
|
$[108] = answers;
|
||
|
|
$[109] = currentQuestionIndex;
|
||
|
|
$[110] = globalContentHeight;
|
||
|
|
$[111] = handleFinalResponse;
|
||
|
|
$[112] = questions;
|
||
|
|
$[113] = toolUseConfirm.permissionResult;
|
||
|
|
$[114] = t23;
|
||
|
|
} else {
|
||
|
|
t23 = $[114];
|
||
|
|
}
|
||
|
|
return t23;
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
function _temp6(c_1) {
|
||
|
|
return c_1.type === "image";
|
||
|
|
}
|
||
|
|
function _temp5(c_0) {
|
||
|
|
return c_0.type === "image";
|
||
|
|
}
|
||
|
|
function _temp4(s) {
|
||
|
|
return s.toolPermissionContext.mode;
|
||
|
|
}
|
||
|
|
function _temp3(c) {
|
||
|
|
return c.type === "image";
|
||
|
|
}
|
||
|
|
function _temp2(contents) {
|
||
|
|
return Object.values(contents);
|
||
|
|
}
|
||
|
|
function _temp(opt) {
|
||
|
|
return opt.preview;
|
||
|
|
}
|
||
|
|
async function convertImagesToBlocks(images: PastedContent[]): Promise<ImageBlockParam[] | undefined> {
|
||
|
|
if (images.length === 0) return undefined;
|
||
|
|
return Promise.all(images.map(async img => {
|
||
|
|
const block: ImageBlockParam = {
|
||
|
|
type: 'image',
|
||
|
|
source: {
|
||
|
|
type: 'base64',
|
||
|
|
media_type: (img.mediaType || 'image/png') as Base64ImageSource['media_type'],
|
||
|
|
data: img.content
|
||
|
|
}
|
||
|
|
};
|
||
|
|
const resized = await maybeResizeAndDownsampleImageBlock(block);
|
||
|
|
return resized.block;
|
||
|
|
}));
|
||
|
|
}
|
||
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJCYXNlNjRJbWFnZVNvdXJjZSIsIkltYWdlQmxvY2tQYXJhbSIsIlJlYWN0IiwiU3VzcGVuc2UiLCJ1c2UiLCJ1c2VDYWxsYmFjayIsInVzZU1lbW8iLCJ1c2VSZWYiLCJ1c2VTdGF0ZSIsInVzZVNldHRpbmdzIiwidXNlVGVybWluYWxTaXplIiwic3RyaW5nV2lkdGgiLCJ1c2VUaGVtZSIsInVzZUtleWJpbmRpbmdzIiwiQW5hbHl0aWNzTWV0YWRhdGFfSV9WRVJJRklFRF9USElTX0lTX05PVF9DT0RFX09SX0ZJTEVQQVRIUyIsImxvZ0V2ZW50IiwidXNlQXBwU3RhdGUiLCJRdWVzdGlvbiIsIkFza1VzZXJRdWVzdGlvblRvb2wiLCJDbGlIaWdobGlnaHQiLCJnZXRDbGlIaWdobGlnaHRQcm9taXNlIiwiUGFzdGVkQ29udGVudCIsIkltYWdlRGltZW5zaW9ucyIsIm1heWJlUmVzaXplQW5kRG93bnNhbXBsZUltYWdlQmxvY2siLCJjYWNoZUltYWdlUGF0aCIsInN0b3JlSW1hZ2UiLCJsb2dFcnJvciIsImFwcGx5TWFya2Rvd24iLCJpc1BsYW5Nb2RlSW50ZXJ2aWV3UGhhc2VFbmFibGVkIiwiZ2V0UGxhbkZpbGVQYXRoIiwiUGVybWlzc2lvblJlcXVlc3RQcm9wcyIsIlF1ZXN0aW9uVmlldyIsIlN1Ym1pdFF1ZXN0aW9uc1ZpZXciLCJ1c2VNdWx0aXBsZUNob2ljZVN0YXRlIiwiTUlOX0NPTlRFTlRfSEVJR0hUIiwiTUlOX0NPTlRFTlRfV0lEVEgiLCJDT05URU5UX0NIUk9NRV9PVkVSSEVBRCIsIkFza1VzZXJRdWVzdGlvblBlcm1pc3Npb25SZXF1ZXN0IiwicHJvcHMiLCIkIiwiX2MiLCJzZXR0aW5ncyIsInN5bnRheEhpZ2hsaWdodGluZ0Rpc2FibGVkIiwidDAiLCJBc2tVc2VyUXVlc3Rpb25XaXRoSGlnaGxpZ2h0IiwiU3ltYm9sIiwiZm9yIiwiaGlnaGxpZ2h0IiwidDEiLCJBc2tVc2VyUXVlc3Rpb25QZXJtaXNzaW9uUmVxdWVzdEJvZHkiLCJ0b29sVXNlQ29uZmlybSIsIm9uRG9uZSIsIm9uUmVqZWN0IiwiaW5wdXQiLCJpbnB1dFNjaGVtYSIsInNhZmVQYXJzZSIsInJlc3VsdCIsInQyIiwiZGF0YSIsInN1Y2Nlc3MiLCJxdWVzdGlvbnMiLCJyb3dzIiwidGVybWluYWxSb3dzIiwidGhlbWUiLCJtYXhIZWlnaHQiLCJtYXhXaWR0aCIsIm1heEFsbG93ZWRIZWlnaHQiLCJNYXRoIiwibWF4IiwicSIsImhhc1ByZXZpZXciLCJvcHRpb25zIiwic29tZSIsIl90ZW1wIiwibWF4UHJldmlld0NvbnRlbnRMaW5lcyIsIm1heFByZXZpZXdCb3hIZWlnaHQiLCJvcHRfMCIsIm9wdCIsInByZXZpZXciLCJyZW5kZXJlZCIsInByZXZpZXdMaW5lcyIsInNwbGl0IiwiaXNUcnVuY2F0ZWQiLCJsZW5ndGgiLCJkaXNwbGF5ZWRMaW5lcyIsImxpbmUiLCJyaWdodFBhbmVsSGVpZ2h0IiwibGVmdFBhbmVsSGVpZ2h0Iiwic2lkZUJ5SGVpZ2h0IiwidDMiLCJtaW4iLCJ0NCIsInQ1IiwiZ2xvYmFsQ29udGVudEhlaWdodCIsImdsb2JhbENvbnRlbnRXaWR0aCIsIm1ldGFkYXRhU291cmNlIiwibWV0YWRhdGEiLCJzb3VyY2UiLCJ1bmRlZmluZWQiLCJ0NiIsInBhc3RlZENvbnRlbnRzQnlRdWVzdGlvbiIsInNldFBhc3RlZENvbnRlbnRzQnlRdWVzdGlvbiIsIm5leHRQYXN0ZUlkUmVmIiwidDciLCJvbkltYWdlUGFzdGUiLCJxdWVzdGlvblRleHQiLCJiYXNlNjRJbWFnZSIsIm1lZGlhVHlwZSIsImZpbGVuYW1lIiwiZGltZW5zaW9ucyIsIl9zb3VyY2VQYXRoIiwiY3VycmVudCIsInBhc3RlSWQiLCJuZXdDb250ZW50IiwiaWQiLCJ0eXBlIiwiY29udGVudCIsInByZXYiLCJ0OCIsInF1ZXN0aW9uVGV4dF8wIiwicHJldl8wIiwicXVlc3Rpb25Db250ZW50cyIsIm9uUmVtb3ZlSW1hZ2UiLCJ0OSIsIk9iamVjdCIsInZhbHVlcyIsImZsYXRNYXAiLCJfdGVtcDIiLCJmaWx0ZXIiLCJfdGVtcDMiLCJhbGxJbWFnZUF0dGFjaG1lbnRzIiwidG9vbFBlcm1pc3Npb25Db250ZXh0TW9kZSIsIl90ZW1wNCIsImlzSW5QbGFuTW9kZSIsInQxMCIsInBsYW5GaWxlUGF0aCIsInN0YXRlIiwiY3VycmVudFF1ZXN0aW9uSW5kZXgiLCJhbnN3ZXJzIiwicXVlc3Rpb25TdGF0ZXMiLCJpc0luVGV4dElucHV0IiwibmV4dFF1ZXN0aW9uIiwicHJldlF1ZXN0aW9uIiwidXBkYXRlUXVlc3Rpb25TdGF0ZSIsInNldEFuc3dlciIsInNldFRleHRJbnB1dE1vZGUiLCJjdXJyZW50UXVlc3Rpb24iLCJpc0luU3VibWl0VmlldyIsInQxMSIsImV2ZXJ5IiwicV8wIiwicXVlc3Rpb24iLCJhbGxRdWVzdGlvbnNBbnN3ZXJlZCIsImhpZGVTdWJtaXRUYWIiLCJtdWx0aVNlbGVjdCIsInQxMiIsInF1ZXN0aW9uQ291bnQiLCJpbnRlcnZpZXdQaGFzZUVuYWJsZWQiLCJoYW5kbGVDYW5jZWwiLCJ0MTMiLCJxdWVzdGlvbnNXaXRoQW5zd2VycyIsIm1hcCIsInFfMSIsImFuc3dlciIsImpvaW4iLCJmZWVkYmFjayIsImltYWdlQmxvY2tzIiwiY29udmVydEltYWdlc1RvQmxvY2tzIiwiaGFuZGxlUmVzcG9uZFRvQ2xhdWRlIiwidDE0IiwicXVlc3Rpb25zV2l0aEFuc3dlcnNfMCIsInFfMiIsImFuc3dlcl8wIiwiZmVlZGJhY2tfMCIsImltYWdlQmxvY2tzXzAiLCJoYW5kbGVGaW5pc2hQbGFuSW50ZXJ2aWV3IiwidDE1IiwiYW5zd2Vyc1RvU3VibWl0IiwiYW5zd2VyQ291bnQiLCJrZXlzIiwiYW5ub3RhdGlvbnMiLCJxXzMiLCJhbnN3ZXJfMSIsIm5vdGVzIiwidGV4dElucHV0VmFsdWUiLCJzZWxlY3RlZE9wdGlvbiIsImZpbmQiLCJvcHRfMSIsImxhYmVsIiwidHJpbSIsInVwZGF0ZWRJbnB1dCIsImNvbnRlbnRCbG9ja3MiLCJvbkFsbG93Iiwic3VibWl0QW5zd2VycyIsInQxNiIsInF1ZXN0aW9uVGV4dF8xIiwidGV4dElucHV0IiwidDE3Iiwic2hvdWxkQWR2YW5jZSIsImlzTXVsdGlTZWxlY3QiLCJBcnJheSIsImlzQXJyYXkiLCJxdWVzdGlvbkltYWdlcyIsIl90ZW1wNSIsInF1ZXN0aW9uSW1hZ2VzXzAiLCJfdGVtcDYiLCJpc1NpbmdsZVF1ZXN0aW9uIiwidXBkYXRlZEFuc3dlcnMiLCJjYXRjaCIsImhhbmRsZVF1ZXN0aW9uQW5zd2VyIiwiaGFuZGxlRmluYWxSZXNwb25zZSIsInZhbHVlIiwibWF4SW5kZXgiLCJ0MTgiLCJoYW5kbGVUYWJQcmV2IiwidDE5IiwiaGFuZGxlVGFiTmV4dCIsInQyMCIsInQyMSIsInQyMiIsImNvbnRleHQiLCJpc0FjdGl
|