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/config/database.ts
DELETED
|
@@ -1,824 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2025 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import initSqlJs from 'sql.js';
|
|
8
|
-
import type { Database } from 'sql.js';
|
|
9
|
-
import * as path from 'path';
|
|
10
|
-
import * as fs from 'fs';
|
|
11
|
-
import { USER_SETTINGS_DIR } from './settings.js';
|
|
12
|
-
import type { ModelConfig } from 'fss-link-core';
|
|
13
|
-
|
|
14
|
-
export interface UserPreference {
|
|
15
|
-
key: string;
|
|
16
|
-
value: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* FSS Link Database Manager
|
|
21
|
-
* Handles all persistent state for model configurations and user preferences
|
|
22
|
-
*/
|
|
23
|
-
export class FSSLinkDatabase {
|
|
24
|
-
private db: Database | null = null;
|
|
25
|
-
private dbPath: string;
|
|
26
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
-
private SQL: any; // SQLite database handle
|
|
28
|
-
private initialized = false;
|
|
29
|
-
|
|
30
|
-
constructor() {
|
|
31
|
-
// Ensure FSS Link settings directory exists
|
|
32
|
-
if (!fs.existsSync(USER_SETTINGS_DIR)) {
|
|
33
|
-
fs.mkdirSync(USER_SETTINGS_DIR, { recursive: true });
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
this.dbPath = path.join(USER_SETTINGS_DIR, 'fss-link.db');
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Initialize the database - must be called before any operations
|
|
41
|
-
*/
|
|
42
|
-
async initialize(): Promise<void> {
|
|
43
|
-
if (this.initialized) return;
|
|
44
|
-
|
|
45
|
-
this.SQL = await initSqlJs();
|
|
46
|
-
|
|
47
|
-
// Load existing database or create new one
|
|
48
|
-
if (fs.existsSync(this.dbPath)) {
|
|
49
|
-
const data = fs.readFileSync(this.dbPath);
|
|
50
|
-
this.db = new this.SQL.Database(data);
|
|
51
|
-
} else {
|
|
52
|
-
this.db = new this.SQL.Database();
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
await this.initializeSchema();
|
|
56
|
-
this.initialized = true;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Ensure database is initialized
|
|
61
|
-
*/
|
|
62
|
-
private async ensureInitialized(): Promise<void> {
|
|
63
|
-
if (!this.initialized) {
|
|
64
|
-
await this.initialize();
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Save database to disk
|
|
70
|
-
*/
|
|
71
|
-
private save(): void {
|
|
72
|
-
if (!this.db) return;
|
|
73
|
-
const data = this.db.export();
|
|
74
|
-
fs.writeFileSync(this.dbPath, Buffer.from(data));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Initialize database schema
|
|
79
|
-
*/
|
|
80
|
-
private async initializeSchema(): Promise<void> {
|
|
81
|
-
if (!this.db) return;
|
|
82
|
-
|
|
83
|
-
// Model configurations table
|
|
84
|
-
this.db.exec(`
|
|
85
|
-
CREATE TABLE IF NOT EXISTS model_configs (
|
|
86
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
87
|
-
auth_type TEXT NOT NULL,
|
|
88
|
-
model_name TEXT NOT NULL,
|
|
89
|
-
endpoint_url TEXT,
|
|
90
|
-
api_key TEXT,
|
|
91
|
-
display_name TEXT,
|
|
92
|
-
is_favorite BOOLEAN DEFAULT 0,
|
|
93
|
-
is_active BOOLEAN DEFAULT 0,
|
|
94
|
-
last_used DATETIME,
|
|
95
|
-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
96
|
-
UNIQUE(auth_type, model_name, endpoint_url)
|
|
97
|
-
)
|
|
98
|
-
`);
|
|
99
|
-
|
|
100
|
-
// User preferences table
|
|
101
|
-
this.db.exec(`
|
|
102
|
-
CREATE TABLE IF NOT EXISTS user_preferences (
|
|
103
|
-
key TEXT PRIMARY KEY,
|
|
104
|
-
value TEXT NOT NULL,
|
|
105
|
-
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
106
|
-
)
|
|
107
|
-
`);
|
|
108
|
-
|
|
109
|
-
// Custom endpoints table
|
|
110
|
-
this.db.exec(`
|
|
111
|
-
CREATE TABLE IF NOT EXISTS custom_endpoints (
|
|
112
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
113
|
-
provider_id INTEGER NOT NULL,
|
|
114
|
-
name TEXT NOT NULL,
|
|
115
|
-
url TEXT NOT NULL,
|
|
116
|
-
description TEXT,
|
|
117
|
-
is_default BOOLEAN DEFAULT 0,
|
|
118
|
-
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
119
|
-
FOREIGN KEY (provider_id) REFERENCES model_configs (id)
|
|
120
|
-
)
|
|
121
|
-
`);
|
|
122
|
-
|
|
123
|
-
// Provider usage tracking table
|
|
124
|
-
this.db.exec(`
|
|
125
|
-
CREATE TABLE IF NOT EXISTS provider_usage (
|
|
126
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
127
|
-
provider_id INTEGER NOT NULL,
|
|
128
|
-
session_date DATE DEFAULT CURRENT_DATE,
|
|
129
|
-
session_count INTEGER DEFAULT 1,
|
|
130
|
-
tokens_used INTEGER DEFAULT 0,
|
|
131
|
-
session_duration INTEGER DEFAULT 0,
|
|
132
|
-
FOREIGN KEY (provider_id) REFERENCES model_configs (id),
|
|
133
|
-
UNIQUE(provider_id, session_date)
|
|
134
|
-
)
|
|
135
|
-
`);
|
|
136
|
-
|
|
137
|
-
// Provider settings table (for additional configuration like sampling params)
|
|
138
|
-
this.db.exec(`
|
|
139
|
-
CREATE TABLE IF NOT EXISTS provider_settings (
|
|
140
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
141
|
-
provider_id INTEGER NOT NULL,
|
|
142
|
-
setting_key TEXT NOT NULL,
|
|
143
|
-
setting_value TEXT NOT NULL,
|
|
144
|
-
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
145
|
-
FOREIGN KEY (provider_id) REFERENCES model_configs (id),
|
|
146
|
-
UNIQUE(provider_id, setting_key)
|
|
147
|
-
)
|
|
148
|
-
`);
|
|
149
|
-
|
|
150
|
-
// Create indexes for performance
|
|
151
|
-
this.db.exec(`
|
|
152
|
-
CREATE INDEX IF NOT EXISTS idx_model_configs_active ON model_configs(is_active);
|
|
153
|
-
CREATE INDEX IF NOT EXISTS idx_model_configs_favorite ON model_configs(is_favorite);
|
|
154
|
-
CREATE INDEX IF NOT EXISTS idx_model_configs_last_used ON model_configs(last_used DESC);
|
|
155
|
-
CREATE INDEX IF NOT EXISTS idx_model_configs_auth_type ON model_configs(auth_type);
|
|
156
|
-
CREATE INDEX IF NOT EXISTS idx_custom_endpoints_provider ON custom_endpoints(provider_id);
|
|
157
|
-
CREATE INDEX IF NOT EXISTS idx_provider_usage_date ON provider_usage(session_date DESC);
|
|
158
|
-
CREATE INDEX IF NOT EXISTS idx_provider_settings_key ON provider_settings(provider_id, setting_key);
|
|
159
|
-
`);
|
|
160
|
-
|
|
161
|
-
// Insert default configurations if none exist
|
|
162
|
-
await this.ensureDefaultConfigurations();
|
|
163
|
-
|
|
164
|
-
// Save initial schema
|
|
165
|
-
this.save();
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Ensure default model configurations exist for new installations
|
|
170
|
-
*/
|
|
171
|
-
private async ensureDefaultConfigurations(): Promise<void> {
|
|
172
|
-
if (!this.db) return;
|
|
173
|
-
|
|
174
|
-
// Check if any configurations exist
|
|
175
|
-
const stmt = this.db.prepare('SELECT COUNT(*) as count FROM model_configs');
|
|
176
|
-
const result = stmt.get() as { count: number };
|
|
177
|
-
|
|
178
|
-
if (result.count === 0) {
|
|
179
|
-
// Insert default Ollama configuration for new users (no API key needed)
|
|
180
|
-
const defaultOllamaConfig = {
|
|
181
|
-
auth_type: 'ollama',
|
|
182
|
-
model_name: 'qwen3-coder:latest',
|
|
183
|
-
endpoint_url: 'http://localhost:11434/v1',
|
|
184
|
-
api_key: null,
|
|
185
|
-
display_name: 'Qwen3 Coder (Ollama)',
|
|
186
|
-
is_favorite: 1, // Mark as favorite so it's selected by default
|
|
187
|
-
is_active: 1, // Mark as active
|
|
188
|
-
last_used: null,
|
|
189
|
-
created_at: new Date().toISOString()
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
const insertStmt = this.db.prepare(`
|
|
193
|
-
INSERT INTO model_configs (
|
|
194
|
-
auth_type, model_name, endpoint_url, api_key, display_name,
|
|
195
|
-
is_favorite, is_active, last_used, created_at
|
|
196
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
197
|
-
`);
|
|
198
|
-
|
|
199
|
-
insertStmt.run(
|
|
200
|
-
defaultOllamaConfig.auth_type,
|
|
201
|
-
defaultOllamaConfig.model_name,
|
|
202
|
-
defaultOllamaConfig.endpoint_url,
|
|
203
|
-
defaultOllamaConfig.api_key,
|
|
204
|
-
defaultOllamaConfig.display_name,
|
|
205
|
-
defaultOllamaConfig.is_favorite,
|
|
206
|
-
defaultOllamaConfig.is_active,
|
|
207
|
-
defaultOllamaConfig.last_used,
|
|
208
|
-
defaultOllamaConfig.created_at
|
|
209
|
-
);
|
|
210
|
-
|
|
211
|
-
// Get the inserted Ollama config ID to add provider settings
|
|
212
|
-
const ollamaId = this.db.lastInsertRowid;
|
|
213
|
-
|
|
214
|
-
// Also insert a default Gemini configuration (inactive) for when users want to configure API keys later
|
|
215
|
-
const defaultGeminiConfig = {
|
|
216
|
-
auth_type: 'use_gemini',
|
|
217
|
-
model_name: 'gemini-2.5-flash-thinking',
|
|
218
|
-
endpoint_url: 'https://generativelanguage.googleapis.com/v1',
|
|
219
|
-
api_key: null,
|
|
220
|
-
display_name: 'Gemini 2.5 Flash Thinking (Requires API Key)',
|
|
221
|
-
is_favorite: 0,
|
|
222
|
-
is_active: 0, // Inactive until user configures API key
|
|
223
|
-
last_used: null,
|
|
224
|
-
created_at: new Date().toISOString()
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
insertStmt.run(
|
|
228
|
-
defaultGeminiConfig.auth_type,
|
|
229
|
-
defaultGeminiConfig.model_name,
|
|
230
|
-
defaultGeminiConfig.endpoint_url,
|
|
231
|
-
defaultGeminiConfig.api_key,
|
|
232
|
-
defaultGeminiConfig.display_name,
|
|
233
|
-
defaultGeminiConfig.is_favorite,
|
|
234
|
-
defaultGeminiConfig.is_active,
|
|
235
|
-
defaultGeminiConfig.last_used,
|
|
236
|
-
defaultGeminiConfig.created_at
|
|
237
|
-
);
|
|
238
|
-
|
|
239
|
-
// Add default LM Studio configuration (active, optional API key)
|
|
240
|
-
const defaultLMStudioConfig = {
|
|
241
|
-
auth_type: 'lm_studio',
|
|
242
|
-
model_name: 'qwen3-coder:latest',
|
|
243
|
-
endpoint_url: 'http://localhost:1234/v1',
|
|
244
|
-
api_key: null, // API key is optional for LM Studio
|
|
245
|
-
display_name: 'Qwen3 Coder (LM Studio)',
|
|
246
|
-
is_favorite: 0,
|
|
247
|
-
is_active: 1, // Active by default since no API key needed
|
|
248
|
-
last_used: null,
|
|
249
|
-
created_at: new Date().toISOString()
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
insertStmt.run(
|
|
253
|
-
defaultLMStudioConfig.auth_type,
|
|
254
|
-
defaultLMStudioConfig.model_name,
|
|
255
|
-
defaultLMStudioConfig.endpoint_url,
|
|
256
|
-
defaultLMStudioConfig.api_key,
|
|
257
|
-
defaultLMStudioConfig.display_name,
|
|
258
|
-
defaultLMStudioConfig.is_favorite,
|
|
259
|
-
defaultLMStudioConfig.is_active,
|
|
260
|
-
defaultLMStudioConfig.last_used,
|
|
261
|
-
defaultLMStudioConfig.created_at
|
|
262
|
-
);
|
|
263
|
-
|
|
264
|
-
// Add default OpenAI configuration (inactive, requires API key)
|
|
265
|
-
const defaultOpenAIConfig = {
|
|
266
|
-
auth_type: 'use_openai',
|
|
267
|
-
model_name: 'gpt-4o',
|
|
268
|
-
endpoint_url: 'https://api.openai.com/v1',
|
|
269
|
-
api_key: null, // API key required but not set by default
|
|
270
|
-
display_name: 'GPT-4o (Requires API Key)',
|
|
271
|
-
is_favorite: 0,
|
|
272
|
-
is_active: 0, // Inactive until user configures API key
|
|
273
|
-
last_used: null,
|
|
274
|
-
created_at: new Date().toISOString()
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
insertStmt.run(
|
|
278
|
-
defaultOpenAIConfig.auth_type,
|
|
279
|
-
defaultOpenAIConfig.model_name,
|
|
280
|
-
defaultOpenAIConfig.endpoint_url,
|
|
281
|
-
defaultOpenAIConfig.api_key,
|
|
282
|
-
defaultOpenAIConfig.display_name,
|
|
283
|
-
defaultOpenAIConfig.is_favorite,
|
|
284
|
-
defaultOpenAIConfig.is_active,
|
|
285
|
-
defaultOpenAIConfig.last_used,
|
|
286
|
-
defaultOpenAIConfig.created_at
|
|
287
|
-
);
|
|
288
|
-
|
|
289
|
-
// Get all the provider IDs we just created for setting default provider settings
|
|
290
|
-
const lmStudioId = this.db.lastInsertRowid;
|
|
291
|
-
|
|
292
|
-
// Insert default provider settings for optimal context windows
|
|
293
|
-
const settingsStmt = this.db.prepare(`
|
|
294
|
-
INSERT INTO provider_settings (provider_id, setting_key, setting_value, updated_at)
|
|
295
|
-
VALUES (?, ?, ?, ?)
|
|
296
|
-
`);
|
|
297
|
-
|
|
298
|
-
const now = new Date().toISOString();
|
|
299
|
-
|
|
300
|
-
// Ollama default settings - 32K context window
|
|
301
|
-
settingsStmt.run(ollamaId, 'num_ctx', '32768', now);
|
|
302
|
-
settingsStmt.run(ollamaId, 'temperature', '0.0', now);
|
|
303
|
-
|
|
304
|
-
// LM Studio default settings - 32K context window
|
|
305
|
-
settingsStmt.run(lmStudioId, 'num_ctx', '32768', now);
|
|
306
|
-
settingsStmt.run(lmStudioId, 'temperature', '0.0', now);
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Get provider settings for a specific provider
|
|
312
|
-
*/
|
|
313
|
-
async getProviderSettings(providerId: number): Promise<Record<string, string>> {
|
|
314
|
-
await this.ensureInitialized();
|
|
315
|
-
if (!this.db) return {};
|
|
316
|
-
|
|
317
|
-
const stmt = this.db.prepare(`
|
|
318
|
-
SELECT setting_key, setting_value
|
|
319
|
-
FROM provider_settings
|
|
320
|
-
WHERE provider_id = ?
|
|
321
|
-
`);
|
|
322
|
-
|
|
323
|
-
const rows = stmt.all(providerId) as Array<{ setting_key: string; setting_value: string }>;
|
|
324
|
-
const settings: Record<string, string> = {};
|
|
325
|
-
|
|
326
|
-
for (const row of rows) {
|
|
327
|
-
settings[row.setting_key] = row.setting_value;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
return settings;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/**
|
|
334
|
-
* Save a provider setting
|
|
335
|
-
*/
|
|
336
|
-
async saveProviderSetting(providerId: number, key: string, value: string | number): Promise<void> {
|
|
337
|
-
await this.ensureInitialized();
|
|
338
|
-
if (!this.db) return;
|
|
339
|
-
|
|
340
|
-
const stmt = this.db.prepare(`
|
|
341
|
-
INSERT OR REPLACE INTO provider_settings (provider_id, setting_key, setting_value, updated_at)
|
|
342
|
-
VALUES (?, ?, ?, ?)
|
|
343
|
-
`);
|
|
344
|
-
|
|
345
|
-
stmt.run(providerId, key, String(value), new Date().toISOString());
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
/**
|
|
349
|
-
* Get the currently active model configuration
|
|
350
|
-
*/
|
|
351
|
-
async getActiveModel(): Promise<ModelConfig | null> {
|
|
352
|
-
await this.ensureInitialized();
|
|
353
|
-
if (!this.db) return null;
|
|
354
|
-
|
|
355
|
-
const stmt = this.db.prepare(`
|
|
356
|
-
SELECT id, auth_type, model_name, endpoint_url, api_key, display_name,
|
|
357
|
-
is_favorite, is_active, last_used, created_at
|
|
358
|
-
FROM model_configs
|
|
359
|
-
WHERE is_active = 1
|
|
360
|
-
LIMIT 1
|
|
361
|
-
`);
|
|
362
|
-
|
|
363
|
-
const result = stmt.getAsObject({});
|
|
364
|
-
// Check if we actually got a valid row by looking for the id field
|
|
365
|
-
// SQLite can return an object with undefined values when no rows match
|
|
366
|
-
return result && result['id'] ? this.mapRowToModelConfig(result) : null;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* Set a model as active (and deactivate all others)
|
|
371
|
-
*/
|
|
372
|
-
async setActiveModel(id: number): Promise<void> {
|
|
373
|
-
await this.ensureInitialized();
|
|
374
|
-
if (!this.db) return;
|
|
375
|
-
|
|
376
|
-
// Deactivate all models
|
|
377
|
-
this.db.run('UPDATE model_configs SET is_active = 0');
|
|
378
|
-
|
|
379
|
-
// Activate the selected model and update last_used
|
|
380
|
-
this.db.run(`
|
|
381
|
-
UPDATE model_configs
|
|
382
|
-
SET is_active = 1, last_used = CURRENT_TIMESTAMP
|
|
383
|
-
WHERE id = ?
|
|
384
|
-
`, [id]);
|
|
385
|
-
|
|
386
|
-
this.save();
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
/**
|
|
390
|
-
* Add or update a model configuration
|
|
391
|
-
*/
|
|
392
|
-
async upsertModelConfig(config: ModelConfig): Promise<number> {
|
|
393
|
-
await this.ensureInitialized();
|
|
394
|
-
if (!this.db) return -1;
|
|
395
|
-
|
|
396
|
-
const stmt = this.db.prepare(`
|
|
397
|
-
INSERT OR REPLACE INTO model_configs
|
|
398
|
-
(auth_type, model_name, endpoint_url, api_key, display_name, is_favorite, is_active, last_used)
|
|
399
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
|
|
400
|
-
`);
|
|
401
|
-
|
|
402
|
-
stmt.run([
|
|
403
|
-
config.authType,
|
|
404
|
-
config.modelName,
|
|
405
|
-
config.endpointUrl || null,
|
|
406
|
-
config.apiKey || null,
|
|
407
|
-
config.displayName || null,
|
|
408
|
-
config.isFavorite ? 1 : 0,
|
|
409
|
-
config.isActive ? 1 : 0
|
|
410
|
-
]);
|
|
411
|
-
|
|
412
|
-
this.save();
|
|
413
|
-
|
|
414
|
-
// Get the last inserted row ID
|
|
415
|
-
const result = this.db.exec('SELECT last_insert_rowid() as id');
|
|
416
|
-
return result[0]?.values[0]?.[0] as number || -1;
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
/**
|
|
420
|
-
* Get all model configurations
|
|
421
|
-
*/
|
|
422
|
-
async getAllModels(): Promise<ModelConfig[]> {
|
|
423
|
-
await this.ensureInitialized();
|
|
424
|
-
if (!this.db) return [];
|
|
425
|
-
|
|
426
|
-
const stmt = this.db.prepare(`
|
|
427
|
-
SELECT id, auth_type, model_name, endpoint_url, api_key, display_name,
|
|
428
|
-
is_favorite, is_active, last_used, created_at
|
|
429
|
-
FROM model_configs
|
|
430
|
-
ORDER BY is_favorite DESC, last_used DESC, created_at DESC
|
|
431
|
-
`);
|
|
432
|
-
|
|
433
|
-
const results = [];
|
|
434
|
-
while (stmt.step()) {
|
|
435
|
-
results.push(this.mapRowToModelConfig(stmt.getAsObject()));
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
return results;
|
|
439
|
-
}
|
|
440
|
-
|
|
441
|
-
/**
|
|
442
|
-
* Get favorite models
|
|
443
|
-
*/
|
|
444
|
-
async getFavoriteModels(): Promise<ModelConfig[]> {
|
|
445
|
-
await this.ensureInitialized();
|
|
446
|
-
if (!this.db) return [];
|
|
447
|
-
|
|
448
|
-
const stmt = this.db.prepare(`
|
|
449
|
-
SELECT id, auth_type, model_name, endpoint_url, api_key, display_name,
|
|
450
|
-
is_favorite, is_active, last_used, created_at
|
|
451
|
-
FROM model_configs
|
|
452
|
-
WHERE is_favorite = 1
|
|
453
|
-
ORDER BY last_used DESC, created_at DESC
|
|
454
|
-
`);
|
|
455
|
-
|
|
456
|
-
const results = [];
|
|
457
|
-
while (stmt.step()) {
|
|
458
|
-
results.push(this.mapRowToModelConfig(stmt.getAsObject()));
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
return results;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
/**
|
|
465
|
-
* Get recently used models
|
|
466
|
-
*/
|
|
467
|
-
async getRecentModels(limit: number = 10): Promise<ModelConfig[]> {
|
|
468
|
-
await this.ensureInitialized();
|
|
469
|
-
if (!this.db) return [];
|
|
470
|
-
|
|
471
|
-
const stmt = this.db.prepare(`
|
|
472
|
-
SELECT id, auth_type, model_name, endpoint_url, api_key, display_name,
|
|
473
|
-
is_favorite, is_active, last_used, created_at
|
|
474
|
-
FROM model_configs
|
|
475
|
-
WHERE last_used IS NOT NULL
|
|
476
|
-
ORDER BY last_used DESC
|
|
477
|
-
LIMIT ?
|
|
478
|
-
`, [limit]);
|
|
479
|
-
|
|
480
|
-
const results = [];
|
|
481
|
-
while (stmt.step()) {
|
|
482
|
-
results.push(this.mapRowToModelConfig(stmt.getAsObject()));
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
return results;
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
/**
|
|
489
|
-
* Toggle favorite status for a model
|
|
490
|
-
*/
|
|
491
|
-
async toggleModelFavorite(id: number): Promise<void> {
|
|
492
|
-
await this.ensureInitialized();
|
|
493
|
-
if (!this.db) return;
|
|
494
|
-
|
|
495
|
-
this.db.run(`
|
|
496
|
-
UPDATE model_configs
|
|
497
|
-
SET is_favorite = CASE WHEN is_favorite = 1 THEN 0 ELSE 1 END
|
|
498
|
-
WHERE id = ?
|
|
499
|
-
`, [id]);
|
|
500
|
-
|
|
501
|
-
this.save();
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
/**
|
|
505
|
-
* Delete a model configuration
|
|
506
|
-
*/
|
|
507
|
-
async deleteModel(id: number): Promise<void> {
|
|
508
|
-
await this.ensureInitialized();
|
|
509
|
-
if (!this.db) return;
|
|
510
|
-
|
|
511
|
-
this.db.run('DELETE FROM model_configs WHERE id = ?', [id]);
|
|
512
|
-
this.save();
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
/**
|
|
516
|
-
* Set user preference
|
|
517
|
-
*/
|
|
518
|
-
async setUserPreference(key: string, value: string): Promise<void> {
|
|
519
|
-
await this.ensureInitialized();
|
|
520
|
-
if (!this.db) return;
|
|
521
|
-
|
|
522
|
-
this.db.run(`
|
|
523
|
-
INSERT OR REPLACE INTO user_preferences (key, value, updated_at)
|
|
524
|
-
VALUES (?, ?, CURRENT_TIMESTAMP)
|
|
525
|
-
`, [key, value]);
|
|
526
|
-
|
|
527
|
-
this.save();
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
/**
|
|
531
|
-
* Get user preference
|
|
532
|
-
*/
|
|
533
|
-
async getUserPreference(key: string): Promise<string | null> {
|
|
534
|
-
await this.ensureInitialized();
|
|
535
|
-
if (!this.db) return null;
|
|
536
|
-
|
|
537
|
-
const stmt = this.db.prepare('SELECT value FROM user_preferences WHERE key = ?', [key]);
|
|
538
|
-
|
|
539
|
-
if (stmt.step()) {
|
|
540
|
-
const result = stmt.getAsObject() as { value: string };
|
|
541
|
-
return result.value || null;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
return null;
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
/**
|
|
548
|
-
* Get all user preferences
|
|
549
|
-
*/
|
|
550
|
-
async getAllUserPreferences(): Promise<Record<string, string>> {
|
|
551
|
-
await this.ensureInitialized();
|
|
552
|
-
if (!this.db) return {};
|
|
553
|
-
|
|
554
|
-
const stmt = this.db.prepare('SELECT key, value FROM user_preferences');
|
|
555
|
-
const prefs: Record<string, string> = {};
|
|
556
|
-
|
|
557
|
-
while (stmt.step()) {
|
|
558
|
-
const row = stmt.getAsObject() as { key: string; value: string };
|
|
559
|
-
prefs[row.key] = row.value;
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
return prefs;
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
/**
|
|
566
|
-
* Close database connection
|
|
567
|
-
*/
|
|
568
|
-
close(): void {
|
|
569
|
-
if (this.db) {
|
|
570
|
-
this.save();
|
|
571
|
-
this.db.close();
|
|
572
|
-
this.db = null;
|
|
573
|
-
this.initialized = false;
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
/**
|
|
578
|
-
* Get database file path (for debugging)
|
|
579
|
-
*/
|
|
580
|
-
getDatabasePath(): string {
|
|
581
|
-
return this.dbPath;
|
|
582
|
-
}
|
|
583
|
-
|
|
584
|
-
/**
|
|
585
|
-
* Map database row to ModelConfig interface
|
|
586
|
-
*/
|
|
587
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
588
|
-
private mapRowToModelConfig(row: any): ModelConfig {
|
|
589
|
-
return {
|
|
590
|
-
id: row.id,
|
|
591
|
-
authType: row.auth_type,
|
|
592
|
-
modelName: row.model_name,
|
|
593
|
-
endpointUrl: row.endpoint_url,
|
|
594
|
-
apiKey: row.api_key,
|
|
595
|
-
displayName: row.display_name,
|
|
596
|
-
isFavorite: Boolean(row.is_favorite),
|
|
597
|
-
isActive: Boolean(row.is_active),
|
|
598
|
-
lastUsed: row.last_used ? new Date(row.last_used) : undefined,
|
|
599
|
-
createdAt: row.created_at ? new Date(row.created_at) : undefined,
|
|
600
|
-
};
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
// ============= ENHANCED PROVIDER MANAGEMENT =============
|
|
604
|
-
|
|
605
|
-
/**
|
|
606
|
-
* Record provider usage for intelligent default selection
|
|
607
|
-
*/
|
|
608
|
-
async recordProviderUsage(providerId: number, tokensUsed: number, sessionDuration: number): Promise<void> {
|
|
609
|
-
await this.ensureInitialized();
|
|
610
|
-
if (!this.db) return;
|
|
611
|
-
|
|
612
|
-
// Update or insert daily usage statistics
|
|
613
|
-
this.db.exec(`
|
|
614
|
-
INSERT INTO provider_usage (provider_id, tokens_used, session_duration)
|
|
615
|
-
VALUES (?, ?, ?)
|
|
616
|
-
ON CONFLICT(provider_id, session_date)
|
|
617
|
-
DO UPDATE SET
|
|
618
|
-
session_count = session_count + 1,
|
|
619
|
-
tokens_used = tokens_used + excluded.tokens_used,
|
|
620
|
-
session_duration = session_duration + excluded.session_duration
|
|
621
|
-
`, [providerId, tokensUsed, sessionDuration]);
|
|
622
|
-
|
|
623
|
-
// Update last_used timestamp in model_configs
|
|
624
|
-
this.db.exec(`
|
|
625
|
-
UPDATE model_configs
|
|
626
|
-
SET last_used = CURRENT_TIMESTAMP
|
|
627
|
-
WHERE id = ?
|
|
628
|
-
`, [providerId]);
|
|
629
|
-
|
|
630
|
-
this.save();
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
/**
|
|
634
|
-
* Save custom endpoint for a provider
|
|
635
|
-
*/
|
|
636
|
-
async saveCustomEndpoint(providerId: number, name: string, url: string, description?: string, isDefault = false): Promise<number> {
|
|
637
|
-
await this.ensureInitialized();
|
|
638
|
-
if (!this.db) return -1;
|
|
639
|
-
|
|
640
|
-
// If setting as default, unset other defaults for this provider
|
|
641
|
-
if (isDefault) {
|
|
642
|
-
this.db.exec(`
|
|
643
|
-
UPDATE custom_endpoints
|
|
644
|
-
SET is_default = 0
|
|
645
|
-
WHERE provider_id = ?
|
|
646
|
-
`, [providerId]);
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
this.db.exec(`
|
|
650
|
-
INSERT OR REPLACE INTO custom_endpoints (provider_id, name, url, description, is_default)
|
|
651
|
-
VALUES (?, ?, ?, ?, ?)
|
|
652
|
-
`, [providerId, name, url, description || null, isDefault ? 1 : 0]);
|
|
653
|
-
|
|
654
|
-
this.save();
|
|
655
|
-
|
|
656
|
-
const result = this.db.exec('SELECT last_insert_rowid() as id');
|
|
657
|
-
return result[0]?.values[0]?.[0] as number || -1;
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
/**
|
|
661
|
-
* Get custom endpoints for a provider
|
|
662
|
-
*/
|
|
663
|
-
async getCustomEndpoints(providerId: number): Promise<Array<Record<string, unknown>>> {
|
|
664
|
-
await this.ensureInitialized();
|
|
665
|
-
if (!this.db) return [];
|
|
666
|
-
|
|
667
|
-
const stmt = this.db.prepare(`
|
|
668
|
-
SELECT id, provider_id, name, url, description, is_default, created_at
|
|
669
|
-
FROM custom_endpoints
|
|
670
|
-
WHERE provider_id = ?
|
|
671
|
-
ORDER BY is_default DESC, created_at DESC
|
|
672
|
-
`);
|
|
673
|
-
|
|
674
|
-
return stmt.all(providerId) || [];
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
/**
|
|
678
|
-
* Save provider-specific settings (like sampling params)
|
|
679
|
-
*/
|
|
680
|
-
async saveProviderSetting(providerId: number, key: string, value: string): Promise<void> {
|
|
681
|
-
await this.ensureInitialized();
|
|
682
|
-
if (!this.db) return;
|
|
683
|
-
|
|
684
|
-
const stmt = this.db.prepare(`
|
|
685
|
-
INSERT OR REPLACE INTO provider_settings (provider_id, setting_key, setting_value)
|
|
686
|
-
VALUES (?, ?, ?)
|
|
687
|
-
`);
|
|
688
|
-
stmt.run(providerId, key, value);
|
|
689
|
-
|
|
690
|
-
this.save();
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
/**
|
|
694
|
-
* Get provider-specific settings
|
|
695
|
-
*/
|
|
696
|
-
async getProviderSettings(providerId: number): Promise<Record<string, string>> {
|
|
697
|
-
await this.ensureInitialized();
|
|
698
|
-
if (!this.db) return {};
|
|
699
|
-
|
|
700
|
-
const stmt = this.db.prepare(`
|
|
701
|
-
SELECT setting_key, setting_value
|
|
702
|
-
FROM provider_settings
|
|
703
|
-
WHERE provider_id = ?
|
|
704
|
-
`);
|
|
705
|
-
|
|
706
|
-
const results = stmt.all(providerId) || [];
|
|
707
|
-
const settings: Record<string, string> = {};
|
|
708
|
-
|
|
709
|
-
for (const row of results) {
|
|
710
|
-
settings[row.setting_key] = row.setting_value;
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
return settings;
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
/**
|
|
717
|
-
* Get smart default provider with settings
|
|
718
|
-
*/
|
|
719
|
-
async getSmartDefaultProviderWithSettings(): Promise<{model: ModelConfig, settings: Record<string, string>} | null> {
|
|
720
|
-
const model = await this.getSmartDefaultProvider();
|
|
721
|
-
if (!model || !model.id) return null;
|
|
722
|
-
|
|
723
|
-
const settings = await this.getProviderSettings(model.id);
|
|
724
|
-
return { model, settings };
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
/**
|
|
728
|
-
* Get smart default provider based on usage and preferences
|
|
729
|
-
*/
|
|
730
|
-
async getSmartDefaultProvider(): Promise<ModelConfig | null> {
|
|
731
|
-
await this.ensureInitialized();
|
|
732
|
-
if (!this.db) return null;
|
|
733
|
-
|
|
734
|
-
// Priority order:
|
|
735
|
-
// 1. User-marked favorite (is_favorite = 1)
|
|
736
|
-
// 2. Most used provider in last 30 days
|
|
737
|
-
// 3. Most recently used provider
|
|
738
|
-
const stmt = this.db.prepare(`
|
|
739
|
-
SELECT
|
|
740
|
-
m.id, m.auth_type, m.model_name, m.endpoint_url, m.api_key,
|
|
741
|
-
m.display_name, m.is_favorite, m.is_active, m.last_used, m.created_at,
|
|
742
|
-
COALESCE(u.recent_usage_score, 0) as usage_score
|
|
743
|
-
FROM model_configs m
|
|
744
|
-
LEFT JOIN (
|
|
745
|
-
SELECT
|
|
746
|
-
provider_id,
|
|
747
|
-
SUM(session_count * (1.0 / (julianday('now') - julianday(session_date) + 1))) as recent_usage_score
|
|
748
|
-
FROM provider_usage
|
|
749
|
-
WHERE session_date >= date('now', '-30 days')
|
|
750
|
-
GROUP BY provider_id
|
|
751
|
-
) u ON m.id = u.provider_id
|
|
752
|
-
ORDER BY
|
|
753
|
-
m.is_favorite DESC,
|
|
754
|
-
usage_score DESC,
|
|
755
|
-
m.last_used DESC,
|
|
756
|
-
m.created_at DESC
|
|
757
|
-
LIMIT 1
|
|
758
|
-
`);
|
|
759
|
-
|
|
760
|
-
const result = stmt.get() as any;
|
|
761
|
-
if (!result) return null;
|
|
762
|
-
|
|
763
|
-
return {
|
|
764
|
-
id: result.id,
|
|
765
|
-
authType: result.auth_type,
|
|
766
|
-
modelName: result.model_name,
|
|
767
|
-
endpointUrl: result.endpoint_url,
|
|
768
|
-
apiKey: result.api_key,
|
|
769
|
-
displayName: result.display_name,
|
|
770
|
-
isFavorite: Boolean(result.is_favorite),
|
|
771
|
-
isActive: Boolean(result.is_active)
|
|
772
|
-
};
|
|
773
|
-
}
|
|
774
|
-
|
|
775
|
-
/**
|
|
776
|
-
* Get a specific model configuration by ID
|
|
777
|
-
*/
|
|
778
|
-
async getModelById(modelId: number): Promise<ModelConfig | null> {
|
|
779
|
-
await this.ensureInitialized();
|
|
780
|
-
if (!this.db) return null;
|
|
781
|
-
|
|
782
|
-
const stmt = this.db.prepare(`
|
|
783
|
-
SELECT * FROM models WHERE id = ?
|
|
784
|
-
`);
|
|
785
|
-
|
|
786
|
-
const result = stmt.get(modelId);
|
|
787
|
-
if (!result) return null;
|
|
788
|
-
|
|
789
|
-
return {
|
|
790
|
-
id: result.id,
|
|
791
|
-
authType: result.auth_type,
|
|
792
|
-
modelName: result.model_name,
|
|
793
|
-
endpointUrl: result.endpoint_url,
|
|
794
|
-
apiKey: result.api_key,
|
|
795
|
-
displayName: result.display_name,
|
|
796
|
-
isFavorite: Boolean(result.is_favorite),
|
|
797
|
-
isActive: Boolean(result.is_active)
|
|
798
|
-
};
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
// Singleton instance for global access
|
|
803
|
-
let databaseInstance: FSSLinkDatabase | null = null;
|
|
804
|
-
|
|
805
|
-
/**
|
|
806
|
-
* Get the global FSS Link database instance
|
|
807
|
-
*/
|
|
808
|
-
export async function getFSSLinkDatabase(): Promise<FSSLinkDatabase> {
|
|
809
|
-
if (!databaseInstance) {
|
|
810
|
-
databaseInstance = new FSSLinkDatabase();
|
|
811
|
-
await databaseInstance.initialize();
|
|
812
|
-
}
|
|
813
|
-
return databaseInstance;
|
|
814
|
-
}
|
|
815
|
-
|
|
816
|
-
/**
|
|
817
|
-
* Close the global database instance (for cleanup)
|
|
818
|
-
*/
|
|
819
|
-
export function closeFSSLinkDatabase(): void {
|
|
820
|
-
if (databaseInstance) {
|
|
821
|
-
databaseInstance.close();
|
|
822
|
-
databaseInstance = null;
|
|
823
|
-
}
|
|
824
|
-
}
|