diff --git a/src/components/chat/hooks/useChatComposerState.ts b/src/components/chat/hooks/useChatComposerState.ts index ae37bce..ca430a1 100644 --- a/src/components/chat/hooks/useChatComposerState.ts +++ b/src/components/chat/hooks/useChatComposerState.ts @@ -271,13 +271,14 @@ export function useChatComposerState({ }, [setChatMessages]); const executeCommand = useCallback( - async (command: SlashCommand) => { + async (command: SlashCommand, rawInput?: string) => { if (!command || !selectedProject) { return; } try { - const commandMatch = input.match(new RegExp(`${escapeRegExp(command.name)}\\s*(.*)`)); + const effectiveInput = rawInput ?? input; + const commandMatch = effectiveInput.match(new RegExp(`${escapeRegExp(command.name)}\\s*(.*)`)); const args = commandMatch && commandMatch[1] ? commandMatch[1].trim().split(/\s+/) : []; @@ -351,6 +352,7 @@ export function useChatComposerState({ ); const { + slashCommands, slashCommandsCount, filteredCommands, frequentCommands, @@ -473,6 +475,28 @@ export function useChatComposerState({ return; } + // Intercept slash commands: if input starts with /commandName, execute as command with args + const trimmedInput = currentInput.trim(); + if (trimmedInput.startsWith('/')) { + const firstSpace = trimmedInput.indexOf(' '); + const commandName = firstSpace > 0 ? trimmedInput.slice(0, firstSpace) : trimmedInput; + const matchedCommand = slashCommands.find((cmd: SlashCommand) => cmd.name === commandName); + if (matchedCommand) { + executeCommand(matchedCommand, trimmedInput); + setInput(''); + inputValueRef.current = ''; + setAttachedImages([]); + setUploadingImages(new Map()); + setImageErrors(new Map()); + resetCommandMenuState(); + setIsTextareaExpanded(false); + if (textareaRef.current) { + textareaRef.current.style.height = 'auto'; + } + return; + } + } + let messageContent = currentInput; const selectedThinkingMode = thinkingModes.find((mode: { id: string; prefix?: string }) => mode.id === thinkingMode); if (selectedThinkingMode && selectedThinkingMode.prefix) { @@ -639,6 +663,7 @@ export function useChatComposerState({ codexModel, currentSessionId, cursorModel, + executeCommand, isLoading, onSessionActive, pendingViewSessionRef, @@ -654,6 +679,7 @@ export function useChatComposerState({ setClaudeStatus, setIsLoading, setIsUserScrolledUp, + slashCommands, thinkingMode, ], ); diff --git a/src/components/chat/hooks/useSlashCommands.ts b/src/components/chat/hooks/useSlashCommands.ts index f14fc43..067cd24 100644 --- a/src/components/chat/hooks/useSlashCommands.ts +++ b/src/components/chat/hooks/useSlashCommands.ts @@ -22,7 +22,7 @@ interface UseSlashCommandsOptions { input: string; setInput: Dispatch>; textareaRef: RefObject; - onExecuteCommand: (command: SlashCommand) => void | Promise; + onExecuteCommand: (command: SlashCommand, rawInput?: string) => void | Promise; } const getCommandHistoryKey = (projectName: string) => `command_history_${projectName}`;