diff --git a/apps/desktop/src/app/chat/composer/hooks/use-composer-trigger.test.ts b/apps/desktop/src/app/chat/composer/hooks/use-composer-trigger.test.ts index a4ab38b3b3a..4239f781afa 100644 --- a/apps/desktop/src/app/chat/composer/hooks/use-composer-trigger.test.ts +++ b/apps/desktop/src/app/chat/composer/hooks/use-composer-trigger.test.ts @@ -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, []) diff --git a/apps/desktop/src/lib/desktop-slash-commands.ts b/apps/desktop/src/lib/desktop-slash-commands.ts index 81e4a694c01..62f2e0d5bd7 100644 --- a/apps/desktop/src/lib/desktop-slash-commands.ts +++ b/apps/desktop/src/lib/desktop-slash-commands.ts @@ -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.