Skip to content

Fix Yargs Command Shadowing and API Key Requirement for Subcommands #23173

@mattKorwel

Description

@mattKorwel

What happened?

The Gemini CLI uses yargs for argument parsing. A greedy default command ($0 [query..]) was registered at the top of the command chain, causing it to shadow explicit subcommands like mcp, extensions, skills, and hooks.

When a user runs a subcommand (e.g., gemini extensions install ...), yargs incorrectly matches it against the default command, treating the subcommand and its arguments as a conversational query. This triggers the main application logic in gemini.tsx, which attempts to initialize the Gemini API client. This initialization requires a GEMINI_API_KEY, which is not needed for administrative subcommands, leading to a fatal error if the key is missing.

What did you expect to happen?

  • Subcommands should be matched first and executed without requiring a Gemini API key (unless the subcommand itself requires it).
  • The default conversational query should only be matched if no explicit subcommand is provided.
  • The application should not attempt to initialize the LLM client or enter interactive mode when a management subcommand is being executed.

Anything else we need to know?

Implementation Plan

  1. Reorder Command Registration in packages/cli/src/config/config.ts

    • Register all explicit subcommands (mcp, extensions, skills, hooks) before the default $0 command.
    • Ensure mcpCommand is actually registered using yargsInstance.command(mcpCommand).
  2. Add High-Priority Middleware to Set isCommand

    • Add a yargs middleware at the top level of parseArguments to explicitly flag when a subcommand is matched.
    yargsInstance.middleware((argv) => {
      const subcommands = ['mcp', 'extensions', 'extension', 'skills', 'skill', 'hooks', 'hook'];
      if (subcommands.includes(argv._[0] as string)) {
        argv.isCommand = true;
      }
    }, true);
  3. Update gemini.tsx to Respect isCommand

    • Skip authentication (partialConfig.refreshAuth and validateNonInteractiveAuth) if argv.isCommand is true.
    • Skip sandbox/child process relaunching logic if argv.isCommand is true.

Verification & Testing

  • Manual Verification: Run gemini extensions install ... without a GEMINI_API_KEY set and verify it proceeds to installation.
  • Unit Tests: Ensure that argv.isCommand is correctly set in parseArguments for various subcommands.

Metadata

Metadata

Assignees

Labels

area/coreIssues related to User Interface, OS Support, Core Functionalitystatus/need-triageIssues that need to be triaged by the triage automation.🔒 maintainer only⛔ Do not contribute. Internal roadmap item.

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions