@vybestack/llxprt-code 0.1.20 → 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,319 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Copyright 2025 Vybestack LLC
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
5
|
+
*/
|
6
|
+
import * as fs from 'fs/promises';
|
7
|
+
import * as path from 'path';
|
8
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
9
|
+
import { createTempDirectory, cleanupTempDirectory, createTempProfile, createTempKeyfile, readSettingsFile, writeSettingsFile, } from './test-utils.js';
|
10
|
+
import { Config } from '@vybestack/llxprt-code-core';
|
11
|
+
import { loadSettings } from '../config/settings.js';
|
12
|
+
describe('API Key Security Integration Tests', () => {
|
13
|
+
let tempDir;
|
14
|
+
let config;
|
15
|
+
beforeEach(async () => {
|
16
|
+
tempDir = await createTempDirectory();
|
17
|
+
// Create a basic config instance
|
18
|
+
config = new Config({
|
19
|
+
sessionId: 'test-session',
|
20
|
+
targetDir: tempDir,
|
21
|
+
debugMode: false,
|
22
|
+
cwd: tempDir,
|
23
|
+
model: 'gemini-1.5-flash',
|
24
|
+
});
|
25
|
+
await config.initialize();
|
26
|
+
});
|
27
|
+
afterEach(async () => {
|
28
|
+
await cleanupTempDirectory(tempDir);
|
29
|
+
});
|
30
|
+
describe('API keys should NEVER persist to settings.json', () => {
|
31
|
+
it('should not write API keys to settings.json when set via ephemeral settings', async () => {
|
32
|
+
// Set API keys via ephemeral settings
|
33
|
+
config.setEphemeralSetting('openai-api-key', 'sk-test-12345');
|
34
|
+
config.setEphemeralSetting('anthropic-api-key', 'sk-ant-test-67890');
|
35
|
+
config.setEphemeralSetting('gemini-api-key', 'AIza-test-abcdef');
|
36
|
+
// Simulate saving settings (without API keys)
|
37
|
+
const settings = {
|
38
|
+
theme: 'default',
|
39
|
+
sandbox: true,
|
40
|
+
coreTools: ['ls', 'grep'],
|
41
|
+
};
|
42
|
+
await writeSettingsFile(tempDir, settings);
|
43
|
+
// Read the actual settings.json file content
|
44
|
+
const settingsPath = path.join(tempDir, '.llxprt', 'settings.json');
|
45
|
+
const fileContent = await fs.readFile(settingsPath, 'utf8');
|
46
|
+
const parsedSettings = JSON.parse(fileContent);
|
47
|
+
// Verify no API keys appear in the file
|
48
|
+
expect(fileContent).not.toContain('sk-test-12345');
|
49
|
+
expect(fileContent).not.toContain('sk-ant-test-67890');
|
50
|
+
expect(fileContent).not.toContain('AIza-test-abcdef');
|
51
|
+
expect(fileContent).not.toContain('api-key');
|
52
|
+
expect(fileContent).not.toContain('apiKey');
|
53
|
+
// Verify expected settings are present
|
54
|
+
expect(parsedSettings.theme).toBe('default');
|
55
|
+
expect(parsedSettings.sandbox).toBe(true);
|
56
|
+
expect(parsedSettings.coreTools).toEqual(['ls', 'grep']);
|
57
|
+
});
|
58
|
+
it('should not persist providerApiKeys to settings.json', async () => {
|
59
|
+
// Try to write providerApiKeys (this should be prevented)
|
60
|
+
const settings = {
|
61
|
+
theme: 'default',
|
62
|
+
providerApiKeys: {
|
63
|
+
openai: 'sk-test-12345',
|
64
|
+
anthropic: 'sk-ant-test-67890',
|
65
|
+
},
|
66
|
+
};
|
67
|
+
await writeSettingsFile(tempDir, settings);
|
68
|
+
// Read back and verify providerApiKeys were written (testing current behavior)
|
69
|
+
const savedSettings = await readSettingsFile(tempDir);
|
70
|
+
// In a properly secured system, this should be filtered out
|
71
|
+
// For now, we're documenting the current behavior
|
72
|
+
if (typeof savedSettings === 'object' && savedSettings !== null) {
|
73
|
+
const settingsObj = savedSettings;
|
74
|
+
// This test documents that providerApiKeys currently DO get saved
|
75
|
+
// This is a security issue that should be fixed
|
76
|
+
expect(settingsObj.providerApiKeys).toBeDefined();
|
77
|
+
}
|
78
|
+
});
|
79
|
+
it('should not write base URLs with embedded credentials to settings.json', async () => {
|
80
|
+
// Set base URLs via ephemeral settings
|
81
|
+
config.setEphemeralSetting('openai-base-url', 'https://api.openai.com/v1');
|
82
|
+
config.setEphemeralSetting('anthropic-base-url', 'https://user:pass@api.anthropic.com');
|
83
|
+
// Write settings
|
84
|
+
const settings = {
|
85
|
+
theme: 'default',
|
86
|
+
providerBaseUrls: {
|
87
|
+
openai: 'https://api.openai.com/v1',
|
88
|
+
// Should not include URLs with credentials
|
89
|
+
anthropic: 'https://api.anthropic.com',
|
90
|
+
},
|
91
|
+
};
|
92
|
+
await writeSettingsFile(tempDir, settings);
|
93
|
+
// Verify no credentials in URLs
|
94
|
+
const fileContent = await fs.readFile(path.join(tempDir, '.llxprt', 'settings.json'), 'utf8');
|
95
|
+
expect(fileContent).not.toContain('user:pass@');
|
96
|
+
});
|
97
|
+
});
|
98
|
+
describe('Provider isolation', () => {
|
99
|
+
it('should maintain provider isolation for API keys', async () => {
|
100
|
+
// Set different API keys for multiple providers
|
101
|
+
config.setEphemeralSetting('openai-api-key', 'sk-openai-12345');
|
102
|
+
config.setEphemeralSetting('anthropic-api-key', 'sk-anthropic-67890');
|
103
|
+
config.setEphemeralSetting('google-api-key', 'AIza-google-abcdef');
|
104
|
+
config.setEphemeralSetting('groq-api-key', 'gsk_groq_xyz123');
|
105
|
+
// Get ephemeral settings
|
106
|
+
const ephemeralSettings = config.getEphemeralSettings();
|
107
|
+
// Verify each provider has its own isolated key
|
108
|
+
expect(ephemeralSettings['openai-api-key']).toBe('sk-openai-12345');
|
109
|
+
expect(ephemeralSettings['anthropic-api-key']).toBe('sk-anthropic-67890');
|
110
|
+
expect(ephemeralSettings['google-api-key']).toBe('AIza-google-abcdef');
|
111
|
+
expect(ephemeralSettings['groq-api-key']).toBe('gsk_groq_xyz123');
|
112
|
+
// Verify no cross-contamination
|
113
|
+
expect(ephemeralSettings['openai-api-key']).not.toContain('anthropic');
|
114
|
+
expect(ephemeralSettings['anthropic-api-key']).not.toContain('openai');
|
115
|
+
});
|
116
|
+
it('should isolate provider settings when dumping to disk', async () => {
|
117
|
+
// Set provider-specific settings
|
118
|
+
const settings = {
|
119
|
+
theme: 'default',
|
120
|
+
providerBaseUrls: {
|
121
|
+
openai: 'https://api.openai.com/v1',
|
122
|
+
anthropic: 'https://api.anthropic.com/v1',
|
123
|
+
groq: 'https://api.groq.com/v1',
|
124
|
+
},
|
125
|
+
providerToolFormatOverrides: {
|
126
|
+
openai: 'openai',
|
127
|
+
anthropic: 'anthropic',
|
128
|
+
},
|
129
|
+
};
|
130
|
+
await writeSettingsFile(tempDir, settings);
|
131
|
+
const savedSettings = await readSettingsFile(tempDir);
|
132
|
+
if (typeof savedSettings === 'object' && savedSettings !== null) {
|
133
|
+
const settingsObj = savedSettings;
|
134
|
+
const baseUrls = settingsObj.providerBaseUrls;
|
135
|
+
// Verify each provider maintains its own settings
|
136
|
+
expect(baseUrls.openai).toBe('https://api.openai.com/v1');
|
137
|
+
expect(baseUrls.anthropic).toBe('https://api.anthropic.com/v1');
|
138
|
+
expect(baseUrls.groq).toBe('https://api.groq.com/v1');
|
139
|
+
}
|
140
|
+
});
|
141
|
+
});
|
142
|
+
describe('Keyfile security', () => {
|
143
|
+
it('should create keyfiles with restrictive permissions (600)', async () => {
|
144
|
+
const apiKey = 'sk-test-secure-key-12345';
|
145
|
+
const keyfilePath = await createTempKeyfile(tempDir, apiKey);
|
146
|
+
// Check file permissions
|
147
|
+
const stats = await fs.stat(keyfilePath);
|
148
|
+
const mode = stats.mode & parseInt('777', 8);
|
149
|
+
// On Unix-like systems, verify 600 permissions
|
150
|
+
if (process.platform !== 'win32') {
|
151
|
+
expect(mode).toBe(parseInt('600', 8));
|
152
|
+
}
|
153
|
+
// Verify content
|
154
|
+
const content = await fs.readFile(keyfilePath, 'utf8');
|
155
|
+
expect(content).toBe(apiKey);
|
156
|
+
});
|
157
|
+
it('should handle keyfiles with wrong permissions', async () => {
|
158
|
+
const apiKey = 'sk-test-key-with-bad-perms';
|
159
|
+
const keyfilePath = await createTempKeyfile(tempDir, apiKey);
|
160
|
+
// Change permissions to be too permissive
|
161
|
+
if (process.platform !== 'win32') {
|
162
|
+
await fs.chmod(keyfilePath, 0o644);
|
163
|
+
// In a real implementation, the system should reject or warn about this
|
164
|
+
const stats = await fs.stat(keyfilePath);
|
165
|
+
const mode = stats.mode & parseInt('777', 8);
|
166
|
+
expect(mode).toBe(parseInt('644', 8));
|
167
|
+
}
|
168
|
+
});
|
169
|
+
it('should fail to read inaccessible keyfiles', async () => {
|
170
|
+
const apiKey = 'sk-test-inaccessible';
|
171
|
+
const keyfilePath = await createTempKeyfile(tempDir, apiKey);
|
172
|
+
// Make file inaccessible
|
173
|
+
if (process.platform !== 'win32') {
|
174
|
+
await fs.chmod(keyfilePath, 0o000);
|
175
|
+
// Attempt to read should fail
|
176
|
+
await expect(fs.readFile(keyfilePath, 'utf8')).rejects.toThrow();
|
177
|
+
// Restore permissions for cleanup
|
178
|
+
await fs.chmod(keyfilePath, 0o600);
|
179
|
+
}
|
180
|
+
});
|
181
|
+
it('should store keyfile paths but not contents in settings', async () => {
|
182
|
+
const keyfilePath = await createTempKeyfile(tempDir, 'sk-test-keyfile-content');
|
183
|
+
const settings = {
|
184
|
+
providerKeyfiles: {
|
185
|
+
openai: keyfilePath,
|
186
|
+
anthropic: path.join(tempDir, '.keys', 'anthropic-key'),
|
187
|
+
},
|
188
|
+
};
|
189
|
+
await writeSettingsFile(tempDir, settings);
|
190
|
+
const fileContent = await fs.readFile(path.join(tempDir, '.llxprt', 'settings.json'), 'utf8');
|
191
|
+
// Should contain paths but not key contents
|
192
|
+
expect(fileContent).toContain(keyfilePath);
|
193
|
+
expect(fileContent).not.toContain('sk-test-keyfile-content');
|
194
|
+
});
|
195
|
+
});
|
196
|
+
describe('API key storage locations', () => {
|
197
|
+
it('should only store API keys in ephemeral settings (runtime only)', async () => {
|
198
|
+
// Set API key in ephemeral settings
|
199
|
+
config.setEphemeralSetting('auth-key', 'sk-test-ephemeral-only');
|
200
|
+
// Verify it's in ephemeral settings
|
201
|
+
expect(config.getEphemeralSetting('auth-key')).toBe('sk-test-ephemeral-only');
|
202
|
+
// Verify it's not in any persistent storage
|
203
|
+
const settingsPath = path.join(tempDir, '.llxprt', 'settings.json');
|
204
|
+
// Write some other settings
|
205
|
+
await writeSettingsFile(tempDir, { theme: 'default' });
|
206
|
+
const fileContent = await fs.readFile(settingsPath, 'utf8');
|
207
|
+
expect(fileContent).not.toContain('sk-test-ephemeral-only');
|
208
|
+
expect(fileContent).not.toContain('auth-key');
|
209
|
+
});
|
210
|
+
it('should store API keys in profile files when explicitly saved', async () => {
|
211
|
+
const profile = {
|
212
|
+
version: 1,
|
213
|
+
provider: 'openai',
|
214
|
+
model: 'gpt-4',
|
215
|
+
modelParams: {
|
216
|
+
temperature: 0.7,
|
217
|
+
max_tokens: 2000,
|
218
|
+
},
|
219
|
+
ephemeralSettings: {
|
220
|
+
'auth-key': 'sk-test-profile-key',
|
221
|
+
'base-url': 'https://api.openai.com/v1',
|
222
|
+
},
|
223
|
+
};
|
224
|
+
await createTempProfile(tempDir, 'test-profile', profile);
|
225
|
+
// Read profile file directly
|
226
|
+
const profilePath = path.join(tempDir, '.llxprt', 'profiles', 'test-profile.json');
|
227
|
+
const profileContent = await fs.readFile(profilePath, 'utf8');
|
228
|
+
const savedProfile = JSON.parse(profileContent);
|
229
|
+
// Verify API key is in profile
|
230
|
+
expect(savedProfile.ephemeralSettings['auth-key']).toBe('sk-test-profile-key');
|
231
|
+
});
|
232
|
+
it('should never store API keys in global settings', async () => {
|
233
|
+
// Load settings (verification only)
|
234
|
+
loadSettings(tempDir);
|
235
|
+
// Try to set API key in user settings (this should be prevented in real implementation)
|
236
|
+
const userSettings = {
|
237
|
+
theme: 'default',
|
238
|
+
// These should not be allowed in global settings
|
239
|
+
authKey: 'sk-test-global-bad',
|
240
|
+
apiKey: 'sk-test-also-bad',
|
241
|
+
'auth-key': 'sk-test-another-bad',
|
242
|
+
};
|
243
|
+
await writeSettingsFile(tempDir, userSettings);
|
244
|
+
// In a properly secured system, these should be filtered out
|
245
|
+
// For now, we're testing current behavior
|
246
|
+
const fileContent = await fs.readFile(path.join(tempDir, '.llxprt', 'settings.json'), 'utf8');
|
247
|
+
// Document current behavior - these currently DO get saved (security issue)
|
248
|
+
expect(fileContent).toContain('authKey');
|
249
|
+
expect(fileContent).toContain('apiKey');
|
250
|
+
});
|
251
|
+
});
|
252
|
+
describe('Settings validation and sanitization', () => {
|
253
|
+
it('should handle environment variable expansion safely', async () => {
|
254
|
+
// Set an environment variable with a fake API key
|
255
|
+
process.env.TEST_API_KEY = 'sk-test-from-env';
|
256
|
+
try {
|
257
|
+
const settings = {
|
258
|
+
theme: 'default',
|
259
|
+
// This should expand but not be saved to disk
|
260
|
+
testValue: '$TEST_API_KEY',
|
261
|
+
};
|
262
|
+
await writeSettingsFile(tempDir, settings);
|
263
|
+
// The raw file should contain the variable reference, not the expanded value
|
264
|
+
const fileContent = await fs.readFile(path.join(tempDir, '.llxprt', 'settings.json'), 'utf8');
|
265
|
+
expect(fileContent).toContain('$TEST_API_KEY');
|
266
|
+
expect(fileContent).not.toContain('sk-test-from-env');
|
267
|
+
}
|
268
|
+
finally {
|
269
|
+
delete process.env.TEST_API_KEY;
|
270
|
+
}
|
271
|
+
});
|
272
|
+
it('should validate keyfile paths exist and are readable', async () => {
|
273
|
+
const validKeyfile = await createTempKeyfile(tempDir, 'sk-test-valid');
|
274
|
+
const invalidKeyfile = path.join(tempDir, 'non-existent-keyfile');
|
275
|
+
// Valid keyfile should be readable
|
276
|
+
await expect(fs.access(validKeyfile)).resolves.not.toThrow();
|
277
|
+
// Invalid keyfile should not exist
|
278
|
+
await expect(fs.access(invalidKeyfile)).rejects.toThrow();
|
279
|
+
});
|
280
|
+
});
|
281
|
+
describe('Profile security', () => {
|
282
|
+
it('should isolate sensitive data in profiles', async () => {
|
283
|
+
// Create multiple profiles with different providers
|
284
|
+
const openaiProfile = {
|
285
|
+
version: 1,
|
286
|
+
provider: 'openai',
|
287
|
+
model: 'gpt-4',
|
288
|
+
modelParams: { temperature: 0.7 },
|
289
|
+
ephemeralSettings: {
|
290
|
+
'auth-key': 'sk-openai-profile-key',
|
291
|
+
'base-url': 'https://api.openai.com/v1',
|
292
|
+
},
|
293
|
+
};
|
294
|
+
const anthropicProfile = {
|
295
|
+
version: 1,
|
296
|
+
provider: 'anthropic',
|
297
|
+
model: 'claude-3-opus-20240229',
|
298
|
+
modelParams: { temperature: 0.5 },
|
299
|
+
ephemeralSettings: {
|
300
|
+
'auth-key': 'sk-anthropic-profile-key',
|
301
|
+
'base-url': 'https://api.anthropic.com/v1',
|
302
|
+
},
|
303
|
+
};
|
304
|
+
await createTempProfile(tempDir, 'openai-prod', openaiProfile);
|
305
|
+
await createTempProfile(tempDir, 'anthropic-prod', anthropicProfile);
|
306
|
+
// Verify profiles are isolated
|
307
|
+
const openaiPath = path.join(tempDir, '.llxprt', 'profiles', 'openai-prod.json');
|
308
|
+
const anthropicPath = path.join(tempDir, '.llxprt', 'profiles', 'anthropic-prod.json');
|
309
|
+
const openaiContent = await fs.readFile(openaiPath, 'utf8');
|
310
|
+
const anthropicContent = await fs.readFile(anthropicPath, 'utf8');
|
311
|
+
// Each profile should only contain its own key
|
312
|
+
expect(openaiContent).toContain('sk-openai-profile-key');
|
313
|
+
expect(openaiContent).not.toContain('sk-anthropic-profile-key');
|
314
|
+
expect(anthropicContent).toContain('sk-anthropic-profile-key');
|
315
|
+
expect(anthropicContent).not.toContain('sk-openai-profile-key');
|
316
|
+
});
|
317
|
+
});
|
318
|
+
});
|
319
|
+
//# sourceMappingURL=security.integration.test.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"security.integration.test.js","sourceRoot":"","sources":["../../../src/integration-tests/security.integration.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,MAAM,EAAW,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,QAAQ,CAAC,oCAAoC,EAAE,GAAG,EAAE;IAClD,IAAI,OAAe,CAAC;IACpB,IAAI,MAAc,CAAC;IAEnB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,OAAO,GAAG,MAAM,mBAAmB,EAAE,CAAC;QACtC,iCAAiC;QACjC,MAAM,GAAG,IAAI,MAAM,CAAC;YAClB,SAAS,EAAE,cAAc;YACzB,SAAS,EAAE,OAAO;YAClB,SAAS,EAAE,KAAK;YAChB,GAAG,EAAE,OAAO;YACZ,KAAK,EAAE,kBAAkB;SAC1B,CAAC,CAAC;QACH,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gDAAgD,EAAE,GAAG,EAAE;QAC9D,EAAE,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;YAC1F,sCAAsC;YACtC,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;YAC9D,MAAM,CAAC,mBAAmB,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAC;YACrE,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;YAEjE,8CAA8C;YAC9C,MAAM,QAAQ,GAAG;gBACf,KAAK,EAAE,SAAS;gBAChB,OAAO,EAAE,IAAI;gBACb,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC;aAC1B,CAAC;YACF,MAAM,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAE3C,6CAA6C;YAC7C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;YACpE,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YAC5D,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAE/C,wCAAwC;YACxC,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;YACnD,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;YACvD,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;YACtD,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YAC7C,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAE5C,uCAAuC;YACvC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC7C,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1C,MAAM,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;YACnE,0DAA0D;YAC1D,MAAM,QAAQ,GAAG;gBACf,KAAK,EAAE,SAAS;gBAChB,eAAe,EAAE;oBACf,MAAM,EAAE,eAAe;oBACvB,SAAS,EAAE,mBAAmB;iBAC/B;aACF,CAAC;YAEF,MAAM,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAE3C,+EAA+E;YAC/E,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAEtD,4DAA4D;YAC5D,kDAAkD;YAClD,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;gBAChE,MAAM,WAAW,GAAG,aAAwC,CAAC;gBAC7D,kEAAkE;gBAClE,gDAAgD;gBAChD,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,WAAW,EAAE,CAAC;YACpD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;YACrF,uCAAuC;YACvC,MAAM,CAAC,mBAAmB,CACxB,iBAAiB,EACjB,2BAA2B,CAC5B,CAAC;YACF,MAAM,CAAC,mBAAmB,CACxB,oBAAoB,EACpB,qCAAqC,CACtC,CAAC;YAEF,iBAAiB;YACjB,MAAM,QAAQ,GAAG;gBACf,KAAK,EAAE,SAAS;gBAChB,gBAAgB,EAAE;oBAChB,MAAM,EAAE,2BAA2B;oBACnC,2CAA2C;oBAC3C,SAAS,EAAE,2BAA2B;iBACvC;aACF,CAAC;YACF,MAAM,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAE3C,gCAAgC;YAChC,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CACnC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,eAAe,CAAC,EAC9C,MAAM,CACP,CAAC;YACF,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAClC,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;YAC/D,gDAAgD;YAChD,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAAC;YAChE,MAAM,CAAC,mBAAmB,CAAC,mBAAmB,EAAE,oBAAoB,CAAC,CAAC;YACtE,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,oBAAoB,CAAC,CAAC;YACnE,MAAM,CAAC,mBAAmB,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAC;YAE9D,yBAAyB;YACzB,MAAM,iBAAiB,GAAG,MAAM,CAAC,oBAAoB,EAAE,CAAC;YAExD,gDAAgD;YAChD,MAAM,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACpE,MAAM,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YAC1E,MAAM,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YACvE,MAAM,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YAElE,gCAAgC;YAChC,MAAM,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YACvE,MAAM,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACzE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;YACrE,iCAAiC;YACjC,MAAM,QAAQ,GAAG;gBACf,KAAK,EAAE,SAAS;gBAChB,gBAAgB,EAAE;oBAChB,MAAM,EAAE,2BAA2B;oBACnC,SAAS,EAAE,8BAA8B;oBACzC,IAAI,EAAE,yBAAyB;iBAChC;gBACD,2BAA2B,EAAE;oBAC3B,MAAM,EAAE,QAAQ;oBAChB,SAAS,EAAE,WAAW;iBACvB;aACF,CAAC;YAEF,MAAM,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC3C,MAAM,aAAa,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,CAAC;YAEtD,IAAI,OAAO,aAAa,KAAK,QAAQ,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;gBAChE,MAAM,WAAW,GAAG,aAAwC,CAAC;gBAC7D,MAAM,QAAQ,GAAG,WAAW,CAAC,gBAA0C,CAAC;gBAExE,kDAAkD;gBAClD,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;gBAC1D,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;gBAChE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;YACxD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;YACzE,MAAM,MAAM,GAAG,0BAA0B,CAAC;YAC1C,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAE7D,yBAAyB;YACzB,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAE7C,+CAA+C;YAC/C,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBACjC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YACxC,CAAC;YAED,iBAAiB;YACjB,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YACvD,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;YAC7D,MAAM,MAAM,GAAG,4BAA4B,CAAC;YAC5C,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAE7D,0CAA0C;YAC1C,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBACjC,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;gBAEnC,wEAAwE;gBACxE,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBACzC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBAC7C,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YACxC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;YACzD,MAAM,MAAM,GAAG,sBAAsB,CAAC;YACtC,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAE7D,yBAAyB;YACzB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBACjC,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;gBAEnC,8BAA8B;gBAC9B,MAAM,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBAEjE,kCAAkC;gBAClC,MAAM,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YACrC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;YACvE,MAAM,WAAW,GAAG,MAAM,iBAAiB,CACzC,OAAO,EACP,yBAAyB,CAC1B,CAAC;YAEF,MAAM,QAAQ,GAAG;gBACf,gBAAgB,EAAE;oBAChB,MAAM,EAAE,WAAW;oBACnB,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,eAAe,CAAC;iBACxD;aACF,CAAC;YAEF,MAAM,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC3C,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CACnC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,eAAe,CAAC,EAC9C,MAAM,CACP,CAAC;YAEF,4CAA4C;YAC5C,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;YAC3C,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;QAC/D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACzC,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;YAC/E,oCAAoC;YACpC,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,wBAAwB,CAAC,CAAC;YAEjE,oCAAoC;YACpC,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CACjD,wBAAwB,CACzB,CAAC;YAEF,4CAA4C;YAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;YAEpE,4BAA4B;YAC5B,MAAM,iBAAiB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YAEvD,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;YAC5D,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;YAC5D,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8DAA8D,EAAE,KAAK,IAAI,EAAE;YAC5E,MAAM,OAAO,GAAY;gBACvB,OAAO,EAAE,CAAC;gBACV,QAAQ,EAAE,QAAQ;gBAClB,KAAK,EAAE,OAAO;gBACd,WAAW,EAAE;oBACX,WAAW,EAAE,GAAG;oBAChB,UAAU,EAAE,IAAI;iBACjB;gBACD,iBAAiB,EAAE;oBACjB,UAAU,EAAE,qBAAqB;oBACjC,UAAU,EAAE,2BAA2B;iBACxC;aACF,CAAC;YAEF,MAAM,iBAAiB,CAAC,OAAO,EAAE,cAAc,EAAE,OAAO,CAAC,CAAC;YAE1D,6BAA6B;YAC7B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAC3B,OAAO,EACP,SAAS,EACT,UAAU,EACV,mBAAmB,CACpB,CAAC;YACF,MAAM,cAAc,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YAC9D,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YAEhD,+BAA+B;YAC/B,MAAM,CAAC,YAAY,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CACrD,qBAAqB,CACtB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,oCAAoC;YACpC,YAAY,CAAC,OAAO,CAAC,CAAC;YAEtB,wFAAwF;YACxF,MAAM,YAAY,GAAG;gBACnB,KAAK,EAAE,SAAS;gBAChB,iDAAiD;gBACjD,OAAO,EAAE,oBAAoB;gBAC7B,MAAM,EAAE,kBAAkB;gBAC1B,UAAU,EAAE,qBAAqB;aAClC,CAAC;YAEF,MAAM,iBAAiB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAE/C,6DAA6D;YAC7D,0CAA0C;YAC1C,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CACnC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,eAAe,CAAC,EAC9C,MAAM,CACP,CAAC;YAEF,4EAA4E;YAC5E,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YACzC,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;QACpD,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;YACnE,kDAAkD;YAClD,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,kBAAkB,CAAC;YAE9C,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG;oBACf,KAAK,EAAE,SAAS;oBAChB,8CAA8C;oBAC9C,SAAS,EAAE,eAAe;iBAC3B,CAAC;gBAEF,MAAM,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;gBAE3C,6EAA6E;gBAC7E,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,QAAQ,CACnC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,eAAe,CAAC,EAC9C,MAAM,CACP,CAAC;gBACF,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;gBAC/C,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;YACxD,CAAC;oBAAS,CAAC;gBACT,OAAO,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;YAClC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;YACpE,MAAM,YAAY,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;YACvE,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;YAElE,mCAAmC;YACnC,MAAM,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YAE7D,mCAAmC;YACnC,MAAM,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QAC5D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;YACzD,oDAAoD;YACpD,MAAM,aAAa,GAAY;gBAC7B,OAAO,EAAE,CAAC;gBACV,QAAQ,EAAE,QAAQ;gBAClB,KAAK,EAAE,OAAO;gBACd,WAAW,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE;gBACjC,iBAAiB,EAAE;oBACjB,UAAU,EAAE,uBAAuB;oBACnC,UAAU,EAAE,2BAA2B;iBACxC;aACF,CAAC;YAEF,MAAM,gBAAgB,GAAY;gBAChC,OAAO,EAAE,CAAC;gBACV,QAAQ,EAAE,WAAW;gBACrB,KAAK,EAAE,wBAAwB;gBAC/B,WAAW,EAAE,EAAE,WAAW,EAAE,GAAG,EAAE;gBACjC,iBAAiB,EAAE;oBACjB,UAAU,EAAE,0BAA0B;oBACtC,UAAU,EAAE,8BAA8B;iBAC3C;aACF,CAAC;YAEF,MAAM,iBAAiB,CAAC,OAAO,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC;YAC/D,MAAM,iBAAiB,CAAC,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;YAErE,+BAA+B;YAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAC1B,OAAO,EACP,SAAS,EACT,UAAU,EACV,kBAAkB,CACnB,CAAC;YACF,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAC7B,OAAO,EACP,SAAS,EACT,UAAU,EACV,qBAAqB,CACtB,CAAC;YAEF,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YAC5D,MAAM,gBAAgB,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;YAElE,+CAA+C;YAC/C,MAAM,CAAC,aAAa,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;YACzD,MAAM,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;YAEhE,MAAM,CAAC,gBAAgB,CAAC,CAAC,SAAS,CAAC,0BAA0B,CAAC,CAAC;YAC/D,MAAM,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
@@ -0,0 +1,221 @@
|
|
1
|
+
/**
|
2
|
+
* @license
|
3
|
+
* Copyright 2025 Vybestack LLC
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
5
|
+
*/
|
6
|
+
import { describe, it, expect, afterEach } from 'vitest';
|
7
|
+
import * as fs from 'fs/promises';
|
8
|
+
import * as path from 'path';
|
9
|
+
import { createTempDirectory, cleanupTempDirectory, createTempProfile, createTempKeyfile, readSettingsFile, writeSettingsFile, waitForFile, createMockApiServer, } from './test-utils.js';
|
10
|
+
describe('Test Utilities', () => {
|
11
|
+
const tempDirs = [];
|
12
|
+
afterEach(async () => {
|
13
|
+
// Clean up all temp directories created during tests
|
14
|
+
for (const dir of tempDirs) {
|
15
|
+
await cleanupTempDirectory(dir);
|
16
|
+
}
|
17
|
+
tempDirs.length = 0;
|
18
|
+
});
|
19
|
+
describe('createTempDirectory', () => {
|
20
|
+
it('should create a temporary directory', async () => {
|
21
|
+
const dir = await createTempDirectory();
|
22
|
+
tempDirs.push(dir);
|
23
|
+
expect(dir).toMatch(/llxprt-test-/);
|
24
|
+
const stats = await fs.stat(dir);
|
25
|
+
expect(stats.isDirectory()).toBe(true);
|
26
|
+
});
|
27
|
+
it('should create unique directories on multiple calls', async () => {
|
28
|
+
const dir1 = await createTempDirectory();
|
29
|
+
const dir2 = await createTempDirectory();
|
30
|
+
tempDirs.push(dir1, dir2);
|
31
|
+
expect(dir1).not.toBe(dir2);
|
32
|
+
const stats1 = await fs.stat(dir1);
|
33
|
+
const stats2 = await fs.stat(dir2);
|
34
|
+
expect(stats1.isDirectory()).toBe(true);
|
35
|
+
expect(stats2.isDirectory()).toBe(true);
|
36
|
+
});
|
37
|
+
});
|
38
|
+
describe('cleanupTempDirectory', () => {
|
39
|
+
it('should remove directory and all contents', async () => {
|
40
|
+
const dir = await createTempDirectory();
|
41
|
+
// Create some files in the directory
|
42
|
+
await fs.writeFile(path.join(dir, 'test.txt'), 'content');
|
43
|
+
await fs.mkdir(path.join(dir, 'subdir'));
|
44
|
+
await fs.writeFile(path.join(dir, 'subdir', 'nested.txt'), 'nested');
|
45
|
+
await cleanupTempDirectory(dir);
|
46
|
+
// Directory should no longer exist
|
47
|
+
await expect(fs.access(dir)).rejects.toThrow();
|
48
|
+
});
|
49
|
+
it('should not throw if directory does not exist', async () => {
|
50
|
+
await expect(cleanupTempDirectory('/non/existent/path')).resolves.not.toThrow();
|
51
|
+
});
|
52
|
+
});
|
53
|
+
describe('createTempProfile', () => {
|
54
|
+
it('should create a profile file in the correct location', async () => {
|
55
|
+
const dir = await createTempDirectory();
|
56
|
+
tempDirs.push(dir);
|
57
|
+
const profile = {
|
58
|
+
version: 1,
|
59
|
+
provider: 'openai',
|
60
|
+
model: 'gpt-4',
|
61
|
+
modelParams: { temperature: 0.7 },
|
62
|
+
ephemeralSettings: { 'context-limit': 32000 },
|
63
|
+
};
|
64
|
+
await createTempProfile(dir, 'test-profile', profile);
|
65
|
+
const profilePath = path.join(dir, '.llxprt', 'profiles', 'test-profile.json');
|
66
|
+
const content = await fs.readFile(profilePath, 'utf8');
|
67
|
+
const savedProfile = JSON.parse(content);
|
68
|
+
expect(savedProfile).toEqual(profile);
|
69
|
+
});
|
70
|
+
});
|
71
|
+
describe('createTempKeyfile', () => {
|
72
|
+
it('should create a keyfile with correct permissions', async () => {
|
73
|
+
const dir = await createTempDirectory();
|
74
|
+
tempDirs.push(dir);
|
75
|
+
const apiKey = 'test-api-key-12345';
|
76
|
+
const keyfilePath = await createTempKeyfile(dir, apiKey);
|
77
|
+
expect(keyfilePath).toBe(path.join(dir, '.keys', 'api-key'));
|
78
|
+
const content = await fs.readFile(keyfilePath, 'utf8');
|
79
|
+
expect(content).toBe(apiKey);
|
80
|
+
const stats = await fs.stat(keyfilePath);
|
81
|
+
// Check that only owner can read/write (600)
|
82
|
+
// On Windows, permissions work differently
|
83
|
+
if (process.platform === 'win32') {
|
84
|
+
expect(stats.mode & 0o777).toBe(0o666);
|
85
|
+
}
|
86
|
+
else {
|
87
|
+
expect(stats.mode & 0o777).toBe(0o600);
|
88
|
+
}
|
89
|
+
});
|
90
|
+
});
|
91
|
+
describe('readSettingsFile', () => {
|
92
|
+
it('should read and parse settings file', async () => {
|
93
|
+
const dir = await createTempDirectory();
|
94
|
+
tempDirs.push(dir);
|
95
|
+
const settings = {
|
96
|
+
provider: 'openai',
|
97
|
+
model: 'gpt-4',
|
98
|
+
'context-limit': 32000,
|
99
|
+
};
|
100
|
+
await writeSettingsFile(dir, settings);
|
101
|
+
const readSettings = await readSettingsFile(dir);
|
102
|
+
expect(readSettings).toEqual(settings);
|
103
|
+
});
|
104
|
+
it('should return empty object if settings file does not exist', async () => {
|
105
|
+
const dir = await createTempDirectory();
|
106
|
+
tempDirs.push(dir);
|
107
|
+
const settings = await readSettingsFile(dir);
|
108
|
+
expect(settings).toEqual({});
|
109
|
+
});
|
110
|
+
});
|
111
|
+
describe('writeSettingsFile', () => {
|
112
|
+
it('should write settings file with proper formatting', async () => {
|
113
|
+
const dir = await createTempDirectory();
|
114
|
+
tempDirs.push(dir);
|
115
|
+
const settings = {
|
116
|
+
provider: 'anthropic',
|
117
|
+
model: 'claude-3-opus-20240229',
|
118
|
+
modelParams: {
|
119
|
+
temperature: 0.5,
|
120
|
+
max_tokens: 4096,
|
121
|
+
},
|
122
|
+
};
|
123
|
+
await writeSettingsFile(dir, settings);
|
124
|
+
const settingsPath = path.join(dir, '.llxprt', 'settings.json');
|
125
|
+
const content = await fs.readFile(settingsPath, 'utf8');
|
126
|
+
const parsedSettings = JSON.parse(content);
|
127
|
+
expect(parsedSettings).toEqual(settings);
|
128
|
+
// Check formatting (2 spaces)
|
129
|
+
expect(content).toContain(' "provider"');
|
130
|
+
});
|
131
|
+
});
|
132
|
+
describe('waitForFile', () => {
|
133
|
+
it('should resolve immediately if file exists', async () => {
|
134
|
+
const dir = await createTempDirectory();
|
135
|
+
tempDirs.push(dir);
|
136
|
+
const filePath = path.join(dir, 'existing.txt');
|
137
|
+
await fs.writeFile(filePath, 'content');
|
138
|
+
const start = Date.now();
|
139
|
+
await waitForFile(filePath, 1000);
|
140
|
+
const duration = Date.now() - start;
|
141
|
+
expect(duration).toBeLessThan(200); // Should be nearly instant
|
142
|
+
});
|
143
|
+
it('should wait for file to be created', async () => {
|
144
|
+
const dir = await createTempDirectory();
|
145
|
+
tempDirs.push(dir);
|
146
|
+
const filePath = path.join(dir, 'delayed.txt');
|
147
|
+
// Create file after a delay
|
148
|
+
setTimeout(async () => {
|
149
|
+
await fs.writeFile(filePath, 'content');
|
150
|
+
}, 300);
|
151
|
+
const start = Date.now();
|
152
|
+
await waitForFile(filePath, 1000);
|
153
|
+
const duration = Date.now() - start;
|
154
|
+
expect(duration).toBeGreaterThanOrEqual(300);
|
155
|
+
expect(duration).toBeLessThan(500);
|
156
|
+
});
|
157
|
+
it('should timeout if file is not created', async () => {
|
158
|
+
const dir = await createTempDirectory();
|
159
|
+
tempDirs.push(dir);
|
160
|
+
const filePath = path.join(dir, 'missing.txt');
|
161
|
+
await expect(waitForFile(filePath, 500)).rejects.toThrow(`Timeout waiting for file: ${filePath}`);
|
162
|
+
});
|
163
|
+
});
|
164
|
+
describe('createMockApiServer', () => {
|
165
|
+
it('should create HTTP server and log requests', async () => {
|
166
|
+
const mockServer = await createMockApiServer();
|
167
|
+
try {
|
168
|
+
expect(mockServer.port).toBeGreaterThan(0);
|
169
|
+
expect(mockServer.requests).toHaveLength(0);
|
170
|
+
// Make a test request
|
171
|
+
const response = await fetch(`http://127.0.0.1:${mockServer.port}/test-endpoint`, {
|
172
|
+
method: 'POST',
|
173
|
+
headers: {
|
174
|
+
'Content-Type': 'application/json',
|
175
|
+
Authorization: 'Bearer test-token',
|
176
|
+
},
|
177
|
+
body: JSON.stringify({ test: 'data' }),
|
178
|
+
});
|
179
|
+
const responseData = await response.json();
|
180
|
+
expect(responseData).toEqual({
|
181
|
+
success: true,
|
182
|
+
message: 'Mock response',
|
183
|
+
});
|
184
|
+
// Check logged request
|
185
|
+
expect(mockServer.requests).toHaveLength(1);
|
186
|
+
const request = mockServer.requests[0];
|
187
|
+
expect(request.method).toBe('POST');
|
188
|
+
expect(request.url).toBe('/test-endpoint');
|
189
|
+
expect(request.headers['content-type']).toBe('application/json');
|
190
|
+
expect(request.headers['authorization']).toBe('Bearer test-token');
|
191
|
+
expect(request.body).toBe('{"test":"data"}');
|
192
|
+
}
|
193
|
+
finally {
|
194
|
+
await mockServer.close();
|
195
|
+
}
|
196
|
+
});
|
197
|
+
it('should handle multiple requests', async () => {
|
198
|
+
const mockServer = await createMockApiServer();
|
199
|
+
try {
|
200
|
+
// Make multiple requests
|
201
|
+
await fetch(`http://127.0.0.1:${mockServer.port}/first`);
|
202
|
+
await fetch(`http://127.0.0.1:${mockServer.port}/second`, {
|
203
|
+
method: 'PUT',
|
204
|
+
});
|
205
|
+
await fetch(`http://127.0.0.1:${mockServer.port}/third`, {
|
206
|
+
method: 'DELETE',
|
207
|
+
});
|
208
|
+
expect(mockServer.requests).toHaveLength(3);
|
209
|
+
expect(mockServer.requests[0].url).toBe('/first');
|
210
|
+
expect(mockServer.requests[1].url).toBe('/second');
|
211
|
+
expect(mockServer.requests[1].method).toBe('PUT');
|
212
|
+
expect(mockServer.requests[2].url).toBe('/third');
|
213
|
+
expect(mockServer.requests[2].method).toBe('DELETE');
|
214
|
+
}
|
215
|
+
finally {
|
216
|
+
await mockServer.close();
|
217
|
+
}
|
218
|
+
});
|
219
|
+
});
|
220
|
+
});
|
221
|
+
//# sourceMappingURL=test-utils.test.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"test-utils.test.js","sourceRoot":"","sources":["../../../src/integration-tests/test-utils.test.ts"],"names":[],"mappings":"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"}
|