diff --git a/packages/cli/src/nonInteractiveCliCommands.ts b/packages/cli/src/nonInteractiveCliCommands.ts
index 31b748d786..15b9301ad4 100644
--- a/packages/cli/src/nonInteractiveCliCommands.ts
+++ b/packages/cli/src/nonInteractiveCliCommands.ts
@@ -39,9 +39,8 @@ export const handleSlashCommand = async (
}
// Only custom commands are supported for now.
- const loaders = [new FileCommandLoader(config)];
const commandService = await CommandService.create(
- loaders,
+ [new FileCommandLoader(config)],
abortController.signal,
);
const commands = commandService.getCommands();
diff --git a/packages/cli/src/ui/AppContainer.tsx b/packages/cli/src/ui/AppContainer.tsx
index bad03fa568..4eab2524f9 100644
--- a/packages/cli/src/ui/AppContainer.tsx
+++ b/packages/cli/src/ui/AppContainer.tsx
@@ -681,6 +681,7 @@ Logging in with Google... Please restart Gemini CLI to continue.
const isInputActive =
!initError &&
!isProcessing &&
+ !!slashCommands &&
(streamingState === StreamingState.Idle ||
streamingState === StreamingState.Responding) &&
!proQuotaRequest;
diff --git a/packages/cli/src/ui/components/Composer.tsx b/packages/cli/src/ui/components/Composer.tsx
index 1d4e942624..d87737619a 100644
--- a/packages/cli/src/ui/components/Composer.tsx
+++ b/packages/cli/src/ui/components/Composer.tsx
@@ -58,7 +58,9 @@ export const Composer = () => {
/>
)}
- {!uiState.isConfigInitialized && }
+ {(!uiState.slashCommands || !uiState.isConfigInitialized) && (
+
+ )}
@@ -133,7 +135,7 @@ export const Composer = () => {
userMessages={uiState.userMessages}
onClearScreen={uiActions.handleClearScreen}
config={config}
- slashCommands={uiState.slashCommands}
+ slashCommands={uiState.slashCommands || []}
commandContext={uiState.commandContext}
shellModeActive={uiState.shellModeActive}
setShellModeActive={uiActions.setShellModeActive}
diff --git a/packages/cli/src/ui/contexts/UIStateContext.tsx b/packages/cli/src/ui/contexts/UIStateContext.tsx
index b9a8b6f739..fcc86f02e2 100644
--- a/packages/cli/src/ui/contexts/UIStateContext.tsx
+++ b/packages/cli/src/ui/contexts/UIStateContext.tsx
@@ -56,7 +56,7 @@ export interface UIState {
isSettingsDialogOpen: boolean;
isModelDialogOpen: boolean;
isPermissionsDialogOpen: boolean;
- slashCommands: readonly SlashCommand[];
+ slashCommands: readonly SlashCommand[] | undefined;
pendingSlashCommandHistoryItems: HistoryItemWithoutId[];
commandContext: CommandContext;
shellConfirmationRequest: ShellConfirmationRequest | null;
diff --git a/packages/cli/src/ui/hooks/slashCommandProcessor.test.ts b/packages/cli/src/ui/hooks/slashCommandProcessor.test.ts
index a59258a265..8762583494 100644
--- a/packages/cli/src/ui/hooks/slashCommandProcessor.test.ts
+++ b/packages/cli/src/ui/hooks/slashCommandProcessor.test.ts
@@ -342,6 +342,8 @@ describe('useSlashCommandProcessor', () => {
setMockIsProcessing,
);
+ await waitFor(() => expect(result.current.slashCommands).toBeDefined());
+
await act(async () => {
await result.current.handleSlashCommand('/fail');
});
diff --git a/packages/cli/src/ui/hooks/slashCommandProcessor.ts b/packages/cli/src/ui/hooks/slashCommandProcessor.ts
index c6c6ea57b8..c5b5d5db4e 100644
--- a/packages/cli/src/ui/hooks/slashCommandProcessor.ts
+++ b/packages/cli/src/ui/hooks/slashCommandProcessor.ts
@@ -74,7 +74,9 @@ export const useSlashCommandProcessor = (
isConfigInitialized: boolean,
) => {
const session = useSessionStats();
- const [commands, setCommands] = useState([]);
+ const [commands, setCommands] = useState(
+ undefined,
+ );
const [reloadTrigger, setReloadTrigger] = useState(0);
const reloadCommands = useCallback(() => {
@@ -257,20 +259,18 @@ export const useSlashCommandProcessor = (
useEffect(() => {
const controller = new AbortController();
- const load = async () => {
- const loaders = [
- new McpPromptLoader(config),
- new BuiltinCommandLoader(config),
- new FileCommandLoader(config),
- ];
+
+ (async () => {
const commandService = await CommandService.create(
- loaders,
+ [
+ new McpPromptLoader(config),
+ new BuiltinCommandLoader(config),
+ new FileCommandLoader(config),
+ ],
controller.signal,
);
setCommands(commandService.getCommands());
- };
-
- load();
+ })();
return () => {
controller.abort();
@@ -283,6 +283,9 @@ export const useSlashCommandProcessor = (
oneTimeShellAllowlist?: Set,
overwriteConfirmed?: boolean,
): Promise => {
+ if (!commands) {
+ return false;
+ }
if (typeof rawQuery !== 'string') {
return false;
}