From 13a6a9a690900a50287d344592bf02bdfb2586f1 Mon Sep 17 00:00:00 2001 From: DeWitt Clinton Date: Sat, 17 May 2025 21:57:27 -0700 Subject: [PATCH] Introduce a small easter egg. Woof. (#412) Also changes auto-completion and /help to skip over slash commands that don't contain a description to avoid spoiling the surprise. --- packages/cli/src/ui/App.tsx | 8 ++++++++ packages/cli/src/ui/components/Footer.tsx | 12 ++++++++++++ packages/cli/src/ui/components/Help.tsx | 18 ++++++++++-------- .../src/ui/hooks/slashCommandProcessor.test.ts | 3 +++ .../cli/src/ui/hooks/slashCommandProcessor.ts | 10 +++++++++- packages/cli/src/ui/hooks/useCompletion.ts | 1 + 6 files changed, 43 insertions(+), 9 deletions(-) diff --git a/packages/cli/src/ui/App.tsx b/packages/cli/src/ui/App.tsx index 70ece34f..707b8b9a 100644 --- a/packages/cli/src/ui/App.tsx +++ b/packages/cli/src/ui/App.tsx @@ -58,6 +58,12 @@ export const App = ({ const [showHelp, setShowHelp] = useState(false); const [themeError, setThemeError] = useState(null); const [footerHeight, setFooterHeight] = useState(0); + const [corgiMode, setCorgiMode] = useState(false); + + const toggleCorgiMode = useCallback(() => { + setCorgiMode((prev) => !prev); + }, []); + const { isThemeDialogOpen, openThemeDialog, @@ -124,6 +130,7 @@ export const App = ({ setDebugMessage, openThemeDialog, performMemoryRefresh, + toggleCorgiMode, ); const { streamingState, submitQuery, initError, pendingHistoryItem } = @@ -408,6 +415,7 @@ export const App = ({ debugMessage={debugMessage} cliVersion={cliVersion} geminiMdFileCount={geminiMdFileCount} + corgiMode={corgiMode} /> diff --git a/packages/cli/src/ui/components/Footer.tsx b/packages/cli/src/ui/components/Footer.tsx index a98c8760..3b3cac72 100644 --- a/packages/cli/src/ui/components/Footer.tsx +++ b/packages/cli/src/ui/components/Footer.tsx @@ -15,6 +15,7 @@ interface FooterProps { debugMessage: string; cliVersion: string; geminiMdFileCount: number; + corgiMode: boolean; } export const Footer: React.FC = ({ @@ -23,6 +24,7 @@ export const Footer: React.FC = ({ debugMessage, cliVersion, geminiMdFileCount, + corgiMode, }) => ( @@ -62,6 +64,16 @@ export const Footer: React.FC = ({ {config.getModel()} | CLI {cliVersion} + {corgiMode && ( + + | + + + + `) + + + )} ); diff --git a/packages/cli/src/ui/components/Help.tsx b/packages/cli/src/ui/components/Help.tsx index 3ca182be..adc49cec 100644 --- a/packages/cli/src/ui/components/Help.tsx +++ b/packages/cli/src/ui/components/Help.tsx @@ -28,15 +28,17 @@ export const Help: React.FC = ({ commands }) => ( Commands: - {commands.map((command: SlashCommand) => ( - - - {' '} - /{command.name} + {commands + .filter((command) => command.description) + .map((command: SlashCommand) => ( + + + {' '} + /{command.name} + + {command.description && ' - ' + command.description} - {command.description && ' - ' + command.description} - - ))} + ))} {' '} diff --git a/packages/cli/src/ui/hooks/slashCommandProcessor.test.ts b/packages/cli/src/ui/hooks/slashCommandProcessor.test.ts index 4055dfd3..f7f1bb5e 100644 --- a/packages/cli/src/ui/hooks/slashCommandProcessor.test.ts +++ b/packages/cli/src/ui/hooks/slashCommandProcessor.test.ts @@ -48,6 +48,7 @@ describe('useSlashCommandProcessor', () => { let mockOpenThemeDialog: ReturnType; let mockPerformMemoryRefresh: ReturnType; let mockConfig: Config; + let mockCorgiMode: ReturnType; beforeEach(() => { mockAddItem = vi.fn(); @@ -58,6 +59,7 @@ describe('useSlashCommandProcessor', () => { mockOpenThemeDialog = vi.fn(); mockPerformMemoryRefresh = vi.fn().mockResolvedValue(undefined); mockConfig = { getDebugMode: vi.fn(() => false) } as unknown as Config; + mockCorgiMode = vi.fn(); // Clear mocks for fsPromises if they were used directly or indirectly vi.mocked(fsPromises.readFile).mockClear(); @@ -89,6 +91,7 @@ describe('useSlashCommandProcessor', () => { mockOnDebugMessage, mockOpenThemeDialog, mockPerformMemoryRefresh, + mockCorgiMode, ), ); return result.current; diff --git a/packages/cli/src/ui/hooks/slashCommandProcessor.ts b/packages/cli/src/ui/hooks/slashCommandProcessor.ts index f489c648..095f4ad7 100644 --- a/packages/cli/src/ui/hooks/slashCommandProcessor.ts +++ b/packages/cli/src/ui/hooks/slashCommandProcessor.ts @@ -15,7 +15,7 @@ import { addMemoryEntry } from '../../config/memoryUtils.js'; export interface SlashCommand { name: string; altName?: string; - description: string; + description?: string; action: (mainCommand: string, subCommand?: string, args?: string) => void; } @@ -31,6 +31,7 @@ export const useSlashCommandProcessor = ( onDebugMessage: (message: string) => void, openThemeDialog: () => void, performMemoryRefresh: () => Promise, // Add performMemoryRefresh prop + toggleCorgiMode: () => void, ) => { const addMessage = useCallback( (message: Message) => { @@ -131,6 +132,12 @@ export const useSlashCommandProcessor = ( } }, }, + { + name: 'corgi', + action: (_mainCommand, _subCommand, _args) => { + toggleCorgiMode(); + }, + }, { name: 'quit', altName: 'exit', @@ -151,6 +158,7 @@ export const useSlashCommandProcessor = ( showMemoryAction, addMemoryAction, addMessage, + toggleCorgiMode, ], ); diff --git a/packages/cli/src/ui/hooks/useCompletion.ts b/packages/cli/src/ui/hooks/useCompletion.ts index 9c0c2db1..c707adef 100644 --- a/packages/cli/src/ui/hooks/useCompletion.ts +++ b/packages/cli/src/ui/hooks/useCompletion.ts @@ -142,6 +142,7 @@ export function useCompletion( (altNameMatch && cmd.altName && cmd.altName.length > 1) ); }) + .filter((cmd) => cmd.description) .map((cmd) => ({ label: cmd.name, // Always show the main name as label value: cmd.name, // Value should be the main command name for execution