MCPcopy
hub / github.com/claude-code-best/claude-code / executeUserInput

Function executeUserInput

src/utils/handlePromptSubmit.ts:408–688  ·  view source on GitHub ↗

* Core logic for executing user input without UI side effects. * * All commands arrive as `queuedCommands`. First command gets full treatment * (attachments, ideSelection, pastedContents with image resizing). Commands 2-N * get `skipAttachments` to avoid duplicating turn-level context.

(params: ExecuteUserInputParams)

Source from the content-addressed store, hash-verified

406 * get `skipAttachments` to avoid duplicating turn-level context.
407 */
408async function executeUserInput(params: ExecuteUserInputParams): Promise<void> {
409 const {
410 messages,
411 mainLoopModel,
412 ideSelection,
413 querySource,
414 queryGuard,
415 setToolJSX,
416 getToolUseContext,
417 setUserInputOnProcessing,
418 setAbortController,
419 onQuery,
420 setAppState,
421 onBeforeQuery,
422 resetHistory,
423 canUseTool,
424 queuedCommands,
425 } = params
426
427 // Note: paste references are already processed before calling this function
428 // (either in handlePromptSubmit before queuing, or before initial execution).
429 // Always create a fresh abort controller — queryGuard guarantees no concurrent
430 // executeUserInput call, so there's no prior controller to inherit.
431 const abortController = createAbortController()
432 setAbortController(abortController)
433
434 function makeContext(): ProcessUserInputContext {
435 return getToolUseContext(messages, [], abortController, mainLoopModel)
436 }
437
438 // Wrap in try-finally so the guard is released even if processUserInput
439 // throws or onQuery is skipped. onQuery's finally calls queryGuard.end(),
440 // which transitions running→idle; cancelReservation() below is a no-op in
441 // that case (only acts on dispatching state).
442 try {
443 // Reserve the guard BEFORE processUserInput — processBashCommand awaits
444 // BashTool.call() and processSlashCommand awaits getMessagesForSlashCommand,
445 // so the guard must be active during those awaits to ensure concurrent
446 // handlePromptSubmit calls queue (via the isActive check above) instead
447 // of starting a second executeUserInput. This call is a no-op if the
448 // guard is already in dispatching (legacy queue-processor path).
449 queryGuard.reserve()
450 queryCheckpoint('query_process_user_input_start')
451
452 const newMessages: Message[] = []
453 let shouldQuery = false
454 let allowedTools: string[] | undefined
455 let model: string | undefined
456 let effort: EffortValue | undefined
457 let nextInput: string | undefined
458 let submitNextInput: boolean | undefined
459
460 // Iterate all commands uniformly. First command gets attachments +
461 // ideSelection + pastedContents, rest skip attachments to avoid
462 // duplicating turn-level context (IDE selection, todos, diffs).
463 let commands = queuedCommands ?? []
464 const queuedAutonomyClaim =
465 await claimConsumableQueuedAutonomyCommands(commands)

Callers 1

handlePromptSubmitFunction · 0.85

Calls 15

createAbortControllerFunction · 0.85
queryCheckpointFunction · 0.85
runWithWorkloadFunction · 0.85
processUserInputFunction · 0.85
fileHistoryEnabledFunction · 0.85
fileHistoryMakeSnapshotFunction · 0.85
getCwdFunction · 0.85
toErrorFunction · 0.85
reserveMethod · 0.80

Tested by

no test coverage detected