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
package/dist/gemini.tsx
DELETED
|
@@ -1,357 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2025 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import React from 'react';
|
|
8
|
-
import { render } from 'ink';
|
|
9
|
-
import { AppWrapper } from './ui/App.js';
|
|
10
|
-
import { loadCliConfig, parseArguments } from './config/config.js';
|
|
11
|
-
import { readStdin } from './utils/readStdin.js';
|
|
12
|
-
import { basename } from 'node:path';
|
|
13
|
-
import v8 from 'node:v8';
|
|
14
|
-
import os from 'node:os';
|
|
15
|
-
import dns from 'node:dns';
|
|
16
|
-
import { spawn } from 'node:child_process';
|
|
17
|
-
import { start_sandbox } from './utils/sandbox.js';
|
|
18
|
-
import {
|
|
19
|
-
DnsResolutionOrder,
|
|
20
|
-
LoadedSettings,
|
|
21
|
-
loadSettings,
|
|
22
|
-
SettingScope,
|
|
23
|
-
} from './config/settings.js';
|
|
24
|
-
import { themeManager } from './ui/themes/theme-manager.js';
|
|
25
|
-
import { getStartupWarnings } from './utils/startupWarnings.js';
|
|
26
|
-
import { getUserStartupWarnings } from './utils/userStartupWarnings.js';
|
|
27
|
-
import { ConsolePatcher } from './ui/utils/ConsolePatcher.js';
|
|
28
|
-
import { runNonInteractive } from './nonInteractiveCli.js';
|
|
29
|
-
import { loadExtensions } from './config/extension.js';
|
|
30
|
-
import { cleanupCheckpoints, registerCleanup } from './utils/cleanup.js';
|
|
31
|
-
import { getCliVersion } from './utils/version.js';
|
|
32
|
-
import {
|
|
33
|
-
Config,
|
|
34
|
-
sessionId,
|
|
35
|
-
logUserPrompt,
|
|
36
|
-
AuthType,
|
|
37
|
-
getOauthClient,
|
|
38
|
-
logIdeConnection,
|
|
39
|
-
IdeConnectionEvent,
|
|
40
|
-
IdeConnectionType,
|
|
41
|
-
} from 'fss-link-core';
|
|
42
|
-
import { validateAuthMethod } from './config/auth.js';
|
|
43
|
-
import { setMaxSizedBoxDebugging } from './ui/components/shared/MaxSizedBox.js';
|
|
44
|
-
import { validateNonInteractiveAuth } from './validateNonInterActiveAuth.js';
|
|
45
|
-
import { detectAndEnableKittyProtocol } from './ui/utils/kittyProtocolDetector.js';
|
|
46
|
-
import { checkForUpdates } from './ui/utils/updateCheck.js';
|
|
47
|
-
import { handleAutoUpdate } from './utils/handleAutoUpdate.js';
|
|
48
|
-
import { appEvents, AppEvent } from './utils/events.js';
|
|
49
|
-
import { SettingsContext } from './ui/contexts/SettingsContext.js';
|
|
50
|
-
import { getModelManager } from './config/modelManager.js';
|
|
51
|
-
|
|
52
|
-
export function validateDnsResolutionOrder(
|
|
53
|
-
order: string | undefined,
|
|
54
|
-
): DnsResolutionOrder {
|
|
55
|
-
const defaultValue: DnsResolutionOrder = 'ipv4first';
|
|
56
|
-
if (order === undefined) {
|
|
57
|
-
return defaultValue;
|
|
58
|
-
}
|
|
59
|
-
if (order === 'ipv4first' || order === 'verbatim') {
|
|
60
|
-
return order;
|
|
61
|
-
}
|
|
62
|
-
// We don't want to throw here, just warn and use the default.
|
|
63
|
-
console.warn(
|
|
64
|
-
`Invalid value for dnsResolutionOrder in settings: "${order}". Using default "${defaultValue}".`,
|
|
65
|
-
);
|
|
66
|
-
return defaultValue;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function getNodeMemoryArgs(config: Config): string[] {
|
|
70
|
-
const totalMemoryMB = os.totalmem() / (1024 * 1024);
|
|
71
|
-
const heapStats = v8.getHeapStatistics();
|
|
72
|
-
const currentMaxOldSpaceSizeMb = Math.floor(
|
|
73
|
-
heapStats.heap_size_limit / 1024 / 1024,
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
// Set target to 50% of total memory
|
|
77
|
-
const targetMaxOldSpaceSizeInMB = Math.floor(totalMemoryMB * 0.5);
|
|
78
|
-
if (config.getDebugMode()) {
|
|
79
|
-
console.debug(
|
|
80
|
-
`Current heap size ${currentMaxOldSpaceSizeMb.toFixed(2)} MB`,
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (process.env['GEMINI_CLI_NO_RELAUNCH']) {
|
|
85
|
-
return [];
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (targetMaxOldSpaceSizeInMB > currentMaxOldSpaceSizeMb) {
|
|
89
|
-
if (config.getDebugMode()) {
|
|
90
|
-
console.debug(
|
|
91
|
-
`Need to relaunch with more memory: ${targetMaxOldSpaceSizeInMB.toFixed(2)} MB`,
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
return [`--max-old-space-size=${targetMaxOldSpaceSizeInMB}`];
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return [];
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
async function relaunchWithAdditionalArgs(additionalArgs: string[]) {
|
|
101
|
-
const nodeArgs = [...additionalArgs, ...process.argv.slice(1)];
|
|
102
|
-
const newEnv = { ...process.env, GEMINI_CLI_NO_RELAUNCH: 'true' };
|
|
103
|
-
|
|
104
|
-
const child = spawn(process.execPath, nodeArgs, {
|
|
105
|
-
stdio: 'inherit',
|
|
106
|
-
env: newEnv,
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
await new Promise((resolve) => child.on('close', resolve));
|
|
110
|
-
process.exit(0);
|
|
111
|
-
}
|
|
112
|
-
import { runZedIntegration } from './zed-integration/zedIntegration.js';
|
|
113
|
-
|
|
114
|
-
export function setupUnhandledRejectionHandler() {
|
|
115
|
-
let unhandledRejectionOccurred = false;
|
|
116
|
-
process.on('unhandledRejection', (reason, _promise) => {
|
|
117
|
-
const errorMessage = `=========================================
|
|
118
|
-
This is an unexpected error. Please file a bug report using the /bug tool.
|
|
119
|
-
CRITICAL: Unhandled Promise Rejection!
|
|
120
|
-
=========================================
|
|
121
|
-
Reason: ${reason}${
|
|
122
|
-
reason instanceof Error && reason.stack
|
|
123
|
-
? `
|
|
124
|
-
Stack trace:
|
|
125
|
-
${reason.stack}`
|
|
126
|
-
: ''
|
|
127
|
-
}`;
|
|
128
|
-
appEvents.emit(AppEvent.LogError, errorMessage);
|
|
129
|
-
if (!unhandledRejectionOccurred) {
|
|
130
|
-
unhandledRejectionOccurred = true;
|
|
131
|
-
appEvents.emit(AppEvent.OpenDebugConsole);
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export async function main() {
|
|
137
|
-
setupUnhandledRejectionHandler();
|
|
138
|
-
const workspaceRoot = process.cwd();
|
|
139
|
-
const settings = loadSettings(workspaceRoot);
|
|
140
|
-
|
|
141
|
-
await cleanupCheckpoints();
|
|
142
|
-
if (settings.errors.length > 0) {
|
|
143
|
-
for (const error of settings.errors) {
|
|
144
|
-
let errorMessage = `Error in ${error.path}: ${error.message}`;
|
|
145
|
-
if (!process.env['NO_COLOR']) {
|
|
146
|
-
errorMessage = `\x1b[31m${errorMessage}\x1b[0m`;
|
|
147
|
-
}
|
|
148
|
-
console.error(errorMessage);
|
|
149
|
-
console.error(`Please fix ${error.path} and try again.`);
|
|
150
|
-
}
|
|
151
|
-
process.exit(1);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const argv = await parseArguments();
|
|
155
|
-
const extensions = loadExtensions(workspaceRoot);
|
|
156
|
-
const config = await loadCliConfig(
|
|
157
|
-
settings.merged,
|
|
158
|
-
extensions,
|
|
159
|
-
sessionId,
|
|
160
|
-
argv,
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
const consolePatcher = new ConsolePatcher({
|
|
164
|
-
stderr: true,
|
|
165
|
-
debugMode: config.getDebugMode(),
|
|
166
|
-
});
|
|
167
|
-
consolePatcher.patch();
|
|
168
|
-
registerCleanup(consolePatcher.cleanup);
|
|
169
|
-
|
|
170
|
-
dns.setDefaultResultOrder(
|
|
171
|
-
validateDnsResolutionOrder(settings.merged.dnsResolutionOrder),
|
|
172
|
-
);
|
|
173
|
-
|
|
174
|
-
if (argv.promptInteractive && !process.stdin.isTTY) {
|
|
175
|
-
console.error(
|
|
176
|
-
'Error: The --prompt-interactive flag is not supported when piping input from stdin.',
|
|
177
|
-
);
|
|
178
|
-
process.exit(1);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (config.getListExtensions()) {
|
|
182
|
-
console.log('Installed extensions:');
|
|
183
|
-
for (const extension of extensions) {
|
|
184
|
-
console.log(`- ${extension.config.name}`);
|
|
185
|
-
}
|
|
186
|
-
process.exit(0);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Set a default auth type if one isn't set.
|
|
190
|
-
if (!settings.merged.selectedAuthType) {
|
|
191
|
-
if (process.env['CLOUD_SHELL'] === 'true') {
|
|
192
|
-
settings.setValue(
|
|
193
|
-
SettingScope.User,
|
|
194
|
-
'selectedAuthType',
|
|
195
|
-
AuthType.CLOUD_SHELL,
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
setMaxSizedBoxDebugging(config.getDebugMode());
|
|
201
|
-
|
|
202
|
-
await config.initialize();
|
|
203
|
-
|
|
204
|
-
// Connect Config with ModelManager for persistent model state
|
|
205
|
-
const modelManager = getModelManager();
|
|
206
|
-
config.setModelStateProvider(modelManager);
|
|
207
|
-
|
|
208
|
-
if (config.getIdeMode()) {
|
|
209
|
-
await config.getIdeClient().connect();
|
|
210
|
-
logIdeConnection(config, new IdeConnectionEvent(IdeConnectionType.START));
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Load custom themes from settings
|
|
214
|
-
themeManager.loadCustomThemes(settings.merged.customThemes);
|
|
215
|
-
|
|
216
|
-
if (settings.merged.theme) {
|
|
217
|
-
if (!themeManager.setActiveTheme(settings.merged.theme)) {
|
|
218
|
-
// If the theme is not found during initial load, log a warning and continue.
|
|
219
|
-
// The useThemeCommand hook in App.tsx will handle opening the dialog.
|
|
220
|
-
console.warn(`Warning: Theme "${settings.merged.theme}" not found.`);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// hop into sandbox if we are outside and sandboxing is enabled
|
|
225
|
-
if (!process.env['SANDBOX']) {
|
|
226
|
-
const memoryArgs = settings.merged.autoConfigureMaxOldSpaceSize
|
|
227
|
-
? getNodeMemoryArgs(config)
|
|
228
|
-
: [];
|
|
229
|
-
const sandboxConfig = config.getSandbox();
|
|
230
|
-
if (sandboxConfig) {
|
|
231
|
-
if (
|
|
232
|
-
settings.merged.selectedAuthType &&
|
|
233
|
-
!settings.merged.useExternalAuth
|
|
234
|
-
) {
|
|
235
|
-
// Validate authentication here because the sandbox will interfere with the Oauth2 web redirect.
|
|
236
|
-
try {
|
|
237
|
-
const err = validateAuthMethod(settings.merged.selectedAuthType);
|
|
238
|
-
if (err) {
|
|
239
|
-
throw new Error(err);
|
|
240
|
-
}
|
|
241
|
-
await config.refreshAuth(settings.merged.selectedAuthType);
|
|
242
|
-
} catch (err) {
|
|
243
|
-
console.error('Error authenticating:', err);
|
|
244
|
-
process.exit(1);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
await start_sandbox(sandboxConfig, memoryArgs, config);
|
|
248
|
-
process.exit(0);
|
|
249
|
-
} else {
|
|
250
|
-
// Not in a sandbox and not entering one, so relaunch with additional
|
|
251
|
-
// arguments to control memory usage if needed.
|
|
252
|
-
if (memoryArgs.length > 0) {
|
|
253
|
-
await relaunchWithAdditionalArgs(memoryArgs);
|
|
254
|
-
process.exit(0);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
if (
|
|
260
|
-
settings.merged.selectedAuthType === AuthType.LOGIN_WITH_GOOGLE &&
|
|
261
|
-
config.isBrowserLaunchSuppressed()
|
|
262
|
-
) {
|
|
263
|
-
// Do oauth before app renders to make copying the link possible.
|
|
264
|
-
await getOauthClient(settings.merged.selectedAuthType, config);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (config.getExperimentalZedIntegration()) {
|
|
268
|
-
return runZedIntegration(config, settings, extensions, argv);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
let input = config.getQuestion();
|
|
272
|
-
const startupWarnings = [
|
|
273
|
-
...(await getStartupWarnings()),
|
|
274
|
-
...(await getUserStartupWarnings(workspaceRoot)),
|
|
275
|
-
];
|
|
276
|
-
|
|
277
|
-
// Render UI, passing necessary config values. Check that there is no command line question.
|
|
278
|
-
if (config.isInteractive()) {
|
|
279
|
-
const version = await getCliVersion();
|
|
280
|
-
// Detect and enable Kitty keyboard protocol once at startup
|
|
281
|
-
await detectAndEnableKittyProtocol();
|
|
282
|
-
setWindowTitle(basename(workspaceRoot), settings);
|
|
283
|
-
const instance = render(
|
|
284
|
-
<React.StrictMode>
|
|
285
|
-
<SettingsContext.Provider value={settings}>
|
|
286
|
-
<AppWrapper
|
|
287
|
-
config={config}
|
|
288
|
-
settings={settings}
|
|
289
|
-
startupWarnings={startupWarnings}
|
|
290
|
-
version={version}
|
|
291
|
-
/>
|
|
292
|
-
</SettingsContext.Provider>
|
|
293
|
-
</React.StrictMode>,
|
|
294
|
-
{ exitOnCtrlC: false },
|
|
295
|
-
);
|
|
296
|
-
|
|
297
|
-
checkForUpdates()
|
|
298
|
-
.then((info) => {
|
|
299
|
-
handleAutoUpdate(info, settings, config.getProjectRoot());
|
|
300
|
-
})
|
|
301
|
-
.catch((err) => {
|
|
302
|
-
// Silently ignore update check errors.
|
|
303
|
-
if (config.getDebugMode()) {
|
|
304
|
-
console.error('Update check failed:', err);
|
|
305
|
-
}
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
registerCleanup(() => instance.unmount());
|
|
309
|
-
return;
|
|
310
|
-
}
|
|
311
|
-
// If not a TTY, read from stdin
|
|
312
|
-
// This is for cases where the user pipes input directly into the command
|
|
313
|
-
if (!process.stdin.isTTY) {
|
|
314
|
-
const stdinData = await readStdin();
|
|
315
|
-
if (stdinData) {
|
|
316
|
-
input = `${stdinData}\n\n${input}`;
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
if (!input) {
|
|
320
|
-
console.error('No input provided via stdin.');
|
|
321
|
-
process.exit(1);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
const prompt_id = Math.random().toString(16).slice(2);
|
|
325
|
-
logUserPrompt(config, {
|
|
326
|
-
'event.name': 'user_prompt',
|
|
327
|
-
'event.timestamp': new Date().toISOString(),
|
|
328
|
-
prompt: input,
|
|
329
|
-
prompt_id,
|
|
330
|
-
auth_type: config.getContentGeneratorConfig()?.authType,
|
|
331
|
-
prompt_length: input.length,
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
const nonInteractiveConfig = await validateNonInteractiveAuth(
|
|
335
|
-
settings.merged.selectedAuthType,
|
|
336
|
-
settings.merged.useExternalAuth,
|
|
337
|
-
config,
|
|
338
|
-
);
|
|
339
|
-
|
|
340
|
-
await runNonInteractive(nonInteractiveConfig, input, prompt_id);
|
|
341
|
-
process.exit(0);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
function setWindowTitle(title: string, settings: LoadedSettings) {
|
|
345
|
-
if (!settings.merged.hideWindowTitle) {
|
|
346
|
-
const windowTitle = (process.env['CLI_TITLE'] || `Qwen - ${title}`).replace(
|
|
347
|
-
// eslint-disable-next-line no-control-regex
|
|
348
|
-
/[\x00-\x1F\x7F]/g,
|
|
349
|
-
'',
|
|
350
|
-
);
|
|
351
|
-
process.stdout.write(`\x1b]2;${windowTitle}\x07`);
|
|
352
|
-
|
|
353
|
-
process.on('exit', () => {
|
|
354
|
-
process.stdout.write(`\x1b]2;\x07`);
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2025 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
// This file is auto-generated by the build script (scripts/generate-git-commit-info.js)
|
|
8
|
-
// Do not edit this file manually.
|
|
9
|
-
export const GIT_COMMIT_INFO = '696dd3d0';
|
|
10
|
-
export const CLI_VERSION = '1.0.31';
|
package/dist/index.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @license
|
|
5
|
-
* Copyright 2025 Google LLC
|
|
6
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import './src/gemini.js';
|
|
10
|
-
import { main } from './src/gemini.js';
|
|
11
|
-
|
|
12
|
-
// --- Global Entry Point ---
|
|
13
|
-
main().catch((error) => {
|
|
14
|
-
console.error('An unexpected critical error occurred:');
|
|
15
|
-
if (error instanceof Error) {
|
|
16
|
-
console.error(error.stack);
|
|
17
|
-
} else {
|
|
18
|
-
console.error(String(error));
|
|
19
|
-
}
|
|
20
|
-
process.exit(1);
|
|
21
|
-
});
|
|
@@ -1,276 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2025 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
Config,
|
|
9
|
-
executeToolCall,
|
|
10
|
-
ToolRegistry,
|
|
11
|
-
ToolErrorType,
|
|
12
|
-
shutdownTelemetry,
|
|
13
|
-
GeminiEventType,
|
|
14
|
-
ServerGeminiStreamEvent,
|
|
15
|
-
} from 'fss-link-core';
|
|
16
|
-
import { Part } from '@google/genai';
|
|
17
|
-
import { runNonInteractive } from './nonInteractiveCli.js';
|
|
18
|
-
import { vi } from 'vitest';
|
|
19
|
-
|
|
20
|
-
// Mock core modules
|
|
21
|
-
vi.mock('fss-link-core', async (importOriginal) => {
|
|
22
|
-
const original =
|
|
23
|
-
await importOriginal<typeof import('fss-link-core')>();
|
|
24
|
-
return {
|
|
25
|
-
...original,
|
|
26
|
-
executeToolCall: vi.fn(),
|
|
27
|
-
shutdownTelemetry: vi.fn(),
|
|
28
|
-
isTelemetrySdkInitialized: vi.fn().mockReturnValue(true),
|
|
29
|
-
};
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
describe('runNonInteractive', () => {
|
|
33
|
-
let mockConfig: Config;
|
|
34
|
-
let mockToolRegistry: ToolRegistry;
|
|
35
|
-
let mockCoreExecuteToolCall: vi.Mock;
|
|
36
|
-
let mockShutdownTelemetry: vi.Mock;
|
|
37
|
-
let consoleErrorSpy: vi.SpyInstance;
|
|
38
|
-
let processExitSpy: vi.SpyInstance;
|
|
39
|
-
let processStdoutSpy: vi.SpyInstance;
|
|
40
|
-
let mockGeminiClient: {
|
|
41
|
-
sendMessageStream: vi.Mock;
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
beforeEach(() => {
|
|
45
|
-
mockCoreExecuteToolCall = vi.mocked(executeToolCall);
|
|
46
|
-
mockShutdownTelemetry = vi.mocked(shutdownTelemetry);
|
|
47
|
-
|
|
48
|
-
consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
49
|
-
processExitSpy = vi
|
|
50
|
-
.spyOn(process, 'exit')
|
|
51
|
-
.mockImplementation((() => {}) as (code?: number) => never);
|
|
52
|
-
processStdoutSpy = vi
|
|
53
|
-
.spyOn(process.stdout, 'write')
|
|
54
|
-
.mockImplementation(() => true);
|
|
55
|
-
|
|
56
|
-
mockToolRegistry = {
|
|
57
|
-
getTool: vi.fn(),
|
|
58
|
-
getFunctionDeclarations: vi.fn().mockReturnValue([]),
|
|
59
|
-
} as unknown as ToolRegistry;
|
|
60
|
-
|
|
61
|
-
mockGeminiClient = {
|
|
62
|
-
sendMessageStream: vi.fn(),
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
mockConfig = {
|
|
66
|
-
initialize: vi.fn().mockResolvedValue(undefined),
|
|
67
|
-
getGeminiClient: vi.fn().mockReturnValue(mockGeminiClient),
|
|
68
|
-
getToolRegistry: vi.fn().mockReturnValue(mockToolRegistry),
|
|
69
|
-
getMaxSessionTurns: vi.fn().mockReturnValue(10),
|
|
70
|
-
getIdeMode: vi.fn().mockReturnValue(false),
|
|
71
|
-
getFullContext: vi.fn().mockReturnValue(false),
|
|
72
|
-
getContentGeneratorConfig: vi.fn().mockReturnValue({}),
|
|
73
|
-
getDebugMode: vi.fn().mockReturnValue(false),
|
|
74
|
-
} as unknown as Config;
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
afterEach(() => {
|
|
78
|
-
vi.restoreAllMocks();
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
async function* createStreamFromEvents(
|
|
82
|
-
events: ServerGeminiStreamEvent[],
|
|
83
|
-
): AsyncGenerator<ServerGeminiStreamEvent> {
|
|
84
|
-
for (const event of events) {
|
|
85
|
-
yield event;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
it('should process input and write text output', async () => {
|
|
90
|
-
const events: ServerGeminiStreamEvent[] = [
|
|
91
|
-
{ type: GeminiEventType.Content, value: 'Hello' },
|
|
92
|
-
{ type: GeminiEventType.Content, value: ' World' },
|
|
93
|
-
];
|
|
94
|
-
mockGeminiClient.sendMessageStream.mockReturnValue(
|
|
95
|
-
createStreamFromEvents(events),
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
await runNonInteractive(mockConfig, 'Test input', 'prompt-id-1');
|
|
99
|
-
|
|
100
|
-
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledWith(
|
|
101
|
-
[{ text: 'Test input' }],
|
|
102
|
-
expect.any(AbortSignal),
|
|
103
|
-
'prompt-id-1',
|
|
104
|
-
);
|
|
105
|
-
expect(processStdoutSpy).toHaveBeenCalledWith('Hello');
|
|
106
|
-
expect(processStdoutSpy).toHaveBeenCalledWith(' World');
|
|
107
|
-
expect(processStdoutSpy).toHaveBeenCalledWith('\n');
|
|
108
|
-
expect(mockShutdownTelemetry).toHaveBeenCalled();
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it('should handle a single tool call and respond', async () => {
|
|
112
|
-
const toolCallEvent: ServerGeminiStreamEvent = {
|
|
113
|
-
type: GeminiEventType.ToolCallRequest,
|
|
114
|
-
value: {
|
|
115
|
-
callId: 'tool-1',
|
|
116
|
-
name: 'testTool',
|
|
117
|
-
args: { arg1: 'value1' },
|
|
118
|
-
isClientInitiated: false,
|
|
119
|
-
prompt_id: 'prompt-id-2',
|
|
120
|
-
},
|
|
121
|
-
};
|
|
122
|
-
const toolResponse: Part[] = [{ text: 'Tool response' }];
|
|
123
|
-
mockCoreExecuteToolCall.mockResolvedValue({ responseParts: toolResponse });
|
|
124
|
-
|
|
125
|
-
const firstCallEvents: ServerGeminiStreamEvent[] = [toolCallEvent];
|
|
126
|
-
const secondCallEvents: ServerGeminiStreamEvent[] = [
|
|
127
|
-
{ type: GeminiEventType.Content, value: 'Final answer' },
|
|
128
|
-
];
|
|
129
|
-
|
|
130
|
-
mockGeminiClient.sendMessageStream
|
|
131
|
-
.mockReturnValueOnce(createStreamFromEvents(firstCallEvents))
|
|
132
|
-
.mockReturnValueOnce(createStreamFromEvents(secondCallEvents));
|
|
133
|
-
|
|
134
|
-
await runNonInteractive(mockConfig, 'Use a tool', 'prompt-id-2');
|
|
135
|
-
|
|
136
|
-
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledTimes(2);
|
|
137
|
-
expect(mockCoreExecuteToolCall).toHaveBeenCalledWith(
|
|
138
|
-
mockConfig,
|
|
139
|
-
expect.objectContaining({ name: 'testTool' }),
|
|
140
|
-
expect.any(AbortSignal),
|
|
141
|
-
);
|
|
142
|
-
expect(mockGeminiClient.sendMessageStream).toHaveBeenNthCalledWith(
|
|
143
|
-
2,
|
|
144
|
-
[{ text: 'Tool response' }],
|
|
145
|
-
expect.any(AbortSignal),
|
|
146
|
-
'prompt-id-2',
|
|
147
|
-
);
|
|
148
|
-
expect(processStdoutSpy).toHaveBeenCalledWith('Final answer');
|
|
149
|
-
expect(processStdoutSpy).toHaveBeenCalledWith('\n');
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it('should handle error during tool execution and should send error back to the model', async () => {
|
|
153
|
-
const toolCallEvent: ServerGeminiStreamEvent = {
|
|
154
|
-
type: GeminiEventType.ToolCallRequest,
|
|
155
|
-
value: {
|
|
156
|
-
callId: 'tool-1',
|
|
157
|
-
name: 'errorTool',
|
|
158
|
-
args: {},
|
|
159
|
-
isClientInitiated: false,
|
|
160
|
-
prompt_id: 'prompt-id-3',
|
|
161
|
-
},
|
|
162
|
-
};
|
|
163
|
-
mockCoreExecuteToolCall.mockResolvedValue({
|
|
164
|
-
error: new Error('Execution failed'),
|
|
165
|
-
errorType: ToolErrorType.EXECUTION_FAILED,
|
|
166
|
-
responseParts: {
|
|
167
|
-
functionResponse: {
|
|
168
|
-
name: 'errorTool',
|
|
169
|
-
response: {
|
|
170
|
-
output: 'Error: Execution failed',
|
|
171
|
-
},
|
|
172
|
-
},
|
|
173
|
-
},
|
|
174
|
-
resultDisplay: 'Execution failed',
|
|
175
|
-
});
|
|
176
|
-
const finalResponse: ServerGeminiStreamEvent[] = [
|
|
177
|
-
{
|
|
178
|
-
type: GeminiEventType.Content,
|
|
179
|
-
value: 'Sorry, let me try again.',
|
|
180
|
-
},
|
|
181
|
-
];
|
|
182
|
-
mockGeminiClient.sendMessageStream
|
|
183
|
-
.mockReturnValueOnce(createStreamFromEvents([toolCallEvent]))
|
|
184
|
-
.mockReturnValueOnce(createStreamFromEvents(finalResponse));
|
|
185
|
-
|
|
186
|
-
await runNonInteractive(mockConfig, 'Trigger tool error', 'prompt-id-3');
|
|
187
|
-
|
|
188
|
-
expect(mockCoreExecuteToolCall).toHaveBeenCalled();
|
|
189
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
190
|
-
'Error executing tool errorTool: Execution failed',
|
|
191
|
-
);
|
|
192
|
-
expect(processExitSpy).not.toHaveBeenCalled();
|
|
193
|
-
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledTimes(2);
|
|
194
|
-
expect(mockGeminiClient.sendMessageStream).toHaveBeenNthCalledWith(
|
|
195
|
-
2,
|
|
196
|
-
[
|
|
197
|
-
{
|
|
198
|
-
functionResponse: {
|
|
199
|
-
name: 'errorTool',
|
|
200
|
-
response: {
|
|
201
|
-
output: 'Error: Execution failed',
|
|
202
|
-
},
|
|
203
|
-
},
|
|
204
|
-
},
|
|
205
|
-
],
|
|
206
|
-
expect.any(AbortSignal),
|
|
207
|
-
'prompt-id-3',
|
|
208
|
-
);
|
|
209
|
-
expect(processStdoutSpy).toHaveBeenCalledWith('Sorry, let me try again.');
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
it('should exit with error if sendMessageStream throws initially', async () => {
|
|
213
|
-
const apiError = new Error('API connection failed');
|
|
214
|
-
mockGeminiClient.sendMessageStream.mockImplementation(() => {
|
|
215
|
-
throw apiError;
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
await runNonInteractive(mockConfig, 'Initial fail', 'prompt-id-4');
|
|
219
|
-
|
|
220
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
221
|
-
'[API Error: API connection failed]',
|
|
222
|
-
);
|
|
223
|
-
expect(processExitSpy).toHaveBeenCalledWith(1);
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
it('should not exit if a tool is not found, and should send error back to model', async () => {
|
|
227
|
-
const toolCallEvent: ServerGeminiStreamEvent = {
|
|
228
|
-
type: GeminiEventType.ToolCallRequest,
|
|
229
|
-
value: {
|
|
230
|
-
callId: 'tool-1',
|
|
231
|
-
name: 'nonexistentTool',
|
|
232
|
-
args: {},
|
|
233
|
-
isClientInitiated: false,
|
|
234
|
-
prompt_id: 'prompt-id-5',
|
|
235
|
-
},
|
|
236
|
-
};
|
|
237
|
-
mockCoreExecuteToolCall.mockResolvedValue({
|
|
238
|
-
error: new Error('Tool "nonexistentTool" not found in registry.'),
|
|
239
|
-
resultDisplay: 'Tool "nonexistentTool" not found in registry.',
|
|
240
|
-
});
|
|
241
|
-
const finalResponse: ServerGeminiStreamEvent[] = [
|
|
242
|
-
{
|
|
243
|
-
type: GeminiEventType.Content,
|
|
244
|
-
value: "Sorry, I can't find that tool.",
|
|
245
|
-
},
|
|
246
|
-
];
|
|
247
|
-
|
|
248
|
-
mockGeminiClient.sendMessageStream
|
|
249
|
-
.mockReturnValueOnce(createStreamFromEvents([toolCallEvent]))
|
|
250
|
-
.mockReturnValueOnce(createStreamFromEvents(finalResponse));
|
|
251
|
-
|
|
252
|
-
await runNonInteractive(
|
|
253
|
-
mockConfig,
|
|
254
|
-
'Trigger tool not found',
|
|
255
|
-
'prompt-id-5',
|
|
256
|
-
);
|
|
257
|
-
|
|
258
|
-
expect(mockCoreExecuteToolCall).toHaveBeenCalled();
|
|
259
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
260
|
-
'Error executing tool nonexistentTool: Tool "nonexistentTool" not found in registry.',
|
|
261
|
-
);
|
|
262
|
-
expect(processExitSpy).not.toHaveBeenCalled();
|
|
263
|
-
expect(mockGeminiClient.sendMessageStream).toHaveBeenCalledTimes(2);
|
|
264
|
-
expect(processStdoutSpy).toHaveBeenCalledWith(
|
|
265
|
-
"Sorry, I can't find that tool.",
|
|
266
|
-
);
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
it('should exit when max session turns are exceeded', async () => {
|
|
270
|
-
vi.mocked(mockConfig.getMaxSessionTurns).mockReturnValue(0);
|
|
271
|
-
await runNonInteractive(mockConfig, 'Trigger loop', 'prompt-id-6');
|
|
272
|
-
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
273
|
-
'\n Reached max session turns for this session. Increase the number of turns by specifying maxSessionTurns in settings.json.',
|
|
274
|
-
);
|
|
275
|
-
});
|
|
276
|
-
});
|