1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
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(),
);
},
},
],
};
|