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
-
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).
-
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);
-
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.
What happened?
The Gemini CLI uses
yargsfor argument parsing. A greedy default command ($0 [query..]) was registered at the top of the command chain, causing it to shadow explicit subcommands likemcp,extensions,skills, andhooks.When a user runs a subcommand (e.g.,
gemini extensions install ...),yargsincorrectly matches it against the default command, treating the subcommand and its arguments as a conversational query. This triggers the main application logic ingemini.tsx, which attempts to initialize the Gemini API client. This initialization requires aGEMINI_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?
Anything else we need to know?
Implementation Plan
Reorder Command Registration in
packages/cli/src/config/config.tsmcp,extensions,skills,hooks) before the default$0command.mcpCommandis actually registered usingyargsInstance.command(mcpCommand).Add High-Priority Middleware to Set
isCommandparseArgumentsto explicitly flag when a subcommand is matched.Update
gemini.tsxto RespectisCommandpartialConfig.refreshAuthandvalidateNonInteractiveAuth) ifargv.isCommandis true.argv.isCommandis true.Verification & Testing
gemini extensions install ...without aGEMINI_API_KEYset and verify it proceeds to installation.argv.isCommandis correctly set inparseArgumentsfor various subcommands.