From 5b6608ad844f89954b9107ad81b3791fae02607a Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Fri, 11 Jul 2025 16:52:56 -0700 Subject: feat(cli): add support for --prompt-interactive/-i flag (#1743) --- packages/cli/src/ui/App.test.tsx | 50 +++++++++++++++++++++++++++++++++++++++- packages/cli/src/ui/App.tsx | 29 +++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) (limited to 'packages/cli/src/ui') 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>; } @@ -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( + , + ); + currentUnmount = unmount; + + // Force a re-render to trigger useEffect + rerender( + , + ); + + 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 ( -- cgit v1.2.3