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

Function executeUserInput

src/utils/handlePromptSubmit.ts:396–610  ·  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

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

Callers 1

handlePromptSubmitFunction · 0.85

Calls 13

createAbortControllerFunction · 0.85
queryCheckpointFunction · 0.85
runWithWorkloadFunction · 0.85
processUserInputFunction · 0.85
makeContextFunction · 0.85
fileHistoryEnabledFunction · 0.85
fileHistoryMakeSnapshotFunction · 0.85
enqueueFunction · 0.85
reserveMethod · 0.80
forEachMethod · 0.80
cancelReservationMethod · 0.80

Tested by

no test coverage detected