|
|
|
@@ -97,8 +97,8 @@ import { logError } from '../utils/log.js';
|
|
|
|
/* eslint-disable custom-rules/no-process-env-top-level, @typescript-eslint/no-require-imports */
|
|
|
|
/* eslint-disable custom-rules/no-process-env-top-level, @typescript-eslint/no-require-imports */
|
|
|
|
const useVoiceIntegration: typeof import('../hooks/useVoiceIntegration.js').useVoiceIntegration = feature('VOICE_MODE') ? require('../hooks/useVoiceIntegration.js').useVoiceIntegration : () => ({
|
|
|
|
const useVoiceIntegration: typeof import('../hooks/useVoiceIntegration.js').useVoiceIntegration = feature('VOICE_MODE') ? require('../hooks/useVoiceIntegration.js').useVoiceIntegration : () => ({
|
|
|
|
stripTrailing: () => 0,
|
|
|
|
stripTrailing: () => 0,
|
|
|
|
handleKeyEvent: () => {},
|
|
|
|
handleKeyEvent: () => { },
|
|
|
|
resetAnchor: () => {}
|
|
|
|
resetAnchor: () => { }
|
|
|
|
});
|
|
|
|
});
|
|
|
|
const VoiceKeybindingHandler: typeof import('../hooks/useVoiceIntegration.js').VoiceKeybindingHandler = feature('VOICE_MODE') ? require('../hooks/useVoiceIntegration.js').VoiceKeybindingHandler : () => null;
|
|
|
|
const VoiceKeybindingHandler: typeof import('../hooks/useVoiceIntegration.js').VoiceKeybindingHandler = feature('VOICE_MODE') ? require('../hooks/useVoiceIntegration.js').VoiceKeybindingHandler : () => null;
|
|
|
|
// Frustration detection is ant-only (dogfooding). Conditional require so external
|
|
|
|
// Frustration detection is ant-only (dogfooding). Conditional require so external
|
|
|
|
@@ -106,11 +106,11 @@ const VoiceKeybindingHandler: typeof import('../hooks/useVoiceIntegration.js').V
|
|
|
|
// on every messages change, plus the GrowthBook fetch).
|
|
|
|
// on every messages change, plus the GrowthBook fetch).
|
|
|
|
const useFrustrationDetection: typeof import('../components/FeedbackSurvey/useFrustrationDetection.js').useFrustrationDetection = "external" === 'ant' ? require('../components/FeedbackSurvey/useFrustrationDetection.js').useFrustrationDetection : () => ({
|
|
|
|
const useFrustrationDetection: typeof import('../components/FeedbackSurvey/useFrustrationDetection.js').useFrustrationDetection = "external" === 'ant' ? require('../components/FeedbackSurvey/useFrustrationDetection.js').useFrustrationDetection : () => ({
|
|
|
|
state: 'closed',
|
|
|
|
state: 'closed',
|
|
|
|
handleTranscriptSelect: () => {}
|
|
|
|
handleTranscriptSelect: () => { }
|
|
|
|
});
|
|
|
|
});
|
|
|
|
// Ant-only org warning. Conditional require so the org UUID list is
|
|
|
|
// Ant-only org warning. Conditional require so the org UUID list is
|
|
|
|
// eliminated from external builds (one UUID is on excluded-strings).
|
|
|
|
// eliminated from external builds (one UUID is on excluded-strings).
|
|
|
|
const useAntOrgWarningNotification: typeof import('../hooks/notifs/useAntOrgWarningNotification.js').useAntOrgWarningNotification = "external" === 'ant' ? require('../hooks/notifs/useAntOrgWarningNotification.js').useAntOrgWarningNotification : () => {};
|
|
|
|
const useAntOrgWarningNotification: typeof import('../hooks/notifs/useAntOrgWarningNotification.js').useAntOrgWarningNotification = "external" === 'ant' ? require('../hooks/notifs/useAntOrgWarningNotification.js').useAntOrgWarningNotification : () => { };
|
|
|
|
// Dead code elimination: conditional import for coordinator mode
|
|
|
|
// Dead code elimination: conditional import for coordinator mode
|
|
|
|
const getCoordinatorUserContext: (mcpClients: ReadonlyArray<{
|
|
|
|
const getCoordinatorUserContext: (mcpClients: ReadonlyArray<{
|
|
|
|
name: string;
|
|
|
|
name: string;
|
|
|
|
@@ -192,7 +192,7 @@ import { useInboxPoller } from '../hooks/useInboxPoller.js';
|
|
|
|
// Dead code elimination: conditional import for loop mode
|
|
|
|
// Dead code elimination: conditional import for loop mode
|
|
|
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
|
|
/* eslint-disable @typescript-eslint/no-require-imports */
|
|
|
|
const proactiveModule = feature('PROACTIVE') || feature('KAIROS') ? require('../proactive/index.js') : null;
|
|
|
|
const proactiveModule = feature('PROACTIVE') || feature('KAIROS') ? require('../proactive/index.js') : null;
|
|
|
|
const PROACTIVE_NO_OP_SUBSCRIBE = (_cb: () => void) => () => {};
|
|
|
|
const PROACTIVE_NO_OP_SUBSCRIBE = (_cb: () => void) => () => { };
|
|
|
|
const PROACTIVE_FALSE = () => false;
|
|
|
|
const PROACTIVE_FALSE = () => false;
|
|
|
|
const SUGGEST_BG_PR_NOOP = (_p: string, _n: string): boolean => false;
|
|
|
|
const SUGGEST_BG_PR_NOOP = (_p: string, _n: string): boolean => false;
|
|
|
|
const useProactive = feature('PROACTIVE') || feature('KAIROS') ? require('../proactive/useProactive.js').useProactive : null;
|
|
|
|
const useProactive = feature('PROACTIVE') || feature('KAIROS') ? require('../proactive/useProactive.js').useProactive : null;
|
|
|
|
@@ -297,7 +297,7 @@ const EMPTY_MCP_CLIENTS: MCPServerConnection[] = [];
|
|
|
|
// Stable stub for useAssistantHistory's non-KAIROS branch — avoids a new
|
|
|
|
// Stable stub for useAssistantHistory's non-KAIROS branch — avoids a new
|
|
|
|
// function identity each render, which would break composedOnScroll's memo.
|
|
|
|
// function identity each render, which would break composedOnScroll's memo.
|
|
|
|
const HISTORY_STUB = {
|
|
|
|
const HISTORY_STUB = {
|
|
|
|
maybeLoadOlder: (_: ScrollBoxHandle) => {}
|
|
|
|
maybeLoadOlder: (_: ScrollBoxHandle) => { }
|
|
|
|
};
|
|
|
|
};
|
|
|
|
// Window after a user-initiated scroll during which type-into-empty does NOT
|
|
|
|
// Window after a user-initiated scroll during which type-into-empty does NOT
|
|
|
|
// repin to bottom. Josh Rosen's workflow: Claude emits long output → scroll
|
|
|
|
// repin to bottom. Josh Rosen's workflow: Claude emits long output → scroll
|
|
|
|
@@ -865,11 +865,11 @@ export function REPL({
|
|
|
|
|
|
|
|
|
|
|
|
// Ref for the bridge result callback — set after useReplBridge initializes,
|
|
|
|
// Ref for the bridge result callback — set after useReplBridge initializes,
|
|
|
|
// read in the onQuery finally block to notify mobile clients that a turn ended.
|
|
|
|
// read in the onQuery finally block to notify mobile clients that a turn ended.
|
|
|
|
const sendBridgeResultRef = useRef<() => void>(() => {});
|
|
|
|
const sendBridgeResultRef = useRef<() => void>(() => { });
|
|
|
|
|
|
|
|
|
|
|
|
// Ref for the synchronous restore callback — set after restoreMessageSync is
|
|
|
|
// Ref for the synchronous restore callback — set after restoreMessageSync is
|
|
|
|
// defined, read in the onQuery finally block for auto-restore on interrupt.
|
|
|
|
// defined, read in the onQuery finally block for auto-restore on interrupt.
|
|
|
|
const restoreMessageSyncRef = useRef<(m: UserMessage) => void>(() => {});
|
|
|
|
const restoreMessageSyncRef = useRef<(m: UserMessage) => void>(() => { });
|
|
|
|
|
|
|
|
|
|
|
|
// Ref to the fullscreen layout's scroll box for keyboard scrolling.
|
|
|
|
// Ref to the fullscreen layout's scroll box for keyboard scrolling.
|
|
|
|
// Null when fullscreen mode is disabled (ref never attached).
|
|
|
|
// Null when fullscreen mode is disabled (ref never attached).
|
|
|
|
@@ -1127,7 +1127,7 @@ export function REPL({
|
|
|
|
// session from mid-conversation context.
|
|
|
|
// session from mid-conversation context.
|
|
|
|
const haikuTitleAttemptedRef = useRef((initialMessages?.length ?? 0) > 0);
|
|
|
|
const haikuTitleAttemptedRef = useRef((initialMessages?.length ?? 0) > 0);
|
|
|
|
const agentTitle = mainThreadAgentDefinition?.agentType;
|
|
|
|
const agentTitle = mainThreadAgentDefinition?.agentType;
|
|
|
|
const terminalTitle = sessionTitle ?? agentTitle ?? haikuTitle ?? 'Claude Code';
|
|
|
|
const terminalTitle = sessionTitle ?? agentTitle ?? haikuTitle ?? 'Open Claude';
|
|
|
|
const isWaitingForApproval = toolUseConfirmQueue.length > 0 || promptQueue.length > 0 || pendingWorkerRequest || pendingSandboxRequest;
|
|
|
|
const isWaitingForApproval = toolUseConfirmQueue.length > 0 || promptQueue.length > 0 || pendingWorkerRequest || pendingSandboxRequest;
|
|
|
|
// Local-jsx commands (like /plugin, /config) show user-facing dialogs that
|
|
|
|
// Local-jsx commands (like /plugin, /config) show user-facing dialogs that
|
|
|
|
// wait for input. Require jsx != null — if the flag is stuck true but jsx
|
|
|
|
// wait for input. Require jsx != null — if the flag is stuck true but jsx
|
|
|
|
@@ -2676,7 +2676,7 @@ export function REPL({
|
|
|
|
// useDeferredHookMessages) and attachment messages (appended by
|
|
|
|
// useDeferredHookMessages) and attachment messages (appended by
|
|
|
|
// processTextPrompt) — both pushed length past 1 on turn one, so the
|
|
|
|
// processTextPrompt) — both pushed length past 1 on turn one, so the
|
|
|
|
// title silently fell through to the "Claude Code" default.
|
|
|
|
// title silently fell through to the "Claude Code" default.
|
|
|
|
if (getAPIProvider() === 'firstParty' && !titleDisabled && !sessionTitle && !agentTitle && !haikuTitleAttemptedRef.current) {
|
|
|
|
if (!titleDisabled && !sessionTitle && !agentTitle && !haikuTitleAttemptedRef.current) {
|
|
|
|
const firstUserMessage = newMessages.find(m => m.type === 'user' && !m.isMeta);
|
|
|
|
const firstUserMessage = newMessages.find(m => m.type === 'user' && !m.isMeta);
|
|
|
|
const text = firstUserMessage?.type === 'user' ? getContentText(firstUserMessage.message.content) : null;
|
|
|
|
const text = firstUserMessage?.type === 'user' ? getContentText(firstUserMessage.message.content) : null;
|
|
|
|
// Skip synthetic breadcrumbs — slash-command output, prompt-skill
|
|
|
|
// Skip synthetic breadcrumbs — slash-command output, prompt-skill
|
|
|
|
@@ -2686,7 +2686,7 @@ export function REPL({
|
|
|
|
if (text && !text.startsWith(`<${LOCAL_COMMAND_STDOUT_TAG}>`) && !text.startsWith(`<${COMMAND_MESSAGE_TAG}>`) && !text.startsWith(`<${COMMAND_NAME_TAG}>`) && !text.startsWith(`<${BASH_INPUT_TAG}>`)) {
|
|
|
|
if (text && !text.startsWith(`<${LOCAL_COMMAND_STDOUT_TAG}>`) && !text.startsWith(`<${COMMAND_MESSAGE_TAG}>`) && !text.startsWith(`<${COMMAND_NAME_TAG}>`) && !text.startsWith(`<${BASH_INPUT_TAG}>`)) {
|
|
|
|
haikuTitleAttemptedRef.current = true;
|
|
|
|
haikuTitleAttemptedRef.current = true;
|
|
|
|
void generateSessionTitle(text, new AbortController().signal).then(title => {
|
|
|
|
void generateSessionTitle(text, new AbortController().signal).then(title => {
|
|
|
|
if (title) setHaikuTitle(title);else haikuTitleAttemptedRef.current = false;
|
|
|
|
if (title) setHaikuTitle(title); else haikuTitleAttemptedRef.current = false;
|
|
|
|
}, () => {
|
|
|
|
}, () => {
|
|
|
|
haikuTitleAttemptedRef.current = false;
|
|
|
|
haikuTitleAttemptedRef.current = false;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
@@ -2760,7 +2760,7 @@ export function REPL({
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
queryCheckpoint('query_context_loading_start');
|
|
|
|
queryCheckpoint('query_context_loading_start');
|
|
|
|
const [,, defaultSystemPrompt, baseUserContext, systemContext] = await Promise.all([
|
|
|
|
const [, , defaultSystemPrompt, baseUserContext, systemContext] = await Promise.all([
|
|
|
|
// IMPORTANT: do this after setMessages() above, to avoid UI jank
|
|
|
|
// IMPORTANT: do this after setMessages() above, to avoid UI jank
|
|
|
|
checkAndDisableBypassPermissionsIfNeeded(toolPermissionContext, setAppState),
|
|
|
|
checkAndDisableBypassPermissionsIfNeeded(toolPermissionContext, setAppState),
|
|
|
|
// Gated on TRANSCRIPT_CLASSIFIER so GrowthBook kill switch runs wherever auto mode is built in
|
|
|
|
// Gated on TRANSCRIPT_CLASSIFIER so GrowthBook kill switch runs wherever auto mode is built in
|
|
|
|
@@ -3110,9 +3110,9 @@ export function REPL({
|
|
|
|
if (typeof content === 'string' && !initialMsg.message.planContent) {
|
|
|
|
if (typeof content === 'string' && !initialMsg.message.planContent) {
|
|
|
|
// Route through onSubmit for proper processing including UserPromptSubmit hooks
|
|
|
|
// Route through onSubmit for proper processing including UserPromptSubmit hooks
|
|
|
|
void onSubmit(content, {
|
|
|
|
void onSubmit(content, {
|
|
|
|
setCursorOffset: () => {},
|
|
|
|
setCursorOffset: () => { },
|
|
|
|
clearBuffer: () => {},
|
|
|
|
clearBuffer: () => { },
|
|
|
|
resetHistory: () => {}
|
|
|
|
resetHistory: () => { }
|
|
|
|
});
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// Plan messages or complex content (images, etc.) - send directly to model
|
|
|
|
// Plan messages or complex content (images, etc.) - send directly to model
|
|
|
|
@@ -3577,9 +3577,9 @@ export function REPL({
|
|
|
|
const command = autoRunIssueReason ? getAutoRunCommand(autoRunIssueReason) : '/issue';
|
|
|
|
const command = autoRunIssueReason ? getAutoRunCommand(autoRunIssueReason) : '/issue';
|
|
|
|
setAutoRunIssueReason(null); // Clear the state
|
|
|
|
setAutoRunIssueReason(null); // Clear the state
|
|
|
|
onSubmit(command, {
|
|
|
|
onSubmit(command, {
|
|
|
|
setCursorOffset: () => {},
|
|
|
|
setCursorOffset: () => { },
|
|
|
|
clearBuffer: () => {},
|
|
|
|
clearBuffer: () => { },
|
|
|
|
resetHistory: () => {}
|
|
|
|
resetHistory: () => { }
|
|
|
|
}).catch(err => {
|
|
|
|
}).catch(err => {
|
|
|
|
logForDebugging(`Auto-run ${command} failed: ${errorMessage(err)}`);
|
|
|
|
logForDebugging(`Auto-run ${command} failed: ${errorMessage(err)}`);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
@@ -3592,9 +3592,9 @@ export function REPL({
|
|
|
|
const handleSurveyRequestFeedback = useCallback(() => {
|
|
|
|
const handleSurveyRequestFeedback = useCallback(() => {
|
|
|
|
const command = "external" === 'ant' ? '/issue' : '/feedback';
|
|
|
|
const command = "external" === 'ant' ? '/issue' : '/feedback';
|
|
|
|
onSubmit(command, {
|
|
|
|
onSubmit(command, {
|
|
|
|
setCursorOffset: () => {},
|
|
|
|
setCursorOffset: () => { },
|
|
|
|
clearBuffer: () => {},
|
|
|
|
clearBuffer: () => { },
|
|
|
|
resetHistory: () => {}
|
|
|
|
resetHistory: () => { }
|
|
|
|
}).catch(err => {
|
|
|
|
}).catch(err => {
|
|
|
|
logForDebugging(`Survey feedback request failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
|
logForDebugging(`Survey feedback request failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
@@ -3609,9 +3609,9 @@ export function REPL({
|
|
|
|
onSubmitRef.current = onSubmit;
|
|
|
|
onSubmitRef.current = onSubmit;
|
|
|
|
const handleOpenRateLimitOptions = useCallback(() => {
|
|
|
|
const handleOpenRateLimitOptions = useCallback(() => {
|
|
|
|
void onSubmitRef.current('/rate-limit-options', {
|
|
|
|
void onSubmitRef.current('/rate-limit-options', {
|
|
|
|
setCursorOffset: () => {},
|
|
|
|
setCursorOffset: () => { },
|
|
|
|
clearBuffer: () => {},
|
|
|
|
clearBuffer: () => { },
|
|
|
|
resetHistory: () => {}
|
|
|
|
resetHistory: () => { }
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}, []);
|
|
|
|
}, []);
|
|
|
|
const handleExit = useCallback(async () => {
|
|
|
|
const handleExit = useCallback(async () => {
|
|
|
|
@@ -3628,14 +3628,14 @@ export function REPL({
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const showWorktree = getCurrentWorktreeSession() !== null;
|
|
|
|
const showWorktree = getCurrentWorktreeSession() !== null;
|
|
|
|
if (showWorktree) {
|
|
|
|
if (showWorktree) {
|
|
|
|
setExitFlow(<ExitFlow showWorktree onDone={() => {}} onCancel={() => {
|
|
|
|
setExitFlow(<ExitFlow showWorktree onDone={() => { }} onCancel={() => {
|
|
|
|
setExitFlow(null);
|
|
|
|
setExitFlow(null);
|
|
|
|
setIsExiting(false);
|
|
|
|
setIsExiting(false);
|
|
|
|
}} />);
|
|
|
|
}} />);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const exitMod = await exit.load();
|
|
|
|
const exitMod = await exit.load();
|
|
|
|
const exitFlowResult = await exitMod.call(() => {});
|
|
|
|
const exitFlowResult = await exitMod.call(() => { });
|
|
|
|
setExitFlow(exitFlowResult);
|
|
|
|
setExitFlow(exitFlowResult);
|
|
|
|
// If call() returned without killing the process (bg session detach),
|
|
|
|
// If call() returned without killing the process (bg session detach),
|
|
|
|
// clear isExiting so the UI is usable on reattach. No-op on the normal
|
|
|
|
// clear isExiting so the UI is usable on reattach. No-op on the normal
|
|
|
|
@@ -3856,14 +3856,14 @@ export function REPL({
|
|
|
|
const executeQueuedInput = useCallback(async (queuedCommands: QueuedCommand[]) => {
|
|
|
|
const executeQueuedInput = useCallback(async (queuedCommands: QueuedCommand[]) => {
|
|
|
|
await handlePromptSubmit({
|
|
|
|
await handlePromptSubmit({
|
|
|
|
helpers: {
|
|
|
|
helpers: {
|
|
|
|
setCursorOffset: () => {},
|
|
|
|
setCursorOffset: () => { },
|
|
|
|
clearBuffer: () => {},
|
|
|
|
clearBuffer: () => { },
|
|
|
|
resetHistory: () => {}
|
|
|
|
resetHistory: () => { }
|
|
|
|
},
|
|
|
|
},
|
|
|
|
queryGuard,
|
|
|
|
queryGuard,
|
|
|
|
commands,
|
|
|
|
commands,
|
|
|
|
onInputChange: () => {},
|
|
|
|
onInputChange: () => { },
|
|
|
|
setPastedContents: () => {},
|
|
|
|
setPastedContents: () => { },
|
|
|
|
setToolJSX,
|
|
|
|
setToolJSX,
|
|
|
|
getToolUseContext,
|
|
|
|
getToolUseContext,
|
|
|
|
messages,
|
|
|
|
messages,
|
|
|
|
@@ -4022,8 +4022,8 @@ export function REPL({
|
|
|
|
insertTextRef
|
|
|
|
insertTextRef
|
|
|
|
}) : {
|
|
|
|
}) : {
|
|
|
|
stripTrailing: () => 0,
|
|
|
|
stripTrailing: () => 0,
|
|
|
|
handleKeyEvent: () => {},
|
|
|
|
handleKeyEvent: () => { },
|
|
|
|
resetAnchor: () => {},
|
|
|
|
resetAnchor: () => { },
|
|
|
|
interimRange: null
|
|
|
|
interimRange: null
|
|
|
|
};
|
|
|
|
};
|
|
|
|
useInboxPoller({
|
|
|
|
useInboxPoller({
|
|
|
|
@@ -4793,9 +4793,9 @@ export function REPL({
|
|
|
|
}
|
|
|
|
}
|
|
|
|
skipIdleCheckRef.current = true;
|
|
|
|
skipIdleCheckRef.current = true;
|
|
|
|
void onSubmitRef.current(pending.input, {
|
|
|
|
void onSubmitRef.current(pending.input, {
|
|
|
|
setCursorOffset: () => {},
|
|
|
|
setCursorOffset: () => { },
|
|
|
|
clearBuffer: () => {},
|
|
|
|
clearBuffer: () => { },
|
|
|
|
resetHistory: () => {}
|
|
|
|
resetHistory: () => { }
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}} />}
|
|
|
|
}} />}
|
|
|
|
{focusedInputDialog === 'ide-onboarding' && <IdeOnboardingDialog onDone={() => setShowIdeOnboarding(false)} installationStatus={ideInstallationStatus} />}
|
|
|
|
{focusedInputDialog === 'ide-onboarding' && <IdeOnboardingDialog onDone={() => setShowIdeOnboarding(false)} installationStatus={ideInstallationStatus} />}
|
|
|
|
@@ -4890,11 +4890,11 @@ export function REPL({
|
|
|
|
{autoRunIssueReason && <AutoRunIssueNotification onRun={handleAutoRunIssue} onCancel={handleCancelAutoRunIssue} reason={getAutoRunIssueReasonText(autoRunIssueReason)} />}
|
|
|
|
{autoRunIssueReason && <AutoRunIssueNotification onRun={handleAutoRunIssue} onCancel={handleCancelAutoRunIssue} reason={getAutoRunIssueReasonText(autoRunIssueReason)} />}
|
|
|
|
{postCompactSurvey.state !== 'closed' ? <FeedbackSurvey state={postCompactSurvey.state} lastResponse={postCompactSurvey.lastResponse} handleSelect={postCompactSurvey.handleSelect} inputValue={inputValue} setInputValue={setInputValue} onRequestFeedback={handleSurveyRequestFeedback} /> : memorySurvey.state !== 'closed' ? <FeedbackSurvey state={memorySurvey.state} lastResponse={memorySurvey.lastResponse} handleSelect={memorySurvey.handleSelect} handleTranscriptSelect={memorySurvey.handleTranscriptSelect} inputValue={inputValue} setInputValue={setInputValue} onRequestFeedback={handleSurveyRequestFeedback} message="How well did Claude use its memory? (optional)" /> : <FeedbackSurvey state={feedbackSurvey.state} lastResponse={feedbackSurvey.lastResponse} handleSelect={feedbackSurvey.handleSelect} handleTranscriptSelect={feedbackSurvey.handleTranscriptSelect} inputValue={inputValue} setInputValue={setInputValue} onRequestFeedback={didAutoRunIssueRef.current ? undefined : handleSurveyRequestFeedback} />}
|
|
|
|
{postCompactSurvey.state !== 'closed' ? <FeedbackSurvey state={postCompactSurvey.state} lastResponse={postCompactSurvey.lastResponse} handleSelect={postCompactSurvey.handleSelect} inputValue={inputValue} setInputValue={setInputValue} onRequestFeedback={handleSurveyRequestFeedback} /> : memorySurvey.state !== 'closed' ? <FeedbackSurvey state={memorySurvey.state} lastResponse={memorySurvey.lastResponse} handleSelect={memorySurvey.handleSelect} handleTranscriptSelect={memorySurvey.handleTranscriptSelect} inputValue={inputValue} setInputValue={setInputValue} onRequestFeedback={handleSurveyRequestFeedback} message="How well did Claude use its memory? (optional)" /> : <FeedbackSurvey state={feedbackSurvey.state} lastResponse={feedbackSurvey.lastResponse} handleSelect={feedbackSurvey.handleSelect} handleTranscriptSelect={feedbackSurvey.handleTranscriptSelect} inputValue={inputValue} setInputValue={setInputValue} onRequestFeedback={didAutoRunIssueRef.current ? undefined : handleSurveyRequestFeedback} />}
|
|
|
|
{/* Frustration-triggered transcript sharing prompt */}
|
|
|
|
{/* Frustration-triggered transcript sharing prompt */}
|
|
|
|
{frustrationDetection.state !== 'closed' && <FeedbackSurvey state={frustrationDetection.state} lastResponse={null} handleSelect={() => {}} handleTranscriptSelect={frustrationDetection.handleTranscriptSelect} inputValue={inputValue} setInputValue={setInputValue} />}
|
|
|
|
{frustrationDetection.state !== 'closed' && <FeedbackSurvey state={frustrationDetection.state} lastResponse={null} handleSelect={() => { }} handleTranscriptSelect={frustrationDetection.handleTranscriptSelect} inputValue={inputValue} setInputValue={setInputValue} />}
|
|
|
|
{/* Skill improvement survey - appears when improvements detected (ant-only) */}
|
|
|
|
{/* Skill improvement survey - appears when improvements detected (ant-only) */}
|
|
|
|
{"external" === 'ant' && skillImprovementSurvey.suggestion && <SkillImprovementSurvey isOpen={skillImprovementSurvey.isOpen} skillName={skillImprovementSurvey.suggestion.skillName} updates={skillImprovementSurvey.suggestion.updates} handleSelect={skillImprovementSurvey.handleSelect} inputValue={inputValue} setInputValue={setInputValue} />}
|
|
|
|
{"external" === 'ant' && skillImprovementSurvey.suggestion && <SkillImprovementSurvey isOpen={skillImprovementSurvey.isOpen} skillName={skillImprovementSurvey.suggestion.skillName} updates={skillImprovementSurvey.suggestion.updates} handleSelect={skillImprovementSurvey.handleSelect} inputValue={inputValue} setInputValue={setInputValue} />}
|
|
|
|
{showIssueFlagBanner && <IssueFlagBanner />}
|
|
|
|
{showIssueFlagBanner && <IssueFlagBanner />}
|
|
|
|
{}
|
|
|
|
{ }
|
|
|
|
<PromptInput debug={debug} ideSelection={ideSelection} hasSuppressedDialogs={!!hasSuppressedDialogs} isLocalJSXCommandActive={isShowingLocalJSXCommand} getToolUseContext={getToolUseContext} toolPermissionContext={toolPermissionContext} setToolPermissionContext={setToolPermissionContext} apiKeyStatus={apiKeyStatus} commands={commands} agents={agentDefinitions.activeAgents} isLoading={isLoading} onExit={handleExit} verbose={verbose} messages={messages} onAutoUpdaterResult={setAutoUpdaterResult} autoUpdaterResult={autoUpdaterResult} input={inputValue} onInputChange={setInputValue} mode={inputMode} onModeChange={setInputMode} stashedPrompt={stashedPrompt} setStashedPrompt={setStashedPrompt} submitCount={submitCount} onShowMessageSelector={handleShowMessageSelector} onMessageActionsEnter={
|
|
|
|
<PromptInput debug={debug} ideSelection={ideSelection} hasSuppressedDialogs={!!hasSuppressedDialogs} isLocalJSXCommandActive={isShowingLocalJSXCommand} getToolUseContext={getToolUseContext} toolPermissionContext={toolPermissionContext} setToolPermissionContext={setToolPermissionContext} apiKeyStatus={apiKeyStatus} commands={commands} agents={agentDefinitions.activeAgents} isLoading={isLoading} onExit={handleExit} verbose={verbose} messages={messages} onAutoUpdaterResult={setAutoUpdaterResult} autoUpdaterResult={autoUpdaterResult} input={inputValue} onInputChange={setInputValue} mode={inputMode} onModeChange={setInputMode} stashedPrompt={stashedPrompt} setStashedPrompt={setStashedPrompt} submitCount={submitCount} onShowMessageSelector={handleShowMessageSelector} onMessageActionsEnter={
|
|
|
|
// Works during isLoading — edit cancels first; uuid selection survives appends.
|
|
|
|
// Works during isLoading — edit cancels first; uuid selection survives appends.
|
|
|
|
feature('MESSAGE_ACTIONS') && isFullscreenEnvEnabled() && !disableMessageActions ? enterMessageActions : undefined} mcpClients={mcpClients} pastedContents={pastedContents} setPastedContents={setPastedContents} vimMode={vimMode} setVimMode={setVimMode} showBashesDialog={showBashesDialog} setShowBashesDialog={setShowBashesDialog} onSubmit={onSubmit} onAgentSubmit={onAgentSubmit} isSearchingHistory={isSearchingHistory} setIsSearchingHistory={setIsSearchingHistory} helpOpen={isHelpOpen} setHelpOpen={setIsHelpOpen} insertTextRef={feature('VOICE_MODE') ? insertTextRef : undefined} voiceInterimRange={voice.interimRange} />
|
|
|
|
feature('MESSAGE_ACTIONS') && isFullscreenEnvEnabled() && !disableMessageActions ? enterMessageActions : undefined} mcpClients={mcpClients} pastedContents={pastedContents} setPastedContents={setPastedContents} vimMode={vimMode} setVimMode={setVimMode} showBashesDialog={showBashesDialog} setShowBashesDialog={setShowBashesDialog} onSubmit={onSubmit} onAgentSubmit={onAgentSubmit} isSearchingHistory={isSearchingHistory} setIsSearchingHistory={setIsSearchingHistory} helpOpen={isHelpOpen} setHelpOpen={setIsHelpOpen} insertTextRef={feature('VOICE_MODE') ? insertTextRef : undefined} voiceInterimRange={voice.interimRange} />
|
|
|
|
|