@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.
- package/README.md +32 -8
- package/dist/src/commands/init.js +91 -219
- package/dist/src/commands/voice/index.js +6 -7
- package/dist/src/commands/voice/voice.js +87 -43
- package/dist/src/commands.js +1 -3
- package/dist/src/components/LogoV2/VoiceModeNotice.js +1 -1
- package/dist/src/components/PromptInput/VoiceIndicator.js +4 -4
- package/dist/src/components/Spinner.js +18 -18
- package/dist/src/constants/spinnerVerbs.js +9 -9
- package/dist/src/hooks/usePasteHandler.js +8 -8
- package/dist/src/hooks/useVoice.js +93 -805
- package/dist/src/hooks/useVoiceEnabled.js +3 -15
- package/dist/src/hooks/useVoiceIntegration.js +6 -25
- package/dist/src/keybindings/defaultBindings.js +9 -6
- package/dist/src/screens/REPL.js +10 -22
- package/dist/src/services/localDictation.js +520 -0
- package/dist/src/services/voice.js +9 -7
- package/dist/src/state/AppState.js +1 -3
- package/dist/src/tools/ConfigTool/ConfigTool.js +12 -15
- package/dist/src/tools/ConfigTool/supportedSettings.js +2 -2
- package/dist/src/utils/imagePaste.js +11 -5
- package/dist/src/utils/model/model.js +2 -0
- package/dist/src/utils/settings/types.js +2 -2
- package/dist/src/voice/voiceModeEnabled.js +5 -25
- package/dist/vendor/audio-capture/arm64-darwin/audio-capture.node +0 -0
- package/dist/vendor/audio-capture/arm64-linux/audio-capture.node +0 -0
- package/dist/vendor/audio-capture/arm64-win32/audio-capture.node +0 -0
- package/dist/vendor/audio-capture/x64-darwin/audio-capture.node +0 -0
- package/dist/vendor/audio-capture/x64-linux/audio-capture.node +0 -0
- package/dist/vendor/audio-capture/x64-win32/audio-capture.node +0 -0
- package/dist/vendor/audio-capture-src/index.js +114 -0
- package/dist/vendor/audio-capture-src/index.ts +155 -0
- package/docs/comandos.md +132 -121
- package/package.json +1 -1
|
@@ -1,21 +1,9 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
1
|
import { useAppState } from '../state/AppState.js';
|
|
3
|
-
import {
|
|
2
|
+
import { isVoiceGrowthBookEnabled } from '../voice/voiceModeEnabled.js';
|
|
4
3
|
/**
|
|
5
|
-
* Combines user intent (settings.voiceEnabled) with
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
176
|
-
const voiceState =
|
|
177
|
-
|
|
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 =
|
|
339
|
-
const voiceState =
|
|
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
|
|
10
|
-
// - Windows: alt+v
|
|
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
|
|
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
|
|
80
|
-
|
|
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
|
-
|
|
92
|
+
space: 'voice:pushToTalk',
|
|
90
93
|
},
|
|
91
94
|
},
|
|
92
95
|
{
|
package/dist/src/screens/REPL.js
CHANGED
|
@@ -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 =
|
|
98
|
-
|
|
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
|
-
|
|
3613
|
-
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
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 }),
|
|
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 }),
|
|
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:
|
|
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 => ({
|