mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-25 04:24:51 -07:00
Revert "feat(ui): add source indicators to slash commands" (#19695)
This commit is contained in:
@@ -10,13 +10,8 @@ import { type ICommandLoader } from './types.js';
|
||||
import { CommandKind, type SlashCommand } from '../ui/commands/types.js';
|
||||
import { debugLogger } from '@google/gemini-cli-core';
|
||||
|
||||
const createMockCommand = (
|
||||
name: string,
|
||||
kind: CommandKind,
|
||||
namespace?: string,
|
||||
): SlashCommand => ({
|
||||
const createMockCommand = (name: string, kind: CommandKind): SlashCommand => ({
|
||||
name,
|
||||
namespace,
|
||||
description: `Description for ${name}`,
|
||||
kind,
|
||||
action: vi.fn(),
|
||||
@@ -184,18 +179,18 @@ describe('CommandService', () => {
|
||||
expect(loader2.loadCommands).toHaveBeenCalledWith(signal);
|
||||
});
|
||||
|
||||
it('should apply namespaces to commands from user and extensions', async () => {
|
||||
it('should rename extension commands when they conflict', async () => {
|
||||
const builtinCommand = createMockCommand('deploy', CommandKind.BUILT_IN);
|
||||
const userCommand = createMockCommand('sync', CommandKind.FILE, 'user');
|
||||
const userCommand = createMockCommand('sync', CommandKind.FILE);
|
||||
const extensionCommand1 = {
|
||||
...createMockCommand('deploy', CommandKind.FILE, 'firebase'),
|
||||
...createMockCommand('deploy', CommandKind.FILE),
|
||||
extensionName: 'firebase',
|
||||
description: 'Deploy to Firebase',
|
||||
description: '[firebase] Deploy to Firebase',
|
||||
};
|
||||
const extensionCommand2 = {
|
||||
...createMockCommand('sync', CommandKind.FILE, 'git-helper'),
|
||||
...createMockCommand('sync', CommandKind.FILE),
|
||||
extensionName: 'git-helper',
|
||||
description: 'Sync with remote',
|
||||
description: '[git-helper] Sync with remote',
|
||||
};
|
||||
|
||||
const mockLoader1 = new MockCommandLoader([builtinCommand]);
|
||||
@@ -213,28 +208,30 @@ describe('CommandService', () => {
|
||||
const commands = service.getCommands();
|
||||
expect(commands).toHaveLength(4);
|
||||
|
||||
// Built-in command keeps original name because it has no namespace
|
||||
// Built-in command keeps original name
|
||||
const deployBuiltin = commands.find(
|
||||
(cmd) => cmd.name === 'deploy' && !cmd.extensionName,
|
||||
);
|
||||
expect(deployBuiltin).toBeDefined();
|
||||
expect(deployBuiltin?.kind).toBe(CommandKind.BUILT_IN);
|
||||
|
||||
// Extension command gets namespaced, preventing conflict with built-in
|
||||
// Extension command conflicting with built-in gets renamed
|
||||
const deployExtension = commands.find(
|
||||
(cmd) => cmd.name === 'firebase:deploy',
|
||||
(cmd) => cmd.name === 'firebase.deploy',
|
||||
);
|
||||
expect(deployExtension).toBeDefined();
|
||||
expect(deployExtension?.extensionName).toBe('firebase');
|
||||
|
||||
// User command gets namespaced
|
||||
const syncUser = commands.find((cmd) => cmd.name === 'user:sync');
|
||||
// User command keeps original name
|
||||
const syncUser = commands.find(
|
||||
(cmd) => cmd.name === 'sync' && !cmd.extensionName,
|
||||
);
|
||||
expect(syncUser).toBeDefined();
|
||||
expect(syncUser?.kind).toBe(CommandKind.FILE);
|
||||
|
||||
// Extension command gets namespaced
|
||||
// Extension command conflicting with user command gets renamed
|
||||
const syncExtension = commands.find(
|
||||
(cmd) => cmd.name === 'git-helper:sync',
|
||||
(cmd) => cmd.name === 'git-helper.sync',
|
||||
);
|
||||
expect(syncExtension).toBeDefined();
|
||||
expect(syncExtension?.extensionName).toBe('git-helper');
|
||||
@@ -272,16 +269,16 @@ describe('CommandService', () => {
|
||||
expect(deployCommand?.kind).toBe(CommandKind.FILE);
|
||||
});
|
||||
|
||||
it('should handle namespaced name conflicts when renaming extension commands', async () => {
|
||||
// User has both /deploy and /gcp:deploy commands
|
||||
it('should handle secondary conflicts when renaming extension commands', async () => {
|
||||
// User has both /deploy and /gcp.deploy commands
|
||||
const userCommand1 = createMockCommand('deploy', CommandKind.FILE);
|
||||
const userCommand2 = createMockCommand('gcp:deploy', CommandKind.FILE);
|
||||
const userCommand2 = createMockCommand('gcp.deploy', CommandKind.FILE);
|
||||
|
||||
// Extension also has a deploy command that will resolve to /gcp:deploy and conflict with userCommand2
|
||||
// Extension also has a deploy command that will conflict with user's /deploy
|
||||
const extensionCommand = {
|
||||
...createMockCommand('deploy', CommandKind.FILE, 'gcp'),
|
||||
...createMockCommand('deploy', CommandKind.FILE),
|
||||
extensionName: 'gcp',
|
||||
description: 'Deploy to Google Cloud',
|
||||
description: '[gcp] Deploy to Google Cloud',
|
||||
};
|
||||
|
||||
const mockLoader = new MockCommandLoader([
|
||||
@@ -304,31 +301,31 @@ describe('CommandService', () => {
|
||||
);
|
||||
expect(deployUser).toBeDefined();
|
||||
|
||||
// User's command keeps its name
|
||||
// User's dot notation command keeps its name
|
||||
const gcpDeployUser = commands.find(
|
||||
(cmd) => cmd.name === 'gcp:deploy' && !cmd.extensionName,
|
||||
(cmd) => cmd.name === 'gcp.deploy' && !cmd.extensionName,
|
||||
);
|
||||
expect(gcpDeployUser).toBeDefined();
|
||||
|
||||
// Extension command gets renamed with suffix due to namespaced name conflict
|
||||
// Extension command gets renamed with suffix due to secondary conflict
|
||||
const deployExtension = commands.find(
|
||||
(cmd) => cmd.name === 'gcp:deploy1' && cmd.extensionName === 'gcp',
|
||||
(cmd) => cmd.name === 'gcp.deploy1' && cmd.extensionName === 'gcp',
|
||||
);
|
||||
expect(deployExtension).toBeDefined();
|
||||
expect(deployExtension?.description).toBe('Deploy to Google Cloud');
|
||||
expect(deployExtension?.description).toBe('[gcp] Deploy to Google Cloud');
|
||||
});
|
||||
|
||||
it('should handle multiple namespaced name conflicts with incrementing suffixes', async () => {
|
||||
// User has /deploy, /gcp:deploy, and /gcp:deploy1
|
||||
it('should handle multiple secondary conflicts with incrementing suffixes', async () => {
|
||||
// User has /deploy, /gcp.deploy, and /gcp.deploy1
|
||||
const userCommand1 = createMockCommand('deploy', CommandKind.FILE);
|
||||
const userCommand2 = createMockCommand('gcp:deploy', CommandKind.FILE);
|
||||
const userCommand3 = createMockCommand('gcp:deploy1', CommandKind.FILE);
|
||||
const userCommand2 = createMockCommand('gcp.deploy', CommandKind.FILE);
|
||||
const userCommand3 = createMockCommand('gcp.deploy1', CommandKind.FILE);
|
||||
|
||||
// Extension has a deploy command which resolves to /gcp:deploy
|
||||
// Extension has a deploy command
|
||||
const extensionCommand = {
|
||||
...createMockCommand('deploy', CommandKind.FILE, 'gcp'),
|
||||
...createMockCommand('deploy', CommandKind.FILE),
|
||||
extensionName: 'gcp',
|
||||
description: 'Deploy to Google Cloud',
|
||||
description: '[gcp] Deploy to Google Cloud',
|
||||
};
|
||||
|
||||
const mockLoader = new MockCommandLoader([
|
||||
@@ -348,19 +345,16 @@ describe('CommandService', () => {
|
||||
|
||||
// Extension command gets renamed with suffix 2 due to multiple conflicts
|
||||
const deployExtension = commands.find(
|
||||
(cmd) => cmd.name === 'gcp:deploy2' && cmd.extensionName === 'gcp',
|
||||
(cmd) => cmd.name === 'gcp.deploy2' && cmd.extensionName === 'gcp',
|
||||
);
|
||||
expect(deployExtension).toBeDefined();
|
||||
expect(deployExtension?.description).toBe('Deploy to Google Cloud');
|
||||
expect(deployExtension?.description).toBe('[gcp] Deploy to Google Cloud');
|
||||
});
|
||||
|
||||
it('should report extension namespaced name conflicts via getConflicts', async () => {
|
||||
const builtinCommand = createMockCommand(
|
||||
'firebase:deploy',
|
||||
CommandKind.BUILT_IN,
|
||||
);
|
||||
it('should report conflicts via getConflicts', async () => {
|
||||
const builtinCommand = createMockCommand('deploy', CommandKind.BUILT_IN);
|
||||
const extensionCommand = {
|
||||
...createMockCommand('deploy', CommandKind.FILE, 'firebase'),
|
||||
...createMockCommand('deploy', CommandKind.FILE),
|
||||
extensionName: 'firebase',
|
||||
};
|
||||
|
||||
@@ -378,29 +372,29 @@ describe('CommandService', () => {
|
||||
expect(conflicts).toHaveLength(1);
|
||||
|
||||
expect(conflicts[0]).toMatchObject({
|
||||
name: 'firebase:deploy',
|
||||
name: 'deploy',
|
||||
winner: builtinCommand,
|
||||
losers: [
|
||||
{
|
||||
renamedTo: 'firebase:deploy1',
|
||||
renamedTo: 'firebase.deploy',
|
||||
command: expect.objectContaining({
|
||||
name: 'deploy',
|
||||
namespace: 'firebase',
|
||||
extensionName: 'firebase',
|
||||
}),
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('should report extension vs extension namespaced name conflicts correctly', async () => {
|
||||
// Both extensions try to register 'firebase:deploy'
|
||||
it('should report extension vs extension conflicts correctly', async () => {
|
||||
// Both extensions try to register 'deploy'
|
||||
const extension1Command = {
|
||||
...createMockCommand('deploy', CommandKind.FILE, 'firebase'),
|
||||
...createMockCommand('deploy', CommandKind.FILE),
|
||||
extensionName: 'firebase',
|
||||
};
|
||||
const extension2Command = {
|
||||
...createMockCommand('deploy', CommandKind.FILE, 'firebase'),
|
||||
extensionName: 'firebase',
|
||||
...createMockCommand('deploy', CommandKind.FILE),
|
||||
extensionName: 'aws',
|
||||
};
|
||||
|
||||
const mockLoader = new MockCommandLoader([
|
||||
@@ -417,37 +411,32 @@ describe('CommandService', () => {
|
||||
expect(conflicts).toHaveLength(1);
|
||||
|
||||
expect(conflicts[0]).toMatchObject({
|
||||
name: 'firebase:deploy',
|
||||
name: 'deploy',
|
||||
winner: expect.objectContaining({
|
||||
name: 'firebase:deploy',
|
||||
name: 'deploy',
|
||||
extensionName: 'firebase',
|
||||
}),
|
||||
losers: [
|
||||
{
|
||||
renamedTo: 'firebase:deploy1',
|
||||
renamedTo: 'aws.deploy', // ext2 is 'aws' and it lost because it was second in the list
|
||||
command: expect.objectContaining({
|
||||
name: 'deploy',
|
||||
extensionName: 'firebase',
|
||||
extensionName: 'aws',
|
||||
}),
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it('should report multiple extension namespaced name conflicts for the same name', async () => {
|
||||
// Built-in command is 'firebase:deploy'
|
||||
const builtinCommand = createMockCommand(
|
||||
'firebase:deploy',
|
||||
CommandKind.BUILT_IN,
|
||||
);
|
||||
// Two extension commands from extension 'firebase' also try to be 'firebase:deploy'
|
||||
it('should report multiple conflicts for the same command name', async () => {
|
||||
const builtinCommand = createMockCommand('deploy', CommandKind.BUILT_IN);
|
||||
const ext1 = {
|
||||
...createMockCommand('deploy', CommandKind.FILE, 'firebase'),
|
||||
extensionName: 'firebase',
|
||||
...createMockCommand('deploy', CommandKind.FILE),
|
||||
extensionName: 'ext1',
|
||||
};
|
||||
const ext2 = {
|
||||
...createMockCommand('deploy', CommandKind.FILE, 'firebase'),
|
||||
extensionName: 'firebase',
|
||||
...createMockCommand('deploy', CommandKind.FILE),
|
||||
extensionName: 'ext2',
|
||||
};
|
||||
|
||||
const mockLoader = new MockCommandLoader([builtinCommand, ext1, ext2]);
|
||||
@@ -459,23 +448,17 @@ describe('CommandService', () => {
|
||||
|
||||
const conflicts = service.getConflicts();
|
||||
expect(conflicts).toHaveLength(1);
|
||||
expect(conflicts[0].name).toBe('firebase:deploy');
|
||||
expect(conflicts[0].name).toBe('deploy');
|
||||
expect(conflicts[0].losers).toHaveLength(2);
|
||||
expect(conflicts[0].losers).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
renamedTo: 'firebase:deploy1',
|
||||
command: expect.objectContaining({
|
||||
name: 'deploy',
|
||||
namespace: 'firebase',
|
||||
}),
|
||||
renamedTo: 'ext1.deploy',
|
||||
command: expect.objectContaining({ extensionName: 'ext1' }),
|
||||
}),
|
||||
expect.objectContaining({
|
||||
renamedTo: 'firebase:deploy2',
|
||||
command: expect.objectContaining({
|
||||
name: 'deploy',
|
||||
namespace: 'firebase',
|
||||
}),
|
||||
renamedTo: 'ext2.deploy',
|
||||
command: expect.objectContaining({ extensionName: 'ext2' }),
|
||||
}),
|
||||
]),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user