From cfaa95a2b9aa0ba22a1af4c2040e1f9aeee1460f Mon Sep 17 00:00:00 2001 From: Allen Hutchison Date: Wed, 15 Oct 2025 15:00:23 -0700 Subject: [PATCH] feat(cli): Add nargs to yargs options (#11132) --- packages/cli/src/config/config.test.ts | 38 ++++++++++++++++++++++++++ packages/cli/src/config/config.ts | 14 ++++++++++ 2 files changed, 52 insertions(+) diff --git a/packages/cli/src/config/config.test.ts b/packages/cli/src/config/config.test.ts index ebe40726a7..778d30fe56 100644 --- a/packages/cli/src/config/config.test.ts +++ b/packages/cli/src/config/config.test.ts @@ -467,6 +467,44 @@ describe('parseArguments', () => { const argv = await parseArguments({} as Settings); expect(argv.extensions).toEqual(['ext1', 'ext2']); }); + + it('should correctly parse positional arguments when flags with arguments are present', async () => { + process.argv = [ + 'node', + 'script.js', + '--telemetry-target', + 'gcp', + 'my-positional-arg', + ]; + const argv = await parseArguments({} as Settings); + expect(argv.telemetryTarget).toBe('gcp'); + expect(argv.query).toBe('my-positional-arg'); + }); + + it('should handle long positional prompts with multiple flags', async () => { + process.argv = [ + 'node', + 'script.js', + '-e', + 'none', + '--approval-mode=auto_edit', + '--allowed-tools=ShellTool', + '--allowed-tools=ShellTool(whoami)', + '--allowed-tools=ShellTool(wc)', + 'Use whoami to write a poem in file poem.md about my username in pig latin and use wc to tell me how many lines are in the poem you wrote.', + ]; + const argv = await parseArguments({} as Settings); + expect(argv.extensions).toEqual(['none']); + expect(argv.approvalMode).toBe('auto_edit'); + expect(argv.allowedTools).toEqual([ + 'ShellTool', + 'ShellTool(whoami)', + 'ShellTool(wc)', + ]); + expect(argv.query).toBe( + 'Use whoami to write a poem in file poem.md about my username in pig latin and use wc to tell me how many lines are in the poem you wrote.', + ); + }); }); describe('loadCliConfig', () => { diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index 13c9a4def2..d192d6d66d 100755 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -105,17 +105,20 @@ export async function parseArguments(settings: Settings): Promise { }) .option('telemetry-target', { type: 'string', + nargs: 1, choices: ['local', 'gcp'], description: 'Set the telemetry target (local or gcp). Overrides settings files.', }) .option('telemetry-otlp-endpoint', { type: 'string', + nargs: 1, description: 'Set the OTLP endpoint for telemetry. Overrides environment variables and settings files.', }) .option('telemetry-otlp-protocol', { type: 'string', + nargs: 1, choices: ['grpc', 'http'], description: 'Set the OTLP protocol for telemetry (grpc or http). Overrides settings files.', @@ -127,6 +130,7 @@ export async function parseArguments(settings: Settings): Promise { }) .option('telemetry-outfile', { type: 'string', + nargs: 1, description: 'Redirect all telemetry output to the specified file.', }) .deprecateOption( @@ -161,6 +165,7 @@ export async function parseArguments(settings: Settings): Promise { }) .option('proxy', { type: 'string', + nargs: 1, description: 'Proxy for gemini client, like schema://user:password@host:port', }) @@ -177,16 +182,19 @@ export async function parseArguments(settings: Settings): Promise { .option('model', { alias: 'm', type: 'string', + nargs: 1, description: `Model`, }) .option('prompt', { alias: 'p', type: 'string', + nargs: 1, description: 'Prompt. Appended to input on stdin (if any).', }) .option('prompt-interactive', { alias: 'i', type: 'string', + nargs: 1, description: 'Execute the provided prompt and continue in interactive mode', }) @@ -197,6 +205,7 @@ export async function parseArguments(settings: Settings): Promise { }) .option('sandbox-image', { type: 'string', + nargs: 1, description: 'Sandbox image URI.', }) .option('all-files', { @@ -219,6 +228,7 @@ export async function parseArguments(settings: Settings): Promise { }) .option('approval-mode', { type: 'string', + nargs: 1, choices: ['default', 'auto_edit', 'yolo'], description: 'Set the approval mode: default (prompt for approval), auto_edit (auto-approve edit tools), yolo (auto-approve all tools)', @@ -236,6 +246,7 @@ export async function parseArguments(settings: Settings): Promise { .option('allowed-mcp-server-names', { type: 'array', string: true, + nargs: 1, description: 'Allowed MCP server names', coerce: (mcpServerNames: string[]) => // Handle comma-separated values @@ -246,6 +257,7 @@ export async function parseArguments(settings: Settings): Promise { .option('allowed-tools', { type: 'array', string: true, + nargs: 1, description: 'Tools that are allowed to run without confirmation', coerce: (tools: string[]) => // Handle comma-separated values @@ -272,6 +284,7 @@ export async function parseArguments(settings: Settings): Promise { .option('include-directories', { type: 'array', string: true, + nargs: 1, description: 'Additional directories to include in the workspace (comma-separated or multiple --include-directories)', coerce: (dirs: string[]) => @@ -285,6 +298,7 @@ export async function parseArguments(settings: Settings): Promise { .option('output-format', { alias: 'o', type: 'string', + nargs: 1, description: 'The format of the CLI output.', choices: ['text', 'json', 'stream-json'], })