fss-link 1.0.49 → 1.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +0 -0
- package/dist/package.json +2 -2
- package/dist/src/config/auth.js +8 -5
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/database.d.ts +103 -11
- package/dist/src/config/database.js +301 -59
- package/dist/src/config/database.js.map +1 -1
- package/dist/src/config/databaseBackup.d.ts +114 -0
- package/dist/src/config/databaseBackup.js +334 -0
- package/dist/src/config/databaseBackup.js.map +1 -0
- package/dist/src/config/databaseMigrations.d.ts +63 -0
- package/dist/src/config/databaseMigrations.js +379 -0
- package/dist/src/config/databaseMigrations.js.map +1 -0
- package/dist/src/config/databasePool.d.ts +70 -0
- package/dist/src/config/databasePool.js +193 -0
- package/dist/src/config/databasePool.js.map +1 -0
- package/dist/src/config/queryOptimizer.d.ts +127 -0
- package/dist/src/config/queryOptimizer.js +309 -0
- package/dist/src/config/queryOptimizer.js.map +1 -0
- package/dist/src/utils/sandbox.js +2 -8
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.js +3 -7
- package/dist/src/validateNonInterActiveAuth.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/dist/commands/mcp/add.test.ts +0 -122
- package/dist/commands/mcp/add.ts +0 -222
- package/dist/commands/mcp/list.test.ts +0 -154
- package/dist/commands/mcp/list.ts +0 -139
- package/dist/commands/mcp/remove.test.ts +0 -69
- package/dist/commands/mcp/remove.ts +0 -60
- package/dist/commands/mcp.test.ts +0 -55
- package/dist/commands/mcp.ts +0 -27
- package/dist/config/apiValidation.test.ts +0 -118
- package/dist/config/auth.test.ts +0 -79
- package/dist/config/auth.ts +0 -100
- package/dist/config/config.integration.test.ts +0 -407
- package/dist/config/config.test.ts +0 -1952
- package/dist/config/config.ts +0 -690
- package/dist/config/database.test.ts +0 -96
- package/dist/config/database.ts +0 -824
- package/dist/config/extension.test.ts +0 -236
- package/dist/config/extension.ts +0 -180
- package/dist/config/keyBindings.test.ts +0 -62
- package/dist/config/keyBindings.ts +0 -184
- package/dist/config/modelManager.ts +0 -326
- package/dist/config/providerManager.ts +0 -244
- package/dist/config/providerPersistence.test.ts +0 -377
- package/dist/config/providerPersistence.ts +0 -105
- package/dist/config/sandboxConfig.ts +0 -107
- package/dist/config/settings.test.ts +0 -1424
- package/dist/config/settings.ts +0 -517
- package/dist/config/settingsSchema.test.ts +0 -252
- package/dist/config/settingsSchema.ts +0 -728
- package/dist/config/trustedFolders.test.ts +0 -208
- package/dist/config/trustedFolders.ts +0 -167
- package/dist/gemini.test.tsx +0 -252
- package/dist/gemini.tsx +0 -357
- package/dist/generated/git-commit.ts +0 -10
- package/dist/index.ts +0 -21
- package/dist/nonInteractiveCli.test.ts +0 -276
- package/dist/nonInteractiveCli.ts +0 -143
- package/dist/patches/is-in-ci.ts +0 -17
- package/dist/services/BuiltinCommandLoader.test.ts +0 -127
- package/dist/services/BuiltinCommandLoader.ts +0 -95
- package/dist/services/CommandService.test.ts +0 -352
- package/dist/services/CommandService.ts +0 -103
- package/dist/services/FileCommandLoader.test.ts +0 -1002
- package/dist/services/FileCommandLoader.ts +0 -289
- package/dist/services/McpPromptLoader.ts +0 -231
- package/dist/services/SearchEngineConfigProvider.ts +0 -100
- package/dist/services/prompt-processors/argumentProcessor.test.ts +0 -41
- package/dist/services/prompt-processors/argumentProcessor.ts +0 -23
- package/dist/services/prompt-processors/shellProcessor.test.ts +0 -709
- package/dist/services/prompt-processors/shellProcessor.ts +0 -248
- package/dist/services/prompt-processors/types.ts +0 -44
- package/dist/services/types.ts +0 -24
- package/dist/src/config/apiValidation.test.d.ts +0 -6
- package/dist/src/config/apiValidation.test.js +0 -99
- package/dist/src/config/apiValidation.test.js.map +0 -1
- package/dist/src/config/database.test.d.ts +0 -6
- package/dist/src/config/database.test.js +0 -80
- package/dist/src/config/database.test.js.map +0 -1
- package/dist/src/config/providerManager.d.ts +0 -74
- package/dist/src/config/providerManager.js +0 -203
- package/dist/src/config/providerManager.js.map +0 -1
- package/dist/src/config/providerPersistence.test.d.ts +0 -6
- package/dist/src/config/providerPersistence.test.js +0 -283
- package/dist/src/config/providerPersistence.test.js.map +0 -1
- package/dist/src/ui/components/GeminiKeyDialog.d.ts +0 -11
- package/dist/src/ui/components/GeminiKeyDialog.js +0 -156
- package/dist/src/ui/components/GeminiKeyDialog.js.map +0 -1
- package/dist/src/ui/components/OpenAIEndpointDialog.d.ts +0 -19
- package/dist/src/ui/components/OpenAIEndpointDialog.js +0 -163
- package/dist/src/ui/components/OpenAIEndpointDialog.js.map +0 -1
- package/dist/test-setup.ts +0 -12
- package/dist/test-utils/customMatchers.ts +0 -65
- package/dist/test-utils/mockCommandContext.test.ts +0 -62
- package/dist/test-utils/mockCommandContext.ts +0 -105
- package/dist/test-utils/render.tsx +0 -18
- package/dist/ui/App.test.tsx +0 -2181
- package/dist/ui/App.tsx +0 -1344
- package/dist/ui/IdeIntegrationNudge.tsx +0 -98
- package/dist/ui/__snapshots__/App.test.tsx.snap +0 -124
- package/dist/ui/colors.ts +0 -56
- package/dist/ui/commands/aboutCommand.test.ts +0 -153
- package/dist/ui/commands/aboutCommand.ts +0 -49
- package/dist/ui/commands/authCommand.test.ts +0 -36
- package/dist/ui/commands/authCommand.ts +0 -17
- package/dist/ui/commands/bugCommand.test.ts +0 -114
- package/dist/ui/commands/bugCommand.ts +0 -92
- package/dist/ui/commands/chatCommand.test.ts +0 -414
- package/dist/ui/commands/chatCommand.ts +0 -280
- package/dist/ui/commands/clearCommand.test.ts +0 -100
- package/dist/ui/commands/clearCommand.ts +0 -29
- package/dist/ui/commands/compressCommand.test.ts +0 -129
- package/dist/ui/commands/compressCommand.ts +0 -78
- package/dist/ui/commands/contextCommand.ts +0 -132
- package/dist/ui/commands/copyCommand.test.ts +0 -296
- package/dist/ui/commands/copyCommand.ts +0 -67
- package/dist/ui/commands/corgiCommand.test.ts +0 -34
- package/dist/ui/commands/corgiCommand.ts +0 -16
- package/dist/ui/commands/directoryCommand.test.tsx +0 -185
- package/dist/ui/commands/directoryCommand.tsx +0 -179
- package/dist/ui/commands/docsCommand.test.ts +0 -99
- package/dist/ui/commands/docsCommand.ts +0 -42
- package/dist/ui/commands/editorCommand.test.ts +0 -30
- package/dist/ui/commands/editorCommand.ts +0 -21
- package/dist/ui/commands/extensionsCommand.test.ts +0 -67
- package/dist/ui/commands/extensionsCommand.ts +0 -46
- package/dist/ui/commands/helpCommand.test.ts +0 -52
- package/dist/ui/commands/helpCommand.ts +0 -23
- package/dist/ui/commands/ideCommand.test.ts +0 -255
- package/dist/ui/commands/ideCommand.ts +0 -283
- package/dist/ui/commands/initCommand.test.ts +0 -127
- package/dist/ui/commands/initCommand.ts +0 -117
- package/dist/ui/commands/mcpCommand.test.ts +0 -1057
- package/dist/ui/commands/mcpCommand.ts +0 -531
- package/dist/ui/commands/memoryCommand.test.ts +0 -344
- package/dist/ui/commands/memoryCommand.ts +0 -305
- package/dist/ui/commands/privacyCommand.test.ts +0 -38
- package/dist/ui/commands/privacyCommand.ts +0 -17
- package/dist/ui/commands/quitCommand.test.ts +0 -55
- package/dist/ui/commands/quitCommand.ts +0 -36
- package/dist/ui/commands/restoreCommand.test.ts +0 -250
- package/dist/ui/commands/restoreCommand.ts +0 -157
- package/dist/ui/commands/searchEngineSetupCommand.ts +0 -18
- package/dist/ui/commands/settingsCommand.test.ts +0 -36
- package/dist/ui/commands/settingsCommand.ts +0 -17
- package/dist/ui/commands/setupGithubCommand.test.ts +0 -238
- package/dist/ui/commands/setupGithubCommand.ts +0 -212
- package/dist/ui/commands/speakCommand.ts +0 -175
- package/dist/ui/commands/statsCommand.test.ts +0 -78
- package/dist/ui/commands/statsCommand.ts +0 -70
- package/dist/ui/commands/terminalSetupCommand.test.ts +0 -85
- package/dist/ui/commands/terminalSetupCommand.ts +0 -45
- package/dist/ui/commands/themeCommand.test.ts +0 -38
- package/dist/ui/commands/themeCommand.ts +0 -17
- package/dist/ui/commands/toolsCommand.test.ts +0 -105
- package/dist/ui/commands/toolsCommand.ts +0 -71
- package/dist/ui/commands/ttsCommand.ts +0 -143
- package/dist/ui/commands/types.ts +0 -204
- package/dist/ui/commands/vimCommand.ts +0 -25
- package/dist/ui/commands/voiceCommand.ts +0 -125
- package/dist/ui/components/AboutBox.tsx +0 -133
- package/dist/ui/components/AsciiArt.ts +0 -54
- package/dist/ui/components/AuthDialog.test.tsx +0 -334
- package/dist/ui/components/AuthDialog.tsx +0 -289
- package/dist/ui/components/AuthInProgress.tsx +0 -62
- package/dist/ui/components/AutoAcceptIndicator.tsx +0 -47
- package/dist/ui/components/ConsoleSummaryDisplay.tsx +0 -35
- package/dist/ui/components/ContextSummaryDisplay.test.tsx +0 -85
- package/dist/ui/components/ContextSummaryDisplay.tsx +0 -120
- package/dist/ui/components/ContextUsageDisplay.tsx +0 -77
- package/dist/ui/components/DebugProfiler.tsx +0 -36
- package/dist/ui/components/DetailedMessagesDisplay.tsx +0 -82
- package/dist/ui/components/EditorSettingsDialog.tsx +0 -172
- package/dist/ui/components/FolderTrustDialog.test.tsx +0 -36
- package/dist/ui/components/FolderTrustDialog.tsx +0 -74
- package/dist/ui/components/Footer.test.tsx +0 -159
- package/dist/ui/components/Footer.tsx +0 -158
- package/dist/ui/components/GeminiKeyDialog.tsx +0 -252
- package/dist/ui/components/GeminiRespondingSpinner.tsx +0 -34
- package/dist/ui/components/Header.test.tsx +0 -44
- package/dist/ui/components/Header.tsx +0 -70
- package/dist/ui/components/Help.tsx +0 -174
- package/dist/ui/components/HistoryItemDisplay.test.tsx +0 -125
- package/dist/ui/components/HistoryItemDisplay.tsx +0 -98
- package/dist/ui/components/InputPrompt.test.tsx +0 -1467
- package/dist/ui/components/InputPrompt.tsx +0 -641
- package/dist/ui/components/LMStudioModelPrompt.tsx +0 -215
- package/dist/ui/components/LoadingIndicator.test.tsx +0 -296
- package/dist/ui/components/LoadingIndicator.tsx +0 -82
- package/dist/ui/components/MemoryUsageDisplay.tsx +0 -36
- package/dist/ui/components/ModelStatsDisplay.test.tsx +0 -252
- package/dist/ui/components/ModelStatsDisplay.tsx +0 -197
- package/dist/ui/components/OllamaModelPrompt.tsx +0 -206
- package/dist/ui/components/OpenAIEndpointDialog.tsx +0 -261
- package/dist/ui/components/OpenAIKeyPrompt.test.tsx +0 -64
- package/dist/ui/components/OpenAIKeyPrompt.tsx +0 -197
- package/dist/ui/components/PrepareLabel.tsx +0 -48
- package/dist/ui/components/SearchEngineConfigDialog.tsx +0 -280
- package/dist/ui/components/SessionSummaryDisplay.test.tsx +0 -75
- package/dist/ui/components/SessionSummaryDisplay.tsx +0 -18
- package/dist/ui/components/SettingsDialog.test.tsx +0 -865
- package/dist/ui/components/SettingsDialog.tsx +0 -753
- package/dist/ui/components/ShellConfirmationDialog.test.tsx +0 -53
- package/dist/ui/components/ShellConfirmationDialog.tsx +0 -103
- package/dist/ui/components/ShellModeIndicator.tsx +0 -18
- package/dist/ui/components/ShowMoreLines.tsx +0 -40
- package/dist/ui/components/StatsDisplay.test.tsx +0 -401
- package/dist/ui/components/StatsDisplay.tsx +0 -273
- package/dist/ui/components/SuggestionsDisplay.tsx +0 -102
- package/dist/ui/components/ThemeDialog.tsx +0 -310
- package/dist/ui/components/Tips.tsx +0 -45
- package/dist/ui/components/TodoDisplay.test.tsx +0 -97
- package/dist/ui/components/TodoDisplay.tsx +0 -72
- package/dist/ui/components/ToolStatsDisplay.test.tsx +0 -180
- package/dist/ui/components/ToolStatsDisplay.tsx +0 -208
- package/dist/ui/components/UpdateNotification.tsx +0 -23
- package/dist/ui/components/WelcomeBackDialog.tsx +0 -290
- package/dist/ui/components/__snapshots__/IDEContextDetailDisplay.test.tsx.snap +0 -24
- package/dist/ui/components/__snapshots__/ModelStatsDisplay.test.tsx.snap +0 -121
- package/dist/ui/components/__snapshots__/SessionSummaryDisplay.test.tsx.snap +0 -30
- package/dist/ui/components/__snapshots__/ShellConfirmationDialog.test.tsx.snap +0 -21
- package/dist/ui/components/__snapshots__/StatsDisplay.test.tsx.snap +0 -264
- package/dist/ui/components/__snapshots__/ToolStatsDisplay.test.tsx.snap +0 -91
- package/dist/ui/components/messages/CompressionMessage.tsx +0 -49
- package/dist/ui/components/messages/DiffRenderer.test.tsx +0 -365
- package/dist/ui/components/messages/DiffRenderer.tsx +0 -358
- package/dist/ui/components/messages/ErrorMessage.tsx +0 -31
- package/dist/ui/components/messages/GeminiMessage.tsx +0 -43
- package/dist/ui/components/messages/GeminiMessageContent.tsx +0 -43
- package/dist/ui/components/messages/InfoMessage.tsx +0 -32
- package/dist/ui/components/messages/ToolConfirmationMessage.test.tsx +0 -58
- package/dist/ui/components/messages/ToolConfirmationMessage.tsx +0 -297
- package/dist/ui/components/messages/ToolGroupMessage.tsx +0 -126
- package/dist/ui/components/messages/ToolMessage.test.tsx +0 -183
- package/dist/ui/components/messages/ToolMessage.tsx +0 -296
- package/dist/ui/components/messages/UserMessage.tsx +0 -43
- package/dist/ui/components/messages/UserShellMessage.tsx +0 -25
- package/dist/ui/components/shared/MaxSizedBox.test.tsx +0 -425
- package/dist/ui/components/shared/MaxSizedBox.tsx +0 -624
- package/dist/ui/components/shared/RadioButtonSelect.test.tsx +0 -181
- package/dist/ui/components/shared/RadioButtonSelect.tsx +0 -234
- package/dist/ui/components/shared/__snapshots__/RadioButtonSelect.test.tsx.snap +0 -47
- package/dist/ui/components/shared/text-buffer.test.ts +0 -1728
- package/dist/ui/components/shared/text-buffer.ts +0 -2227
- package/dist/ui/components/shared/vim-buffer-actions.test.ts +0 -1119
- package/dist/ui/components/shared/vim-buffer-actions.ts +0 -814
- package/dist/ui/constants.ts +0 -17
- package/dist/ui/contexts/KeypressContext.test.tsx +0 -391
- package/dist/ui/contexts/KeypressContext.tsx +0 -440
- package/dist/ui/contexts/OverflowContext.tsx +0 -87
- package/dist/ui/contexts/SessionContext.test.tsx +0 -132
- package/dist/ui/contexts/SessionContext.tsx +0 -143
- package/dist/ui/contexts/SettingsContext.tsx +0 -20
- package/dist/ui/contexts/StreamingContext.tsx +0 -22
- package/dist/ui/contexts/VimModeContext.tsx +0 -79
- package/dist/ui/editors/editorSettingsManager.ts +0 -66
- package/dist/ui/hooks/atCommandProcessor.test.ts +0 -1102
- package/dist/ui/hooks/atCommandProcessor.ts +0 -485
- package/dist/ui/hooks/shellCommandProcessor.test.ts +0 -481
- package/dist/ui/hooks/shellCommandProcessor.ts +0 -314
- package/dist/ui/hooks/slashCommandProcessor.test.ts +0 -1044
- package/dist/ui/hooks/slashCommandProcessor.ts +0 -595
- package/dist/ui/hooks/useAtCompletion.test.ts +0 -497
- package/dist/ui/hooks/useAtCompletion.ts +0 -244
- package/dist/ui/hooks/useAuthCommand.ts +0 -129
- package/dist/ui/hooks/useAutoAcceptIndicator.test.ts +0 -300
- package/dist/ui/hooks/useAutoAcceptIndicator.ts +0 -52
- package/dist/ui/hooks/useBracketedPaste.ts +0 -37
- package/dist/ui/hooks/useCommandCompletion.test.ts +0 -518
- package/dist/ui/hooks/useCommandCompletion.tsx +0 -238
- package/dist/ui/hooks/useCompletion.ts +0 -128
- package/dist/ui/hooks/useConsoleMessages.test.ts +0 -147
- package/dist/ui/hooks/useConsoleMessages.ts +0 -110
- package/dist/ui/hooks/useEditorSettings.test.ts +0 -283
- package/dist/ui/hooks/useEditorSettings.ts +0 -75
- package/dist/ui/hooks/useFocus.test.ts +0 -119
- package/dist/ui/hooks/useFocus.ts +0 -48
- package/dist/ui/hooks/useFolderTrust.test.ts +0 -159
- package/dist/ui/hooks/useFolderTrust.ts +0 -72
- package/dist/ui/hooks/useGeminiStream.test.tsx +0 -1998
- package/dist/ui/hooks/useGeminiStream.ts +0 -1017
- package/dist/ui/hooks/useGitBranchName.test.ts +0 -280
- package/dist/ui/hooks/useGitBranchName.ts +0 -79
- package/dist/ui/hooks/useHistoryManager.test.ts +0 -202
- package/dist/ui/hooks/useHistoryManager.ts +0 -111
- package/dist/ui/hooks/useInputHistory.test.ts +0 -261
- package/dist/ui/hooks/useInputHistory.ts +0 -111
- package/dist/ui/hooks/useKeypress.test.ts +0 -280
- package/dist/ui/hooks/useKeypress.ts +0 -39
- package/dist/ui/hooks/useKittyKeyboardProtocol.ts +0 -31
- package/dist/ui/hooks/useLoadingIndicator.test.ts +0 -139
- package/dist/ui/hooks/useLoadingIndicator.ts +0 -57
- package/dist/ui/hooks/useLogger.ts +0 -32
- package/dist/ui/hooks/useMessageQueue.test.ts +0 -226
- package/dist/ui/hooks/useMessageQueue.ts +0 -69
- package/dist/ui/hooks/usePhraseCycler.test.ts +0 -145
- package/dist/ui/hooks/usePhraseCycler.ts +0 -198
- package/dist/ui/hooks/usePrivacySettings.test.ts +0 -242
- package/dist/ui/hooks/usePrivacySettings.ts +0 -150
- package/dist/ui/hooks/useReactToolScheduler.ts +0 -309
- package/dist/ui/hooks/useRefreshMemoryCommand.ts +0 -7
- package/dist/ui/hooks/useReverseSearchCompletion.test.tsx +0 -260
- package/dist/ui/hooks/useReverseSearchCompletion.tsx +0 -95
- package/dist/ui/hooks/useSettingsCommand.ts +0 -25
- package/dist/ui/hooks/useShellHistory.test.ts +0 -219
- package/dist/ui/hooks/useShellHistory.ts +0 -133
- package/dist/ui/hooks/useShowMemoryCommand.ts +0 -75
- package/dist/ui/hooks/useSlashCompletion.test.ts +0 -434
- package/dist/ui/hooks/useSlashCompletion.ts +0 -187
- package/dist/ui/hooks/useStateAndRef.ts +0 -36
- package/dist/ui/hooks/useTerminalSize.ts +0 -32
- package/dist/ui/hooks/useThemeCommand.ts +0 -110
- package/dist/ui/hooks/useTimer.test.ts +0 -120
- package/dist/ui/hooks/useTimer.ts +0 -65
- package/dist/ui/hooks/useToolScheduler.test.ts +0 -1123
- package/dist/ui/hooks/useWelcomeBack.ts +0 -253
- package/dist/ui/hooks/vim.test.ts +0 -1691
- package/dist/ui/hooks/vim.ts +0 -784
- package/dist/ui/keyMatchers.test.ts +0 -337
- package/dist/ui/keyMatchers.ts +0 -105
- package/dist/ui/privacy/CloudFreePrivacyNotice.tsx +0 -117
- package/dist/ui/privacy/CloudPaidPrivacyNotice.tsx +0 -59
- package/dist/ui/privacy/GeminiPrivacyNotice.tsx +0 -62
- package/dist/ui/privacy/PrivacyNotice.tsx +0 -42
- package/dist/ui/semantic-colors.ts +0 -26
- package/dist/ui/themes/ansi-light.ts +0 -150
- package/dist/ui/themes/ansi.ts +0 -159
- package/dist/ui/themes/atom-one-dark.ts +0 -147
- package/dist/ui/themes/ayu-light.ts +0 -139
- package/dist/ui/themes/ayu.ts +0 -113
- package/dist/ui/themes/color-utils.test.ts +0 -221
- package/dist/ui/themes/color-utils.ts +0 -231
- package/dist/ui/themes/default-light.ts +0 -108
- package/dist/ui/themes/default.ts +0 -151
- package/dist/ui/themes/dracula.ts +0 -124
- package/dist/ui/themes/fss-code-dark.ts +0 -156
- package/dist/ui/themes/fss-dark.ts +0 -113
- package/dist/ui/themes/fss-light.ts +0 -139
- package/dist/ui/themes/github-dark.ts +0 -147
- package/dist/ui/themes/github-light.ts +0 -149
- package/dist/ui/themes/googlecode.ts +0 -146
- package/dist/ui/themes/no-color.ts +0 -125
- package/dist/ui/themes/qwen-dark.ts +0 -118
- package/dist/ui/themes/qwen-light.ts +0 -144
- package/dist/ui/themes/semantic-tokens.ts +0 -127
- package/dist/ui/themes/shades-of-purple.ts +0 -352
- package/dist/ui/themes/theme-manager.test.ts +0 -99
- package/dist/ui/themes/theme-manager.ts +0 -257
- package/dist/ui/themes/theme.test.ts +0 -97
- package/dist/ui/themes/theme.ts +0 -451
- package/dist/ui/themes/xcode.ts +0 -154
- package/dist/ui/types.ts +0 -255
- package/dist/ui/utils/CodeColorizer.tsx +0 -217
- package/dist/ui/utils/ConsolePatcher.ts +0 -71
- package/dist/ui/utils/InlineMarkdownRenderer.tsx +0 -173
- package/dist/ui/utils/MarkdownDisplay.test.tsx +0 -244
- package/dist/ui/utils/MarkdownDisplay.tsx +0 -415
- package/dist/ui/utils/TableRenderer.tsx +0 -159
- package/dist/ui/utils/__snapshots__/MarkdownDisplay.test.tsx.snap +0 -93
- package/dist/ui/utils/clipboardUtils.test.ts +0 -76
- package/dist/ui/utils/clipboardUtils.ts +0 -149
- package/dist/ui/utils/commandUtils.test.ts +0 -384
- package/dist/ui/utils/commandUtils.ts +0 -106
- package/dist/ui/utils/computeStats.test.ts +0 -292
- package/dist/ui/utils/computeStats.ts +0 -86
- package/dist/ui/utils/displayUtils.test.ts +0 -58
- package/dist/ui/utils/displayUtils.ts +0 -32
- package/dist/ui/utils/formatters.test.ts +0 -72
- package/dist/ui/utils/formatters.ts +0 -63
- package/dist/ui/utils/isNarrowWidth.ts +0 -9
- package/dist/ui/utils/kittyProtocolDetector.ts +0 -105
- package/dist/ui/utils/markdownUtilities.test.ts +0 -50
- package/dist/ui/utils/markdownUtilities.ts +0 -125
- package/dist/ui/utils/platformConstants.ts +0 -52
- package/dist/ui/utils/terminalSetup.ts +0 -342
- package/dist/ui/utils/textUtils.ts +0 -40
- package/dist/ui/utils/updateCheck.test.ts +0 -163
- package/dist/ui/utils/updateCheck.ts +0 -100
- package/dist/utils/checks.ts +0 -28
- package/dist/utils/cleanup.test.ts +0 -68
- package/dist/utils/cleanup.ts +0 -36
- package/dist/utils/dialogScopeUtils.ts +0 -64
- package/dist/utils/events.ts +0 -14
- package/dist/utils/gitUtils.test.ts +0 -149
- package/dist/utils/gitUtils.ts +0 -116
- package/dist/utils/handleAutoUpdate.test.ts +0 -272
- package/dist/utils/handleAutoUpdate.ts +0 -145
- package/dist/utils/installationInfo.test.ts +0 -315
- package/dist/utils/installationInfo.ts +0 -176
- package/dist/utils/package.ts +0 -38
- package/dist/utils/readStdin.ts +0 -51
- package/dist/utils/resolvePath.ts +0 -21
- package/dist/utils/sandbox-macos-permissive-closed.sb +0 -32
- package/dist/utils/sandbox-macos-permissive-open.sb +0 -25
- package/dist/utils/sandbox-macos-permissive-proxied.sb +0 -37
- package/dist/utils/sandbox-macos-restrictive-closed.sb +0 -93
- package/dist/utils/sandbox-macos-restrictive-open.sb +0 -96
- package/dist/utils/sandbox-macos-restrictive-proxied.sb +0 -98
- package/dist/utils/sandbox.ts +0 -962
- package/dist/utils/settingsUtils.test.ts +0 -797
- package/dist/utils/settingsUtils.ts +0 -489
- package/dist/utils/spawnWrapper.ts +0 -9
- package/dist/utils/startupWarnings.test.ts +0 -83
- package/dist/utils/startupWarnings.ts +0 -40
- package/dist/utils/updateEventEmitter.ts +0 -13
- package/dist/utils/userStartupWarnings.test.ts +0 -87
- package/dist/utils/userStartupWarnings.ts +0 -69
- package/dist/utils/version.ts +0 -12
- package/dist/validateNonInterActiveAuth.test.ts +0 -260
- package/dist/validateNonInterActiveAuth.ts +0 -51
- package/dist/vitest.config.ts +0 -37
- package/dist/zed-integration/acp.ts +0 -366
- package/dist/zed-integration/fileSystemService.ts +0 -47
- package/dist/zed-integration/schema.ts +0 -466
- package/dist/zed-integration/zedIntegration.ts +0 -944
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2025 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
// Mock 'os' first.
|
|
8
|
-
import * as osActual from 'os';
|
|
9
|
-
vi.mock('os', async (importOriginal) => {
|
|
10
|
-
const actualOs = await importOriginal<typeof osActual>();
|
|
11
|
-
return {
|
|
12
|
-
...actualOs,
|
|
13
|
-
homedir: vi.fn(() => '/mock/home/user'),
|
|
14
|
-
platform: vi.fn(() => 'linux'),
|
|
15
|
-
};
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
import {
|
|
19
|
-
describe,
|
|
20
|
-
it,
|
|
21
|
-
expect,
|
|
22
|
-
vi,
|
|
23
|
-
beforeEach,
|
|
24
|
-
afterEach,
|
|
25
|
-
type Mocked,
|
|
26
|
-
type Mock,
|
|
27
|
-
} from 'vitest';
|
|
28
|
-
import * as fs from 'fs';
|
|
29
|
-
import stripJsonComments from 'strip-json-comments';
|
|
30
|
-
import * as path from 'path';
|
|
31
|
-
|
|
32
|
-
import {
|
|
33
|
-
loadTrustedFolders,
|
|
34
|
-
USER_TRUSTED_FOLDERS_PATH,
|
|
35
|
-
TrustLevel,
|
|
36
|
-
isWorkspaceTrusted,
|
|
37
|
-
} from './trustedFolders.js';
|
|
38
|
-
import { Settings } from './settings.js';
|
|
39
|
-
|
|
40
|
-
vi.mock('fs', async (importOriginal) => {
|
|
41
|
-
const actualFs = await importOriginal<typeof fs>();
|
|
42
|
-
return {
|
|
43
|
-
...actualFs,
|
|
44
|
-
existsSync: vi.fn(),
|
|
45
|
-
readFileSync: vi.fn(),
|
|
46
|
-
writeFileSync: vi.fn(),
|
|
47
|
-
mkdirSync: vi.fn(),
|
|
48
|
-
};
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
vi.mock('strip-json-comments', () => ({
|
|
52
|
-
default: vi.fn((content) => content),
|
|
53
|
-
}));
|
|
54
|
-
|
|
55
|
-
describe('Trusted Folders Loading', () => {
|
|
56
|
-
let mockFsExistsSync: Mocked<typeof fs.existsSync>;
|
|
57
|
-
let mockStripJsonComments: Mocked<typeof stripJsonComments>;
|
|
58
|
-
let mockFsWriteFileSync: Mocked<typeof fs.writeFileSync>;
|
|
59
|
-
|
|
60
|
-
beforeEach(() => {
|
|
61
|
-
vi.resetAllMocks();
|
|
62
|
-
mockFsExistsSync = vi.mocked(fs.existsSync);
|
|
63
|
-
mockStripJsonComments = vi.mocked(stripJsonComments);
|
|
64
|
-
mockFsWriteFileSync = vi.mocked(fs.writeFileSync);
|
|
65
|
-
vi.mocked(osActual.homedir).mockReturnValue('/mock/home/user');
|
|
66
|
-
(mockStripJsonComments as unknown as Mock).mockImplementation(
|
|
67
|
-
(jsonString: string) => jsonString,
|
|
68
|
-
);
|
|
69
|
-
(mockFsExistsSync as Mock).mockReturnValue(false);
|
|
70
|
-
(fs.readFileSync as Mock).mockReturnValue('{}');
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
afterEach(() => {
|
|
74
|
-
vi.restoreAllMocks();
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('should load empty rules if no files exist', () => {
|
|
78
|
-
const { rules, errors } = loadTrustedFolders();
|
|
79
|
-
expect(rules).toEqual([]);
|
|
80
|
-
expect(errors).toEqual([]);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it('should load user rules if only user file exists', () => {
|
|
84
|
-
const userPath = USER_TRUSTED_FOLDERS_PATH;
|
|
85
|
-
(mockFsExistsSync as Mock).mockImplementation((p) => p === userPath);
|
|
86
|
-
const userContent = {
|
|
87
|
-
'/user/folder': TrustLevel.TRUST_FOLDER,
|
|
88
|
-
};
|
|
89
|
-
(fs.readFileSync as Mock).mockImplementation((p) => {
|
|
90
|
-
if (p === userPath) return JSON.stringify(userContent);
|
|
91
|
-
return '{}';
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
const { rules, errors } = loadTrustedFolders();
|
|
95
|
-
expect(rules).toEqual([
|
|
96
|
-
{ path: '/user/folder', trustLevel: TrustLevel.TRUST_FOLDER },
|
|
97
|
-
]);
|
|
98
|
-
expect(errors).toEqual([]);
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('should handle JSON parsing errors gracefully', () => {
|
|
102
|
-
const userPath = USER_TRUSTED_FOLDERS_PATH;
|
|
103
|
-
(mockFsExistsSync as Mock).mockImplementation((p) => p === userPath);
|
|
104
|
-
(fs.readFileSync as Mock).mockImplementation((p) => {
|
|
105
|
-
if (p === userPath) return 'invalid json';
|
|
106
|
-
return '{}';
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
const { rules, errors } = loadTrustedFolders();
|
|
110
|
-
expect(rules).toEqual([]);
|
|
111
|
-
expect(errors.length).toBe(1);
|
|
112
|
-
expect(errors[0].path).toBe(userPath);
|
|
113
|
-
expect(errors[0].message).toContain('Unexpected token');
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it('setValue should update the user config and save it', () => {
|
|
117
|
-
const loadedFolders = loadTrustedFolders();
|
|
118
|
-
loadedFolders.setValue('/new/path', TrustLevel.TRUST_FOLDER);
|
|
119
|
-
|
|
120
|
-
expect(loadedFolders.user.config['/new/path']).toBe(
|
|
121
|
-
TrustLevel.TRUST_FOLDER,
|
|
122
|
-
);
|
|
123
|
-
expect(mockFsWriteFileSync).toHaveBeenCalledWith(
|
|
124
|
-
USER_TRUSTED_FOLDERS_PATH,
|
|
125
|
-
JSON.stringify({ '/new/path': TrustLevel.TRUST_FOLDER }, null, 2),
|
|
126
|
-
'utf-8',
|
|
127
|
-
);
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
describe('isWorkspaceTrusted', () => {
|
|
132
|
-
let mockCwd: string;
|
|
133
|
-
const mockRules: Record<string, TrustLevel> = {};
|
|
134
|
-
const mockSettings: Settings = {
|
|
135
|
-
folderTrustFeature: true,
|
|
136
|
-
folderTrust: true,
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
beforeEach(() => {
|
|
140
|
-
vi.spyOn(process, 'cwd').mockImplementation(() => mockCwd);
|
|
141
|
-
vi.spyOn(fs, 'readFileSync').mockImplementation((p) => {
|
|
142
|
-
if (p === USER_TRUSTED_FOLDERS_PATH) {
|
|
143
|
-
return JSON.stringify(mockRules);
|
|
144
|
-
}
|
|
145
|
-
return '{}';
|
|
146
|
-
});
|
|
147
|
-
vi.spyOn(fs, 'existsSync').mockImplementation(
|
|
148
|
-
(p) => p === USER_TRUSTED_FOLDERS_PATH,
|
|
149
|
-
);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
afterEach(() => {
|
|
153
|
-
vi.restoreAllMocks();
|
|
154
|
-
// Clear the object
|
|
155
|
-
Object.keys(mockRules).forEach((key) => delete mockRules[key]);
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
it('should return true for a directly trusted folder', () => {
|
|
159
|
-
mockCwd = '/home/user/projectA';
|
|
160
|
-
mockRules['/home/user/projectA'] = TrustLevel.TRUST_FOLDER;
|
|
161
|
-
expect(isWorkspaceTrusted(mockSettings)).toBe(true);
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
it('should return true for a child of a trusted folder', () => {
|
|
165
|
-
mockCwd = '/home/user/projectA/src';
|
|
166
|
-
mockRules['/home/user/projectA'] = TrustLevel.TRUST_FOLDER;
|
|
167
|
-
expect(isWorkspaceTrusted(mockSettings)).toBe(true);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it('should return true for a child of a trusted parent folder', () => {
|
|
171
|
-
mockCwd = '/home/user/projectB';
|
|
172
|
-
mockRules['/home/user/projectB/somefile.txt'] = TrustLevel.TRUST_PARENT;
|
|
173
|
-
expect(isWorkspaceTrusted(mockSettings)).toBe(true);
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
it('should return false for a directly untrusted folder', () => {
|
|
177
|
-
mockCwd = '/home/user/untrusted';
|
|
178
|
-
mockRules['/home/user/untrusted'] = TrustLevel.DO_NOT_TRUST;
|
|
179
|
-
expect(isWorkspaceTrusted(mockSettings)).toBe(false);
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
it('should return undefined for a child of an untrusted folder', () => {
|
|
183
|
-
mockCwd = '/home/user/untrusted/src';
|
|
184
|
-
mockRules['/home/user/untrusted'] = TrustLevel.DO_NOT_TRUST;
|
|
185
|
-
expect(isWorkspaceTrusted(mockSettings)).toBeUndefined();
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it('should return undefined when no rules match', () => {
|
|
189
|
-
mockCwd = '/home/user/other';
|
|
190
|
-
mockRules['/home/user/projectA'] = TrustLevel.TRUST_FOLDER;
|
|
191
|
-
mockRules['/home/user/untrusted'] = TrustLevel.DO_NOT_TRUST;
|
|
192
|
-
expect(isWorkspaceTrusted(mockSettings)).toBeUndefined();
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
it('should prioritize trust over distrust', () => {
|
|
196
|
-
mockCwd = '/home/user/projectA/untrusted';
|
|
197
|
-
mockRules['/home/user/projectA'] = TrustLevel.TRUST_FOLDER;
|
|
198
|
-
mockRules['/home/user/projectA/untrusted'] = TrustLevel.DO_NOT_TRUST;
|
|
199
|
-
expect(isWorkspaceTrusted(mockSettings)).toBe(true);
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
it('should handle path normalization', () => {
|
|
203
|
-
mockCwd = '/home/user/projectA';
|
|
204
|
-
mockRules[`/home/user/../user/${path.basename('/home/user/projectA')}`] =
|
|
205
|
-
TrustLevel.TRUST_FOLDER;
|
|
206
|
-
expect(isWorkspaceTrusted(mockSettings)).toBe(true);
|
|
207
|
-
});
|
|
208
|
-
});
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2025 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import * as fs from 'fs';
|
|
8
|
-
import * as path from 'path';
|
|
9
|
-
import { homedir } from 'os';
|
|
10
|
-
import { getErrorMessage, isWithinRoot } from 'fss-link-core';
|
|
11
|
-
import { Settings } from './settings.js';
|
|
12
|
-
import stripJsonComments from 'strip-json-comments';
|
|
13
|
-
|
|
14
|
-
export const TRUSTED_FOLDERS_FILENAME = 'trustedFolders.json';
|
|
15
|
-
export const SETTINGS_DIRECTORY_NAME = '.fss-link';
|
|
16
|
-
export const USER_SETTINGS_DIR = path.join(homedir(), SETTINGS_DIRECTORY_NAME);
|
|
17
|
-
export const USER_TRUSTED_FOLDERS_PATH = path.join(
|
|
18
|
-
USER_SETTINGS_DIR,
|
|
19
|
-
TRUSTED_FOLDERS_FILENAME,
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
export enum TrustLevel {
|
|
23
|
-
TRUST_FOLDER = 'TRUST_FOLDER',
|
|
24
|
-
TRUST_PARENT = 'TRUST_PARENT',
|
|
25
|
-
DO_NOT_TRUST = 'DO_NOT_TRUST',
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface TrustRule {
|
|
29
|
-
path: string;
|
|
30
|
-
trustLevel: TrustLevel;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface TrustedFoldersError {
|
|
34
|
-
message: string;
|
|
35
|
-
path: string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface TrustedFoldersFile {
|
|
39
|
-
config: Record<string, TrustLevel>;
|
|
40
|
-
path: string;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export class LoadedTrustedFolders {
|
|
44
|
-
constructor(
|
|
45
|
-
public user: TrustedFoldersFile,
|
|
46
|
-
public errors: TrustedFoldersError[],
|
|
47
|
-
) {}
|
|
48
|
-
|
|
49
|
-
get rules(): TrustRule[] {
|
|
50
|
-
return Object.entries(this.user.config).map(([path, trustLevel]) => ({
|
|
51
|
-
path,
|
|
52
|
-
trustLevel,
|
|
53
|
-
}));
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
setValue(path: string, trustLevel: TrustLevel): void {
|
|
57
|
-
this.user.config[path] = trustLevel;
|
|
58
|
-
saveTrustedFolders(this.user);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function loadTrustedFolders(): LoadedTrustedFolders {
|
|
63
|
-
const errors: TrustedFoldersError[] = [];
|
|
64
|
-
const userConfig: Record<string, TrustLevel> = {};
|
|
65
|
-
|
|
66
|
-
const userPath = USER_TRUSTED_FOLDERS_PATH;
|
|
67
|
-
|
|
68
|
-
// Load user trusted folders
|
|
69
|
-
try {
|
|
70
|
-
if (fs.existsSync(userPath)) {
|
|
71
|
-
const content = fs.readFileSync(userPath, 'utf-8');
|
|
72
|
-
const parsed = JSON.parse(stripJsonComments(content)) as Record<
|
|
73
|
-
string,
|
|
74
|
-
TrustLevel
|
|
75
|
-
>;
|
|
76
|
-
if (parsed) {
|
|
77
|
-
Object.assign(userConfig, parsed);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
} catch (error: unknown) {
|
|
81
|
-
errors.push({
|
|
82
|
-
message: getErrorMessage(error),
|
|
83
|
-
path: userPath,
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return new LoadedTrustedFolders(
|
|
88
|
-
{ path: userPath, config: userConfig },
|
|
89
|
-
errors,
|
|
90
|
-
);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export function saveTrustedFolders(
|
|
94
|
-
trustedFoldersFile: TrustedFoldersFile,
|
|
95
|
-
): void {
|
|
96
|
-
try {
|
|
97
|
-
// Ensure the directory exists
|
|
98
|
-
const dirPath = path.dirname(trustedFoldersFile.path);
|
|
99
|
-
if (!fs.existsSync(dirPath)) {
|
|
100
|
-
fs.mkdirSync(dirPath, { recursive: true });
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
fs.writeFileSync(
|
|
104
|
-
trustedFoldersFile.path,
|
|
105
|
-
JSON.stringify(trustedFoldersFile.config, null, 2),
|
|
106
|
-
'utf-8',
|
|
107
|
-
);
|
|
108
|
-
} catch (error) {
|
|
109
|
-
console.error('Error saving trusted folders file:', error);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export function isWorkspaceTrusted(settings: Settings): boolean | undefined {
|
|
114
|
-
const folderTrustFeature = settings.folderTrustFeature ?? false;
|
|
115
|
-
const folderTrustSetting = settings.folderTrust ?? true;
|
|
116
|
-
const folderTrustEnabled = folderTrustFeature && folderTrustSetting;
|
|
117
|
-
|
|
118
|
-
if (!folderTrustEnabled) {
|
|
119
|
-
return true;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const { rules, errors } = loadTrustedFolders();
|
|
123
|
-
|
|
124
|
-
if (errors.length > 0) {
|
|
125
|
-
for (const error of errors) {
|
|
126
|
-
console.error(
|
|
127
|
-
`Error loading trusted folders config from ${error.path}: ${error.message}`,
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const trustedPaths: string[] = [];
|
|
133
|
-
const untrustedPaths: string[] = [];
|
|
134
|
-
|
|
135
|
-
for (const rule of rules) {
|
|
136
|
-
switch (rule.trustLevel) {
|
|
137
|
-
case TrustLevel.TRUST_FOLDER:
|
|
138
|
-
trustedPaths.push(rule.path);
|
|
139
|
-
break;
|
|
140
|
-
case TrustLevel.TRUST_PARENT:
|
|
141
|
-
trustedPaths.push(path.dirname(rule.path));
|
|
142
|
-
break;
|
|
143
|
-
case TrustLevel.DO_NOT_TRUST:
|
|
144
|
-
untrustedPaths.push(rule.path);
|
|
145
|
-
break;
|
|
146
|
-
default:
|
|
147
|
-
// Do nothing for unknown trust levels.
|
|
148
|
-
break;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const cwd = process.cwd();
|
|
153
|
-
|
|
154
|
-
for (const trustedPath of trustedPaths) {
|
|
155
|
-
if (isWithinRoot(cwd, trustedPath)) {
|
|
156
|
-
return true;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
for (const untrustedPath of untrustedPaths) {
|
|
161
|
-
if (path.normalize(cwd) === path.normalize(untrustedPath)) {
|
|
162
|
-
return false;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return undefined;
|
|
167
|
-
}
|
package/dist/gemini.test.tsx
DELETED
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2025 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import stripAnsi from 'strip-ansi';
|
|
8
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
9
|
-
import {
|
|
10
|
-
main,
|
|
11
|
-
setupUnhandledRejectionHandler,
|
|
12
|
-
validateDnsResolutionOrder,
|
|
13
|
-
} from './gemini.js';
|
|
14
|
-
import {
|
|
15
|
-
LoadedSettings,
|
|
16
|
-
SettingsFile,
|
|
17
|
-
loadSettings,
|
|
18
|
-
} from './config/settings.js';
|
|
19
|
-
import { appEvents, AppEvent } from './utils/events.js';
|
|
20
|
-
|
|
21
|
-
// Custom error to identify mock process.exit calls
|
|
22
|
-
class MockProcessExitError extends Error {
|
|
23
|
-
constructor(readonly code?: string | number | null | undefined) {
|
|
24
|
-
super('PROCESS_EXIT_MOCKED');
|
|
25
|
-
this.name = 'MockProcessExitError';
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Mock dependencies
|
|
30
|
-
vi.mock('./config/settings.js', async (importOriginal) => {
|
|
31
|
-
const actual = await importOriginal<typeof import('./config/settings.js')>();
|
|
32
|
-
return {
|
|
33
|
-
...actual,
|
|
34
|
-
loadSettings: vi.fn(),
|
|
35
|
-
};
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
vi.mock('./config/config.js', () => ({
|
|
39
|
-
loadCliConfig: vi.fn().mockResolvedValue({
|
|
40
|
-
config: {
|
|
41
|
-
getSandbox: vi.fn(() => false),
|
|
42
|
-
getQuestion: vi.fn(() => ''),
|
|
43
|
-
},
|
|
44
|
-
modelWasSwitched: false,
|
|
45
|
-
originalModelBeforeSwitch: null,
|
|
46
|
-
finalModel: 'test-model',
|
|
47
|
-
}),
|
|
48
|
-
}));
|
|
49
|
-
|
|
50
|
-
vi.mock('read-package-up', () => ({
|
|
51
|
-
readPackageUp: vi.fn().mockResolvedValue({
|
|
52
|
-
packageJson: { name: 'test-pkg', version: 'test-version' },
|
|
53
|
-
path: '/fake/path/package.json',
|
|
54
|
-
}),
|
|
55
|
-
}));
|
|
56
|
-
|
|
57
|
-
vi.mock('update-notifier', () => ({
|
|
58
|
-
default: vi.fn(() => ({
|
|
59
|
-
notify: vi.fn(),
|
|
60
|
-
})),
|
|
61
|
-
}));
|
|
62
|
-
|
|
63
|
-
vi.mock('./utils/events.js', async (importOriginal) => {
|
|
64
|
-
const actual = await importOriginal<typeof import('./utils/events.js')>();
|
|
65
|
-
return {
|
|
66
|
-
...actual,
|
|
67
|
-
appEvents: {
|
|
68
|
-
emit: vi.fn(),
|
|
69
|
-
},
|
|
70
|
-
};
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
vi.mock('./utils/sandbox.js', () => ({
|
|
74
|
-
sandbox_command: vi.fn(() => ''), // Default to no sandbox command
|
|
75
|
-
start_sandbox: vi.fn(() => Promise.resolve()), // Mock as an async function that resolves
|
|
76
|
-
}));
|
|
77
|
-
|
|
78
|
-
describe('gemini.tsx main function', () => {
|
|
79
|
-
let consoleErrorSpy: ReturnType<typeof vi.spyOn>;
|
|
80
|
-
let loadSettingsMock: ReturnType<typeof vi.mocked<typeof loadSettings>>;
|
|
81
|
-
let originalEnvGeminiSandbox: string | undefined;
|
|
82
|
-
let originalEnvSandbox: string | undefined;
|
|
83
|
-
let initialUnhandledRejectionListeners: NodeJS.UnhandledRejectionListener[] =
|
|
84
|
-
[];
|
|
85
|
-
|
|
86
|
-
const processExitSpy = vi
|
|
87
|
-
.spyOn(process, 'exit')
|
|
88
|
-
.mockImplementation((code) => {
|
|
89
|
-
throw new MockProcessExitError(code);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
beforeEach(() => {
|
|
93
|
-
loadSettingsMock = vi.mocked(loadSettings);
|
|
94
|
-
|
|
95
|
-
// Store and clear sandbox-related env variables to ensure a consistent test environment
|
|
96
|
-
originalEnvGeminiSandbox = process.env['FSS_LINK_SANDBOX'];
|
|
97
|
-
originalEnvSandbox = process.env['SANDBOX'];
|
|
98
|
-
delete process.env['FSS_LINK_SANDBOX'];
|
|
99
|
-
delete process.env['SANDBOX'];
|
|
100
|
-
|
|
101
|
-
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
102
|
-
initialUnhandledRejectionListeners =
|
|
103
|
-
process.listeners('unhandledRejection');
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
afterEach(() => {
|
|
107
|
-
// Restore original env variables
|
|
108
|
-
if (originalEnvGeminiSandbox !== undefined) {
|
|
109
|
-
process.env['FSS_LINK_SANDBOX'] = originalEnvGeminiSandbox;
|
|
110
|
-
} else {
|
|
111
|
-
delete process.env['FSS_LINK_SANDBOX'];
|
|
112
|
-
}
|
|
113
|
-
if (originalEnvSandbox !== undefined) {
|
|
114
|
-
process.env['SANDBOX'] = originalEnvSandbox;
|
|
115
|
-
} else {
|
|
116
|
-
delete process.env['SANDBOX'];
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const currentListeners = process.listeners('unhandledRejection');
|
|
120
|
-
const addedListener = currentListeners.find(
|
|
121
|
-
(listener) => !initialUnhandledRejectionListeners.includes(listener),
|
|
122
|
-
);
|
|
123
|
-
|
|
124
|
-
if (addedListener) {
|
|
125
|
-
process.removeListener('unhandledRejection', addedListener);
|
|
126
|
-
}
|
|
127
|
-
vi.restoreAllMocks();
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it('should call process.exit(1) if settings have errors', async () => {
|
|
131
|
-
const settingsError = {
|
|
132
|
-
message: 'Test settings error',
|
|
133
|
-
path: '/test/settings.json',
|
|
134
|
-
};
|
|
135
|
-
const userSettingsFile: SettingsFile = {
|
|
136
|
-
path: '/user/settings.json',
|
|
137
|
-
settings: {},
|
|
138
|
-
};
|
|
139
|
-
const workspaceSettingsFile: SettingsFile = {
|
|
140
|
-
path: '/workspace/.gemini/settings.json',
|
|
141
|
-
settings: {},
|
|
142
|
-
};
|
|
143
|
-
const systemSettingsFile: SettingsFile = {
|
|
144
|
-
path: '/system/settings.json',
|
|
145
|
-
settings: {},
|
|
146
|
-
};
|
|
147
|
-
const mockLoadedSettings = new LoadedSettings(
|
|
148
|
-
systemSettingsFile,
|
|
149
|
-
userSettingsFile,
|
|
150
|
-
workspaceSettingsFile,
|
|
151
|
-
[settingsError],
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
loadSettingsMock.mockReturnValue(mockLoadedSettings);
|
|
155
|
-
|
|
156
|
-
try {
|
|
157
|
-
await main();
|
|
158
|
-
// If main completes without throwing, the test should fail because process.exit was expected
|
|
159
|
-
expect.fail('main function did not exit as expected');
|
|
160
|
-
} catch (error) {
|
|
161
|
-
expect(error).toBeInstanceOf(MockProcessExitError);
|
|
162
|
-
if (error instanceof MockProcessExitError) {
|
|
163
|
-
expect(error.code).toBe(1);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Verify console.error was called with the error message
|
|
168
|
-
expect(consoleErrorSpy).toHaveBeenCalledTimes(2);
|
|
169
|
-
expect(stripAnsi(String(consoleErrorSpy.mock.calls[0][0]))).toBe(
|
|
170
|
-
'Error in /test/settings.json: Test settings error',
|
|
171
|
-
);
|
|
172
|
-
expect(stripAnsi(String(consoleErrorSpy.mock.calls[1][0]))).toBe(
|
|
173
|
-
'Please fix /test/settings.json and try again.',
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
// Verify process.exit was called.
|
|
177
|
-
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it('should log unhandled promise rejections and open debug console on first error', async () => {
|
|
181
|
-
const appEventsMock = vi.mocked(appEvents);
|
|
182
|
-
const rejectionError = new Error('Test unhandled rejection');
|
|
183
|
-
|
|
184
|
-
setupUnhandledRejectionHandler();
|
|
185
|
-
// Simulate an unhandled rejection.
|
|
186
|
-
// We are not using Promise.reject here as vitest will catch it.
|
|
187
|
-
// Instead we will dispatch the event manually.
|
|
188
|
-
process.emit('unhandledRejection', rejectionError, Promise.resolve());
|
|
189
|
-
|
|
190
|
-
// We need to wait for the rejection handler to be called.
|
|
191
|
-
await new Promise(process.nextTick);
|
|
192
|
-
|
|
193
|
-
expect(appEventsMock.emit).toHaveBeenCalledWith(AppEvent.OpenDebugConsole);
|
|
194
|
-
expect(appEventsMock.emit).toHaveBeenCalledWith(
|
|
195
|
-
AppEvent.LogError,
|
|
196
|
-
expect.stringContaining('Unhandled Promise Rejection'),
|
|
197
|
-
);
|
|
198
|
-
expect(appEventsMock.emit).toHaveBeenCalledWith(
|
|
199
|
-
AppEvent.LogError,
|
|
200
|
-
expect.stringContaining('Please file a bug report using the /bug tool.'),
|
|
201
|
-
);
|
|
202
|
-
|
|
203
|
-
// Simulate a second rejection
|
|
204
|
-
const secondRejectionError = new Error('Second test unhandled rejection');
|
|
205
|
-
process.emit('unhandledRejection', secondRejectionError, Promise.resolve());
|
|
206
|
-
await new Promise(process.nextTick);
|
|
207
|
-
|
|
208
|
-
// Ensure emit was only called once for OpenDebugConsole
|
|
209
|
-
const openDebugConsoleCalls = appEventsMock.emit.mock.calls.filter(
|
|
210
|
-
(call) => call[0] === AppEvent.OpenDebugConsole,
|
|
211
|
-
);
|
|
212
|
-
expect(openDebugConsoleCalls.length).toBe(1);
|
|
213
|
-
|
|
214
|
-
// Avoid the process.exit error from being thrown.
|
|
215
|
-
processExitSpy.mockRestore();
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
describe('validateDnsResolutionOrder', () => {
|
|
220
|
-
let consoleWarnSpy: ReturnType<typeof vi.spyOn>;
|
|
221
|
-
|
|
222
|
-
beforeEach(() => {
|
|
223
|
-
consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
afterEach(() => {
|
|
227
|
-
consoleWarnSpy.mockRestore();
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
it('should return "ipv4first" when the input is "ipv4first"', () => {
|
|
231
|
-
expect(validateDnsResolutionOrder('ipv4first')).toBe('ipv4first');
|
|
232
|
-
expect(consoleWarnSpy).not.toHaveBeenCalled();
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
it('should return "verbatim" when the input is "verbatim"', () => {
|
|
236
|
-
expect(validateDnsResolutionOrder('verbatim')).toBe('verbatim');
|
|
237
|
-
expect(consoleWarnSpy).not.toHaveBeenCalled();
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
it('should return the default "ipv4first" when the input is undefined', () => {
|
|
241
|
-
expect(validateDnsResolutionOrder(undefined)).toBe('ipv4first');
|
|
242
|
-
expect(consoleWarnSpy).not.toHaveBeenCalled();
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
it('should return the default "ipv4first" and log a warning for an invalid string', () => {
|
|
246
|
-
expect(validateDnsResolutionOrder('invalid-value')).toBe('ipv4first');
|
|
247
|
-
expect(consoleWarnSpy).toHaveBeenCalledOnce();
|
|
248
|
-
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
249
|
-
'Invalid value for dnsResolutionOrder in settings: "invalid-value". Using default "ipv4first".',
|
|
250
|
-
);
|
|
251
|
-
});
|
|
252
|
-
});
|