@google/gemini-cli 0.25.0-preview.0 → 0.26.0-nightly.20260119.20580d754
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.26.0-nightly.20260115.6cb3ae4e0.tgz +0 -0
- package/dist/package.json +4 -3
- package/dist/src/commands/extensions/configure.js +8 -1
- package/dist/src/commands/extensions/configure.js.map +1 -1
- package/dist/src/commands/hooks/migrate.js +1 -1
- package/dist/src/commands/hooks/migrate.js.map +1 -1
- package/dist/src/commands/mcp/list.js +2 -2
- package/dist/src/commands/mcp/list.js.map +1 -1
- package/dist/src/commands/mcp/list.test.js +25 -8
- package/dist/src/commands/mcp/list.test.js.map +1 -1
- package/dist/src/commands/skills/disable.js +6 -4
- package/dist/src/commands/skills/disable.js.map +1 -1
- package/dist/src/commands/skills/disable.test.js +16 -0
- package/dist/src/commands/skills/disable.test.js.map +1 -1
- package/dist/src/commands/skills/enable.test.js +3 -3
- package/dist/src/commands/skills/enable.test.js.map +1 -1
- package/dist/src/commands/skills/install.d.ts +1 -0
- package/dist/src/commands/skills/install.js +17 -2
- package/dist/src/commands/skills/install.js.map +1 -1
- package/dist/src/commands/skills/install.test.js +43 -5
- package/dist/src/commands/skills/install.test.js.map +1 -1
- package/dist/src/config/config.d.ts +3 -3
- package/dist/src/config/config.integration.test.js +3 -2
- package/dist/src/config/config.integration.test.js.map +1 -1
- package/dist/src/config/config.js +37 -26
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +361 -280
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/extension-manager-agents.test.js +3 -4
- package/dist/src/config/extension-manager-agents.test.js.map +1 -1
- package/dist/src/config/extension-manager-scope.test.js +13 -15
- package/dist/src/config/extension-manager-scope.test.js.map +1 -1
- package/dist/src/config/extension-manager-skills.test.js +5 -7
- package/dist/src/config/extension-manager-skills.test.js.map +1 -1
- package/dist/src/config/extension-manager.d.ts +2 -2
- package/dist/src/config/extension-manager.js +16 -11
- package/dist/src/config/extension-manager.js.map +1 -1
- package/dist/src/config/extension.test.js +13 -21
- package/dist/src/config/extension.test.js.map +1 -1
- package/dist/src/config/extensions/consent.d.ts +4 -0
- package/dist/src/config/extensions/consent.js +40 -16
- package/dist/src/config/extensions/consent.js.map +1 -1
- package/dist/src/config/extensions/consent.test.js +31 -7
- package/dist/src/config/extensions/consent.test.js.map +1 -1
- package/dist/src/config/extensions/extensionUpdates.test.js +5 -2
- package/dist/src/config/extensions/extensionUpdates.test.js.map +1 -1
- package/dist/src/config/keyBindings.d.ts +58 -59
- package/dist/src/config/keyBindings.js +131 -135
- package/dist/src/config/keyBindings.js.map +1 -1
- package/dist/src/config/keyBindings.test.js +3 -8
- package/dist/src/config/keyBindings.test.js.map +1 -1
- package/dist/src/config/policy-engine.integration.test.js +15 -0
- package/dist/src/config/policy-engine.integration.test.js.map +1 -1
- package/dist/src/config/settings.d.ts +24 -6
- package/dist/src/config/settings.js +150 -6
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/config/settings.test.js +258 -3
- package/dist/src/config/settings.test.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +53 -20
- package/dist/src/config/settingsSchema.js +48 -22
- package/dist/src/config/settingsSchema.js.map +1 -1
- package/dist/src/config/settingsSchema.test.js +22 -2
- package/dist/src/config/settingsSchema.test.js.map +1 -1
- package/dist/src/config/skills-backward-compatibility.test.js +99 -0
- package/dist/src/config/skills-backward-compatibility.test.js.map +1 -0
- package/dist/src/core/initializer.js +2 -2
- package/dist/src/core/initializer.js.map +1 -1
- package/dist/src/core/initializer.test.js.map +1 -1
- package/dist/src/core/theme.js +1 -1
- package/dist/src/core/theme.js.map +1 -1
- package/dist/src/core/theme.test.js.map +1 -1
- package/dist/src/gemini.js +51 -19
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.js +48 -61
- 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/nonInteractiveCli.d.ts +1 -2
- package/dist/src/nonInteractiveCli.js +1 -16
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/nonInteractiveCli.test.js +0 -39
- package/dist/src/nonInteractiveCli.test.js.map +1 -1
- package/dist/src/test-utils/mockCommandContext.js +7 -1
- package/dist/src/test-utils/mockCommandContext.js.map +1 -1
- package/dist/src/test-utils/render.js +2 -0
- package/dist/src/test-utils/render.js.map +1 -1
- package/dist/src/ui/App.test.js +2 -2
- package/dist/src/ui/App.test.js.map +1 -1
- package/dist/src/ui/AppContainer.js +41 -35
- package/dist/src/ui/AppContainer.js.map +1 -1
- package/dist/src/ui/AppContainer.test.js +33 -22
- package/dist/src/ui/AppContainer.test.js.map +1 -1
- package/dist/src/ui/auth/ApiAuthDialog.test.js +0 -1
- package/dist/src/ui/auth/ApiAuthDialog.test.js.map +1 -1
- package/dist/src/ui/auth/AuthDialog.js +5 -5
- package/dist/src/ui/auth/AuthDialog.js.map +1 -1
- package/dist/src/ui/auth/AuthDialog.test.js.map +1 -1
- package/dist/src/ui/auth/LoginWithGoogleRestartDialog.test.js +0 -2
- package/dist/src/ui/auth/LoginWithGoogleRestartDialog.test.js.map +1 -1
- package/dist/src/ui/auth/useAuth.js +3 -3
- package/dist/src/ui/auth/useAuth.js.map +1 -1
- package/dist/src/ui/commands/aboutCommand.js +1 -1
- package/dist/src/ui/commands/aboutCommand.js.map +1 -1
- package/dist/src/ui/commands/agentsCommand.js +158 -1
- package/dist/src/ui/commands/agentsCommand.js.map +1 -1
- package/dist/src/ui/commands/agentsCommand.test.js +140 -1
- package/dist/src/ui/commands/agentsCommand.test.js.map +1 -1
- package/dist/src/ui/commands/hooksCommand.js +23 -23
- package/dist/src/ui/commands/hooksCommand.js.map +1 -1
- package/dist/src/ui/commands/hooksCommand.test.js +12 -15
- package/dist/src/ui/commands/hooksCommand.test.js.map +1 -1
- package/dist/src/ui/commands/policiesCommand.js +3 -0
- package/dist/src/ui/commands/policiesCommand.js.map +1 -1
- package/dist/src/ui/commands/policiesCommand.test.js +2 -1
- package/dist/src/ui/commands/policiesCommand.test.js.map +1 -1
- package/dist/src/ui/commands/skillsCommand.test.js +14 -7
- package/dist/src/ui/commands/skillsCommand.test.js.map +1 -1
- package/dist/src/ui/components/AdminSettingsChangedDialog.d.ts +6 -0
- package/dist/src/ui/components/AdminSettingsChangedDialog.js +22 -0
- package/dist/src/ui/components/AdminSettingsChangedDialog.js.map +1 -0
- package/dist/src/ui/components/AdminSettingsChangedDialog.test.d.ts +6 -0
- package/dist/src/ui/components/AdminSettingsChangedDialog.test.js +43 -0
- package/dist/src/ui/components/AdminSettingsChangedDialog.test.js.map +1 -0
- package/dist/src/ui/components/AppHeader.js +1 -1
- package/dist/src/ui/components/AppHeader.js.map +1 -1
- package/dist/src/ui/components/Composer.js +4 -6
- package/dist/src/ui/components/Composer.js.map +1 -1
- package/dist/src/ui/components/Composer.test.js +17 -9
- package/dist/src/ui/components/Composer.test.js.map +1 -1
- package/dist/src/ui/components/DialogManager.js +4 -4
- package/dist/src/ui/components/DialogManager.js.map +1 -1
- package/dist/src/ui/components/DialogManager.test.js +0 -14
- package/dist/src/ui/components/DialogManager.test.js.map +1 -1
- package/dist/src/ui/components/EditorSettingsDialog.js +3 -3
- package/dist/src/ui/components/EditorSettingsDialog.js.map +1 -1
- package/dist/src/ui/components/Footer.js +5 -5
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/Help.js +2 -1
- package/dist/src/ui/components/Help.js.map +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.test.js +1 -0
- package/dist/src/ui/components/HistoryItemDisplay.test.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.js +6 -9
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.test.js +8 -14
- package/dist/src/ui/components/InputPrompt.test.js.map +1 -1
- package/dist/src/ui/components/MultiFolderTrustDialog.test.js +0 -1
- package/dist/src/ui/components/MultiFolderTrustDialog.test.js.map +1 -1
- package/dist/src/ui/components/RewindConfirmation.d.ts +21 -0
- package/dist/src/ui/components/RewindConfirmation.js +63 -0
- package/dist/src/ui/components/RewindConfirmation.js.map +1 -0
- package/dist/src/ui/components/RewindConfirmation.test.d.ts +6 -0
- package/dist/src/ui/components/RewindConfirmation.test.js +53 -0
- package/dist/src/ui/components/RewindConfirmation.test.js.map +1 -0
- package/dist/src/ui/components/RewindViewer.d.ts +15 -0
- package/dist/src/ui/components/RewindViewer.js +79 -0
- package/dist/src/ui/components/RewindViewer.js.map +1 -0
- package/dist/src/ui/components/RewindViewer.test.d.ts +6 -0
- package/dist/src/ui/components/RewindViewer.test.js +239 -0
- package/dist/src/ui/components/RewindViewer.test.js.map +1 -0
- package/dist/src/ui/components/SessionBrowser.test.js +0 -1
- package/dist/src/ui/components/SessionBrowser.test.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.js +4 -4
- package/dist/src/ui/components/SettingsDialog.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.test.js +14 -14
- package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
- package/dist/src/ui/components/StatusDisplay.js +3 -4
- package/dist/src/ui/components/StatusDisplay.js.map +1 -1
- package/dist/src/ui/components/ThemeDialog.js +2 -2
- package/dist/src/ui/components/ThemeDialog.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js +8 -3
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js +18 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js.map +1 -1
- package/dist/src/ui/components/shared/TextInput.test.js +0 -8
- package/dist/src/ui/components/shared/TextInput.test.js.map +1 -1
- package/dist/src/ui/components/shared/performance.test.d.ts +1 -0
- package/dist/src/ui/components/shared/performance.test.js +67 -0
- package/dist/src/ui/components/shared/performance.test.js.map +1 -0
- package/dist/src/ui/components/shared/text-buffer.d.ts +1 -0
- package/dist/src/ui/components/shared/text-buffer.js +80 -54
- package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
- package/dist/src/ui/components/shared/text-buffer.test.js +97 -21
- package/dist/src/ui/components/shared/text-buffer.test.js.map +1 -1
- package/dist/src/ui/constants/tips.js +150 -150
- package/dist/src/ui/constants/tips.js.map +1 -1
- package/dist/src/ui/constants/wittyPhrases.js +118 -118
- package/dist/src/ui/constants/wittyPhrases.js.map +1 -1
- package/dist/src/ui/constants.d.ts +2 -0
- package/dist/src/ui/constants.js +2 -0
- package/dist/src/ui/constants.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.d.ts +0 -1
- package/dist/src/ui/contexts/KeypressContext.js +2 -6
- package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.test.js +2 -10
- package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
- package/dist/src/ui/contexts/UIActionsContext.d.ts +1 -0
- package/dist/src/ui/contexts/UIActionsContext.js.map +1 -1
- package/dist/src/ui/contexts/UIStateContext.d.ts +2 -2
- package/dist/src/ui/contexts/UIStateContext.js.map +1 -1
- package/dist/src/ui/contexts/VimModeContext.js +3 -3
- package/dist/src/ui/contexts/VimModeContext.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.d.ts +0 -5
- package/dist/src/ui/hooks/slashCommandProcessor.js +42 -11
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.test.js +1 -144
- package/dist/src/ui/hooks/slashCommandProcessor.test.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/useAtCompletion.js +21 -1
- package/dist/src/ui/hooks/useAtCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useAtCompletion.test.js +4 -4
- package/dist/src/ui/hooks/useAtCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useAtCompletion_agents.test.js +2 -0
- package/dist/src/ui/hooks/useAtCompletion_agents.test.js.map +1 -1
- package/dist/src/ui/hooks/useFolderTrust.js +1 -1
- package/dist/src/ui/hooks/useFolderTrust.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +17 -5
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.test.js +103 -1
- package/dist/src/ui/hooks/useGeminiStream.test.js.map +1 -1
- package/dist/src/ui/hooks/useKeypress.test.js +11 -13
- package/dist/src/ui/hooks/useKeypress.test.js.map +1 -1
- package/dist/src/ui/hooks/usePermissionsModifyTrust.js +1 -1
- package/dist/src/ui/hooks/usePermissionsModifyTrust.js.map +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.d.ts +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.js +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
- package/dist/src/ui/hooks/useSelectionList.test.js +0 -3
- package/dist/src/ui/hooks/useSelectionList.test.js.map +1 -1
- package/dist/src/ui/hooks/useShowMemoryCommand.js +1 -1
- package/dist/src/ui/hooks/useShowMemoryCommand.js.map +1 -1
- package/dist/src/ui/hooks/useThemeCommand.js +4 -4
- package/dist/src/ui/hooks/useThemeCommand.js.map +1 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js +62 -46
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
- package/dist/src/ui/hooks/vim.js +0 -1
- package/dist/src/ui/hooks/vim.js.map +1 -1
- package/dist/src/ui/hooks/vim.test.js +0 -1
- package/dist/src/ui/hooks/vim.test.js.map +1 -1
- package/dist/src/ui/keyMatchers.js +1 -16
- package/dist/src/ui/keyMatchers.js.map +1 -1
- package/dist/src/ui/keyMatchers.test.js +2 -14
- package/dist/src/ui/keyMatchers.test.js.map +1 -1
- package/dist/src/ui/types.d.ts +1 -5
- package/dist/src/ui/types.js.map +1 -1
- package/dist/src/ui/utils/CodeColorizer.js +1 -1
- package/dist/src/ui/utils/CodeColorizer.js.map +1 -1
- package/dist/src/ui/utils/commandUtils.js +31 -6
- package/dist/src/ui/utils/commandUtils.js.map +1 -1
- package/dist/src/ui/utils/commandUtils.test.js +71 -10
- package/dist/src/ui/utils/commandUtils.test.js.map +1 -1
- package/dist/src/ui/utils/formatters.d.ts +9 -0
- package/dist/src/ui/utils/formatters.js +26 -0
- package/dist/src/ui/utils/formatters.js.map +1 -1
- package/dist/src/ui/utils/formatters.test.js +70 -2
- package/dist/src/ui/utils/formatters.test.js.map +1 -1
- package/dist/src/ui/utils/highlight.js +18 -1
- package/dist/src/ui/utils/highlight.js.map +1 -1
- package/dist/src/ui/utils/highlight.test.js +2 -2
- package/dist/src/ui/utils/highlight.test.js.map +1 -1
- package/dist/src/ui/utils/textUtils.d.ts +0 -1
- package/dist/src/ui/utils/textUtils.js +17 -12
- package/dist/src/ui/utils/textUtils.js.map +1 -1
- package/dist/src/ui/utils/textUtils.test.js +1 -0
- package/dist/src/ui/utils/textUtils.test.js.map +1 -1
- package/dist/src/ui/utils/ui-sizing.js +1 -1
- package/dist/src/ui/utils/ui-sizing.js.map +1 -1
- package/dist/src/ui/utils/updateCheck.js +1 -1
- package/dist/src/ui/utils/updateCheck.js.map +1 -1
- package/dist/src/ui/utils/updateCheck.test.js +3 -3
- package/dist/src/ui/utils/updateCheck.test.js.map +1 -1
- package/dist/src/utils/agentSettings.d.ts +31 -0
- package/dist/src/utils/agentSettings.js +103 -0
- package/dist/src/utils/agentSettings.js.map +1 -0
- package/dist/src/utils/agentUtils.d.ts +15 -0
- package/dist/src/utils/agentUtils.js +50 -0
- package/dist/src/utils/agentUtils.js.map +1 -0
- package/dist/src/utils/agentUtils.test.d.ts +6 -0
- package/dist/src/utils/agentUtils.test.js +121 -0
- package/dist/src/utils/agentUtils.test.js.map +1 -0
- package/dist/src/utils/handleAutoUpdate.js +4 -4
- package/dist/src/utils/handleAutoUpdate.js.map +1 -1
- package/dist/src/utils/handleAutoUpdate.test.js +8 -4
- package/dist/src/utils/handleAutoUpdate.test.js.map +1 -1
- package/dist/src/utils/installationInfo.d.ts +1 -1
- package/dist/src/utils/installationInfo.js +13 -13
- package/dist/src/utils/installationInfo.js.map +1 -1
- package/dist/src/utils/installationInfo.test.js +28 -20
- package/dist/src/utils/installationInfo.test.js.map +1 -1
- package/dist/src/utils/relaunch.d.ts +2 -1
- package/dist/src/utils/relaunch.js +6 -3
- package/dist/src/utils/relaunch.js.map +1 -1
- package/dist/src/utils/settingsUtils.d.ts +7 -0
- package/dist/src/utils/settingsUtils.js +17 -0
- package/dist/src/utils/settingsUtils.js.map +1 -1
- package/dist/src/utils/settingsUtils.test.js +33 -33
- package/dist/src/utils/settingsUtils.test.js.map +1 -1
- package/dist/src/utils/skillUtils.d.ts +2 -1
- package/dist/src/utils/skillUtils.js +58 -56
- package/dist/src/utils/skillUtils.js.map +1 -1
- package/dist/src/utils/skillUtils.test.js +13 -0
- package/dist/src/utils/skillUtils.test.js.map +1 -1
- package/dist/src/utils/terminalTheme.js +4 -4
- package/dist/src/utils/terminalTheme.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.js +1 -1
- package/dist/src/validateNonInterActiveAuth.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.test.js +2 -4
- package/dist/src/validateNonInterActiveAuth.test.js.map +1 -1
- package/dist/src/zed-integration/zedIntegration.js +8 -3
- package/dist/src/zed-integration/zedIntegration.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -4
- package/dist/src/ui/components/ShellConfirmationDialog.d.ts +0 -15
- package/dist/src/ui/components/ShellConfirmationDialog.js +0 -49
- package/dist/src/ui/components/ShellConfirmationDialog.js.map +0 -1
- package/dist/src/ui/components/ShellConfirmationDialog.test.js +0 -40
- package/dist/src/ui/components/ShellConfirmationDialog.test.js.map +0 -1
- /package/dist/src/{ui/components/ShellConfirmationDialog.test.d.ts → config/skills-backward-compatibility.test.d.ts} +0 -0
|
@@ -8,6 +8,7 @@ import * as os from 'node:os';
|
|
|
8
8
|
import * as path from 'node:path';
|
|
9
9
|
import { DEFAULT_FILE_FILTERING_OPTIONS, OutputFormat, SHELL_TOOL_NAME, WRITE_FILE_TOOL_NAME, EDIT_TOOL_NAME, WEB_FETCH_TOOL_NAME, debugLogger, ApprovalMode, } from '@google/gemini-cli-core';
|
|
10
10
|
import { loadCliConfig, parseArguments } from './config.js';
|
|
11
|
+
import { createTestMergedSettings } from './settings.js';
|
|
11
12
|
import * as ServerConfig from '@google/gemini-cli-core';
|
|
12
13
|
import { isWorkspaceTrusted } from './trustedFolders.js';
|
|
13
14
|
import { ExtensionManager } from './extension-manager.js';
|
|
@@ -146,7 +147,7 @@ describe('parseArguments', () => {
|
|
|
146
147
|
const mockConsoleError = vi
|
|
147
148
|
.spyOn(console, 'error')
|
|
148
149
|
.mockImplementation(() => { });
|
|
149
|
-
await expect(parseArguments(
|
|
150
|
+
await expect(parseArguments(createTestMergedSettings())).rejects.toThrow('process.exit called');
|
|
150
151
|
expect(mockConsoleError).toHaveBeenCalledWith(expect.stringContaining('Cannot use both --prompt (-p) and --prompt-interactive (-i) together'));
|
|
151
152
|
mockExit.mockRestore();
|
|
152
153
|
mockConsoleError.mockRestore();
|
|
@@ -169,7 +170,7 @@ describe('parseArguments', () => {
|
|
|
169
170
|
},
|
|
170
171
|
])('$description', async ({ argv, expected }) => {
|
|
171
172
|
process.argv = argv;
|
|
172
|
-
const parsedArgs = await parseArguments(
|
|
173
|
+
const parsedArgs = await parseArguments(createTestMergedSettings());
|
|
173
174
|
expect(parsedArgs.prompt).toBe(expected.prompt);
|
|
174
175
|
expect(parsedArgs.promptInteractive).toBe(expected.promptInteractive);
|
|
175
176
|
});
|
|
@@ -282,7 +283,7 @@ describe('parseArguments', () => {
|
|
|
282
283
|
},
|
|
283
284
|
])('$description', async ({ argv, expectedQuery, expectedModel, debug }) => {
|
|
284
285
|
process.argv = argv;
|
|
285
|
-
const parsedArgs = await parseArguments(
|
|
286
|
+
const parsedArgs = await parseArguments(createTestMergedSettings());
|
|
286
287
|
expect(parsedArgs.query).toBe(expectedQuery);
|
|
287
288
|
expect(parsedArgs.prompt).toBe(expectedQuery);
|
|
288
289
|
expect(parsedArgs.promptInteractive).toBeUndefined();
|
|
@@ -311,7 +312,7 @@ describe('parseArguments', () => {
|
|
|
311
312
|
const mockConsoleError = vi
|
|
312
313
|
.spyOn(console, 'error')
|
|
313
314
|
.mockImplementation(() => { });
|
|
314
|
-
await expect(parseArguments(
|
|
315
|
+
await expect(parseArguments(createTestMergedSettings())).rejects.toThrow('process.exit called');
|
|
315
316
|
expect(mockConsoleError).toHaveBeenCalledWith(expect.stringContaining('Cannot use both --yolo (-y) and --approval-mode together. Use --approval-mode=yolo instead.'));
|
|
316
317
|
mockExit.mockRestore();
|
|
317
318
|
mockConsoleError.mockRestore();
|
|
@@ -329,7 +330,7 @@ describe('parseArguments', () => {
|
|
|
329
330
|
},
|
|
330
331
|
])('$description', async ({ argv, expected }) => {
|
|
331
332
|
process.argv = argv;
|
|
332
|
-
const parsedArgs = await parseArguments(
|
|
333
|
+
const parsedArgs = await parseArguments(createTestMergedSettings());
|
|
333
334
|
expect(parsedArgs.approvalMode).toBe(expected.approvalMode);
|
|
334
335
|
expect(parsedArgs.yolo).toBe(expected.yolo);
|
|
335
336
|
});
|
|
@@ -344,7 +345,7 @@ describe('parseArguments', () => {
|
|
|
344
345
|
const debugErrorSpy = vi
|
|
345
346
|
.spyOn(debugLogger, 'error')
|
|
346
347
|
.mockImplementation(() => { });
|
|
347
|
-
await expect(parseArguments(
|
|
348
|
+
await expect(parseArguments(createTestMergedSettings())).rejects.toThrow('process.exit called');
|
|
348
349
|
expect(debugErrorSpy).toHaveBeenCalledWith(expect.stringContaining('Invalid values:'));
|
|
349
350
|
expect(mockConsoleError).toHaveBeenCalled();
|
|
350
351
|
mockExit.mockRestore();
|
|
@@ -356,7 +357,7 @@ describe('parseArguments', () => {
|
|
|
356
357
|
process.stdin.isTTY = false;
|
|
357
358
|
process.argv = ['node', 'script.js', '--resume', 'session-id'];
|
|
358
359
|
try {
|
|
359
|
-
const argv = await parseArguments(
|
|
360
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
360
361
|
expect(argv.resume).toBe('session-id');
|
|
361
362
|
}
|
|
362
363
|
finally {
|
|
@@ -368,7 +369,7 @@ describe('parseArguments', () => {
|
|
|
368
369
|
process.stdin.isTTY = true; // Make it interactive to avoid validation error
|
|
369
370
|
process.argv = ['node', 'script.js', '--resume'];
|
|
370
371
|
try {
|
|
371
|
-
const argv = await parseArguments(
|
|
372
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
372
373
|
expect(argv.resume).toBe(RESUME_LATEST);
|
|
373
374
|
expect(argv.resume).toBe('latest');
|
|
374
375
|
}
|
|
@@ -383,7 +384,7 @@ describe('parseArguments', () => {
|
|
|
383
384
|
'--allowed-tools',
|
|
384
385
|
'read_file,ShellTool(git status)',
|
|
385
386
|
];
|
|
386
|
-
const argv = await parseArguments(
|
|
387
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
387
388
|
expect(argv.allowedTools).toEqual(['read_file', 'ShellTool(git status)']);
|
|
388
389
|
});
|
|
389
390
|
it('should support comma-separated values for --allowed-mcp-server-names', async () => {
|
|
@@ -393,12 +394,12 @@ describe('parseArguments', () => {
|
|
|
393
394
|
'--allowed-mcp-server-names',
|
|
394
395
|
'server1,server2',
|
|
395
396
|
];
|
|
396
|
-
const argv = await parseArguments(
|
|
397
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
397
398
|
expect(argv.allowedMcpServerNames).toEqual(['server1', 'server2']);
|
|
398
399
|
});
|
|
399
400
|
it('should support comma-separated values for --extensions', async () => {
|
|
400
401
|
process.argv = ['node', 'script.js', '--extensions', 'ext1,ext2'];
|
|
401
|
-
const argv = await parseArguments(
|
|
402
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
402
403
|
expect(argv.extensions).toEqual(['ext1', 'ext2']);
|
|
403
404
|
});
|
|
404
405
|
it('should correctly parse positional arguments when flags with arguments are present', async () => {
|
|
@@ -409,7 +410,7 @@ describe('parseArguments', () => {
|
|
|
409
410
|
'test-model-string',
|
|
410
411
|
'my-positional-arg',
|
|
411
412
|
];
|
|
412
|
-
const argv = await parseArguments(
|
|
413
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
413
414
|
expect(argv.model).toBe('test-model-string');
|
|
414
415
|
expect(argv.query).toBe('my-positional-arg');
|
|
415
416
|
});
|
|
@@ -425,7 +426,7 @@ describe('parseArguments', () => {
|
|
|
425
426
|
'--allowed-tools=ShellTool(wc)',
|
|
426
427
|
'Use whoami to write a poem in file poem.md about my username in pig latin and use wc to tell me how many lines are in the poem you wrote.',
|
|
427
428
|
];
|
|
428
|
-
const argv = await parseArguments(
|
|
429
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
429
430
|
expect(argv.extensions).toEqual(['none']);
|
|
430
431
|
expect(argv.approvalMode).toBe('auto_edit');
|
|
431
432
|
expect(argv.allowedTools).toEqual([
|
|
@@ -473,8 +474,8 @@ describe('loadCliConfig', () => {
|
|
|
473
474
|
});
|
|
474
475
|
it(`should leave proxy to empty by default`, async () => {
|
|
475
476
|
process.argv = ['node', 'script.js'];
|
|
476
|
-
const argv = await parseArguments(
|
|
477
|
-
const settings =
|
|
477
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
478
|
+
const settings = createTestMergedSettings();
|
|
478
479
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
479
480
|
expect(config.getProxy()).toBeFalsy();
|
|
480
481
|
});
|
|
@@ -513,8 +514,8 @@ describe('loadCliConfig', () => {
|
|
|
513
514
|
it(`should set proxy to ${expected} according to environment variable [${input.env_name}]`, async () => {
|
|
514
515
|
vi.stubEnv(input.env_name, input.proxy_url);
|
|
515
516
|
process.argv = ['node', 'script.js'];
|
|
516
|
-
const argv = await parseArguments(
|
|
517
|
-
const settings =
|
|
517
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
518
|
+
const settings = createTestMergedSettings();
|
|
518
519
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
519
520
|
expect(config.getProxy()).toBe(expected);
|
|
520
521
|
});
|
|
@@ -522,8 +523,8 @@ describe('loadCliConfig', () => {
|
|
|
522
523
|
});
|
|
523
524
|
it('should use default fileFilter options when unconfigured', async () => {
|
|
524
525
|
process.argv = ['node', 'script.js'];
|
|
525
|
-
const argv = await parseArguments(
|
|
526
|
-
const settings =
|
|
526
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
527
|
+
const settings = createTestMergedSettings();
|
|
527
528
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
528
529
|
expect(config.getFileFilteringRespectGitIgnore()).toBe(DEFAULT_FILE_FILTERING_OPTIONS.respectGitIgnore);
|
|
529
530
|
expect(config.getFileFilteringRespectGeminiIgnore()).toBe(DEFAULT_FILE_FILTERING_OPTIONS.respectGeminiIgnore);
|
|
@@ -541,7 +542,7 @@ describe('Hierarchical Memory Loading (config.ts) - Placeholder Suite', () => {
|
|
|
541
542
|
});
|
|
542
543
|
it('should pass extension context file paths to loadServerHierarchicalMemory', async () => {
|
|
543
544
|
process.argv = ['node', 'script.js'];
|
|
544
|
-
const settings =
|
|
545
|
+
const settings = createTestMergedSettings();
|
|
545
546
|
vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([
|
|
546
547
|
{
|
|
547
548
|
path: '/path/to/ext1',
|
|
@@ -571,23 +572,23 @@ describe('Hierarchical Memory Loading (config.ts) - Placeholder Suite', () => {
|
|
|
571
572
|
isActive: true,
|
|
572
573
|
},
|
|
573
574
|
]);
|
|
574
|
-
const argv = await parseArguments(
|
|
575
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
575
576
|
await loadCliConfig(settings, 'session-id', argv);
|
|
576
|
-
expect(ServerConfig.loadServerHierarchicalMemory).toHaveBeenCalledWith(expect.any(String), [], false, expect.any(Object), expect.any(ExtensionManager), true, 'tree', {
|
|
577
|
-
respectGitIgnore:
|
|
577
|
+
expect(ServerConfig.loadServerHierarchicalMemory).toHaveBeenCalledWith(expect.any(String), [], false, expect.any(Object), expect.any(ExtensionManager), true, 'tree', expect.objectContaining({
|
|
578
|
+
respectGitIgnore: true,
|
|
578
579
|
respectGeminiIgnore: true,
|
|
579
|
-
},
|
|
580
|
+
}), 200);
|
|
580
581
|
});
|
|
581
582
|
});
|
|
582
583
|
describe('mergeMcpServers', () => {
|
|
583
584
|
it('should not modify the original settings object', async () => {
|
|
584
|
-
const settings = {
|
|
585
|
+
const settings = createTestMergedSettings({
|
|
585
586
|
mcpServers: {
|
|
586
587
|
'test-server': {
|
|
587
588
|
url: 'http://localhost:8080',
|
|
588
589
|
},
|
|
589
590
|
},
|
|
590
|
-
};
|
|
591
|
+
});
|
|
591
592
|
vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([
|
|
592
593
|
{
|
|
593
594
|
path: '/path/to/ext1',
|
|
@@ -605,7 +606,7 @@ describe('mergeMcpServers', () => {
|
|
|
605
606
|
]);
|
|
606
607
|
const originalSettings = JSON.parse(JSON.stringify(settings));
|
|
607
608
|
process.argv = ['node', 'script.js'];
|
|
608
|
-
const argv = await parseArguments(
|
|
609
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
609
610
|
await loadCliConfig(settings, 'test-session', argv);
|
|
610
611
|
expect(settings).toEqual(originalSettings);
|
|
611
612
|
});
|
|
@@ -626,7 +627,9 @@ describe('mergeExcludeTools', () => {
|
|
|
626
627
|
process.stdin.isTTY = originalIsTTY;
|
|
627
628
|
});
|
|
628
629
|
it('should merge excludeTools from settings and extensions', async () => {
|
|
629
|
-
const settings = {
|
|
630
|
+
const settings = createTestMergedSettings({
|
|
631
|
+
tools: { exclude: ['tool1', 'tool2'] },
|
|
632
|
+
});
|
|
630
633
|
vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([
|
|
631
634
|
{
|
|
632
635
|
path: '/path/to/ext1',
|
|
@@ -648,13 +651,15 @@ describe('mergeExcludeTools', () => {
|
|
|
648
651
|
},
|
|
649
652
|
]);
|
|
650
653
|
process.argv = ['node', 'script.js'];
|
|
651
|
-
const argv = await parseArguments(
|
|
654
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
652
655
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
653
656
|
expect(config.getExcludeTools()).toEqual(new Set(['tool1', 'tool2', 'tool3', 'tool4', 'tool5']));
|
|
654
657
|
expect(config.getExcludeTools()).toHaveLength(5);
|
|
655
658
|
});
|
|
656
659
|
it('should handle overlapping excludeTools between settings and extensions', async () => {
|
|
657
|
-
const settings = {
|
|
660
|
+
const settings = createTestMergedSettings({
|
|
661
|
+
tools: { exclude: ['tool1', 'tool2'] },
|
|
662
|
+
});
|
|
658
663
|
vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([
|
|
659
664
|
{
|
|
660
665
|
path: '/path/to/ext1',
|
|
@@ -667,13 +672,15 @@ describe('mergeExcludeTools', () => {
|
|
|
667
672
|
},
|
|
668
673
|
]);
|
|
669
674
|
process.argv = ['node', 'script.js'];
|
|
670
|
-
const argv = await parseArguments(
|
|
675
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
671
676
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
672
677
|
expect(config.getExcludeTools()).toEqual(new Set(['tool1', 'tool2', 'tool3']));
|
|
673
678
|
expect(config.getExcludeTools()).toHaveLength(3);
|
|
674
679
|
});
|
|
675
680
|
it('should handle overlapping excludeTools between extensions', async () => {
|
|
676
|
-
const settings = {
|
|
681
|
+
const settings = createTestMergedSettings({
|
|
682
|
+
tools: { exclude: ['tool1'] },
|
|
683
|
+
});
|
|
677
684
|
vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([
|
|
678
685
|
{
|
|
679
686
|
path: '/path/to/ext1',
|
|
@@ -695,38 +702,40 @@ describe('mergeExcludeTools', () => {
|
|
|
695
702
|
},
|
|
696
703
|
]);
|
|
697
704
|
process.argv = ['node', 'script.js'];
|
|
698
|
-
const argv = await parseArguments(
|
|
705
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
699
706
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
700
707
|
expect(config.getExcludeTools()).toEqual(new Set(['tool1', 'tool2', 'tool3', 'tool4']));
|
|
701
708
|
expect(config.getExcludeTools()).toHaveLength(4);
|
|
702
709
|
});
|
|
703
710
|
it('should return an empty array when no excludeTools are specified and it is interactive', async () => {
|
|
704
711
|
process.stdin.isTTY = true;
|
|
705
|
-
const settings =
|
|
712
|
+
const settings = createTestMergedSettings();
|
|
706
713
|
process.argv = ['node', 'script.js'];
|
|
707
|
-
const argv = await parseArguments(
|
|
714
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
708
715
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
709
716
|
expect(config.getExcludeTools()).toEqual(new Set([]));
|
|
710
717
|
});
|
|
711
718
|
it('should return default excludes when no excludeTools are specified and it is not interactive', async () => {
|
|
712
719
|
process.stdin.isTTY = false;
|
|
713
|
-
const settings =
|
|
720
|
+
const settings = createTestMergedSettings();
|
|
714
721
|
process.argv = ['node', 'script.js', '-p', 'test'];
|
|
715
|
-
const argv = await parseArguments(
|
|
722
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
716
723
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
717
724
|
expect(config.getExcludeTools()).toEqual(defaultExcludes);
|
|
718
725
|
});
|
|
719
726
|
it('should handle settings with excludeTools but no extensions', async () => {
|
|
720
727
|
process.argv = ['node', 'script.js'];
|
|
721
|
-
const argv = await parseArguments(
|
|
722
|
-
const settings = {
|
|
728
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
729
|
+
const settings = createTestMergedSettings({
|
|
730
|
+
tools: { exclude: ['tool1', 'tool2'] },
|
|
731
|
+
});
|
|
723
732
|
vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([]);
|
|
724
733
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
725
734
|
expect(config.getExcludeTools()).toEqual(new Set(['tool1', 'tool2']));
|
|
726
735
|
expect(config.getExcludeTools()).toHaveLength(2);
|
|
727
736
|
});
|
|
728
737
|
it('should handle extensions with excludeTools but no settings', async () => {
|
|
729
|
-
const settings =
|
|
738
|
+
const settings = createTestMergedSettings();
|
|
730
739
|
vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([
|
|
731
740
|
{
|
|
732
741
|
path: '/path/to/ext',
|
|
@@ -739,13 +748,15 @@ describe('mergeExcludeTools', () => {
|
|
|
739
748
|
},
|
|
740
749
|
]);
|
|
741
750
|
process.argv = ['node', 'script.js'];
|
|
742
|
-
const argv = await parseArguments(
|
|
751
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
743
752
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
744
753
|
expect(config.getExcludeTools()).toEqual(new Set(['tool1', 'tool2']));
|
|
745
754
|
expect(config.getExcludeTools()).toHaveLength(2);
|
|
746
755
|
});
|
|
747
756
|
it('should not modify the original settings object', async () => {
|
|
748
|
-
const settings = {
|
|
757
|
+
const settings = createTestMergedSettings({
|
|
758
|
+
tools: { exclude: ['tool1'] },
|
|
759
|
+
});
|
|
749
760
|
vi.spyOn(ExtensionManager.prototype, 'getExtensions').mockReturnValue([
|
|
750
761
|
{
|
|
751
762
|
path: '/path/to/ext',
|
|
@@ -759,7 +770,7 @@ describe('mergeExcludeTools', () => {
|
|
|
759
770
|
]);
|
|
760
771
|
const originalSettings = JSON.parse(JSON.stringify(settings));
|
|
761
772
|
process.argv = ['node', 'script.js'];
|
|
762
|
-
const argv = await parseArguments(
|
|
773
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
763
774
|
await loadCliConfig(settings, 'test-session', argv);
|
|
764
775
|
expect(settings).toEqual(originalSettings);
|
|
765
776
|
});
|
|
@@ -779,8 +790,8 @@ describe('Approval mode tool exclusion logic', () => {
|
|
|
779
790
|
});
|
|
780
791
|
it('should exclude all interactive tools in non-interactive mode with default approval mode', async () => {
|
|
781
792
|
process.argv = ['node', 'script.js', '-p', 'test'];
|
|
782
|
-
const argv = await parseArguments(
|
|
783
|
-
const settings =
|
|
793
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
794
|
+
const settings = createTestMergedSettings();
|
|
784
795
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
785
796
|
const excludedTools = config.getExcludeTools();
|
|
786
797
|
expect(excludedTools).toContain(SHELL_TOOL_NAME);
|
|
@@ -796,8 +807,8 @@ describe('Approval mode tool exclusion logic', () => {
|
|
|
796
807
|
'-p',
|
|
797
808
|
'test',
|
|
798
809
|
];
|
|
799
|
-
const argv = await parseArguments(
|
|
800
|
-
const settings =
|
|
810
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
811
|
+
const settings = createTestMergedSettings();
|
|
801
812
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
802
813
|
const excludedTools = config.getExcludeTools();
|
|
803
814
|
expect(excludedTools).toContain(SHELL_TOOL_NAME);
|
|
@@ -813,8 +824,8 @@ describe('Approval mode tool exclusion logic', () => {
|
|
|
813
824
|
'-p',
|
|
814
825
|
'test',
|
|
815
826
|
];
|
|
816
|
-
const argv = await parseArguments(
|
|
817
|
-
const settings =
|
|
827
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
828
|
+
const settings = createTestMergedSettings();
|
|
818
829
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
819
830
|
const excludedTools = config.getExcludeTools();
|
|
820
831
|
expect(excludedTools).toContain(SHELL_TOOL_NAME);
|
|
@@ -830,18 +841,39 @@ describe('Approval mode tool exclusion logic', () => {
|
|
|
830
841
|
'-p',
|
|
831
842
|
'test',
|
|
832
843
|
];
|
|
833
|
-
const argv = await parseArguments(
|
|
834
|
-
const settings =
|
|
844
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
845
|
+
const settings = createTestMergedSettings();
|
|
835
846
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
836
847
|
const excludedTools = config.getExcludeTools();
|
|
837
848
|
expect(excludedTools).not.toContain(SHELL_TOOL_NAME);
|
|
838
849
|
expect(excludedTools).not.toContain(EDIT_TOOL_NAME);
|
|
839
850
|
expect(excludedTools).not.toContain(WRITE_FILE_TOOL_NAME);
|
|
840
851
|
});
|
|
852
|
+
it('should exclude all interactive tools in non-interactive mode with plan approval mode', async () => {
|
|
853
|
+
process.argv = [
|
|
854
|
+
'node',
|
|
855
|
+
'script.js',
|
|
856
|
+
'--approval-mode',
|
|
857
|
+
'plan',
|
|
858
|
+
'-p',
|
|
859
|
+
'test',
|
|
860
|
+
];
|
|
861
|
+
const settings = createTestMergedSettings({
|
|
862
|
+
experimental: {
|
|
863
|
+
plan: true,
|
|
864
|
+
},
|
|
865
|
+
});
|
|
866
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
867
|
+
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
868
|
+
const excludedTools = config.getExcludeTools();
|
|
869
|
+
expect(excludedTools).toContain(SHELL_TOOL_NAME);
|
|
870
|
+
expect(excludedTools).toContain(EDIT_TOOL_NAME);
|
|
871
|
+
expect(excludedTools).toContain(WRITE_FILE_TOOL_NAME);
|
|
872
|
+
});
|
|
841
873
|
it('should exclude no interactive tools in non-interactive mode with legacy yolo flag', async () => {
|
|
842
874
|
process.argv = ['node', 'script.js', '--yolo', '-p', 'test'];
|
|
843
|
-
const argv = await parseArguments(
|
|
844
|
-
const settings =
|
|
875
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
876
|
+
const settings = createTestMergedSettings();
|
|
845
877
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
846
878
|
const excludedTools = config.getExcludeTools();
|
|
847
879
|
expect(excludedTools).not.toContain(SHELL_TOOL_NAME);
|
|
@@ -859,8 +891,8 @@ describe('Approval mode tool exclusion logic', () => {
|
|
|
859
891
|
];
|
|
860
892
|
for (const testCase of testCases) {
|
|
861
893
|
process.argv = testCase.args;
|
|
862
|
-
const argv = await parseArguments(
|
|
863
|
-
const settings =
|
|
894
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
895
|
+
const settings = createTestMergedSettings();
|
|
864
896
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
865
897
|
const excludedTools = config.getExcludeTools();
|
|
866
898
|
expect(excludedTools).not.toContain(SHELL_TOOL_NAME);
|
|
@@ -877,8 +909,10 @@ describe('Approval mode tool exclusion logic', () => {
|
|
|
877
909
|
'-p',
|
|
878
910
|
'test',
|
|
879
911
|
];
|
|
880
|
-
const argv = await parseArguments(
|
|
881
|
-
const settings = {
|
|
912
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
913
|
+
const settings = createTestMergedSettings({
|
|
914
|
+
tools: { exclude: ['custom_tool'] },
|
|
915
|
+
});
|
|
882
916
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
883
917
|
const excludedTools = config.getExcludeTools();
|
|
884
918
|
expect(excludedTools).toContain('custom_tool'); // From settings
|
|
@@ -888,12 +922,12 @@ describe('Approval mode tool exclusion logic', () => {
|
|
|
888
922
|
});
|
|
889
923
|
it('should throw an error if YOLO mode is attempted when disableYoloMode is true', async () => {
|
|
890
924
|
process.argv = ['node', 'script.js', '--yolo'];
|
|
891
|
-
const argv = await parseArguments(
|
|
892
|
-
const settings = {
|
|
925
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
926
|
+
const settings = createTestMergedSettings({
|
|
893
927
|
security: {
|
|
894
928
|
disableYoloMode: true,
|
|
895
929
|
},
|
|
896
|
-
};
|
|
930
|
+
});
|
|
897
931
|
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow('Cannot start in YOLO mode since it is disabled by your admin');
|
|
898
932
|
});
|
|
899
933
|
it('should throw an error for invalid approval mode values in loadCliConfig', async () => {
|
|
@@ -904,8 +938,8 @@ describe('Approval mode tool exclusion logic', () => {
|
|
|
904
938
|
prompt: '',
|
|
905
939
|
yolo: false,
|
|
906
940
|
};
|
|
907
|
-
const settings =
|
|
908
|
-
await expect(loadCliConfig(settings, 'test-session', invalidArgv)).rejects.toThrow('Invalid approval mode: invalid_mode. Valid values are: yolo, auto_edit, default');
|
|
941
|
+
const settings = createTestMergedSettings();
|
|
942
|
+
await expect(loadCliConfig(settings, 'test-session', invalidArgv)).rejects.toThrow('Invalid approval mode: invalid_mode. Valid values are: yolo, auto_edit, plan, default');
|
|
909
943
|
});
|
|
910
944
|
});
|
|
911
945
|
describe('loadCliConfig with allowed-mcp-server-names', () => {
|
|
@@ -919,16 +953,16 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
|
|
|
919
953
|
vi.unstubAllEnvs();
|
|
920
954
|
vi.restoreAllMocks();
|
|
921
955
|
});
|
|
922
|
-
const baseSettings = {
|
|
956
|
+
const baseSettings = createTestMergedSettings({
|
|
923
957
|
mcpServers: {
|
|
924
958
|
server1: { url: 'http://localhost:8080' },
|
|
925
959
|
server2: { url: 'http://localhost:8081' },
|
|
926
960
|
server3: { url: 'http://localhost:8082' },
|
|
927
961
|
},
|
|
928
|
-
};
|
|
962
|
+
});
|
|
929
963
|
it('should allow all MCP servers if the flag is not provided', async () => {
|
|
930
964
|
process.argv = ['node', 'script.js'];
|
|
931
|
-
const argv = await parseArguments(
|
|
965
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
932
966
|
const config = await loadCliConfig(baseSettings, 'test-session', argv);
|
|
933
967
|
expect(config.getMcpServers()).toEqual(baseSettings.mcpServers);
|
|
934
968
|
});
|
|
@@ -939,7 +973,7 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
|
|
|
939
973
|
'--allowed-mcp-server-names',
|
|
940
974
|
'server1',
|
|
941
975
|
];
|
|
942
|
-
const argv = await parseArguments(
|
|
976
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
943
977
|
const config = await loadCliConfig(baseSettings, 'test-session', argv);
|
|
944
978
|
expect(config.getAllowedMcpServers()).toEqual(['server1']);
|
|
945
979
|
});
|
|
@@ -952,7 +986,7 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
|
|
|
952
986
|
'--allowed-mcp-server-names',
|
|
953
987
|
'server3',
|
|
954
988
|
];
|
|
955
|
-
const argv = await parseArguments(
|
|
989
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
956
990
|
const config = await loadCliConfig(baseSettings, 'test-session', argv);
|
|
957
991
|
expect(config.getAllowedMcpServers()).toEqual(['server1', 'server3']);
|
|
958
992
|
});
|
|
@@ -965,46 +999,46 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
|
|
|
965
999
|
'--allowed-mcp-server-names',
|
|
966
1000
|
'server4',
|
|
967
1001
|
];
|
|
968
|
-
const argv = await parseArguments(
|
|
1002
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
969
1003
|
const config = await loadCliConfig(baseSettings, 'test-session', argv);
|
|
970
1004
|
expect(config.getAllowedMcpServers()).toEqual(['server1', 'server4']);
|
|
971
1005
|
});
|
|
972
1006
|
it('should allow no MCP servers if the flag is provided but empty', async () => {
|
|
973
1007
|
process.argv = ['node', 'script.js', '--allowed-mcp-server-names', ''];
|
|
974
|
-
const argv = await parseArguments(
|
|
1008
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
975
1009
|
const config = await loadCliConfig(baseSettings, 'test-session', argv);
|
|
976
1010
|
expect(config.getAllowedMcpServers()).toEqual(['']);
|
|
977
1011
|
});
|
|
978
1012
|
it('should read allowMCPServers from settings', async () => {
|
|
979
1013
|
process.argv = ['node', 'script.js'];
|
|
980
|
-
const argv = await parseArguments(
|
|
981
|
-
const settings = {
|
|
1014
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1015
|
+
const settings = createTestMergedSettings({
|
|
982
1016
|
...baseSettings,
|
|
983
1017
|
mcp: { allowed: ['server1', 'server2'] },
|
|
984
|
-
};
|
|
1018
|
+
});
|
|
985
1019
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
986
1020
|
expect(config.getAllowedMcpServers()).toEqual(['server1', 'server2']);
|
|
987
1021
|
});
|
|
988
1022
|
it('should read excludeMCPServers from settings', async () => {
|
|
989
1023
|
process.argv = ['node', 'script.js'];
|
|
990
|
-
const argv = await parseArguments(
|
|
991
|
-
const settings = {
|
|
1024
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1025
|
+
const settings = createTestMergedSettings({
|
|
992
1026
|
...baseSettings,
|
|
993
1027
|
mcp: { excluded: ['server1', 'server2'] },
|
|
994
|
-
};
|
|
1028
|
+
});
|
|
995
1029
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
996
1030
|
expect(config.getBlockedMcpServers()).toEqual(['server1', 'server2']);
|
|
997
1031
|
});
|
|
998
1032
|
it('should override allowMCPServers with excludeMCPServers if overlapping', async () => {
|
|
999
1033
|
process.argv = ['node', 'script.js'];
|
|
1000
|
-
const argv = await parseArguments(
|
|
1001
|
-
const settings = {
|
|
1034
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1035
|
+
const settings = createTestMergedSettings({
|
|
1002
1036
|
...baseSettings,
|
|
1003
1037
|
mcp: {
|
|
1004
1038
|
excluded: ['server1'],
|
|
1005
1039
|
allowed: ['server1', 'server2'],
|
|
1006
1040
|
},
|
|
1007
|
-
};
|
|
1041
|
+
});
|
|
1008
1042
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1009
1043
|
expect(config.getAllowedMcpServers()).toEqual(['server1', 'server2']);
|
|
1010
1044
|
expect(config.getBlockedMcpServers()).toEqual(['server1']);
|
|
@@ -1016,14 +1050,14 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
|
|
|
1016
1050
|
'--allowed-mcp-server-names',
|
|
1017
1051
|
'server1',
|
|
1018
1052
|
];
|
|
1019
|
-
const argv = await parseArguments(
|
|
1020
|
-
const settings = {
|
|
1053
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1054
|
+
const settings = createTestMergedSettings({
|
|
1021
1055
|
...baseSettings,
|
|
1022
1056
|
mcp: {
|
|
1023
1057
|
excluded: ['server1'],
|
|
1024
1058
|
allowed: ['server2'],
|
|
1025
1059
|
},
|
|
1026
|
-
};
|
|
1060
|
+
});
|
|
1027
1061
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1028
1062
|
expect(config.getAllowedMcpServers()).toEqual(['server1']);
|
|
1029
1063
|
});
|
|
@@ -1036,14 +1070,14 @@ describe('loadCliConfig with allowed-mcp-server-names', () => {
|
|
|
1036
1070
|
'--allowed-mcp-server-names',
|
|
1037
1071
|
'server3',
|
|
1038
1072
|
];
|
|
1039
|
-
const argv = await parseArguments(
|
|
1040
|
-
const settings = {
|
|
1073
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1074
|
+
const settings = createTestMergedSettings({
|
|
1041
1075
|
...baseSettings,
|
|
1042
1076
|
mcp: {
|
|
1043
1077
|
allowed: ['server1', 'server2'], // Should be ignored
|
|
1044
1078
|
excluded: ['server3'], // Should be ignored
|
|
1045
1079
|
},
|
|
1046
|
-
};
|
|
1080
|
+
});
|
|
1047
1081
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1048
1082
|
expect(config.getAllowedMcpServers()).toEqual(['server2', 'server3']);
|
|
1049
1083
|
expect(config.getBlockedMcpServers()).toEqual([]);
|
|
@@ -1058,40 +1092,48 @@ describe('loadCliConfig model selection', () => {
|
|
|
1058
1092
|
});
|
|
1059
1093
|
it('selects a model from settings.json if provided', async () => {
|
|
1060
1094
|
process.argv = ['node', 'script.js'];
|
|
1061
|
-
const argv = await parseArguments(
|
|
1062
|
-
const config = await loadCliConfig({
|
|
1095
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1096
|
+
const config = await loadCliConfig(createTestMergedSettings({
|
|
1063
1097
|
model: {
|
|
1064
1098
|
name: 'gemini-2.5-pro',
|
|
1065
1099
|
},
|
|
1066
|
-
}, 'test-session', argv);
|
|
1100
|
+
}), 'test-session', argv);
|
|
1067
1101
|
expect(config.getModel()).toBe('gemini-2.5-pro');
|
|
1068
1102
|
});
|
|
1069
1103
|
it('uses the default gemini model if nothing is set', async () => {
|
|
1070
1104
|
process.argv = ['node', 'script.js']; // No model set.
|
|
1071
|
-
const argv = await parseArguments(
|
|
1072
|
-
const config = await loadCliConfig({
|
|
1105
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1106
|
+
const config = await loadCliConfig(createTestMergedSettings({
|
|
1073
1107
|
// No model set.
|
|
1074
|
-
}, 'test-session', argv);
|
|
1108
|
+
}), 'test-session', argv);
|
|
1075
1109
|
expect(config.getModel()).toBe('auto-gemini-2.5');
|
|
1076
1110
|
});
|
|
1077
1111
|
it('always prefers model from argv', async () => {
|
|
1078
1112
|
process.argv = ['node', 'script.js', '--model', 'gemini-2.5-flash-preview'];
|
|
1079
|
-
const argv = await parseArguments(
|
|
1080
|
-
const config = await loadCliConfig({
|
|
1113
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1114
|
+
const config = await loadCliConfig(createTestMergedSettings({
|
|
1081
1115
|
model: {
|
|
1082
1116
|
name: 'gemini-2.5-pro',
|
|
1083
1117
|
},
|
|
1084
|
-
}, 'test-session', argv);
|
|
1118
|
+
}), 'test-session', argv);
|
|
1085
1119
|
expect(config.getModel()).toBe('gemini-2.5-flash-preview');
|
|
1086
1120
|
});
|
|
1087
1121
|
it('selects the model from argv if provided', async () => {
|
|
1088
1122
|
process.argv = ['node', 'script.js', '--model', 'gemini-2.5-flash-preview'];
|
|
1089
|
-
const argv = await parseArguments(
|
|
1090
|
-
const config = await loadCliConfig({
|
|
1123
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1124
|
+
const config = await loadCliConfig(createTestMergedSettings({
|
|
1091
1125
|
// No model provided via settings.
|
|
1092
|
-
}, 'test-session', argv);
|
|
1126
|
+
}), 'test-session', argv);
|
|
1093
1127
|
expect(config.getModel()).toBe('gemini-2.5-flash-preview');
|
|
1094
1128
|
});
|
|
1129
|
+
it('selects the default auto model if provided via auto alias', async () => {
|
|
1130
|
+
process.argv = ['node', 'script.js', '--model', 'auto'];
|
|
1131
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1132
|
+
const config = await loadCliConfig(createTestMergedSettings({
|
|
1133
|
+
// No model provided via settings.
|
|
1134
|
+
}), 'test-session', argv);
|
|
1135
|
+
expect(config.getModel()).toBe('auto-gemini-2.5');
|
|
1136
|
+
});
|
|
1095
1137
|
});
|
|
1096
1138
|
describe('loadCliConfig folderTrust', () => {
|
|
1097
1139
|
beforeEach(() => {
|
|
@@ -1106,34 +1148,34 @@ describe('loadCliConfig folderTrust', () => {
|
|
|
1106
1148
|
});
|
|
1107
1149
|
it('should be false when folderTrust is false', async () => {
|
|
1108
1150
|
process.argv = ['node', 'script.js'];
|
|
1109
|
-
const settings = {
|
|
1151
|
+
const settings = createTestMergedSettings({
|
|
1110
1152
|
security: {
|
|
1111
1153
|
folderTrust: {
|
|
1112
1154
|
enabled: false,
|
|
1113
1155
|
},
|
|
1114
1156
|
},
|
|
1115
|
-
};
|
|
1116
|
-
const argv = await parseArguments(
|
|
1157
|
+
});
|
|
1158
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1117
1159
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1118
1160
|
expect(config.getFolderTrust()).toBe(false);
|
|
1119
1161
|
});
|
|
1120
1162
|
it('should be true when folderTrust is true', async () => {
|
|
1121
1163
|
process.argv = ['node', 'script.js'];
|
|
1122
|
-
const argv = await parseArguments(
|
|
1123
|
-
const settings = {
|
|
1164
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1165
|
+
const settings = createTestMergedSettings({
|
|
1124
1166
|
security: {
|
|
1125
1167
|
folderTrust: {
|
|
1126
1168
|
enabled: true,
|
|
1127
1169
|
},
|
|
1128
1170
|
},
|
|
1129
|
-
};
|
|
1171
|
+
});
|
|
1130
1172
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1131
1173
|
expect(config.getFolderTrust()).toBe(true);
|
|
1132
1174
|
});
|
|
1133
1175
|
it('should be false by default', async () => {
|
|
1134
1176
|
process.argv = ['node', 'script.js'];
|
|
1135
|
-
const argv = await parseArguments(
|
|
1136
|
-
const settings =
|
|
1177
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1178
|
+
const settings = createTestMergedSettings();
|
|
1137
1179
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1138
1180
|
expect(config.getFolderTrust()).toBe(false);
|
|
1139
1181
|
});
|
|
@@ -1157,8 +1199,8 @@ describe('loadCliConfig with includeDirectories', () => {
|
|
|
1157
1199
|
'--include-directories',
|
|
1158
1200
|
`${path.resolve(path.sep, 'cli', 'path1')},${path.join(mockCwd, 'cli', 'path2')}`,
|
|
1159
1201
|
];
|
|
1160
|
-
const argv = await parseArguments(
|
|
1161
|
-
const settings = {
|
|
1202
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1203
|
+
const settings = createTestMergedSettings({
|
|
1162
1204
|
context: {
|
|
1163
1205
|
includeDirectories: [
|
|
1164
1206
|
path.resolve(path.sep, 'settings', 'path1'),
|
|
@@ -1166,7 +1208,7 @@ describe('loadCliConfig with includeDirectories', () => {
|
|
|
1166
1208
|
path.join(mockCwd, 'settings', 'path3'),
|
|
1167
1209
|
],
|
|
1168
1210
|
},
|
|
1169
|
-
};
|
|
1211
|
+
});
|
|
1170
1212
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1171
1213
|
const expected = [
|
|
1172
1214
|
mockCwd,
|
|
@@ -1195,21 +1237,21 @@ describe('loadCliConfig compressionThreshold', () => {
|
|
|
1195
1237
|
});
|
|
1196
1238
|
it('should pass settings to the core config', async () => {
|
|
1197
1239
|
process.argv = ['node', 'script.js'];
|
|
1198
|
-
const argv = await parseArguments(
|
|
1199
|
-
const settings = {
|
|
1240
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1241
|
+
const settings = createTestMergedSettings({
|
|
1200
1242
|
model: {
|
|
1201
1243
|
compressionThreshold: 0.5,
|
|
1202
1244
|
},
|
|
1203
|
-
};
|
|
1245
|
+
});
|
|
1204
1246
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1205
1247
|
expect(await config.getCompressionThreshold()).toBe(0.5);
|
|
1206
1248
|
});
|
|
1207
|
-
it('should have
|
|
1249
|
+
it('should have default compressionThreshold if not in settings', async () => {
|
|
1208
1250
|
process.argv = ['node', 'script.js'];
|
|
1209
|
-
const argv = await parseArguments(
|
|
1210
|
-
const settings =
|
|
1251
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1252
|
+
const settings = createTestMergedSettings();
|
|
1211
1253
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1212
|
-
expect(await config.getCompressionThreshold()).
|
|
1254
|
+
expect(await config.getCompressionThreshold()).toBe(0.5);
|
|
1213
1255
|
});
|
|
1214
1256
|
});
|
|
1215
1257
|
describe('loadCliConfig useRipgrep', () => {
|
|
@@ -1225,22 +1267,22 @@ describe('loadCliConfig useRipgrep', () => {
|
|
|
1225
1267
|
});
|
|
1226
1268
|
it('should be true by default when useRipgrep is not set in settings', async () => {
|
|
1227
1269
|
process.argv = ['node', 'script.js'];
|
|
1228
|
-
const argv = await parseArguments(
|
|
1229
|
-
const settings =
|
|
1270
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1271
|
+
const settings = createTestMergedSettings();
|
|
1230
1272
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1231
1273
|
expect(config.getUseRipgrep()).toBe(true);
|
|
1232
1274
|
});
|
|
1233
1275
|
it('should be false when useRipgrep is set to false in settings', async () => {
|
|
1234
1276
|
process.argv = ['node', 'script.js'];
|
|
1235
|
-
const argv = await parseArguments(
|
|
1236
|
-
const settings = { tools: { useRipgrep: false } };
|
|
1277
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1278
|
+
const settings = createTestMergedSettings({ tools: { useRipgrep: false } });
|
|
1237
1279
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1238
1280
|
expect(config.getUseRipgrep()).toBe(false);
|
|
1239
1281
|
});
|
|
1240
1282
|
it('should be true when useRipgrep is explicitly set to true in settings', async () => {
|
|
1241
1283
|
process.argv = ['node', 'script.js'];
|
|
1242
|
-
const argv = await parseArguments(
|
|
1243
|
-
const settings = { tools: { useRipgrep: true } };
|
|
1284
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1285
|
+
const settings = createTestMergedSettings({ tools: { useRipgrep: true } });
|
|
1244
1286
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1245
1287
|
expect(config.getUseRipgrep()).toBe(true);
|
|
1246
1288
|
});
|
|
@@ -1258,35 +1300,35 @@ describe('screenReader configuration', () => {
|
|
|
1258
1300
|
});
|
|
1259
1301
|
it('should use screenReader value from settings if CLI flag is not present (settings true)', async () => {
|
|
1260
1302
|
process.argv = ['node', 'script.js'];
|
|
1261
|
-
const argv = await parseArguments(
|
|
1262
|
-
const settings = {
|
|
1303
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1304
|
+
const settings = createTestMergedSettings({
|
|
1263
1305
|
ui: { accessibility: { screenReader: true } },
|
|
1264
|
-
};
|
|
1306
|
+
});
|
|
1265
1307
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1266
1308
|
expect(config.getScreenReader()).toBe(true);
|
|
1267
1309
|
});
|
|
1268
1310
|
it('should use screenReader value from settings if CLI flag is not present (settings false)', async () => {
|
|
1269
1311
|
process.argv = ['node', 'script.js'];
|
|
1270
|
-
const argv = await parseArguments(
|
|
1271
|
-
const settings = {
|
|
1312
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1313
|
+
const settings = createTestMergedSettings({
|
|
1272
1314
|
ui: { accessibility: { screenReader: false } },
|
|
1273
|
-
};
|
|
1315
|
+
});
|
|
1274
1316
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1275
1317
|
expect(config.getScreenReader()).toBe(false);
|
|
1276
1318
|
});
|
|
1277
1319
|
it('should prioritize --screen-reader CLI flag (true) over settings (false)', async () => {
|
|
1278
1320
|
process.argv = ['node', 'script.js', '--screen-reader'];
|
|
1279
|
-
const argv = await parseArguments(
|
|
1280
|
-
const settings = {
|
|
1321
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1322
|
+
const settings = createTestMergedSettings({
|
|
1281
1323
|
ui: { accessibility: { screenReader: false } },
|
|
1282
|
-
};
|
|
1324
|
+
});
|
|
1283
1325
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1284
1326
|
expect(config.getScreenReader()).toBe(true);
|
|
1285
1327
|
});
|
|
1286
1328
|
it('should be false by default when no flag or setting is present', async () => {
|
|
1287
1329
|
process.argv = ['node', 'script.js'];
|
|
1288
|
-
const argv = await parseArguments(
|
|
1289
|
-
const settings =
|
|
1330
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1331
|
+
const settings = createTestMergedSettings();
|
|
1290
1332
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1291
1333
|
expect(config.getScreenReader()).toBe(false);
|
|
1292
1334
|
});
|
|
@@ -1312,8 +1354,8 @@ describe('loadCliConfig tool exclusions', () => {
|
|
|
1312
1354
|
it('should not exclude interactive tools in interactive mode without YOLO', async () => {
|
|
1313
1355
|
process.stdin.isTTY = true;
|
|
1314
1356
|
process.argv = ['node', 'script.js'];
|
|
1315
|
-
const argv = await parseArguments(
|
|
1316
|
-
const config = await loadCliConfig(
|
|
1357
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1358
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1317
1359
|
expect(config.getExcludeTools()).not.toContain('run_shell_command');
|
|
1318
1360
|
expect(config.getExcludeTools()).not.toContain('replace');
|
|
1319
1361
|
expect(config.getExcludeTools()).not.toContain('write_file');
|
|
@@ -1321,8 +1363,8 @@ describe('loadCliConfig tool exclusions', () => {
|
|
|
1321
1363
|
it('should not exclude interactive tools in interactive mode with YOLO', async () => {
|
|
1322
1364
|
process.stdin.isTTY = true;
|
|
1323
1365
|
process.argv = ['node', 'script.js', '--yolo'];
|
|
1324
|
-
const argv = await parseArguments(
|
|
1325
|
-
const config = await loadCliConfig(
|
|
1366
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1367
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1326
1368
|
expect(config.getExcludeTools()).not.toContain('run_shell_command');
|
|
1327
1369
|
expect(config.getExcludeTools()).not.toContain('replace');
|
|
1328
1370
|
expect(config.getExcludeTools()).not.toContain('write_file');
|
|
@@ -1330,8 +1372,8 @@ describe('loadCliConfig tool exclusions', () => {
|
|
|
1330
1372
|
it('should exclude interactive tools in non-interactive mode without YOLO', async () => {
|
|
1331
1373
|
process.stdin.isTTY = false;
|
|
1332
1374
|
process.argv = ['node', 'script.js', '-p', 'test'];
|
|
1333
|
-
const argv = await parseArguments(
|
|
1334
|
-
const config = await loadCliConfig(
|
|
1375
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1376
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1335
1377
|
expect(config.getExcludeTools()).toContain('run_shell_command');
|
|
1336
1378
|
expect(config.getExcludeTools()).toContain('replace');
|
|
1337
1379
|
expect(config.getExcludeTools()).toContain('write_file');
|
|
@@ -1339,8 +1381,8 @@ describe('loadCliConfig tool exclusions', () => {
|
|
|
1339
1381
|
it('should not exclude interactive tools in non-interactive mode with YOLO', async () => {
|
|
1340
1382
|
process.stdin.isTTY = false;
|
|
1341
1383
|
process.argv = ['node', 'script.js', '-p', 'test', '--yolo'];
|
|
1342
|
-
const argv = await parseArguments(
|
|
1343
|
-
const config = await loadCliConfig(
|
|
1384
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1385
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1344
1386
|
expect(config.getExcludeTools()).not.toContain('run_shell_command');
|
|
1345
1387
|
expect(config.getExcludeTools()).not.toContain('replace');
|
|
1346
1388
|
expect(config.getExcludeTools()).not.toContain('write_file');
|
|
@@ -1355,15 +1397,15 @@ describe('loadCliConfig tool exclusions', () => {
|
|
|
1355
1397
|
'--allowed-tools',
|
|
1356
1398
|
'ShellTool',
|
|
1357
1399
|
];
|
|
1358
|
-
const argv = await parseArguments(
|
|
1359
|
-
const config = await loadCliConfig(
|
|
1400
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1401
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1360
1402
|
expect(config.getExcludeTools()).not.toContain(SHELL_TOOL_NAME);
|
|
1361
1403
|
});
|
|
1362
1404
|
it('should exclude web-fetch in non-interactive mode when not allowed', async () => {
|
|
1363
1405
|
process.stdin.isTTY = false;
|
|
1364
1406
|
process.argv = ['node', 'script.js', '-p', 'test'];
|
|
1365
|
-
const argv = await parseArguments(
|
|
1366
|
-
const config = await loadCliConfig(
|
|
1407
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1408
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1367
1409
|
expect(config.getExcludeTools()).toContain(WEB_FETCH_TOOL_NAME);
|
|
1368
1410
|
});
|
|
1369
1411
|
it('should not exclude web-fetch in non-interactive mode when allowed', async () => {
|
|
@@ -1376,8 +1418,8 @@ describe('loadCliConfig tool exclusions', () => {
|
|
|
1376
1418
|
'--allowed-tools',
|
|
1377
1419
|
WEB_FETCH_TOOL_NAME,
|
|
1378
1420
|
];
|
|
1379
|
-
const argv = await parseArguments(
|
|
1380
|
-
const config = await loadCliConfig(
|
|
1421
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1422
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1381
1423
|
expect(config.getExcludeTools()).not.toContain(WEB_FETCH_TOOL_NAME);
|
|
1382
1424
|
});
|
|
1383
1425
|
it('should not exclude shell tool in non-interactive mode when --allowed-tools="run_shell_command" is set', async () => {
|
|
@@ -1390,8 +1432,8 @@ describe('loadCliConfig tool exclusions', () => {
|
|
|
1390
1432
|
'--allowed-tools',
|
|
1391
1433
|
'run_shell_command',
|
|
1392
1434
|
];
|
|
1393
|
-
const argv = await parseArguments(
|
|
1394
|
-
const config = await loadCliConfig(
|
|
1435
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1436
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1395
1437
|
expect(config.getExcludeTools()).not.toContain(SHELL_TOOL_NAME);
|
|
1396
1438
|
});
|
|
1397
1439
|
it('should not exclude shell tool in non-interactive mode when --allowed-tools="ShellTool(wc)" is set', async () => {
|
|
@@ -1404,8 +1446,8 @@ describe('loadCliConfig tool exclusions', () => {
|
|
|
1404
1446
|
'--allowed-tools',
|
|
1405
1447
|
'ShellTool(wc)',
|
|
1406
1448
|
];
|
|
1407
|
-
const argv = await parseArguments(
|
|
1408
|
-
const config = await loadCliConfig(
|
|
1449
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1450
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1409
1451
|
expect(config.getExcludeTools()).not.toContain(SHELL_TOOL_NAME);
|
|
1410
1452
|
});
|
|
1411
1453
|
});
|
|
@@ -1426,36 +1468,36 @@ describe('loadCliConfig interactive', () => {
|
|
|
1426
1468
|
it('should be interactive if isTTY and no prompt', async () => {
|
|
1427
1469
|
process.stdin.isTTY = true;
|
|
1428
1470
|
process.argv = ['node', 'script.js'];
|
|
1429
|
-
const argv = await parseArguments(
|
|
1430
|
-
const config = await loadCliConfig(
|
|
1471
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1472
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1431
1473
|
expect(config.isInteractive()).toBe(true);
|
|
1432
1474
|
});
|
|
1433
1475
|
it('should be interactive if prompt-interactive is set', async () => {
|
|
1434
1476
|
process.stdin.isTTY = false;
|
|
1435
1477
|
process.argv = ['node', 'script.js', '--prompt-interactive', 'test'];
|
|
1436
|
-
const argv = await parseArguments(
|
|
1437
|
-
const config = await loadCliConfig(
|
|
1478
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1479
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1438
1480
|
expect(config.isInteractive()).toBe(true);
|
|
1439
1481
|
});
|
|
1440
1482
|
it('should not be interactive if not isTTY and no prompt', async () => {
|
|
1441
1483
|
process.stdin.isTTY = false;
|
|
1442
1484
|
process.argv = ['node', 'script.js'];
|
|
1443
|
-
const argv = await parseArguments(
|
|
1444
|
-
const config = await loadCliConfig(
|
|
1485
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1486
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1445
1487
|
expect(config.isInteractive()).toBe(false);
|
|
1446
1488
|
});
|
|
1447
1489
|
it('should not be interactive if prompt is set', async () => {
|
|
1448
1490
|
process.stdin.isTTY = true;
|
|
1449
1491
|
process.argv = ['node', 'script.js', '--prompt', 'test'];
|
|
1450
|
-
const argv = await parseArguments(
|
|
1451
|
-
const config = await loadCliConfig(
|
|
1492
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1493
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1452
1494
|
expect(config.isInteractive()).toBe(false);
|
|
1453
1495
|
});
|
|
1454
1496
|
it('should not be interactive if positional prompt words are provided with other flags', async () => {
|
|
1455
1497
|
process.stdin.isTTY = true;
|
|
1456
1498
|
process.argv = ['node', 'script.js', '--model', 'gemini-2.5-pro', 'Hello'];
|
|
1457
|
-
const argv = await parseArguments(
|
|
1458
|
-
const config = await loadCliConfig(
|
|
1499
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1500
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1459
1501
|
expect(config.isInteractive()).toBe(false);
|
|
1460
1502
|
});
|
|
1461
1503
|
it('should not be interactive if positional prompt words are provided with multiple flags', async () => {
|
|
@@ -1468,8 +1510,8 @@ describe('loadCliConfig interactive', () => {
|
|
|
1468
1510
|
'--yolo',
|
|
1469
1511
|
'Hello world',
|
|
1470
1512
|
];
|
|
1471
|
-
const argv = await parseArguments(
|
|
1472
|
-
const config = await loadCliConfig(
|
|
1513
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1514
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1473
1515
|
expect(config.isInteractive()).toBe(false);
|
|
1474
1516
|
// Verify the question is preserved for one-shot execution
|
|
1475
1517
|
expect(argv.prompt).toBe('Hello world');
|
|
@@ -1478,8 +1520,8 @@ describe('loadCliConfig interactive', () => {
|
|
|
1478
1520
|
it('should not be interactive if positional prompt words are provided with extensions flag', async () => {
|
|
1479
1521
|
process.stdin.isTTY = true;
|
|
1480
1522
|
process.argv = ['node', 'script.js', '-e', 'none', 'hello'];
|
|
1481
|
-
const argv = await parseArguments(
|
|
1482
|
-
const config = await loadCliConfig(
|
|
1523
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1524
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1483
1525
|
expect(config.isInteractive()).toBe(false);
|
|
1484
1526
|
expect(argv.query).toBe('hello');
|
|
1485
1527
|
expect(argv.extensions).toEqual(['none']);
|
|
@@ -1487,8 +1529,8 @@ describe('loadCliConfig interactive', () => {
|
|
|
1487
1529
|
it('should handle multiple positional words correctly', async () => {
|
|
1488
1530
|
process.stdin.isTTY = true;
|
|
1489
1531
|
process.argv = ['node', 'script.js', 'hello world how are you'];
|
|
1490
|
-
const argv = await parseArguments(
|
|
1491
|
-
const config = await loadCliConfig(
|
|
1532
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1533
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1492
1534
|
expect(config.isInteractive()).toBe(false);
|
|
1493
1535
|
expect(argv.query).toBe('hello world how are you');
|
|
1494
1536
|
expect(argv.prompt).toBe('hello world how are you');
|
|
@@ -1507,8 +1549,8 @@ describe('loadCliConfig interactive', () => {
|
|
|
1507
1549
|
'sort',
|
|
1508
1550
|
'array',
|
|
1509
1551
|
];
|
|
1510
|
-
const argv = await parseArguments(
|
|
1511
|
-
const config = await loadCliConfig(
|
|
1552
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1553
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1512
1554
|
expect(config.isInteractive()).toBe(false);
|
|
1513
1555
|
expect(argv.query).toBe('write a function to sort array');
|
|
1514
1556
|
expect(argv.model).toBe('gemini-2.5-pro');
|
|
@@ -1516,8 +1558,8 @@ describe('loadCliConfig interactive', () => {
|
|
|
1516
1558
|
it('should handle empty positional arguments', async () => {
|
|
1517
1559
|
process.stdin.isTTY = true;
|
|
1518
1560
|
process.argv = ['node', 'script.js', ''];
|
|
1519
|
-
const argv = await parseArguments(
|
|
1520
|
-
const config = await loadCliConfig(
|
|
1561
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1562
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1521
1563
|
expect(config.isInteractive()).toBe(true);
|
|
1522
1564
|
expect(argv.query).toBeUndefined();
|
|
1523
1565
|
});
|
|
@@ -1534,8 +1576,8 @@ describe('loadCliConfig interactive', () => {
|
|
|
1534
1576
|
'are',
|
|
1535
1577
|
'you',
|
|
1536
1578
|
];
|
|
1537
|
-
const argv = await parseArguments(
|
|
1538
|
-
const config = await loadCliConfig(
|
|
1579
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1580
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1539
1581
|
expect(config.isInteractive()).toBe(false);
|
|
1540
1582
|
expect(argv.query).toBe('hello world how are you');
|
|
1541
1583
|
expect(argv.extensions).toEqual(['none']);
|
|
@@ -1543,8 +1585,8 @@ describe('loadCliConfig interactive', () => {
|
|
|
1543
1585
|
it('should be interactive if no positional prompt words are provided with flags', async () => {
|
|
1544
1586
|
process.stdin.isTTY = true;
|
|
1545
1587
|
process.argv = ['node', 'script.js', '--model', 'gemini-2.5-pro'];
|
|
1546
|
-
const argv = await parseArguments(
|
|
1547
|
-
const config = await loadCliConfig(
|
|
1588
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1589
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1548
1590
|
expect(config.isInteractive()).toBe(true);
|
|
1549
1591
|
});
|
|
1550
1592
|
});
|
|
@@ -1568,56 +1610,83 @@ describe('loadCliConfig approval mode', () => {
|
|
|
1568
1610
|
});
|
|
1569
1611
|
it('should default to DEFAULT approval mode when no flags are set', async () => {
|
|
1570
1612
|
process.argv = ['node', 'script.js'];
|
|
1571
|
-
const argv = await parseArguments(
|
|
1572
|
-
const config = await loadCliConfig(
|
|
1613
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1614
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1573
1615
|
expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.DEFAULT);
|
|
1574
1616
|
});
|
|
1575
1617
|
it('should set YOLO approval mode when --yolo flag is used', async () => {
|
|
1576
1618
|
process.argv = ['node', 'script.js', '--yolo'];
|
|
1577
|
-
const argv = await parseArguments(
|
|
1578
|
-
const config = await loadCliConfig(
|
|
1619
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1620
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1579
1621
|
expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.YOLO);
|
|
1580
1622
|
});
|
|
1581
1623
|
it('should set YOLO approval mode when -y flag is used', async () => {
|
|
1582
1624
|
process.argv = ['node', 'script.js', '-y'];
|
|
1583
|
-
const argv = await parseArguments(
|
|
1584
|
-
const config = await loadCliConfig(
|
|
1625
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1626
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1585
1627
|
expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.YOLO);
|
|
1586
1628
|
});
|
|
1587
1629
|
it('should set DEFAULT approval mode when --approval-mode=default', async () => {
|
|
1588
1630
|
process.argv = ['node', 'script.js', '--approval-mode', 'default'];
|
|
1589
|
-
const argv = await parseArguments(
|
|
1590
|
-
const config = await loadCliConfig(
|
|
1631
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1632
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1591
1633
|
expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.DEFAULT);
|
|
1592
1634
|
});
|
|
1593
1635
|
it('should set AUTO_EDIT approval mode when --approval-mode=auto_edit', async () => {
|
|
1594
1636
|
process.argv = ['node', 'script.js', '--approval-mode', 'auto_edit'];
|
|
1595
|
-
const argv = await parseArguments(
|
|
1596
|
-
const config = await loadCliConfig(
|
|
1637
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1638
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1597
1639
|
expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.AUTO_EDIT);
|
|
1598
1640
|
});
|
|
1599
1641
|
it('should set YOLO approval mode when --approval-mode=yolo', async () => {
|
|
1600
1642
|
process.argv = ['node', 'script.js', '--approval-mode', 'yolo'];
|
|
1601
|
-
const argv = await parseArguments(
|
|
1602
|
-
const config = await loadCliConfig(
|
|
1643
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1644
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1603
1645
|
expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.YOLO);
|
|
1604
1646
|
});
|
|
1605
1647
|
it('should prioritize --approval-mode over --yolo when both would be valid (but validation prevents this)', async () => {
|
|
1606
1648
|
// Note: This test documents the intended behavior, but in practice the validation
|
|
1607
1649
|
// prevents both flags from being used together
|
|
1608
1650
|
process.argv = ['node', 'script.js', '--approval-mode', 'default'];
|
|
1609
|
-
const argv = await parseArguments(
|
|
1651
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1610
1652
|
// Manually set yolo to true to simulate what would happen if validation didn't prevent it
|
|
1611
1653
|
argv.yolo = true;
|
|
1612
|
-
const config = await loadCliConfig(
|
|
1654
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1613
1655
|
expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.DEFAULT);
|
|
1614
1656
|
});
|
|
1615
1657
|
it('should fall back to --yolo behavior when --approval-mode is not set', async () => {
|
|
1616
1658
|
process.argv = ['node', 'script.js', '--yolo'];
|
|
1617
|
-
const argv = await parseArguments(
|
|
1618
|
-
const config = await loadCliConfig(
|
|
1659
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1660
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1619
1661
|
expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.YOLO);
|
|
1620
1662
|
});
|
|
1663
|
+
it('should set Plan approval mode when --approval-mode=plan is used and experimental.plan is enabled', async () => {
|
|
1664
|
+
process.argv = ['node', 'script.js', '--approval-mode', 'plan'];
|
|
1665
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1666
|
+
const settings = createTestMergedSettings({
|
|
1667
|
+
experimental: {
|
|
1668
|
+
plan: true,
|
|
1669
|
+
},
|
|
1670
|
+
});
|
|
1671
|
+
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1672
|
+
expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.PLAN);
|
|
1673
|
+
});
|
|
1674
|
+
it('should throw error when --approval-mode=plan is used but experimental.plan is disabled', async () => {
|
|
1675
|
+
process.argv = ['node', 'script.js', '--approval-mode', 'plan'];
|
|
1676
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1677
|
+
const settings = createTestMergedSettings({
|
|
1678
|
+
experimental: {
|
|
1679
|
+
plan: false,
|
|
1680
|
+
},
|
|
1681
|
+
});
|
|
1682
|
+
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow('Approval mode "plan" is only available when experimental.plan is enabled.');
|
|
1683
|
+
});
|
|
1684
|
+
it('should throw error when --approval-mode=plan is used but experimental.plan setting is missing', async () => {
|
|
1685
|
+
process.argv = ['node', 'script.js', '--approval-mode', 'plan'];
|
|
1686
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1687
|
+
const settings = createTestMergedSettings({});
|
|
1688
|
+
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow('Approval mode "plan" is only available when experimental.plan is enabled.');
|
|
1689
|
+
});
|
|
1621
1690
|
// --- Untrusted Folder Scenarios ---
|
|
1622
1691
|
describe('when folder is NOT trusted', () => {
|
|
1623
1692
|
beforeEach(() => {
|
|
@@ -1628,26 +1697,26 @@ describe('loadCliConfig approval mode', () => {
|
|
|
1628
1697
|
});
|
|
1629
1698
|
it('should override --approval-mode=yolo to DEFAULT', async () => {
|
|
1630
1699
|
process.argv = ['node', 'script.js', '--approval-mode', 'yolo'];
|
|
1631
|
-
const argv = await parseArguments(
|
|
1632
|
-
const config = await loadCliConfig(
|
|
1700
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1701
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1633
1702
|
expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.DEFAULT);
|
|
1634
1703
|
});
|
|
1635
1704
|
it('should override --approval-mode=auto_edit to DEFAULT', async () => {
|
|
1636
1705
|
process.argv = ['node', 'script.js', '--approval-mode', 'auto_edit'];
|
|
1637
|
-
const argv = await parseArguments(
|
|
1638
|
-
const config = await loadCliConfig(
|
|
1706
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1707
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1639
1708
|
expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.DEFAULT);
|
|
1640
1709
|
});
|
|
1641
1710
|
it('should override --yolo flag to DEFAULT', async () => {
|
|
1642
1711
|
process.argv = ['node', 'script.js', '--yolo'];
|
|
1643
|
-
const argv = await parseArguments(
|
|
1644
|
-
const config = await loadCliConfig(
|
|
1712
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1713
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1645
1714
|
expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.DEFAULT);
|
|
1646
1715
|
});
|
|
1647
1716
|
it('should remain DEFAULT when --approval-mode=default', async () => {
|
|
1648
1717
|
process.argv = ['node', 'script.js', '--approval-mode', 'default'];
|
|
1649
|
-
const argv = await parseArguments(
|
|
1650
|
-
const config = await loadCliConfig(
|
|
1718
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1719
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1651
1720
|
expect(config.getApprovalMode()).toBe(ServerConfig.ApprovalMode.DEFAULT);
|
|
1652
1721
|
});
|
|
1653
1722
|
});
|
|
@@ -1668,13 +1737,13 @@ describe('loadCliConfig fileFiltering', () => {
|
|
|
1668
1737
|
});
|
|
1669
1738
|
const testCases = [
|
|
1670
1739
|
{
|
|
1671
|
-
property: '
|
|
1672
|
-
getter: (c) => c.
|
|
1740
|
+
property: 'enableFuzzySearch',
|
|
1741
|
+
getter: (c) => c.getFileFilteringEnableFuzzySearch(),
|
|
1673
1742
|
value: true,
|
|
1674
1743
|
},
|
|
1675
1744
|
{
|
|
1676
|
-
property: '
|
|
1677
|
-
getter: (c) => c.
|
|
1745
|
+
property: 'enableFuzzySearch',
|
|
1746
|
+
getter: (c) => c.getFileFilteringEnableFuzzySearch(),
|
|
1678
1747
|
value: false,
|
|
1679
1748
|
},
|
|
1680
1749
|
{
|
|
@@ -1709,11 +1778,11 @@ describe('loadCliConfig fileFiltering', () => {
|
|
|
1709
1778
|
},
|
|
1710
1779
|
];
|
|
1711
1780
|
it.each(testCases)('should pass $property from settings to config when $value', async ({ property, getter, value }) => {
|
|
1712
|
-
const settings = {
|
|
1781
|
+
const settings = createTestMergedSettings({
|
|
1713
1782
|
context: {
|
|
1714
1783
|
fileFiltering: { [property]: value },
|
|
1715
1784
|
},
|
|
1716
|
-
};
|
|
1785
|
+
});
|
|
1717
1786
|
const argv = await parseArguments(settings);
|
|
1718
1787
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1719
1788
|
expect(getter(config)).toBe(value);
|
|
@@ -1728,26 +1797,26 @@ describe('Output format', () => {
|
|
|
1728
1797
|
});
|
|
1729
1798
|
it('should default to TEXT', async () => {
|
|
1730
1799
|
process.argv = ['node', 'script.js'];
|
|
1731
|
-
const argv = await parseArguments(
|
|
1732
|
-
const config = await loadCliConfig(
|
|
1800
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1801
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1733
1802
|
expect(config.getOutputFormat()).toBe(OutputFormat.TEXT);
|
|
1734
1803
|
});
|
|
1735
1804
|
it('should use the format from settings', async () => {
|
|
1736
1805
|
process.argv = ['node', 'script.js'];
|
|
1737
|
-
const argv = await parseArguments(
|
|
1738
|
-
const config = await loadCliConfig({ output: { format: OutputFormat.JSON } }, 'test-session', argv);
|
|
1806
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1807
|
+
const config = await loadCliConfig(createTestMergedSettings({ output: { format: OutputFormat.JSON } }), 'test-session', argv);
|
|
1739
1808
|
expect(config.getOutputFormat()).toBe(OutputFormat.JSON);
|
|
1740
1809
|
});
|
|
1741
1810
|
it('should prioritize the format from argv', async () => {
|
|
1742
1811
|
process.argv = ['node', 'script.js', '--output-format', 'json'];
|
|
1743
|
-
const argv = await parseArguments(
|
|
1744
|
-
const config = await loadCliConfig({ output: { format: OutputFormat.JSON } }, 'test-session', argv);
|
|
1812
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1813
|
+
const config = await loadCliConfig(createTestMergedSettings({ output: { format: OutputFormat.JSON } }), 'test-session', argv);
|
|
1745
1814
|
expect(config.getOutputFormat()).toBe(OutputFormat.JSON);
|
|
1746
1815
|
});
|
|
1747
1816
|
it('should accept stream-json as a valid output format', async () => {
|
|
1748
1817
|
process.argv = ['node', 'script.js', '--output-format', 'stream-json'];
|
|
1749
|
-
const argv = await parseArguments(
|
|
1750
|
-
const config = await loadCliConfig(
|
|
1818
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1819
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1751
1820
|
expect(config.getOutputFormat()).toBe(OutputFormat.STREAM_JSON);
|
|
1752
1821
|
});
|
|
1753
1822
|
it('should error on invalid --output-format argument', async () => {
|
|
@@ -1761,7 +1830,7 @@ describe('Output format', () => {
|
|
|
1761
1830
|
const debugErrorSpy = vi
|
|
1762
1831
|
.spyOn(debugLogger, 'error')
|
|
1763
1832
|
.mockImplementation(() => { });
|
|
1764
|
-
await expect(parseArguments(
|
|
1833
|
+
await expect(parseArguments(createTestMergedSettings())).rejects.toThrow('process.exit called');
|
|
1765
1834
|
expect(debugErrorSpy).toHaveBeenCalledWith(expect.stringContaining('Invalid values:'));
|
|
1766
1835
|
expect(mockConsoleError).toHaveBeenCalled();
|
|
1767
1836
|
mockExit.mockRestore();
|
|
@@ -1792,7 +1861,7 @@ describe('parseArguments with positional prompt', () => {
|
|
|
1792
1861
|
const debugErrorSpy = vi
|
|
1793
1862
|
.spyOn(debugLogger, 'error')
|
|
1794
1863
|
.mockImplementation(() => { });
|
|
1795
|
-
await expect(parseArguments(
|
|
1864
|
+
await expect(parseArguments(createTestMergedSettings())).rejects.toThrow('process.exit called');
|
|
1796
1865
|
expect(debugErrorSpy).toHaveBeenCalledWith(expect.stringContaining('Cannot use both a positional prompt and the --prompt (-p) flag together'));
|
|
1797
1866
|
mockExit.mockRestore();
|
|
1798
1867
|
mockConsoleError.mockRestore();
|
|
@@ -1800,7 +1869,7 @@ describe('parseArguments with positional prompt', () => {
|
|
|
1800
1869
|
});
|
|
1801
1870
|
it('should correctly parse a positional prompt to query field', async () => {
|
|
1802
1871
|
process.argv = ['node', 'script.js', 'positional', 'prompt'];
|
|
1803
|
-
const argv = await parseArguments(
|
|
1872
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1804
1873
|
expect(argv.query).toBe('positional prompt');
|
|
1805
1874
|
// Since no explicit prompt flags are set and query doesn't start with @, should map to prompt (one-shot)
|
|
1806
1875
|
expect(argv.prompt).toBe('positional prompt');
|
|
@@ -1812,12 +1881,12 @@ describe('parseArguments with positional prompt', () => {
|
|
|
1812
1881
|
// This test verifies that the positional 'query' argument is properly configured
|
|
1813
1882
|
// with the description: "Positional prompt. Defaults to one-shot; use -i/--prompt-interactive for interactive."
|
|
1814
1883
|
process.argv = ['node', 'script.js', 'test', 'query'];
|
|
1815
|
-
const argv = await yargsInstance.parseArguments(
|
|
1884
|
+
const argv = await yargsInstance.parseArguments(createTestMergedSettings());
|
|
1816
1885
|
expect(argv.query).toBe('test query');
|
|
1817
1886
|
});
|
|
1818
1887
|
it('should correctly parse a prompt from the --prompt flag', async () => {
|
|
1819
1888
|
process.argv = ['node', 'script.js', '--prompt', 'test prompt'];
|
|
1820
|
-
const argv = await parseArguments(
|
|
1889
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1821
1890
|
expect(argv.prompt).toBe('test prompt');
|
|
1822
1891
|
});
|
|
1823
1892
|
});
|
|
@@ -1831,28 +1900,30 @@ describe('Telemetry configuration via environment variables', () => {
|
|
|
1831
1900
|
it('should prioritize GEMINI_TELEMETRY_ENABLED over settings', async () => {
|
|
1832
1901
|
vi.stubEnv('GEMINI_TELEMETRY_ENABLED', 'true');
|
|
1833
1902
|
process.argv = ['node', 'script.js'];
|
|
1834
|
-
const argv = await parseArguments(
|
|
1835
|
-
const settings = {
|
|
1903
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1904
|
+
const settings = createTestMergedSettings({
|
|
1905
|
+
telemetry: { enabled: false },
|
|
1906
|
+
});
|
|
1836
1907
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1837
1908
|
expect(config.getTelemetryEnabled()).toBe(true);
|
|
1838
1909
|
});
|
|
1839
1910
|
it('should prioritize GEMINI_TELEMETRY_TARGET over settings', async () => {
|
|
1840
1911
|
vi.stubEnv('GEMINI_TELEMETRY_TARGET', 'gcp');
|
|
1841
1912
|
process.argv = ['node', 'script.js'];
|
|
1842
|
-
const argv = await parseArguments(
|
|
1843
|
-
const settings = {
|
|
1913
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1914
|
+
const settings = createTestMergedSettings({
|
|
1844
1915
|
telemetry: { target: ServerConfig.TelemetryTarget.LOCAL },
|
|
1845
|
-
};
|
|
1916
|
+
});
|
|
1846
1917
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1847
1918
|
expect(config.getTelemetryTarget()).toBe('gcp');
|
|
1848
1919
|
});
|
|
1849
1920
|
it('should throw when GEMINI_TELEMETRY_TARGET is invalid', async () => {
|
|
1850
1921
|
vi.stubEnv('GEMINI_TELEMETRY_TARGET', 'bogus');
|
|
1851
1922
|
process.argv = ['node', 'script.js'];
|
|
1852
|
-
const argv = await parseArguments(
|
|
1853
|
-
const settings = {
|
|
1923
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1924
|
+
const settings = createTestMergedSettings({
|
|
1854
1925
|
telemetry: { target: ServerConfig.TelemetryTarget.GCP },
|
|
1855
|
-
};
|
|
1926
|
+
});
|
|
1856
1927
|
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow(/Invalid telemetry configuration: .*Invalid telemetry target/i);
|
|
1857
1928
|
vi.unstubAllEnvs();
|
|
1858
1929
|
});
|
|
@@ -1860,91 +1931,97 @@ describe('Telemetry configuration via environment variables', () => {
|
|
|
1860
1931
|
vi.stubEnv('OTEL_EXPORTER_OTLP_ENDPOINT', 'http://default.env.com');
|
|
1861
1932
|
vi.stubEnv('GEMINI_TELEMETRY_OTLP_ENDPOINT', 'http://gemini.env.com');
|
|
1862
1933
|
process.argv = ['node', 'script.js'];
|
|
1863
|
-
const argv = await parseArguments(
|
|
1864
|
-
const settings = {
|
|
1934
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1935
|
+
const settings = createTestMergedSettings({
|
|
1865
1936
|
telemetry: { otlpEndpoint: 'http://settings.com' },
|
|
1866
|
-
};
|
|
1937
|
+
});
|
|
1867
1938
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1868
1939
|
expect(config.getTelemetryOtlpEndpoint()).toBe('http://gemini.env.com');
|
|
1869
1940
|
});
|
|
1870
1941
|
it('should prioritize GEMINI_TELEMETRY_OTLP_PROTOCOL over settings', async () => {
|
|
1871
1942
|
vi.stubEnv('GEMINI_TELEMETRY_OTLP_PROTOCOL', 'http');
|
|
1872
1943
|
process.argv = ['node', 'script.js'];
|
|
1873
|
-
const argv = await parseArguments(
|
|
1874
|
-
const settings = {
|
|
1944
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1945
|
+
const settings = createTestMergedSettings({
|
|
1946
|
+
telemetry: { otlpProtocol: 'grpc' },
|
|
1947
|
+
});
|
|
1875
1948
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1876
1949
|
expect(config.getTelemetryOtlpProtocol()).toBe('http');
|
|
1877
1950
|
});
|
|
1878
1951
|
it('should prioritize GEMINI_TELEMETRY_LOG_PROMPTS over settings', async () => {
|
|
1879
1952
|
vi.stubEnv('GEMINI_TELEMETRY_LOG_PROMPTS', 'false');
|
|
1880
1953
|
process.argv = ['node', 'script.js'];
|
|
1881
|
-
const argv = await parseArguments(
|
|
1882
|
-
const settings = {
|
|
1954
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1955
|
+
const settings = createTestMergedSettings({
|
|
1956
|
+
telemetry: { logPrompts: true },
|
|
1957
|
+
});
|
|
1883
1958
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1884
1959
|
expect(config.getTelemetryLogPromptsEnabled()).toBe(false);
|
|
1885
1960
|
});
|
|
1886
1961
|
it('should prioritize GEMINI_TELEMETRY_OUTFILE over settings', async () => {
|
|
1887
1962
|
vi.stubEnv('GEMINI_TELEMETRY_OUTFILE', '/gemini/env/telemetry.log');
|
|
1888
1963
|
process.argv = ['node', 'script.js'];
|
|
1889
|
-
const argv = await parseArguments(
|
|
1890
|
-
const settings = {
|
|
1964
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1965
|
+
const settings = createTestMergedSettings({
|
|
1891
1966
|
telemetry: { outfile: '/settings/telemetry.log' },
|
|
1892
|
-
};
|
|
1967
|
+
});
|
|
1893
1968
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1894
1969
|
expect(config.getTelemetryOutfile()).toBe('/gemini/env/telemetry.log');
|
|
1895
1970
|
});
|
|
1896
1971
|
it('should prioritize GEMINI_TELEMETRY_USE_COLLECTOR over settings', async () => {
|
|
1897
1972
|
vi.stubEnv('GEMINI_TELEMETRY_USE_COLLECTOR', 'true');
|
|
1898
1973
|
process.argv = ['node', 'script.js'];
|
|
1899
|
-
const argv = await parseArguments(
|
|
1900
|
-
const settings = {
|
|
1974
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1975
|
+
const settings = createTestMergedSettings({
|
|
1976
|
+
telemetry: { useCollector: false },
|
|
1977
|
+
});
|
|
1901
1978
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1902
1979
|
expect(config.getTelemetryUseCollector()).toBe(true);
|
|
1903
1980
|
});
|
|
1904
1981
|
it('should use settings value when GEMINI_TELEMETRY_ENABLED is not set', async () => {
|
|
1905
1982
|
vi.stubEnv('GEMINI_TELEMETRY_ENABLED', undefined);
|
|
1906
1983
|
process.argv = ['node', 'script.js'];
|
|
1907
|
-
const argv = await parseArguments(
|
|
1908
|
-
const settings = { telemetry: { enabled: true } };
|
|
1984
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1985
|
+
const settings = createTestMergedSettings({ telemetry: { enabled: true } });
|
|
1909
1986
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1910
1987
|
expect(config.getTelemetryEnabled()).toBe(true);
|
|
1911
1988
|
});
|
|
1912
1989
|
it('should use settings value when GEMINI_TELEMETRY_TARGET is not set', async () => {
|
|
1913
1990
|
vi.stubEnv('GEMINI_TELEMETRY_TARGET', undefined);
|
|
1914
1991
|
process.argv = ['node', 'script.js'];
|
|
1915
|
-
const argv = await parseArguments(
|
|
1916
|
-
const settings = {
|
|
1992
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1993
|
+
const settings = createTestMergedSettings({
|
|
1917
1994
|
telemetry: { target: ServerConfig.TelemetryTarget.LOCAL },
|
|
1918
|
-
};
|
|
1995
|
+
});
|
|
1919
1996
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
1920
1997
|
expect(config.getTelemetryTarget()).toBe('local');
|
|
1921
1998
|
});
|
|
1922
1999
|
it("should treat GEMINI_TELEMETRY_ENABLED='1' as true", async () => {
|
|
1923
2000
|
vi.stubEnv('GEMINI_TELEMETRY_ENABLED', '1');
|
|
1924
2001
|
process.argv = ['node', 'script.js'];
|
|
1925
|
-
const argv = await parseArguments(
|
|
1926
|
-
const config = await loadCliConfig(
|
|
2002
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
2003
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1927
2004
|
expect(config.getTelemetryEnabled()).toBe(true);
|
|
1928
2005
|
});
|
|
1929
2006
|
it("should treat GEMINI_TELEMETRY_ENABLED='0' as false", async () => {
|
|
1930
2007
|
vi.stubEnv('GEMINI_TELEMETRY_ENABLED', '0');
|
|
1931
2008
|
process.argv = ['node', 'script.js'];
|
|
1932
|
-
const argv = await parseArguments(
|
|
1933
|
-
const config = await loadCliConfig({ telemetry: { enabled: true } }, 'test-session', argv);
|
|
2009
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
2010
|
+
const config = await loadCliConfig(createTestMergedSettings({ telemetry: { enabled: true } }), 'test-session', argv);
|
|
1934
2011
|
expect(config.getTelemetryEnabled()).toBe(false);
|
|
1935
2012
|
});
|
|
1936
2013
|
it("should treat GEMINI_TELEMETRY_LOG_PROMPTS='1' as true", async () => {
|
|
1937
2014
|
vi.stubEnv('GEMINI_TELEMETRY_LOG_PROMPTS', '1');
|
|
1938
2015
|
process.argv = ['node', 'script.js'];
|
|
1939
|
-
const argv = await parseArguments(
|
|
1940
|
-
const config = await loadCliConfig(
|
|
2016
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
2017
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1941
2018
|
expect(config.getTelemetryLogPromptsEnabled()).toBe(true);
|
|
1942
2019
|
});
|
|
1943
2020
|
it("should treat GEMINI_TELEMETRY_LOG_PROMPTS='false' as false", async () => {
|
|
1944
2021
|
vi.stubEnv('GEMINI_TELEMETRY_LOG_PROMPTS', 'false');
|
|
1945
2022
|
process.argv = ['node', 'script.js'];
|
|
1946
|
-
const argv = await parseArguments(
|
|
1947
|
-
const config = await loadCliConfig({ telemetry: { logPrompts: true } }, 'test-session', argv);
|
|
2023
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
2024
|
+
const config = await loadCliConfig(createTestMergedSettings({ telemetry: { logPrompts: true } }), 'test-session', argv);
|
|
1948
2025
|
expect(config.getTelemetryLogPromptsEnabled()).toBe(false);
|
|
1949
2026
|
});
|
|
1950
2027
|
});
|
|
@@ -1962,8 +2039,8 @@ describe('PolicyEngine nonInteractive wiring', () => {
|
|
|
1962
2039
|
it('should set nonInteractive to true in one-shot mode', async () => {
|
|
1963
2040
|
process.stdin.isTTY = true;
|
|
1964
2041
|
process.argv = ['node', 'script.js', 'echo hello']; // Positional query makes it one-shot
|
|
1965
|
-
const argv = await parseArguments(
|
|
1966
|
-
const config = await loadCliConfig(
|
|
2042
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
2043
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1967
2044
|
expect(config.isInteractive()).toBe(false);
|
|
1968
2045
|
expect(config.getPolicyEngine()
|
|
1969
2046
|
.nonInteractive).toBe(true);
|
|
@@ -1971,8 +2048,8 @@ describe('PolicyEngine nonInteractive wiring', () => {
|
|
|
1971
2048
|
it('should set nonInteractive to false in interactive mode', async () => {
|
|
1972
2049
|
process.stdin.isTTY = true;
|
|
1973
2050
|
process.argv = ['node', 'script.js'];
|
|
1974
|
-
const argv = await parseArguments(
|
|
1975
|
-
const config = await loadCliConfig(
|
|
2051
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
2052
|
+
const config = await loadCliConfig(createTestMergedSettings(), 'test-session', argv);
|
|
1976
2053
|
expect(config.isInteractive()).toBe(true);
|
|
1977
2054
|
expect(config.getPolicyEngine()
|
|
1978
2055
|
.nonInteractive).toBe(false);
|
|
@@ -1991,8 +2068,10 @@ describe('Policy Engine Integration in loadCliConfig', () => {
|
|
|
1991
2068
|
});
|
|
1992
2069
|
it('should pass merged allowed tools from CLI and settings to createPolicyEngineConfig', async () => {
|
|
1993
2070
|
process.argv = ['node', 'script.js', '--allowed-tools', 'cli-tool'];
|
|
1994
|
-
const settings = {
|
|
1995
|
-
|
|
2071
|
+
const settings = createTestMergedSettings({
|
|
2072
|
+
tools: { allowed: ['settings-tool'] },
|
|
2073
|
+
});
|
|
2074
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
1996
2075
|
await loadCliConfig(settings, 'test-session', argv);
|
|
1997
2076
|
expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith(expect.objectContaining({
|
|
1998
2077
|
tools: expect.objectContaining({
|
|
@@ -2003,8 +2082,10 @@ describe('Policy Engine Integration in loadCliConfig', () => {
|
|
|
2003
2082
|
it('should pass merged exclude tools from CLI logic and settings to createPolicyEngineConfig', async () => {
|
|
2004
2083
|
process.stdin.isTTY = false; // Non-interactive to trigger default excludes
|
|
2005
2084
|
process.argv = ['node', 'script.js', '-p', 'test'];
|
|
2006
|
-
const settings = {
|
|
2007
|
-
|
|
2085
|
+
const settings = createTestMergedSettings({
|
|
2086
|
+
tools: { exclude: ['settings-exclude'] },
|
|
2087
|
+
});
|
|
2088
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
2008
2089
|
await loadCliConfig(settings, 'test-session', argv);
|
|
2009
2090
|
// In non-interactive mode, ShellTool, etc. are excluded
|
|
2010
2091
|
expect(ServerConfig.createPolicyEngineConfig).toHaveBeenCalledWith(expect.objectContaining({
|
|
@@ -2031,19 +2112,19 @@ describe('loadCliConfig disableYoloMode', () => {
|
|
|
2031
2112
|
});
|
|
2032
2113
|
it('should allow auto_edit mode even if yolo mode is disabled', async () => {
|
|
2033
2114
|
process.argv = ['node', 'script.js', '--approval-mode=auto_edit'];
|
|
2034
|
-
const argv = await parseArguments(
|
|
2035
|
-
const settings = {
|
|
2115
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
2116
|
+
const settings = createTestMergedSettings({
|
|
2036
2117
|
security: { disableYoloMode: true },
|
|
2037
|
-
};
|
|
2118
|
+
});
|
|
2038
2119
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
2039
2120
|
expect(config.getApprovalMode()).toBe(ApprovalMode.AUTO_EDIT);
|
|
2040
2121
|
});
|
|
2041
2122
|
it('should throw if YOLO mode is attempted when disableYoloMode is true', async () => {
|
|
2042
2123
|
process.argv = ['node', 'script.js', '--yolo'];
|
|
2043
|
-
const argv = await parseArguments(
|
|
2044
|
-
const settings = {
|
|
2124
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
2125
|
+
const settings = createTestMergedSettings({
|
|
2045
2126
|
security: { disableYoloMode: true },
|
|
2046
|
-
};
|
|
2127
|
+
});
|
|
2047
2128
|
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow('Cannot start in YOLO mode since it is disabled by your admin');
|
|
2048
2129
|
});
|
|
2049
2130
|
});
|
|
@@ -2064,32 +2145,32 @@ describe('loadCliConfig secureModeEnabled', () => {
|
|
|
2064
2145
|
});
|
|
2065
2146
|
it('should throw an error if YOLO mode is attempted when secureModeEnabled is true', async () => {
|
|
2066
2147
|
process.argv = ['node', 'script.js', '--yolo'];
|
|
2067
|
-
const argv = await parseArguments(
|
|
2068
|
-
const settings = {
|
|
2148
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
2149
|
+
const settings = createTestMergedSettings({
|
|
2069
2150
|
admin: {
|
|
2070
2151
|
secureModeEnabled: true,
|
|
2071
2152
|
},
|
|
2072
|
-
};
|
|
2153
|
+
});
|
|
2073
2154
|
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow('Cannot start in YOLO mode since it is disabled by your admin');
|
|
2074
2155
|
});
|
|
2075
2156
|
it('should throw an error if approval-mode=yolo is attempted when secureModeEnabled is true', async () => {
|
|
2076
2157
|
process.argv = ['node', 'script.js', '--approval-mode=yolo'];
|
|
2077
|
-
const argv = await parseArguments(
|
|
2078
|
-
const settings = {
|
|
2158
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
2159
|
+
const settings = createTestMergedSettings({
|
|
2079
2160
|
admin: {
|
|
2080
2161
|
secureModeEnabled: true,
|
|
2081
2162
|
},
|
|
2082
|
-
};
|
|
2163
|
+
});
|
|
2083
2164
|
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow('Cannot start in YOLO mode since it is disabled by your admin');
|
|
2084
2165
|
});
|
|
2085
2166
|
it('should set disableYoloMode to true when secureModeEnabled is true', async () => {
|
|
2086
2167
|
process.argv = ['node', 'script.js'];
|
|
2087
|
-
const argv = await parseArguments(
|
|
2088
|
-
const settings = {
|
|
2168
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
2169
|
+
const settings = createTestMergedSettings({
|
|
2089
2170
|
admin: {
|
|
2090
2171
|
secureModeEnabled: true,
|
|
2091
2172
|
},
|
|
2092
|
-
};
|
|
2173
|
+
});
|
|
2093
2174
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
2094
2175
|
expect(config.isYoloModeDisabled()).toBe(true);
|
|
2095
2176
|
});
|
|
@@ -2115,8 +2196,8 @@ describe('loadCliConfig mcpEnabled', () => {
|
|
|
2115
2196
|
};
|
|
2116
2197
|
it('should enable MCP by default', async () => {
|
|
2117
2198
|
process.argv = ['node', 'script.js'];
|
|
2118
|
-
const argv = await parseArguments(
|
|
2119
|
-
const settings = { ...mcpSettings };
|
|
2199
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
2200
|
+
const settings = createTestMergedSettings({ ...mcpSettings });
|
|
2120
2201
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
2121
2202
|
expect(config.getMcpEnabled()).toBe(true);
|
|
2122
2203
|
expect(config.getMcpServerCommand()).toBe('mcp-server');
|
|
@@ -2126,15 +2207,15 @@ describe('loadCliConfig mcpEnabled', () => {
|
|
|
2126
2207
|
});
|
|
2127
2208
|
it('should disable MCP when mcpEnabled is false', async () => {
|
|
2128
2209
|
process.argv = ['node', 'script.js'];
|
|
2129
|
-
const argv = await parseArguments(
|
|
2130
|
-
const settings = {
|
|
2210
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
2211
|
+
const settings = createTestMergedSettings({
|
|
2131
2212
|
...mcpSettings,
|
|
2132
2213
|
admin: {
|
|
2133
2214
|
mcp: {
|
|
2134
2215
|
enabled: false,
|
|
2135
2216
|
},
|
|
2136
2217
|
},
|
|
2137
|
-
};
|
|
2218
|
+
});
|
|
2138
2219
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
2139
2220
|
expect(config.getMcpEnabled()).toBe(false);
|
|
2140
2221
|
expect(config.getMcpServerCommand()).toBeUndefined();
|
|
@@ -2144,15 +2225,15 @@ describe('loadCliConfig mcpEnabled', () => {
|
|
|
2144
2225
|
});
|
|
2145
2226
|
it('should enable MCP when mcpEnabled is true', async () => {
|
|
2146
2227
|
process.argv = ['node', 'script.js'];
|
|
2147
|
-
const argv = await parseArguments(
|
|
2148
|
-
const settings = {
|
|
2228
|
+
const argv = await parseArguments(createTestMergedSettings());
|
|
2229
|
+
const settings = createTestMergedSettings({
|
|
2149
2230
|
...mcpSettings,
|
|
2150
2231
|
admin: {
|
|
2151
2232
|
mcp: {
|
|
2152
2233
|
enabled: true,
|
|
2153
2234
|
},
|
|
2154
2235
|
},
|
|
2155
|
-
};
|
|
2236
|
+
});
|
|
2156
2237
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
|
2157
2238
|
expect(config.getMcpEnabled()).toBe(true);
|
|
2158
2239
|
expect(config.getMcpServerCommand()).toBe('mcp-server');
|