Skip to content

feat(cli): implement dot-prefixing for slash command conflicts#20979

Merged
ehedlund merged 3 commits intogoogle-gemini:mainfrom
ehedlund:feat/slash-command-conflict-prefixing
Mar 6, 2026
Merged

feat(cli): implement dot-prefixing for slash command conflicts#20979
ehedlund merged 3 commits intogoogle-gemini:mainfrom
ehedlund:feat/slash-command-conflict-prefixing

Conversation

@ehedlund
Copy link
Copy Markdown
Contributor

@ehedlund ehedlund commented Mar 3, 2026

Summary

This PR implements robust dot-prefixing for slash command name conflicts. It ensures that when multiple versions of a command exist, all are discoverable and uniquely identifiable via source-specific prefixes (e.g., user.launch, workspace.launch), while allowing Built-in commands to retain their primary names.

Screenshot 2026-03-06 at 1 29 55 PM

Key Changes

  • Modular Architecture: Extracted conflict resolution logic from CommandService into a dedicated, pure SlashCommandResolver class.
  • Precedence & Renaming Rules:
    • Built-in commands always keep the original base name.
    • All other types (User, Workspace, MCP, Extension) are prefixed with their source name whenever a conflict occurs.
    • If multiple non-built-in commands conflict, all of them are renamed to ensure unique addressability.
  • Isolated Testing: Replaced bulky hook tests with dedicated unit tests for SlashCommandResolver and SlashCommandConflictHandler.

Related Issues

Related to: https://github.com/google-gemini/maintainers-gemini-cli/issues/1218

How to Validate

  1. Create a command file .gemini/commands/test-conflict.toml in both your user config and project root.
  2. Configure an MCP server with a conflicting prompt.
  3. Start the CLI.
  4. Observe the consolidated conflict message and verify that all versions are available via autocomplete with their respective prefixes.

@ehedlund ehedlund requested a review from a team as a code owner March 3, 2026 15:37
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly improves the handling of slash command conflicts within the CLI by introducing a robust dot-prefixing strategy for user, workspace, and extension-defined commands. This change ensures that all commands remain discoverable and uniquely addressable, even when their base names clash. Additionally, the system for reporting these conflicts has been refined to be more user-friendly and less intrusive. A new security feature has also been integrated to alert users to potentially deceptive URLs, bolstering the overall safety of command execution.

Highlights

  • Enhanced Slash Command Conflict Resolution: Implemented a new conflict resolution mechanism for slash commands, introducing dot-prefixing (e.g., user.command, workspace.command, extension.command) to uniquely identify commands from different sources (user, workspace, extensions) when their names conflict. This ensures all commands are accessible instead of one silently overriding another.
  • Improved Conflict Reporting: Updated the conflict reporting system to provide more consolidated and descriptive feedback messages. Conflicts are now grouped by command name, and a 500ms trailing debouncer unifies fragmented notifications during startup, preventing UI clutter.
  • Refined CommandKind Enum: The CommandKind enum was expanded to include USER_FILE, WORKSPACE_FILE, and EXTENSION_FILE, allowing for more granular tracking of command origins.
  • Deceptive URL Detection: Added new functionality to detect and warn users about deceptive URLs (e.g., Punycode or non-ASCII characters in hostnames) within tool confirmation messages, enhancing security.
Changelog
  • packages/cli/src/services/CommandService.test.ts
    • Refactored MockCommandLoader to simplify command initialization.
    • Replaced numerous specific test cases with new describe blocks for 'basic loading', 'name conflicts', 'secondary conflicts (suffixing)', and 'conflict reporting'.
    • Added new tests to verify dot-prefixing for user and workspace commands, handling of multi-way conflicts, and numeric suffixing for secondary conflicts.
    • Updated conflict reporting tests to reflect the new CommandConflict structure and detailed winner/loser information.
  • packages/cli/src/services/CommandService.ts
    • Modified CommandConflict interface to remove winner property at the top level and add winner and loserKind/winnerKind to individual losers entries.
    • Updated create method documentation to reflect new conflict resolution rules for extension, user, and workspace commands.
    • Implemented new conflict resolution logic using firstEncounters map to track the first command claiming a name.
    • Added getRenamedExtensionName static helper to generate unique names for conflicting extension commands, including numeric suffixes.
    • Added getKindPrefix static helper to return 'user' or 'workspace' prefixes based on CommandKind.
    • Added trackConflict static helper to centralize the recording of command conflicts.
  • packages/cli/src/services/FileCommandLoader.ts
    • Added kind property to CommandDirectory interface to specify the source type of commands.
    • Updated getCommandDirectories to assign CommandKind.USER_FILE, CommandKind.WORKSPACE_FILE, and CommandKind.EXTENSION_FILE to respective command directories.
    • Modified parseAndAdaptFile to accept and use the kind parameter when creating SlashCommand objects.
  • packages/cli/src/services/SlashCommandConflictHandler.ts
    • Added pendingConflicts array and flushTimeout for debouncing conflict notifications.
    • Updated stop method to clear the flushTimeout.
    • Modified handleConflicts to use a more robust key for notifiedConflicts and to push new conflicts to pendingConflicts.
    • Implemented scheduleFlush and flush methods to debounce and group conflict notifications.
    • Introduced logic to format conflict messages differently for single vs. multiple conflicts for the same command name.
    • Added capitalize helper function.
    • Added getSourceDescription helper to provide human-readable descriptions for command sources (extension, user, workspace, built-in).
  • packages/cli/src/ui/commands/types.ts
    • Expanded CommandKind enum to include USER_FILE, WORKSPACE_FILE, and EXTENSION_FILE, replacing the generic FILE kind.
  • packages/cli/src/ui/components/InputPrompt.test.tsx
    • Updated customCommand kind from CommandKind.FILE to CommandKind.USER_FILE in autocomplete test.
  • packages/cli/src/ui/components/messages/ToolConfirmationMessage.test.tsx
    • Added new tests to verify WarningMessage display for deceptive URLs in 'info' and 'exec' type confirmations.
    • Added a test to ensure shell delimiters are excluded from extracted URLs in 'exec' commands.
    • Added a test to confirm aggregation of multiple deceptive URLs into a single warning message.
  • packages/cli/src/ui/components/messages/ToolConfirmationMessage.tsx
    • Imported WarningMessage, getDeceptiveUrlDetails, and toUnicodeUrl for URL security features.
    • Implemented deceptiveUrlWarnings and deceptiveUrlWarningText memos to detect and format deceptive URL warnings.
    • Modified useMemo for question, bodyContent, options to also return securityWarnings.
    • Rendered securityWarnings within the component when deceptive URLs are detected.
    • Updated URL display in info type confirmations to use toUnicodeUrl for better readability.
  • packages/cli/src/ui/hooks/slashCommandProcessor.test.tsx
    • Updated tests for command precedence to reflect new conflict resolution: should prefix user-file commands that conflict with built-in commands and should prefix user-file commands that conflict with MCP commands.
    • Modified createTestCommand calls to use specific CommandKind values (USER_FILE, EXTENSION_FILE).
    • Adjusted assertions for slashCommands length and mockAddItem calls to match new conflict reporting behavior and debouncing.
  • packages/cli/src/ui/hooks/useSlashCompletion.test.ts
    • Updated customCommand kind from CommandKind.FILE to CommandKind.USER_FILE in completion test.
  • packages/cli/src/ui/utils/urlSecurityUtils.test.ts
    • Added new test file for urlSecurityUtils.
    • Included tests for toUnicodeUrl to verify conversion of Punycode to Unicode URLs, handling complex URLs, and gracefully managing invalid inputs.
    • Added tests for getDeceptiveUrlDetails to confirm detection of deceptive URLs and proper handling of safe or already Punycoded hostnames.
  • packages/cli/src/ui/utils/urlSecurityUtils.ts
    • Added new utility file urlSecurityUtils.ts.
    • Defined DeceptiveUrlDetails interface.
    • Implemented containsDeceptiveMarkers to check for non-ASCII or Punycode in hostnames.
    • Implemented toUnicodeUrl to convert URL strings/objects to their Unicode representation, manually reconstructing the URL to avoid automatic Punycode conversion.
    • Implemented getDeceptiveUrlDetails to extract details about potentially deceptive URLs, returning null for safe or invalid URLs.
  • packages/cli/src/utils/commands.test.ts
    • Updated mock command kind from CommandKind.FILE to CommandKind.USER_FILE.
  • packages/core/src/code_assist/oauth2.test.ts
    • Imported isHeadlessMode.
    • Added mocks for isHeadlessMode and readline.createInterface in beforeEach to ensure consistent test environment.
  • packages/core/src/mcp/oauth-provider.test.ts
    • Added mocks for isHeadlessMode and node:readline to control test environment behavior.
  • packages/core/src/utils/events.ts
    • Added loserKind and winnerKind optional properties to the SlashCommandConflict interface to provide more context about conflicting command types.
Activity
  • The pull request author, ehedlund, has implemented the core logic for dot-prefixing and improved conflict reporting.
  • Comprehensive unit and functional tests have been added or updated across 8 files to validate the new behavior.
  • The pre-merge checklist indicates that tests have been added/updated and validated on MacOS using npm run.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This PR introduces dot-prefixing for user and workspace slash command conflicts in the Gemini CLI, ensuring that multiple versions of a command are uniquely identifiable. It also enhances conflict reporting with consolidated feedback messages and updates unit tests to reflect the new behavior. The changes include modifications to CommandService, FileCommandLoader, SlashCommandConflictHandler, and several test files. The review focuses on ensuring the correctness of the conflict resolution logic and adherence to the repository's coding style.

@ehedlund ehedlund force-pushed the feat/slash-command-conflict-prefixing branch from d697cd6 to 981c1e8 Compare March 3, 2026 15:55
@gemini-cli gemini-cli bot added the status/need-issue Pull requests that need to have an associated issue. label Mar 3, 2026
@ehedlund ehedlund changed the title feat(cli): implement dot-prefixing for user and workspace slash command conflicts feat(cli): implement dot-prefixing for slash command conflicts Mar 6, 2026
@ehedlund ehedlund added this pull request to the merge queue Mar 6, 2026
Merged via the queue into google-gemini:main with commit 7989c28 Mar 6, 2026
28 of 29 checks passed
@ehedlund ehedlund deleted the feat/slash-command-conflict-prefixing branch March 6, 2026 20:56
kunal-10-cloud pushed a commit to kunal-10-cloud/gemini-cli that referenced this pull request Mar 12, 2026
yashodipmore pushed a commit to yashodipmore/geemi-cli that referenced this pull request Mar 21, 2026
SUNDRAM07 pushed a commit to SUNDRAM07/gemini-cli that referenced this pull request Mar 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status/need-issue Pull requests that need to have an associated issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants