@vybestack/llxprt-code 0.1.20-nightly.250818.90f427f5 → 0.1.21
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/README.md +31 -0
- package/dist/package.json +3 -3
- package/dist/src/config/auth.test.d.ts +6 -0
- package/dist/src/config/auth.test.js +57 -0
- package/dist/src/config/auth.test.js.map +1 -0
- package/dist/src/config/config.d.ts +1 -1
- package/dist/src/config/config.js +27 -14
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/keyBindings.js +2 -2
- package/dist/src/config/keyBindings.test.d.ts +6 -0
- package/dist/src/config/keyBindings.test.js +51 -0
- package/dist/src/config/keyBindings.test.js.map +1 -0
- package/dist/src/config/logging/loggingConfig.test.d.ts +6 -0
- package/dist/src/config/logging/loggingConfig.test.js +363 -0
- package/dist/src/config/logging/loggingConfig.test.js.map +1 -0
- package/dist/src/config/settingsSchema.d.ts +0 -9
- package/dist/src/config/settingsSchema.js +0 -9
- package/dist/src/config/settingsSchema.js.map +1 -1
- package/dist/src/config/settingsSchema.test.d.ts +6 -0
- package/dist/src/config/settingsSchema.test.js +195 -0
- package/dist/src/config/settingsSchema.test.js.map +1 -0
- package/dist/src/config/trustedFolders.test.d.ts +6 -0
- package/dist/src/config/trustedFolders.test.js +156 -0
- package/dist/src/config/trustedFolders.test.js.map +1 -0
- package/dist/src/gemini.js +14 -4
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.d.ts +6 -0
- package/dist/src/gemini.test.js +199 -0
- package/dist/src/gemini.test.js.map +1 -0
- package/dist/src/generated/git-commit.d.ts +1 -1
- package/dist/src/generated/git-commit.js +1 -1
- package/dist/src/integration-tests/base-url-behavior.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/base-url-behavior.integration.test.js +492 -0
- package/dist/src/integration-tests/base-url-behavior.integration.test.js.map +1 -0
- package/dist/src/integration-tests/cli-args.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/cli-args.integration.test.js +398 -0
- package/dist/src/integration-tests/cli-args.integration.test.js.map +1 -0
- package/dist/src/integration-tests/compression-settings-apply.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/compression-settings-apply.integration.test.js +436 -0
- package/dist/src/integration-tests/compression-settings-apply.integration.test.js.map +1 -0
- package/dist/src/integration-tests/ephemeral-settings.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/ephemeral-settings.integration.test.js +290 -0
- package/dist/src/integration-tests/ephemeral-settings.integration.test.js.map +1 -0
- package/dist/src/integration-tests/model-params-isolation.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/model-params-isolation.integration.test.js +564 -0
- package/dist/src/integration-tests/model-params-isolation.integration.test.js.map +1 -0
- package/dist/src/integration-tests/modelParams.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/modelParams.integration.test.js +784 -0
- package/dist/src/integration-tests/modelParams.integration.test.js.map +1 -0
- package/dist/src/integration-tests/profile-keyfile.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/profile-keyfile.integration.test.js +429 -0
- package/dist/src/integration-tests/profile-keyfile.integration.test.js.map +1 -0
- package/dist/src/integration-tests/profile-system.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/profile-system.integration.test.js +364 -0
- package/dist/src/integration-tests/profile-system.integration.test.js.map +1 -0
- package/dist/src/integration-tests/provider-switching.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/provider-switching.integration.test.js +207 -0
- package/dist/src/integration-tests/provider-switching.integration.test.js.map +1 -0
- package/dist/src/integration-tests/security.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/security.integration.test.js +319 -0
- package/dist/src/integration-tests/security.integration.test.js.map +1 -0
- package/dist/src/integration-tests/test-utils.test.d.ts +6 -0
- package/dist/src/integration-tests/test-utils.test.js +221 -0
- package/dist/src/integration-tests/test-utils.test.js.map +1 -0
- package/dist/src/integration-tests/todo-continuation.integration.test.d.ts +6 -0
- package/dist/src/integration-tests/todo-continuation.integration.test.js +559 -0
- package/dist/src/integration-tests/todo-continuation.integration.test.js.map +1 -0
- package/dist/src/providers/logging/LoggingProviderWrapper.test.d.ts +6 -0
- package/dist/src/providers/logging/LoggingProviderWrapper.test.js +305 -0
- package/dist/src/providers/logging/LoggingProviderWrapper.test.js.map +1 -0
- package/dist/src/providers/logging/git-stats.integration.test.d.ts +6 -0
- package/dist/src/providers/logging/git-stats.integration.test.js +245 -0
- package/dist/src/providers/logging/git-stats.integration.test.js.map +1 -0
- package/dist/src/providers/logging/git-stats.test.d.ts +6 -0
- package/dist/src/providers/logging/git-stats.test.js +432 -0
- package/dist/src/providers/logging/git-stats.test.js.map +1 -0
- package/dist/src/providers/logging/multi-provider-logging.integration.test.d.ts +6 -0
- package/dist/src/providers/logging/multi-provider-logging.integration.test.js +531 -0
- package/dist/src/providers/logging/multi-provider-logging.integration.test.js.map +1 -0
- package/dist/src/providers/logging/performance.test.d.ts +6 -0
- package/dist/src/providers/logging/performance.test.js +465 -0
- package/dist/src/providers/logging/performance.test.js.map +1 -0
- package/dist/src/providers/provider-gemini-switching.test.d.ts +6 -0
- package/dist/src/providers/provider-gemini-switching.test.js +129 -0
- package/dist/src/providers/provider-gemini-switching.test.js.map +1 -0
- package/dist/src/providers/provider-switching.integration.test.d.ts +6 -0
- package/dist/src/providers/provider-switching.integration.test.js +113 -0
- package/dist/src/providers/provider-switching.integration.test.js.map +1 -0
- package/dist/src/providers/providerManagerInstance.test.d.ts +6 -0
- package/dist/src/providers/providerManagerInstance.test.js +104 -0
- package/dist/src/providers/providerManagerInstance.test.js.map +1 -0
- package/dist/src/services/BuiltinCommandLoader.test.d.ts +6 -0
- package/dist/src/services/BuiltinCommandLoader.test.js +118 -0
- package/dist/src/services/BuiltinCommandLoader.test.js.map +1 -0
- package/dist/src/services/CommandService.test.d.ts +6 -0
- package/dist/src/services/CommandService.test.js +232 -0
- package/dist/src/services/CommandService.test.js.map +1 -0
- package/dist/src/storage/ConversationStorage.test.d.ts +6 -0
- package/dist/src/storage/ConversationStorage.test.js +379 -0
- package/dist/src/storage/ConversationStorage.test.js.map +1 -0
- package/dist/src/test-utils/customMatchers.d.ts +14 -0
- package/dist/src/test-utils/customMatchers.js +46 -0
- package/dist/src/test-utils/customMatchers.js.map +1 -0
- package/dist/src/test-utils/mockCommandContext.d.ts +18 -0
- package/dist/src/test-utils/mockCommandContext.js +86 -0
- package/dist/src/test-utils/mockCommandContext.js.map +1 -0
- package/dist/src/test-utils/mockCommandContext.test.d.ts +6 -0
- package/dist/src/test-utils/mockCommandContext.test.js +51 -0
- package/dist/src/test-utils/mockCommandContext.test.js.map +1 -0
- package/dist/src/test-utils/responsive-testing.d.ts +14 -0
- package/dist/src/test-utils/responsive-testing.js +35 -0
- package/dist/src/test-utils/responsive-testing.js.map +1 -0
- package/dist/src/test-utils/responsive-testing.test.d.ts +6 -0
- package/dist/src/test-utils/responsive-testing.test.js +89 -0
- package/dist/src/test-utils/responsive-testing.test.js.map +1 -0
- package/dist/src/test-utils/testProviderConfig.d.ts +18 -0
- package/dist/src/test-utils/testProviderConfig.js +19 -0
- package/dist/src/test-utils/testProviderConfig.js.map +1 -0
- package/dist/src/ui/App.js +1 -1
- package/dist/src/ui/App.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/commands/chatCommand.js +8 -6
- package/dist/src/ui/commands/chatCommand.js.map +1 -1
- package/dist/src/ui/commands/diagnosticsCommand.js +0 -1
- package/dist/src/ui/commands/diagnosticsCommand.js.map +1 -1
- package/dist/src/ui/commands/ideCommand.js +5 -5
- package/dist/src/ui/commands/ideCommand.js.map +1 -1
- package/dist/src/ui/commands/keyCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/keyCommand.test.js +128 -0
- package/dist/src/ui/commands/keyCommand.test.js.map +1 -0
- package/dist/src/ui/commands/profileCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/profileCommand.test.js +343 -0
- package/dist/src/ui/commands/profileCommand.test.js.map +1 -0
- package/dist/src/ui/commands/setCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/setCommand.test.js +431 -0
- package/dist/src/ui/commands/setCommand.test.js.map +1 -0
- package/dist/src/ui/commands/setupGithubCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/setupGithubCommand.test.js +69 -0
- package/dist/src/ui/commands/setupGithubCommand.test.js.map +1 -0
- package/dist/src/ui/commands/toolformatCommand.test.d.ts +1 -0
- package/dist/src/ui/commands/toolformatCommand.test.js +145 -0
- package/dist/src/ui/commands/toolformatCommand.test.js.map +1 -0
- package/dist/src/ui/components/AuthDialog.js +1 -1
- package/dist/src/ui/components/AuthDialog.js.map +1 -1
- package/dist/src/ui/components/AuthDialog.test.d.ts +6 -0
- package/dist/src/ui/components/AuthDialog.test.js +252 -0
- package/dist/src/ui/components/AuthDialog.test.js.map +1 -0
- package/dist/src/ui/components/ContextIndicator.ui.test.d.ts +1 -0
- package/dist/src/ui/components/ContextIndicator.ui.test.js +89 -0
- package/dist/src/ui/components/ContextIndicator.ui.test.js.map +1 -0
- package/dist/src/ui/components/ContextSummaryDisplay.js +1 -1
- package/dist/src/ui/components/ContextUsageDisplay.semantic.test.d.ts +6 -0
- package/dist/src/ui/components/ContextUsageDisplay.semantic.test.js +75 -0
- package/dist/src/ui/components/ContextUsageDisplay.semantic.test.js.map +1 -0
- package/dist/src/ui/components/FolderTrustDialog.test.d.ts +6 -0
- package/dist/src/ui/components/FolderTrustDialog.test.js +26 -0
- package/dist/src/ui/components/FolderTrustDialog.test.js.map +1 -0
- package/dist/src/ui/components/Footer.d.ts +1 -0
- package/dist/src/ui/components/Footer.js +2 -2
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/Footer.responsive.test.d.ts +6 -0
- package/dist/src/ui/components/Footer.responsive.test.js +262 -0
- package/dist/src/ui/components/Footer.responsive.test.js.map +1 -0
- package/dist/src/ui/components/HistoryItemDisplay.test.d.ts +6 -0
- package/dist/src/ui/components/HistoryItemDisplay.test.js +92 -0
- package/dist/src/ui/components/HistoryItemDisplay.test.js.map +1 -0
- package/dist/src/ui/components/InputPrompt.paste.test.d.ts +6 -0
- package/dist/src/ui/components/InputPrompt.paste.test.js +263 -0
- package/dist/src/ui/components/InputPrompt.paste.test.js.map +1 -0
- package/dist/src/ui/components/LoadingIndicator.test.d.ts +6 -0
- package/dist/src/ui/components/LoadingIndicator.test.js +149 -0
- package/dist/src/ui/components/LoadingIndicator.test.js.map +1 -0
- package/dist/src/ui/components/MemoryUsageDisplay.semantic.test.d.ts +6 -0
- package/dist/src/ui/components/MemoryUsageDisplay.semantic.test.js +127 -0
- package/dist/src/ui/components/MemoryUsageDisplay.semantic.test.js.map +1 -0
- package/dist/src/ui/components/ProviderDialog.responsive.test.d.ts +6 -0
- package/dist/src/ui/components/ProviderDialog.responsive.test.js +153 -0
- package/dist/src/ui/components/ProviderDialog.responsive.test.js.map +1 -0
- package/dist/src/ui/components/ProviderModelDialog.responsive.test.d.ts +6 -0
- package/dist/src/ui/components/ProviderModelDialog.responsive.test.js +252 -0
- package/dist/src/ui/components/ProviderModelDialog.responsive.test.js.map +1 -0
- package/dist/src/ui/components/ProviderModelDialog.test.d.ts +6 -0
- package/dist/src/ui/components/ProviderModelDialog.test.js +197 -0
- package/dist/src/ui/components/ProviderModelDialog.test.js.map +1 -0
- package/dist/src/ui/components/SettingsDialog.test.d.ts +6 -0
- package/dist/src/ui/components/SettingsDialog.test.js +555 -0
- package/dist/src/ui/components/SettingsDialog.test.js.map +1 -0
- package/dist/src/ui/components/ShellConfirmationDialog.test.d.ts +6 -0
- package/dist/src/ui/components/ShellConfirmationDialog.test.js +40 -0
- package/dist/src/ui/components/ShellConfirmationDialog.test.js.map +1 -0
- package/dist/src/ui/components/TodoPanel.responsive.test.d.ts +6 -0
- package/dist/src/ui/components/TodoPanel.responsive.test.js +221 -0
- package/dist/src/ui/components/TodoPanel.responsive.test.js.map +1 -0
- package/dist/src/ui/components/TodoPanel.semantic.test.d.ts +6 -0
- package/dist/src/ui/components/TodoPanel.semantic.test.js +137 -0
- package/dist/src/ui/components/TodoPanel.semantic.test.js.map +1 -0
- package/dist/src/ui/components/__tests__/LayoutManager.test.d.ts +6 -0
- package/dist/src/ui/components/__tests__/LayoutManager.test.js +94 -0
- package/dist/src/ui/components/__tests__/LayoutManager.test.js.map +1 -0
- package/dist/src/ui/components/messages/DiffRenderer.js +9 -7
- package/dist/src/ui/components/messages/DiffRenderer.js.map +1 -1
- package/dist/src/ui/components/messages/DiffRenderer.test.d.ts +6 -0
- package/dist/src/ui/components/messages/DiffRenderer.test.js +239 -0
- package/dist/src/ui/components/messages/DiffRenderer.test.js.map +1 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js +13 -4
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.responsive.test.d.ts +6 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.responsive.test.js +172 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.responsive.test.js.map +1 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.d.ts +6 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js +37 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js.map +1 -0
- package/dist/src/ui/components/messages/ToolMessage.test.d.ts +6 -0
- package/dist/src/ui/components/messages/ToolMessage.test.js +118 -0
- package/dist/src/ui/components/messages/ToolMessage.test.js.map +1 -0
- package/dist/src/ui/components/shared/MaxSizedBox.test.d.ts +6 -0
- package/dist/src/ui/components/shared/MaxSizedBox.test.js +154 -0
- package/dist/src/ui/components/shared/MaxSizedBox.test.js.map +1 -0
- package/dist/src/ui/components/shared/RadioButtonSelect.js +1 -1
- package/dist/src/ui/components/shared/RadioButtonSelect.js.map +1 -1
- package/dist/src/ui/components/shared/RadioButtonSelect.test.d.ts +6 -0
- package/dist/src/ui/components/shared/RadioButtonSelect.test.js +112 -0
- package/dist/src/ui/components/shared/RadioButtonSelect.test.js.map +1 -0
- package/dist/src/ui/containers/SessionController.test.d.ts +6 -0
- package/dist/src/ui/containers/SessionController.test.js +440 -0
- package/dist/src/ui/containers/SessionController.test.js.map +1 -0
- package/dist/src/ui/hooks/atCommandProcessor.test.d.ts +6 -0
- package/dist/src/ui/hooks/atCommandProcessor.test.js +830 -0
- package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -0
- package/dist/src/ui/hooks/shellCommandProcessor.test.d.ts +6 -0
- package/dist/src/ui/hooks/shellCommandProcessor.test.js +328 -0
- package/dist/src/ui/hooks/shellCommandProcessor.test.js.map +1 -0
- package/dist/src/ui/hooks/useAutoAcceptIndicator.test.d.ts +6 -0
- package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js +191 -0
- package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js.map +1 -0
- package/dist/src/ui/hooks/useEditorSettings.test.d.ts +6 -0
- package/dist/src/ui/hooks/useEditorSettings.test.js +221 -0
- package/dist/src/ui/hooks/useEditorSettings.test.js.map +1 -0
- package/dist/src/ui/hooks/useGeminiStream.integration.test.d.ts +6 -0
- package/dist/src/ui/hooks/useGeminiStream.integration.test.js +800 -0
- package/dist/src/ui/hooks/useGeminiStream.integration.test.js.map +1 -0
- package/dist/src/ui/hooks/useGeminiStream.js +12 -47
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useGitBranchName.test.d.ts +6 -0
- package/dist/src/ui/hooks/useGitBranchName.test.js +170 -0
- package/dist/src/ui/hooks/useGitBranchName.test.js.map +1 -0
- package/dist/src/ui/hooks/useHistoryManager.test.d.ts +6 -0
- package/dist/src/ui/hooks/useHistoryManager.test.js +171 -0
- package/dist/src/ui/hooks/useHistoryManager.test.js.map +1 -0
- package/dist/src/ui/hooks/useInputHistory.test.d.ts +6 -0
- package/dist/src/ui/hooks/useInputHistory.test.js +207 -0
- package/dist/src/ui/hooks/useInputHistory.test.js.map +1 -0
- package/dist/src/ui/hooks/useKeypress.test.d.ts +6 -0
- package/dist/src/ui/hooks/useKeypress.test.js +171 -0
- package/dist/src/ui/hooks/useKeypress.test.js.map +1 -0
- package/dist/src/ui/hooks/useResponsive.test.d.ts +6 -0
- package/dist/src/ui/hooks/useResponsive.test.js +124 -0
- package/dist/src/ui/hooks/useResponsive.test.js.map +1 -0
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.d.ts +6 -0
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.js +163 -0
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.js.map +1 -0
- package/dist/src/ui/hooks/useShellHistory.test.d.ts +6 -0
- package/dist/src/ui/hooks/useShellHistory.test.js +162 -0
- package/dist/src/ui/hooks/useShellHistory.test.js.map +1 -0
- package/dist/src/ui/hooks/useSlashCompletion.test.d.ts +6 -0
- package/dist/src/ui/hooks/useSlashCompletion.test.js +929 -0
- package/dist/src/ui/hooks/useSlashCompletion.test.js.map +1 -0
- package/dist/src/ui/hooks/useStableCallback.test.d.ts +6 -0
- package/dist/src/ui/hooks/useStableCallback.test.js +57 -0
- package/dist/src/ui/hooks/useStableCallback.test.js.map +1 -0
- package/dist/src/ui/keyMatchers.test.d.ts +6 -0
- package/dist/src/ui/keyMatchers.test.js +276 -0
- package/dist/src/ui/keyMatchers.test.js.map +1 -0
- package/dist/src/ui/reducers/appReducer.test.d.ts +6 -0
- package/dist/src/ui/reducers/appReducer.test.js +519 -0
- package/dist/src/ui/reducers/appReducer.test.js.map +1 -0
- package/dist/src/ui/themes/color-utils.test.d.ts +6 -0
- package/dist/src/ui/themes/color-utils.test.js +197 -0
- package/dist/src/ui/themes/color-utils.test.js.map +1 -0
- package/dist/src/ui/themes/semantic-resolver.test.d.ts +6 -0
- package/dist/src/ui/themes/semantic-resolver.test.js +210 -0
- package/dist/src/ui/themes/semantic-resolver.test.js.map +1 -0
- package/dist/src/ui/themes/semantic-tokens.test.d.ts +6 -0
- package/dist/src/ui/themes/semantic-tokens.test.js +272 -0
- package/dist/src/ui/themes/semantic-tokens.test.js.map +1 -0
- package/dist/src/ui/themes/theme-manager.test.d.ts +6 -0
- package/dist/src/ui/themes/theme-manager.test.js +151 -0
- package/dist/src/ui/themes/theme-manager.test.js.map +1 -0
- package/dist/src/ui/utils/MarkdownDisplay.test.d.ts +6 -0
- package/dist/src/ui/utils/MarkdownDisplay.test.js +151 -0
- package/dist/src/ui/utils/MarkdownDisplay.test.js.map +1 -0
- package/dist/src/ui/utils/clipboardUtils.test.d.ts +6 -0
- package/dist/src/ui/utils/clipboardUtils.test.js +65 -0
- package/dist/src/ui/utils/clipboardUtils.test.js.map +1 -0
- package/dist/src/ui/utils/commandUtils.test.d.ts +6 -0
- package/dist/src/ui/utils/commandUtils.test.js +294 -0
- package/dist/src/ui/utils/commandUtils.test.js.map +1 -0
- package/dist/src/ui/utils/displayUtils.test.d.ts +6 -0
- package/dist/src/ui/utils/displayUtils.test.js +42 -0
- package/dist/src/ui/utils/displayUtils.test.js.map +1 -0
- package/dist/src/ui/utils/formatters.test.d.ts +6 -0
- package/dist/src/ui/utils/formatters.test.js +56 -0
- package/dist/src/ui/utils/formatters.test.js.map +1 -0
- package/dist/src/ui/utils/markdownUtilities.test.d.ts +6 -0
- package/dist/src/ui/utils/markdownUtilities.test.js +42 -0
- package/dist/src/ui/utils/markdownUtilities.test.js.map +1 -0
- package/dist/src/ui/utils/responsive.test.d.ts +6 -0
- package/dist/src/ui/utils/responsive.test.js +107 -0
- package/dist/src/ui/utils/responsive.test.js.map +1 -0
- package/dist/src/ui/utils/secureInputHandler.test.d.ts +6 -0
- package/dist/src/ui/utils/secureInputHandler.test.js +274 -0
- package/dist/src/ui/utils/secureInputHandler.test.js.map +1 -0
- package/dist/src/ui/utils/updateCheck.test.d.ts +6 -0
- package/dist/src/ui/utils/updateCheck.test.js +202 -0
- package/dist/src/ui/utils/updateCheck.test.js.map +1 -0
- package/dist/src/utils/ConversationContext.test.d.ts +6 -0
- package/dist/src/utils/ConversationContext.test.js +64 -0
- package/dist/src/utils/ConversationContext.test.js.map +1 -0
- package/dist/src/utils/gitUtils.test.d.ts +6 -0
- package/dist/src/utils/gitUtils.test.js +113 -0
- package/dist/src/utils/gitUtils.test.js.map +1 -0
- package/dist/src/utils/installationInfo.test.d.ts +6 -0
- package/dist/src/utils/installationInfo.test.js +242 -0
- package/dist/src/utils/installationInfo.test.js.map +1 -0
- package/dist/src/utils/privacy/ConversationDataRedactor.test.d.ts +6 -0
- package/dist/src/utils/privacy/ConversationDataRedactor.test.js +463 -0
- package/dist/src/utils/privacy/ConversationDataRedactor.test.js.map +1 -0
- package/dist/src/utils/readStdin.js +10 -0
- package/dist/src/utils/readStdin.js.map +1 -1
- package/dist/src/utils/sandbox.js +2 -2
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/utils/settingsUtils.test.d.ts +6 -0
- package/dist/src/utils/settingsUtils.test.js +514 -0
- package/dist/src/utils/settingsUtils.test.js.map +1 -0
- package/dist/src/utils/userStartupWarnings.js +2 -2
- package/dist/src/utils/userStartupWarnings.test.d.ts +6 -0
- package/dist/src/utils/userStartupWarnings.test.js +67 -0
- package/dist/src/utils/userStartupWarnings.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
@@ -0,0 +1,305 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Copyright 2025 Vybestack LLC
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
5
|
+
*/
|
6
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
7
|
+
import { ContentGeneratorRole, } from '@vybestack/llxprt-code-core';
|
8
|
+
// Remove unused interfaces to fix TS6196 errors
|
9
|
+
// Mock telemetry loggers
|
10
|
+
const telemetryLoggers = {
|
11
|
+
logConversationRequest: vi.fn(),
|
12
|
+
logProviderSwitch: vi.fn(),
|
13
|
+
};
|
14
|
+
// Test helper functions
|
15
|
+
function createMockProvider(name) {
|
16
|
+
return {
|
17
|
+
name,
|
18
|
+
getModels: vi.fn().mockResolvedValue([]),
|
19
|
+
generateChatCompletion: vi.fn().mockImplementation(async function* () {
|
20
|
+
yield {
|
21
|
+
content: `Response from ${name}`,
|
22
|
+
role: ContentGeneratorRole.ASSISTANT,
|
23
|
+
};
|
24
|
+
}),
|
25
|
+
getDefaultModel: vi.fn().mockReturnValue(`${name}-default-model`),
|
26
|
+
getServerTools: vi.fn().mockReturnValue([]),
|
27
|
+
invokeServerTool: vi.fn().mockResolvedValue({}),
|
28
|
+
};
|
29
|
+
}
|
30
|
+
function createConfigWithLogging(enabled) {
|
31
|
+
return {
|
32
|
+
getConversationLoggingEnabled: () => enabled,
|
33
|
+
};
|
34
|
+
}
|
35
|
+
async function consumeAsyncIterable(iterable) {
|
36
|
+
const results = [];
|
37
|
+
for await (const item of iterable) {
|
38
|
+
results.push(item);
|
39
|
+
}
|
40
|
+
return results;
|
41
|
+
}
|
42
|
+
// Mock classes that will be implemented
|
43
|
+
class MockLoggingProviderWrapper {
|
44
|
+
provider;
|
45
|
+
config;
|
46
|
+
redactor;
|
47
|
+
constructor(provider, config, redactor) {
|
48
|
+
this.provider = provider;
|
49
|
+
this.config = config;
|
50
|
+
this.redactor = redactor;
|
51
|
+
}
|
52
|
+
async *generateChatCompletion(messages, tools, toolFormat) {
|
53
|
+
// This should log the conversation request when logging is enabled
|
54
|
+
if (this.config.getConversationLoggingEnabled?.()) {
|
55
|
+
try {
|
56
|
+
const redactedMessages = messages.map((msg) => this.redactor.redactMessage(msg, this.provider.name));
|
57
|
+
telemetryLoggers.logConversationRequest(this.config, {
|
58
|
+
provider_name: this.provider.name,
|
59
|
+
redacted_messages: redactedMessages,
|
60
|
+
timestamp: new Date().toISOString(),
|
61
|
+
});
|
62
|
+
}
|
63
|
+
catch (_error) {
|
64
|
+
// Silently catch logging errors to ensure provider operation continues
|
65
|
+
// In real implementation, this would be properly logged to a fallback system
|
66
|
+
}
|
67
|
+
}
|
68
|
+
// Delegate to wrapped provider
|
69
|
+
yield* this.provider.generateChatCompletion(messages, tools, toolFormat);
|
70
|
+
}
|
71
|
+
getWrappedProvider() {
|
72
|
+
return this.provider;
|
73
|
+
}
|
74
|
+
}
|
75
|
+
class MockConversationDataRedactor {
|
76
|
+
redactMessage(message, _provider) {
|
77
|
+
// This is a placeholder - actual implementation will handle redaction
|
78
|
+
return { ...message, content: message.content };
|
79
|
+
}
|
80
|
+
redactToolCall(tool) {
|
81
|
+
// This is a placeholder - actual implementation will handle redaction
|
82
|
+
return { ...tool };
|
83
|
+
}
|
84
|
+
}
|
85
|
+
describe('Multi-Provider Conversation Logging', () => {
|
86
|
+
let mockProvider;
|
87
|
+
let config;
|
88
|
+
let redactor;
|
89
|
+
beforeEach(() => {
|
90
|
+
vi.clearAllMocks();
|
91
|
+
redactor = new MockConversationDataRedactor();
|
92
|
+
});
|
93
|
+
/**
|
94
|
+
* @requirement LOGGING-001: Provider-agnostic logging
|
95
|
+
* @scenario OpenAI provider generates chat completion
|
96
|
+
* @given LoggingProviderWrapper wrapping OpenAI provider with logging enabled
|
97
|
+
* @when generateChatCompletion() is called with test messages
|
98
|
+
* @then ConversationRequestEvent is created with provider_name: 'openai'
|
99
|
+
* @and Event contains redacted messages matching input structure
|
100
|
+
*/
|
101
|
+
it('should log OpenAI provider requests with provider context', async () => {
|
102
|
+
mockProvider = createMockProvider('openai');
|
103
|
+
config = createConfigWithLogging(true);
|
104
|
+
const wrapper = new MockLoggingProviderWrapper(mockProvider, config, redactor);
|
105
|
+
const messages = [
|
106
|
+
{ role: ContentGeneratorRole.USER, content: 'Test prompt' },
|
107
|
+
];
|
108
|
+
const logSpy = vi.spyOn(telemetryLoggers, 'logConversationRequest');
|
109
|
+
const stream = wrapper.generateChatCompletion(messages);
|
110
|
+
await consumeAsyncIterable(stream);
|
111
|
+
expect(logSpy).toHaveBeenCalledWith(config, expect.objectContaining({
|
112
|
+
provider_name: 'openai',
|
113
|
+
redacted_messages: expect.arrayContaining([
|
114
|
+
expect.objectContaining({
|
115
|
+
role: ContentGeneratorRole.USER,
|
116
|
+
content: 'Test prompt',
|
117
|
+
}),
|
118
|
+
]),
|
119
|
+
}));
|
120
|
+
});
|
121
|
+
/**
|
122
|
+
* @requirement LOGGING-002: Anthropic provider logging
|
123
|
+
* @scenario Anthropic provider generates chat completion
|
124
|
+
* @given LoggingProviderWrapper wrapping Anthropic provider with logging enabled
|
125
|
+
* @when generateChatCompletion() is called with messages containing tool calls
|
126
|
+
* @then ConversationRequestEvent includes provider_name: 'anthropic'
|
127
|
+
* @and Tool calls are properly redacted in the logged messages
|
128
|
+
*/
|
129
|
+
it('should log Anthropic provider requests with tool call redaction', async () => {
|
130
|
+
mockProvider = createMockProvider('anthropic');
|
131
|
+
config = createConfigWithLogging(true);
|
132
|
+
const wrapper = new MockLoggingProviderWrapper(mockProvider, config, redactor);
|
133
|
+
const messages = [
|
134
|
+
{
|
135
|
+
role: ContentGeneratorRole.USER,
|
136
|
+
content: 'Read my API key file',
|
137
|
+
tool_calls: [
|
138
|
+
{
|
139
|
+
id: 'call_1',
|
140
|
+
type: 'function',
|
141
|
+
function: {
|
142
|
+
name: 'read_file',
|
143
|
+
arguments: JSON.stringify({
|
144
|
+
file_path: '/home/user/.openai/key',
|
145
|
+
}),
|
146
|
+
},
|
147
|
+
},
|
148
|
+
],
|
149
|
+
},
|
150
|
+
];
|
151
|
+
const logSpy = vi.spyOn(telemetryLoggers, 'logConversationRequest');
|
152
|
+
const stream = wrapper.generateChatCompletion(messages);
|
153
|
+
await consumeAsyncIterable(stream);
|
154
|
+
expect(logSpy).toHaveBeenCalledWith(config, expect.objectContaining({
|
155
|
+
provider_name: 'anthropic',
|
156
|
+
redacted_messages: expect.arrayContaining([
|
157
|
+
expect.objectContaining({
|
158
|
+
role: ContentGeneratorRole.USER,
|
159
|
+
tool_calls: expect.any(Array),
|
160
|
+
}),
|
161
|
+
]),
|
162
|
+
}));
|
163
|
+
});
|
164
|
+
/**
|
165
|
+
* @requirement LOGGING-003: Gemini provider logging
|
166
|
+
* @scenario Gemini provider generates chat completion
|
167
|
+
* @given LoggingProviderWrapper wrapping Gemini provider with logging enabled
|
168
|
+
* @when generateChatCompletion() is called with system message
|
169
|
+
* @then ConversationRequestEvent includes provider_name: 'gemini'
|
170
|
+
* @and System message is included in redacted messages
|
171
|
+
*/
|
172
|
+
it('should log Gemini provider requests with system messages', async () => {
|
173
|
+
mockProvider = createMockProvider('gemini');
|
174
|
+
config = createConfigWithLogging(true);
|
175
|
+
const wrapper = new MockLoggingProviderWrapper(mockProvider, config, redactor);
|
176
|
+
const messages = [
|
177
|
+
{ role: 'system', content: 'You are a helpful assistant' },
|
178
|
+
{ role: ContentGeneratorRole.USER, content: 'Hello' },
|
179
|
+
];
|
180
|
+
const logSpy = vi.spyOn(telemetryLoggers, 'logConversationRequest');
|
181
|
+
const stream = wrapper.generateChatCompletion(messages);
|
182
|
+
await consumeAsyncIterable(stream);
|
183
|
+
expect(logSpy).toHaveBeenCalledWith(config, expect.objectContaining({
|
184
|
+
provider_name: 'gemini',
|
185
|
+
redacted_messages: expect.arrayContaining([
|
186
|
+
expect.objectContaining({ role: 'system' }),
|
187
|
+
expect.objectContaining({
|
188
|
+
role: ContentGeneratorRole.USER,
|
189
|
+
content: 'Hello',
|
190
|
+
}),
|
191
|
+
]),
|
192
|
+
}));
|
193
|
+
});
|
194
|
+
/**
|
195
|
+
* @requirement LOGGING-004: Logging disabled behavior
|
196
|
+
* @scenario LoggingProviderWrapper with logging disabled
|
197
|
+
* @given LoggingProviderWrapper with config.logConversations: false
|
198
|
+
* @when generateChatCompletion() is called
|
199
|
+
* @then No telemetry logging methods are called
|
200
|
+
* @and Provider operates normally without logging overhead
|
201
|
+
*/
|
202
|
+
it('should not log when conversation logging is disabled', async () => {
|
203
|
+
mockProvider = createMockProvider('openai');
|
204
|
+
config = createConfigWithLogging(false);
|
205
|
+
const wrapper = new MockLoggingProviderWrapper(mockProvider, config, redactor);
|
206
|
+
const messages = [
|
207
|
+
{ role: ContentGeneratorRole.USER, content: 'Test prompt' },
|
208
|
+
];
|
209
|
+
const logSpy = vi.spyOn(telemetryLoggers, 'logConversationRequest');
|
210
|
+
const stream = wrapper.generateChatCompletion(messages);
|
211
|
+
await consumeAsyncIterable(stream);
|
212
|
+
expect(logSpy).not.toHaveBeenCalled();
|
213
|
+
});
|
214
|
+
/**
|
215
|
+
* @requirement LOGGING-005: Tool format preservation
|
216
|
+
* @scenario Provider with custom tool format
|
217
|
+
* @given LoggingProviderWrapper wrapping provider with hermes tool format
|
218
|
+
* @when generateChatCompletion() is called with toolFormat parameter
|
219
|
+
* @then Tool format is passed through to wrapped provider unchanged
|
220
|
+
* @and Logging captures the tool format used
|
221
|
+
*/
|
222
|
+
it('should preserve tool format when logging provider requests', async () => {
|
223
|
+
mockProvider = createMockProvider('openai');
|
224
|
+
config = createConfigWithLogging(true);
|
225
|
+
const wrapper = new MockLoggingProviderWrapper(mockProvider, config, redactor);
|
226
|
+
const messages = [
|
227
|
+
{ role: ContentGeneratorRole.USER, content: 'Test' },
|
228
|
+
];
|
229
|
+
const tools = [
|
230
|
+
{
|
231
|
+
type: 'function',
|
232
|
+
function: {
|
233
|
+
name: 'test_tool',
|
234
|
+
description: 'A test tool',
|
235
|
+
parameters: { type: 'object', properties: {} },
|
236
|
+
},
|
237
|
+
},
|
238
|
+
];
|
239
|
+
const stream = wrapper.generateChatCompletion(messages, tools, 'hermes');
|
240
|
+
await consumeAsyncIterable(stream);
|
241
|
+
expect(mockProvider.generateChatCompletion).toHaveBeenCalledWith(messages, tools, 'hermes');
|
242
|
+
});
|
243
|
+
/**
|
244
|
+
* @requirement LOGGING-006: Error handling in logging
|
245
|
+
* @scenario LoggingProviderWrapper encounters logging error
|
246
|
+
* @given LoggingProviderWrapper with logging enabled
|
247
|
+
* @when generateChatCompletion() is called and logging throws error
|
248
|
+
* @then Provider operation continues normally
|
249
|
+
* @and Error does not propagate to caller
|
250
|
+
*/
|
251
|
+
it('should handle logging errors gracefully without affecting provider operation', async () => {
|
252
|
+
mockProvider = createMockProvider('openai');
|
253
|
+
config = createConfigWithLogging(true);
|
254
|
+
// Mock the logging function to throw an error
|
255
|
+
vi.spyOn(telemetryLoggers, 'logConversationRequest').mockImplementation(() => {
|
256
|
+
throw new Error('Logging service unavailable');
|
257
|
+
});
|
258
|
+
const wrapper = new MockLoggingProviderWrapper(mockProvider, config, redactor);
|
259
|
+
const messages = [
|
260
|
+
{ role: ContentGeneratorRole.USER, content: 'Test' },
|
261
|
+
];
|
262
|
+
// Should not throw despite logging error
|
263
|
+
const stream = wrapper.generateChatCompletion(messages);
|
264
|
+
const results = await consumeAsyncIterable(stream);
|
265
|
+
expect(results).toHaveLength(1);
|
266
|
+
expect(results[0]).toMatchObject({ content: 'Response from openai' });
|
267
|
+
});
|
268
|
+
/**
|
269
|
+
* @requirement LOGGING-007: Async iterator preservation
|
270
|
+
* @scenario LoggingProviderWrapper with streaming response
|
271
|
+
* @given LoggingProviderWrapper wrapping provider that yields multiple chunks
|
272
|
+
* @when generateChatCompletion() returns async iterator
|
273
|
+
* @then All chunks are yielded in correct order
|
274
|
+
* @and Logging occurs before first chunk is yielded
|
275
|
+
*/
|
276
|
+
it('should preserve async iterator behavior while logging', async () => {
|
277
|
+
const streamingProvider = {
|
278
|
+
name: 'streaming',
|
279
|
+
getModels: vi.fn().mockResolvedValue([]),
|
280
|
+
async *generateChatCompletion() {
|
281
|
+
yield { content: 'Chunk 1', role: ContentGeneratorRole.ASSISTANT };
|
282
|
+
yield { content: 'Chunk 2', role: ContentGeneratorRole.ASSISTANT };
|
283
|
+
yield { content: 'Chunk 3', role: ContentGeneratorRole.ASSISTANT };
|
284
|
+
},
|
285
|
+
getDefaultModel: vi.fn().mockReturnValue('streaming-default-model'),
|
286
|
+
getServerTools: vi.fn().mockReturnValue([]),
|
287
|
+
invokeServerTool: vi.fn().mockResolvedValue({}),
|
288
|
+
};
|
289
|
+
config = createConfigWithLogging(true);
|
290
|
+
const wrapper = new MockLoggingProviderWrapper(streamingProvider, config, redactor);
|
291
|
+
const logSpy = vi.spyOn(telemetryLoggers, 'logConversationRequest');
|
292
|
+
const messages = [
|
293
|
+
{ role: ContentGeneratorRole.USER, content: 'Stream test' },
|
294
|
+
];
|
295
|
+
const results = await consumeAsyncIterable(wrapper.generateChatCompletion(messages));
|
296
|
+
expect(logSpy).toHaveBeenCalled();
|
297
|
+
expect(results).toHaveLength(3);
|
298
|
+
expect(results.map((r) => r.content)).toEqual([
|
299
|
+
'Chunk 1',
|
300
|
+
'Chunk 2',
|
301
|
+
'Chunk 3',
|
302
|
+
]);
|
303
|
+
});
|
304
|
+
});
|
305
|
+
//# sourceMappingURL=LoggingProviderWrapper.test.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"LoggingProviderWrapper.test.js","sourceRoot":"","sources":["../../../../src/providers/logging/LoggingProviderWrapper.test.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,245 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Copyright 2025 Vybestack LLC
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
5
|
+
*/
|
6
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
7
|
+
import { promises as fs } from 'node:fs';
|
8
|
+
import { join } from 'node:path';
|
9
|
+
import { tmpdir } from 'node:os';
|
10
|
+
import { GitStatsTracker } from './git-stats.js';
|
11
|
+
import { Config } from '@vybestack/llxprt-code-core';
|
12
|
+
describe('Git Stats Integration', () => {
|
13
|
+
let tempDir;
|
14
|
+
let conversationLogDir;
|
15
|
+
let config;
|
16
|
+
let tracker;
|
17
|
+
beforeEach(async () => {
|
18
|
+
// Create temporary directories for testing
|
19
|
+
tempDir = await fs.mkdtemp(join(tmpdir(), 'git-stats-test-'));
|
20
|
+
conversationLogDir = join(tempDir, '.llxprt', 'conversations');
|
21
|
+
await fs.mkdir(conversationLogDir, { recursive: true });
|
22
|
+
// Create config with temp directory
|
23
|
+
const randomId = Math.floor(Math.random() * 10000);
|
24
|
+
config = new Config({
|
25
|
+
sessionId: `test-session-${randomId}`,
|
26
|
+
targetDir: tempDir,
|
27
|
+
debugMode: false,
|
28
|
+
cwd: tempDir,
|
29
|
+
model: 'gemini-flash',
|
30
|
+
telemetry: {
|
31
|
+
logConversations: true,
|
32
|
+
conversationLogPath: conversationLogDir,
|
33
|
+
},
|
34
|
+
});
|
35
|
+
tracker = new GitStatsTracker(config);
|
36
|
+
});
|
37
|
+
afterEach(async () => {
|
38
|
+
// Clean up temporary directory
|
39
|
+
try {
|
40
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
41
|
+
}
|
42
|
+
catch (error) {
|
43
|
+
// Ignore cleanup errors in tests
|
44
|
+
console.warn('Failed to cleanup temp directory:', error);
|
45
|
+
}
|
46
|
+
});
|
47
|
+
it('should track stats during actual file edits', async () => {
|
48
|
+
const testFile = join(tempDir, 'test.ts');
|
49
|
+
const initialContent = 'function hello() {\n console.log("Hello");\n}';
|
50
|
+
const modifiedContent = initialContent +
|
51
|
+
'\n\n// Added comment\nfunction goodbye() {\n console.log("Goodbye");\n}';
|
52
|
+
// Create the initial file
|
53
|
+
await fs.writeFile(testFile, initialContent, 'utf8');
|
54
|
+
// Track the edit from initial to modified content
|
55
|
+
const stats = await tracker.trackFileEdit(testFile, initialContent, modifiedContent);
|
56
|
+
expect(stats).not.toBeNull();
|
57
|
+
expect(stats.linesAdded).toBe(4); // blank line + comment + function with 3 lines
|
58
|
+
expect(stats.linesRemoved).toBe(0);
|
59
|
+
expect(stats.filesChanged).toBe(1);
|
60
|
+
// Verify the actual file can be read and matches
|
61
|
+
const actualContent = await fs.readFile(testFile, 'utf8');
|
62
|
+
expect(actualContent).toBe(initialContent); // File itself shouldn't be modified by tracking
|
63
|
+
});
|
64
|
+
it('should persist stats to conversation log file', async () => {
|
65
|
+
const testFile = join(tempDir, 'example.js');
|
66
|
+
// Perform multiple file edits
|
67
|
+
await tracker.trackFileEdit(testFile, 'const x = 1;', 'const x = 1;\nconst y = 2;\nconst z = x + y;');
|
68
|
+
await tracker.trackFileEdit(join(tempDir, 'another.ts'), 'let data: string;', 'let data: string = "updated";');
|
69
|
+
// Force write to log file (in real implementation, this would happen automatically)
|
70
|
+
const logEntry = tracker.getLogEntry();
|
71
|
+
expect(logEntry).not.toBeNull();
|
72
|
+
// Write a sample conversation log entry
|
73
|
+
const logFile = join(conversationLogDir, `conversation-${config.getSessionId()}.jsonl`);
|
74
|
+
const logData = {
|
75
|
+
timestamp: new Date().toISOString(),
|
76
|
+
session_id: config.getSessionId(),
|
77
|
+
git_stats: tracker.getSummary(),
|
78
|
+
};
|
79
|
+
await fs.writeFile(logFile, JSON.stringify(logData) + '\n', 'utf8');
|
80
|
+
// Verify log file was created and contains stats
|
81
|
+
const logExists = await fs
|
82
|
+
.access(logFile)
|
83
|
+
.then(() => true)
|
84
|
+
.catch(() => false);
|
85
|
+
expect(logExists).toBe(true);
|
86
|
+
const logContent = await fs.readFile(logFile, 'utf8');
|
87
|
+
const parsedLog = JSON.parse(logContent.trim());
|
88
|
+
expect(parsedLog.git_stats).toMatchObject({
|
89
|
+
filesChanged: 2,
|
90
|
+
totalLinesAdded: expect.any(Number),
|
91
|
+
totalLinesRemoved: 0,
|
92
|
+
sessionId: config.getSessionId(),
|
93
|
+
});
|
94
|
+
});
|
95
|
+
it('should display stats in /logging show command simulation', async () => {
|
96
|
+
const testFiles = [
|
97
|
+
{ path: 'src/main.ts', old: 'main code', new: 'main code\n// updated' },
|
98
|
+
{
|
99
|
+
path: 'src/utils.ts',
|
100
|
+
old: 'utils',
|
101
|
+
new: 'utilities with more content',
|
102
|
+
},
|
103
|
+
{ path: 'package.json', old: '{}', new: '{\n "name": "test"\n}' },
|
104
|
+
];
|
105
|
+
// Track edits for multiple files
|
106
|
+
for (const file of testFiles) {
|
107
|
+
await tracker.trackFileEdit(file.path, file.old, file.new);
|
108
|
+
}
|
109
|
+
// Get summary that would be displayed in logging show
|
110
|
+
const summary = tracker.getSummary();
|
111
|
+
expect(summary).toMatchObject({
|
112
|
+
sessionId: expect.any(String),
|
113
|
+
filesChanged: 3,
|
114
|
+
totalLinesAdded: expect.any(Number),
|
115
|
+
totalLinesRemoved: expect.any(Number),
|
116
|
+
});
|
117
|
+
// Verify the summary contains reasonable data
|
118
|
+
expect(summary.totalLinesAdded).toBeGreaterThan(0);
|
119
|
+
expect(summary.filesChanged).toBe(3);
|
120
|
+
// Simulate the display format that would be shown to users
|
121
|
+
const displayFormat = {
|
122
|
+
'Files Modified': summary.filesChanged,
|
123
|
+
'Lines Added': summary.totalLinesAdded,
|
124
|
+
'Lines Removed': summary.totalLinesRemoved,
|
125
|
+
'Session ID': summary.sessionId.substring(0, 8) + '...', // Truncated for display
|
126
|
+
};
|
127
|
+
expect(displayFormat['Files Modified']).toBe(3);
|
128
|
+
expect(displayFormat['Lines Added']).toBeGreaterThan(0);
|
129
|
+
});
|
130
|
+
it('should handle concurrent file operations', async () => {
|
131
|
+
const concurrentEdits = Array.from({ length: 10 }, (_, i) => ({
|
132
|
+
path: `concurrent-${i}.ts`,
|
133
|
+
old: `// File ${i}`,
|
134
|
+
new: `// File ${i}\nconst value${i} = ${i};`,
|
135
|
+
}));
|
136
|
+
// Execute all edits concurrently
|
137
|
+
const results = await Promise.all(concurrentEdits.map((edit) => tracker.trackFileEdit(edit.path, edit.old, edit.new)));
|
138
|
+
// All results should be successful
|
139
|
+
results.forEach((result) => {
|
140
|
+
expect(result).not.toBeNull();
|
141
|
+
expect(result.linesAdded).toBe(1);
|
142
|
+
expect(result.linesRemoved).toBe(0);
|
143
|
+
expect(result.filesChanged).toBe(1);
|
144
|
+
});
|
145
|
+
// Final summary should account for all edits
|
146
|
+
const summary = tracker.getSummary();
|
147
|
+
expect(summary.filesChanged).toBe(10);
|
148
|
+
expect(summary.totalLinesAdded).toBe(10);
|
149
|
+
expect(summary.totalLinesRemoved).toBe(0);
|
150
|
+
});
|
151
|
+
it('should preserve stats across tracker recreation', async () => {
|
152
|
+
// Initial edits with first tracker
|
153
|
+
await tracker.trackFileEdit('file1.ts', 'old', 'new content');
|
154
|
+
const firstSummary = tracker.getSummary();
|
155
|
+
expect(firstSummary.filesChanged).toBe(1);
|
156
|
+
// Create new tracker with same config (simulating app restart)
|
157
|
+
const newTracker = new GitStatsTracker(config);
|
158
|
+
// Should start fresh (stats are session-scoped, not persistent across restarts)
|
159
|
+
expect(newTracker.getSummary().filesChanged).toBe(0);
|
160
|
+
// New edits should work normally
|
161
|
+
await newTracker.trackFileEdit('file2.ts', 'another', 'another file');
|
162
|
+
expect(newTracker.getSummary().filesChanged).toBe(1);
|
163
|
+
});
|
164
|
+
it('should handle file system errors gracefully', async () => {
|
165
|
+
// Test with read-only directory (if possible to create)
|
166
|
+
const readOnlyDir = join(tempDir, 'readonly');
|
167
|
+
await fs.mkdir(readOnlyDir);
|
168
|
+
try {
|
169
|
+
// Make directory read-only
|
170
|
+
await fs.chmod(readOnlyDir, 0o444);
|
171
|
+
// Attempt to track file in read-only directory
|
172
|
+
const stats = await tracker.trackFileEdit(join(readOnlyDir, 'readonly-file.ts'), 'original', 'modified');
|
173
|
+
// Should still track stats even if file system operations fail
|
174
|
+
expect(stats).not.toBeNull();
|
175
|
+
expect(stats.linesAdded).toBeGreaterThan(0);
|
176
|
+
}
|
177
|
+
finally {
|
178
|
+
// Restore permissions for cleanup
|
179
|
+
await fs.chmod(readOnlyDir, 0o755).catch(() => { });
|
180
|
+
}
|
181
|
+
});
|
182
|
+
it('should work with large files in real filesystem', async () => {
|
183
|
+
const largeFile = join(tempDir, 'large-file.ts');
|
184
|
+
// Generate large content (1000 lines)
|
185
|
+
const generateContent = (lines, prefix) => Array.from({ length: lines }, (_, i) => `${prefix}${i}: console.log('Line ${i}');`).join('\n');
|
186
|
+
const originalContent = generateContent(1000, 'original_');
|
187
|
+
const modifiedContent = originalContent + '\n' + generateContent(100, 'added_');
|
188
|
+
// Write the large file to disk
|
189
|
+
await fs.writeFile(largeFile, originalContent, 'utf8');
|
190
|
+
// Track the edit
|
191
|
+
const startTime = process.hrtime.bigint();
|
192
|
+
const stats = await tracker.trackFileEdit(largeFile, originalContent, modifiedContent);
|
193
|
+
const endTime = process.hrtime.bigint();
|
194
|
+
const durationMs = Number(endTime - startTime) / 1_000_000;
|
195
|
+
// Verify stats are correct
|
196
|
+
expect(stats).not.toBeNull();
|
197
|
+
expect(stats.linesAdded).toBe(101); // 1 blank line + 100 added lines
|
198
|
+
expect(stats.linesRemoved).toBe(0);
|
199
|
+
expect(stats.filesChanged).toBe(1);
|
200
|
+
// Should complete in reasonable time even with large files
|
201
|
+
expect(durationMs).toBeLessThan(500); // Less than 500ms
|
202
|
+
// Verify file still exists and can be read
|
203
|
+
const fileExists = await fs
|
204
|
+
.access(largeFile)
|
205
|
+
.then(() => true)
|
206
|
+
.catch(() => false);
|
207
|
+
expect(fileExists).toBe(true);
|
208
|
+
const fileContent = await fs.readFile(largeFile, 'utf8');
|
209
|
+
expect(fileContent).toBe(originalContent); // File shouldn't be modified by tracking
|
210
|
+
});
|
211
|
+
it('should handle special characters and encoding', async () => {
|
212
|
+
const testFile = join(tempDir, 'unicode-test.ts');
|
213
|
+
// Content with various encodings and special characters
|
214
|
+
const unicodeContent = {
|
215
|
+
original: '// Original: Hello 世界\nconst emoji = "🚀";',
|
216
|
+
modified: '// Modified: Hello 世界 🌍\nconst emoji = "🚀";\nconst symbols = "αβγδε";',
|
217
|
+
};
|
218
|
+
await tracker.trackFileEdit(testFile, unicodeContent.original, unicodeContent.modified);
|
219
|
+
const summary = tracker.getSummary();
|
220
|
+
expect(summary.filesChanged).toBe(1);
|
221
|
+
expect(summary.totalLinesAdded).toBe(1); // Added one line with symbols
|
222
|
+
});
|
223
|
+
it('should validate no external network calls during integration', async () => {
|
224
|
+
// Set up network monitoring
|
225
|
+
const originalFetch = global.fetch;
|
226
|
+
const fetchSpy = vi.fn();
|
227
|
+
global.fetch = fetchSpy;
|
228
|
+
try {
|
229
|
+
// Perform various operations that could potentially make network calls
|
230
|
+
await tracker.trackFileEdit('network-test.ts', 'import api from "external";', 'import api from "external";\napi.call();');
|
231
|
+
const summary = tracker.getSummary();
|
232
|
+
const logEntry = tracker.getLogEntry();
|
233
|
+
// Verify operations completed successfully
|
234
|
+
expect(summary.filesChanged).toBe(1);
|
235
|
+
expect(logEntry).not.toBeNull();
|
236
|
+
// Most important: verify no network calls were made
|
237
|
+
expect(fetchSpy).not.toHaveBeenCalled();
|
238
|
+
}
|
239
|
+
finally {
|
240
|
+
// Restore original fetch
|
241
|
+
global.fetch = originalFetch;
|
242
|
+
}
|
243
|
+
});
|
244
|
+
});
|
245
|
+
//# sourceMappingURL=git-stats.integration.test.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"git-stats.integration.test.js","sourceRoot":"","sources":["../../../../src/providers/logging/git-stats.integration.test.ts"],"names":[],"mappings":"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"}
|