summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/cli/src/services/CommandService.test.ts14
-rw-r--r--packages/cli/src/services/CommandService.ts2
-rw-r--r--packages/cli/src/ui/commands/privacyCommand.test.ts38
-rw-r--r--packages/cli/src/ui/commands/privacyCommand.ts16
-rw-r--r--packages/cli/src/ui/commands/types.ts2
-rw-r--r--packages/cli/src/ui/hooks/slashCommandProcessor.ts10
6 files changed, 71 insertions, 11 deletions
diff --git a/packages/cli/src/services/CommandService.test.ts b/packages/cli/src/services/CommandService.test.ts
index a7528b58..1a62c904 100644
--- a/packages/cli/src/services/CommandService.test.ts
+++ b/packages/cli/src/services/CommandService.test.ts
@@ -12,6 +12,7 @@ import { helpCommand } from '../ui/commands/helpCommand.js';
import { clearCommand } from '../ui/commands/clearCommand.js';
import { authCommand } from '../ui/commands/authCommand.js';
import { themeCommand } from '../ui/commands/themeCommand.js';
+import { privacyCommand } from '../ui/commands/privacyCommand.js';
// Mock the command modules to isolate the service from the command implementations.
vi.mock('../ui/commands/memoryCommand.js', () => ({
@@ -29,6 +30,9 @@ vi.mock('../ui/commands/authCommand.js', () => ({
vi.mock('../ui/commands/themeCommand.js', () => ({
themeCommand: { name: 'theme', description: 'Mock Theme' },
}));
+vi.mock('../ui/commands/privacyCommand.js', () => ({
+ privacyCommand: { name: 'privacy', description: 'Mock Privacy' },
+}));
describe('CommandService', () => {
describe('when using default production loader', () => {
@@ -54,7 +58,7 @@ describe('CommandService', () => {
const tree = commandService.getCommands();
// Post-condition assertions
- expect(tree.length).toBe(5);
+ expect(tree.length).toBe(6);
const commandNames = tree.map((cmd) => cmd.name);
expect(commandNames).toContain('auth');
@@ -62,19 +66,20 @@ describe('CommandService', () => {
expect(commandNames).toContain('help');
expect(commandNames).toContain('clear');
expect(commandNames).toContain('theme');
+ expect(commandNames).toContain('privacy');
});
it('should overwrite any existing commands when called again', async () => {
// Load once
await commandService.loadCommands();
- expect(commandService.getCommands().length).toBe(5);
+ expect(commandService.getCommands().length).toBe(6);
// Load again
await commandService.loadCommands();
const tree = commandService.getCommands();
// Should not append, but overwrite
- expect(tree.length).toBe(5);
+ expect(tree.length).toBe(6);
});
});
@@ -86,12 +91,13 @@ describe('CommandService', () => {
await commandService.loadCommands();
const loadedTree = commandService.getCommands();
- expect(loadedTree.length).toBe(5);
+ expect(loadedTree.length).toBe(6);
expect(loadedTree).toEqual([
authCommand,
clearCommand,
helpCommand,
memoryCommand,
+ privacyCommand,
themeCommand,
]);
});
diff --git a/packages/cli/src/services/CommandService.ts b/packages/cli/src/services/CommandService.ts
index 97784e18..0e2a8acb 100644
--- a/packages/cli/src/services/CommandService.ts
+++ b/packages/cli/src/services/CommandService.ts
@@ -10,12 +10,14 @@ import { helpCommand } from '../ui/commands/helpCommand.js';
import { clearCommand } from '../ui/commands/clearCommand.js';
import { authCommand } from '../ui/commands/authCommand.js';
import { themeCommand } from '../ui/commands/themeCommand.js';
+import { privacyCommand } from '../ui/commands/privacyCommand.js';
const loadBuiltInCommands = async (): Promise<SlashCommand[]> => [
authCommand,
clearCommand,
helpCommand,
memoryCommand,
+ privacyCommand,
themeCommand,
];
diff --git a/packages/cli/src/ui/commands/privacyCommand.test.ts b/packages/cli/src/ui/commands/privacyCommand.test.ts
new file mode 100644
index 00000000..691e5be8
--- /dev/null
+++ b/packages/cli/src/ui/commands/privacyCommand.test.ts
@@ -0,0 +1,38 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { describe, it, expect, beforeEach } from 'vitest';
+import { privacyCommand } from './privacyCommand.js';
+import { type CommandContext } from './types.js';
+import { createMockCommandContext } from '../../test-utils/mockCommandContext.js';
+
+describe('privacyCommand', () => {
+ let mockContext: CommandContext;
+
+ beforeEach(() => {
+ mockContext = createMockCommandContext();
+ });
+
+ it('should return a dialog action to open the privacy dialog', () => {
+ // Ensure the command has an action to test.
+ if (!privacyCommand.action) {
+ throw new Error('The privacy command must have an action.');
+ }
+
+ const result = privacyCommand.action(mockContext, '');
+
+ // Assert that the action returns the correct object to trigger the privacy dialog.
+ expect(result).toEqual({
+ type: 'dialog',
+ dialog: 'privacy',
+ });
+ });
+
+ it('should have the correct name and description', () => {
+ expect(privacyCommand.name).toBe('privacy');
+ expect(privacyCommand.description).toBe('display the privacy notice');
+ });
+});
diff --git a/packages/cli/src/ui/commands/privacyCommand.ts b/packages/cli/src/ui/commands/privacyCommand.ts
new file mode 100644
index 00000000..f239158c
--- /dev/null
+++ b/packages/cli/src/ui/commands/privacyCommand.ts
@@ -0,0 +1,16 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { OpenDialogActionReturn, SlashCommand } from './types.js';
+
+export const privacyCommand: SlashCommand = {
+ name: 'privacy',
+ description: 'display the privacy notice',
+ action: (): OpenDialogActionReturn => ({
+ type: 'dialog',
+ dialog: 'privacy',
+ }),
+};
diff --git a/packages/cli/src/ui/commands/types.ts b/packages/cli/src/ui/commands/types.ts
index b35374a8..68b22543 100644
--- a/packages/cli/src/ui/commands/types.ts
+++ b/packages/cli/src/ui/commands/types.ts
@@ -66,7 +66,7 @@ export interface MessageActionReturn {
export interface OpenDialogActionReturn {
type: 'dialog';
// TODO: Add 'theme' | 'auth' | 'editor' | 'privacy' as migration happens.
- dialog: 'help' | 'auth' | 'theme';
+ dialog: 'help' | 'auth' | 'theme' | 'privacy';
}
export type SlashCommandActionReturn =
diff --git a/packages/cli/src/ui/hooks/slashCommandProcessor.ts b/packages/cli/src/ui/hooks/slashCommandProcessor.ts
index 3a071fab..6465a49d 100644
--- a/packages/cli/src/ui/hooks/slashCommandProcessor.ts
+++ b/packages/cli/src/ui/hooks/slashCommandProcessor.ts
@@ -248,11 +248,6 @@ export const useSlashCommandProcessor = (
action: (_mainCommand, _subCommand, _args) => openEditorDialog(),
},
{
- name: 'privacy',
- description: 'display the privacy notice',
- action: (_mainCommand, _subCommand, _args) => openPrivacyNotice(),
- },
- {
name: 'stats',
altName: 'usage',
description: 'check session stats. Usage: /stats [model|tools]',
@@ -1023,7 +1018,6 @@ export const useSlashCommandProcessor = (
}, [
addMessage,
openEditorDialog,
- openPrivacyNotice,
toggleCorgiMode,
savedChatTags,
config,
@@ -1125,6 +1119,9 @@ export const useSlashCommandProcessor = (
case 'theme':
openThemeDialog();
return { type: 'handled' };
+ case 'privacy':
+ openPrivacyNotice();
+ return { type: 'handled' };
default: {
const unhandled: never = result.dialog;
throw new Error(
@@ -1208,6 +1205,7 @@ export const useSlashCommandProcessor = (
commandContext,
addMessage,
openThemeDialog,
+ openPrivacyNotice,
],
);