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.
Files changed (419) hide show
  1. package/dist/index.js +0 -0
  2. package/dist/package.json +2 -2
  3. package/dist/src/config/auth.js +8 -5
  4. package/dist/src/config/auth.js.map +1 -1
  5. package/dist/src/config/database.d.ts +103 -11
  6. package/dist/src/config/database.js +301 -59
  7. package/dist/src/config/database.js.map +1 -1
  8. package/dist/src/config/databaseBackup.d.ts +114 -0
  9. package/dist/src/config/databaseBackup.js +334 -0
  10. package/dist/src/config/databaseBackup.js.map +1 -0
  11. package/dist/src/config/databaseMigrations.d.ts +63 -0
  12. package/dist/src/config/databaseMigrations.js +379 -0
  13. package/dist/src/config/databaseMigrations.js.map +1 -0
  14. package/dist/src/config/databasePool.d.ts +70 -0
  15. package/dist/src/config/databasePool.js +193 -0
  16. package/dist/src/config/databasePool.js.map +1 -0
  17. package/dist/src/config/queryOptimizer.d.ts +127 -0
  18. package/dist/src/config/queryOptimizer.js +309 -0
  19. package/dist/src/config/queryOptimizer.js.map +1 -0
  20. package/dist/src/utils/sandbox.js +2 -8
  21. package/dist/src/utils/sandbox.js.map +1 -1
  22. package/dist/src/validateNonInterActiveAuth.js +3 -7
  23. package/dist/src/validateNonInterActiveAuth.js.map +1 -1
  24. package/dist/tsconfig.tsbuildinfo +1 -1
  25. package/package.json +2 -2
  26. package/dist/commands/mcp/add.test.ts +0 -122
  27. package/dist/commands/mcp/add.ts +0 -222
  28. package/dist/commands/mcp/list.test.ts +0 -154
  29. package/dist/commands/mcp/list.ts +0 -139
  30. package/dist/commands/mcp/remove.test.ts +0 -69
  31. package/dist/commands/mcp/remove.ts +0 -60
  32. package/dist/commands/mcp.test.ts +0 -55
  33. package/dist/commands/mcp.ts +0 -27
  34. package/dist/config/apiValidation.test.ts +0 -118
  35. package/dist/config/auth.test.ts +0 -79
  36. package/dist/config/auth.ts +0 -100
  37. package/dist/config/config.integration.test.ts +0 -407
  38. package/dist/config/config.test.ts +0 -1952
  39. package/dist/config/config.ts +0 -690
  40. package/dist/config/database.test.ts +0 -96
  41. package/dist/config/database.ts +0 -824
  42. package/dist/config/extension.test.ts +0 -236
  43. package/dist/config/extension.ts +0 -180
  44. package/dist/config/keyBindings.test.ts +0 -62
  45. package/dist/config/keyBindings.ts +0 -184
  46. package/dist/config/modelManager.ts +0 -326
  47. package/dist/config/providerManager.ts +0 -244
  48. package/dist/config/providerPersistence.test.ts +0 -377
  49. package/dist/config/providerPersistence.ts +0 -105
  50. package/dist/config/sandboxConfig.ts +0 -107
  51. package/dist/config/settings.test.ts +0 -1424
  52. package/dist/config/settings.ts +0 -517
  53. package/dist/config/settingsSchema.test.ts +0 -252
  54. package/dist/config/settingsSchema.ts +0 -728
  55. package/dist/config/trustedFolders.test.ts +0 -208
  56. package/dist/config/trustedFolders.ts +0 -167
  57. package/dist/gemini.test.tsx +0 -252
  58. package/dist/gemini.tsx +0 -357
  59. package/dist/generated/git-commit.ts +0 -10
  60. package/dist/index.ts +0 -21
  61. package/dist/nonInteractiveCli.test.ts +0 -276
  62. package/dist/nonInteractiveCli.ts +0 -143
  63. package/dist/patches/is-in-ci.ts +0 -17
  64. package/dist/services/BuiltinCommandLoader.test.ts +0 -127
  65. package/dist/services/BuiltinCommandLoader.ts +0 -95
  66. package/dist/services/CommandService.test.ts +0 -352
  67. package/dist/services/CommandService.ts +0 -103
  68. package/dist/services/FileCommandLoader.test.ts +0 -1002
  69. package/dist/services/FileCommandLoader.ts +0 -289
  70. package/dist/services/McpPromptLoader.ts +0 -231
  71. package/dist/services/SearchEngineConfigProvider.ts +0 -100
  72. package/dist/services/prompt-processors/argumentProcessor.test.ts +0 -41
  73. package/dist/services/prompt-processors/argumentProcessor.ts +0 -23
  74. package/dist/services/prompt-processors/shellProcessor.test.ts +0 -709
  75. package/dist/services/prompt-processors/shellProcessor.ts +0 -248
  76. package/dist/services/prompt-processors/types.ts +0 -44
  77. package/dist/services/types.ts +0 -24
  78. package/dist/src/config/apiValidation.test.d.ts +0 -6
  79. package/dist/src/config/apiValidation.test.js +0 -99
  80. package/dist/src/config/apiValidation.test.js.map +0 -1
  81. package/dist/src/config/database.test.d.ts +0 -6
  82. package/dist/src/config/database.test.js +0 -80
  83. package/dist/src/config/database.test.js.map +0 -1
  84. package/dist/src/config/providerManager.d.ts +0 -74
  85. package/dist/src/config/providerManager.js +0 -203
  86. package/dist/src/config/providerManager.js.map +0 -1
  87. package/dist/src/config/providerPersistence.test.d.ts +0 -6
  88. package/dist/src/config/providerPersistence.test.js +0 -283
  89. package/dist/src/config/providerPersistence.test.js.map +0 -1
  90. package/dist/src/ui/components/GeminiKeyDialog.d.ts +0 -11
  91. package/dist/src/ui/components/GeminiKeyDialog.js +0 -156
  92. package/dist/src/ui/components/GeminiKeyDialog.js.map +0 -1
  93. package/dist/src/ui/components/OpenAIEndpointDialog.d.ts +0 -19
  94. package/dist/src/ui/components/OpenAIEndpointDialog.js +0 -163
  95. package/dist/src/ui/components/OpenAIEndpointDialog.js.map +0 -1
  96. package/dist/test-setup.ts +0 -12
  97. package/dist/test-utils/customMatchers.ts +0 -65
  98. package/dist/test-utils/mockCommandContext.test.ts +0 -62
  99. package/dist/test-utils/mockCommandContext.ts +0 -105
  100. package/dist/test-utils/render.tsx +0 -18
  101. package/dist/ui/App.test.tsx +0 -2181
  102. package/dist/ui/App.tsx +0 -1344
  103. package/dist/ui/IdeIntegrationNudge.tsx +0 -98
  104. package/dist/ui/__snapshots__/App.test.tsx.snap +0 -124
  105. package/dist/ui/colors.ts +0 -56
  106. package/dist/ui/commands/aboutCommand.test.ts +0 -153
  107. package/dist/ui/commands/aboutCommand.ts +0 -49
  108. package/dist/ui/commands/authCommand.test.ts +0 -36
  109. package/dist/ui/commands/authCommand.ts +0 -17
  110. package/dist/ui/commands/bugCommand.test.ts +0 -114
  111. package/dist/ui/commands/bugCommand.ts +0 -92
  112. package/dist/ui/commands/chatCommand.test.ts +0 -414
  113. package/dist/ui/commands/chatCommand.ts +0 -280
  114. package/dist/ui/commands/clearCommand.test.ts +0 -100
  115. package/dist/ui/commands/clearCommand.ts +0 -29
  116. package/dist/ui/commands/compressCommand.test.ts +0 -129
  117. package/dist/ui/commands/compressCommand.ts +0 -78
  118. package/dist/ui/commands/contextCommand.ts +0 -132
  119. package/dist/ui/commands/copyCommand.test.ts +0 -296
  120. package/dist/ui/commands/copyCommand.ts +0 -67
  121. package/dist/ui/commands/corgiCommand.test.ts +0 -34
  122. package/dist/ui/commands/corgiCommand.ts +0 -16
  123. package/dist/ui/commands/directoryCommand.test.tsx +0 -185
  124. package/dist/ui/commands/directoryCommand.tsx +0 -179
  125. package/dist/ui/commands/docsCommand.test.ts +0 -99
  126. package/dist/ui/commands/docsCommand.ts +0 -42
  127. package/dist/ui/commands/editorCommand.test.ts +0 -30
  128. package/dist/ui/commands/editorCommand.ts +0 -21
  129. package/dist/ui/commands/extensionsCommand.test.ts +0 -67
  130. package/dist/ui/commands/extensionsCommand.ts +0 -46
  131. package/dist/ui/commands/helpCommand.test.ts +0 -52
  132. package/dist/ui/commands/helpCommand.ts +0 -23
  133. package/dist/ui/commands/ideCommand.test.ts +0 -255
  134. package/dist/ui/commands/ideCommand.ts +0 -283
  135. package/dist/ui/commands/initCommand.test.ts +0 -127
  136. package/dist/ui/commands/initCommand.ts +0 -117
  137. package/dist/ui/commands/mcpCommand.test.ts +0 -1057
  138. package/dist/ui/commands/mcpCommand.ts +0 -531
  139. package/dist/ui/commands/memoryCommand.test.ts +0 -344
  140. package/dist/ui/commands/memoryCommand.ts +0 -305
  141. package/dist/ui/commands/privacyCommand.test.ts +0 -38
  142. package/dist/ui/commands/privacyCommand.ts +0 -17
  143. package/dist/ui/commands/quitCommand.test.ts +0 -55
  144. package/dist/ui/commands/quitCommand.ts +0 -36
  145. package/dist/ui/commands/restoreCommand.test.ts +0 -250
  146. package/dist/ui/commands/restoreCommand.ts +0 -157
  147. package/dist/ui/commands/searchEngineSetupCommand.ts +0 -18
  148. package/dist/ui/commands/settingsCommand.test.ts +0 -36
  149. package/dist/ui/commands/settingsCommand.ts +0 -17
  150. package/dist/ui/commands/setupGithubCommand.test.ts +0 -238
  151. package/dist/ui/commands/setupGithubCommand.ts +0 -212
  152. package/dist/ui/commands/speakCommand.ts +0 -175
  153. package/dist/ui/commands/statsCommand.test.ts +0 -78
  154. package/dist/ui/commands/statsCommand.ts +0 -70
  155. package/dist/ui/commands/terminalSetupCommand.test.ts +0 -85
  156. package/dist/ui/commands/terminalSetupCommand.ts +0 -45
  157. package/dist/ui/commands/themeCommand.test.ts +0 -38
  158. package/dist/ui/commands/themeCommand.ts +0 -17
  159. package/dist/ui/commands/toolsCommand.test.ts +0 -105
  160. package/dist/ui/commands/toolsCommand.ts +0 -71
  161. package/dist/ui/commands/ttsCommand.ts +0 -143
  162. package/dist/ui/commands/types.ts +0 -204
  163. package/dist/ui/commands/vimCommand.ts +0 -25
  164. package/dist/ui/commands/voiceCommand.ts +0 -125
  165. package/dist/ui/components/AboutBox.tsx +0 -133
  166. package/dist/ui/components/AsciiArt.ts +0 -54
  167. package/dist/ui/components/AuthDialog.test.tsx +0 -334
  168. package/dist/ui/components/AuthDialog.tsx +0 -289
  169. package/dist/ui/components/AuthInProgress.tsx +0 -62
  170. package/dist/ui/components/AutoAcceptIndicator.tsx +0 -47
  171. package/dist/ui/components/ConsoleSummaryDisplay.tsx +0 -35
  172. package/dist/ui/components/ContextSummaryDisplay.test.tsx +0 -85
  173. package/dist/ui/components/ContextSummaryDisplay.tsx +0 -120
  174. package/dist/ui/components/ContextUsageDisplay.tsx +0 -77
  175. package/dist/ui/components/DebugProfiler.tsx +0 -36
  176. package/dist/ui/components/DetailedMessagesDisplay.tsx +0 -82
  177. package/dist/ui/components/EditorSettingsDialog.tsx +0 -172
  178. package/dist/ui/components/FolderTrustDialog.test.tsx +0 -36
  179. package/dist/ui/components/FolderTrustDialog.tsx +0 -74
  180. package/dist/ui/components/Footer.test.tsx +0 -159
  181. package/dist/ui/components/Footer.tsx +0 -158
  182. package/dist/ui/components/GeminiKeyDialog.tsx +0 -252
  183. package/dist/ui/components/GeminiRespondingSpinner.tsx +0 -34
  184. package/dist/ui/components/Header.test.tsx +0 -44
  185. package/dist/ui/components/Header.tsx +0 -70
  186. package/dist/ui/components/Help.tsx +0 -174
  187. package/dist/ui/components/HistoryItemDisplay.test.tsx +0 -125
  188. package/dist/ui/components/HistoryItemDisplay.tsx +0 -98
  189. package/dist/ui/components/InputPrompt.test.tsx +0 -1467
  190. package/dist/ui/components/InputPrompt.tsx +0 -641
  191. package/dist/ui/components/LMStudioModelPrompt.tsx +0 -215
  192. package/dist/ui/components/LoadingIndicator.test.tsx +0 -296
  193. package/dist/ui/components/LoadingIndicator.tsx +0 -82
  194. package/dist/ui/components/MemoryUsageDisplay.tsx +0 -36
  195. package/dist/ui/components/ModelStatsDisplay.test.tsx +0 -252
  196. package/dist/ui/components/ModelStatsDisplay.tsx +0 -197
  197. package/dist/ui/components/OllamaModelPrompt.tsx +0 -206
  198. package/dist/ui/components/OpenAIEndpointDialog.tsx +0 -261
  199. package/dist/ui/components/OpenAIKeyPrompt.test.tsx +0 -64
  200. package/dist/ui/components/OpenAIKeyPrompt.tsx +0 -197
  201. package/dist/ui/components/PrepareLabel.tsx +0 -48
  202. package/dist/ui/components/SearchEngineConfigDialog.tsx +0 -280
  203. package/dist/ui/components/SessionSummaryDisplay.test.tsx +0 -75
  204. package/dist/ui/components/SessionSummaryDisplay.tsx +0 -18
  205. package/dist/ui/components/SettingsDialog.test.tsx +0 -865
  206. package/dist/ui/components/SettingsDialog.tsx +0 -753
  207. package/dist/ui/components/ShellConfirmationDialog.test.tsx +0 -53
  208. package/dist/ui/components/ShellConfirmationDialog.tsx +0 -103
  209. package/dist/ui/components/ShellModeIndicator.tsx +0 -18
  210. package/dist/ui/components/ShowMoreLines.tsx +0 -40
  211. package/dist/ui/components/StatsDisplay.test.tsx +0 -401
  212. package/dist/ui/components/StatsDisplay.tsx +0 -273
  213. package/dist/ui/components/SuggestionsDisplay.tsx +0 -102
  214. package/dist/ui/components/ThemeDialog.tsx +0 -310
  215. package/dist/ui/components/Tips.tsx +0 -45
  216. package/dist/ui/components/TodoDisplay.test.tsx +0 -97
  217. package/dist/ui/components/TodoDisplay.tsx +0 -72
  218. package/dist/ui/components/ToolStatsDisplay.test.tsx +0 -180
  219. package/dist/ui/components/ToolStatsDisplay.tsx +0 -208
  220. package/dist/ui/components/UpdateNotification.tsx +0 -23
  221. package/dist/ui/components/WelcomeBackDialog.tsx +0 -290
  222. package/dist/ui/components/__snapshots__/IDEContextDetailDisplay.test.tsx.snap +0 -24
  223. package/dist/ui/components/__snapshots__/ModelStatsDisplay.test.tsx.snap +0 -121
  224. package/dist/ui/components/__snapshots__/SessionSummaryDisplay.test.tsx.snap +0 -30
  225. package/dist/ui/components/__snapshots__/ShellConfirmationDialog.test.tsx.snap +0 -21
  226. package/dist/ui/components/__snapshots__/StatsDisplay.test.tsx.snap +0 -264
  227. package/dist/ui/components/__snapshots__/ToolStatsDisplay.test.tsx.snap +0 -91
  228. package/dist/ui/components/messages/CompressionMessage.tsx +0 -49
  229. package/dist/ui/components/messages/DiffRenderer.test.tsx +0 -365
  230. package/dist/ui/components/messages/DiffRenderer.tsx +0 -358
  231. package/dist/ui/components/messages/ErrorMessage.tsx +0 -31
  232. package/dist/ui/components/messages/GeminiMessage.tsx +0 -43
  233. package/dist/ui/components/messages/GeminiMessageContent.tsx +0 -43
  234. package/dist/ui/components/messages/InfoMessage.tsx +0 -32
  235. package/dist/ui/components/messages/ToolConfirmationMessage.test.tsx +0 -58
  236. package/dist/ui/components/messages/ToolConfirmationMessage.tsx +0 -297
  237. package/dist/ui/components/messages/ToolGroupMessage.tsx +0 -126
  238. package/dist/ui/components/messages/ToolMessage.test.tsx +0 -183
  239. package/dist/ui/components/messages/ToolMessage.tsx +0 -296
  240. package/dist/ui/components/messages/UserMessage.tsx +0 -43
  241. package/dist/ui/components/messages/UserShellMessage.tsx +0 -25
  242. package/dist/ui/components/shared/MaxSizedBox.test.tsx +0 -425
  243. package/dist/ui/components/shared/MaxSizedBox.tsx +0 -624
  244. package/dist/ui/components/shared/RadioButtonSelect.test.tsx +0 -181
  245. package/dist/ui/components/shared/RadioButtonSelect.tsx +0 -234
  246. package/dist/ui/components/shared/__snapshots__/RadioButtonSelect.test.tsx.snap +0 -47
  247. package/dist/ui/components/shared/text-buffer.test.ts +0 -1728
  248. package/dist/ui/components/shared/text-buffer.ts +0 -2227
  249. package/dist/ui/components/shared/vim-buffer-actions.test.ts +0 -1119
  250. package/dist/ui/components/shared/vim-buffer-actions.ts +0 -814
  251. package/dist/ui/constants.ts +0 -17
  252. package/dist/ui/contexts/KeypressContext.test.tsx +0 -391
  253. package/dist/ui/contexts/KeypressContext.tsx +0 -440
  254. package/dist/ui/contexts/OverflowContext.tsx +0 -87
  255. package/dist/ui/contexts/SessionContext.test.tsx +0 -132
  256. package/dist/ui/contexts/SessionContext.tsx +0 -143
  257. package/dist/ui/contexts/SettingsContext.tsx +0 -20
  258. package/dist/ui/contexts/StreamingContext.tsx +0 -22
  259. package/dist/ui/contexts/VimModeContext.tsx +0 -79
  260. package/dist/ui/editors/editorSettingsManager.ts +0 -66
  261. package/dist/ui/hooks/atCommandProcessor.test.ts +0 -1102
  262. package/dist/ui/hooks/atCommandProcessor.ts +0 -485
  263. package/dist/ui/hooks/shellCommandProcessor.test.ts +0 -481
  264. package/dist/ui/hooks/shellCommandProcessor.ts +0 -314
  265. package/dist/ui/hooks/slashCommandProcessor.test.ts +0 -1044
  266. package/dist/ui/hooks/slashCommandProcessor.ts +0 -595
  267. package/dist/ui/hooks/useAtCompletion.test.ts +0 -497
  268. package/dist/ui/hooks/useAtCompletion.ts +0 -244
  269. package/dist/ui/hooks/useAuthCommand.ts +0 -129
  270. package/dist/ui/hooks/useAutoAcceptIndicator.test.ts +0 -300
  271. package/dist/ui/hooks/useAutoAcceptIndicator.ts +0 -52
  272. package/dist/ui/hooks/useBracketedPaste.ts +0 -37
  273. package/dist/ui/hooks/useCommandCompletion.test.ts +0 -518
  274. package/dist/ui/hooks/useCommandCompletion.tsx +0 -238
  275. package/dist/ui/hooks/useCompletion.ts +0 -128
  276. package/dist/ui/hooks/useConsoleMessages.test.ts +0 -147
  277. package/dist/ui/hooks/useConsoleMessages.ts +0 -110
  278. package/dist/ui/hooks/useEditorSettings.test.ts +0 -283
  279. package/dist/ui/hooks/useEditorSettings.ts +0 -75
  280. package/dist/ui/hooks/useFocus.test.ts +0 -119
  281. package/dist/ui/hooks/useFocus.ts +0 -48
  282. package/dist/ui/hooks/useFolderTrust.test.ts +0 -159
  283. package/dist/ui/hooks/useFolderTrust.ts +0 -72
  284. package/dist/ui/hooks/useGeminiStream.test.tsx +0 -1998
  285. package/dist/ui/hooks/useGeminiStream.ts +0 -1017
  286. package/dist/ui/hooks/useGitBranchName.test.ts +0 -280
  287. package/dist/ui/hooks/useGitBranchName.ts +0 -79
  288. package/dist/ui/hooks/useHistoryManager.test.ts +0 -202
  289. package/dist/ui/hooks/useHistoryManager.ts +0 -111
  290. package/dist/ui/hooks/useInputHistory.test.ts +0 -261
  291. package/dist/ui/hooks/useInputHistory.ts +0 -111
  292. package/dist/ui/hooks/useKeypress.test.ts +0 -280
  293. package/dist/ui/hooks/useKeypress.ts +0 -39
  294. package/dist/ui/hooks/useKittyKeyboardProtocol.ts +0 -31
  295. package/dist/ui/hooks/useLoadingIndicator.test.ts +0 -139
  296. package/dist/ui/hooks/useLoadingIndicator.ts +0 -57
  297. package/dist/ui/hooks/useLogger.ts +0 -32
  298. package/dist/ui/hooks/useMessageQueue.test.ts +0 -226
  299. package/dist/ui/hooks/useMessageQueue.ts +0 -69
  300. package/dist/ui/hooks/usePhraseCycler.test.ts +0 -145
  301. package/dist/ui/hooks/usePhraseCycler.ts +0 -198
  302. package/dist/ui/hooks/usePrivacySettings.test.ts +0 -242
  303. package/dist/ui/hooks/usePrivacySettings.ts +0 -150
  304. package/dist/ui/hooks/useReactToolScheduler.ts +0 -309
  305. package/dist/ui/hooks/useRefreshMemoryCommand.ts +0 -7
  306. package/dist/ui/hooks/useReverseSearchCompletion.test.tsx +0 -260
  307. package/dist/ui/hooks/useReverseSearchCompletion.tsx +0 -95
  308. package/dist/ui/hooks/useSettingsCommand.ts +0 -25
  309. package/dist/ui/hooks/useShellHistory.test.ts +0 -219
  310. package/dist/ui/hooks/useShellHistory.ts +0 -133
  311. package/dist/ui/hooks/useShowMemoryCommand.ts +0 -75
  312. package/dist/ui/hooks/useSlashCompletion.test.ts +0 -434
  313. package/dist/ui/hooks/useSlashCompletion.ts +0 -187
  314. package/dist/ui/hooks/useStateAndRef.ts +0 -36
  315. package/dist/ui/hooks/useTerminalSize.ts +0 -32
  316. package/dist/ui/hooks/useThemeCommand.ts +0 -110
  317. package/dist/ui/hooks/useTimer.test.ts +0 -120
  318. package/dist/ui/hooks/useTimer.ts +0 -65
  319. package/dist/ui/hooks/useToolScheduler.test.ts +0 -1123
  320. package/dist/ui/hooks/useWelcomeBack.ts +0 -253
  321. package/dist/ui/hooks/vim.test.ts +0 -1691
  322. package/dist/ui/hooks/vim.ts +0 -784
  323. package/dist/ui/keyMatchers.test.ts +0 -337
  324. package/dist/ui/keyMatchers.ts +0 -105
  325. package/dist/ui/privacy/CloudFreePrivacyNotice.tsx +0 -117
  326. package/dist/ui/privacy/CloudPaidPrivacyNotice.tsx +0 -59
  327. package/dist/ui/privacy/GeminiPrivacyNotice.tsx +0 -62
  328. package/dist/ui/privacy/PrivacyNotice.tsx +0 -42
  329. package/dist/ui/semantic-colors.ts +0 -26
  330. package/dist/ui/themes/ansi-light.ts +0 -150
  331. package/dist/ui/themes/ansi.ts +0 -159
  332. package/dist/ui/themes/atom-one-dark.ts +0 -147
  333. package/dist/ui/themes/ayu-light.ts +0 -139
  334. package/dist/ui/themes/ayu.ts +0 -113
  335. package/dist/ui/themes/color-utils.test.ts +0 -221
  336. package/dist/ui/themes/color-utils.ts +0 -231
  337. package/dist/ui/themes/default-light.ts +0 -108
  338. package/dist/ui/themes/default.ts +0 -151
  339. package/dist/ui/themes/dracula.ts +0 -124
  340. package/dist/ui/themes/fss-code-dark.ts +0 -156
  341. package/dist/ui/themes/fss-dark.ts +0 -113
  342. package/dist/ui/themes/fss-light.ts +0 -139
  343. package/dist/ui/themes/github-dark.ts +0 -147
  344. package/dist/ui/themes/github-light.ts +0 -149
  345. package/dist/ui/themes/googlecode.ts +0 -146
  346. package/dist/ui/themes/no-color.ts +0 -125
  347. package/dist/ui/themes/qwen-dark.ts +0 -118
  348. package/dist/ui/themes/qwen-light.ts +0 -144
  349. package/dist/ui/themes/semantic-tokens.ts +0 -127
  350. package/dist/ui/themes/shades-of-purple.ts +0 -352
  351. package/dist/ui/themes/theme-manager.test.ts +0 -99
  352. package/dist/ui/themes/theme-manager.ts +0 -257
  353. package/dist/ui/themes/theme.test.ts +0 -97
  354. package/dist/ui/themes/theme.ts +0 -451
  355. package/dist/ui/themes/xcode.ts +0 -154
  356. package/dist/ui/types.ts +0 -255
  357. package/dist/ui/utils/CodeColorizer.tsx +0 -217
  358. package/dist/ui/utils/ConsolePatcher.ts +0 -71
  359. package/dist/ui/utils/InlineMarkdownRenderer.tsx +0 -173
  360. package/dist/ui/utils/MarkdownDisplay.test.tsx +0 -244
  361. package/dist/ui/utils/MarkdownDisplay.tsx +0 -415
  362. package/dist/ui/utils/TableRenderer.tsx +0 -159
  363. package/dist/ui/utils/__snapshots__/MarkdownDisplay.test.tsx.snap +0 -93
  364. package/dist/ui/utils/clipboardUtils.test.ts +0 -76
  365. package/dist/ui/utils/clipboardUtils.ts +0 -149
  366. package/dist/ui/utils/commandUtils.test.ts +0 -384
  367. package/dist/ui/utils/commandUtils.ts +0 -106
  368. package/dist/ui/utils/computeStats.test.ts +0 -292
  369. package/dist/ui/utils/computeStats.ts +0 -86
  370. package/dist/ui/utils/displayUtils.test.ts +0 -58
  371. package/dist/ui/utils/displayUtils.ts +0 -32
  372. package/dist/ui/utils/formatters.test.ts +0 -72
  373. package/dist/ui/utils/formatters.ts +0 -63
  374. package/dist/ui/utils/isNarrowWidth.ts +0 -9
  375. package/dist/ui/utils/kittyProtocolDetector.ts +0 -105
  376. package/dist/ui/utils/markdownUtilities.test.ts +0 -50
  377. package/dist/ui/utils/markdownUtilities.ts +0 -125
  378. package/dist/ui/utils/platformConstants.ts +0 -52
  379. package/dist/ui/utils/terminalSetup.ts +0 -342
  380. package/dist/ui/utils/textUtils.ts +0 -40
  381. package/dist/ui/utils/updateCheck.test.ts +0 -163
  382. package/dist/ui/utils/updateCheck.ts +0 -100
  383. package/dist/utils/checks.ts +0 -28
  384. package/dist/utils/cleanup.test.ts +0 -68
  385. package/dist/utils/cleanup.ts +0 -36
  386. package/dist/utils/dialogScopeUtils.ts +0 -64
  387. package/dist/utils/events.ts +0 -14
  388. package/dist/utils/gitUtils.test.ts +0 -149
  389. package/dist/utils/gitUtils.ts +0 -116
  390. package/dist/utils/handleAutoUpdate.test.ts +0 -272
  391. package/dist/utils/handleAutoUpdate.ts +0 -145
  392. package/dist/utils/installationInfo.test.ts +0 -315
  393. package/dist/utils/installationInfo.ts +0 -176
  394. package/dist/utils/package.ts +0 -38
  395. package/dist/utils/readStdin.ts +0 -51
  396. package/dist/utils/resolvePath.ts +0 -21
  397. package/dist/utils/sandbox-macos-permissive-closed.sb +0 -32
  398. package/dist/utils/sandbox-macos-permissive-open.sb +0 -25
  399. package/dist/utils/sandbox-macos-permissive-proxied.sb +0 -37
  400. package/dist/utils/sandbox-macos-restrictive-closed.sb +0 -93
  401. package/dist/utils/sandbox-macos-restrictive-open.sb +0 -96
  402. package/dist/utils/sandbox-macos-restrictive-proxied.sb +0 -98
  403. package/dist/utils/sandbox.ts +0 -962
  404. package/dist/utils/settingsUtils.test.ts +0 -797
  405. package/dist/utils/settingsUtils.ts +0 -489
  406. package/dist/utils/spawnWrapper.ts +0 -9
  407. package/dist/utils/startupWarnings.test.ts +0 -83
  408. package/dist/utils/startupWarnings.ts +0 -40
  409. package/dist/utils/updateEventEmitter.ts +0 -13
  410. package/dist/utils/userStartupWarnings.test.ts +0 -87
  411. package/dist/utils/userStartupWarnings.ts +0 -69
  412. package/dist/utils/version.ts +0 -12
  413. package/dist/validateNonInterActiveAuth.test.ts +0 -260
  414. package/dist/validateNonInterActiveAuth.ts +0 -51
  415. package/dist/vitest.config.ts +0 -37
  416. package/dist/zed-integration/acp.ts +0 -366
  417. package/dist/zed-integration/fileSystemService.ts +0 -47
  418. package/dist/zed-integration/schema.ts +0 -466
  419. package/dist/zed-integration/zedIntegration.ts +0 -944
@@ -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
- }