@machina.ai/cell-cli 1.11.0-rc1 → 1.13.0-rc1
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/package.json +12 -10
- package/dist/src/commands/extensions/disable.d.ts +1 -1
- package/dist/src/commands/extensions/disable.js +15 -7
- package/dist/src/commands/extensions/disable.js.map +1 -1
- package/dist/src/commands/extensions/enable.d.ts +1 -1
- package/dist/src/commands/extensions/enable.js +15 -7
- package/dist/src/commands/extensions/enable.js.map +1 -1
- package/dist/src/commands/extensions/install.js +14 -3
- package/dist/src/commands/extensions/install.js.map +1 -1
- package/dist/src/commands/extensions/install.test.js +39 -19
- package/dist/src/commands/extensions/install.test.js.map +1 -1
- package/dist/src/commands/extensions/link.js +14 -3
- package/dist/src/commands/extensions/link.js.map +1 -1
- package/dist/src/commands/extensions/list.js +13 -4
- package/dist/src/commands/extensions/list.js.map +1 -1
- package/dist/src/commands/extensions/uninstall.js +13 -2
- package/dist/src/commands/extensions/uninstall.js.map +1 -1
- package/dist/src/commands/extensions/update.js +18 -13
- package/dist/src/commands/extensions/update.js.map +1 -1
- package/dist/src/commands/extensions/validate.d.ts +12 -0
- package/dist/src/commands/extensions/validate.js +83 -0
- package/dist/src/commands/extensions/validate.js.map +1 -0
- package/dist/src/commands/extensions/validate.test.js +93 -0
- package/dist/src/commands/extensions/validate.test.js.map +1 -0
- package/dist/src/commands/extensions.js +3 -0
- package/dist/src/commands/extensions.js.map +1 -1
- package/dist/src/commands/mcp/add.test.js +3 -0
- package/dist/src/commands/mcp/add.test.js.map +1 -1
- package/dist/src/commands/mcp/list.js +10 -3
- package/dist/src/commands/mcp/list.js.map +1 -1
- package/dist/src/commands/mcp/list.test.js +37 -27
- package/dist/src/commands/mcp/list.test.js.map +1 -1
- package/dist/src/config/auth.js +0 -5
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/config.d.ts +6 -3
- package/dist/src/config/config.js +65 -80
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +235 -212
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/extension-manager.d.ts +63 -0
- package/dist/src/config/extension-manager.js +450 -0
- package/dist/src/config/extension-manager.js.map +1 -0
- package/dist/src/config/extension.d.ts +4 -51
- package/dist/src/config/extension.js +1 -535
- package/dist/src/config/extension.js.map +1 -1
- package/dist/src/config/extension.test.js +525 -201
- package/dist/src/config/extension.test.js.map +1 -1
- package/dist/src/config/extensions/consent.d.ts +38 -0
- package/dist/src/config/extensions/consent.js +123 -0
- package/dist/src/config/extensions/consent.js.map +1 -0
- package/dist/src/config/extensions/extensionEnablement.d.ts +1 -1
- package/dist/src/config/extensions/extensionEnablement.js +4 -3
- package/dist/src/config/extensions/extensionEnablement.js.map +1 -1
- package/dist/src/config/extensions/extensionEnablement.test.js +10 -10
- package/dist/src/config/extensions/extensionEnablement.test.js.map +1 -1
- package/dist/src/config/extensions/extensionSettings.d.ts +15 -0
- package/dist/src/config/extensions/extensionSettings.js +113 -0
- package/dist/src/config/extensions/extensionSettings.js.map +1 -0
- package/dist/src/config/extensions/extensionSettings.test.d.ts +6 -0
- package/dist/src/config/extensions/extensionSettings.test.js +254 -0
- package/dist/src/config/extensions/extensionSettings.test.js.map +1 -0
- package/dist/src/config/extensions/github.d.ts +2 -2
- package/dist/src/config/extensions/github.js +5 -10
- package/dist/src/config/extensions/github.js.map +1 -1
- package/dist/src/config/extensions/github.test.js +153 -167
- package/dist/src/config/extensions/github.test.js.map +1 -1
- package/dist/src/config/extensions/github_fetch.d.ts +1 -1
- package/dist/src/config/extensions/github_fetch.js +13 -1
- package/dist/src/config/extensions/github_fetch.js.map +1 -1
- package/dist/src/config/extensions/github_fetch.test.d.ts +6 -0
- package/dist/src/config/extensions/github_fetch.test.js +169 -0
- package/dist/src/config/extensions/github_fetch.test.js.map +1 -0
- package/dist/src/config/extensions/storage.d.ts +14 -0
- package/dist/src/config/extensions/storage.js +32 -0
- package/dist/src/config/extensions/storage.js.map +1 -0
- package/dist/src/config/extensions/update.d.ts +4 -4
- package/dist/src/config/extensions/update.js +39 -39
- package/dist/src/config/extensions/update.js.map +1 -1
- package/dist/src/config/extensions/update.test.js +72 -74
- package/dist/src/config/extensions/update.test.js.map +1 -1
- package/dist/src/config/extensions/variableSchema.d.ts +0 -6
- package/dist/src/config/extensions/variableSchema.js.map +1 -1
- package/dist/src/config/extensions/variables.d.ts +4 -0
- package/dist/src/config/extensions/variables.js +6 -0
- package/dist/src/config/extensions/variables.js.map +1 -1
- package/dist/src/config/keyBindings.d.ts +3 -0
- package/dist/src/config/keyBindings.js +30 -8
- package/dist/src/config/keyBindings.js.map +1 -1
- package/dist/src/config/keyBindings.test.js +17 -0
- package/dist/src/config/keyBindings.test.js.map +1 -1
- package/dist/src/config/policies/read-only.toml +56 -0
- package/dist/src/config/policies/write.toml +63 -0
- package/dist/src/config/policies/yolo.toml +31 -0
- package/dist/src/config/policy-engine.integration.test.js +41 -38
- package/dist/src/config/policy-engine.integration.test.js.map +1 -1
- package/dist/src/config/policy.d.ts +2 -2
- package/dist/src/config/policy.js +10 -148
- package/dist/src/config/policy.js.map +1 -1
- package/dist/src/config/sandboxConfig.d.ts +1 -1
- package/dist/src/config/sandboxConfig.js +6 -3
- package/dist/src/config/sandboxConfig.js.map +1 -1
- package/dist/src/config/settings.d.ts +2 -1
- package/dist/src/config/settings.js +58 -18
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/config/settings.test.js +128 -69
- package/dist/src/config/settings.test.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +170 -28
- package/dist/src/config/settingsSchema.js +418 -27
- package/dist/src/config/settingsSchema.js.map +1 -1
- package/dist/src/config/settingsSchema.test.js +42 -1
- package/dist/src/config/settingsSchema.test.js.map +1 -1
- package/dist/src/config/trustedFolders.d.ts +1 -1
- package/dist/src/config/trustedFolders.js +4 -2
- package/dist/src/config/trustedFolders.js.map +1 -1
- package/dist/src/core/initializer.js +2 -1
- package/dist/src/core/initializer.js.map +1 -1
- package/dist/src/gemini.d.ts +1 -1
- package/dist/src/gemini.js +46 -16
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.js +88 -30
- 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/nonInteractiveCli.d.ts +9 -1
- package/dist/src/nonInteractiveCli.js +114 -7
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/nonInteractiveCli.test.js +355 -112
- package/dist/src/nonInteractiveCli.test.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.js +4 -0
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.test.js +22 -0
- package/dist/src/services/BuiltinCommandLoader.test.js.map +1 -1
- package/dist/src/services/FeedbackService.js +2 -2
- package/dist/src/services/FeedbackService.js.map +1 -1
- package/dist/src/services/McpPromptLoader.js +2 -2
- package/dist/src/services/McpPromptLoader.js.map +1 -1
- package/dist/src/services/McpPromptLoader.test.js +4 -2
- package/dist/src/services/McpPromptLoader.test.js.map +1 -1
- package/dist/src/test-utils/async.d.ts +9 -0
- package/dist/src/test-utils/async.js +29 -0
- package/dist/src/test-utils/async.js.map +1 -0
- package/dist/src/test-utils/createExtension.d.ts +3 -1
- package/dist/src/test-utils/createExtension.js +3 -3
- package/dist/src/test-utils/createExtension.js.map +1 -1
- package/dist/src/test-utils/render.d.ts +16 -2
- package/dist/src/test-utils/render.js +66 -4
- package/dist/src/test-utils/render.js.map +1 -1
- package/dist/src/test-utils/render.test.d.ts +6 -0
- package/dist/src/test-utils/render.test.js +79 -0
- package/dist/src/test-utils/render.test.js.map +1 -0
- package/dist/src/ui/App.test.js +1 -1
- package/dist/src/ui/App.test.js.map +1 -1
- package/dist/src/ui/AppContainer.js +181 -65
- package/dist/src/ui/AppContainer.js.map +1 -1
- package/dist/src/ui/AppContainer.test.js +505 -147
- package/dist/src/ui/AppContainer.test.js.map +1 -1
- package/dist/src/ui/IdeIntegrationNudge.js +1 -1
- package/dist/src/ui/IdeIntegrationNudge.js.map +1 -1
- package/dist/src/ui/auth/ApiAuthDialog.d.ts +14 -0
- package/dist/src/ui/auth/ApiAuthDialog.js +26 -0
- package/dist/src/ui/auth/ApiAuthDialog.js.map +1 -0
- package/dist/src/ui/auth/ApiAuthDialog.test.d.ts +6 -0
- package/dist/src/ui/auth/ApiAuthDialog.test.js +91 -0
- package/dist/src/ui/auth/ApiAuthDialog.test.js.map +1 -0
- package/dist/src/ui/auth/AuthDialog.js +7 -3
- package/dist/src/ui/auth/AuthDialog.js.map +1 -1
- package/dist/src/ui/auth/useAuth.d.ts +2 -0
- package/dist/src/ui/auth/useAuth.js +31 -2
- package/dist/src/ui/auth/useAuth.js.map +1 -1
- package/dist/src/ui/colors.js +3 -0
- package/dist/src/ui/colors.js.map +1 -1
- package/dist/src/ui/commands/directoryCommand.js +1 -1
- package/dist/src/ui/commands/directoryCommand.js.map +1 -1
- package/dist/src/ui/commands/extensionsCommand.js +64 -11
- package/dist/src/ui/commands/extensionsCommand.js.map +1 -1
- package/dist/src/ui/commands/extensionsCommand.test.js +72 -1
- package/dist/src/ui/commands/extensionsCommand.test.js.map +1 -1
- package/dist/src/ui/commands/mcpCommand.js +14 -14
- package/dist/src/ui/commands/mcpCommand.js.map +1 -1
- package/dist/src/ui/commands/mcpCommand.test.js +4 -0
- package/dist/src/ui/commands/mcpCommand.test.js.map +1 -1
- package/dist/src/ui/commands/memoryCommand.js +1 -1
- package/dist/src/ui/commands/memoryCommand.js.map +1 -1
- package/dist/src/ui/commands/memoryCommand.test.js +3 -1
- package/dist/src/ui/commands/memoryCommand.test.js.map +1 -1
- package/dist/src/ui/commands/policiesCommand.d.ts +7 -0
- package/dist/src/ui/commands/policiesCommand.js +59 -0
- package/dist/src/ui/commands/policiesCommand.js.map +1 -0
- package/dist/src/ui/commands/policiesCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/policiesCommand.test.js +83 -0
- package/dist/src/ui/commands/policiesCommand.test.js.map +1 -0
- package/dist/src/ui/components/AnsiOutput.test.js +1 -1
- package/dist/src/ui/components/AnsiOutput.test.js.map +1 -1
- package/dist/src/ui/components/AsciiArt.d.ts +3 -3
- package/dist/src/ui/components/AsciiArt.js +3 -3
- package/dist/src/ui/components/Composer.js +1 -1
- package/dist/src/ui/components/Composer.js.map +1 -1
- package/dist/src/ui/components/Composer.test.js +5 -2
- package/dist/src/ui/components/Composer.test.js.map +1 -1
- package/dist/src/ui/components/ConfigInitDisplay.js +4 -6
- package/dist/src/ui/components/ConfigInitDisplay.js.map +1 -1
- package/dist/src/ui/components/ConsentPrompt.test.js +18 -8
- package/dist/src/ui/components/ConsentPrompt.test.js.map +1 -1
- package/dist/src/ui/components/ConsoleSummaryDisplay.js +1 -1
- package/dist/src/ui/components/ConsoleSummaryDisplay.js.map +1 -1
- package/dist/src/ui/components/ContextSummaryDisplay.test.js +11 -6
- package/dist/src/ui/components/ContextSummaryDisplay.test.js.map +1 -1
- package/dist/src/ui/components/DetailedMessagesDisplay.js +1 -1
- package/dist/src/ui/components/DetailedMessagesDisplay.js.map +1 -1
- package/dist/src/ui/components/DialogManager.js +4 -0
- package/dist/src/ui/components/DialogManager.js.map +1 -1
- package/dist/src/ui/components/FolderTrustDialog.test.js +2 -1
- package/dist/src/ui/components/FolderTrustDialog.test.js.map +1 -1
- package/dist/src/ui/components/Footer.js +4 -3
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/Footer.test.js +83 -0
- package/dist/src/ui/components/Footer.test.js.map +1 -1
- package/dist/src/ui/components/Header.test.js +13 -5
- package/dist/src/ui/components/Header.test.js.map +1 -1
- package/dist/src/ui/components/Help.test.js +5 -4
- package/dist/src/ui/components/Help.test.js.map +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.js +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.js +27 -8
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.test.js +776 -727
- package/dist/src/ui/components/InputPrompt.test.js.map +1 -1
- package/dist/src/ui/components/LoadingIndicator.js +2 -2
- package/dist/src/ui/components/LoadingIndicator.js.map +1 -1
- package/dist/src/ui/components/LoadingIndicator.test.js +28 -15
- package/dist/src/ui/components/LoadingIndicator.test.js.map +1 -1
- package/dist/src/ui/components/LoopDetectionConfirmation.js +1 -1
- package/dist/src/ui/components/LoopDetectionConfirmation.js.map +1 -1
- package/dist/src/ui/components/LoopDetectionConfirmation.test.js +2 -2
- package/dist/src/ui/components/LoopDetectionConfirmation.test.js.map +1 -1
- package/dist/src/ui/components/MainContent.js +15 -4
- package/dist/src/ui/components/MainContent.js.map +1 -1
- package/dist/src/ui/components/ModelDialog.js +1 -1
- package/dist/src/ui/components/ModelDialog.js.map +1 -1
- package/dist/src/ui/components/ModelDialog.test.js +23 -13
- package/dist/src/ui/components/ModelDialog.test.js.map +1 -1
- package/dist/src/ui/components/ModelStatsDisplay.test.js +1 -1
- package/dist/src/ui/components/ModelStatsDisplay.test.js.map +1 -1
- package/dist/src/ui/components/Notifications.js +38 -5
- package/dist/src/ui/components/Notifications.js.map +1 -1
- package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js +2 -2
- package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js.map +1 -1
- package/dist/src/ui/components/PrepareLabel.test.js +14 -8
- package/dist/src/ui/components/PrepareLabel.test.js.map +1 -1
- package/dist/src/ui/components/ProQuotaDialog.test.js +14 -6
- package/dist/src/ui/components/ProQuotaDialog.test.js.map +1 -1
- package/dist/src/ui/components/QueuedMessageDisplay.test.js +11 -6
- package/dist/src/ui/components/QueuedMessageDisplay.test.js.map +1 -1
- package/dist/src/ui/components/SessionSummaryDisplay.test.js +1 -1
- package/dist/src/ui/components/SessionSummaryDisplay.test.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.js +32 -25
- package/dist/src/ui/components/SettingsDialog.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.test.js +428 -532
- package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
- package/dist/src/ui/components/ShellConfirmationDialog.js +1 -1
- package/dist/src/ui/components/ShellConfirmationDialog.js.map +1 -1
- package/dist/src/ui/components/ShellConfirmationDialog.test.js +2 -2
- package/dist/src/ui/components/ShellConfirmationDialog.test.js.map +1 -1
- package/dist/src/ui/components/StatsDisplay.test.js +1 -1
- package/dist/src/ui/components/StatsDisplay.test.js.map +1 -1
- package/dist/src/ui/components/SuggestionsDisplay.js +1 -1
- package/dist/src/ui/components/SuggestionsDisplay.js.map +1 -1
- package/dist/src/ui/components/ThemeDialog.test.js +2 -2
- package/dist/src/ui/components/ThemeDialog.test.js.map +1 -1
- package/dist/src/ui/components/ToolStatsDisplay.test.js +1 -1
- package/dist/src/ui/components/ToolStatsDisplay.test.js.map +1 -1
- package/dist/src/ui/components/messages/CompressionMessage.test.js +25 -17
- package/dist/src/ui/components/messages/CompressionMessage.test.js.map +1 -1
- package/dist/src/ui/components/messages/DiffRenderer.test.js +1 -1
- package/dist/src/ui/components/messages/DiffRenderer.test.js.map +1 -1
- package/dist/src/ui/components/messages/InfoMessage.js +1 -1
- package/dist/src/ui/components/messages/InfoMessage.js.map +1 -1
- package/dist/src/ui/components/messages/Todo.js +27 -5
- package/dist/src/ui/components/messages/Todo.js.map +1 -1
- package/dist/src/ui/components/messages/Todo.test.js +20 -8
- package/dist/src/ui/components/messages/Todo.test.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js +29 -15
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js.map +1 -1
- package/dist/src/ui/components/messages/WarningMessage.js +2 -2
- package/dist/src/ui/components/messages/WarningMessage.js.map +1 -1
- package/dist/src/ui/components/shared/BaseSelectionList.test.js +1 -1
- package/dist/src/ui/components/shared/BaseSelectionList.test.js.map +1 -1
- package/dist/src/ui/components/shared/MaxSizedBox.test.js +43 -22
- package/dist/src/ui/components/shared/MaxSizedBox.test.js.map +1 -1
- package/dist/src/ui/components/shared/TextInput.d.ts +15 -0
- package/dist/src/ui/components/shared/TextInput.js +38 -0
- package/dist/src/ui/components/shared/TextInput.js.map +1 -0
- package/dist/src/ui/components/shared/TextInput.test.d.ts +6 -0
- package/dist/src/ui/components/shared/TextInput.test.js +242 -0
- package/dist/src/ui/components/shared/TextInput.test.js.map +1 -0
- package/dist/src/ui/components/shared/text-buffer.d.ts +9 -2
- package/dist/src/ui/components/shared/text-buffer.js +51 -13
- package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
- package/dist/src/ui/components/shared/text-buffer.test.js +385 -202
- package/dist/src/ui/components/shared/text-buffer.test.js.map +1 -1
- package/dist/src/ui/components/views/ChatList.test.js +7 -4
- package/dist/src/ui/components/views/ChatList.test.js.map +1 -1
- package/dist/src/ui/components/views/ExtensionsList.d.ts +7 -1
- package/dist/src/ui/components/views/ExtensionsList.js +9 -11
- package/dist/src/ui/components/views/ExtensionsList.js.map +1 -1
- package/dist/src/ui/components/views/ExtensionsList.test.js +43 -22
- package/dist/src/ui/components/views/ExtensionsList.test.js.map +1 -1
- package/dist/src/ui/components/views/McpStatus.test.js +23 -12
- package/dist/src/ui/components/views/McpStatus.test.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.d.ts +3 -2
- package/dist/src/ui/contexts/KeypressContext.js +610 -540
- package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.test.js +438 -718
- package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
- package/dist/src/ui/contexts/MouseContext.d.ts +21 -0
- package/dist/src/ui/contexts/MouseContext.js +89 -0
- package/dist/src/ui/contexts/MouseContext.js.map +1 -0
- package/dist/src/ui/contexts/MouseContext.test.d.ts +6 -0
- package/dist/src/ui/contexts/MouseContext.test.js +164 -0
- package/dist/src/ui/contexts/MouseContext.test.js.map +1 -0
- package/dist/src/ui/contexts/SessionContext.test.js +35 -17
- package/dist/src/ui/contexts/SessionContext.test.js.map +1 -1
- package/dist/src/ui/contexts/UIActionsContext.d.ts +2 -0
- package/dist/src/ui/contexts/UIActionsContext.js.map +1 -1
- package/dist/src/ui/contexts/UIStateContext.d.ts +2 -0
- package/dist/src/ui/contexts/UIStateContext.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.js +31 -9
- package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.test.js +163 -64
- package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/shellCommandProcessor.test.js +64 -35
- package/dist/src/ui/hooks/shellCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.test.js +193 -165
- package/dist/src/ui/hooks/slashCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/useAtCompletion.test.js +16 -5
- package/dist/src/ui/hooks/useAtCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useAutoAcceptIndicator.js +10 -0
- package/dist/src/ui/hooks/useAutoAcceptIndicator.js.map +1 -1
- package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js +32 -1
- package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js.map +1 -1
- package/dist/src/ui/hooks/useCommandCompletion.test.js +66 -64
- package/dist/src/ui/hooks/useCommandCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useConsoleMessages.test.js +26 -9
- package/dist/src/ui/hooks/useConsoleMessages.test.js.map +1 -1
- package/dist/src/ui/hooks/useEditorSettings.test.js +40 -34
- package/dist/src/ui/hooks/useEditorSettings.test.js.map +1 -1
- package/dist/src/ui/hooks/useExtensionUpdates.d.ts +14 -5
- package/dist/src/ui/hooks/useExtensionUpdates.js +18 -13
- package/dist/src/ui/hooks/useExtensionUpdates.js.map +1 -1
- package/dist/src/ui/hooks/useExtensionUpdates.test.js +49 -44
- package/dist/src/ui/hooks/useExtensionUpdates.test.js.map +1 -1
- package/dist/src/ui/hooks/useFlickerDetector.test.js +9 -5
- package/dist/src/ui/hooks/useFlickerDetector.test.js.map +1 -1
- package/dist/src/ui/hooks/useFocus.test.js +25 -9
- package/dist/src/ui/hooks/useFocus.test.js.map +1 -1
- package/dist/src/ui/hooks/useFolderTrust.test.js +46 -22
- package/dist/src/ui/hooks/useFolderTrust.test.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +56 -19
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.test.js +260 -411
- package/dist/src/ui/hooks/useGeminiStream.test.js.map +1 -1
- package/dist/src/ui/hooks/useGitBranchName.js +4 -0
- package/dist/src/ui/hooks/useGitBranchName.js.map +1 -1
- package/dist/src/ui/hooks/useGitBranchName.test.js +46 -34
- package/dist/src/ui/hooks/useGitBranchName.test.js.map +1 -1
- package/dist/src/ui/hooks/useHistoryManager.test.js +2 -1
- package/dist/src/ui/hooks/useHistoryManager.test.js.map +1 -1
- package/dist/src/ui/hooks/useIdeTrustListener.test.js +40 -9
- package/dist/src/ui/hooks/useIdeTrustListener.test.js.map +1 -1
- package/dist/src/ui/hooks/useInputHistory.test.js +2 -1
- package/dist/src/ui/hooks/useInputHistory.test.js.map +1 -1
- package/dist/src/ui/hooks/useInputHistoryStore.test.js +2 -1
- package/dist/src/ui/hooks/useInputHistoryStore.test.js.map +1 -1
- package/dist/src/ui/hooks/useKeypress.test.js +103 -114
- package/dist/src/ui/hooks/useKeypress.test.js.map +1 -1
- package/dist/src/ui/hooks/useLoadingIndicator.test.js +24 -6
- package/dist/src/ui/hooks/useLoadingIndicator.test.js.map +1 -1
- package/dist/src/ui/hooks/useMemoryMonitor.test.js +10 -5
- package/dist/src/ui/hooks/useMemoryMonitor.test.js.map +1 -1
- package/dist/src/ui/hooks/useMessageQueue.test.js +62 -45
- package/dist/src/ui/hooks/useMessageQueue.test.js.map +1 -1
- package/dist/src/ui/hooks/useModelCommand.test.js +21 -11
- package/dist/src/ui/hooks/useModelCommand.test.js.map +1 -1
- package/dist/src/ui/hooks/useMouse.d.ts +17 -0
- package/dist/src/ui/hooks/useMouse.js +27 -0
- package/dist/src/ui/hooks/useMouse.js.map +1 -0
- package/dist/src/ui/hooks/useMouse.test.d.ts +6 -0
- package/dist/src/ui/hooks/useMouse.test.js +57 -0
- package/dist/src/ui/hooks/useMouse.test.js.map +1 -0
- package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js +2 -2
- package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js.map +1 -1
- package/dist/src/ui/hooks/usePhraseCycler.js +1 -1
- package/dist/src/ui/hooks/usePhraseCycler.js.map +1 -1
- package/dist/src/ui/hooks/usePhraseCycler.test.js +109 -106
- package/dist/src/ui/hooks/usePhraseCycler.test.js.map +1 -1
- package/dist/src/ui/hooks/usePrivacySettings.test.js +26 -6
- package/dist/src/ui/hooks/usePrivacySettings.test.js.map +1 -1
- package/dist/src/ui/hooks/usePromptCompletion.js +2 -2
- package/dist/src/ui/hooks/usePromptCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useQuotaAndFallback.js +13 -14
- package/dist/src/ui/hooks/useQuotaAndFallback.js.map +1 -1
- package/dist/src/ui/hooks/useQuotaAndFallback.test.js +55 -48
- package/dist/src/ui/hooks/useQuotaAndFallback.test.js.map +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.d.ts +8 -1
- package/dist/src/ui/hooks/useReactToolScheduler.js +59 -34
- package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.test.d.ts +6 -0
- package/dist/src/ui/hooks/useReactToolScheduler.test.js +65 -0
- package/dist/src/ui/hooks/useReactToolScheduler.test.js.map +1 -0
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.js +2 -2
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useSelectionList.js +5 -4
- package/dist/src/ui/hooks/useSelectionList.js.map +1 -1
- package/dist/src/ui/hooks/useSelectionList.test.js +272 -183
- package/dist/src/ui/hooks/useSelectionList.test.js.map +1 -1
- package/dist/src/ui/hooks/useShellHistory.test.js +52 -20
- package/dist/src/ui/hooks/useShellHistory.test.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.js +18 -7
- package/dist/src/ui/hooks/useSlashCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.test.js +275 -137
- package/dist/src/ui/hooks/useSlashCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useTimer.test.js +43 -14
- package/dist/src/ui/hooks/useTimer.test.js.map +1 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js +226 -242
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
- package/dist/src/ui/hooks/vim.test.js +235 -355
- package/dist/src/ui/hooks/vim.test.js.map +1 -1
- package/dist/src/ui/keyMatchers.test.js +30 -3
- package/dist/src/ui/keyMatchers.test.js.map +1 -1
- package/dist/src/ui/state/extensions.d.ts +1 -0
- package/dist/src/ui/state/extensions.js +1 -0
- package/dist/src/ui/state/extensions.js.map +1 -1
- package/dist/src/ui/themes/ansi-light.js +1 -0
- package/dist/src/ui/themes/ansi-light.js.map +1 -1
- package/dist/src/ui/themes/ansi.js +1 -0
- package/dist/src/ui/themes/ansi.js.map +1 -1
- package/dist/src/ui/themes/atom-one-dark.js +2 -0
- package/dist/src/ui/themes/atom-one-dark.js.map +1 -1
- package/dist/src/ui/themes/ayu-light.js +2 -0
- package/dist/src/ui/themes/ayu-light.js.map +1 -1
- package/dist/src/ui/themes/ayu.js +2 -0
- package/dist/src/ui/themes/ayu.js.map +1 -1
- package/dist/src/ui/themes/color-utils.d.ts +1 -0
- package/dist/src/ui/themes/color-utils.js +6 -0
- package/dist/src/ui/themes/color-utils.js.map +1 -1
- package/dist/src/ui/themes/color-utils.test.js +13 -1
- package/dist/src/ui/themes/color-utils.test.js.map +1 -1
- package/dist/src/ui/themes/dracula.js +2 -0
- package/dist/src/ui/themes/dracula.js.map +1 -1
- package/dist/src/ui/themes/github-dark.js +2 -0
- package/dist/src/ui/themes/github-dark.js.map +1 -1
- package/dist/src/ui/themes/github-light.js +2 -0
- package/dist/src/ui/themes/github-light.js.map +1 -1
- package/dist/src/ui/themes/googlecode.js +2 -0
- package/dist/src/ui/themes/googlecode.js.map +1 -1
- package/dist/src/ui/themes/no-color.js +3 -0
- package/dist/src/ui/themes/no-color.js.map +1 -1
- package/dist/src/ui/themes/semantic-tokens.d.ts +2 -0
- package/dist/src/ui/themes/semantic-tokens.js +6 -0
- package/dist/src/ui/themes/semantic-tokens.js.map +1 -1
- package/dist/src/ui/themes/shades-of-purple.js +2 -0
- package/dist/src/ui/themes/shades-of-purple.js.map +1 -1
- package/dist/src/ui/themes/theme.d.ts +3 -0
- package/dist/src/ui/themes/theme.js +14 -3
- package/dist/src/ui/themes/theme.js.map +1 -1
- package/dist/src/ui/themes/theme.test.js +67 -1
- package/dist/src/ui/themes/theme.test.js.map +1 -1
- package/dist/src/ui/themes/xcode.js +2 -0
- package/dist/src/ui/themes/xcode.js.map +1 -1
- package/dist/src/ui/types.d.ts +3 -1
- package/dist/src/ui/types.js +2 -0
- package/dist/src/ui/types.js.map +1 -1
- package/dist/src/ui/utils/CodeColorizer.js +2 -1
- package/dist/src/ui/utils/CodeColorizer.js.map +1 -1
- package/dist/src/ui/utils/InlineMarkdownRenderer.d.ts +1 -0
- package/dist/src/ui/utils/InlineMarkdownRenderer.js +11 -10
- package/dist/src/ui/utils/InlineMarkdownRenderer.js.map +1 -1
- package/dist/src/ui/utils/MarkdownDisplay.js +11 -9
- package/dist/src/ui/utils/MarkdownDisplay.js.map +1 -1
- package/dist/src/ui/utils/clipboardUtils.js +2 -2
- package/dist/src/ui/utils/clipboardUtils.js.map +1 -1
- package/dist/src/ui/utils/input.d.ts +17 -0
- package/dist/src/ui/utils/input.js +51 -0
- package/dist/src/ui/utils/input.js.map +1 -0
- package/dist/src/ui/utils/input.test.d.ts +6 -0
- package/dist/src/ui/utils/input.test.js +44 -0
- package/dist/src/ui/utils/input.test.js.map +1 -0
- package/dist/src/ui/utils/kittyProtocolDetector.js +13 -4
- package/dist/src/ui/utils/kittyProtocolDetector.js.map +1 -1
- package/dist/src/ui/utils/mouse.d.ts +31 -0
- package/dist/src/ui/utils/mouse.js +164 -0
- package/dist/src/ui/utils/mouse.js.map +1 -0
- package/dist/src/ui/utils/mouse.test.d.ts +6 -0
- package/dist/src/ui/utils/mouse.test.js +131 -0
- package/dist/src/ui/utils/mouse.test.js.map +1 -0
- package/dist/src/ui/utils/textOutput.d.ts +25 -0
- package/dist/src/ui/utils/textOutput.js +49 -0
- package/dist/src/ui/utils/textOutput.js.map +1 -0
- package/dist/src/ui/utils/textOutput.test.d.ts +6 -0
- package/dist/src/ui/utils/textOutput.test.js +79 -0
- package/dist/src/ui/utils/textOutput.test.js.map +1 -0
- package/dist/src/ui/utils/updateCheck.d.ts +7 -1
- package/dist/src/ui/utils/updateCheck.js +33 -29
- package/dist/src/ui/utils/updateCheck.js.map +1 -1
- package/dist/src/ui/utils/updateCheck.test.js +24 -50
- package/dist/src/ui/utils/updateCheck.test.js.map +1 -1
- package/dist/src/utils/commentJson.js +2 -2
- package/dist/src/utils/commentJson.js.map +1 -1
- package/dist/src/utils/commentJson.test.js +7 -6
- package/dist/src/utils/commentJson.test.js.map +1 -1
- package/dist/src/utils/envVarResolver.d.ts +2 -2
- package/dist/src/utils/envVarResolver.js +10 -7
- package/dist/src/utils/envVarResolver.js.map +1 -1
- package/dist/src/utils/events.d.ts +11 -2
- package/dist/src/utils/events.js +1 -0
- package/dist/src/utils/events.js.map +1 -1
- package/dist/src/utils/handleAutoUpdate.js +9 -3
- package/dist/src/utils/handleAutoUpdate.js.map +1 -1
- package/dist/src/utils/sandbox.js +16 -18
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/utils/version.js +6 -2
- package/dist/src/utils/version.js.map +1 -1
- package/dist/src/zed-integration/acp.js +2 -1
- package/dist/src/zed-integration/acp.js.map +1 -1
- package/dist/src/zed-integration/schema.d.ts +4 -4
- package/dist/src/zed-integration/zedIntegration.d.ts +2 -2
- package/dist/src/zed-integration/zedIntegration.js +12 -19
- package/dist/src/zed-integration/zedIntegration.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -14
- package/dist/src/config/policy.test.js +0 -360
- package/dist/src/config/policy.test.js.map +0 -1
- package/dist/src/utils/package.d.ts +0 -12
- package/dist/src/utils/package.js +0 -24
- package/dist/src/utils/package.js.map +0 -1
- /package/dist/src/{config/policy.test.d.ts → commands/extensions/validate.test.d.ts} +0 -0
|
@@ -3,11 +3,17 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import { executeToolCall, ToolErrorType, shutdownTelemetry, GeminiEventType, OutputFormat, uiTelemetryService, FatalInputError, } from '@google/gemini-cli-core';
|
|
6
|
+
import { executeToolCall, ToolErrorType, shutdownTelemetry, GeminiEventType, OutputFormat, uiTelemetryService, FatalInputError, CoreEvent, } from '@google/gemini-cli-core';
|
|
7
7
|
import { runNonInteractive } from './nonInteractiveCli.js';
|
|
8
|
-
import { vi } from 'vitest';
|
|
8
|
+
import { describe, it, expect, beforeEach, afterEach, vi, } from 'vitest';
|
|
9
9
|
// Mock core modules
|
|
10
10
|
vi.mock('./ui/hooks/atCommandProcessor.js');
|
|
11
|
+
const mockCoreEvents = vi.hoisted(() => ({
|
|
12
|
+
on: vi.fn(),
|
|
13
|
+
off: vi.fn(),
|
|
14
|
+
drainFeedbackBacklog: vi.fn(),
|
|
15
|
+
emit: vi.fn(),
|
|
16
|
+
}));
|
|
11
17
|
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
|
12
18
|
const original = await importOriginal();
|
|
13
19
|
class MockChatRecordingService {
|
|
@@ -25,6 +31,7 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
|
|
|
25
31
|
uiTelemetryService: {
|
|
26
32
|
getMetrics: vi.fn(),
|
|
27
33
|
},
|
|
34
|
+
coreEvents: mockCoreEvents,
|
|
28
35
|
};
|
|
29
36
|
});
|
|
30
37
|
const mockGetCommands = vi.hoisted(() => vi.fn());
|
|
@@ -44,7 +51,28 @@ describe('runNonInteractive', () => {
|
|
|
44
51
|
let mockShutdownTelemetry;
|
|
45
52
|
let consoleErrorSpy;
|
|
46
53
|
let processStdoutSpy;
|
|
54
|
+
let processStderrSpy;
|
|
47
55
|
let mockGeminiClient;
|
|
56
|
+
const MOCK_SESSION_METRICS = {
|
|
57
|
+
models: {},
|
|
58
|
+
tools: {
|
|
59
|
+
totalCalls: 0,
|
|
60
|
+
totalSuccess: 0,
|
|
61
|
+
totalFail: 0,
|
|
62
|
+
totalDurationMs: 0,
|
|
63
|
+
totalDecisions: {
|
|
64
|
+
accept: 0,
|
|
65
|
+
reject: 0,
|
|
66
|
+
modify: 0,
|
|
67
|
+
auto_accept: 0,
|
|
68
|
+
},
|
|
69
|
+
byName: {},
|
|
70
|
+
},
|
|
71
|
+
files: {
|
|
72
|
+
totalLinesAdded: 0,
|
|
73
|
+
totalLinesRemoved: 0,
|
|
74
|
+
},
|
|
75
|
+
};
|
|
48
76
|
beforeEach(async () => {
|
|
49
77
|
mockCoreExecuteToolCall = vi.mocked(executeToolCall);
|
|
50
78
|
mockShutdownTelemetry = vi.mocked(shutdownTelemetry);
|
|
@@ -55,6 +83,9 @@ describe('runNonInteractive', () => {
|
|
|
55
83
|
processStdoutSpy = vi
|
|
56
84
|
.spyOn(process.stdout, 'write')
|
|
57
85
|
.mockImplementation(() => true);
|
|
86
|
+
processStderrSpy = vi
|
|
87
|
+
.spyOn(process.stderr, 'write')
|
|
88
|
+
.mockImplementation(() => true);
|
|
58
89
|
vi.spyOn(process, 'exit').mockImplementation((code) => {
|
|
59
90
|
throw new Error(`process.exit(${code}) called`);
|
|
60
91
|
});
|
|
@@ -123,6 +154,7 @@ describe('runNonInteractive', () => {
|
|
|
123
154
|
yield event;
|
|
124
155
|
}
|
|
125
156
|
}
|
|
157
|
+
const getWrittenOutput = () => processStdoutSpy.mock.calls.map((c) => c[0]).join('');
|
|
126
158
|
it('should process input and write text output', async () => {
|
|
127
159
|
const events = [
|
|
128
160
|
{ type: GeminiEventType.Content, value: 'Hello' },
|
|
@@ -133,11 +165,14 @@ describe('runNonInteractive', () => {
|
|
|
133
165
|
},
|
|
134
166
|
];
|
|
135
167
|
mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
|
|
136
|
-
await runNonInteractive(
|
|
168
|
+
await runNonInteractive({
|
|
169
|
+
config: mockConfig,
|
|
170
|
+
settings: mockSettings,
|
|
171
|
+
input: 'Test input',
|
|
172
|
+
prompt_id: 'prompt-id-1',
|
|
173
|
+
});
|
|
137
174
|
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith([{ text: 'Test input' }], expect.any(AbortSignal), 'prompt-id-1');
|
|
138
|
-
expect(
|
|
139
|
-
expect(processStdoutSpy).toHaveBeenCalledWith(' World');
|
|
140
|
-
expect(processStdoutSpy).toHaveBeenCalledWith('\n');
|
|
175
|
+
expect(getWrittenOutput()).toBe('Hello World\n');
|
|
141
176
|
expect(mockShutdownTelemetry).toHaveBeenCalled();
|
|
142
177
|
});
|
|
143
178
|
it('should handle a single tool call and respond', async () => {
|
|
@@ -182,12 +217,78 @@ describe('runNonInteractive', () => {
|
|
|
182
217
|
mockGeminiClient.sendMessageStream
|
|
183
218
|
.mockReturnValueOnce(createStreamFromEvents(firstCallEvents))
|
|
184
219
|
.mockReturnValueOnce(createStreamFromEvents(secondCallEvents));
|
|
185
|
-
await runNonInteractive(
|
|
220
|
+
await runNonInteractive({
|
|
221
|
+
config: mockConfig,
|
|
222
|
+
settings: mockSettings,
|
|
223
|
+
input: 'Use a tool',
|
|
224
|
+
prompt_id: 'prompt-id-2',
|
|
225
|
+
});
|
|
186
226
|
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledTimes(2);
|
|
187
227
|
expect(mockCoreExecuteToolCall).toHaveBeenCalledWith(mockConfig, expect.objectContaining({ name: 'testTool' }), expect.any(AbortSignal));
|
|
188
228
|
expect(mockGeminiClient.sendMessageStream).toHaveBeenNthCalledWith(2, [{ text: 'Tool response' }], expect.any(AbortSignal), 'prompt-id-2');
|
|
189
|
-
expect(
|
|
190
|
-
|
|
229
|
+
expect(getWrittenOutput()).toBe('Final answer\n');
|
|
230
|
+
});
|
|
231
|
+
it('should write a single newline between sequential text outputs from the model', async () => {
|
|
232
|
+
// This test simulates a multi-turn conversation to ensure that a single newline
|
|
233
|
+
// is printed between each block of text output from the model.
|
|
234
|
+
// 1. Define the tool requests that the model will ask the CLI to run.
|
|
235
|
+
const toolCallEvent = {
|
|
236
|
+
type: GeminiEventType.ToolCallRequest,
|
|
237
|
+
value: {
|
|
238
|
+
callId: 'mock-tool',
|
|
239
|
+
name: 'mockTool',
|
|
240
|
+
args: {},
|
|
241
|
+
isClientInitiated: false,
|
|
242
|
+
prompt_id: 'prompt-id-multi',
|
|
243
|
+
},
|
|
244
|
+
};
|
|
245
|
+
// 2. Mock the execution of the tools. We just need them to succeed.
|
|
246
|
+
mockCoreExecuteToolCall.mockResolvedValue({
|
|
247
|
+
status: 'success',
|
|
248
|
+
request: toolCallEvent.value, // This is generic enough for both calls
|
|
249
|
+
tool: {},
|
|
250
|
+
invocation: {},
|
|
251
|
+
response: {
|
|
252
|
+
responseParts: [],
|
|
253
|
+
callId: 'mock-tool',
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
// 3. Define the sequence of events streamed from the mock model.
|
|
257
|
+
// Turn 1: Model outputs text, then requests a tool call.
|
|
258
|
+
const modelTurn1 = [
|
|
259
|
+
{ type: GeminiEventType.Content, value: 'Use mock tool' },
|
|
260
|
+
toolCallEvent,
|
|
261
|
+
];
|
|
262
|
+
// Turn 2: Model outputs more text, then requests another tool call.
|
|
263
|
+
const modelTurn2 = [
|
|
264
|
+
{ type: GeminiEventType.Content, value: 'Use mock tool again' },
|
|
265
|
+
toolCallEvent,
|
|
266
|
+
];
|
|
267
|
+
// Turn 3: Model outputs a final answer.
|
|
268
|
+
const modelTurn3 = [
|
|
269
|
+
{ type: GeminiEventType.Content, value: 'Finished.' },
|
|
270
|
+
{
|
|
271
|
+
type: GeminiEventType.Finished,
|
|
272
|
+
value: { reason: undefined, usageMetadata: { totalTokenCount: 10 } },
|
|
273
|
+
},
|
|
274
|
+
];
|
|
275
|
+
mockGeminiClient.sendMessageStream
|
|
276
|
+
.mockReturnValueOnce(createStreamFromEvents(modelTurn1))
|
|
277
|
+
.mockReturnValueOnce(createStreamFromEvents(modelTurn2))
|
|
278
|
+
.mockReturnValueOnce(createStreamFromEvents(modelTurn3));
|
|
279
|
+
// 4. Run the command.
|
|
280
|
+
await runNonInteractive({
|
|
281
|
+
config: mockConfig,
|
|
282
|
+
settings: mockSettings,
|
|
283
|
+
input: 'Use mock tool multiple times',
|
|
284
|
+
prompt_id: 'prompt-id-multi',
|
|
285
|
+
});
|
|
286
|
+
// 5. Verify the output.
|
|
287
|
+
// The rendered output should contain the text from each turn, separated by a
|
|
288
|
+
// single newline, with a final newline at the end.
|
|
289
|
+
expect(getWrittenOutput()).toMatchSnapshot();
|
|
290
|
+
// Also verify the tools were called as expected.
|
|
291
|
+
expect(mockCoreExecuteToolCall).toHaveBeenCalledTimes(2);
|
|
191
292
|
});
|
|
192
293
|
it('should handle error during tool execution and should send error back to the model', async () => {
|
|
193
294
|
const toolCallEvent = {
|
|
@@ -241,7 +342,12 @@ describe('runNonInteractive', () => {
|
|
|
241
342
|
mockGeminiClient.sendMessageStream
|
|
242
343
|
.mockReturnValueOnce(createStreamFromEvents([toolCallEvent]))
|
|
243
344
|
.mockReturnValueOnce(createStreamFromEvents(finalResponse));
|
|
244
|
-
await runNonInteractive(
|
|
345
|
+
await runNonInteractive({
|
|
346
|
+
config: mockConfig,
|
|
347
|
+
settings: mockSettings,
|
|
348
|
+
input: 'Trigger tool error',
|
|
349
|
+
prompt_id: 'prompt-id-3',
|
|
350
|
+
});
|
|
245
351
|
expect(mockCoreExecuteToolCall).toHaveBeenCalled();
|
|
246
352
|
expect(consoleErrorSpy).toHaveBeenCalledWith('Error executing tool errorTool: Execution failed');
|
|
247
353
|
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledTimes(2);
|
|
@@ -255,14 +361,19 @@ describe('runNonInteractive', () => {
|
|
|
255
361
|
},
|
|
256
362
|
},
|
|
257
363
|
], expect.any(AbortSignal), 'prompt-id-3');
|
|
258
|
-
expect(
|
|
364
|
+
expect(getWrittenOutput()).toBe('Sorry, let me try again.\n');
|
|
259
365
|
});
|
|
260
366
|
it('should exit with error if sendMessageStream throws initially', async () => {
|
|
261
367
|
const apiError = new Error('API connection failed');
|
|
262
368
|
mockGeminiClient.sendMessageStream.mockImplementation(() => {
|
|
263
369
|
throw apiError;
|
|
264
370
|
});
|
|
265
|
-
await expect(runNonInteractive(
|
|
371
|
+
await expect(runNonInteractive({
|
|
372
|
+
config: mockConfig,
|
|
373
|
+
settings: mockSettings,
|
|
374
|
+
input: 'Initial fail',
|
|
375
|
+
prompt_id: 'prompt-id-4',
|
|
376
|
+
})).rejects.toThrow(apiError);
|
|
266
377
|
});
|
|
267
378
|
it('should not exit if a tool is not found, and should send error back to model', async () => {
|
|
268
379
|
const toolCallEvent = {
|
|
@@ -306,15 +417,25 @@ describe('runNonInteractive', () => {
|
|
|
306
417
|
mockGeminiClient.sendMessageStream
|
|
307
418
|
.mockReturnValueOnce(createStreamFromEvents([toolCallEvent]))
|
|
308
419
|
.mockReturnValueOnce(createStreamFromEvents(finalResponse));
|
|
309
|
-
await runNonInteractive(
|
|
420
|
+
await runNonInteractive({
|
|
421
|
+
config: mockConfig,
|
|
422
|
+
settings: mockSettings,
|
|
423
|
+
input: 'Trigger tool not found',
|
|
424
|
+
prompt_id: 'prompt-id-5',
|
|
425
|
+
});
|
|
310
426
|
expect(mockCoreExecuteToolCall).toHaveBeenCalled();
|
|
311
427
|
expect(consoleErrorSpy).toHaveBeenCalledWith('Error executing tool nonexistentTool: Tool "nonexistentTool" not found in registry.');
|
|
312
428
|
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledTimes(2);
|
|
313
|
-
expect(
|
|
429
|
+
expect(getWrittenOutput()).toBe("Sorry, I can't find that tool.\n");
|
|
314
430
|
});
|
|
315
431
|
it('should exit when max session turns are exceeded', async () => {
|
|
316
432
|
vi.mocked(mockConfig.getMaxSessionTurns).mockReturnValue(0);
|
|
317
|
-
await expect(runNonInteractive(
|
|
433
|
+
await expect(runNonInteractive({
|
|
434
|
+
config: mockConfig,
|
|
435
|
+
settings: mockSettings,
|
|
436
|
+
input: 'Trigger loop',
|
|
437
|
+
prompt_id: 'prompt-id-6',
|
|
438
|
+
})).rejects.toThrow('process.exit(53) called');
|
|
318
439
|
});
|
|
319
440
|
it('should preprocess @include commands before sending to the model', async () => {
|
|
320
441
|
// 1. Mock the imported atCommandProcessor
|
|
@@ -343,11 +464,16 @@ describe('runNonInteractive', () => {
|
|
|
343
464
|
];
|
|
344
465
|
mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
|
|
345
466
|
// 4. Run the non-interactive mode with the raw input
|
|
346
|
-
await runNonInteractive(
|
|
467
|
+
await runNonInteractive({
|
|
468
|
+
config: mockConfig,
|
|
469
|
+
settings: mockSettings,
|
|
470
|
+
input: rawInput,
|
|
471
|
+
prompt_id: 'prompt-id-7',
|
|
472
|
+
});
|
|
347
473
|
// 5. Assert that sendMessageStream was called with the PROCESSED parts, not the raw input
|
|
348
474
|
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith(processedParts, expect.any(AbortSignal), 'prompt-id-7');
|
|
349
475
|
// 6. Assert the final output is correct
|
|
350
|
-
expect(
|
|
476
|
+
expect(getWrittenOutput()).toBe('Summary complete.\n');
|
|
351
477
|
});
|
|
352
478
|
it('should process input and write JSON output with stats', async () => {
|
|
353
479
|
const events = [
|
|
@@ -359,30 +485,15 @@ describe('runNonInteractive', () => {
|
|
|
359
485
|
];
|
|
360
486
|
mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
|
|
361
487
|
vi.mocked(mockConfig.getOutputFormat).mockReturnValue(OutputFormat.JSON);
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
totalDecisions: {
|
|
370
|
-
accept: 0,
|
|
371
|
-
reject: 0,
|
|
372
|
-
modify: 0,
|
|
373
|
-
auto_accept: 0,
|
|
374
|
-
},
|
|
375
|
-
byName: {},
|
|
376
|
-
},
|
|
377
|
-
files: {
|
|
378
|
-
totalLinesAdded: 0,
|
|
379
|
-
totalLinesRemoved: 0,
|
|
380
|
-
},
|
|
381
|
-
};
|
|
382
|
-
vi.mocked(uiTelemetryService.getMetrics).mockReturnValue(mockMetrics);
|
|
383
|
-
await runNonInteractive(mockConfig, mockSettings, 'Test input', 'prompt-id-1');
|
|
488
|
+
vi.mocked(uiTelemetryService.getMetrics).mockReturnValue(MOCK_SESSION_METRICS);
|
|
489
|
+
await runNonInteractive({
|
|
490
|
+
config: mockConfig,
|
|
491
|
+
settings: mockSettings,
|
|
492
|
+
input: 'Test input',
|
|
493
|
+
prompt_id: 'prompt-id-1',
|
|
494
|
+
});
|
|
384
495
|
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith([{ text: 'Test input' }], expect.any(AbortSignal), 'prompt-id-1');
|
|
385
|
-
expect(processStdoutSpy).toHaveBeenCalledWith(JSON.stringify({ response: 'Hello World', stats:
|
|
496
|
+
expect(processStdoutSpy).toHaveBeenCalledWith(JSON.stringify({ response: 'Hello World', stats: MOCK_SESSION_METRICS }, null, 2));
|
|
386
497
|
});
|
|
387
498
|
it('should write JSON output with stats for tool-only commands (no text response)', async () => {
|
|
388
499
|
// Test the scenario where a command completes successfully with only tool calls
|
|
@@ -436,45 +547,17 @@ describe('runNonInteractive', () => {
|
|
|
436
547
|
.mockReturnValueOnce(createStreamFromEvents(firstCallEvents))
|
|
437
548
|
.mockReturnValueOnce(createStreamFromEvents(secondCallEvents));
|
|
438
549
|
vi.mocked(mockConfig.getOutputFormat).mockReturnValue(OutputFormat.JSON);
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
totalDecisions: {
|
|
447
|
-
accept: 1,
|
|
448
|
-
reject: 0,
|
|
449
|
-
modify: 0,
|
|
450
|
-
auto_accept: 0,
|
|
451
|
-
},
|
|
452
|
-
byName: {
|
|
453
|
-
testTool: {
|
|
454
|
-
count: 1,
|
|
455
|
-
success: 1,
|
|
456
|
-
fail: 0,
|
|
457
|
-
durationMs: 100,
|
|
458
|
-
decisions: {
|
|
459
|
-
accept: 1,
|
|
460
|
-
reject: 0,
|
|
461
|
-
modify: 0,
|
|
462
|
-
auto_accept: 0,
|
|
463
|
-
},
|
|
464
|
-
},
|
|
465
|
-
},
|
|
466
|
-
},
|
|
467
|
-
files: {
|
|
468
|
-
totalLinesAdded: 0,
|
|
469
|
-
totalLinesRemoved: 0,
|
|
470
|
-
},
|
|
471
|
-
};
|
|
472
|
-
vi.mocked(uiTelemetryService.getMetrics).mockReturnValue(mockMetrics);
|
|
473
|
-
await runNonInteractive(mockConfig, mockSettings, 'Execute tool only', 'prompt-id-tool-only');
|
|
550
|
+
vi.mocked(uiTelemetryService.getMetrics).mockReturnValue(MOCK_SESSION_METRICS);
|
|
551
|
+
await runNonInteractive({
|
|
552
|
+
config: mockConfig,
|
|
553
|
+
settings: mockSettings,
|
|
554
|
+
input: 'Execute tool only',
|
|
555
|
+
prompt_id: 'prompt-id-tool-only',
|
|
556
|
+
});
|
|
474
557
|
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledTimes(2);
|
|
475
558
|
expect(mockCoreExecuteToolCall).toHaveBeenCalledWith(mockConfig, expect.objectContaining({ name: 'testTool' }), expect.any(AbortSignal));
|
|
476
559
|
// This should output JSON with empty response but include stats
|
|
477
|
-
expect(processStdoutSpy).toHaveBeenCalledWith(JSON.stringify({ response: '', stats:
|
|
560
|
+
expect(processStdoutSpy).toHaveBeenCalledWith(JSON.stringify({ response: '', stats: MOCK_SESSION_METRICS }, null, 2));
|
|
478
561
|
});
|
|
479
562
|
it('should write JSON output with stats for empty response commands', async () => {
|
|
480
563
|
// Test the scenario where a command completes but produces no content at all
|
|
@@ -486,31 +569,16 @@ describe('runNonInteractive', () => {
|
|
|
486
569
|
];
|
|
487
570
|
mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
|
|
488
571
|
vi.mocked(mockConfig.getOutputFormat).mockReturnValue(OutputFormat.JSON);
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
totalDecisions: {
|
|
497
|
-
accept: 0,
|
|
498
|
-
reject: 0,
|
|
499
|
-
modify: 0,
|
|
500
|
-
auto_accept: 0,
|
|
501
|
-
},
|
|
502
|
-
byName: {},
|
|
503
|
-
},
|
|
504
|
-
files: {
|
|
505
|
-
totalLinesAdded: 0,
|
|
506
|
-
totalLinesRemoved: 0,
|
|
507
|
-
},
|
|
508
|
-
};
|
|
509
|
-
vi.mocked(uiTelemetryService.getMetrics).mockReturnValue(mockMetrics);
|
|
510
|
-
await runNonInteractive(mockConfig, mockSettings, 'Empty response test', 'prompt-id-empty');
|
|
572
|
+
vi.mocked(uiTelemetryService.getMetrics).mockReturnValue(MOCK_SESSION_METRICS);
|
|
573
|
+
await runNonInteractive({
|
|
574
|
+
config: mockConfig,
|
|
575
|
+
settings: mockSettings,
|
|
576
|
+
input: 'Empty response test',
|
|
577
|
+
prompt_id: 'prompt-id-empty',
|
|
578
|
+
});
|
|
511
579
|
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith([{ text: 'Empty response test' }], expect.any(AbortSignal), 'prompt-id-empty');
|
|
512
580
|
// This should output JSON with empty response but include stats
|
|
513
|
-
expect(processStdoutSpy).toHaveBeenCalledWith(JSON.stringify({ response: '', stats:
|
|
581
|
+
expect(processStdoutSpy).toHaveBeenCalledWith(JSON.stringify({ response: '', stats: MOCK_SESSION_METRICS }, null, 2));
|
|
514
582
|
});
|
|
515
583
|
it('should handle errors in JSON format', async () => {
|
|
516
584
|
vi.mocked(mockConfig.getOutputFormat).mockReturnValue(OutputFormat.JSON);
|
|
@@ -524,7 +592,12 @@ describe('runNonInteractive', () => {
|
|
|
524
592
|
.mockImplementation(() => { });
|
|
525
593
|
let thrownError = null;
|
|
526
594
|
try {
|
|
527
|
-
await runNonInteractive(
|
|
595
|
+
await runNonInteractive({
|
|
596
|
+
config: mockConfig,
|
|
597
|
+
settings: mockSettings,
|
|
598
|
+
input: 'Test input',
|
|
599
|
+
prompt_id: 'prompt-id-error',
|
|
600
|
+
});
|
|
528
601
|
// Should not reach here
|
|
529
602
|
expect.fail('Expected process.exit to be called');
|
|
530
603
|
}
|
|
@@ -553,7 +626,12 @@ describe('runNonInteractive', () => {
|
|
|
553
626
|
.mockImplementation(() => { });
|
|
554
627
|
let thrownError = null;
|
|
555
628
|
try {
|
|
556
|
-
await runNonInteractive(
|
|
629
|
+
await runNonInteractive({
|
|
630
|
+
config: mockConfig,
|
|
631
|
+
settings: mockSettings,
|
|
632
|
+
input: 'Invalid syntax',
|
|
633
|
+
prompt_id: 'prompt-id-fatal',
|
|
634
|
+
});
|
|
557
635
|
// Should not reach here
|
|
558
636
|
expect.fail('Expected process.exit to be called');
|
|
559
637
|
}
|
|
@@ -588,10 +666,15 @@ describe('runNonInteractive', () => {
|
|
|
588
666
|
},
|
|
589
667
|
];
|
|
590
668
|
mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
|
|
591
|
-
await runNonInteractive(
|
|
669
|
+
await runNonInteractive({
|
|
670
|
+
config: mockConfig,
|
|
671
|
+
settings: mockSettings,
|
|
672
|
+
input: '/testcommand',
|
|
673
|
+
prompt_id: 'prompt-id-slash',
|
|
674
|
+
});
|
|
592
675
|
// Ensure the prompt sent to the model is from the command, not the raw input
|
|
593
676
|
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith([{ text: 'Prompt from command' }], expect.any(AbortSignal), 'prompt-id-slash');
|
|
594
|
-
expect(
|
|
677
|
+
expect(getWrittenOutput()).toBe('Response from command\n');
|
|
595
678
|
});
|
|
596
679
|
it('should throw FatalInputError if a command requires confirmation', async () => {
|
|
597
680
|
const mockCommand = {
|
|
@@ -603,7 +686,12 @@ describe('runNonInteractive', () => {
|
|
|
603
686
|
}),
|
|
604
687
|
};
|
|
605
688
|
mockGetCommands.mockReturnValue([mockCommand]);
|
|
606
|
-
await expect(runNonInteractive(
|
|
689
|
+
await expect(runNonInteractive({
|
|
690
|
+
config: mockConfig,
|
|
691
|
+
settings: mockSettings,
|
|
692
|
+
input: '/confirm',
|
|
693
|
+
prompt_id: 'prompt-id-confirm',
|
|
694
|
+
})).rejects.toThrow('Exiting due to a confirmation prompt requested by the command.');
|
|
607
695
|
});
|
|
608
696
|
it('should treat an unknown slash command as a regular prompt', async () => {
|
|
609
697
|
// No commands are mocked, so any slash command is "unknown"
|
|
@@ -616,10 +704,15 @@ describe('runNonInteractive', () => {
|
|
|
616
704
|
},
|
|
617
705
|
];
|
|
618
706
|
mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
|
|
619
|
-
await runNonInteractive(
|
|
707
|
+
await runNonInteractive({
|
|
708
|
+
config: mockConfig,
|
|
709
|
+
settings: mockSettings,
|
|
710
|
+
input: '/unknowncommand',
|
|
711
|
+
prompt_id: 'prompt-id-unknown',
|
|
712
|
+
});
|
|
620
713
|
// Ensure the raw input is sent to the model
|
|
621
714
|
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith([{ text: '/unknowncommand' }], expect.any(AbortSignal), 'prompt-id-unknown');
|
|
622
|
-
expect(
|
|
715
|
+
expect(getWrittenOutput()).toBe('Response to unknown\n');
|
|
623
716
|
});
|
|
624
717
|
it('should throw for unhandled command result types', async () => {
|
|
625
718
|
const mockCommand = {
|
|
@@ -630,7 +723,12 @@ describe('runNonInteractive', () => {
|
|
|
630
723
|
}),
|
|
631
724
|
};
|
|
632
725
|
mockGetCommands.mockReturnValue([mockCommand]);
|
|
633
|
-
await expect(runNonInteractive(
|
|
726
|
+
await expect(runNonInteractive({
|
|
727
|
+
config: mockConfig,
|
|
728
|
+
settings: mockSettings,
|
|
729
|
+
input: '/noaction',
|
|
730
|
+
prompt_id: 'prompt-id-unhandled',
|
|
731
|
+
})).rejects.toThrow('Exiting due to command result that is not supported in non-interactive mode.');
|
|
634
732
|
});
|
|
635
733
|
it('should pass arguments to the slash command action', async () => {
|
|
636
734
|
const mockAction = vi.fn().mockResolvedValue({
|
|
@@ -651,9 +749,14 @@ describe('runNonInteractive', () => {
|
|
|
651
749
|
},
|
|
652
750
|
];
|
|
653
751
|
mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
|
|
654
|
-
await runNonInteractive(
|
|
752
|
+
await runNonInteractive({
|
|
753
|
+
config: mockConfig,
|
|
754
|
+
settings: mockSettings,
|
|
755
|
+
input: '/testargs arg1 arg2',
|
|
756
|
+
prompt_id: 'prompt-id-args',
|
|
757
|
+
});
|
|
655
758
|
expect(mockAction).toHaveBeenCalledWith(expect.any(Object), 'arg1 arg2');
|
|
656
|
-
expect(
|
|
759
|
+
expect(getWrittenOutput()).toBe('Acknowledged\n');
|
|
657
760
|
});
|
|
658
761
|
it('should instantiate CommandService with correct loaders for slash commands', async () => {
|
|
659
762
|
// This test indirectly checks that handleSlashCommand is using the right loaders.
|
|
@@ -668,7 +771,12 @@ describe('runNonInteractive', () => {
|
|
|
668
771
|
},
|
|
669
772
|
];
|
|
670
773
|
mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
|
|
671
|
-
await runNonInteractive(
|
|
774
|
+
await runNonInteractive({
|
|
775
|
+
config: mockConfig,
|
|
776
|
+
settings: mockSettings,
|
|
777
|
+
input: '/mycommand',
|
|
778
|
+
prompt_id: 'prompt-id-loaders',
|
|
779
|
+
});
|
|
672
780
|
// Check that loaders were instantiated with the config
|
|
673
781
|
expect(FileCommandLoader).toHaveBeenCalledTimes(1);
|
|
674
782
|
expect(FileCommandLoader).toHaveBeenCalledWith(mockConfig);
|
|
@@ -733,9 +841,144 @@ describe('runNonInteractive', () => {
|
|
|
733
841
|
mockGeminiClient.sendMessageStream
|
|
734
842
|
.mockReturnValueOnce(createStreamFromEvents(firstCallEvents))
|
|
735
843
|
.mockReturnValueOnce(createStreamFromEvents(secondCallEvents));
|
|
736
|
-
await runNonInteractive(
|
|
844
|
+
await runNonInteractive({
|
|
845
|
+
config: mockConfig,
|
|
846
|
+
settings: mockSettings,
|
|
847
|
+
input: 'List the files',
|
|
848
|
+
prompt_id: 'prompt-id-allowed',
|
|
849
|
+
});
|
|
737
850
|
expect(mockCoreExecuteToolCall).toHaveBeenCalledWith(mockConfig, expect.objectContaining({ name: 'ShellTool' }), expect.any(AbortSignal));
|
|
738
|
-
expect(
|
|
851
|
+
expect(getWrittenOutput()).toBe('file.txt\n');
|
|
852
|
+
});
|
|
853
|
+
describe('CoreEvents Integration', () => {
|
|
854
|
+
it('subscribes to UserFeedback and drains backlog on start', async () => {
|
|
855
|
+
const events = [
|
|
856
|
+
{
|
|
857
|
+
type: GeminiEventType.Finished,
|
|
858
|
+
value: { reason: undefined, usageMetadata: { totalTokenCount: 0 } },
|
|
859
|
+
},
|
|
860
|
+
];
|
|
861
|
+
mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
|
|
862
|
+
await runNonInteractive({
|
|
863
|
+
config: mockConfig,
|
|
864
|
+
settings: mockSettings,
|
|
865
|
+
input: 'test',
|
|
866
|
+
prompt_id: 'prompt-id-events',
|
|
867
|
+
});
|
|
868
|
+
expect(mockCoreEvents.on).toHaveBeenCalledWith(CoreEvent.UserFeedback, expect.any(Function));
|
|
869
|
+
expect(mockCoreEvents.drainFeedbackBacklog).toHaveBeenCalledTimes(1);
|
|
870
|
+
});
|
|
871
|
+
it('unsubscribes from UserFeedback on finish', async () => {
|
|
872
|
+
const events = [
|
|
873
|
+
{
|
|
874
|
+
type: GeminiEventType.Finished,
|
|
875
|
+
value: { reason: undefined, usageMetadata: { totalTokenCount: 0 } },
|
|
876
|
+
},
|
|
877
|
+
];
|
|
878
|
+
mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
|
|
879
|
+
await runNonInteractive({
|
|
880
|
+
config: mockConfig,
|
|
881
|
+
settings: mockSettings,
|
|
882
|
+
input: 'test',
|
|
883
|
+
prompt_id: 'prompt-id-events',
|
|
884
|
+
});
|
|
885
|
+
expect(mockCoreEvents.off).toHaveBeenCalledWith(CoreEvent.UserFeedback, expect.any(Function));
|
|
886
|
+
});
|
|
887
|
+
it('logs to process.stderr when UserFeedback event is received', async () => {
|
|
888
|
+
const events = [
|
|
889
|
+
{
|
|
890
|
+
type: GeminiEventType.Finished,
|
|
891
|
+
value: { reason: undefined, usageMetadata: { totalTokenCount: 0 } },
|
|
892
|
+
},
|
|
893
|
+
];
|
|
894
|
+
mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
|
|
895
|
+
await runNonInteractive({
|
|
896
|
+
config: mockConfig,
|
|
897
|
+
settings: mockSettings,
|
|
898
|
+
input: 'test',
|
|
899
|
+
prompt_id: 'prompt-id-events',
|
|
900
|
+
});
|
|
901
|
+
// Get the registered handler
|
|
902
|
+
const handler = mockCoreEvents.on.mock.calls.find((call) => call[0] === CoreEvent.UserFeedback)?.[1];
|
|
903
|
+
expect(handler).toBeDefined();
|
|
904
|
+
// Simulate an event
|
|
905
|
+
const payload = {
|
|
906
|
+
severity: 'error',
|
|
907
|
+
message: 'Test error message',
|
|
908
|
+
};
|
|
909
|
+
handler(payload);
|
|
910
|
+
expect(processStderrSpy).toHaveBeenCalledWith('[ERROR] Test error message\n');
|
|
911
|
+
});
|
|
912
|
+
it('logs optional error object to process.stderr in debug mode', async () => {
|
|
913
|
+
vi.mocked(mockConfig.getDebugMode).mockReturnValue(true);
|
|
914
|
+
const events = [
|
|
915
|
+
{
|
|
916
|
+
type: GeminiEventType.Finished,
|
|
917
|
+
value: { reason: undefined, usageMetadata: { totalTokenCount: 0 } },
|
|
918
|
+
},
|
|
919
|
+
];
|
|
920
|
+
mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
|
|
921
|
+
await runNonInteractive({
|
|
922
|
+
config: mockConfig,
|
|
923
|
+
settings: mockSettings,
|
|
924
|
+
input: 'test',
|
|
925
|
+
prompt_id: 'prompt-id-events',
|
|
926
|
+
});
|
|
927
|
+
// Get the registered handler
|
|
928
|
+
const handler = mockCoreEvents.on.mock.calls.find((call) => call[0] === CoreEvent.UserFeedback)?.[1];
|
|
929
|
+
expect(handler).toBeDefined();
|
|
930
|
+
// Simulate an event with error object
|
|
931
|
+
const errorObj = new Error('Original error');
|
|
932
|
+
// Mock stack for deterministic testing
|
|
933
|
+
errorObj.stack = 'Error: Original error\n at test';
|
|
934
|
+
const payload = {
|
|
935
|
+
severity: 'warning',
|
|
936
|
+
message: 'Test warning message',
|
|
937
|
+
error: errorObj,
|
|
938
|
+
};
|
|
939
|
+
handler(payload);
|
|
940
|
+
expect(processStderrSpy).toHaveBeenCalledWith('[WARNING] Test warning message\n');
|
|
941
|
+
expect(processStderrSpy).toHaveBeenCalledWith('Error: Original error\n at test\n');
|
|
942
|
+
});
|
|
943
|
+
});
|
|
944
|
+
it('should display a deprecation warning if hasDeprecatedPromptArg is true', async () => {
|
|
945
|
+
const events = [
|
|
946
|
+
{ type: GeminiEventType.Content, value: 'Final Answer' },
|
|
947
|
+
{
|
|
948
|
+
type: GeminiEventType.Finished,
|
|
949
|
+
value: { reason: undefined, usageMetadata: { totalTokenCount: 10 } },
|
|
950
|
+
},
|
|
951
|
+
];
|
|
952
|
+
mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
|
|
953
|
+
await runNonInteractive({
|
|
954
|
+
config: mockConfig,
|
|
955
|
+
settings: mockSettings,
|
|
956
|
+
input: 'Test input',
|
|
957
|
+
prompt_id: 'prompt-id-deprecated',
|
|
958
|
+
hasDeprecatedPromptArg: true,
|
|
959
|
+
});
|
|
960
|
+
expect(processStderrSpy).toHaveBeenCalledWith('The --prompt (-p) flag has been deprecated and will be removed in a future version. Please use a positional argument for your prompt. See gemini --help for more information.\n');
|
|
961
|
+
expect(processStdoutSpy).toHaveBeenCalledWith('Final Answer');
|
|
962
|
+
});
|
|
963
|
+
it('should display a deprecation warning for JSON format', async () => {
|
|
964
|
+
const events = [
|
|
965
|
+
{ type: GeminiEventType.Content, value: 'Final Answer' },
|
|
966
|
+
{
|
|
967
|
+
type: GeminiEventType.Finished,
|
|
968
|
+
value: { reason: undefined, usageMetadata: { totalTokenCount: 10 } },
|
|
969
|
+
},
|
|
970
|
+
];
|
|
971
|
+
mockGeminiClient.sendMessageStream.mockReturnValue(createStreamFromEvents(events));
|
|
972
|
+
vi.mocked(mockConfig.getOutputFormat).mockReturnValue(OutputFormat.JSON);
|
|
973
|
+
await runNonInteractive({
|
|
974
|
+
config: mockConfig,
|
|
975
|
+
settings: mockSettings,
|
|
976
|
+
input: 'Test input',
|
|
977
|
+
prompt_id: 'prompt-id-deprecated-json',
|
|
978
|
+
hasDeprecatedPromptArg: true,
|
|
979
|
+
});
|
|
980
|
+
const deprecateText = 'The --prompt (-p) flag has been deprecated and will be removed in a future version. Please use a positional argument for your prompt. See gemini --help for more information.\n';
|
|
981
|
+
expect(processStderrSpy).toHaveBeenCalledWith(deprecateText);
|
|
739
982
|
});
|
|
740
983
|
});
|
|
741
984
|
//# sourceMappingURL=nonInteractiveCli.test.js.map
|