Repository navigation
fix(vscode-companion): fill slash commands into input on Enter instead of auto-submitting #3618
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
5eb5a17
ffce3d1
f92fd6a
407708b
75e4e87
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -176,7 +176,7 @@ | |
| } | ||
| // No wrapper div — message components render directly as children | ||
| // of the scroll container, preserving the original CSS layout. | ||
| if (child == null) return null; | ||
|
Check warning on line 179 in packages/vscode-ide-companion/src/webview/App.tsx
|
||
| mapping.push(index); | ||
| return <React.Fragment key={`msg-${index}`}>{child}</React.Fragment>; | ||
| }); | ||
|
|
@@ -212,7 +212,7 @@ | |
| while (directChild && directChild.parentElement !== container) { | ||
| directChild = directChild.parentElement; | ||
| } | ||
| if (!directChild) return -1; | ||
|
Check warning on line 215 in packages/vscode-ide-companion/src/webview/App.tsx
|
||
|
|
||
| // Find DOM child position among container's children | ||
| const children = container.children; | ||
|
|
@@ -796,52 +796,49 @@ | |
| } | ||
| }; | ||
|
|
||
| if (itemId === 'auth') { | ||
| clearTriggerText(); | ||
| vscode.postMessage({ type: 'auth', data: {} }); | ||
| closeCompletion(); | ||
| return; | ||
| } | ||
|
|
||
| if (itemId === 'account') { | ||
| clearTriggerText(); | ||
| vscode.postMessage({ type: 'getAccountInfo', data: {} }); | ||
| closeCompletion(); | ||
| return; | ||
| } | ||
| // Client-side commands that trigger extension actions directly | ||
| // instead of being sent to the agent as messages. | ||
| const clientActions: Record<string, () => void> = { | ||
| auth: () => vscode.postMessage({ type: 'auth', data: {} }), | ||
| account: () => | ||
| vscode.postMessage({ type: 'getAccountInfo', data: {} }), | ||
| model: () => setShowModelSelector(true), | ||
| }; | ||
|
|
||
| if (itemId === 'model') { | ||
| const clientAction = clientActions[itemId]; | ||
| if (clientAction) { | ||
| clearTriggerText(); | ||
| setShowModelSelector(true); | ||
| clientAction(); | ||
| closeCompletion(); | ||
| return; | ||
| } | ||
|
|
||
| // Handle server-provided slash commands by sending them as messages. | ||
| // Skip when fillOnly (Tab) — let the generic insertion path fill the | ||
| // command text so the user can keep typing arguments. | ||
| // Special case: /skills always uses fill behavior (Enter = Tab) to | ||
| // allow the secondary skill picker to appear. | ||
| // For server-provided slash commands, decide based on the `input` | ||
| // field: commands without input (input == null) auto-submit | ||
| // immediately; commands that accept input fall through to the generic | ||
| // insertion path so users can type arguments before submitting. | ||
| // Special case: /skills always uses fill behavior to allow the | ||
| // secondary skill picker to appear. | ||
| const serverCmd = availableCommands.find((c) => c.name === itemId); | ||
| const isSkillsCmd = shouldOpenSkillsSecondaryPicker( | ||
| item, | ||
| availableSkills, | ||
| ); | ||
| if ( | ||
| serverCmd && | ||
| !fillOnly && | ||
| !isSkillsCmd && | ||
| !isExpandableSlashCommand(serverCmd.name) | ||
| ) { | ||
| // Clear the trigger text since we're sending the command | ||
| clearTriggerText(); | ||
| // Send the slash command as a user message | ||
| vscode.postMessage({ | ||
| type: 'sendMessage', | ||
| data: { text: `/${serverCmd.name}` }, | ||
| }); | ||
| closeCompletion(); | ||
| return; | ||
| if (!serverCmd.input && !fillOnly) { | ||
| clearTriggerText(); | ||
| vscode.postMessage({ | ||
| type: 'sendMessage', | ||
| data: { text: `/${serverCmd.name}` }, | ||
| }); | ||
| closeCompletion(); | ||
| return; | ||
| } | ||
| // Command accepts input — fall through to fill the input box. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Critical] Falling through here uses the generic insertion path, which reads Please normalize the text used for completion insertion, for example by stripping — gpt-5.5 via Qwen Code /review |
||
| } | ||
|
|
||
| // Handle secondary skill selection — send `/skills <name>` with | ||
|
|
@@ -1203,7 +1200,7 @@ | |
| useEffect(() => { | ||
| const handler = (event: MessageEvent) => { | ||
| const message = event.data; | ||
| if (message?.type !== 'copyCommand') return; | ||
|
Check warning on line 1203 in packages/vscode-ide-companion/src/webview/App.tsx
|
||
|
|
||
| const { action } = message.data as { action: string }; | ||
|
|
||
|
|
@@ -1234,7 +1231,7 @@ | |
| msg.kind === 'image' && msg.imagePath | ||
| ? `` | ||
| : (msg.content || '').trim(); | ||
| if (!content) continue; | ||
|
Check warning on line 1234 in packages/vscode-ide-companion/src/webview/App.tsx
|
||
| if (msg.role === 'user') { | ||
| parts.push(`**User:** ${content}`); | ||
| } else if (msg.role === 'thinking') { | ||
|
|
@@ -1247,7 +1244,7 @@ | |
| item.type === 'in-progress-tool-call' | ||
| ) { | ||
| const tc = item.data as ToolCallData; | ||
| if (!shouldShowToolCall(tc.kind)) continue; | ||
|
Check warning on line 1247 in packages/vscode-ide-companion/src/webview/App.tsx
|
||
| const text = formatToolCallForCopy(tc, true); | ||
| if (text) { | ||
| parts.push(`**[Tool: ${tc.kind}]**\n\n${text}`); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Critical] This now marks every built-in command without a completion function as
input: null, so the webview auto-submits it on Enter. Some ACP-supported built-ins still accept meaningful arguments without exposingcompletion—for example/buguses its args as the issue title and/context detailenables the detailed view. After this change, selecting those commands from the completion menu sends only/<command>immediately, preventing users from filling the arguments that the command supports. Please derive this from explicit input metadata (or preserveargumentHint/subcommand-aware input support for these built-ins) instead of defaulting all built-ins without completion to no-input.— gpt-5.5 via Qwen Code /review