feat(ui): improve discoverability of MCP slash commands (#6080)

Co-authored-by: Rinil Kunhiraman <rinilkunhiraman@users.noreply.github.com>
Co-authored-by: Allen Hutchison <adh@google.com>
This commit is contained in:
Rinil Kunhiraman
2025-09-05 20:15:40 -07:00
committed by GitHub
parent a027010097
commit d2b5b4f129
4 changed files with 231 additions and 509 deletions
@@ -7,12 +7,13 @@
import { Box, Text } from 'ink';
import { Colors } from '../colors.js';
import { PrepareLabel } from './PrepareLabel.js';
import { isSlashCommand } from '../utils/commandUtils.js';
import { CommandKind } from '../commands/types.js';
export interface Suggestion {
label: string;
value: string;
description?: string;
matchedIndex?: number;
commandKind?: CommandKind;
}
interface SuggestionsDisplayProps {
suggestions: Suggestion[];
@@ -53,21 +54,6 @@ export function SuggestionsDisplay({
);
const visibleSuggestions = suggestions.slice(startIndex, endIndex);
const isSlashCommandMode = isSlashCommand(userInput);
let commandNameWidth = 0;
if (isSlashCommandMode) {
const maxLabelLength = visibleSuggestions.length
? Math.max(...visibleSuggestions.map((s) => s.label.length))
: 0;
const maxAllowedWidth = Math.floor(width * 0.35);
commandNameWidth = Math.max(
15,
Math.min(maxLabelLength + 2, maxAllowedWidth),
);
}
return (
<Box flexDirection="column" paddingX={1} width={width}>
{scrollOffset > 0 && <Text color={Colors.Foreground}></Text>}
@@ -88,31 +74,33 @@ export function SuggestionsDisplay({
return (
<Box key={`${suggestion.value}-${originalIndex}`} width={width}>
<Box flexDirection="row">
{isSlashCommandMode ? (
<>
<Box width={commandNameWidth} flexShrink={0}>
{labelElement}
</Box>
{suggestion.description ? (
<Box flexGrow={1} marginLeft={1}>
<Text color={textColor} wrap="wrap">
{suggestion.description}
</Text>
</Box>
) : null}
</>
) : (
<>
{labelElement}
{suggestion.description ? (
<Box flexGrow={1} marginLeft={1}>
<Text color={textColor} wrap="wrap">
{suggestion.description}
</Text>
</Box>
) : null}
</>
)}
{(() => {
const isSlashCommand = userInput.startsWith('/');
return (
<>
{isSlashCommand ? (
<Box flexShrink={0} paddingRight={2}>
{labelElement}
{suggestion.commandKind === CommandKind.MCP_PROMPT && (
<Text color={Colors.Gray}> [MCP]</Text>
)}
</Box>
) : (
labelElement
)}
{suggestion.description && (
<Box
flexGrow={1}
paddingLeft={isSlashCommand ? undefined : 1}
>
<Text color={textColor} wrap="truncate">
{suggestion.description}
</Text>
</Box>
)}
</>
);
})()}
</Box>
</Box>
);