summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/hooks
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src/ui/hooks')
-rw-r--r--packages/cli/src/ui/hooks/slashCommandProcessor.test.ts164
-rw-r--r--packages/cli/src/ui/hooks/slashCommandProcessor.ts76
2 files changed, 3 insertions, 237 deletions
diff --git a/packages/cli/src/ui/hooks/slashCommandProcessor.test.ts b/packages/cli/src/ui/hooks/slashCommandProcessor.test.ts
index 3a0428d9..2d7a8ffd 100644
--- a/packages/cli/src/ui/hooks/slashCommandProcessor.test.ts
+++ b/packages/cli/src/ui/hooks/slashCommandProcessor.test.ts
@@ -66,7 +66,7 @@ import {
} from 'vitest';
import open from 'open';
import { useSlashCommandProcessor } from './slashCommandProcessor.js';
-import { MessageType, SlashCommandProcessorResult } from '../types.js';
+import { SlashCommandProcessorResult } from '../types.js';
import { Config, GeminiClient } from '@google/gemini-cli-core';
import { useSessionStats } from '../contexts/SessionContext.js';
import { LoadedSettings } from '../../config/settings.js';
@@ -176,7 +176,7 @@ describe('useSlashCommandProcessor', () => {
process.env = { ...globalThis.process.env };
});
- const getProcessorHook = (showToolDescriptions: boolean = false) => {
+ const getProcessorHook = () => {
const settings = {
merged: {
contextFileName: 'GEMINI.md',
@@ -197,15 +197,13 @@ describe('useSlashCommandProcessor', () => {
mockOpenAuthDialog,
mockOpenEditorDialog,
mockCorgiMode,
- showToolDescriptions,
mockSetQuittingMessages,
vi.fn(), // mockOpenPrivacyNotice
),
);
};
- const getProcessor = (showToolDescriptions: boolean = false) =>
- getProcessorHook(showToolDescriptions).result.current;
+ const getProcessor = () => getProcessorHook().result.current;
describe('Other commands', () => {
it('/editor should open editor dialog and return handled', async () => {
@@ -595,160 +593,4 @@ describe('useSlashCommandProcessor', () => {
},
);
});
-
- describe('Unknown command', () => {
- it('should show an error and return handled for a general unknown command', async () => {
- const { handleSlashCommand } = getProcessor();
- let commandResult: SlashCommandProcessorResult | false = false;
- await act(async () => {
- commandResult = await handleSlashCommand('/unknowncommand');
- });
- expect(mockAddItem).toHaveBeenNthCalledWith(
- 2,
- expect.objectContaining({
- type: MessageType.ERROR,
- text: 'Unknown command: /unknowncommand',
- }),
- expect.any(Number),
- );
- expect(commandResult).toEqual({ type: 'handled' });
- });
- });
-
- describe('/tools command', () => {
- it('should show an error if tool registry is not available', async () => {
- mockConfig = {
- ...mockConfig,
- getToolRegistry: vi.fn().mockResolvedValue(undefined),
- } as unknown as Config;
- const { handleSlashCommand } = getProcessor();
- let commandResult: SlashCommandProcessorResult | false = false;
- await act(async () => {
- commandResult = await handleSlashCommand('/tools');
- });
-
- expect(mockAddItem).toHaveBeenNthCalledWith(
- 2,
- expect.objectContaining({
- type: MessageType.ERROR,
- text: 'Could not retrieve tools.',
- }),
- expect.any(Number),
- );
- expect(commandResult).toEqual({ type: 'handled' });
- });
-
- it('should show an error if getAllTools returns undefined', async () => {
- mockConfig = {
- ...mockConfig,
- getToolRegistry: vi.fn().mockResolvedValue({
- getAllTools: vi.fn().mockReturnValue(undefined),
- }),
- } as unknown as Config;
- const { handleSlashCommand } = getProcessor();
- let commandResult: SlashCommandProcessorResult | false = false;
- await act(async () => {
- commandResult = await handleSlashCommand('/tools');
- });
-
- expect(mockAddItem).toHaveBeenNthCalledWith(
- 2,
- expect.objectContaining({
- type: MessageType.ERROR,
- text: 'Could not retrieve tools.',
- }),
- expect.any(Number),
- );
- expect(commandResult).toEqual({ type: 'handled' });
- });
-
- it('should display only Gemini CLI tools (filtering out MCP tools)', async () => {
- // Create mock tools - some with serverName property (MCP tools) and some without (Gemini CLI tools)
- const mockTools = [
- { name: 'tool1', displayName: 'Tool1' },
- { name: 'tool2', displayName: 'Tool2' },
- { name: 'mcp_tool1', serverName: 'mcp-server1' },
- { name: 'mcp_tool2', serverName: 'mcp-server1' },
- ];
-
- mockConfig = {
- ...mockConfig,
- getToolRegistry: vi.fn().mockResolvedValue({
- getAllTools: vi.fn().mockReturnValue(mockTools),
- }),
- } as unknown as Config;
-
- const { handleSlashCommand } = getProcessor();
- let commandResult: SlashCommandProcessorResult | false = false;
- await act(async () => {
- commandResult = await handleSlashCommand('/tools');
- });
-
- // Should only show tool1 and tool2, not the MCP tools
- const message = mockAddItem.mock.calls[1][0].text;
- expect(message).toContain('Tool1');
- expect(message).toContain('Tool2');
- expect(commandResult).toEqual({ type: 'handled' });
- });
-
- it('should display a message when no Gemini CLI tools are available', async () => {
- // Only MCP tools available
- const mockTools = [
- { name: 'mcp_tool1', serverName: 'mcp-server1' },
- { name: 'mcp_tool2', serverName: 'mcp-server1' },
- ];
-
- mockConfig = {
- ...mockConfig,
- getToolRegistry: vi.fn().mockResolvedValue({
- getAllTools: vi.fn().mockReturnValue(mockTools),
- }),
- } as unknown as Config;
-
- const { handleSlashCommand } = getProcessor();
- let commandResult: SlashCommandProcessorResult | false = false;
- await act(async () => {
- commandResult = await handleSlashCommand('/tools');
- });
-
- const message = mockAddItem.mock.calls[1][0].text;
- expect(message).toContain('No tools available');
- expect(commandResult).toEqual({ type: 'handled' });
- });
-
- it('should display tool descriptions when /tools desc is used', async () => {
- const mockTools = [
- {
- name: 'tool1',
- displayName: 'Tool1',
- description: 'Description for Tool1',
- },
- {
- name: 'tool2',
- displayName: 'Tool2',
- description: 'Description for Tool2',
- },
- ];
-
- mockConfig = {
- ...mockConfig,
- getToolRegistry: vi.fn().mockResolvedValue({
- getAllTools: vi.fn().mockReturnValue(mockTools),
- }),
- } as unknown as Config;
-
- const { handleSlashCommand } = getProcessor();
- let commandResult: SlashCommandProcessorResult | false = false;
- await act(async () => {
- commandResult = await handleSlashCommand('/tools desc');
- });
-
- const message = mockAddItem.mock.calls[1][0].text;
- expect(message).toContain('Tool1');
- expect(message).toContain('Description for Tool1');
- expect(message).toContain('Tool2');
- expect(message).toContain('Description for Tool2');
- expect(commandResult).toEqual({ type: 'handled' });
- });
- });
});
diff --git a/packages/cli/src/ui/hooks/slashCommandProcessor.ts b/packages/cli/src/ui/hooks/slashCommandProcessor.ts
index 8fa3f880..24758842 100644
--- a/packages/cli/src/ui/hooks/slashCommandProcessor.ts
+++ b/packages/cli/src/ui/hooks/slashCommandProcessor.ts
@@ -66,7 +66,6 @@ export const useSlashCommandProcessor = (
openAuthDialog: () => void,
openEditorDialog: () => void,
toggleCorgiMode: () => void,
- showToolDescriptions: boolean = false,
setQuittingMessages: (message: HistoryItem[]) => void,
openPrivacyNotice: () => void,
) => {
@@ -206,80 +205,6 @@ export const useSlashCommandProcessor = (
action: (_mainCommand, _subCommand, _args) => openEditorDialog(),
},
{
- name: 'tools',
- description: 'list available Gemini CLI tools',
- action: async (_mainCommand, _subCommand, _args) => {
- // Check if the _subCommand includes a specific flag to control description visibility
- let useShowDescriptions = showToolDescriptions;
- if (_subCommand === 'desc' || _subCommand === 'descriptions') {
- useShowDescriptions = true;
- } else if (
- _subCommand === 'nodesc' ||
- _subCommand === 'nodescriptions'
- ) {
- useShowDescriptions = false;
- } else if (_args === 'desc' || _args === 'descriptions') {
- useShowDescriptions = true;
- } else if (_args === 'nodesc' || _args === 'nodescriptions') {
- useShowDescriptions = false;
- }
-
- const toolRegistry = await config?.getToolRegistry();
- const tools = toolRegistry?.getAllTools();
- if (!tools) {
- addMessage({
- type: MessageType.ERROR,
- content: 'Could not retrieve tools.',
- timestamp: new Date(),
- });
- return;
- }
-
- // Filter out MCP tools by checking if they have a serverName property
- const geminiTools = tools.filter((tool) => !('serverName' in tool));
-
- let message = 'Available Gemini CLI tools:\n\n';
-
- if (geminiTools.length > 0) {
- geminiTools.forEach((tool) => {
- if (useShowDescriptions && tool.description) {
- // Format tool name in cyan using simple ANSI cyan color
- message += ` - \u001b[36m${tool.displayName} (${tool.name})\u001b[0m:\n`;
-
- // Apply green color to the description text
- const greenColor = '\u001b[32m';
- const resetColor = '\u001b[0m';
-
- // Handle multi-line descriptions by properly indenting and preserving formatting
- const descLines = tool.description.trim().split('\n');
-
- // If there are multiple lines, add proper indentation for each line
- if (descLines) {
- for (const descLine of descLines) {
- message += ` ${greenColor}${descLine}${resetColor}\n`;
- }
- }
- } else {
- // Use cyan color for the tool name even when not showing descriptions
- message += ` - \u001b[36m${tool.displayName}\u001b[0m\n`;
- }
- });
- } else {
- message += ' No tools available\n';
- }
- message += '\n';
-
- // Make sure to reset any ANSI formatting at the end to prevent it from affecting the terminal
- message += '\u001b[0m';
-
- addMessage({
- type: MessageType.INFO,
- content: message,
- timestamp: new Date(),
- });
- },
- },
- {
name: 'corgi',
action: (_mainCommand, _subCommand, _args) => {
toggleCorgiMode();
@@ -503,7 +428,6 @@ export const useSlashCommandProcessor = (
openEditorDialog,
toggleCorgiMode,
config,
- showToolDescriptions,
session,
gitService,
loadHistory,