summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src/ui')
-rw-r--r--packages/cli/src/ui/App.test.tsx50
-rw-r--r--packages/cli/src/ui/App.tsx29
2 files changed, 78 insertions, 1 deletions
diff --git a/packages/cli/src/ui/App.test.tsx b/packages/cli/src/ui/App.test.tsx
index fffea64d..c64b526e 100644
--- a/packages/cli/src/ui/App.test.tsx
+++ b/packages/cli/src/ui/App.test.tsx
@@ -14,9 +14,12 @@ import {
ToolRegistry,
AccessibilitySettings,
SandboxConfig,
+ GeminiClient,
} from '@google/gemini-cli-core';
import { LoadedSettings, SettingsFile, Settings } from '../config/settings.js';
import process from 'node:process';
+import { useGeminiStream } from './hooks/useGeminiStream.js';
+import { StreamingState } from './types.js';
import { Tips } from './components/Tips.js';
// Define a more complete mock server config based on actual Config
@@ -67,6 +70,7 @@ interface MockServerConfig {
getAccessibility: Mock<() => AccessibilitySettings>;
getProjectRoot: Mock<() => string | undefined>;
getAllGeminiMdFilenames: Mock<() => string[]>;
+ getGeminiClient: Mock<() => GeminiClient | undefined>;
getUserTier: Mock<() => Promise<string | undefined>>;
}
@@ -124,7 +128,7 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
getVertexAI: vi.fn(() => opts.vertexai),
getShowMemoryUsage: vi.fn(() => opts.showMemoryUsage ?? false),
getAccessibility: vi.fn(() => opts.accessibility ?? {}),
- getProjectRoot: vi.fn(() => opts.projectRoot),
+ getProjectRoot: vi.fn(() => opts.targetDir),
getGeminiClient: vi.fn(() => ({})),
getCheckpointingEnabled: vi.fn(() => opts.checkpointing ?? true),
getAllGeminiMdFilenames: vi.fn(() => ['GEMINI.md']),
@@ -508,4 +512,48 @@ describe('App UI', () => {
expect(lastFrame()).not.toContain('Select Theme');
});
});
+
+ describe('with initial prompt from --prompt-interactive', () => {
+ it('should submit the initial prompt automatically', async () => {
+ const mockSubmitQuery = vi.fn();
+
+ mockConfig.getQuestion = vi.fn(() => 'hello from prompt-interactive');
+
+ vi.mocked(useGeminiStream).mockReturnValue({
+ streamingState: StreamingState.Idle,
+ submitQuery: mockSubmitQuery,
+ initError: null,
+ pendingHistoryItems: [],
+ thought: null,
+ });
+
+ mockConfig.getGeminiClient.mockReturnValue({
+ isInitialized: vi.fn(() => true),
+ } as unknown as GeminiClient);
+
+ const { unmount, rerender } = render(
+ <App
+ config={mockConfig as unknown as ServerConfig}
+ settings={mockSettings}
+ version={mockVersion}
+ />,
+ );
+ currentUnmount = unmount;
+
+ // Force a re-render to trigger useEffect
+ rerender(
+ <App
+ config={mockConfig as unknown as ServerConfig}
+ settings={mockSettings}
+ version={mockVersion}
+ />,
+ );
+
+ await new Promise((resolve) => setTimeout(resolve, 0));
+
+ expect(mockSubmitQuery).toHaveBeenCalledWith(
+ 'hello from prompt-interactive',
+ );
+ });
+ });
});
diff --git a/packages/cli/src/ui/App.tsx b/packages/cli/src/ui/App.tsx
index f2324b28..98f7689c 100644
--- a/packages/cli/src/ui/App.tsx
+++ b/packages/cli/src/ui/App.tsx
@@ -148,6 +148,7 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
const openPrivacyNotice = useCallback(() => {
setShowPrivacyNotice(true);
}, []);
+ const initialPromptSubmitted = useRef(false);
const errorCount = useMemo(
() => consoleMessages.filter((msg) => msg.type === 'error').length,
@@ -637,6 +638,34 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => {
return getAllGeminiMdFilenames();
}, [settings.merged.contextFileName]);
+ const initialPrompt = useMemo(() => config.getQuestion(), [config]);
+ const geminiClient = config.getGeminiClient();
+
+ useEffect(() => {
+ if (
+ initialPrompt &&
+ !initialPromptSubmitted.current &&
+ !isAuthenticating &&
+ !isAuthDialogOpen &&
+ !isThemeDialogOpen &&
+ !isEditorDialogOpen &&
+ !showPrivacyNotice &&
+ geminiClient?.isInitialized?.()
+ ) {
+ submitQuery(initialPrompt);
+ initialPromptSubmitted.current = true;
+ }
+ }, [
+ initialPrompt,
+ submitQuery,
+ isAuthenticating,
+ isAuthDialogOpen,
+ isThemeDialogOpen,
+ isEditorDialogOpen,
+ showPrivacyNotice,
+ geminiClient,
+ ]);
+
if (quittingMessages) {
return (
<Box flexDirection="column" marginBottom={1}>