feat: Add positional argument for prompt (#7668)

This commit is contained in:
Allen Hutchison
2025-09-03 15:48:54 -07:00
committed by GitHub
parent 987f08a619
commit 6bb944f942
2 changed files with 67 additions and 3 deletions

View File

@@ -1971,3 +1971,55 @@ describe('loadCliConfig fileFiltering', () => {
},
);
});
describe('parseArguments with positional prompt', () => {
const originalArgv = process.argv;
afterEach(() => {
process.argv = originalArgv;
});
it('should throw an error when both a positional prompt and the --prompt flag are used', async () => {
process.argv = [
'node',
'script.js',
'positional',
'prompt',
'--prompt',
'test prompt',
];
const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => {
throw new Error('process.exit called');
});
const mockConsoleError = vi
.spyOn(console, 'error')
.mockImplementation(() => {});
await expect(parseArguments({} as Settings)).rejects.toThrow(
'process.exit called',
);
expect(mockConsoleError).toHaveBeenCalledWith(
expect.stringContaining(
'Cannot use both a positional prompt and the --prompt (-p) flag together',
),
);
mockExit.mockRestore();
mockConsoleError.mockRestore();
});
it('should correctly parse a positional prompt', async () => {
process.argv = ['node', 'script.js', 'positional', 'prompt'];
const argv = await parseArguments({} as Settings);
expect(argv.promptWords).toEqual(['positional', 'prompt']);
});
it('should correctly parse a prompt from the --prompt flag', async () => {
process.argv = ['node', 'script.js', '--prompt', 'test prompt'];
const argv = await parseArguments({} as Settings);
expect(argv.prompt).toBe('test prompt');
});
});

View File

@@ -80,6 +80,7 @@ export interface CliArgs {
screenReader: boolean | undefined;
useSmartEdit: boolean | undefined;
sessionSummary: string | undefined;
promptWords: string[] | undefined;
}
export async function parseArguments(settings: Settings): Promise<CliArgs> {
@@ -89,7 +90,7 @@ export async function parseArguments(settings: Settings): Promise<CliArgs> {
.usage(
'Usage: gemini [options] [command]\n\nGemini CLI - Launch an interactive CLI, use -p/--prompt for non-interactive mode',
)
.command('$0', 'Launch Gemini CLI', (yargsInstance) =>
.command('$0 [promptWords...]', 'Launch Gemini CLI', (yargsInstance) =>
yargsInstance
.option('model', {
alias: 'm',
@@ -277,8 +278,18 @@ export async function parseArguments(settings: Settings): Promise<CliArgs> {
'all-files',
'Use @ includes in the application instead. This flag will be removed in a future version.',
)
.deprecateOption(
'prompt',
'Use the positional prompt instead. This flag will be removed in a future version.',
)
.check((argv) => {
if (argv.prompt && argv['promptInteractive']) {
const promptWords = argv['promptWords'] as string[] | undefined;
if (argv['prompt'] && promptWords && promptWords.length > 0) {
throw new Error(
'Cannot use both a positional prompt and the --prompt (-p) flag together',
);
}
if (argv['prompt'] && argv['promptInteractive']) {
throw new Error(
'Cannot use both --prompt (-p) and --prompt-interactive (-i) together',
);
@@ -439,7 +450,8 @@ export async function loadCliConfig(
);
let mcpServers = mergeMcpServers(settings, activeExtensions);
const question = argv.promptInteractive || argv.prompt || '';
const question =
argv.promptInteractive || argv.prompt || (argv.promptWords || []).join(' ');
// Determine approval mode with backward compatibility
let approvalMode: ApprovalMode;