Something went wrong. Try again.
source dump of claude code forked from oppi.li/claude-code
Something went wrong. Try again.
3.2 kB · 95 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596import type { QueuedCommand } from '../types/textInputTypes.js'import { dequeue, dequeueAllMatching, hasCommandsInQueue, peek,} from './messageQueueManager.js'
type ProcessQueueParams = { executeInput: (commands: QueuedCommand[]) => Promise<void>}
type ProcessQueueResult = { processed: boolean}
/** * Check if a queued command is a slash command (value starts with '/'). */function isSlashCommand(cmd: QueuedCommand): boolean { if (typeof cmd.value === 'string') { return cmd.value.trim().startsWith('/') } // For ContentBlockParam[], check the first text block for (const block of cmd.value) { if (block.type === 'text') { return block.text.trim().startsWith('/') } } return false}
/** * Processes commands from the queue. * * Slash commands (starting with '/') and bash-mode commands are processed * one at a time so each goes through the executeInput path individually. * Bash commands need individual processing to preserve per-command error * isolation, exit codes, and progress UI. Other non-slash commands are * batched: all items **with the same mode** as the highest-priority item * are drained at once and passed as a single array to executeInput — each * becomes its own user message with its own UUID. Different modes * (e.g. prompt vs task-notification) are never mixed because they are * treated differently downstream. * * The caller is responsible for ensuring no query is currently running * and for calling this function again after each command completes * until the queue is empty. * * @returns result with processed status */export function processQueueIfReady({ executeInput,}: ProcessQueueParams): ProcessQueueResult { // This processor runs on the REPL main thread between turns. Skip anything // addressed to a subagent — an unfiltered peek() returning a subagent // notification would set targetMode, dequeueAllMatching would find nothing // matching that mode with agentId===undefined, and we'd return processed: // false with the queue unchanged → the React effect never re-fires and any // queued user prompt stalls permanently. const isMainThread = (cmd: QueuedCommand) => cmd.agentId === undefined
const next = peek(isMainThread) if (!next) { return { processed: false } }
// Slash commands and bash-mode commands are processed individually. // Bash commands need per-command error isolation, exit codes, and progress UI. if (isSlashCommand(next) || next.mode === 'bash') { const cmd = dequeue(isMainThread)! void executeInput([cmd]) return { processed: true } }
// Drain all non-slash-command items with the same mode at once. const targetMode = next.mode const commands = dequeueAllMatching( cmd => isMainThread(cmd) && !isSlashCommand(cmd) && cmd.mode === targetMode, ) if (commands.length === 0) { return { processed: false } }
void executeInput(commands) return { processed: true }}
/** * Checks if the queue has pending commands. * Use this to determine if queue processing should be triggered. */export function hasQueuedCommands(): boolean { return hasCommandsInQueue()}