fix(desktop): keep /resume's free-text search typeable

/resume was classified as an options command, but its argument is a
free-text query the picker fuzzy-matches against session titles and
previews. Its completion list also always ends in a "Browse all
sessions…" action row, so Space-to-accept never fell through to an
empty list: the first space in a multi-word query emptied the composer
and threw the user into the overlay, query and all.

Classify it as mixed so spaces type through, matches keep narrowing as
you refine, and Tab or arrow-then-Enter still accept a highlighted
session.
This commit is contained in:
Brooklyn Nicholson 2026-07-27 18:02:54 -05:00
parent 7de4fbd493
commit 3c74f463d0
2 changed files with 21 additions and 1 deletions

View file

@ -172,6 +172,20 @@ describe('useComposerTrigger — free-text slash arguments', () => {
expect(hook.result.current.triggerActiveExplicit).toBe(false)
})
it('keeps a multi-word /resume search typeable instead of firing the picker action', () => {
// The session list always ends in a "Browse all sessions…" action row, so
// an accept here doesn't insert a chip — it empties the composer and opens
// the overlay, taking the half-typed query with it.
const editor = mountEditor('/resume my new')
const { hook } = mountTrigger(editor, [item('/resume', 'Sessions')])
act(() => hook.result.current.refreshTrigger())
expect(hook.result.current.slashFreeTextArgStage).toBe(true)
expect(hook.result.current.commitTypedSlashDirective()).toBe(false)
expect(composerPlainText(editor)).toBe('/resume my new')
})
it('still commits a fully typed finite option as one directive chip', () => {
const editor = mountEditor('/personality creative')
const { hook } = mountTrigger(editor, [])

View file

@ -188,7 +188,13 @@ const DESKTOP_COMMAND_SPECS: readonly DesktopCommandSpec[] = [
description: 'Resume a saved session',
aliases: ['/sessions', '/switch'],
surface: picker('session'),
argumentMode: 'options'
// `mixed`, not `options`: the argument is a free-text search the picker
// fuzzy-matches against titles and previews, so multi-word queries have to
// stay typeable. Its completion list also always carries a trailing
// "Browse all sessions…" action row, which meant Space-to-accept could
// never fall through — the first space wiped the composer and threw the
// user into the overlay.
argumentMode: 'mixed'
},
// Backend-executed commands that render useful inline output.