summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/commands/directoryCommand.tsx
diff options
context:
space:
mode:
authorYuki Okita <[email protected]>2025-08-01 04:02:08 +0900
committerGitHub <[email protected]>2025-07-31 19:02:08 +0000
commitf9a05401c1d2d93d1251d3ebf2c079ee1f4ba8df (patch)
tree870f1cf4b31ed974ca180bb7068388ba2dfc3788 /packages/cli/src/ui/commands/directoryCommand.tsx
parent9a6422f331294ea2f56d67599ed142d09cc33320 (diff)
feat: Multi-Directory Workspace Support (part2: add "directory" command) (#5241)
Diffstat (limited to 'packages/cli/src/ui/commands/directoryCommand.tsx')
-rw-r--r--packages/cli/src/ui/commands/directoryCommand.tsx150
1 files changed, 150 insertions, 0 deletions
diff --git a/packages/cli/src/ui/commands/directoryCommand.tsx b/packages/cli/src/ui/commands/directoryCommand.tsx
new file mode 100644
index 00000000..18f7e78f
--- /dev/null
+++ b/packages/cli/src/ui/commands/directoryCommand.tsx
@@ -0,0 +1,150 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { SlashCommand, CommandContext, CommandKind } from './types.js';
+import { MessageType } from '../types.js';
+import * as os from 'os';
+import * as path from 'path';
+
+export function expandHomeDir(p: string): string {
+ if (!p) {
+ return '';
+ }
+ let expandedPath = p;
+ if (p.toLowerCase().startsWith('%userprofile%')) {
+ expandedPath = os.homedir() + p.substring('%userprofile%'.length);
+ } else if (p.startsWith('~')) {
+ expandedPath = os.homedir() + p.substring(1);
+ }
+ return path.normalize(expandedPath);
+}
+
+export const directoryCommand: SlashCommand = {
+ name: 'directory',
+ altNames: ['dir'],
+ description: 'Manage workspace directories',
+ kind: CommandKind.BUILT_IN,
+ subCommands: [
+ {
+ name: 'add',
+ description:
+ 'Add directories to the workspace. Use comma to separate multiple paths',
+ kind: CommandKind.BUILT_IN,
+ action: async (context: CommandContext, args: string) => {
+ const {
+ ui: { addItem },
+ services: { config },
+ } = context;
+ const [...rest] = args.split(' ');
+
+ if (!config) {
+ addItem(
+ {
+ type: MessageType.ERROR,
+ text: 'Configuration is not available.',
+ },
+ Date.now(),
+ );
+ return;
+ }
+
+ const workspaceContext = config.getWorkspaceContext();
+
+ const pathsToAdd = rest
+ .join(' ')
+ .split(',')
+ .filter((p) => p);
+ if (pathsToAdd.length === 0) {
+ addItem(
+ {
+ type: MessageType.ERROR,
+ text: 'Please provide at least one path to add.',
+ },
+ Date.now(),
+ );
+ return;
+ }
+
+ if (config.isRestrictiveSandbox()) {
+ return {
+ type: 'message' as const,
+ messageType: 'error' as const,
+ content:
+ 'The /directory add command is not supported in restrictive sandbox profiles. Please use --include-directories when starting the session instead.',
+ };
+ }
+
+ const added: string[] = [];
+ const errors: string[] = [];
+
+ for (const pathToAdd of pathsToAdd) {
+ try {
+ workspaceContext.addDirectory(expandHomeDir(pathToAdd.trim()));
+ added.push(pathToAdd.trim());
+ } catch (e) {
+ const error = e as Error;
+ errors.push(`Error adding '${pathToAdd.trim()}': ${error.message}`);
+ }
+ }
+
+ if (added.length > 0) {
+ const gemini = config.getGeminiClient();
+ if (gemini) {
+ await gemini.addDirectoryContext();
+ }
+ addItem(
+ {
+ type: MessageType.INFO,
+ text: `Successfully added directories:\n- ${added.join('\n- ')}`,
+ },
+ Date.now(),
+ );
+ }
+
+ if (errors.length > 0) {
+ addItem(
+ {
+ type: MessageType.ERROR,
+ text: errors.join('\n'),
+ },
+ Date.now(),
+ );
+ }
+ },
+ },
+ {
+ name: 'show',
+ description: 'Show all directories in the workspace',
+ kind: CommandKind.BUILT_IN,
+ action: async (context: CommandContext) => {
+ const {
+ ui: { addItem },
+ services: { config },
+ } = context;
+ if (!config) {
+ addItem(
+ {
+ type: MessageType.ERROR,
+ text: 'Configuration is not available.',
+ },
+ Date.now(),
+ );
+ return;
+ }
+ const workspaceContext = config.getWorkspaceContext();
+ const directories = workspaceContext.getDirectories();
+ const directoryList = directories.map((dir) => `- ${dir}`).join('\n');
+ addItem(
+ {
+ type: MessageType.INFO,
+ text: `Current workspace directories:\n${directoryList}`,
+ },
+ Date.now(),
+ );
+ },
+ },
+ ],
+};