Merge pull request #2817 from Dawnfz-Lenfeng/fix/init-command-always-available

fix(ui): always show /init command in autocomplete
This commit is contained in:
Bohdan Triapitsyn
2026-08-27 23:14:46 +03:00
committed by GitHub
@@ -1,7 +1,6 @@
import React from 'react'; import React from 'react';
import { cn, fuzzyMatch } from '@/lib/utils'; import { cn, fuzzyMatch } from '@/lib/utils';
import { useSessionUIStore } from '@/sync/session-ui-store'; import { useSessionUIStore } from '@/sync/session-ui-store';
import { useSessionMessages } from '@/sync/sync-context';
import { useCommandsStore } from '@/stores/useCommandsStore'; import { useCommandsStore } from '@/stores/useCommandsStore';
import { useSkillsStore } from '@/stores/useSkillsStore'; import { useSkillsStore } from '@/stores/useSkillsStore';
import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay'; import { ScrollableOverlay } from '@/components/ui/ScrollableOverlay';
@@ -66,8 +65,6 @@ export const CommandAutocomplete = React.forwardRef<CommandAutocompleteHandle, C
}, ref) => { }, ref) => {
const { t } = useI18n(); const { t } = useI18n();
const currentSessionId = useSessionUIStore((state) => state.currentSessionId); const currentSessionId = useSessionUIStore((state) => state.currentSessionId);
const sessionMessages = useSessionMessages(currentSessionId ?? '');
const hasMessagesInCurrentSession = sessionMessages.length > 0;
const hasSession = Boolean(currentSessionId); const hasSession = Boolean(currentSessionId);
const hasNewSessionDraft = useSessionUIStore((state) => Boolean(state.newSessionDraft?.open)); const hasNewSessionDraft = useSessionUIStore((state) => Boolean(state.newSessionDraft?.open));
const canStartSessionCommand = hasSession || hasNewSessionDraft; const canStartSessionCommand = hasSession || hasNewSessionDraft;
@@ -140,7 +137,7 @@ export const CommandAutocomplete = React.forwardRef<CommandAutocompleteHandle, C
})); }));
const builtInCommands: CommandInfo[] = [ const builtInCommands: CommandInfo[] = [
...(hasSession && !hasMessagesInCurrentSession ...(hasSession
? [{ id: 'openchamber:init', name: 'init', source: 'openchamber' as const, description: t('chat.commandAutocomplete.command.initDescription'), isBuiltIn: true }] ? [{ id: 'openchamber:init', name: 'init', source: 'openchamber' as const, description: t('chat.commandAutocomplete.command.initDescription'), isBuiltIn: true }]
: [] : []
), ),
@@ -200,10 +197,9 @@ export const CommandAutocomplete = React.forwardRef<CommandAutocompleteHandle, C
]; ];
const allCommands = mergeCommandAutocompleteItems(builtInCommands, customCommands, skillCommands); const allCommands = mergeCommandAutocompleteItems(builtInCommands, customCommands, skillCommands);
const allowInitCommand = !hasMessagesInCurrentSession; const filtered = searchQuery
const filtered = (searchQuery
? allCommands.filter(cmd => commandMatchesSearch(cmd, searchQuery)) ? allCommands.filter(cmd => commandMatchesSearch(cmd, searchQuery))
: allCommands).filter(cmd => allowInitCommand || cmd.name !== 'init'); : allCommands;
filtered.sort((a, b) => { filtered.sort((a, b) => {
const aStartsWith = a.name.toLowerCase().startsWith(searchQuery.toLowerCase()); const aStartsWith = a.name.toLowerCase().startsWith(searchQuery.toLowerCase());
@@ -216,9 +212,8 @@ export const CommandAutocomplete = React.forwardRef<CommandAutocompleteHandle, C
setCommands(filtered); setCommands(filtered);
} catch { } catch {
const allowInitCommand = !hasMessagesInCurrentSession;
const builtInCommands: CommandInfo[] = [ const builtInCommands: CommandInfo[] = [
...(hasSession && !hasMessagesInCurrentSession ...(hasSession
? [{ id: 'openchamber:init', name: 'init', source: 'openchamber' as const, description: t('chat.commandAutocomplete.command.initDescription'), isBuiltIn: true }] ? [{ id: 'openchamber:init', name: 'init', source: 'openchamber' as const, description: t('chat.commandAutocomplete.command.initDescription'), isBuiltIn: true }]
: [] : []
), ),
@@ -277,12 +272,12 @@ export const CommandAutocomplete = React.forwardRef<CommandAutocompleteHandle, C
), ),
]; ];
const filtered = (searchQuery const filtered = searchQuery
? builtInCommands.filter(cmd => ? builtInCommands.filter(cmd =>
fuzzyMatch(cmd.name, searchQuery) || fuzzyMatch(cmd.name, searchQuery) ||
(cmd.description && fuzzyMatch(cmd.description, searchQuery)) (cmd.description && fuzzyMatch(cmd.description, searchQuery))
) )
: builtInCommands).filter(cmd => allowInitCommand || cmd.name !== 'init'); : builtInCommands;
setCommands(filtered); setCommands(filtered);
} finally { } finally {
@@ -291,7 +286,7 @@ export const CommandAutocomplete = React.forwardRef<CommandAutocompleteHandle, C
}; };
loadCommands(); loadCommands();
}, [searchQuery, hasMessagesInCurrentSession, hasSession, canStartSessionCommand, canUseReviewHandoffFlow, commandsWithMetadata, skills, t]); }, [searchQuery, hasSession, canStartSessionCommand, canUseReviewHandoffFlow, commandsWithMetadata, skills, t]);
React.useEffect(() => { React.useEffect(() => {
setSelectedIndex(0); setSelectedIndex(0);