@iaforged/context-code 1.1.4 → 1.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/README.md +32 -8
  2. package/dist/src/commands/init.js +91 -219
  3. package/dist/src/commands/voice/index.js +6 -7
  4. package/dist/src/commands/voice/voice.js +87 -43
  5. package/dist/src/commands.js +1 -3
  6. package/dist/src/components/LogoV2/VoiceModeNotice.js +1 -1
  7. package/dist/src/components/PromptInput/VoiceIndicator.js +4 -4
  8. package/dist/src/components/Spinner.js +18 -18
  9. package/dist/src/constants/spinnerVerbs.js +9 -9
  10. package/dist/src/hooks/usePasteHandler.js +8 -8
  11. package/dist/src/hooks/useVoice.js +93 -805
  12. package/dist/src/hooks/useVoiceEnabled.js +3 -15
  13. package/dist/src/hooks/useVoiceIntegration.js +6 -25
  14. package/dist/src/keybindings/defaultBindings.js +9 -6
  15. package/dist/src/screens/REPL.js +10 -22
  16. package/dist/src/services/localDictation.js +520 -0
  17. package/dist/src/services/voice.js +9 -7
  18. package/dist/src/state/AppState.js +1 -3
  19. package/dist/src/tools/ConfigTool/ConfigTool.js +12 -15
  20. package/dist/src/tools/ConfigTool/supportedSettings.js +2 -2
  21. package/dist/src/utils/imagePaste.js +11 -5
  22. package/dist/src/utils/model/model.js +2 -0
  23. package/dist/src/utils/settings/types.js +2 -2
  24. package/dist/src/voice/voiceModeEnabled.js +5 -25
  25. package/dist/vendor/audio-capture/arm64-darwin/audio-capture.node +0 -0
  26. package/dist/vendor/audio-capture/arm64-linux/audio-capture.node +0 -0
  27. package/dist/vendor/audio-capture/arm64-win32/audio-capture.node +0 -0
  28. package/dist/vendor/audio-capture/x64-darwin/audio-capture.node +0 -0
  29. package/dist/vendor/audio-capture/x64-linux/audio-capture.node +0 -0
  30. package/dist/vendor/audio-capture/x64-win32/audio-capture.node +0 -0
  31. package/dist/vendor/audio-capture-src/index.js +114 -0
  32. package/dist/vendor/audio-capture-src/index.ts +155 -0
  33. package/docs/comandos.md +132 -121
  34. package/package.json +1 -1
@@ -1,21 +1,9 @@
1
- import { useMemo } from 'react';
2
1
  import { useAppState } from '../state/AppState.js';
3
- import { hasVoiceAuth, isVoiceGrowthBookEnabled, } from '../voice/voiceModeEnabled.js';
2
+ import { isVoiceGrowthBookEnabled } from '../voice/voiceModeEnabled.js';
4
3
  /**
5
- * Combines user intent (settings.voiceEnabled) with auth + GB kill-switch.
6
- * Only the auth half is memoized on authVersion — it's the expensive one
7
- * (cold getClaudeAIOAuthTokens memoize → sync `security` spawn, ~60ms/call,
8
- * ~180ms total in profile v5 when token refresh cleared the cache mid-session).
9
- * GB is a cheap cached-map lookup and stays outside the memo so a mid-session
10
- * kill-switch flip still takes effect on the next render.
11
- *
12
- * authVersion bumps on /login only. Background token refresh leaves it alone
13
- * (user is still authed), so the auth memo stays correct without re-eval.
4
+ * Combines user intent (settings.voiceEnabled) with the runtime feature gate.
14
5
  */
15
6
  export function useVoiceEnabled() {
16
7
  const userIntent = useAppState(s => s.settings.voiceEnabled === true);
17
- const authVersion = useAppState(s => s.authVersion);
18
- // eslint-disable-next-line react-hooks/exhaustive-deps
19
- const authed = useMemo(hasVoiceAuth, [authVersion]);
20
- return userIntent && authed && isVoiceGrowthBookEnabled();
8
+ return userIntent && isVoiceGrowthBookEnabled();
21
9
  }
@@ -17,12 +17,7 @@ import { useVoiceEnabled } from './useVoiceEnabled.js';
17
17
  // Capture the module namespace, not the function: spyOn() mutates the module
18
18
  // object, so `voiceNs.useVoice(...)` resolves to the spy even if this module
19
19
  // was loaded before the spy was installed (test ordering independence).
20
- const voiceNs = feature('VOICE_MODE') ? require('./useVoice.js') : {
21
- useVoice: ({ enabled: _e }) => ({
22
- state: 'idle',
23
- handleKeyEvent: (_fallbackMs) => { }
24
- })
25
- };
20
+ const voiceNs = require('./useVoice.js');
26
21
  /* eslint-enable @typescript-eslint/no-require-imports */
27
22
  // Maximum gap (ms) between key presses to count as held (auto-repeat).
28
23
  // Terminal auto-repeat fires every 30-80ms; 120ms covers jitter while
@@ -172,18 +167,12 @@ export function useVoiceIntegration({ setInputValueRaw, inputValueRef, insertTex
172
167
  // auth + GB kill-switch, with the auth half memoized on authVersion so
173
168
  // render loops never hit a cold keychain spawn.
174
169
  // biome-ignore lint/correctness/useHookAtTopLevel: feature() is a compile-time constant
175
- const voiceEnabled = feature('VOICE_MODE') ? useVoiceEnabled() : false;
176
- const voiceState = feature('VOICE_MODE') ?
177
- // biome-ignore lint/correctness/useHookAtTopLevel: feature() is a compile-time constant
178
- useVoiceState(s => s.voiceState) : 'idle';
179
- const voiceInterimTranscript = feature('VOICE_MODE') ?
180
- // biome-ignore lint/correctness/useHookAtTopLevel: feature() is a compile-time constant
181
- useVoiceState(s_0 => s_0.voiceInterimTranscript) : '';
170
+ const voiceEnabled = useVoiceEnabled();
171
+ const voiceState = useVoiceState(s => s.voiceState);
172
+ const voiceInterimTranscript = useVoiceState(s_0 => s_0.voiceInterimTranscript);
182
173
  // Set the voice anchor for focus mode (where recording starts via terminal
183
174
  // focus, not key hold). Key-hold sets the anchor in stripTrailing.
184
175
  useEffect(() => {
185
- if (!feature('VOICE_MODE'))
186
- return;
187
176
  if (voiceState === 'recording' && voicePrefixRef.current === null) {
188
177
  const input = inputValueRef.current;
189
178
  const offset_0 = insertTextRef.current?.cursorOffset ?? input.length;
@@ -201,8 +190,6 @@ export function useVoiceIntegration({ setInputValueRaw, inputValueRef, insertTex
201
190
  // transcribes speech. The prefix (user-typed text before the cursor) is
202
191
  // preserved and the transcript is inserted between prefix and suffix.
203
192
  useEffect(() => {
204
- if (!feature('VOICE_MODE'))
205
- return;
206
193
  if (voicePrefixRef.current === null)
207
194
  return;
208
195
  const prefix_0 = voicePrefixRef.current;
@@ -233,8 +220,6 @@ export function useVoiceIntegration({ setInputValueRaw, inputValueRef, insertTex
233
220
  lastSetInputRef.current = newValue_0;
234
221
  }, [voiceInterimTranscript, setInputValueRaw, inputValueRef, insertTextRef]);
235
222
  const handleVoiceTranscript = useCallback((text) => {
236
- if (!feature('VOICE_MODE'))
237
- return;
238
223
  const prefix_1 = voicePrefixRef.current;
239
224
  // No voice anchor — voice was reset (or never started). Nothing to do.
240
225
  if (prefix_1 === null)
@@ -283,8 +268,6 @@ export function useVoiceIntegration({ setInputValueRaw, inputValueRef, insertTex
283
268
  // Compute the character range of interim (not-yet-finalized) transcript
284
269
  // text in the input value, so the UI can dim it.
285
270
  const interimRange = useMemo(() => {
286
- if (!feature('VOICE_MODE'))
287
- return null;
288
271
  if (voicePrefixRef.current === null)
289
272
  return null;
290
273
  if (voiceInterimTranscript.length === 0)
@@ -335,10 +318,8 @@ export function useVoiceKeybindingHandler({ voiceHandleKeyEvent, stripTrailing,
335
318
  const keybindingContext = useOptionalKeybindingContext();
336
319
  const isModalOverlayActive = useIsModalOverlayActive();
337
320
  // biome-ignore lint/correctness/useHookAtTopLevel: feature() is a compile-time constant
338
- const voiceEnabled = feature('VOICE_MODE') ? useVoiceEnabled() : false;
339
- const voiceState = feature('VOICE_MODE') ?
340
- // biome-ignore lint/correctness/useHookAtTopLevel: feature() is a compile-time constant
341
- useVoiceState(s => s.voiceState) : 'idle';
321
+ const voiceEnabled = useVoiceEnabled();
322
+ const voiceState = useVoiceState(s => s.voiceState);
342
323
  // Find the configured key for voice:pushToTalk from keybinding context.
343
324
  // Forward iteration with last-wins (matching the resolver): if a later
344
325
  // Chat binding overrides the same chord with null or a different
@@ -6,10 +6,13 @@ import { getPlatform } from '../utils/platform.js';
6
6
  * Default keybindings that match current Context Code behavior.
7
7
  * These are loaded first, then user keybindings.json overrides them.
8
8
  */
9
- // Platform-specific image paste shortcut:
10
- // - Windows: alt+v (ctrl+v is system paste)
9
+ // Platform-specific image paste shortcuts:
10
+ // - Windows: accept both ctrl+v and alt+v. Some terminals forward ctrl+v as a
11
+ // regular keybinding, while others reserve it for paste handling.
11
12
  // - Other platforms: ctrl+v
12
- const IMAGE_PASTE_KEY = getPlatform() === 'windows' ? 'alt+v' : 'ctrl+v';
13
+ const IMAGE_PASTE_BINDINGS = getPlatform() === 'windows'
14
+ ? { 'ctrl+v': 'chat:imagePaste', 'alt+v': 'chat:imagePaste' }
15
+ : { 'ctrl+v': 'chat:imagePaste' };
13
16
  // Modifier-only chords (like shift+tab) may fail on Windows Terminal without VT mode
14
17
  // See: https://github.com/microsoft/terminal/issues/879#issuecomment-618801651
15
18
  // Node enabled VT mode in 24.2.0 / 22.17.0: https://github.com/nodejs/node/pull/58358
@@ -76,8 +79,8 @@ export const DEFAULT_BINDINGS = [
76
79
  'ctrl+x ctrl+e': 'chat:externalEditor',
77
80
  'ctrl+g': 'chat:externalEditor',
78
81
  'ctrl+s': 'chat:stash',
79
- // Image paste shortcut (platform-specific key defined above)
80
- [IMAGE_PASTE_KEY]: 'chat:imagePaste',
82
+ // Image paste shortcuts (platform-specific bindings defined above)
83
+ ...IMAGE_PASTE_BINDINGS,
81
84
  ...(feature('MESSAGE_ACTIONS')
82
85
  ? { 'shift+up': 'chat:messageActions' }
83
86
  : {}),
@@ -86,7 +89,7 @@ export const DEFAULT_BINDINGS = [
86
89
  // add a voice:pushToTalk entry (last wins); to disable, use /voice
87
90
  // — null-unbinding space hits a pre-existing useKeybinding.ts trap
88
91
  // where 'unbound' swallows the event (space dead for typing).
89
- ...(feature('VOICE_MODE') ? { space: 'voice:pushToTalk' } : {}),
92
+ space: 'voice:pushToTalk',
90
93
  },
91
94
  },
92
95
  {
@@ -94,12 +94,8 @@ import { isHumanTurn } from '../utils/messagePredicates.js';
94
94
  import { logError } from '../utils/log.js';
95
95
  // Dead code elimination: conditional imports
96
96
  /* eslint-disable custom-rules/no-process-env-top-level, @typescript-eslint/no-require-imports */
97
- const useVoiceIntegration = feature('VOICE_MODE') ? require('../hooks/useVoiceIntegration.js').useVoiceIntegration : () => ({
98
- stripTrailing: () => 0,
99
- handleKeyEvent: () => { },
100
- resetAnchor: () => { }
101
- });
102
- const VoiceKeybindingHandler = feature('VOICE_MODE') ? require('../hooks/useVoiceIntegration.js').VoiceKeybindingHandler : () => null;
97
+ const useVoiceIntegration = require('../hooks/useVoiceIntegration.js').useVoiceIntegration;
98
+ const VoiceKeybindingHandler = require('../hooks/useVoiceIntegration.js').VoiceKeybindingHandler;
103
99
  // Frustration detection is ant-only (dogfooding). Conditional require so external
104
100
  // builds eliminate the module entirely (including its two O(n) useMemos that run
105
101
  // on every messages change, plus the GrowthBook fetch).
@@ -3609,19 +3605,11 @@ export function REPL({ commands: initialCommands, debug, initialTools, initialMe
3609
3605
  void onQuery([userMessage], newAbortController, true, [], mainLoopModel);
3610
3606
  return true;
3611
3607
  }, [onQuery, mainLoopModel, store]);
3612
- // Voice input integration (VOICE_MODE builds only)
3613
- const voice = feature('VOICE_MODE') ?
3614
- // biome-ignore lint/correctness/useHookAtTopLevel: feature() is a compile-time constant
3615
- useVoiceIntegration({
3616
- setInputValueRaw,
3617
- inputValueRef,
3618
- insertTextRef
3619
- }) : {
3620
- stripTrailing: () => 0,
3621
- handleKeyEvent: () => { },
3622
- resetAnchor: () => { },
3623
- interimRange: null
3624
- };
3608
+ const voice = useVoiceIntegration({
3609
+ setInputValueRaw,
3610
+ inputValueRef,
3611
+ insertTextRef
3612
+ });
3625
3613
  useInboxPoller({
3626
3614
  enabled: isAgentSwarmsEnabled(),
3627
3615
  isLoading,
@@ -3977,7 +3965,7 @@ export function REPL({ commands: initialCommands, debug, initialTools, initialMe
3977
3965
  const transcriptScrollRef = isFullscreenEnvEnabled() && !disableVirtualScroll && !dumpMode ? scrollRef : undefined;
3978
3966
  const transcriptMessagesElement = _jsx(Messages, { messages: transcriptMessages, tools: tools, commands: commands, verbose: true, toolJSX: null, toolUseConfirmQueue: [], inProgressToolUseIDs: inProgressToolUseIDs, isMessageSelectorVisible: false, conversationId: conversationId, screen: screen, agentDefinitions: agentDefinitions, streamingToolUses: transcriptStreamingToolUses, showAllInTranscript: showAllInTranscript, onOpenRateLimitOptions: handleOpenRateLimitOptions, isLoading: isLoading, hidePastThinking: true, streamingThinking: streamingThinking, scrollRef: transcriptScrollRef, jumpRef: jumpRef, onSearchMatchesChange: onSearchMatchesChange, scanElement: scanElement, setPositions: setPositions, disableRenderCap: dumpMode });
3979
3967
  const transcriptToolJSX = toolJSX && _jsx(Box, { flexDirection: "column", width: "100%", children: toolJSX.jsx });
3980
- const transcriptReturn = _jsxs(KeybindingSetup, { children: [_jsx(AnimatedTerminalTitle, { isAnimating: titleIsAnimating, title: terminalTitle, disabled: titleDisabled, noPrefix: showStatusInTerminalTab }), _jsx(GlobalKeybindingHandlers, { ...globalKeybindingProps }), feature('VOICE_MODE') ? _jsx(VoiceKeybindingHandler, { voiceHandleKeyEvent: voice.handleKeyEvent, stripTrailing: voice.stripTrailing, resetAnchor: voice.resetAnchor, isActive: !toolJSX?.isLocalJSXCommand }) : null, _jsx(CommandKeybindingHandlers, { onSubmit: onSubmit, isActive: !toolJSX?.isLocalJSXCommand }), transcriptScrollRef ?
3968
+ const transcriptReturn = _jsxs(KeybindingSetup, { children: [_jsx(AnimatedTerminalTitle, { isAnimating: titleIsAnimating, title: terminalTitle, disabled: titleDisabled, noPrefix: showStatusInTerminalTab }), _jsx(GlobalKeybindingHandlers, { ...globalKeybindingProps }), _jsx(VoiceKeybindingHandler, { voiceHandleKeyEvent: voice.handleKeyEvent, stripTrailing: voice.stripTrailing, resetAnchor: voice.resetAnchor, isActive: !toolJSX?.isLocalJSXCommand }), _jsx(CommandKeybindingHandlers, { onSubmit: onSubmit, isActive: !toolJSX?.isLocalJSXCommand }), transcriptScrollRef ?
3981
3969
  _jsx(ScrollKeybindingHandler, { scrollRef: scrollRef,
3982
3970
  // Yield wheel/ctrl+u/d to UltraplanChoiceDialog's own scroll
3983
3971
  // handler while the modal is showing.
@@ -4091,7 +4079,7 @@ export function REPL({ commands: initialCommands, debug, initialTools, initialMe
4091
4079
  // flexGrow in FullscreenLayout resolves against this Box. The transcript
4092
4080
  // early return above wraps its virtual-scroll branch the same way; only
4093
4081
  // the 30-cap dump branch stays unwrapped for native terminal scrollback.
4094
- const mainReturn = _jsxs(KeybindingSetup, { children: [_jsx(AnimatedTerminalTitle, { isAnimating: titleIsAnimating, title: terminalTitle, disabled: titleDisabled, noPrefix: showStatusInTerminalTab }), _jsx(GlobalKeybindingHandlers, { ...globalKeybindingProps }), feature('VOICE_MODE') ? _jsx(VoiceKeybindingHandler, { voiceHandleKeyEvent: voice.handleKeyEvent, stripTrailing: voice.stripTrailing, resetAnchor: voice.resetAnchor, isActive: !toolJSX?.isLocalJSXCommand }) : null, _jsx(CommandKeybindingHandlers, { onSubmit: onSubmit, isActive: !toolJSX?.isLocalJSXCommand }), _jsx(ScrollKeybindingHandler, { scrollRef: scrollRef, isActive: isFullscreenEnvEnabled() && (centeredModal != null || !focusedInputDialog || focusedInputDialog === 'tool-permission'), onScroll: centeredModal || toolPermissionOverlay || viewedAgentTask ? undefined : composedOnScroll }), feature('MESSAGE_ACTIONS') && isFullscreenEnvEnabled() && !disableMessageActions ? _jsx(MessageActionsKeybindings, { handlers: messageActionHandlers, isActive: cursor !== null }) : null, _jsx(CancelRequestHandler, { ...cancelRequestProps }), _jsx(MCPConnectionManager, { dynamicMcpConfig: dynamicMcpConfig, isStrictMcpConfig: strictMcpConfig, children: _jsx(FullscreenLayout, { scrollRef: scrollRef, overlay: toolPermissionOverlay, bottomFloat: feature('BUDDY') && companionVisible && !companionNarrow ? _jsx(CompanionFloatingBubble, {}) : undefined, modal: centeredModal, modalScrollRef: modalScrollRef, dividerYRef: dividerYRef, hidePill: !!viewedAgentTask, hideSticky: !!viewedTeammateTask, newMessageCount: unseenDivider?.count ?? 0, onPillClick: () => {
4082
+ const mainReturn = _jsxs(KeybindingSetup, { children: [_jsx(AnimatedTerminalTitle, { isAnimating: titleIsAnimating, title: terminalTitle, disabled: titleDisabled, noPrefix: showStatusInTerminalTab }), _jsx(GlobalKeybindingHandlers, { ...globalKeybindingProps }), _jsx(VoiceKeybindingHandler, { voiceHandleKeyEvent: voice.handleKeyEvent, stripTrailing: voice.stripTrailing, resetAnchor: voice.resetAnchor, isActive: !toolJSX?.isLocalJSXCommand }), _jsx(CommandKeybindingHandlers, { onSubmit: onSubmit, isActive: !toolJSX?.isLocalJSXCommand }), _jsx(ScrollKeybindingHandler, { scrollRef: scrollRef, isActive: isFullscreenEnvEnabled() && (centeredModal != null || !focusedInputDialog || focusedInputDialog === 'tool-permission'), onScroll: centeredModal || toolPermissionOverlay || viewedAgentTask ? undefined : composedOnScroll }), feature('MESSAGE_ACTIONS') && isFullscreenEnvEnabled() && !disableMessageActions ? _jsx(MessageActionsKeybindings, { handlers: messageActionHandlers, isActive: cursor !== null }) : null, _jsx(CancelRequestHandler, { ...cancelRequestProps }), _jsx(MCPConnectionManager, { dynamicMcpConfig: dynamicMcpConfig, isStrictMcpConfig: strictMcpConfig, children: _jsx(FullscreenLayout, { scrollRef: scrollRef, overlay: toolPermissionOverlay, bottomFloat: feature('BUDDY') && companionVisible && !companionNarrow ? _jsx(CompanionFloatingBubble, {}) : undefined, modal: centeredModal, modalScrollRef: modalScrollRef, dividerYRef: dividerYRef, hidePill: !!viewedAgentTask, hideSticky: !!viewedTeammateTask, newMessageCount: unseenDivider?.count ?? 0, onPillClick: () => {
4095
4083
  setCursor(null);
4096
4084
  jumpToNew(scrollRef.current);
4097
4085
  }, scrollable: _jsxs(_Fragment, { children: [_jsx(TeammateViewHeader, {}), _jsx(Messages, { messages: displayedMessages, tools: tools, commands: commands, verbose: verbose, toolJSX: toolJSX, toolUseConfirmQueue: toolUseConfirmQueue, inProgressToolUseIDs: viewedTeammateTask ? viewedTeammateTask.inProgressToolUseIDs ?? new Set() : inProgressToolUseIDs, isMessageSelectorVisible: isMessageSelectorVisible, conversationId: conversationId, screen: screen, streamingToolUses: streamingToolUses, showAllInTranscript: showAllInTranscript, agentDefinitions: agentDefinitions, onOpenRateLimitOptions: handleOpenRateLimitOptions, isLoading: isLoading, streamingText: isLoading && !viewedAgentTask ? visibleStreamingText : null, isBriefOnly: viewedAgentTask ? false : isBriefOnly, unseenDivider: viewedAgentTask ? undefined : unseenDivider, scrollRef: isFullscreenEnvEnabled() ? scrollRef : undefined, trackStickyPrompt: isFullscreenEnvEnabled() ? true : undefined, cursor: cursor, setCursor: setCursor, cursorNavRef: cursorNavRef }), _jsx(AwsAuthStatusBox, {}), !disabled && placeholderText && !centeredModal && _jsx(UserTextMessage, { param: {
@@ -4344,7 +4332,7 @@ export function REPL({ commands: initialCommands, debug, initialTools, initialMe
4344
4332
  }).then(appendStdout).catch(logError);
4345
4333
  } }) : null, mrRender(), !toolJSX?.shouldHidePromptInput && !focusedInputDialog && !isExiting && !disabled && !cursor && _jsxs(_Fragment, { children: [autoRunIssueReason && _jsx(AutoRunIssueNotification, { onRun: handleAutoRunIssue, onCancel: handleCancelAutoRunIssue, reason: getAutoRunIssueReasonText(autoRunIssueReason) }), postCompactSurvey.state !== 'closed' ? _jsx(FeedbackSurvey, { state: postCompactSurvey.state, lastResponse: postCompactSurvey.lastResponse, handleSelect: postCompactSurvey.handleSelect, inputValue: inputValue, setInputValue: setInputValue, onRequestFeedback: handleSurveyRequestFeedback }) : memorySurvey.state !== 'closed' ? _jsx(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)" }) : _jsx(FeedbackSurvey, { state: feedbackSurvey.state, lastResponse: feedbackSurvey.lastResponse, handleSelect: feedbackSurvey.handleSelect, handleTranscriptSelect: feedbackSurvey.handleTranscriptSelect, inputValue: inputValue, setInputValue: setInputValue, onRequestFeedback: didAutoRunIssueRef.current ? undefined : handleSurveyRequestFeedback }), frustrationDetection.state !== 'closed' && _jsx(FeedbackSurvey, { state: frustrationDetection.state, lastResponse: null, handleSelect: () => { }, handleTranscriptSelect: frustrationDetection.handleTranscriptSelect, inputValue: inputValue, setInputValue: setInputValue }), "external" === 'ant' && skillImprovementSurvey.suggestion && _jsx(SkillImprovementSurvey, { isOpen: skillImprovementSurvey.isOpen, skillName: skillImprovementSurvey.suggestion.skillName, updates: skillImprovementSurvey.suggestion.updates, handleSelect: skillImprovementSurvey.handleSelect, inputValue: inputValue, setInputValue: setInputValue }), showIssueFlagBanner && _jsx(IssueFlagBanner, {}), _jsx(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:
4346
4334
  // Works during isLoading — edit cancels first; uuid selection survives appends.
4347
- 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 }), _jsx(SessionBackgroundHint, { onBackgroundSession: handleBackgroundSession, isLoading: isLoading })] }), cursor &&
4335
+ 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: insertTextRef, voiceInterimRange: voice.interimRange }), _jsx(SessionBackgroundHint, { onBackgroundSession: handleBackgroundSession, isLoading: isLoading })] }), cursor &&
4348
4336
  _jsx(MessageActionsBar, { cursor: cursor }), focusedInputDialog === 'message-selector' && _jsx(MessageSelector, { messages: messages, preselectedMessage: messageSelectorPreselect, onPreRestore: onCancel, onRestoreCode: async (message) => {
4349
4337
  await fileHistoryRewind((updater) => {
4350
4338
  setAppState(prev => ({