@google/gemini-cli 0.12.0-nightly.20251023.c4c0c0d1 → 0.12.0-preview.0

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.
Files changed (248) hide show
  1. package/README.md +7 -5
  2. package/dist/package.json +3 -3
  3. package/dist/src/commands/extensions/disable.d.ts +1 -1
  4. package/dist/src/commands/extensions/disable.js +5 -4
  5. package/dist/src/commands/extensions/disable.js.map +1 -1
  6. package/dist/src/commands/extensions/enable.d.ts +1 -1
  7. package/dist/src/commands/extensions/enable.js +3 -2
  8. package/dist/src/commands/extensions/enable.js.map +1 -1
  9. package/dist/src/commands/extensions/install.js +2 -1
  10. package/dist/src/commands/extensions/install.js.map +1 -1
  11. package/dist/src/commands/extensions/install.test.js +1 -0
  12. package/dist/src/commands/extensions/install.test.js.map +1 -1
  13. package/dist/src/commands/extensions/link.js +2 -1
  14. package/dist/src/commands/extensions/link.js.map +1 -1
  15. package/dist/src/commands/extensions/list.js +2 -2
  16. package/dist/src/commands/extensions/list.js.map +1 -1
  17. package/dist/src/commands/extensions/uninstall.js +2 -1
  18. package/dist/src/commands/extensions/uninstall.js.map +1 -1
  19. package/dist/src/commands/extensions/update.js +2 -2
  20. package/dist/src/commands/extensions/update.js.map +1 -1
  21. package/dist/src/commands/mcp/list.js +2 -2
  22. package/dist/src/commands/mcp/list.js.map +1 -1
  23. package/dist/src/config/config.d.ts +6 -3
  24. package/dist/src/config/config.js +56 -11
  25. package/dist/src/config/config.js.map +1 -1
  26. package/dist/src/config/config.test.js +208 -175
  27. package/dist/src/config/config.test.js.map +1 -1
  28. package/dist/src/config/extension-manager.d.ts +23 -10
  29. package/dist/src/config/extension-manager.js +90 -64
  30. package/dist/src/config/extension-manager.js.map +1 -1
  31. package/dist/src/config/extension.test.js +183 -76
  32. package/dist/src/config/extension.test.js.map +1 -1
  33. package/dist/src/config/extensions/extensionEnablement.d.ts +1 -1
  34. package/dist/src/config/extensions/extensionEnablement.js +3 -2
  35. package/dist/src/config/extensions/extensionEnablement.js.map +1 -1
  36. package/dist/src/config/extensions/extensionEnablement.test.js +10 -10
  37. package/dist/src/config/extensions/extensionEnablement.test.js.map +1 -1
  38. package/dist/src/config/extensions/extensionSettings.d.ts +3 -3
  39. package/dist/src/config/extensions/extensionSettings.js +74 -24
  40. package/dist/src/config/extensions/extensionSettings.js.map +1 -1
  41. package/dist/src/config/extensions/extensionSettings.test.js +145 -24
  42. package/dist/src/config/extensions/extensionSettings.test.js.map +1 -1
  43. package/dist/src/config/extensions/github.js +3 -3
  44. package/dist/src/config/extensions/github.js.map +1 -1
  45. package/dist/src/config/extensions/github.test.js +1 -1
  46. package/dist/src/config/extensions/github.test.js.map +1 -1
  47. package/dist/src/config/extensions/github_fetch.d.ts +1 -1
  48. package/dist/src/config/extensions/github_fetch.js +13 -1
  49. package/dist/src/config/extensions/github_fetch.js.map +1 -1
  50. package/dist/src/config/extensions/github_fetch.test.d.ts +6 -0
  51. package/dist/src/config/extensions/github_fetch.test.js +169 -0
  52. package/dist/src/config/extensions/github_fetch.test.js.map +1 -0
  53. package/dist/src/config/extensions/update.js +7 -6
  54. package/dist/src/config/extensions/update.js.map +1 -1
  55. package/dist/src/config/extensions/update.test.js +54 -30
  56. package/dist/src/config/extensions/update.test.js.map +1 -1
  57. package/dist/src/config/keyBindings.js +1 -1
  58. package/dist/src/config/keyBindings.js.map +1 -1
  59. package/dist/src/config/policies/read-only.toml +56 -0
  60. package/dist/src/config/policies/write.toml +63 -0
  61. package/dist/src/config/policies/yolo.toml +31 -0
  62. package/dist/src/config/policy-engine.integration.test.js +41 -38
  63. package/dist/src/config/policy-engine.integration.test.js.map +1 -1
  64. package/dist/src/config/policy-toml-loader.d.ts +46 -0
  65. package/dist/src/config/policy-toml-loader.js +314 -0
  66. package/dist/src/config/policy-toml-loader.js.map +1 -0
  67. package/dist/src/config/policy-toml-loader.test.d.ts +6 -0
  68. package/dist/src/config/policy-toml-loader.test.js +626 -0
  69. package/dist/src/config/policy-toml-loader.test.js.map +1 -0
  70. package/dist/src/config/policy.d.ts +9 -2
  71. package/dist/src/config/policy.js +139 -110
  72. package/dist/src/config/policy.js.map +1 -1
  73. package/dist/src/config/policy.test.js +780 -82
  74. package/dist/src/config/policy.test.js.map +1 -1
  75. package/dist/src/config/settings.test.js +6 -6
  76. package/dist/src/config/settings.test.js.map +1 -1
  77. package/dist/src/core/initializer.js +2 -1
  78. package/dist/src/core/initializer.js.map +1 -1
  79. package/dist/src/gemini.js +6 -17
  80. package/dist/src/gemini.js.map +1 -1
  81. package/dist/src/gemini.test.js +27 -2
  82. package/dist/src/gemini.test.js.map +1 -1
  83. package/dist/src/generated/git-commit.d.ts +2 -2
  84. package/dist/src/generated/git-commit.js +2 -2
  85. package/dist/src/generated/git-commit.js.map +1 -1
  86. package/dist/src/nonInteractiveCli.js +16 -4
  87. package/dist/src/nonInteractiveCli.js.map +1 -1
  88. package/dist/src/nonInteractiveCli.test.js +67 -12
  89. package/dist/src/nonInteractiveCli.test.js.map +1 -1
  90. package/dist/src/test-utils/render.d.ts +12 -0
  91. package/dist/src/test-utils/render.js +28 -1
  92. package/dist/src/test-utils/render.js.map +1 -1
  93. package/dist/src/test-utils/render.test.d.ts +6 -0
  94. package/dist/src/test-utils/render.test.js +54 -0
  95. package/dist/src/test-utils/render.test.js.map +1 -0
  96. package/dist/src/ui/AppContainer.js +29 -23
  97. package/dist/src/ui/AppContainer.js.map +1 -1
  98. package/dist/src/ui/AppContainer.test.js +8 -0
  99. package/dist/src/ui/AppContainer.test.js.map +1 -1
  100. package/dist/src/ui/commands/directoryCommand.js +1 -1
  101. package/dist/src/ui/commands/directoryCommand.js.map +1 -1
  102. package/dist/src/ui/commands/extensionsCommand.js +45 -1
  103. package/dist/src/ui/commands/extensionsCommand.js.map +1 -1
  104. package/dist/src/ui/commands/extensionsCommand.test.js +64 -1
  105. package/dist/src/ui/commands/extensionsCommand.test.js.map +1 -1
  106. package/dist/src/ui/commands/memoryCommand.js +1 -1
  107. package/dist/src/ui/commands/memoryCommand.js.map +1 -1
  108. package/dist/src/ui/commands/memoryCommand.test.js +3 -1
  109. package/dist/src/ui/commands/memoryCommand.test.js.map +1 -1
  110. package/dist/src/ui/components/ConsoleSummaryDisplay.js +1 -1
  111. package/dist/src/ui/components/ConsoleSummaryDisplay.js.map +1 -1
  112. package/dist/src/ui/components/DetailedMessagesDisplay.js +1 -1
  113. package/dist/src/ui/components/DetailedMessagesDisplay.js.map +1 -1
  114. package/dist/src/ui/components/FolderTrustDialog.test.js +4 -4
  115. package/dist/src/ui/components/FolderTrustDialog.test.js.map +1 -1
  116. package/dist/src/ui/components/Footer.js +1 -1
  117. package/dist/src/ui/components/Footer.js.map +1 -1
  118. package/dist/src/ui/components/Footer.test.js +24 -0
  119. package/dist/src/ui/components/Footer.test.js.map +1 -1
  120. package/dist/src/ui/components/Help.test.js +0 -1
  121. package/dist/src/ui/components/Help.test.js.map +1 -1
  122. package/dist/src/ui/components/InputPrompt.test.js +442 -342
  123. package/dist/src/ui/components/InputPrompt.test.js.map +1 -1
  124. package/dist/src/ui/components/ModelDialog.test.js +5 -5
  125. package/dist/src/ui/components/ModelDialog.test.js.map +1 -1
  126. package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js +11 -12
  127. package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js.map +1 -1
  128. package/dist/src/ui/components/SettingsDialog.test.js +13 -14
  129. package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
  130. package/dist/src/ui/components/ThemeDialog.test.js +1 -2
  131. package/dist/src/ui/components/ThemeDialog.test.js.map +1 -1
  132. package/dist/src/ui/components/shared/BaseSelectionList.test.js +11 -12
  133. package/dist/src/ui/components/shared/BaseSelectionList.test.js.map +1 -1
  134. package/dist/src/ui/components/shared/text-buffer.test.js +2 -1
  135. package/dist/src/ui/components/shared/text-buffer.test.js.map +1 -1
  136. package/dist/src/ui/components/views/ExtensionsList.d.ts +1 -1
  137. package/dist/src/ui/components/views/ExtensionsList.js +4 -1
  138. package/dist/src/ui/components/views/ExtensionsList.js.map +1 -1
  139. package/dist/src/ui/contexts/KeypressContext.d.ts +3 -2
  140. package/dist/src/ui/contexts/KeypressContext.js +114 -64
  141. package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
  142. package/dist/src/ui/contexts/KeypressContext.test.js +166 -482
  143. package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
  144. package/dist/src/ui/contexts/SessionContext.test.js +27 -13
  145. package/dist/src/ui/contexts/SessionContext.test.js.map +1 -1
  146. package/dist/src/ui/hooks/atCommandProcessor.js +2 -2
  147. package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
  148. package/dist/src/ui/hooks/shellCommandProcessor.test.js +18 -2
  149. package/dist/src/ui/hooks/shellCommandProcessor.test.js.map +1 -1
  150. package/dist/src/ui/hooks/slashCommandProcessor.test.js +74 -80
  151. package/dist/src/ui/hooks/slashCommandProcessor.test.js.map +1 -1
  152. package/dist/src/ui/hooks/useAtCompletion.test.js +32 -23
  153. package/dist/src/ui/hooks/useAtCompletion.test.js.map +1 -1
  154. package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js +2 -1
  155. package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js.map +1 -1
  156. package/dist/src/ui/hooks/useCommandCompletion.test.js +79 -78
  157. package/dist/src/ui/hooks/useCommandCompletion.test.js.map +1 -1
  158. package/dist/src/ui/hooks/useConsoleMessages.test.js +26 -9
  159. package/dist/src/ui/hooks/useConsoleMessages.test.js.map +1 -1
  160. package/dist/src/ui/hooks/useEditorSettings.test.js +40 -34
  161. package/dist/src/ui/hooks/useEditorSettings.test.js.map +1 -1
  162. package/dist/src/ui/hooks/useExtensionUpdates.d.ts +1 -2
  163. package/dist/src/ui/hooks/useExtensionUpdates.js +4 -2
  164. package/dist/src/ui/hooks/useExtensionUpdates.js.map +1 -1
  165. package/dist/src/ui/hooks/useExtensionUpdates.test.js +37 -26
  166. package/dist/src/ui/hooks/useExtensionUpdates.test.js.map +1 -1
  167. package/dist/src/ui/hooks/useFlickerDetector.test.js +9 -5
  168. package/dist/src/ui/hooks/useFlickerDetector.test.js.map +1 -1
  169. package/dist/src/ui/hooks/useFocus.test.js +25 -9
  170. package/dist/src/ui/hooks/useFocus.test.js.map +1 -1
  171. package/dist/src/ui/hooks/useFolderTrust.test.js +45 -22
  172. package/dist/src/ui/hooks/useFolderTrust.test.js.map +1 -1
  173. package/dist/src/ui/hooks/useGeminiStream.js +56 -19
  174. package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
  175. package/dist/src/ui/hooks/useGeminiStream.test.js +155 -74
  176. package/dist/src/ui/hooks/useGeminiStream.test.js.map +1 -1
  177. package/dist/src/ui/hooks/useGitBranchName.test.js +29 -16
  178. package/dist/src/ui/hooks/useGitBranchName.test.js.map +1 -1
  179. package/dist/src/ui/hooks/useHistoryManager.test.js +2 -1
  180. package/dist/src/ui/hooks/useHistoryManager.test.js.map +1 -1
  181. package/dist/src/ui/hooks/useIdeTrustListener.test.js +24 -7
  182. package/dist/src/ui/hooks/useIdeTrustListener.test.js.map +1 -1
  183. package/dist/src/ui/hooks/useInputHistory.test.js +2 -1
  184. package/dist/src/ui/hooks/useInputHistory.test.js.map +1 -1
  185. package/dist/src/ui/hooks/useInputHistoryStore.test.js +2 -1
  186. package/dist/src/ui/hooks/useInputHistoryStore.test.js.map +1 -1
  187. package/dist/src/ui/hooks/useKeypress.test.js +94 -113
  188. package/dist/src/ui/hooks/useKeypress.test.js.map +1 -1
  189. package/dist/src/ui/hooks/useLoadingIndicator.test.js +24 -6
  190. package/dist/src/ui/hooks/useLoadingIndicator.test.js.map +1 -1
  191. package/dist/src/ui/hooks/useMemoryMonitor.test.js +10 -5
  192. package/dist/src/ui/hooks/useMemoryMonitor.test.js.map +1 -1
  193. package/dist/src/ui/hooks/useMessageQueue.test.js +61 -45
  194. package/dist/src/ui/hooks/useMessageQueue.test.js.map +1 -1
  195. package/dist/src/ui/hooks/useModelCommand.test.js +18 -11
  196. package/dist/src/ui/hooks/useModelCommand.test.js.map +1 -1
  197. package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js +2 -2
  198. package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js.map +1 -1
  199. package/dist/src/ui/hooks/usePhraseCycler.js +1 -1
  200. package/dist/src/ui/hooks/usePhraseCycler.js.map +1 -1
  201. package/dist/src/ui/hooks/usePhraseCycler.test.js +83 -110
  202. package/dist/src/ui/hooks/usePhraseCycler.test.js.map +1 -1
  203. package/dist/src/ui/hooks/usePrivacySettings.test.js +26 -10
  204. package/dist/src/ui/hooks/usePrivacySettings.test.js.map +1 -1
  205. package/dist/src/ui/hooks/useQuotaAndFallback.js +13 -14
  206. package/dist/src/ui/hooks/useQuotaAndFallback.js.map +1 -1
  207. package/dist/src/ui/hooks/useQuotaAndFallback.test.js +33 -40
  208. package/dist/src/ui/hooks/useQuotaAndFallback.test.js.map +1 -1
  209. package/dist/src/ui/hooks/useReactToolScheduler.d.ts +8 -1
  210. package/dist/src/ui/hooks/useReactToolScheduler.js +37 -26
  211. package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
  212. package/dist/src/ui/hooks/useReactToolScheduler.test.js +1 -1
  213. package/dist/src/ui/hooks/useReactToolScheduler.test.js.map +1 -1
  214. package/dist/src/ui/hooks/useReverseSearchCompletion.test.js +2 -2
  215. package/dist/src/ui/hooks/useReverseSearchCompletion.test.js.map +1 -1
  216. package/dist/src/ui/hooks/useSelectionList.test.js +193 -132
  217. package/dist/src/ui/hooks/useSelectionList.test.js.map +1 -1
  218. package/dist/src/ui/hooks/useShellHistory.test.js +40 -16
  219. package/dist/src/ui/hooks/useShellHistory.test.js.map +1 -1
  220. package/dist/src/ui/hooks/useSlashCompletion.test.js +54 -49
  221. package/dist/src/ui/hooks/useSlashCompletion.test.js.map +1 -1
  222. package/dist/src/ui/hooks/useTimer.test.js +43 -14
  223. package/dist/src/ui/hooks/useTimer.test.js.map +1 -1
  224. package/dist/src/ui/hooks/useToolScheduler.test.js +163 -74
  225. package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
  226. package/dist/src/ui/hooks/vim.test.js +251 -356
  227. package/dist/src/ui/hooks/vim.test.js.map +1 -1
  228. package/dist/src/ui/keyMatchers.test.js +3 -3
  229. package/dist/src/ui/keyMatchers.test.js.map +1 -1
  230. package/dist/src/ui/utils/textOutput.d.ts +25 -0
  231. package/dist/src/ui/utils/textOutput.js +49 -0
  232. package/dist/src/ui/utils/textOutput.js.map +1 -0
  233. package/dist/src/ui/utils/textOutput.test.d.ts +6 -0
  234. package/dist/src/ui/utils/textOutput.test.js +79 -0
  235. package/dist/src/ui/utils/textOutput.test.js.map +1 -0
  236. package/dist/src/ui/utils/updateCheck.d.ts +7 -1
  237. package/dist/src/ui/utils/updateCheck.js +27 -26
  238. package/dist/src/ui/utils/updateCheck.js.map +1 -1
  239. package/dist/src/ui/utils/updateCheck.test.js +19 -49
  240. package/dist/src/ui/utils/updateCheck.test.js.map +1 -1
  241. package/dist/src/utils/handleAutoUpdate.js +9 -3
  242. package/dist/src/utils/handleAutoUpdate.js.map +1 -1
  243. package/dist/src/zed-integration/zedIntegration.d.ts +2 -2
  244. package/dist/src/zed-integration/zedIntegration.js +9 -16
  245. package/dist/src/zed-integration/zedIntegration.js.map +1 -1
  246. package/dist/tsconfig.tsbuildinfo +1 -1
  247. package/package.json +4 -4
  248. package/dist/google-gemini-cli-0.12.0-nightly.20251022.0542de95.tgz +0 -0
@@ -6,10 +6,11 @@
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_GEMINI_MODEL, DEFAULT_GEMINI_MODEL_AUTO, OutputFormat, SHELL_TOOL_NAME, WRITE_FILE_TOOL_NAME, EDIT_TOOL_NAME, } from '@google/gemini-cli-core';
9
+ import { DEFAULT_FILE_FILTERING_OPTIONS, DEFAULT_GEMINI_MODEL, DEFAULT_GEMINI_MODEL_AUTO, OutputFormat, SHELL_TOOL_NAME, WRITE_FILE_TOOL_NAME, EDIT_TOOL_NAME, } 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';
13
+ import { ExtensionManager } from './extension-manager.js';
13
14
  vi.mock('./trustedFolders.js', () => ({
14
15
  isWorkspaceTrusted: vi
15
16
  .fn()
@@ -72,10 +73,15 @@ vi.mock('@google/gemini-cli-core', async () => {
72
73
  }),
73
74
  },
74
75
  loadEnvironment: vi.fn(),
75
- loadServerHierarchicalMemory: vi.fn((cwd, dirs, debug, fileService, extensionPaths, _maxDirs) => Promise.resolve({
76
- memoryContent: extensionPaths?.join(',') || '',
77
- fileCount: extensionPaths?.length || 0,
78
- })),
76
+ loadServerHierarchicalMemory: vi.fn((cwd, dirs, debug, fileService, extensionLoader, _maxDirs) => {
77
+ const extensionPaths = extensionLoader
78
+ .getExtensions()
79
+ .flatMap((e) => e.contextFiles);
80
+ return Promise.resolve({
81
+ memoryContent: extensionPaths.join(',') || '',
82
+ fileCount: extensionPaths?.length || 0,
83
+ });
84
+ }),
79
85
  DEFAULT_MEMORY_FILE_FILTERING_OPTIONS: {
80
86
  respectGitIgnore: false,
81
87
  respectGeminiIgnore: true,
@@ -86,11 +92,23 @@ vi.mock('@google/gemini-cli-core', async () => {
86
92
  },
87
93
  };
88
94
  });
95
+ vi.mock('./extension-manager.js');
96
+ // Global setup to ensure clean environment for all tests in this file
97
+ const originalArgv = process.argv;
98
+ const originalGeminiModel = process.env['GEMINI_MODEL'];
99
+ beforeEach(() => {
100
+ delete process.env['GEMINI_MODEL'];
101
+ });
102
+ afterEach(() => {
103
+ process.argv = originalArgv;
104
+ if (originalGeminiModel !== undefined) {
105
+ process.env['GEMINI_MODEL'] = originalGeminiModel;
106
+ }
107
+ else {
108
+ delete process.env['GEMINI_MODEL'];
109
+ }
110
+ });
89
111
  describe('parseArguments', () => {
90
- const originalArgv = process.argv;
91
- afterEach(() => {
92
- process.argv = originalArgv;
93
- });
94
112
  it('should throw an error when both --prompt and --prompt-interactive are used together', async () => {
95
113
  process.argv = [
96
114
  'node',
@@ -176,13 +194,13 @@ describe('parseArguments', () => {
176
194
  '@path',
177
195
  './file.md',
178
196
  '--model',
179
- 'gemini-1.5-pro',
197
+ 'gemini-2.5-pro',
180
198
  ];
181
199
  const argv = await parseArguments({});
182
200
  expect(argv.query).toBe('@path ./file.md');
183
201
  expect(argv.prompt).toBe('@path ./file.md'); // Should map to one-shot
184
202
  expect(argv.promptInteractive).toBeUndefined();
185
- expect(argv.model).toBe('gemini-1.5-pro');
203
+ expect(argv.model).toBe('gemini-2.5-pro');
186
204
  });
187
205
  it('maps unquoted positional @path + arg to prompt (one-shot)', async () => {
188
206
  // Simulate: gemini @path ./file.md
@@ -380,14 +398,13 @@ describe('parseArguments', () => {
380
398
  });
381
399
  });
382
400
  describe('loadCliConfig', () => {
383
- const originalArgv = process.argv;
384
401
  beforeEach(() => {
385
402
  vi.resetAllMocks();
386
403
  vi.mocked(os.homedir).mockReturnValue('/mock/home/user');
387
404
  vi.stubEnv('GEMINI_API_KEY', 'test-api-key');
405
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
388
406
  });
389
407
  afterEach(() => {
390
- process.argv = originalArgv;
391
408
  vi.unstubAllEnvs();
392
409
  vi.restoreAllMocks();
393
410
  });
@@ -419,7 +436,7 @@ describe('loadCliConfig', () => {
419
436
  process.argv = ['node', 'script.js'];
420
437
  const argv = await parseArguments({});
421
438
  const settings = {};
422
- const config = await loadCliConfig(settings, [], 'test-session', argv);
439
+ const config = await loadCliConfig(settings, 'test-session', argv);
423
440
  expect(config.getProxy()).toBeFalsy();
424
441
  });
425
442
  const proxy_url = 'http://localhost:7890';
@@ -459,11 +476,19 @@ describe('loadCliConfig', () => {
459
476
  process.argv = ['node', 'script.js'];
460
477
  const argv = await parseArguments({});
461
478
  const settings = {};
462
- const config = await loadCliConfig(settings, [], 'test-session', argv);
479
+ const config = await loadCliConfig(settings, 'test-session', argv);
463
480
  expect(config.getProxy()).toBe(expected);
464
481
  });
465
482
  });
466
483
  });
484
+ it('should use default fileFilter options when unconfigured', async () => {
485
+ process.argv = ['node', 'script.js'];
486
+ const argv = await parseArguments({});
487
+ const settings = {};
488
+ const config = await loadCliConfig(settings, 'test-session', argv);
489
+ expect(config.getFileFilteringRespectGitIgnore()).toBe(DEFAULT_FILE_FILTERING_OPTIONS.respectGitIgnore);
490
+ expect(config.getFileFilteringRespectGeminiIgnore()).toBe(DEFAULT_FILE_FILTERING_OPTIONS.respectGeminiIgnore);
491
+ });
467
492
  });
468
493
  describe('Hierarchical Memory Loading (config.ts) - Placeholder Suite', () => {
469
494
  beforeEach(() => {
@@ -477,7 +502,7 @@ describe('Hierarchical Memory Loading (config.ts) - Placeholder Suite', () => {
477
502
  it('should pass extension context file paths to loadServerHierarchicalMemory', async () => {
478
503
  process.argv = ['node', 'script.js'];
479
504
  const settings = {};
480
- const extensions = [
505
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([
481
506
  {
482
507
  path: '/path/to/ext1',
483
508
  name: 'ext1',
@@ -505,10 +530,10 @@ describe('Hierarchical Memory Loading (config.ts) - Placeholder Suite', () => {
505
530
  ],
506
531
  isActive: true,
507
532
  },
508
- ];
533
+ ]);
509
534
  const argv = await parseArguments({});
510
- await loadCliConfig(settings, extensions, 'session-id', argv);
511
- expect(ServerConfig.loadServerHierarchicalMemory).toHaveBeenCalledWith(expect.any(String), [], false, expect.any(Object), extensions, true, 'tree', {
535
+ await loadCliConfig(settings, 'session-id', argv);
536
+ expect(ServerConfig.loadServerHierarchicalMemory).toHaveBeenCalledWith(expect.any(String), [], false, expect.any(Object), expect.any(ExtensionManager), true, 'tree', {
512
537
  respectGitIgnore: false,
513
538
  respectGeminiIgnore: true,
514
539
  }, undefined);
@@ -555,7 +580,7 @@ describe('mergeMcpServers', () => {
555
580
  },
556
581
  },
557
582
  };
558
- const extensions = [
583
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([
559
584
  {
560
585
  path: '/path/to/ext1',
561
586
  name: 'ext1',
@@ -569,11 +594,11 @@ describe('mergeMcpServers', () => {
569
594
  contextFiles: [],
570
595
  isActive: true,
571
596
  },
572
- ];
597
+ ]);
573
598
  const originalSettings = JSON.parse(JSON.stringify(settings));
574
599
  process.argv = ['node', 'script.js'];
575
600
  const argv = await parseArguments({});
576
- await loadCliConfig(settings, extensions, 'test-session', argv);
601
+ await loadCliConfig(settings, 'test-session', argv);
577
602
  expect(settings).toEqual(originalSettings);
578
603
  });
579
604
  });
@@ -585,6 +610,7 @@ describe('mergeExcludeTools', () => {
585
610
  ];
586
611
  const originalIsTTY = process.stdin.isTTY;
587
612
  beforeEach(() => {
613
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
588
614
  process.stdin.isTTY = true;
589
615
  });
590
616
  afterEach(() => {
@@ -592,7 +618,7 @@ describe('mergeExcludeTools', () => {
592
618
  });
593
619
  it('should merge excludeTools from settings and extensions', async () => {
594
620
  const settings = { tools: { exclude: ['tool1', 'tool2'] } };
595
- const extensions = [
621
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([
596
622
  {
597
623
  path: '/path/to/ext1',
598
624
  name: 'ext1',
@@ -611,16 +637,16 @@ describe('mergeExcludeTools', () => {
611
637
  contextFiles: [],
612
638
  isActive: true,
613
639
  },
614
- ];
640
+ ]);
615
641
  process.argv = ['node', 'script.js'];
616
642
  const argv = await parseArguments({});
617
- const config = await loadCliConfig(settings, extensions, 'test-session', argv);
643
+ const config = await loadCliConfig(settings, 'test-session', argv);
618
644
  expect(config.getExcludeTools()).toEqual(expect.arrayContaining(['tool1', 'tool2', 'tool3', 'tool4', 'tool5']));
619
645
  expect(config.getExcludeTools()).toHaveLength(5);
620
646
  });
621
647
  it('should handle overlapping excludeTools between settings and extensions', async () => {
622
648
  const settings = { tools: { exclude: ['tool1', 'tool2'] } };
623
- const extensions = [
649
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([
624
650
  {
625
651
  path: '/path/to/ext1',
626
652
  name: 'ext1',
@@ -630,16 +656,16 @@ describe('mergeExcludeTools', () => {
630
656
  contextFiles: [],
631
657
  isActive: true,
632
658
  },
633
- ];
659
+ ]);
634
660
  process.argv = ['node', 'script.js'];
635
661
  const argv = await parseArguments({});
636
- const config = await loadCliConfig(settings, extensions, 'test-session', argv);
662
+ const config = await loadCliConfig(settings, 'test-session', argv);
637
663
  expect(config.getExcludeTools()).toEqual(expect.arrayContaining(['tool1', 'tool2', 'tool3']));
638
664
  expect(config.getExcludeTools()).toHaveLength(3);
639
665
  });
640
666
  it('should handle overlapping excludeTools between extensions', async () => {
641
667
  const settings = { tools: { exclude: ['tool1'] } };
642
- const extensions = [
668
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([
643
669
  {
644
670
  path: '/path/to/ext1',
645
671
  name: 'ext1',
@@ -658,43 +684,41 @@ describe('mergeExcludeTools', () => {
658
684
  contextFiles: [],
659
685
  isActive: true,
660
686
  },
661
- ];
687
+ ]);
662
688
  process.argv = ['node', 'script.js'];
663
689
  const argv = await parseArguments({});
664
- const config = await loadCliConfig(settings, extensions, 'test-session', argv);
690
+ const config = await loadCliConfig(settings, 'test-session', argv);
665
691
  expect(config.getExcludeTools()).toEqual(expect.arrayContaining(['tool1', 'tool2', 'tool3', 'tool4']));
666
692
  expect(config.getExcludeTools()).toHaveLength(4);
667
693
  });
668
694
  it('should return an empty array when no excludeTools are specified and it is interactive', async () => {
669
695
  process.stdin.isTTY = true;
670
696
  const settings = {};
671
- const extensions = [];
672
697
  process.argv = ['node', 'script.js'];
673
698
  const argv = await parseArguments({});
674
- const config = await loadCliConfig(settings, extensions, 'test-session', argv);
699
+ const config = await loadCliConfig(settings, 'test-session', argv);
675
700
  expect(config.getExcludeTools()).toEqual([]);
676
701
  });
677
702
  it('should return default excludes when no excludeTools are specified and it is not interactive', async () => {
678
703
  process.stdin.isTTY = false;
679
704
  const settings = {};
680
- const extensions = [];
681
705
  process.argv = ['node', 'script.js', '-p', 'test'];
682
706
  const argv = await parseArguments({});
683
- const config = await loadCliConfig(settings, extensions, 'test-session', argv);
707
+ const config = await loadCliConfig(settings, 'test-session', argv);
684
708
  expect(config.getExcludeTools()).toEqual(defaultExcludes);
685
709
  });
686
710
  it('should handle settings with excludeTools but no extensions', async () => {
687
711
  process.argv = ['node', 'script.js'];
688
712
  const argv = await parseArguments({});
689
713
  const settings = { tools: { exclude: ['tool1', 'tool2'] } };
690
- const extensions = [];
691
- const config = await loadCliConfig(settings, extensions, 'test-session', argv);
714
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
715
+ const config = await loadCliConfig(settings, 'test-session', argv);
692
716
  expect(config.getExcludeTools()).toEqual(expect.arrayContaining(['tool1', 'tool2']));
693
717
  expect(config.getExcludeTools()).toHaveLength(2);
694
718
  });
695
719
  it('should handle extensions with excludeTools but no settings', async () => {
696
720
  const settings = {};
697
- const extensions = [
721
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([
698
722
  {
699
723
  path: '/path/to/ext',
700
724
  name: 'ext1',
@@ -704,16 +728,16 @@ describe('mergeExcludeTools', () => {
704
728
  contextFiles: [],
705
729
  isActive: true,
706
730
  },
707
- ];
731
+ ]);
708
732
  process.argv = ['node', 'script.js'];
709
733
  const argv = await parseArguments({});
710
- const config = await loadCliConfig(settings, extensions, 'test-session', argv);
734
+ const config = await loadCliConfig(settings, 'test-session', argv);
711
735
  expect(config.getExcludeTools()).toEqual(expect.arrayContaining(['tool1', 'tool2']));
712
736
  expect(config.getExcludeTools()).toHaveLength(2);
713
737
  });
714
738
  it('should not modify the original settings object', async () => {
715
739
  const settings = { tools: { exclude: ['tool1'] } };
716
- const extensions = [
740
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([
717
741
  {
718
742
  path: '/path/to/ext',
719
743
  name: 'ext1',
@@ -723,11 +747,11 @@ describe('mergeExcludeTools', () => {
723
747
  contextFiles: [],
724
748
  isActive: true,
725
749
  },
726
- ];
750
+ ]);
727
751
  const originalSettings = JSON.parse(JSON.stringify(settings));
728
752
  process.argv = ['node', 'script.js'];
729
753
  const argv = await parseArguments({});
730
- await loadCliConfig(settings, extensions, 'test-session', argv);
754
+ await loadCliConfig(settings, 'test-session', argv);
731
755
  expect(settings).toEqual(originalSettings);
732
756
  });
733
757
  });
@@ -739,6 +763,7 @@ describe('Approval mode tool exclusion logic', () => {
739
763
  isTrusted: true,
740
764
  source: undefined,
741
765
  });
766
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
742
767
  });
743
768
  afterEach(() => {
744
769
  process.stdin.isTTY = originalIsTTY;
@@ -747,8 +772,7 @@ describe('Approval mode tool exclusion logic', () => {
747
772
  process.argv = ['node', 'script.js', '-p', 'test'];
748
773
  const argv = await parseArguments({});
749
774
  const settings = {};
750
- const extensions = [];
751
- const config = await loadCliConfig(settings, extensions, 'test-session', argv);
775
+ const config = await loadCliConfig(settings, 'test-session', argv);
752
776
  const excludedTools = config.getExcludeTools();
753
777
  expect(excludedTools).toContain(SHELL_TOOL_NAME);
754
778
  expect(excludedTools).toContain(EDIT_TOOL_NAME);
@@ -765,8 +789,7 @@ describe('Approval mode tool exclusion logic', () => {
765
789
  ];
766
790
  const argv = await parseArguments({});
767
791
  const settings = {};
768
- const extensions = [];
769
- const config = await loadCliConfig(settings, extensions, 'test-session', argv);
792
+ const config = await loadCliConfig(settings, 'test-session', argv);
770
793
  const excludedTools = config.getExcludeTools();
771
794
  expect(excludedTools).toContain(SHELL_TOOL_NAME);
772
795
  expect(excludedTools).toContain(EDIT_TOOL_NAME);
@@ -783,8 +806,7 @@ describe('Approval mode tool exclusion logic', () => {
783
806
  ];
784
807
  const argv = await parseArguments({});
785
808
  const settings = {};
786
- const extensions = [];
787
- const config = await loadCliConfig(settings, extensions, 'test-session', argv);
809
+ const config = await loadCliConfig(settings, 'test-session', argv);
788
810
  const excludedTools = config.getExcludeTools();
789
811
  expect(excludedTools).toContain(SHELL_TOOL_NAME);
790
812
  expect(excludedTools).not.toContain(EDIT_TOOL_NAME);
@@ -801,8 +823,7 @@ describe('Approval mode tool exclusion logic', () => {
801
823
  ];
802
824
  const argv = await parseArguments({});
803
825
  const settings = {};
804
- const extensions = [];
805
- const config = await loadCliConfig(settings, extensions, 'test-session', argv);
826
+ const config = await loadCliConfig(settings, 'test-session', argv);
806
827
  const excludedTools = config.getExcludeTools();
807
828
  expect(excludedTools).not.toContain(SHELL_TOOL_NAME);
808
829
  expect(excludedTools).not.toContain(EDIT_TOOL_NAME);
@@ -812,8 +833,7 @@ describe('Approval mode tool exclusion logic', () => {
812
833
  process.argv = ['node', 'script.js', '--yolo', '-p', 'test'];
813
834
  const argv = await parseArguments({});
814
835
  const settings = {};
815
- const extensions = [];
816
- const config = await loadCliConfig(settings, extensions, 'test-session', argv);
836
+ const config = await loadCliConfig(settings, 'test-session', argv);
817
837
  const excludedTools = config.getExcludeTools();
818
838
  expect(excludedTools).not.toContain(SHELL_TOOL_NAME);
819
839
  expect(excludedTools).not.toContain(EDIT_TOOL_NAME);
@@ -832,8 +852,7 @@ describe('Approval mode tool exclusion logic', () => {
832
852
  process.argv = testCase.args;
833
853
  const argv = await parseArguments({});
834
854
  const settings = {};
835
- const extensions = [];
836
- const config = await loadCliConfig(settings, extensions, 'test-session', argv);
855
+ const config = await loadCliConfig(settings, 'test-session', argv);
837
856
  const excludedTools = config.getExcludeTools();
838
857
  expect(excludedTools).not.toContain(SHELL_TOOL_NAME);
839
858
  expect(excludedTools).not.toContain(EDIT_TOOL_NAME);
@@ -851,8 +870,7 @@ describe('Approval mode tool exclusion logic', () => {
851
870
  ];
852
871
  const argv = await parseArguments({});
853
872
  const settings = { tools: { exclude: ['custom_tool'] } };
854
- const extensions = [];
855
- const config = await loadCliConfig(settings, extensions, 'test-session', argv);
873
+ const config = await loadCliConfig(settings, 'test-session', argv);
856
874
  const excludedTools = config.getExcludeTools();
857
875
  expect(excludedTools).toContain('custom_tool'); // From settings
858
876
  expect(excludedTools).toContain(SHELL_TOOL_NAME); // From approval mode
@@ -867,8 +885,7 @@ describe('Approval mode tool exclusion logic', () => {
867
885
  disableYoloMode: true,
868
886
  },
869
887
  };
870
- const extensions = [];
871
- await expect(loadCliConfig(settings, extensions, 'test-session', argv)).rejects.toThrow('Cannot start in YOLO mode when it is disabled by settings');
888
+ await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow('Cannot start in YOLO mode when it is disabled by settings');
872
889
  });
873
890
  it('should throw an error for invalid approval mode values in loadCliConfig', async () => {
874
891
  // Create a mock argv with an invalid approval mode that bypasses argument parsing validation
@@ -879,19 +896,17 @@ describe('Approval mode tool exclusion logic', () => {
879
896
  yolo: false,
880
897
  };
881
898
  const settings = {};
882
- const extensions = [];
883
- await expect(loadCliConfig(settings, extensions, 'test-session', invalidArgv)).rejects.toThrow('Invalid approval mode: invalid_mode. Valid values are: yolo, auto_edit, default');
899
+ await expect(loadCliConfig(settings, 'test-session', invalidArgv)).rejects.toThrow('Invalid approval mode: invalid_mode. Valid values are: yolo, auto_edit, default');
884
900
  });
885
901
  });
886
902
  describe('loadCliConfig with allowed-mcp-server-names', () => {
887
- const originalArgv = process.argv;
888
903
  beforeEach(() => {
889
904
  vi.resetAllMocks();
890
905
  vi.mocked(os.homedir).mockReturnValue('/mock/home/user');
891
906
  vi.stubEnv('GEMINI_API_KEY', 'test-api-key');
907
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
892
908
  });
893
909
  afterEach(() => {
894
- process.argv = originalArgv;
895
910
  vi.unstubAllEnvs();
896
911
  vi.restoreAllMocks();
897
912
  });
@@ -905,7 +920,7 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
905
920
  it('should allow all MCP servers if the flag is not provided', async () => {
906
921
  process.argv = ['node', 'script.js'];
907
922
  const argv = await parseArguments({});
908
- const config = await loadCliConfig(baseSettings, [], 'test-session', argv);
923
+ const config = await loadCliConfig(baseSettings, 'test-session', argv);
909
924
  expect(config.getMcpServers()).toEqual(baseSettings.mcpServers);
910
925
  });
911
926
  it('should allow only the specified MCP server', async () => {
@@ -916,7 +931,7 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
916
931
  'server1',
917
932
  ];
918
933
  const argv = await parseArguments({});
919
- const config = await loadCliConfig(baseSettings, [], 'test-session', argv);
934
+ const config = await loadCliConfig(baseSettings, 'test-session', argv);
920
935
  expect(config.getMcpServers()).toEqual({
921
936
  server1: { url: 'http://localhost:8080' },
922
937
  });
@@ -931,7 +946,7 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
931
946
  'server3',
932
947
  ];
933
948
  const argv = await parseArguments({});
934
- const config = await loadCliConfig(baseSettings, [], 'test-session', argv);
949
+ const config = await loadCliConfig(baseSettings, 'test-session', argv);
935
950
  expect(config.getMcpServers()).toEqual({
936
951
  server1: { url: 'http://localhost:8080' },
937
952
  server3: { url: 'http://localhost:8082' },
@@ -947,7 +962,7 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
947
962
  'server4',
948
963
  ];
949
964
  const argv = await parseArguments({});
950
- const config = await loadCliConfig(baseSettings, [], 'test-session', argv);
965
+ const config = await loadCliConfig(baseSettings, 'test-session', argv);
951
966
  expect(config.getMcpServers()).toEqual({
952
967
  server1: { url: 'http://localhost:8080' },
953
968
  });
@@ -955,7 +970,7 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
955
970
  it('should allow no MCP servers if the flag is provided but empty', async () => {
956
971
  process.argv = ['node', 'script.js', '--allowed-mcp-server-names', ''];
957
972
  const argv = await parseArguments({});
958
- const config = await loadCliConfig(baseSettings, [], 'test-session', argv);
973
+ const config = await loadCliConfig(baseSettings, 'test-session', argv);
959
974
  expect(config.getMcpServers()).toEqual({});
960
975
  });
961
976
  it('should read allowMCPServers from settings', async () => {
@@ -965,7 +980,7 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
965
980
  ...baseSettings,
966
981
  mcp: { allowed: ['server1', 'server2'] },
967
982
  };
968
- const config = await loadCliConfig(settings, [], 'test-session', argv);
983
+ const config = await loadCliConfig(settings, 'test-session', argv);
969
984
  expect(config.getMcpServers()).toEqual({
970
985
  server1: { url: 'http://localhost:8080' },
971
986
  server2: { url: 'http://localhost:8081' },
@@ -978,7 +993,7 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
978
993
  ...baseSettings,
979
994
  mcp: { excluded: ['server1', 'server2'] },
980
995
  };
981
- const config = await loadCliConfig(settings, [], 'test-session', argv);
996
+ const config = await loadCliConfig(settings, 'test-session', argv);
982
997
  expect(config.getMcpServers()).toEqual({
983
998
  server3: { url: 'http://localhost:8082' },
984
999
  });
@@ -993,7 +1008,7 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
993
1008
  allowed: ['server1', 'server2'],
994
1009
  },
995
1010
  };
996
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1011
+ const config = await loadCliConfig(settings, 'test-session', argv);
997
1012
  expect(config.getMcpServers()).toEqual({
998
1013
  server2: { url: 'http://localhost:8081' },
999
1014
  });
@@ -1013,7 +1028,7 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
1013
1028
  allowed: ['server2'],
1014
1029
  },
1015
1030
  };
1016
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1031
+ const config = await loadCliConfig(settings, 'test-session', argv);
1017
1032
  expect(config.getMcpServers()).toEqual({
1018
1033
  server1: { url: 'http://localhost:8080' },
1019
1034
  });
@@ -1035,7 +1050,7 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
1035
1050
  excluded: ['server3'], // Should be ignored
1036
1051
  },
1037
1052
  };
1038
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1053
+ const config = await loadCliConfig(settings, 'test-session', argv);
1039
1054
  expect(config.getMcpServers()).toEqual({
1040
1055
  server2: { url: 'http://localhost:8081' },
1041
1056
  server3: { url: 'http://localhost:8082' },
@@ -1043,44 +1058,56 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
1043
1058
  });
1044
1059
  });
1045
1060
  describe('loadCliConfig model selection', () => {
1061
+ beforeEach(() => {
1062
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
1063
+ });
1064
+ afterEach(() => {
1065
+ vi.resetAllMocks();
1066
+ });
1046
1067
  it('selects a model from settings.json if provided', async () => {
1047
1068
  process.argv = ['node', 'script.js'];
1048
1069
  const argv = await parseArguments({});
1049
1070
  const config = await loadCliConfig({
1050
1071
  model: {
1051
- name: 'gemini-9001-ultra',
1072
+ name: 'gemini-2.5-pro',
1052
1073
  },
1053
- }, [], 'test-session', argv);
1054
- expect(config.getModel()).toBe('gemini-9001-ultra');
1074
+ }, 'test-session', argv);
1075
+ expect(config.getModel()).toBe('gemini-2.5-pro');
1055
1076
  });
1056
1077
  it('uses the default gemini model if nothing is set', async () => {
1057
1078
  process.argv = ['node', 'script.js']; // No model set.
1058
1079
  const argv = await parseArguments({});
1059
1080
  const config = await loadCliConfig({
1060
1081
  // No model set.
1061
- }, [], 'test-session', argv);
1082
+ }, 'test-session', argv);
1062
1083
  expect(config.getModel()).toBe('auto');
1063
1084
  });
1064
1085
  it('always prefers model from argv', async () => {
1065
- process.argv = ['node', 'script.js', '--model', 'gemini-8675309-ultra'];
1086
+ process.argv = ['node', 'script.js', '--model', 'gemini-2.5-flash-preview'];
1066
1087
  const argv = await parseArguments({});
1067
1088
  const config = await loadCliConfig({
1068
1089
  model: {
1069
- name: 'gemini-9001-ultra',
1090
+ name: 'gemini-2.5-pro',
1070
1091
  },
1071
- }, [], 'test-session', argv);
1072
- expect(config.getModel()).toBe('gemini-8675309-ultra');
1092
+ }, 'test-session', argv);
1093
+ expect(config.getModel()).toBe('gemini-2.5-flash-preview');
1073
1094
  });
1074
1095
  it('selects the model from argv if provided', async () => {
1075
- process.argv = ['node', 'script.js', '--model', 'gemini-8675309-ultra'];
1096
+ process.argv = ['node', 'script.js', '--model', 'gemini-2.5-flash-preview'];
1076
1097
  const argv = await parseArguments({});
1077
1098
  const config = await loadCliConfig({
1078
1099
  // No model provided via settings.
1079
- }, [], 'test-session', argv);
1080
- expect(config.getModel()).toBe('gemini-8675309-ultra');
1100
+ }, 'test-session', argv);
1101
+ expect(config.getModel()).toBe('gemini-2.5-flash-preview');
1081
1102
  });
1082
1103
  });
1083
1104
  describe('loadCliConfig model selection with model router', () => {
1105
+ beforeEach(() => {
1106
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
1107
+ });
1108
+ afterEach(() => {
1109
+ vi.resetAllMocks();
1110
+ });
1084
1111
  it('should use auto model when useModelRouter is true and no model is provided', async () => {
1085
1112
  process.argv = ['node', 'script.js'];
1086
1113
  const argv = await parseArguments({});
@@ -1088,7 +1115,7 @@ describe('loadCliConfig model selection with model router', () => {
1088
1115
  experimental: {
1089
1116
  useModelRouter: true,
1090
1117
  },
1091
- }, [], 'test-session', argv);
1118
+ }, 'test-session', argv);
1092
1119
  expect(config.getModel()).toBe(DEFAULT_GEMINI_MODEL_AUTO);
1093
1120
  });
1094
1121
  it('should use default model when useModelRouter is false and no model is provided', async () => {
@@ -1098,7 +1125,7 @@ describe('loadCliConfig model selection with model router', () => {
1098
1125
  experimental: {
1099
1126
  useModelRouter: false,
1100
1127
  },
1101
- }, [], 'test-session', argv);
1128
+ }, 'test-session', argv);
1102
1129
  expect(config.getModel()).toBe(DEFAULT_GEMINI_MODEL);
1103
1130
  });
1104
1131
  it('should prioritize argv over useModelRouter', async () => {
@@ -1108,7 +1135,7 @@ describe('loadCliConfig model selection with model router', () => {
1108
1135
  experimental: {
1109
1136
  useModelRouter: true,
1110
1137
  },
1111
- }, [], 'test-session', argv);
1138
+ }, 'test-session', argv);
1112
1139
  expect(config.getModel()).toBe('gemini-from-argv');
1113
1140
  });
1114
1141
  it('should prioritize settings over useModelRouter', async () => {
@@ -1121,7 +1148,7 @@ describe('loadCliConfig model selection with model router', () => {
1121
1148
  model: {
1122
1149
  name: 'gemini-from-settings',
1123
1150
  },
1124
- }, [], 'test-session', argv);
1151
+ }, 'test-session', argv);
1125
1152
  expect(config.getModel()).toBe('gemini-from-settings');
1126
1153
  });
1127
1154
  it('should prioritize environment variable over useModelRouter', async () => {
@@ -1132,19 +1159,18 @@ describe('loadCliConfig model selection with model router', () => {
1132
1159
  experimental: {
1133
1160
  useModelRouter: true,
1134
1161
  },
1135
- }, [], 'test-session', argv);
1162
+ }, 'test-session', argv);
1136
1163
  expect(config.getModel()).toBe('gemini-from-env');
1137
1164
  });
1138
1165
  });
1139
1166
  describe('loadCliConfig folderTrust', () => {
1140
- const originalArgv = process.argv;
1141
1167
  beforeEach(() => {
1142
1168
  vi.resetAllMocks();
1143
1169
  vi.mocked(os.homedir).mockReturnValue('/mock/home/user');
1144
1170
  vi.stubEnv('GEMINI_API_KEY', 'test-api-key');
1171
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
1145
1172
  });
1146
1173
  afterEach(() => {
1147
- process.argv = originalArgv;
1148
1174
  vi.unstubAllEnvs();
1149
1175
  vi.restoreAllMocks();
1150
1176
  });
@@ -1158,7 +1184,7 @@ describe('loadCliConfig folderTrust', () => {
1158
1184
  },
1159
1185
  };
1160
1186
  const argv = await parseArguments({});
1161
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1187
+ const config = await loadCliConfig(settings, 'test-session', argv);
1162
1188
  expect(config.getFolderTrust()).toBe(false);
1163
1189
  });
1164
1190
  it('should be true when folderTrust is true', async () => {
@@ -1171,28 +1197,26 @@ describe('loadCliConfig folderTrust', () => {
1171
1197
  },
1172
1198
  },
1173
1199
  };
1174
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1200
+ const config = await loadCliConfig(settings, 'test-session', argv);
1175
1201
  expect(config.getFolderTrust()).toBe(true);
1176
1202
  });
1177
1203
  it('should be false by default', async () => {
1178
1204
  process.argv = ['node', 'script.js'];
1179
1205
  const argv = await parseArguments({});
1180
1206
  const settings = {};
1181
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1207
+ const config = await loadCliConfig(settings, 'test-session', argv);
1182
1208
  expect(config.getFolderTrust()).toBe(false);
1183
1209
  });
1184
1210
  });
1185
1211
  describe('loadCliConfig with includeDirectories', () => {
1186
- const originalArgv = process.argv;
1187
1212
  beforeEach(() => {
1188
1213
  vi.resetAllMocks();
1189
1214
  vi.mocked(os.homedir).mockReturnValue('/mock/home/user');
1190
1215
  vi.stubEnv('GEMINI_API_KEY', 'test-api-key');
1191
1216
  vi.spyOn(process, 'cwd').mockReturnValue(path.resolve(path.sep, 'home', 'user', 'project'));
1217
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
1192
1218
  });
1193
1219
  afterEach(() => {
1194
- process.argv = originalArgv;
1195
- vi.unstubAllEnvs();
1196
1220
  vi.restoreAllMocks();
1197
1221
  });
1198
1222
  it('should combine and resolve paths from settings and CLI arguments', async () => {
@@ -1213,7 +1237,7 @@ describe('loadCliConfig with includeDirectories', () => {
1213
1237
  ],
1214
1238
  },
1215
1239
  };
1216
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1240
+ const config = await loadCliConfig(settings, 'test-session', argv);
1217
1241
  const expected = [
1218
1242
  mockCwd,
1219
1243
  path.resolve(path.sep, 'cli', 'path1'),
@@ -1227,14 +1251,13 @@ describe('loadCliConfig with includeDirectories', () => {
1227
1251
  });
1228
1252
  });
1229
1253
  describe('loadCliConfig chatCompression', () => {
1230
- const originalArgv = process.argv;
1231
1254
  beforeEach(() => {
1232
1255
  vi.resetAllMocks();
1233
1256
  vi.mocked(os.homedir).mockReturnValue('/mock/home/user');
1234
1257
  vi.stubEnv('GEMINI_API_KEY', 'test-api-key');
1258
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
1235
1259
  });
1236
1260
  afterEach(() => {
1237
- process.argv = originalArgv;
1238
1261
  vi.unstubAllEnvs();
1239
1262
  vi.restoreAllMocks();
1240
1263
  });
@@ -1248,7 +1271,7 @@ describe('loadCliConfig chatCompression', () => {
1248
1271
  },
1249
1272
  },
1250
1273
  };
1251
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1274
+ const config = await loadCliConfig(settings, 'test-session', argv);
1252
1275
  expect(config.getChatCompression()).toEqual({
1253
1276
  contextPercentageThreshold: 0.5,
1254
1277
  });
@@ -1257,19 +1280,18 @@ describe('loadCliConfig chatCompression', () => {
1257
1280
  process.argv = ['node', 'script.js'];
1258
1281
  const argv = await parseArguments({});
1259
1282
  const settings = {};
1260
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1283
+ const config = await loadCliConfig(settings, 'test-session', argv);
1261
1284
  expect(config.getChatCompression()).toBeUndefined();
1262
1285
  });
1263
1286
  });
1264
1287
  describe('loadCliConfig useRipgrep', () => {
1265
- const originalArgv = process.argv;
1266
1288
  beforeEach(() => {
1267
1289
  vi.resetAllMocks();
1268
1290
  vi.mocked(os.homedir).mockReturnValue('/mock/home/user');
1269
1291
  vi.stubEnv('GEMINI_API_KEY', 'test-api-key');
1292
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
1270
1293
  });
1271
1294
  afterEach(() => {
1272
- process.argv = originalArgv;
1273
1295
  vi.unstubAllEnvs();
1274
1296
  vi.restoreAllMocks();
1275
1297
  });
@@ -1277,21 +1299,21 @@ describe('loadCliConfig useRipgrep', () => {
1277
1299
  process.argv = ['node', 'script.js'];
1278
1300
  const argv = await parseArguments({});
1279
1301
  const settings = {};
1280
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1302
+ const config = await loadCliConfig(settings, 'test-session', argv);
1281
1303
  expect(config.getUseRipgrep()).toBe(true);
1282
1304
  });
1283
1305
  it('should be false when useRipgrep is set to false in settings', async () => {
1284
1306
  process.argv = ['node', 'script.js'];
1285
1307
  const argv = await parseArguments({});
1286
1308
  const settings = { tools: { useRipgrep: false } };
1287
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1309
+ const config = await loadCliConfig(settings, 'test-session', argv);
1288
1310
  expect(config.getUseRipgrep()).toBe(false);
1289
1311
  });
1290
1312
  it('should be true when useRipgrep is explicitly set to true in settings', async () => {
1291
1313
  process.argv = ['node', 'script.js'];
1292
1314
  const argv = await parseArguments({});
1293
1315
  const settings = { tools: { useRipgrep: true } };
1294
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1316
+ const config = await loadCliConfig(settings, 'test-session', argv);
1295
1317
  expect(config.getUseRipgrep()).toBe(true);
1296
1318
  });
1297
1319
  describe('loadCliConfig useModelRouter', () => {
@@ -1299,34 +1321,33 @@ describe('loadCliConfig useRipgrep', () => {
1299
1321
  process.argv = ['node', 'script.js'];
1300
1322
  const argv = await parseArguments({});
1301
1323
  const settings = {};
1302
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1324
+ const config = await loadCliConfig(settings, 'test-session', argv);
1303
1325
  expect(config.getUseModelRouter()).toBe(true);
1304
1326
  });
1305
1327
  it('should be true when useModelRouter is set to true in settings', async () => {
1306
1328
  process.argv = ['node', 'script.js'];
1307
1329
  const argv = await parseArguments({});
1308
1330
  const settings = { experimental: { useModelRouter: true } };
1309
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1331
+ const config = await loadCliConfig(settings, 'test-session', argv);
1310
1332
  expect(config.getUseModelRouter()).toBe(true);
1311
1333
  });
1312
1334
  it('should be false when useModelRouter is explicitly set to false in settings', async () => {
1313
1335
  process.argv = ['node', 'script.js'];
1314
1336
  const argv = await parseArguments({});
1315
1337
  const settings = { experimental: { useModelRouter: false } };
1316
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1338
+ const config = await loadCliConfig(settings, 'test-session', argv);
1317
1339
  expect(config.getUseModelRouter()).toBe(false);
1318
1340
  });
1319
1341
  });
1320
1342
  });
1321
1343
  describe('screenReader configuration', () => {
1322
- const originalArgv = process.argv;
1323
1344
  beforeEach(() => {
1324
1345
  vi.resetAllMocks();
1325
1346
  vi.mocked(os.homedir).mockReturnValue('/mock/home/user');
1326
1347
  vi.stubEnv('GEMINI_API_KEY', 'test-api-key');
1348
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
1327
1349
  });
1328
1350
  afterEach(() => {
1329
- process.argv = originalArgv;
1330
1351
  vi.unstubAllEnvs();
1331
1352
  vi.restoreAllMocks();
1332
1353
  });
@@ -1336,7 +1357,7 @@ describe('screenReader configuration', () => {
1336
1357
  const settings = {
1337
1358
  ui: { accessibility: { screenReader: true } },
1338
1359
  };
1339
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1360
+ const config = await loadCliConfig(settings, 'test-session', argv);
1340
1361
  expect(config.getScreenReader()).toBe(true);
1341
1362
  });
1342
1363
  it('should use screenReader value from settings if CLI flag is not present (settings false)', async () => {
@@ -1345,7 +1366,7 @@ describe('screenReader configuration', () => {
1345
1366
  const settings = {
1346
1367
  ui: { accessibility: { screenReader: false } },
1347
1368
  };
1348
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1369
+ const config = await loadCliConfig(settings, 'test-session', argv);
1349
1370
  expect(config.getScreenReader()).toBe(false);
1350
1371
  });
1351
1372
  it('should prioritize --screen-reader CLI flag (true) over settings (false)', async () => {
@@ -1354,19 +1375,18 @@ describe('screenReader configuration', () => {
1354
1375
  const settings = {
1355
1376
  ui: { accessibility: { screenReader: false } },
1356
1377
  };
1357
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1378
+ const config = await loadCliConfig(settings, 'test-session', argv);
1358
1379
  expect(config.getScreenReader()).toBe(true);
1359
1380
  });
1360
1381
  it('should be false by default when no flag or setting is present', async () => {
1361
1382
  process.argv = ['node', 'script.js'];
1362
1383
  const argv = await parseArguments({});
1363
1384
  const settings = {};
1364
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1385
+ const config = await loadCliConfig(settings, 'test-session', argv);
1365
1386
  expect(config.getScreenReader()).toBe(false);
1366
1387
  });
1367
1388
  });
1368
1389
  describe('loadCliConfig tool exclusions', () => {
1369
- const originalArgv = process.argv;
1370
1390
  const originalIsTTY = process.stdin.isTTY;
1371
1391
  beforeEach(() => {
1372
1392
  vi.resetAllMocks();
@@ -1377,9 +1397,9 @@ describe('loadCliConfig tool exclusions', () => {
1377
1397
  isTrusted: true,
1378
1398
  source: undefined,
1379
1399
  });
1400
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
1380
1401
  });
1381
1402
  afterEach(() => {
1382
- process.argv = originalArgv;
1383
1403
  process.stdin.isTTY = originalIsTTY;
1384
1404
  vi.unstubAllEnvs();
1385
1405
  vi.restoreAllMocks();
@@ -1388,7 +1408,7 @@ describe('loadCliConfig tool exclusions', () => {
1388
1408
  process.stdin.isTTY = true;
1389
1409
  process.argv = ['node', 'script.js'];
1390
1410
  const argv = await parseArguments({});
1391
- const config = await loadCliConfig({}, [], 'test-session', argv);
1411
+ const config = await loadCliConfig({}, 'test-session', argv);
1392
1412
  expect(config.getExcludeTools()).not.toContain('run_shell_command');
1393
1413
  expect(config.getExcludeTools()).not.toContain('replace');
1394
1414
  expect(config.getExcludeTools()).not.toContain('write_file');
@@ -1397,7 +1417,7 @@ describe('loadCliConfig tool exclusions', () => {
1397
1417
  process.stdin.isTTY = true;
1398
1418
  process.argv = ['node', 'script.js', '--yolo'];
1399
1419
  const argv = await parseArguments({});
1400
- const config = await loadCliConfig({}, [], 'test-session', argv);
1420
+ const config = await loadCliConfig({}, 'test-session', argv);
1401
1421
  expect(config.getExcludeTools()).not.toContain('run_shell_command');
1402
1422
  expect(config.getExcludeTools()).not.toContain('replace');
1403
1423
  expect(config.getExcludeTools()).not.toContain('write_file');
@@ -1406,7 +1426,7 @@ describe('loadCliConfig tool exclusions', () => {
1406
1426
  process.stdin.isTTY = false;
1407
1427
  process.argv = ['node', 'script.js', '-p', 'test'];
1408
1428
  const argv = await parseArguments({});
1409
- const config = await loadCliConfig({}, [], 'test-session', argv);
1429
+ const config = await loadCliConfig({}, 'test-session', argv);
1410
1430
  expect(config.getExcludeTools()).toContain('run_shell_command');
1411
1431
  expect(config.getExcludeTools()).toContain('replace');
1412
1432
  expect(config.getExcludeTools()).toContain('write_file');
@@ -1415,7 +1435,7 @@ describe('loadCliConfig tool exclusions', () => {
1415
1435
  process.stdin.isTTY = false;
1416
1436
  process.argv = ['node', 'script.js', '-p', 'test', '--yolo'];
1417
1437
  const argv = await parseArguments({});
1418
- const config = await loadCliConfig({}, [], 'test-session', argv);
1438
+ const config = await loadCliConfig({}, 'test-session', argv);
1419
1439
  expect(config.getExcludeTools()).not.toContain('run_shell_command');
1420
1440
  expect(config.getExcludeTools()).not.toContain('replace');
1421
1441
  expect(config.getExcludeTools()).not.toContain('write_file');
@@ -1431,7 +1451,7 @@ describe('loadCliConfig tool exclusions', () => {
1431
1451
  'ShellTool',
1432
1452
  ];
1433
1453
  const argv = await parseArguments({});
1434
- const config = await loadCliConfig({}, [], 'test-session', argv);
1454
+ const config = await loadCliConfig({}, 'test-session', argv);
1435
1455
  expect(config.getExcludeTools()).not.toContain(SHELL_TOOL_NAME);
1436
1456
  });
1437
1457
  it('should not exclude shell tool in non-interactive mode when --allowed-tools="run_shell_command" is set', async () => {
@@ -1445,7 +1465,7 @@ describe('loadCliConfig tool exclusions', () => {
1445
1465
  'run_shell_command',
1446
1466
  ];
1447
1467
  const argv = await parseArguments({});
1448
- const config = await loadCliConfig({}, [], 'test-session', argv);
1468
+ const config = await loadCliConfig({}, 'test-session', argv);
1449
1469
  expect(config.getExcludeTools()).not.toContain(SHELL_TOOL_NAME);
1450
1470
  });
1451
1471
  it('should not exclude shell tool in non-interactive mode when --allowed-tools="ShellTool(wc)" is set', async () => {
@@ -1459,21 +1479,20 @@ describe('loadCliConfig tool exclusions', () => {
1459
1479
  'ShellTool(wc)',
1460
1480
  ];
1461
1481
  const argv = await parseArguments({});
1462
- const config = await loadCliConfig({}, [], 'test-session', argv);
1482
+ const config = await loadCliConfig({}, 'test-session', argv);
1463
1483
  expect(config.getExcludeTools()).not.toContain(SHELL_TOOL_NAME);
1464
1484
  });
1465
1485
  });
1466
1486
  describe('loadCliConfig interactive', () => {
1467
- const originalArgv = process.argv;
1468
1487
  const originalIsTTY = process.stdin.isTTY;
1469
1488
  beforeEach(() => {
1470
1489
  vi.resetAllMocks();
1471
1490
  vi.mocked(os.homedir).mockReturnValue('/mock/home/user');
1472
1491
  vi.stubEnv('GEMINI_API_KEY', 'test-api-key');
1473
1492
  process.stdin.isTTY = true;
1493
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
1474
1494
  });
1475
1495
  afterEach(() => {
1476
- process.argv = originalArgv;
1477
1496
  process.stdin.isTTY = originalIsTTY;
1478
1497
  vi.unstubAllEnvs();
1479
1498
  vi.restoreAllMocks();
@@ -1482,35 +1501,35 @@ describe('loadCliConfig interactive', () => {
1482
1501
  process.stdin.isTTY = true;
1483
1502
  process.argv = ['node', 'script.js'];
1484
1503
  const argv = await parseArguments({});
1485
- const config = await loadCliConfig({}, [], 'test-session', argv);
1504
+ const config = await loadCliConfig({}, 'test-session', argv);
1486
1505
  expect(config.isInteractive()).toBe(true);
1487
1506
  });
1488
1507
  it('should be interactive if prompt-interactive is set', async () => {
1489
1508
  process.stdin.isTTY = false;
1490
1509
  process.argv = ['node', 'script.js', '--prompt-interactive', 'test'];
1491
1510
  const argv = await parseArguments({});
1492
- const config = await loadCliConfig({}, [], 'test-session', argv);
1511
+ const config = await loadCliConfig({}, 'test-session', argv);
1493
1512
  expect(config.isInteractive()).toBe(true);
1494
1513
  });
1495
1514
  it('should not be interactive if not isTTY and no prompt', async () => {
1496
1515
  process.stdin.isTTY = false;
1497
1516
  process.argv = ['node', 'script.js'];
1498
1517
  const argv = await parseArguments({});
1499
- const config = await loadCliConfig({}, [], 'test-session', argv);
1518
+ const config = await loadCliConfig({}, 'test-session', argv);
1500
1519
  expect(config.isInteractive()).toBe(false);
1501
1520
  });
1502
1521
  it('should not be interactive if prompt is set', async () => {
1503
1522
  process.stdin.isTTY = true;
1504
1523
  process.argv = ['node', 'script.js', '--prompt', 'test'];
1505
1524
  const argv = await parseArguments({});
1506
- const config = await loadCliConfig({}, [], 'test-session', argv);
1525
+ const config = await loadCliConfig({}, 'test-session', argv);
1507
1526
  expect(config.isInteractive()).toBe(false);
1508
1527
  });
1509
1528
  it('should not be interactive if positional prompt words are provided with other flags', async () => {
1510
1529
  process.stdin.isTTY = true;
1511
- process.argv = ['node', 'script.js', '--model', 'gemini-1.5-pro', 'Hello'];
1530
+ process.argv = ['node', 'script.js', '--model', 'gemini-2.5-pro', 'Hello'];
1512
1531
  const argv = await parseArguments({});
1513
- const config = await loadCliConfig({}, [], 'test-session', argv);
1532
+ const config = await loadCliConfig({}, 'test-session', argv);
1514
1533
  expect(config.isInteractive()).toBe(false);
1515
1534
  });
1516
1535
  it('should not be interactive if positional prompt words are provided with multiple flags', async () => {
@@ -1519,12 +1538,12 @@ describe('loadCliConfig interactive', () => {
1519
1538
  'node',
1520
1539
  'script.js',
1521
1540
  '--model',
1522
- 'gemini-1.5-pro',
1541
+ 'gemini-2.5-pro',
1523
1542
  '--yolo',
1524
1543
  'Hello world',
1525
1544
  ];
1526
1545
  const argv = await parseArguments({});
1527
- const config = await loadCliConfig({}, [], 'test-session', argv);
1546
+ const config = await loadCliConfig({}, 'test-session', argv);
1528
1547
  expect(config.isInteractive()).toBe(false);
1529
1548
  // Verify the question is preserved for one-shot execution
1530
1549
  expect(argv.prompt).toBe('Hello world');
@@ -1534,7 +1553,7 @@ describe('loadCliConfig interactive', () => {
1534
1553
  process.stdin.isTTY = true;
1535
1554
  process.argv = ['node', 'script.js', '-e', 'none', 'hello'];
1536
1555
  const argv = await parseArguments({});
1537
- const config = await loadCliConfig({}, [], 'test-session', argv);
1556
+ const config = await loadCliConfig({}, 'test-session', argv);
1538
1557
  expect(config.isInteractive()).toBe(false);
1539
1558
  expect(argv.query).toBe('hello');
1540
1559
  expect(argv.extensions).toEqual(['none']);
@@ -1543,7 +1562,7 @@ describe('loadCliConfig interactive', () => {
1543
1562
  process.stdin.isTTY = true;
1544
1563
  process.argv = ['node', 'script.js', 'hello world how are you'];
1545
1564
  const argv = await parseArguments({});
1546
- const config = await loadCliConfig({}, [], 'test-session', argv);
1565
+ const config = await loadCliConfig({}, 'test-session', argv);
1547
1566
  expect(config.isInteractive()).toBe(false);
1548
1567
  expect(argv.query).toBe('hello world how are you');
1549
1568
  expect(argv.prompt).toBe('hello world how are you');
@@ -1554,7 +1573,7 @@ describe('loadCliConfig interactive', () => {
1554
1573
  'node',
1555
1574
  'script.js',
1556
1575
  '--model',
1557
- 'gemini-1.5-pro',
1576
+ 'gemini-2.5-pro',
1558
1577
  'write',
1559
1578
  'a',
1560
1579
  'function',
@@ -1563,16 +1582,16 @@ describe('loadCliConfig interactive', () => {
1563
1582
  'array',
1564
1583
  ];
1565
1584
  const argv = await parseArguments({});
1566
- const config = await loadCliConfig({}, [], 'test-session', argv);
1585
+ const config = await loadCliConfig({}, 'test-session', argv);
1567
1586
  expect(config.isInteractive()).toBe(false);
1568
1587
  expect(argv.query).toBe('write a function to sort array');
1569
- expect(argv.model).toBe('gemini-1.5-pro');
1588
+ expect(argv.model).toBe('gemini-2.5-pro');
1570
1589
  });
1571
1590
  it('should handle empty positional arguments', async () => {
1572
1591
  process.stdin.isTTY = true;
1573
1592
  process.argv = ['node', 'script.js', ''];
1574
1593
  const argv = await parseArguments({});
1575
- const config = await loadCliConfig({}, [], 'test-session', argv);
1594
+ const config = await loadCliConfig({}, 'test-session', argv);
1576
1595
  expect(config.isInteractive()).toBe(true);
1577
1596
  expect(argv.query).toBeUndefined();
1578
1597
  });
@@ -1590,16 +1609,16 @@ describe('loadCliConfig interactive', () => {
1590
1609
  'you',
1591
1610
  ];
1592
1611
  const argv = await parseArguments({});
1593
- const config = await loadCliConfig({}, [], 'test-session', argv);
1612
+ const config = await loadCliConfig({}, 'test-session', argv);
1594
1613
  expect(config.isInteractive()).toBe(false);
1595
1614
  expect(argv.query).toBe('hello world how are you');
1596
1615
  expect(argv.extensions).toEqual(['none']);
1597
1616
  });
1598
1617
  it('should be interactive if no positional prompt words are provided with flags', async () => {
1599
1618
  process.stdin.isTTY = true;
1600
- process.argv = ['node', 'script.js', '--model', 'gemini-1.5-pro'];
1619
+ process.argv = ['node', 'script.js', '--model', 'gemini-2.5-pro'];
1601
1620
  const argv = await parseArguments({});
1602
- const config = await loadCliConfig({}, [], 'test-session', argv);
1621
+ const config = await loadCliConfig({}, 'test-session', argv);
1603
1622
  expect(config.isInteractive()).toBe(true);
1604
1623
  });
1605
1624
  });
@@ -1614,6 +1633,7 @@ describe('loadCliConfig approval mode', () => {
1614
1633
  isTrusted: true,
1615
1634
  source: undefined,
1616
1635
  });
1636
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
1617
1637
  });
1618
1638
  afterEach(() => {
1619
1639
  process.argv = originalArgv;
@@ -1623,37 +1643,37 @@ describe('loadCliConfig approval mode', () => {
1623
1643
  it('should default to DEFAULT approval mode when no flags are set', async () => {
1624
1644
  process.argv = ['node', 'script.js'];
1625
1645
  const argv = await parseArguments({});
1626
- const config = await loadCliConfig({}, [], 'test-session', argv);
1646
+ const config = await loadCliConfig({}, 'test-session', argv);
1627
1647
  expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.DEFAULT);
1628
1648
  });
1629
1649
  it('should set YOLO approval mode when --yolo flag is used', async () => {
1630
1650
  process.argv = ['node', 'script.js', '--yolo'];
1631
1651
  const argv = await parseArguments({});
1632
- const config = await loadCliConfig({}, [], 'test-session', argv);
1652
+ const config = await loadCliConfig({}, 'test-session', argv);
1633
1653
  expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.YOLO);
1634
1654
  });
1635
1655
  it('should set YOLO approval mode when -y flag is used', async () => {
1636
1656
  process.argv = ['node', 'script.js', '-y'];
1637
1657
  const argv = await parseArguments({});
1638
- const config = await loadCliConfig({}, [], 'test-session', argv);
1658
+ const config = await loadCliConfig({}, 'test-session', argv);
1639
1659
  expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.YOLO);
1640
1660
  });
1641
1661
  it('should set DEFAULT approval mode when --approval-mode=default', async () => {
1642
1662
  process.argv = ['node', 'script.js', '--approval-mode', 'default'];
1643
1663
  const argv = await parseArguments({});
1644
- const config = await loadCliConfig({}, [], 'test-session', argv);
1664
+ const config = await loadCliConfig({}, 'test-session', argv);
1645
1665
  expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.DEFAULT);
1646
1666
  });
1647
1667
  it('should set AUTO_EDIT approval mode when --approval-mode=auto_edit', async () => {
1648
1668
  process.argv = ['node', 'script.js', '--approval-mode', 'auto_edit'];
1649
1669
  const argv = await parseArguments({});
1650
- const config = await loadCliConfig({}, [], 'test-session', argv);
1670
+ const config = await loadCliConfig({}, 'test-session', argv);
1651
1671
  expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.AUTO_EDIT);
1652
1672
  });
1653
1673
  it('should set YOLO approval mode when --approval-mode=yolo', async () => {
1654
1674
  process.argv = ['node', 'script.js', '--approval-mode', 'yolo'];
1655
1675
  const argv = await parseArguments({});
1656
- const config = await loadCliConfig({}, [], 'test-session', argv);
1676
+ const config = await loadCliConfig({}, 'test-session', argv);
1657
1677
  expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.YOLO);
1658
1678
  });
1659
1679
  it('should prioritize --approval-mode over --yolo when both would be valid (but validation prevents this)', async () => {
@@ -1663,13 +1683,13 @@ describe('loadCliConfig approval mode', () => {
1663
1683
  const argv = await parseArguments({});
1664
1684
  // Manually set yolo to true to simulate what would happen if validation didn't prevent it
1665
1685
  argv.yolo = true;
1666
- const config = await loadCliConfig({}, [], 'test-session', argv);
1686
+ const config = await loadCliConfig({}, 'test-session', argv);
1667
1687
  expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.DEFAULT);
1668
1688
  });
1669
1689
  it('should fall back to --yolo behavior when --approval-mode is not set', async () => {
1670
1690
  process.argv = ['node', 'script.js', '--yolo'];
1671
1691
  const argv = await parseArguments({});
1672
- const config = await loadCliConfig({}, [], 'test-session', argv);
1692
+ const config = await loadCliConfig({}, 'test-session', argv);
1673
1693
  expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.YOLO);
1674
1694
  });
1675
1695
  // --- Untrusted Folder Scenarios ---
@@ -1683,25 +1703,25 @@ describe('loadCliConfig approval mode', () => {
1683
1703
  it('should override --approval-mode=yolo to DEFAULT', async () => {
1684
1704
  process.argv = ['node', 'script.js', '--approval-mode', 'yolo'];
1685
1705
  const argv = await parseArguments({});
1686
- const config = await loadCliConfig({}, [], 'test-session', argv);
1706
+ const config = await loadCliConfig({}, 'test-session', argv);
1687
1707
  expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.DEFAULT);
1688
1708
  });
1689
1709
  it('should override --approval-mode=auto_edit to DEFAULT', async () => {
1690
1710
  process.argv = ['node', 'script.js', '--approval-mode', 'auto_edit'];
1691
1711
  const argv = await parseArguments({});
1692
- const config = await loadCliConfig({}, [], 'test-session', argv);
1712
+ const config = await loadCliConfig({}, 'test-session', argv);
1693
1713
  expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.DEFAULT);
1694
1714
  });
1695
1715
  it('should override --yolo flag to DEFAULT', async () => {
1696
1716
  process.argv = ['node', 'script.js', '--yolo'];
1697
1717
  const argv = await parseArguments({});
1698
- const config = await loadCliConfig({}, [], 'test-session', argv);
1718
+ const config = await loadCliConfig({}, 'test-session', argv);
1699
1719
  expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.DEFAULT);
1700
1720
  });
1701
1721
  it('should remain DEFAULT when --approval-mode=default', async () => {
1702
1722
  process.argv = ['node', 'script.js', '--approval-mode', 'default'];
1703
1723
  const argv = await parseArguments({});
1704
- const config = await loadCliConfig({}, [], 'test-session', argv);
1724
+ const config = await loadCliConfig({}, 'test-session', argv);
1705
1725
  expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.DEFAULT);
1706
1726
  });
1707
1727
  });
@@ -1713,6 +1733,7 @@ describe('loadCliConfig fileFiltering', () => {
1713
1733
  vi.mocked(os.homedir).mockReturnValue('/mock/home/user');
1714
1734
  vi.stubEnv('GEMINI_API_KEY', 'test-api-key');
1715
1735
  process.argv = ['node', 'script.js']; // Reset argv for each test
1736
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
1716
1737
  });
1717
1738
  afterEach(() => {
1718
1739
  process.argv = originalArgv;
@@ -1768,33 +1789,39 @@ describe('loadCliConfig fileFiltering', () => {
1768
1789
  },
1769
1790
  };
1770
1791
  const argv = await parseArguments(settings);
1771
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1792
+ const config = await loadCliConfig(settings, 'test-session', argv);
1772
1793
  expect(getter(config)).toBe(value);
1773
1794
  });
1774
1795
  });
1775
1796
  describe('Output format', () => {
1797
+ beforeEach(() => {
1798
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
1799
+ });
1800
+ afterEach(() => {
1801
+ vi.resetAllMocks();
1802
+ });
1776
1803
  it('should default to TEXT', async () => {
1777
1804
  process.argv = ['node', 'script.js'];
1778
1805
  const argv = await parseArguments({});
1779
- const config = await loadCliConfig({}, [], 'test-session', argv);
1806
+ const config = await loadCliConfig({}, 'test-session', argv);
1780
1807
  expect(config.getOutputFormat()).toBe(OutputFormat.TEXT);
1781
1808
  });
1782
1809
  it('should use the format from settings', async () => {
1783
1810
  process.argv = ['node', 'script.js'];
1784
1811
  const argv = await parseArguments({});
1785
- const config = await loadCliConfig({ output: { format: OutputFormat.JSON } }, [], 'test-session', argv);
1812
+ const config = await loadCliConfig({ output: { format: OutputFormat.JSON } }, 'test-session', argv);
1786
1813
  expect(config.getOutputFormat()).toBe(OutputFormat.JSON);
1787
1814
  });
1788
1815
  it('should prioritize the format from argv', async () => {
1789
1816
  process.argv = ['node', 'script.js', '--output-format', 'json'];
1790
1817
  const argv = await parseArguments({});
1791
- const config = await loadCliConfig({ output: { format: OutputFormat.JSON } }, [], 'test-session', argv);
1818
+ const config = await loadCliConfig({ output: { format: OutputFormat.JSON } }, 'test-session', argv);
1792
1819
  expect(config.getOutputFormat()).toBe(OutputFormat.JSON);
1793
1820
  });
1794
1821
  it('should accept stream-json as a valid output format', async () => {
1795
1822
  process.argv = ['node', 'script.js', '--output-format', 'stream-json'];
1796
1823
  const argv = await parseArguments({});
1797
- const config = await loadCliConfig({}, [], 'test-session', argv);
1824
+ const config = await loadCliConfig({}, 'test-session', argv);
1798
1825
  expect(config.getOutputFormat()).toBe(OutputFormat.STREAM_JSON);
1799
1826
  });
1800
1827
  it('should error on invalid --output-format argument', async () => {
@@ -1860,12 +1887,18 @@ describe('parseArguments with positional prompt', () => {
1860
1887
  });
1861
1888
  });
1862
1889
  describe('Telemetry configuration via environment variables', () => {
1890
+ beforeEach(() => {
1891
+ vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
1892
+ });
1893
+ afterEach(() => {
1894
+ vi.resetAllMocks();
1895
+ });
1863
1896
  it('should prioritize GEMINI_TELEMETRY_ENABLED over settings', async () => {
1864
1897
  vi.stubEnv('GEMINI_TELEMETRY_ENABLED', 'true');
1865
1898
  process.argv = ['node', 'script.js'];
1866
1899
  const argv = await parseArguments({});
1867
1900
  const settings = { telemetry: { enabled: false } };
1868
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1901
+ const config = await loadCliConfig(settings, 'test-session', argv);
1869
1902
  expect(config.getTelemetryEnabled()).toBe(true);
1870
1903
  });
1871
1904
  it('should prioritize GEMINI_TELEMETRY_TARGET over settings', async () => {
@@ -1875,7 +1908,7 @@ describe('Telemetry configuration via environment variables', () => {
1875
1908
  const settings = {
1876
1909
  telemetry: { target: ServerConfig.TelemetryTarget.LOCAL },
1877
1910
  };
1878
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1911
+ const config = await loadCliConfig(settings, 'test-session', argv);
1879
1912
  expect(config.getTelemetryTarget()).toBe('gcp');
1880
1913
  });
1881
1914
  it('should throw when GEMINI_TELEMETRY_TARGET is invalid', async () => {
@@ -1885,7 +1918,7 @@ describe('Telemetry configuration via environment variables', () => {
1885
1918
  const settings = {
1886
1919
  telemetry: { target: ServerConfig.TelemetryTarget.GCP },
1887
1920
  };
1888
- await expect(loadCliConfig(settings, [], 'test-session', argv)).rejects.toThrow(/Invalid telemetry configuration: .*Invalid telemetry target/i);
1921
+ await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow(/Invalid telemetry configuration: .*Invalid telemetry target/i);
1889
1922
  vi.unstubAllEnvs();
1890
1923
  });
1891
1924
  it('should prioritize GEMINI_TELEMETRY_OTLP_ENDPOINT over settings and default env var', async () => {
@@ -1896,7 +1929,7 @@ describe('Telemetry configuration via environment variables', () => {
1896
1929
  const settings = {
1897
1930
  telemetry: { otlpEndpoint: 'http://settings.com' },
1898
1931
  };
1899
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1932
+ const config = await loadCliConfig(settings, 'test-session', argv);
1900
1933
  expect(config.getTelemetryOtlpEndpoint()).toBe('http://gemini.env.com');
1901
1934
  });
1902
1935
  it('should prioritize GEMINI_TELEMETRY_OTLP_PROTOCOL over settings', async () => {
@@ -1904,7 +1937,7 @@ describe('Telemetry configuration via environment variables', () => {
1904
1937
  process.argv = ['node', 'script.js'];
1905
1938
  const argv = await parseArguments({});
1906
1939
  const settings = { telemetry: { otlpProtocol: 'grpc' } };
1907
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1940
+ const config = await loadCliConfig(settings, 'test-session', argv);
1908
1941
  expect(config.getTelemetryOtlpProtocol()).toBe('http');
1909
1942
  });
1910
1943
  it('should prioritize GEMINI_TELEMETRY_LOG_PROMPTS over settings', async () => {
@@ -1912,7 +1945,7 @@ describe('Telemetry configuration via environment variables', () => {
1912
1945
  process.argv = ['node', 'script.js'];
1913
1946
  const argv = await parseArguments({});
1914
1947
  const settings = { telemetry: { logPrompts: true } };
1915
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1948
+ const config = await loadCliConfig(settings, 'test-session', argv);
1916
1949
  expect(config.getTelemetryLogPromptsEnabled()).toBe(false);
1917
1950
  });
1918
1951
  it('should prioritize GEMINI_TELEMETRY_OUTFILE over settings', async () => {
@@ -1922,7 +1955,7 @@ describe('Telemetry configuration via environment variables', () => {
1922
1955
  const settings = {
1923
1956
  telemetry: { outfile: '/settings/telemetry.log' },
1924
1957
  };
1925
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1958
+ const config = await loadCliConfig(settings, 'test-session', argv);
1926
1959
  expect(config.getTelemetryOutfile()).toBe('/gemini/env/telemetry.log');
1927
1960
  });
1928
1961
  it('should prioritize GEMINI_TELEMETRY_USE_COLLECTOR over settings', async () => {
@@ -1930,7 +1963,7 @@ describe('Telemetry configuration via environment variables', () => {
1930
1963
  process.argv = ['node', 'script.js'];
1931
1964
  const argv = await parseArguments({});
1932
1965
  const settings = { telemetry: { useCollector: false } };
1933
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1966
+ const config = await loadCliConfig(settings, 'test-session', argv);
1934
1967
  expect(config.getTelemetryUseCollector()).toBe(true);
1935
1968
  });
1936
1969
  it('should use settings value when GEMINI_TELEMETRY_ENABLED is not set', async () => {
@@ -1938,7 +1971,7 @@ describe('Telemetry configuration via environment variables', () => {
1938
1971
  process.argv = ['node', 'script.js'];
1939
1972
  const argv = await parseArguments({});
1940
1973
  const settings = { telemetry: { enabled: true } };
1941
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1974
+ const config = await loadCliConfig(settings, 'test-session', argv);
1942
1975
  expect(config.getTelemetryEnabled()).toBe(true);
1943
1976
  });
1944
1977
  it('should use settings value when GEMINI_TELEMETRY_TARGET is not set', async () => {
@@ -1948,35 +1981,35 @@ describe('Telemetry configuration via environment variables', () => {
1948
1981
  const settings = {
1949
1982
  telemetry: { target: ServerConfig.TelemetryTarget.LOCAL },
1950
1983
  };
1951
- const config = await loadCliConfig(settings, [], 'test-session', argv);
1984
+ const config = await loadCliConfig(settings, 'test-session', argv);
1952
1985
  expect(config.getTelemetryTarget()).toBe('local');
1953
1986
  });
1954
1987
  it("should treat GEMINI_TELEMETRY_ENABLED='1' as true", async () => {
1955
1988
  vi.stubEnv('GEMINI_TELEMETRY_ENABLED', '1');
1956
1989
  process.argv = ['node', 'script.js'];
1957
1990
  const argv = await parseArguments({});
1958
- const config = await loadCliConfig({}, [], 'test-session', argv);
1991
+ const config = await loadCliConfig({}, 'test-session', argv);
1959
1992
  expect(config.getTelemetryEnabled()).toBe(true);
1960
1993
  });
1961
1994
  it("should treat GEMINI_TELEMETRY_ENABLED='0' as false", async () => {
1962
1995
  vi.stubEnv('GEMINI_TELEMETRY_ENABLED', '0');
1963
1996
  process.argv = ['node', 'script.js'];
1964
1997
  const argv = await parseArguments({});
1965
- const config = await loadCliConfig({ telemetry: { enabled: true } }, [], 'test-session', argv);
1998
+ const config = await loadCliConfig({ telemetry: { enabled: true } }, 'test-session', argv);
1966
1999
  expect(config.getTelemetryEnabled()).toBe(false);
1967
2000
  });
1968
2001
  it("should treat GEMINI_TELEMETRY_LOG_PROMPTS='1' as true", async () => {
1969
2002
  vi.stubEnv('GEMINI_TELEMETRY_LOG_PROMPTS', '1');
1970
2003
  process.argv = ['node', 'script.js'];
1971
2004
  const argv = await parseArguments({});
1972
- const config = await loadCliConfig({}, [], 'test-session', argv);
2005
+ const config = await loadCliConfig({}, 'test-session', argv);
1973
2006
  expect(config.getTelemetryLogPromptsEnabled()).toBe(true);
1974
2007
  });
1975
2008
  it("should treat GEMINI_TELEMETRY_LOG_PROMPTS='false' as false", async () => {
1976
2009
  vi.stubEnv('GEMINI_TELEMETRY_LOG_PROMPTS', 'false');
1977
2010
  process.argv = ['node', 'script.js'];
1978
2011
  const argv = await parseArguments({});
1979
- const config = await loadCliConfig({ telemetry: { logPrompts: true } }, [], 'test-session', argv);
2012
+ const config = await loadCliConfig({ telemetry: { logPrompts: true } }, 'test-session', argv);
1980
2013
  expect(config.getTelemetryLogPromptsEnabled()).toBe(false);
1981
2014
  });
1982
2015
  });