@google/gemini-cli 0.18.0-preview.1 → 0.19.0-nightly.20251122.42c2e1b21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/google-gemini-cli-0.19.0-nightly.20251120.8e531dc02.tgz +0 -0
- package/dist/index.js +8 -6
- package/dist/index.js.map +1 -1
- package/dist/package.json +3 -3
- package/dist/src/commands/extensions/examples/mcp-server/package.json +1 -1
- package/dist/src/config/auth.js +4 -0
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/auth.test.js +61 -37
- package/dist/src/config/auth.test.js.map +1 -1
- package/dist/src/config/config.integration.test.js +81 -198
- package/dist/src/config/config.integration.test.js.map +1 -1
- package/dist/src/config/config.js +2 -6
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +196 -299
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/extension.test.js +109 -133
- package/dist/src/config/extension.test.js.map +1 -1
- package/dist/src/config/extensions/consent.test.js +152 -0
- package/dist/src/config/extensions/consent.test.js.map +1 -0
- package/dist/src/config/extensions/extensionEnablement.test.js +82 -15
- package/dist/src/config/extensions/extensionEnablement.test.js.map +1 -1
- package/dist/src/config/extensions/extensionSettings.test.js +105 -1
- package/dist/src/config/extensions/extensionSettings.test.js.map +1 -1
- package/dist/src/config/extensions/github.d.ts +1 -0
- package/dist/src/config/extensions/github.js +1 -1
- package/dist/src/config/extensions/github.js.map +1 -1
- package/dist/src/config/extensions/github.test.js +197 -318
- package/dist/src/config/extensions/github.test.js.map +1 -1
- package/dist/src/config/extensions/storage.test.d.ts +6 -0
- package/dist/src/config/extensions/storage.test.js +64 -0
- package/dist/src/config/extensions/storage.test.js.map +1 -0
- package/dist/src/config/extensions/update.test.js +154 -263
- package/dist/src/config/extensions/update.test.js.map +1 -1
- package/dist/src/config/extensions/variables.test.js +87 -1
- package/dist/src/config/extensions/variables.test.js.map +1 -1
- package/dist/src/config/sandboxConfig.d.ts +1 -1
- package/dist/src/config/sandboxConfig.js.map +1 -1
- package/dist/src/config/sandboxConfig.test.d.ts +6 -0
- package/dist/src/config/sandboxConfig.test.js +178 -0
- package/dist/src/config/sandboxConfig.test.js.map +1 -0
- package/dist/src/config/settingPaths.test.d.ts +6 -0
- package/dist/src/config/settingPaths.test.js +22 -0
- package/dist/src/config/settingPaths.test.js.map +1 -0
- package/dist/src/config/settings.test.js +164 -226
- package/dist/src/config/settings.test.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +10 -10
- package/dist/src/config/settingsSchema.js +10 -10
- package/dist/src/config/settingsSchema.js.map +1 -1
- package/dist/src/config/settingsSchema.test.js +0 -6
- package/dist/src/config/settingsSchema.test.js.map +1 -1
- package/dist/src/gemini.d.ts +1 -1
- package/dist/src/gemini.js +5 -7
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.js +18 -21
- package/dist/src/gemini.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.js +1 -1
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.test.js +0 -22
- package/dist/src/services/BuiltinCommandLoader.test.js.map +1 -1
- package/dist/src/test-utils/mockCommandContext.js +1 -1
- package/dist/src/test-utils/render.js +1 -1
- package/dist/src/test-utils/render.js.map +1 -1
- package/dist/src/ui/AppContainer.js +13 -11
- package/dist/src/ui/AppContainer.js.map +1 -1
- package/dist/src/ui/AppContainer.test.js +10 -16
- package/dist/src/ui/AppContainer.test.js.map +1 -1
- package/dist/src/ui/auth/AuthDialog.js +17 -10
- package/dist/src/ui/auth/AuthDialog.js.map +1 -1
- package/dist/src/ui/auth/AuthDialog.test.js +5 -2
- package/dist/src/ui/auth/AuthDialog.test.js.map +1 -1
- package/dist/src/ui/components/AppHeader.js +3 -17
- package/dist/src/ui/components/AppHeader.js.map +1 -1
- package/dist/src/ui/components/AppHeader.test.js +10 -4
- package/dist/src/ui/components/AppHeader.test.js.map +1 -1
- package/dist/src/ui/components/DebugProfiler.js +1 -1
- package/dist/src/ui/components/DebugProfiler.js.map +1 -1
- package/dist/src/ui/components/DialogManager.js +6 -1
- package/dist/src/ui/components/DialogManager.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.js +1 -1
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/LoadingIndicator.js +6 -1
- package/dist/src/ui/components/LoadingIndicator.js.map +1 -1
- package/dist/src/ui/components/ModelDialog.test.js +1 -1
- package/dist/src/ui/components/ModelDialog.test.js.map +1 -1
- package/dist/src/ui/components/SessionBrowser.d.ts +98 -0
- package/dist/src/ui/components/SessionBrowser.js +457 -0
- package/dist/src/ui/components/SessionBrowser.js.map +1 -0
- package/dist/src/ui/components/SessionBrowser.test.d.ts +6 -0
- package/dist/src/ui/components/SessionBrowser.test.js +245 -0
- package/dist/src/ui/components/SessionBrowser.test.js.map +1 -0
- package/dist/src/ui/components/messages/ShellToolMessage.js +2 -2
- package/dist/src/ui/components/messages/ShellToolMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolMessage.d.ts +5 -0
- package/dist/src/ui/components/messages/ToolMessage.js +32 -3
- package/dist/src/ui/components/messages/ToolMessage.js.map +1 -1
- package/dist/src/ui/components/shared/text-buffer.js +20 -4
- package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
- package/dist/src/ui/components/shared/text-buffer.test.js +20 -0
- package/dist/src/ui/components/shared/text-buffer.test.js.map +1 -1
- package/dist/src/ui/constants.d.ts +1 -0
- package/dist/src/ui/constants.js +1 -0
- package/dist/src/ui/constants.js.map +1 -1
- package/dist/src/ui/hooks/shellCommandProcessor.d.ts +1 -0
- package/dist/src/ui/hooks/shellCommandProcessor.js +3 -1
- package/dist/src/ui/hooks/shellCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useAlternateBuffer.js +1 -1
- package/dist/src/ui/hooks/useAlternateBuffer.js.map +1 -1
- package/dist/src/ui/hooks/useBanner.d.ts +14 -0
- package/dist/src/ui/hooks/useBanner.js +48 -0
- package/dist/src/ui/hooks/useBanner.js.map +1 -0
- package/dist/src/ui/hooks/useBanner.test.d.ts +6 -0
- package/dist/src/ui/hooks/useBanner.test.js +92 -0
- package/dist/src/ui/hooks/useBanner.test.js.map +1 -0
- package/dist/src/ui/hooks/useBracketedPaste.js +3 -5
- package/dist/src/ui/hooks/useBracketedPaste.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.d.ts +1 -0
- package/dist/src/ui/hooks/useGeminiStream.js +6 -4
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.test.js +1 -1
- package/dist/src/ui/hooks/useGeminiStream.test.js.map +1 -1
- package/dist/src/ui/hooks/useInactivityTimer.d.ts +14 -0
- package/dist/src/ui/hooks/useInactivityTimer.js +30 -0
- package/dist/src/ui/hooks/useInactivityTimer.js.map +1 -0
- package/dist/src/ui/hooks/useLoadingIndicator.d.ts +1 -1
- package/dist/src/ui/hooks/useLoadingIndicator.js +2 -2
- package/dist/src/ui/hooks/useLoadingIndicator.js.map +1 -1
- package/dist/src/ui/hooks/useLoadingIndicator.test.js +16 -5
- package/dist/src/ui/hooks/useLoadingIndicator.test.js.map +1 -1
- package/dist/src/ui/hooks/usePhraseCycler.d.ts +4 -1
- package/dist/src/ui/hooks/usePhraseCycler.js +52 -43
- package/dist/src/ui/hooks/usePhraseCycler.js.map +1 -1
- package/dist/src/ui/hooks/usePhraseCycler.test.js +52 -3
- package/dist/src/ui/hooks/usePhraseCycler.test.js.map +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.d.ts +2 -1
- package/dist/src/ui/hooks/useReactToolScheduler.js +3 -0
- package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
- package/dist/src/ui/hooks/useSessionBrowser.d.ts +18 -1
- package/dist/src/ui/hooks/useSessionBrowser.js +59 -0
- package/dist/src/ui/hooks/useSessionBrowser.js.map +1 -1
- package/dist/src/ui/hooks/useSessionBrowser.test.js +154 -526
- package/dist/src/ui/hooks/useSessionBrowser.test.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.test.js +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js +1 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.test.d.ts +6 -0
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.test.js +121 -0
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.test.js.map +1 -0
- package/dist/src/ui/privacy/CloudPaidPrivacyNotice.test.d.ts +6 -0
- package/dist/src/ui/privacy/CloudPaidPrivacyNotice.test.js +34 -0
- package/dist/src/ui/privacy/CloudPaidPrivacyNotice.test.js.map +1 -0
- package/dist/src/ui/privacy/GeminiPrivacyNotice.test.d.ts +6 -0
- package/dist/src/ui/privacy/GeminiPrivacyNotice.test.js +34 -0
- package/dist/src/ui/privacy/GeminiPrivacyNotice.test.js.map +1 -0
- package/dist/src/ui/privacy/PrivacyNotice.test.d.ts +6 -0
- package/dist/src/ui/privacy/PrivacyNotice.test.js +62 -0
- package/dist/src/ui/privacy/PrivacyNotice.test.js.map +1 -0
- package/dist/src/ui/types.js +1 -1
- package/dist/src/ui/utils/bracketedPaste.d.ts +7 -0
- package/dist/src/ui/utils/bracketedPaste.js +15 -0
- package/dist/src/ui/utils/bracketedPaste.js.map +1 -0
- package/dist/src/ui/utils/kittyProtocolDetector.js +3 -4
- package/dist/src/ui/utils/kittyProtocolDetector.js.map +1 -1
- package/dist/src/ui/utils/mouse.d.ts +2 -2
- package/dist/src/ui/utils/mouse.js +2 -11
- package/dist/src/ui/utils/mouse.js.map +1 -1
- package/dist/src/utils/persistentState.d.ts +1 -1
- package/dist/src/utils/sessionCleanup.test.js +38 -0
- package/dist/src/utils/sessionCleanup.test.js.map +1 -1
- package/dist/src/utils/sessionUtils.d.ts +49 -4
- package/dist/src/utils/sessionUtils.js +100 -25
- package/dist/src/utils/sessionUtils.js.map +1 -1
- package/dist/src/utils/sessionUtils.test.js +46 -3
- package/dist/src/utils/sessionUtils.test.js.map +1 -1
- package/dist/src/utils/sessions.js +4 -1
- package/dist/src/utils/sessions.js.map +1 -1
- package/dist/src/utils/sessions.test.js +42 -0
- package/dist/src/utils/sessions.test.js.map +1 -1
- package/dist/src/zed-integration/connection.test.d.ts +6 -0
- package/dist/src/zed-integration/connection.test.js +175 -0
- package/dist/src/zed-integration/connection.test.js.map +1 -0
- package/dist/src/zed-integration/fileSystemService.test.d.ts +6 -0
- package/dist/src/zed-integration/fileSystemService.test.js +98 -0
- package/dist/src/zed-integration/fileSystemService.test.js.map +1 -0
- package/dist/src/zed-integration/schema.d.ts +30 -30
- package/dist/src/zed-integration/zedIntegration.d.ts +31 -1
- package/dist/src/zed-integration/zedIntegration.js +5 -2
- package/dist/src/zed-integration/zedIntegration.js.map +1 -1
- package/dist/src/zed-integration/zedIntegration.test.d.ts +6 -0
- package/dist/src/zed-integration/zedIntegration.test.js +619 -0
- package/dist/src/zed-integration/zedIntegration.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/dist/google-gemini-cli-0.18.0-preview.0.tgz +0 -0
- package/dist/src/utils/stdio.d.ts +0 -32
- package/dist/src/utils/stdio.js +0 -85
- package/dist/src/utils/stdio.js.map +0 -1
- package/dist/src/utils/stdio.test.js +0 -47
- package/dist/src/utils/stdio.test.js.map +0 -1
- /package/dist/src/{utils/stdio.test.d.ts → config/extensions/consent.test.d.ts} +0 -0
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
7
7
|
import * as os from 'node:os';
|
|
8
8
|
import * as path from 'node:path';
|
|
9
|
-
import { DEFAULT_FILE_FILTERING_OPTIONS,
|
|
9
|
+
import { DEFAULT_FILE_FILTERING_OPTIONS, OutputFormat, SHELL_TOOL_NAME, WRITE_FILE_TOOL_NAME, EDIT_TOOL_NAME, debugLogger, } from '@google/gemini-cli-core';
|
|
10
10
|
import { loadCliConfig, parseArguments } from './config.js';
|
|
11
11
|
import * as ServerConfig from '@google/gemini-cli-core';
|
|
12
12
|
import { isWorkspaceTrusted } from './trustedFolders.js';
|
|
@@ -111,241 +111,223 @@ afterEach(() => {
|
|
|
111
111
|
}
|
|
112
112
|
});
|
|
113
113
|
describe('parseArguments', () => {
|
|
114
|
-
it(
|
|
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
|
-
it('should throw an error when using short flags -p and -i together', async () => {
|
|
141
|
-
process.argv = [
|
|
142
|
-
'node',
|
|
143
|
-
'script.js',
|
|
144
|
-
'-p',
|
|
145
|
-
'test prompt',
|
|
146
|
-
'-i',
|
|
147
|
-
'interactive prompt',
|
|
148
|
-
];
|
|
114
|
+
it.each([
|
|
115
|
+
{
|
|
116
|
+
description: 'long flags',
|
|
117
|
+
argv: [
|
|
118
|
+
'node',
|
|
119
|
+
'script.js',
|
|
120
|
+
'--prompt',
|
|
121
|
+
'test prompt',
|
|
122
|
+
'--prompt-interactive',
|
|
123
|
+
'interactive prompt',
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
description: 'short flags',
|
|
128
|
+
argv: [
|
|
129
|
+
'node',
|
|
130
|
+
'script.js',
|
|
131
|
+
'-p',
|
|
132
|
+
'test prompt',
|
|
133
|
+
'-i',
|
|
134
|
+
'interactive prompt',
|
|
135
|
+
],
|
|
136
|
+
},
|
|
137
|
+
])('should throw an error when using conflicting prompt flags ($description)', async ({ argv }) => {
|
|
138
|
+
process.argv = argv;
|
|
149
139
|
const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => {
|
|
150
140
|
throw new Error('process.exit called');
|
|
151
141
|
});
|
|
152
142
|
const mockConsoleError = vi
|
|
153
143
|
.spyOn(console, 'error')
|
|
154
144
|
.mockImplementation(() => { });
|
|
155
|
-
const debugErrorSpy = vi
|
|
156
|
-
.spyOn(debugLogger, 'error')
|
|
157
|
-
.mockImplementation(() => { });
|
|
158
145
|
await expect(parseArguments({})).rejects.toThrow('process.exit called');
|
|
159
|
-
expect(
|
|
160
|
-
expect(mockConsoleError).toHaveBeenCalled();
|
|
146
|
+
expect(mockConsoleError).toHaveBeenCalledWith(expect.stringContaining('Cannot use both --prompt (-p) and --prompt-interactive (-i) together'));
|
|
161
147
|
mockExit.mockRestore();
|
|
162
148
|
mockConsoleError.mockRestore();
|
|
163
|
-
debugErrorSpy.mockRestore();
|
|
164
|
-
});
|
|
165
|
-
it('should allow --prompt without --prompt-interactive', async () => {
|
|
166
|
-
process.argv = ['node', 'script.js', '--prompt', 'test prompt'];
|
|
167
|
-
const argv = await parseArguments({});
|
|
168
|
-
expect(argv.prompt).toBe('test prompt');
|
|
169
|
-
expect(argv.promptInteractive).toBeUndefined();
|
|
170
|
-
});
|
|
171
|
-
it('should allow --prompt-interactive without --prompt', async () => {
|
|
172
|
-
process.argv = [
|
|
173
|
-
'node',
|
|
174
|
-
'script.js',
|
|
175
|
-
'--prompt-interactive',
|
|
176
|
-
'interactive prompt',
|
|
177
|
-
];
|
|
178
|
-
const argv = await parseArguments({});
|
|
179
|
-
expect(argv.promptInteractive).toBe('interactive prompt');
|
|
180
|
-
expect(argv.prompt).toBeUndefined();
|
|
181
|
-
});
|
|
182
|
-
it('should allow -i flag as alias for --prompt-interactive', async () => {
|
|
183
|
-
process.argv = ['node', 'script.js', '-i', 'interactive prompt'];
|
|
184
|
-
const argv = await parseArguments({});
|
|
185
|
-
expect(argv.promptInteractive).toBe('interactive prompt');
|
|
186
|
-
expect(argv.prompt).toBeUndefined();
|
|
187
|
-
});
|
|
188
|
-
it('should convert positional query argument to prompt by default', async () => {
|
|
189
|
-
process.argv = ['node', 'script.js', 'Hi Gemini'];
|
|
190
|
-
const argv = await parseArguments({});
|
|
191
|
-
expect(argv.query).toBe('Hi Gemini');
|
|
192
|
-
expect(argv.prompt).toBe('Hi Gemini');
|
|
193
|
-
expect(argv.promptInteractive).toBeUndefined();
|
|
194
|
-
});
|
|
195
|
-
it('should map @path to prompt (one-shot) when it starts with @', async () => {
|
|
196
|
-
process.argv = ['node', 'script.js', '@path ./file.md'];
|
|
197
|
-
const argv = await parseArguments({});
|
|
198
|
-
expect(argv.query).toBe('@path ./file.md');
|
|
199
|
-
expect(argv.prompt).toBe('@path ./file.md');
|
|
200
|
-
expect(argv.promptInteractive).toBeUndefined();
|
|
201
149
|
});
|
|
202
|
-
it(
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
'node',
|
|
206
|
-
'
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
'--
|
|
210
|
-
'
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
150
|
+
it.each([
|
|
151
|
+
{
|
|
152
|
+
description: 'should allow --prompt without --prompt-interactive',
|
|
153
|
+
argv: ['node', 'script.js', '--prompt', 'test prompt'],
|
|
154
|
+
expected: { prompt: 'test prompt', promptInteractive: undefined },
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
description: 'should allow --prompt-interactive without --prompt',
|
|
158
|
+
argv: ['node', 'script.js', '--prompt-interactive', 'interactive prompt'],
|
|
159
|
+
expected: { prompt: undefined, promptInteractive: 'interactive prompt' },
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
description: 'should allow -i flag as alias for --prompt-interactive',
|
|
163
|
+
argv: ['node', 'script.js', '-i', 'interactive prompt'],
|
|
164
|
+
expected: { prompt: undefined, promptInteractive: 'interactive prompt' },
|
|
165
|
+
},
|
|
166
|
+
])('$description', async ({ argv, expected }) => {
|
|
167
|
+
process.argv = argv;
|
|
168
|
+
const parsedArgs = await parseArguments({});
|
|
169
|
+
expect(parsedArgs.prompt).toBe(expected.prompt);
|
|
170
|
+
expect(parsedArgs.promptInteractive).toBe(expected.promptInteractive);
|
|
171
|
+
});
|
|
172
|
+
describe('positional arguments and @commands', () => {
|
|
173
|
+
it.each([
|
|
174
|
+
{
|
|
175
|
+
description: 'should convert positional query argument to prompt by default',
|
|
176
|
+
argv: ['node', 'script.js', 'Hi Gemini'],
|
|
177
|
+
expectedQuery: 'Hi Gemini',
|
|
178
|
+
expectedModel: undefined,
|
|
179
|
+
debug: false,
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
description: 'should map @path to prompt (one-shot) when it starts with @',
|
|
183
|
+
argv: ['node', 'script.js', '@path ./file.md'],
|
|
184
|
+
expectedQuery: '@path ./file.md',
|
|
185
|
+
expectedModel: undefined,
|
|
186
|
+
debug: false,
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
description: 'should map @path to prompt even when config flags are present',
|
|
190
|
+
argv: [
|
|
191
|
+
'node',
|
|
192
|
+
'script.js',
|
|
193
|
+
'@path',
|
|
194
|
+
'./file.md',
|
|
195
|
+
'--model',
|
|
196
|
+
'gemini-2.5-pro',
|
|
197
|
+
],
|
|
198
|
+
expectedQuery: '@path ./file.md',
|
|
199
|
+
expectedModel: 'gemini-2.5-pro',
|
|
200
|
+
debug: false,
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
description: 'maps unquoted positional @path + arg to prompt (one-shot)',
|
|
204
|
+
argv: ['node', 'script.js', '@path', './file.md'],
|
|
205
|
+
expectedQuery: '@path ./file.md',
|
|
206
|
+
expectedModel: undefined,
|
|
207
|
+
debug: false,
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
description: 'should handle multiple @path arguments in a single command (one-shot)',
|
|
211
|
+
argv: [
|
|
212
|
+
'node',
|
|
213
|
+
'script.js',
|
|
214
|
+
'@path',
|
|
215
|
+
'./file1.md',
|
|
216
|
+
'@path',
|
|
217
|
+
'./file2.md',
|
|
218
|
+
],
|
|
219
|
+
expectedQuery: '@path ./file1.md @path ./file2.md',
|
|
220
|
+
expectedModel: undefined,
|
|
221
|
+
debug: false,
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
description: 'should handle mixed quoted and unquoted @path arguments (one-shot)',
|
|
225
|
+
argv: [
|
|
226
|
+
'node',
|
|
227
|
+
'script.js',
|
|
228
|
+
'@path ./file1.md',
|
|
229
|
+
'@path',
|
|
230
|
+
'./file2.md',
|
|
231
|
+
'additional text',
|
|
232
|
+
],
|
|
233
|
+
expectedQuery: '@path ./file1.md @path ./file2.md additional text',
|
|
234
|
+
expectedModel: undefined,
|
|
235
|
+
debug: false,
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
description: 'should map @path to prompt with ambient flags (debug)',
|
|
239
|
+
argv: ['node', 'script.js', '@path', './file.md', '--debug'],
|
|
240
|
+
expectedQuery: '@path ./file.md',
|
|
241
|
+
expectedModel: undefined,
|
|
242
|
+
debug: true,
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
description: 'should map @include to prompt (one-shot)',
|
|
246
|
+
argv: ['node', 'script.js', '@include src/'],
|
|
247
|
+
expectedQuery: '@include src/',
|
|
248
|
+
expectedModel: undefined,
|
|
249
|
+
debug: false,
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
description: 'should map @search to prompt (one-shot)',
|
|
253
|
+
argv: ['node', 'script.js', '@search pattern'],
|
|
254
|
+
expectedQuery: '@search pattern',
|
|
255
|
+
expectedModel: undefined,
|
|
256
|
+
debug: false,
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
description: 'should map @web to prompt (one-shot)',
|
|
260
|
+
argv: ['node', 'script.js', '@web query'],
|
|
261
|
+
expectedQuery: '@web query',
|
|
262
|
+
expectedModel: undefined,
|
|
263
|
+
debug: false,
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
description: 'should map @git to prompt (one-shot)',
|
|
267
|
+
argv: ['node', 'script.js', '@git status'],
|
|
268
|
+
expectedQuery: '@git status',
|
|
269
|
+
expectedModel: undefined,
|
|
270
|
+
debug: false,
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
description: 'should handle @command with leading whitespace',
|
|
274
|
+
argv: ['node', 'script.js', ' @path ./file.md'],
|
|
275
|
+
expectedQuery: ' @path ./file.md',
|
|
276
|
+
expectedModel: undefined,
|
|
277
|
+
debug: false,
|
|
278
|
+
},
|
|
279
|
+
])('$description', async ({ argv, expectedQuery, expectedModel, debug }) => {
|
|
280
|
+
process.argv = argv;
|
|
281
|
+
const parsedArgs = await parseArguments({});
|
|
282
|
+
expect(parsedArgs.query).toBe(expectedQuery);
|
|
283
|
+
expect(parsedArgs.prompt).toBe(expectedQuery);
|
|
284
|
+
expect(parsedArgs.promptInteractive).toBeUndefined();
|
|
285
|
+
if (expectedModel) {
|
|
286
|
+
expect(parsedArgs.model).toBe(expectedModel);
|
|
287
|
+
}
|
|
288
|
+
if (debug) {
|
|
289
|
+
expect(parsedArgs.debug).toBe(true);
|
|
290
|
+
}
|
|
306
291
|
});
|
|
307
|
-
const mockConsoleError = vi
|
|
308
|
-
.spyOn(console, 'error')
|
|
309
|
-
.mockImplementation(() => { });
|
|
310
|
-
const debugErrorSpy = vi
|
|
311
|
-
.spyOn(debugLogger, 'error')
|
|
312
|
-
.mockImplementation(() => { });
|
|
313
|
-
await expect(parseArguments({})).rejects.toThrow('process.exit called');
|
|
314
|
-
expect(debugErrorSpy).toHaveBeenCalledWith(expect.stringContaining('Cannot use both --yolo (-y) and --approval-mode together. Use --approval-mode=yolo instead.'));
|
|
315
|
-
expect(mockConsoleError).toHaveBeenCalled();
|
|
316
|
-
mockExit.mockRestore();
|
|
317
|
-
mockConsoleError.mockRestore();
|
|
318
|
-
debugErrorSpy.mockRestore();
|
|
319
292
|
});
|
|
320
|
-
it(
|
|
321
|
-
|
|
293
|
+
it.each([
|
|
294
|
+
{
|
|
295
|
+
description: 'long flags',
|
|
296
|
+
argv: ['node', 'script.js', '--yolo', '--approval-mode', 'default'],
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
description: 'short flags',
|
|
300
|
+
argv: ['node', 'script.js', '-y', '--approval-mode', 'yolo'],
|
|
301
|
+
},
|
|
302
|
+
])('should throw an error when using conflicting yolo/approval-mode flags ($description)', async ({ argv }) => {
|
|
303
|
+
process.argv = argv;
|
|
322
304
|
const mockExit = vi.spyOn(process, 'exit').mockImplementation(() => {
|
|
323
305
|
throw new Error('process.exit called');
|
|
324
306
|
});
|
|
325
307
|
const mockConsoleError = vi
|
|
326
308
|
.spyOn(console, 'error')
|
|
327
309
|
.mockImplementation(() => { });
|
|
328
|
-
const debugErrorSpy = vi
|
|
329
|
-
.spyOn(debugLogger, 'error')
|
|
330
|
-
.mockImplementation(() => { });
|
|
331
310
|
await expect(parseArguments({})).rejects.toThrow('process.exit called');
|
|
332
|
-
expect(
|
|
333
|
-
expect(mockConsoleError).toHaveBeenCalled();
|
|
311
|
+
expect(mockConsoleError).toHaveBeenCalledWith(expect.stringContaining('Cannot use both --yolo (-y) and --approval-mode together. Use --approval-mode=yolo instead.'));
|
|
334
312
|
mockExit.mockRestore();
|
|
335
313
|
mockConsoleError.mockRestore();
|
|
336
|
-
debugErrorSpy.mockRestore();
|
|
337
314
|
});
|
|
338
|
-
it(
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
315
|
+
it.each([
|
|
316
|
+
{
|
|
317
|
+
description: 'should allow --approval-mode without --yolo',
|
|
318
|
+
argv: ['node', 'script.js', '--approval-mode', 'auto_edit'],
|
|
319
|
+
expected: { approvalMode: 'auto_edit', yolo: false },
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
description: 'should allow --yolo without --approval-mode',
|
|
323
|
+
argv: ['node', 'script.js', '--yolo'],
|
|
324
|
+
expected: { approvalMode: undefined, yolo: true },
|
|
325
|
+
},
|
|
326
|
+
])('$description', async ({ argv, expected }) => {
|
|
327
|
+
process.argv = argv;
|
|
328
|
+
const parsedArgs = await parseArguments({});
|
|
329
|
+
expect(parsedArgs.approvalMode).toBe(expected.approvalMode);
|
|
330
|
+
expect(parsedArgs.yolo).toBe(expected.yolo);
|
|
349
331
|
});
|
|
350
332
|
it('should reject invalid --approval-mode values', async () => {
|
|
351
333
|
process.argv = ['node', 'script.js', '--approval-mode', 'invalid'];
|
|
@@ -1150,68 +1132,6 @@ describe('loadCliConfig model selection', () => {
|
|
|
1150
1132
|
expect(config.getModel()).toBe('gemini-2.5-flash-preview');
|
|
1151
1133
|
});
|
|
1152
1134
|
});
|
|
1153
|
-
describe('loadCliConfig model selection with model router', () => {
|
|
1154
|
-
beforeEach(() => {
|
|
1155
|
-
vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
|
|
1156
|
-
});
|
|
1157
|
-
afterEach(() => {
|
|
1158
|
-
vi.resetAllMocks();
|
|
1159
|
-
});
|
|
1160
|
-
it('should use auto model when useModelRouter is true and no model is provided', async () => {
|
|
1161
|
-
process.argv = ['node', 'script.js'];
|
|
1162
|
-
const argv = await parseArguments({});
|
|
1163
|
-
const config = await loadCliConfig({
|
|
1164
|
-
experimental: {
|
|
1165
|
-
useModelRouter: true,
|
|
1166
|
-
},
|
|
1167
|
-
}, 'test-session', argv);
|
|
1168
|
-
expect(config.getModel()).toBe(DEFAULT_GEMINI_MODEL_AUTO);
|
|
1169
|
-
});
|
|
1170
|
-
it('should use default model when useModelRouter is false and no model is provided', async () => {
|
|
1171
|
-
process.argv = ['node', 'script.js'];
|
|
1172
|
-
const argv = await parseArguments({});
|
|
1173
|
-
const config = await loadCliConfig({
|
|
1174
|
-
experimental: {
|
|
1175
|
-
useModelRouter: false,
|
|
1176
|
-
},
|
|
1177
|
-
}, 'test-session', argv);
|
|
1178
|
-
expect(config.getModel()).toBe(DEFAULT_GEMINI_MODEL);
|
|
1179
|
-
});
|
|
1180
|
-
it('should prioritize argv over useModelRouter', async () => {
|
|
1181
|
-
process.argv = ['node', 'script.js', '--model', 'gemini-from-argv'];
|
|
1182
|
-
const argv = await parseArguments({});
|
|
1183
|
-
const config = await loadCliConfig({
|
|
1184
|
-
experimental: {
|
|
1185
|
-
useModelRouter: true,
|
|
1186
|
-
},
|
|
1187
|
-
}, 'test-session', argv);
|
|
1188
|
-
expect(config.getModel()).toBe('gemini-from-argv');
|
|
1189
|
-
});
|
|
1190
|
-
it('should prioritize settings over useModelRouter', async () => {
|
|
1191
|
-
process.argv = ['node', 'script.js'];
|
|
1192
|
-
const argv = await parseArguments({});
|
|
1193
|
-
const config = await loadCliConfig({
|
|
1194
|
-
experimental: {
|
|
1195
|
-
useModelRouter: true,
|
|
1196
|
-
},
|
|
1197
|
-
model: {
|
|
1198
|
-
name: 'gemini-from-settings',
|
|
1199
|
-
},
|
|
1200
|
-
}, 'test-session', argv);
|
|
1201
|
-
expect(config.getModel()).toBe('gemini-from-settings');
|
|
1202
|
-
});
|
|
1203
|
-
it('should prioritize environment variable over useModelRouter', async () => {
|
|
1204
|
-
process.argv = ['node', 'script.js'];
|
|
1205
|
-
vi.stubEnv('GEMINI_MODEL', 'gemini-from-env');
|
|
1206
|
-
const argv = await parseArguments({});
|
|
1207
|
-
const config = await loadCliConfig({
|
|
1208
|
-
experimental: {
|
|
1209
|
-
useModelRouter: true,
|
|
1210
|
-
},
|
|
1211
|
-
}, 'test-session', argv);
|
|
1212
|
-
expect(config.getModel()).toBe('gemini-from-env');
|
|
1213
|
-
});
|
|
1214
|
-
});
|
|
1215
1135
|
describe('loadCliConfig folderTrust', () => {
|
|
1216
1136
|
beforeEach(() => {
|
|
1217
1137
|
vi.resetAllMocks();
|
|
@@ -1363,29 +1283,6 @@ describe('loadCliConfig useRipgrep', () => {
|
|
|
1363
1283
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1364
1284
|
expect(config.getUseRipgrep()).toBe(true);
|
|
1365
1285
|
});
|
|
1366
|
-
describe('loadCliConfig useModelRouter', () => {
|
|
1367
|
-
it('should be true by default when useModelRouter is not set in settings', async () => {
|
|
1368
|
-
process.argv = ['node', 'script.js'];
|
|
1369
|
-
const argv = await parseArguments({});
|
|
1370
|
-
const settings = {};
|
|
1371
|
-
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1372
|
-
expect(config.getUseModelRouter()).toBe(true);
|
|
1373
|
-
});
|
|
1374
|
-
it('should be true when useModelRouter is set to true in settings', async () => {
|
|
1375
|
-
process.argv = ['node', 'script.js'];
|
|
1376
|
-
const argv = await parseArguments({});
|
|
1377
|
-
const settings = { experimental: { useModelRouter: true } };
|
|
1378
|
-
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1379
|
-
expect(config.getUseModelRouter()).toBe(true);
|
|
1380
|
-
});
|
|
1381
|
-
it('should be false when useModelRouter is explicitly set to false in settings', async () => {
|
|
1382
|
-
process.argv = ['node', 'script.js'];
|
|
1383
|
-
const argv = await parseArguments({});
|
|
1384
|
-
const settings = { experimental: { useModelRouter: false } };
|
|
1385
|
-
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1386
|
-
expect(config.getUseModelRouter()).toBe(false);
|
|
1387
|
-
});
|
|
1388
|
-
});
|
|
1389
1286
|
});
|
|
1390
1287
|
describe('screenReader configuration', () => {
|
|
1391
1288
|
beforeEach(() => {
|