fix(desktop): surface an exactly-typed command alias in slash completions

Typing /reset to completion showed an empty "no matches" popover while
Enter still executed the command, because aliases are hidden while
browsing. An exact typed query now unlocks its own alias, gated on
isDesktopSlashCommand so aliases with no desktop surface stay hidden.

Fixes #57641
This commit is contained in:
Hermes Agent
2026-09-25 11:40:03 -05:00
committed by brooklyn!
parent f6b17285ce
commit c60299e614
3 changed files with 46 additions and 2 deletions

View File

@@ -12,7 +12,7 @@ import {
type DesktopThemeCommandOption,
filterDesktopCommandsCatalog,
isDesktopSlashExtensionCommand,
isDesktopSlashSuggestion,
isDesktopSlashSuggestionWithOptions,
rankSkillCommands,
slashCompletionGroup
} from '@/lib/desktop-slash-commands'
@@ -221,6 +221,12 @@ export function useSlashCompletions(options: {
const isArgCompletion = replaceFrom > 1
const prefix = isArgCompletion ? text.slice(0, replaceFrom) : ''
// An alias the user typed to completion (`/reset`) must surface even
// though aliases are hidden while browsing — otherwise the popover
// says "no matches" for a command Enter happily executes (#57641).
// Only an EXACT match unlocks it; a partial prefix keeps hiding.
const exactAliasQuery = isArgCompletion ? undefined : commandText(query).toLowerCase()
const decorated = (result.items ?? [])
.map(item => {
if (!isArgCompletion) {
@@ -231,7 +237,10 @@ export function useSlashCompletions(options: {
return { ...item, text: `${prefix}${argText}` }
})
.filter(item => isArgCompletion || isDesktopSlashSuggestion(item.text))
.filter(
item =>
isArgCompletion || isDesktopSlashSuggestionWithOptions(item.text, { exactAlias: exactAliasQuery })
)
.map(item => ({
...item,
// Arg suggestions (e.g. `/handoff <platform>`) live under one

View File

@@ -11,6 +11,7 @@ import {
isDesktopSlashCommand,
isDesktopSlashExtensionCommand,
isDesktopSlashSuggestion,
isDesktopSlashSuggestionWithOptions,
isModelPickerCommand,
isPickerCommand,
rankSkillCommands,
@@ -149,6 +150,22 @@ describe('desktop slash command curation', () => {
expect(isDesktopSlashCommand('/reset')).toBe(true)
})
it('surfaces an alias the user typed exactly, gated on desktop availability (#57641)', () => {
// Browsing (no exact query): aliases stay hidden — popover stays lean.
expect(isDesktopSlashSuggestionWithOptions('/reset')).toBe(false)
// Exact typed query: the alias must appear, not "no matches".
expect(isDesktopSlashSuggestionWithOptions('/reset', { exactAlias: '/reset' })).toBe(true)
expect(isDesktopSlashSuggestionWithOptions('/reset', { exactAlias: 'reset' })).toBe(true)
// Partial prefixes and other queries keep aliases hidden.
expect(isDesktopSlashSuggestionWithOptions('/reset', { exactAlias: 're' })).toBe(false)
expect(isDesktopSlashSuggestionWithOptions('/reset', { exactAlias: '/new' })).toBe(false)
// A different alias never rides along with this query.
expect(isDesktopSlashSuggestionWithOptions('/fork', { exactAlias: '/reset' })).toBe(false)
// Aliases whose canonical has no desktop surface stay hidden even on an
// exact match (isDesktopSlashCommand gate).
expect(isDesktopSlashSuggestionWithOptions('/reload_mcp', { exactAlias: '/reload_mcp' })).toBe(false)
})
it('filters built-in catalog noise but keeps skill / quick-command extensions', () => {
const filtered = filterDesktopCommandsCatalog({
categories: [

View File

@@ -556,10 +556,28 @@ export function isDesktopSlashCommand(command: string): boolean {
/** Gates discovery in the popover/completions. */
export function isDesktopSlashSuggestion(command: string): boolean {
return isDesktopSlashSuggestionWithOptions(command, {})
}
/**
* Same gate, with the one escape hatch the composer needs: an alias the user
* typed EXACTLY (`/reset`, not a browsing prefix) must surface, or the empty
* "no matches" popover reads as "this command doesn't exist" while Enter still
* executes it (#57641). Gated on `isDesktopSlashCommand` so aliases whose
* canonical has no desktop surface (e.g. `/reload_mcp`) stay hidden.
*/
export function isDesktopSlashSuggestionWithOptions(
command: string,
options: { exactAlias?: string } = {}
): boolean {
const normalized = normalizeCommand(command)
// Aliases stay hidden so the popover isn't cluttered with duplicates.
if (isAliasCommand(normalized)) {
if (options.exactAlias != null) {
return normalizeCommand(options.exactAlias) === normalized && isDesktopSlashCommand(normalized)
}
return false
}