fss-link 1.0.49 → 1.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +0 -0
- package/dist/package.json +2 -2
- package/dist/src/config/auth.js +8 -5
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/database.d.ts +103 -11
- package/dist/src/config/database.js +301 -59
- package/dist/src/config/database.js.map +1 -1
- package/dist/src/config/databaseBackup.d.ts +114 -0
- package/dist/src/config/databaseBackup.js +334 -0
- package/dist/src/config/databaseBackup.js.map +1 -0
- package/dist/src/config/databaseMigrations.d.ts +63 -0
- package/dist/src/config/databaseMigrations.js +379 -0
- package/dist/src/config/databaseMigrations.js.map +1 -0
- package/dist/src/config/databasePool.d.ts +70 -0
- package/dist/src/config/databasePool.js +193 -0
- package/dist/src/config/databasePool.js.map +1 -0
- package/dist/src/config/queryOptimizer.d.ts +127 -0
- package/dist/src/config/queryOptimizer.js +309 -0
- package/dist/src/config/queryOptimizer.js.map +1 -0
- package/dist/src/utils/sandbox.js +2 -8
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/validateNonInterActiveAuth.js +3 -7
- package/dist/src/validateNonInterActiveAuth.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/dist/commands/mcp/add.test.ts +0 -122
- package/dist/commands/mcp/add.ts +0 -222
- package/dist/commands/mcp/list.test.ts +0 -154
- package/dist/commands/mcp/list.ts +0 -139
- package/dist/commands/mcp/remove.test.ts +0 -69
- package/dist/commands/mcp/remove.ts +0 -60
- package/dist/commands/mcp.test.ts +0 -55
- package/dist/commands/mcp.ts +0 -27
- package/dist/config/apiValidation.test.ts +0 -118
- package/dist/config/auth.test.ts +0 -79
- package/dist/config/auth.ts +0 -100
- package/dist/config/config.integration.test.ts +0 -407
- package/dist/config/config.test.ts +0 -1952
- package/dist/config/config.ts +0 -690
- package/dist/config/database.test.ts +0 -96
- package/dist/config/database.ts +0 -824
- package/dist/config/extension.test.ts +0 -236
- package/dist/config/extension.ts +0 -180
- package/dist/config/keyBindings.test.ts +0 -62
- package/dist/config/keyBindings.ts +0 -184
- package/dist/config/modelManager.ts +0 -326
- package/dist/config/providerManager.ts +0 -244
- package/dist/config/providerPersistence.test.ts +0 -377
- package/dist/config/providerPersistence.ts +0 -105
- package/dist/config/sandboxConfig.ts +0 -107
- package/dist/config/settings.test.ts +0 -1424
- package/dist/config/settings.ts +0 -517
- package/dist/config/settingsSchema.test.ts +0 -252
- package/dist/config/settingsSchema.ts +0 -728
- package/dist/config/trustedFolders.test.ts +0 -208
- package/dist/config/trustedFolders.ts +0 -167
- package/dist/gemini.test.tsx +0 -252
- package/dist/gemini.tsx +0 -357
- package/dist/generated/git-commit.ts +0 -10
- package/dist/index.ts +0 -21
- package/dist/nonInteractiveCli.test.ts +0 -276
- package/dist/nonInteractiveCli.ts +0 -143
- package/dist/patches/is-in-ci.ts +0 -17
- package/dist/services/BuiltinCommandLoader.test.ts +0 -127
- package/dist/services/BuiltinCommandLoader.ts +0 -95
- package/dist/services/CommandService.test.ts +0 -352
- package/dist/services/CommandService.ts +0 -103
- package/dist/services/FileCommandLoader.test.ts +0 -1002
- package/dist/services/FileCommandLoader.ts +0 -289
- package/dist/services/McpPromptLoader.ts +0 -231
- package/dist/services/SearchEngineConfigProvider.ts +0 -100
- package/dist/services/prompt-processors/argumentProcessor.test.ts +0 -41
- package/dist/services/prompt-processors/argumentProcessor.ts +0 -23
- package/dist/services/prompt-processors/shellProcessor.test.ts +0 -709
- package/dist/services/prompt-processors/shellProcessor.ts +0 -248
- package/dist/services/prompt-processors/types.ts +0 -44
- package/dist/services/types.ts +0 -24
- package/dist/src/config/apiValidation.test.d.ts +0 -6
- package/dist/src/config/apiValidation.test.js +0 -99
- package/dist/src/config/apiValidation.test.js.map +0 -1
- package/dist/src/config/database.test.d.ts +0 -6
- package/dist/src/config/database.test.js +0 -80
- package/dist/src/config/database.test.js.map +0 -1
- package/dist/src/config/providerManager.d.ts +0 -74
- package/dist/src/config/providerManager.js +0 -203
- package/dist/src/config/providerManager.js.map +0 -1
- package/dist/src/config/providerPersistence.test.d.ts +0 -6
- package/dist/src/config/providerPersistence.test.js +0 -283
- package/dist/src/config/providerPersistence.test.js.map +0 -1
- package/dist/src/ui/components/GeminiKeyDialog.d.ts +0 -11
- package/dist/src/ui/components/GeminiKeyDialog.js +0 -156
- package/dist/src/ui/components/GeminiKeyDialog.js.map +0 -1
- package/dist/src/ui/components/OpenAIEndpointDialog.d.ts +0 -19
- package/dist/src/ui/components/OpenAIEndpointDialog.js +0 -163
- package/dist/src/ui/components/OpenAIEndpointDialog.js.map +0 -1
- package/dist/test-setup.ts +0 -12
- package/dist/test-utils/customMatchers.ts +0 -65
- package/dist/test-utils/mockCommandContext.test.ts +0 -62
- package/dist/test-utils/mockCommandContext.ts +0 -105
- package/dist/test-utils/render.tsx +0 -18
- package/dist/ui/App.test.tsx +0 -2181
- package/dist/ui/App.tsx +0 -1344
- package/dist/ui/IdeIntegrationNudge.tsx +0 -98
- package/dist/ui/__snapshots__/App.test.tsx.snap +0 -124
- package/dist/ui/colors.ts +0 -56
- package/dist/ui/commands/aboutCommand.test.ts +0 -153
- package/dist/ui/commands/aboutCommand.ts +0 -49
- package/dist/ui/commands/authCommand.test.ts +0 -36
- package/dist/ui/commands/authCommand.ts +0 -17
- package/dist/ui/commands/bugCommand.test.ts +0 -114
- package/dist/ui/commands/bugCommand.ts +0 -92
- package/dist/ui/commands/chatCommand.test.ts +0 -414
- package/dist/ui/commands/chatCommand.ts +0 -280
- package/dist/ui/commands/clearCommand.test.ts +0 -100
- package/dist/ui/commands/clearCommand.ts +0 -29
- package/dist/ui/commands/compressCommand.test.ts +0 -129
- package/dist/ui/commands/compressCommand.ts +0 -78
- package/dist/ui/commands/contextCommand.ts +0 -132
- package/dist/ui/commands/copyCommand.test.ts +0 -296
- package/dist/ui/commands/copyCommand.ts +0 -67
- package/dist/ui/commands/corgiCommand.test.ts +0 -34
- package/dist/ui/commands/corgiCommand.ts +0 -16
- package/dist/ui/commands/directoryCommand.test.tsx +0 -185
- package/dist/ui/commands/directoryCommand.tsx +0 -179
- package/dist/ui/commands/docsCommand.test.ts +0 -99
- package/dist/ui/commands/docsCommand.ts +0 -42
- package/dist/ui/commands/editorCommand.test.ts +0 -30
- package/dist/ui/commands/editorCommand.ts +0 -21
- package/dist/ui/commands/extensionsCommand.test.ts +0 -67
- package/dist/ui/commands/extensionsCommand.ts +0 -46
- package/dist/ui/commands/helpCommand.test.ts +0 -52
- package/dist/ui/commands/helpCommand.ts +0 -23
- package/dist/ui/commands/ideCommand.test.ts +0 -255
- package/dist/ui/commands/ideCommand.ts +0 -283
- package/dist/ui/commands/initCommand.test.ts +0 -127
- package/dist/ui/commands/initCommand.ts +0 -117
- package/dist/ui/commands/mcpCommand.test.ts +0 -1057
- package/dist/ui/commands/mcpCommand.ts +0 -531
- package/dist/ui/commands/memoryCommand.test.ts +0 -344
- package/dist/ui/commands/memoryCommand.ts +0 -305
- package/dist/ui/commands/privacyCommand.test.ts +0 -38
- package/dist/ui/commands/privacyCommand.ts +0 -17
- package/dist/ui/commands/quitCommand.test.ts +0 -55
- package/dist/ui/commands/quitCommand.ts +0 -36
- package/dist/ui/commands/restoreCommand.test.ts +0 -250
- package/dist/ui/commands/restoreCommand.ts +0 -157
- package/dist/ui/commands/searchEngineSetupCommand.ts +0 -18
- package/dist/ui/commands/settingsCommand.test.ts +0 -36
- package/dist/ui/commands/settingsCommand.ts +0 -17
- package/dist/ui/commands/setupGithubCommand.test.ts +0 -238
- package/dist/ui/commands/setupGithubCommand.ts +0 -212
- package/dist/ui/commands/speakCommand.ts +0 -175
- package/dist/ui/commands/statsCommand.test.ts +0 -78
- package/dist/ui/commands/statsCommand.ts +0 -70
- package/dist/ui/commands/terminalSetupCommand.test.ts +0 -85
- package/dist/ui/commands/terminalSetupCommand.ts +0 -45
- package/dist/ui/commands/themeCommand.test.ts +0 -38
- package/dist/ui/commands/themeCommand.ts +0 -17
- package/dist/ui/commands/toolsCommand.test.ts +0 -105
- package/dist/ui/commands/toolsCommand.ts +0 -71
- package/dist/ui/commands/ttsCommand.ts +0 -143
- package/dist/ui/commands/types.ts +0 -204
- package/dist/ui/commands/vimCommand.ts +0 -25
- package/dist/ui/commands/voiceCommand.ts +0 -125
- package/dist/ui/components/AboutBox.tsx +0 -133
- package/dist/ui/components/AsciiArt.ts +0 -54
- package/dist/ui/components/AuthDialog.test.tsx +0 -334
- package/dist/ui/components/AuthDialog.tsx +0 -289
- package/dist/ui/components/AuthInProgress.tsx +0 -62
- package/dist/ui/components/AutoAcceptIndicator.tsx +0 -47
- package/dist/ui/components/ConsoleSummaryDisplay.tsx +0 -35
- package/dist/ui/components/ContextSummaryDisplay.test.tsx +0 -85
- package/dist/ui/components/ContextSummaryDisplay.tsx +0 -120
- package/dist/ui/components/ContextUsageDisplay.tsx +0 -77
- package/dist/ui/components/DebugProfiler.tsx +0 -36
- package/dist/ui/components/DetailedMessagesDisplay.tsx +0 -82
- package/dist/ui/components/EditorSettingsDialog.tsx +0 -172
- package/dist/ui/components/FolderTrustDialog.test.tsx +0 -36
- package/dist/ui/components/FolderTrustDialog.tsx +0 -74
- package/dist/ui/components/Footer.test.tsx +0 -159
- package/dist/ui/components/Footer.tsx +0 -158
- package/dist/ui/components/GeminiKeyDialog.tsx +0 -252
- package/dist/ui/components/GeminiRespondingSpinner.tsx +0 -34
- package/dist/ui/components/Header.test.tsx +0 -44
- package/dist/ui/components/Header.tsx +0 -70
- package/dist/ui/components/Help.tsx +0 -174
- package/dist/ui/components/HistoryItemDisplay.test.tsx +0 -125
- package/dist/ui/components/HistoryItemDisplay.tsx +0 -98
- package/dist/ui/components/InputPrompt.test.tsx +0 -1467
- package/dist/ui/components/InputPrompt.tsx +0 -641
- package/dist/ui/components/LMStudioModelPrompt.tsx +0 -215
- package/dist/ui/components/LoadingIndicator.test.tsx +0 -296
- package/dist/ui/components/LoadingIndicator.tsx +0 -82
- package/dist/ui/components/MemoryUsageDisplay.tsx +0 -36
- package/dist/ui/components/ModelStatsDisplay.test.tsx +0 -252
- package/dist/ui/components/ModelStatsDisplay.tsx +0 -197
- package/dist/ui/components/OllamaModelPrompt.tsx +0 -206
- package/dist/ui/components/OpenAIEndpointDialog.tsx +0 -261
- package/dist/ui/components/OpenAIKeyPrompt.test.tsx +0 -64
- package/dist/ui/components/OpenAIKeyPrompt.tsx +0 -197
- package/dist/ui/components/PrepareLabel.tsx +0 -48
- package/dist/ui/components/SearchEngineConfigDialog.tsx +0 -280
- package/dist/ui/components/SessionSummaryDisplay.test.tsx +0 -75
- package/dist/ui/components/SessionSummaryDisplay.tsx +0 -18
- package/dist/ui/components/SettingsDialog.test.tsx +0 -865
- package/dist/ui/components/SettingsDialog.tsx +0 -753
- package/dist/ui/components/ShellConfirmationDialog.test.tsx +0 -53
- package/dist/ui/components/ShellConfirmationDialog.tsx +0 -103
- package/dist/ui/components/ShellModeIndicator.tsx +0 -18
- package/dist/ui/components/ShowMoreLines.tsx +0 -40
- package/dist/ui/components/StatsDisplay.test.tsx +0 -401
- package/dist/ui/components/StatsDisplay.tsx +0 -273
- package/dist/ui/components/SuggestionsDisplay.tsx +0 -102
- package/dist/ui/components/ThemeDialog.tsx +0 -310
- package/dist/ui/components/Tips.tsx +0 -45
- package/dist/ui/components/TodoDisplay.test.tsx +0 -97
- package/dist/ui/components/TodoDisplay.tsx +0 -72
- package/dist/ui/components/ToolStatsDisplay.test.tsx +0 -180
- package/dist/ui/components/ToolStatsDisplay.tsx +0 -208
- package/dist/ui/components/UpdateNotification.tsx +0 -23
- package/dist/ui/components/WelcomeBackDialog.tsx +0 -290
- package/dist/ui/components/__snapshots__/IDEContextDetailDisplay.test.tsx.snap +0 -24
- package/dist/ui/components/__snapshots__/ModelStatsDisplay.test.tsx.snap +0 -121
- package/dist/ui/components/__snapshots__/SessionSummaryDisplay.test.tsx.snap +0 -30
- package/dist/ui/components/__snapshots__/ShellConfirmationDialog.test.tsx.snap +0 -21
- package/dist/ui/components/__snapshots__/StatsDisplay.test.tsx.snap +0 -264
- package/dist/ui/components/__snapshots__/ToolStatsDisplay.test.tsx.snap +0 -91
- package/dist/ui/components/messages/CompressionMessage.tsx +0 -49
- package/dist/ui/components/messages/DiffRenderer.test.tsx +0 -365
- package/dist/ui/components/messages/DiffRenderer.tsx +0 -358
- package/dist/ui/components/messages/ErrorMessage.tsx +0 -31
- package/dist/ui/components/messages/GeminiMessage.tsx +0 -43
- package/dist/ui/components/messages/GeminiMessageContent.tsx +0 -43
- package/dist/ui/components/messages/InfoMessage.tsx +0 -32
- package/dist/ui/components/messages/ToolConfirmationMessage.test.tsx +0 -58
- package/dist/ui/components/messages/ToolConfirmationMessage.tsx +0 -297
- package/dist/ui/components/messages/ToolGroupMessage.tsx +0 -126
- package/dist/ui/components/messages/ToolMessage.test.tsx +0 -183
- package/dist/ui/components/messages/ToolMessage.tsx +0 -296
- package/dist/ui/components/messages/UserMessage.tsx +0 -43
- package/dist/ui/components/messages/UserShellMessage.tsx +0 -25
- package/dist/ui/components/shared/MaxSizedBox.test.tsx +0 -425
- package/dist/ui/components/shared/MaxSizedBox.tsx +0 -624
- package/dist/ui/components/shared/RadioButtonSelect.test.tsx +0 -181
- package/dist/ui/components/shared/RadioButtonSelect.tsx +0 -234
- package/dist/ui/components/shared/__snapshots__/RadioButtonSelect.test.tsx.snap +0 -47
- package/dist/ui/components/shared/text-buffer.test.ts +0 -1728
- package/dist/ui/components/shared/text-buffer.ts +0 -2227
- package/dist/ui/components/shared/vim-buffer-actions.test.ts +0 -1119
- package/dist/ui/components/shared/vim-buffer-actions.ts +0 -814
- package/dist/ui/constants.ts +0 -17
- package/dist/ui/contexts/KeypressContext.test.tsx +0 -391
- package/dist/ui/contexts/KeypressContext.tsx +0 -440
- package/dist/ui/contexts/OverflowContext.tsx +0 -87
- package/dist/ui/contexts/SessionContext.test.tsx +0 -132
- package/dist/ui/contexts/SessionContext.tsx +0 -143
- package/dist/ui/contexts/SettingsContext.tsx +0 -20
- package/dist/ui/contexts/StreamingContext.tsx +0 -22
- package/dist/ui/contexts/VimModeContext.tsx +0 -79
- package/dist/ui/editors/editorSettingsManager.ts +0 -66
- package/dist/ui/hooks/atCommandProcessor.test.ts +0 -1102
- package/dist/ui/hooks/atCommandProcessor.ts +0 -485
- package/dist/ui/hooks/shellCommandProcessor.test.ts +0 -481
- package/dist/ui/hooks/shellCommandProcessor.ts +0 -314
- package/dist/ui/hooks/slashCommandProcessor.test.ts +0 -1044
- package/dist/ui/hooks/slashCommandProcessor.ts +0 -595
- package/dist/ui/hooks/useAtCompletion.test.ts +0 -497
- package/dist/ui/hooks/useAtCompletion.ts +0 -244
- package/dist/ui/hooks/useAuthCommand.ts +0 -129
- package/dist/ui/hooks/useAutoAcceptIndicator.test.ts +0 -300
- package/dist/ui/hooks/useAutoAcceptIndicator.ts +0 -52
- package/dist/ui/hooks/useBracketedPaste.ts +0 -37
- package/dist/ui/hooks/useCommandCompletion.test.ts +0 -518
- package/dist/ui/hooks/useCommandCompletion.tsx +0 -238
- package/dist/ui/hooks/useCompletion.ts +0 -128
- package/dist/ui/hooks/useConsoleMessages.test.ts +0 -147
- package/dist/ui/hooks/useConsoleMessages.ts +0 -110
- package/dist/ui/hooks/useEditorSettings.test.ts +0 -283
- package/dist/ui/hooks/useEditorSettings.ts +0 -75
- package/dist/ui/hooks/useFocus.test.ts +0 -119
- package/dist/ui/hooks/useFocus.ts +0 -48
- package/dist/ui/hooks/useFolderTrust.test.ts +0 -159
- package/dist/ui/hooks/useFolderTrust.ts +0 -72
- package/dist/ui/hooks/useGeminiStream.test.tsx +0 -1998
- package/dist/ui/hooks/useGeminiStream.ts +0 -1017
- package/dist/ui/hooks/useGitBranchName.test.ts +0 -280
- package/dist/ui/hooks/useGitBranchName.ts +0 -79
- package/dist/ui/hooks/useHistoryManager.test.ts +0 -202
- package/dist/ui/hooks/useHistoryManager.ts +0 -111
- package/dist/ui/hooks/useInputHistory.test.ts +0 -261
- package/dist/ui/hooks/useInputHistory.ts +0 -111
- package/dist/ui/hooks/useKeypress.test.ts +0 -280
- package/dist/ui/hooks/useKeypress.ts +0 -39
- package/dist/ui/hooks/useKittyKeyboardProtocol.ts +0 -31
- package/dist/ui/hooks/useLoadingIndicator.test.ts +0 -139
- package/dist/ui/hooks/useLoadingIndicator.ts +0 -57
- package/dist/ui/hooks/useLogger.ts +0 -32
- package/dist/ui/hooks/useMessageQueue.test.ts +0 -226
- package/dist/ui/hooks/useMessageQueue.ts +0 -69
- package/dist/ui/hooks/usePhraseCycler.test.ts +0 -145
- package/dist/ui/hooks/usePhraseCycler.ts +0 -198
- package/dist/ui/hooks/usePrivacySettings.test.ts +0 -242
- package/dist/ui/hooks/usePrivacySettings.ts +0 -150
- package/dist/ui/hooks/useReactToolScheduler.ts +0 -309
- package/dist/ui/hooks/useRefreshMemoryCommand.ts +0 -7
- package/dist/ui/hooks/useReverseSearchCompletion.test.tsx +0 -260
- package/dist/ui/hooks/useReverseSearchCompletion.tsx +0 -95
- package/dist/ui/hooks/useSettingsCommand.ts +0 -25
- package/dist/ui/hooks/useShellHistory.test.ts +0 -219
- package/dist/ui/hooks/useShellHistory.ts +0 -133
- package/dist/ui/hooks/useShowMemoryCommand.ts +0 -75
- package/dist/ui/hooks/useSlashCompletion.test.ts +0 -434
- package/dist/ui/hooks/useSlashCompletion.ts +0 -187
- package/dist/ui/hooks/useStateAndRef.ts +0 -36
- package/dist/ui/hooks/useTerminalSize.ts +0 -32
- package/dist/ui/hooks/useThemeCommand.ts +0 -110
- package/dist/ui/hooks/useTimer.test.ts +0 -120
- package/dist/ui/hooks/useTimer.ts +0 -65
- package/dist/ui/hooks/useToolScheduler.test.ts +0 -1123
- package/dist/ui/hooks/useWelcomeBack.ts +0 -253
- package/dist/ui/hooks/vim.test.ts +0 -1691
- package/dist/ui/hooks/vim.ts +0 -784
- package/dist/ui/keyMatchers.test.ts +0 -337
- package/dist/ui/keyMatchers.ts +0 -105
- package/dist/ui/privacy/CloudFreePrivacyNotice.tsx +0 -117
- package/dist/ui/privacy/CloudPaidPrivacyNotice.tsx +0 -59
- package/dist/ui/privacy/GeminiPrivacyNotice.tsx +0 -62
- package/dist/ui/privacy/PrivacyNotice.tsx +0 -42
- package/dist/ui/semantic-colors.ts +0 -26
- package/dist/ui/themes/ansi-light.ts +0 -150
- package/dist/ui/themes/ansi.ts +0 -159
- package/dist/ui/themes/atom-one-dark.ts +0 -147
- package/dist/ui/themes/ayu-light.ts +0 -139
- package/dist/ui/themes/ayu.ts +0 -113
- package/dist/ui/themes/color-utils.test.ts +0 -221
- package/dist/ui/themes/color-utils.ts +0 -231
- package/dist/ui/themes/default-light.ts +0 -108
- package/dist/ui/themes/default.ts +0 -151
- package/dist/ui/themes/dracula.ts +0 -124
- package/dist/ui/themes/fss-code-dark.ts +0 -156
- package/dist/ui/themes/fss-dark.ts +0 -113
- package/dist/ui/themes/fss-light.ts +0 -139
- package/dist/ui/themes/github-dark.ts +0 -147
- package/dist/ui/themes/github-light.ts +0 -149
- package/dist/ui/themes/googlecode.ts +0 -146
- package/dist/ui/themes/no-color.ts +0 -125
- package/dist/ui/themes/qwen-dark.ts +0 -118
- package/dist/ui/themes/qwen-light.ts +0 -144
- package/dist/ui/themes/semantic-tokens.ts +0 -127
- package/dist/ui/themes/shades-of-purple.ts +0 -352
- package/dist/ui/themes/theme-manager.test.ts +0 -99
- package/dist/ui/themes/theme-manager.ts +0 -257
- package/dist/ui/themes/theme.test.ts +0 -97
- package/dist/ui/themes/theme.ts +0 -451
- package/dist/ui/themes/xcode.ts +0 -154
- package/dist/ui/types.ts +0 -255
- package/dist/ui/utils/CodeColorizer.tsx +0 -217
- package/dist/ui/utils/ConsolePatcher.ts +0 -71
- package/dist/ui/utils/InlineMarkdownRenderer.tsx +0 -173
- package/dist/ui/utils/MarkdownDisplay.test.tsx +0 -244
- package/dist/ui/utils/MarkdownDisplay.tsx +0 -415
- package/dist/ui/utils/TableRenderer.tsx +0 -159
- package/dist/ui/utils/__snapshots__/MarkdownDisplay.test.tsx.snap +0 -93
- package/dist/ui/utils/clipboardUtils.test.ts +0 -76
- package/dist/ui/utils/clipboardUtils.ts +0 -149
- package/dist/ui/utils/commandUtils.test.ts +0 -384
- package/dist/ui/utils/commandUtils.ts +0 -106
- package/dist/ui/utils/computeStats.test.ts +0 -292
- package/dist/ui/utils/computeStats.ts +0 -86
- package/dist/ui/utils/displayUtils.test.ts +0 -58
- package/dist/ui/utils/displayUtils.ts +0 -32
- package/dist/ui/utils/formatters.test.ts +0 -72
- package/dist/ui/utils/formatters.ts +0 -63
- package/dist/ui/utils/isNarrowWidth.ts +0 -9
- package/dist/ui/utils/kittyProtocolDetector.ts +0 -105
- package/dist/ui/utils/markdownUtilities.test.ts +0 -50
- package/dist/ui/utils/markdownUtilities.ts +0 -125
- package/dist/ui/utils/platformConstants.ts +0 -52
- package/dist/ui/utils/terminalSetup.ts +0 -342
- package/dist/ui/utils/textUtils.ts +0 -40
- package/dist/ui/utils/updateCheck.test.ts +0 -163
- package/dist/ui/utils/updateCheck.ts +0 -100
- package/dist/utils/checks.ts +0 -28
- package/dist/utils/cleanup.test.ts +0 -68
- package/dist/utils/cleanup.ts +0 -36
- package/dist/utils/dialogScopeUtils.ts +0 -64
- package/dist/utils/events.ts +0 -14
- package/dist/utils/gitUtils.test.ts +0 -149
- package/dist/utils/gitUtils.ts +0 -116
- package/dist/utils/handleAutoUpdate.test.ts +0 -272
- package/dist/utils/handleAutoUpdate.ts +0 -145
- package/dist/utils/installationInfo.test.ts +0 -315
- package/dist/utils/installationInfo.ts +0 -176
- package/dist/utils/package.ts +0 -38
- package/dist/utils/readStdin.ts +0 -51
- package/dist/utils/resolvePath.ts +0 -21
- package/dist/utils/sandbox-macos-permissive-closed.sb +0 -32
- package/dist/utils/sandbox-macos-permissive-open.sb +0 -25
- package/dist/utils/sandbox-macos-permissive-proxied.sb +0 -37
- package/dist/utils/sandbox-macos-restrictive-closed.sb +0 -93
- package/dist/utils/sandbox-macos-restrictive-open.sb +0 -96
- package/dist/utils/sandbox-macos-restrictive-proxied.sb +0 -98
- package/dist/utils/sandbox.ts +0 -962
- package/dist/utils/settingsUtils.test.ts +0 -797
- package/dist/utils/settingsUtils.ts +0 -489
- package/dist/utils/spawnWrapper.ts +0 -9
- package/dist/utils/startupWarnings.test.ts +0 -83
- package/dist/utils/startupWarnings.ts +0 -40
- package/dist/utils/updateEventEmitter.ts +0 -13
- package/dist/utils/userStartupWarnings.test.ts +0 -87
- package/dist/utils/userStartupWarnings.ts +0 -69
- package/dist/utils/version.ts +0 -12
- package/dist/validateNonInterActiveAuth.test.ts +0 -260
- package/dist/validateNonInterActiveAuth.ts +0 -51
- package/dist/vitest.config.ts +0 -37
- package/dist/zed-integration/acp.ts +0 -366
- package/dist/zed-integration/fileSystemService.ts +0 -47
- package/dist/zed-integration/schema.ts +0 -466
- package/dist/zed-integration/zedIntegration.ts +0 -944
|
@@ -1,352 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2025 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { vi, describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
8
|
-
import { CommandService } from './CommandService.js';
|
|
9
|
-
import { type ICommandLoader } from './types.js';
|
|
10
|
-
import { CommandKind, type SlashCommand } from '../ui/commands/types.js';
|
|
11
|
-
|
|
12
|
-
const createMockCommand = (name: string, kind: CommandKind): SlashCommand => ({
|
|
13
|
-
name,
|
|
14
|
-
description: `Description for ${name}`,
|
|
15
|
-
kind,
|
|
16
|
-
action: vi.fn(),
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const mockCommandA = createMockCommand('command-a', CommandKind.BUILT_IN);
|
|
20
|
-
const mockCommandB = createMockCommand('command-b', CommandKind.BUILT_IN);
|
|
21
|
-
const mockCommandC = createMockCommand('command-c', CommandKind.FILE);
|
|
22
|
-
const mockCommandB_Override = createMockCommand('command-b', CommandKind.FILE);
|
|
23
|
-
|
|
24
|
-
class MockCommandLoader implements ICommandLoader {
|
|
25
|
-
private commandsToLoad: SlashCommand[];
|
|
26
|
-
|
|
27
|
-
constructor(commandsToLoad: SlashCommand[]) {
|
|
28
|
-
this.commandsToLoad = commandsToLoad;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
loadCommands = vi.fn(
|
|
32
|
-
async (): Promise<SlashCommand[]> => Promise.resolve(this.commandsToLoad),
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
describe('CommandService', () => {
|
|
37
|
-
beforeEach(() => {
|
|
38
|
-
vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
afterEach(() => {
|
|
42
|
-
vi.restoreAllMocks();
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('should load commands from a single loader', async () => {
|
|
46
|
-
const mockLoader = new MockCommandLoader([mockCommandA, mockCommandB]);
|
|
47
|
-
const service = await CommandService.create(
|
|
48
|
-
[mockLoader],
|
|
49
|
-
new AbortController().signal,
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
const commands = service.getCommands();
|
|
53
|
-
|
|
54
|
-
expect(mockLoader.loadCommands).toHaveBeenCalledTimes(1);
|
|
55
|
-
expect(commands).toHaveLength(2);
|
|
56
|
-
expect(commands).toEqual(
|
|
57
|
-
expect.arrayContaining([mockCommandA, mockCommandB]),
|
|
58
|
-
);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('should aggregate commands from multiple loaders', async () => {
|
|
62
|
-
const loader1 = new MockCommandLoader([mockCommandA]);
|
|
63
|
-
const loader2 = new MockCommandLoader([mockCommandC]);
|
|
64
|
-
const service = await CommandService.create(
|
|
65
|
-
[loader1, loader2],
|
|
66
|
-
new AbortController().signal,
|
|
67
|
-
);
|
|
68
|
-
|
|
69
|
-
const commands = service.getCommands();
|
|
70
|
-
|
|
71
|
-
expect(loader1.loadCommands).toHaveBeenCalledTimes(1);
|
|
72
|
-
expect(loader2.loadCommands).toHaveBeenCalledTimes(1);
|
|
73
|
-
expect(commands).toHaveLength(2);
|
|
74
|
-
expect(commands).toEqual(
|
|
75
|
-
expect.arrayContaining([mockCommandA, mockCommandC]),
|
|
76
|
-
);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('should override commands from earlier loaders with those from later loaders', async () => {
|
|
80
|
-
const loader1 = new MockCommandLoader([mockCommandA, mockCommandB]);
|
|
81
|
-
const loader2 = new MockCommandLoader([
|
|
82
|
-
mockCommandB_Override,
|
|
83
|
-
mockCommandC,
|
|
84
|
-
]);
|
|
85
|
-
const service = await CommandService.create(
|
|
86
|
-
[loader1, loader2],
|
|
87
|
-
new AbortController().signal,
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
const commands = service.getCommands();
|
|
91
|
-
|
|
92
|
-
expect(commands).toHaveLength(3); // Should be A, C, and the overridden B.
|
|
93
|
-
|
|
94
|
-
// The final list should contain the override from the *last* loader.
|
|
95
|
-
const commandB = commands.find((cmd) => cmd.name === 'command-b');
|
|
96
|
-
expect(commandB).toBeDefined();
|
|
97
|
-
expect(commandB?.kind).toBe(CommandKind.FILE); // Verify it's the overridden version.
|
|
98
|
-
expect(commandB).toEqual(mockCommandB_Override);
|
|
99
|
-
|
|
100
|
-
// Ensure the other commands are still present.
|
|
101
|
-
expect(commands).toEqual(
|
|
102
|
-
expect.arrayContaining([
|
|
103
|
-
mockCommandA,
|
|
104
|
-
mockCommandC,
|
|
105
|
-
mockCommandB_Override,
|
|
106
|
-
]),
|
|
107
|
-
);
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it('should handle loaders that return an empty array of commands gracefully', async () => {
|
|
111
|
-
const loader1 = new MockCommandLoader([mockCommandA]);
|
|
112
|
-
const emptyLoader = new MockCommandLoader([]);
|
|
113
|
-
const loader3 = new MockCommandLoader([mockCommandB]);
|
|
114
|
-
const service = await CommandService.create(
|
|
115
|
-
[loader1, emptyLoader, loader3],
|
|
116
|
-
new AbortController().signal,
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
const commands = service.getCommands();
|
|
120
|
-
|
|
121
|
-
expect(emptyLoader.loadCommands).toHaveBeenCalledTimes(1);
|
|
122
|
-
expect(commands).toHaveLength(2);
|
|
123
|
-
expect(commands).toEqual(
|
|
124
|
-
expect.arrayContaining([mockCommandA, mockCommandB]),
|
|
125
|
-
);
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it('should load commands from successful loaders even if one fails', async () => {
|
|
129
|
-
const successfulLoader = new MockCommandLoader([mockCommandA]);
|
|
130
|
-
const failingLoader = new MockCommandLoader([]);
|
|
131
|
-
const error = new Error('Loader failed');
|
|
132
|
-
vi.spyOn(failingLoader, 'loadCommands').mockRejectedValue(error);
|
|
133
|
-
|
|
134
|
-
const service = await CommandService.create(
|
|
135
|
-
[successfulLoader, failingLoader],
|
|
136
|
-
new AbortController().signal,
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
const commands = service.getCommands();
|
|
140
|
-
expect(commands).toHaveLength(1);
|
|
141
|
-
expect(commands).toEqual([mockCommandA]);
|
|
142
|
-
expect(console.error).toHaveBeenCalledWith(
|
|
143
|
-
'Command loader failed:',
|
|
144
|
-
error,
|
|
145
|
-
);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it('getCommands should return a readonly array that cannot be mutated', async () => {
|
|
149
|
-
const service = await CommandService.create(
|
|
150
|
-
[new MockCommandLoader([mockCommandA])],
|
|
151
|
-
new AbortController().signal,
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
const commands = service.getCommands();
|
|
155
|
-
|
|
156
|
-
// Expect it to throw a TypeError at runtime because the array is frozen.
|
|
157
|
-
expect(() => {
|
|
158
|
-
// @ts-expect-error - Testing immutability is intentional here.
|
|
159
|
-
commands.push(mockCommandB);
|
|
160
|
-
}).toThrow();
|
|
161
|
-
|
|
162
|
-
// Verify the original array was not mutated.
|
|
163
|
-
expect(service.getCommands()).toHaveLength(1);
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
it('should pass the abort signal to all loaders', async () => {
|
|
167
|
-
const controller = new AbortController();
|
|
168
|
-
const signal = controller.signal;
|
|
169
|
-
|
|
170
|
-
const loader1 = new MockCommandLoader([mockCommandA]);
|
|
171
|
-
const loader2 = new MockCommandLoader([mockCommandB]);
|
|
172
|
-
|
|
173
|
-
await CommandService.create([loader1, loader2], signal);
|
|
174
|
-
|
|
175
|
-
expect(loader1.loadCommands).toHaveBeenCalledTimes(1);
|
|
176
|
-
expect(loader1.loadCommands).toHaveBeenCalledWith(signal);
|
|
177
|
-
expect(loader2.loadCommands).toHaveBeenCalledTimes(1);
|
|
178
|
-
expect(loader2.loadCommands).toHaveBeenCalledWith(signal);
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
it('should rename extension commands when they conflict', async () => {
|
|
182
|
-
const builtinCommand = createMockCommand('deploy', CommandKind.BUILT_IN);
|
|
183
|
-
const userCommand = createMockCommand('sync', CommandKind.FILE);
|
|
184
|
-
const extensionCommand1 = {
|
|
185
|
-
...createMockCommand('deploy', CommandKind.FILE),
|
|
186
|
-
extensionName: 'firebase',
|
|
187
|
-
description: '[firebase] Deploy to Firebase',
|
|
188
|
-
};
|
|
189
|
-
const extensionCommand2 = {
|
|
190
|
-
...createMockCommand('sync', CommandKind.FILE),
|
|
191
|
-
extensionName: 'git-helper',
|
|
192
|
-
description: '[git-helper] Sync with remote',
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
const mockLoader1 = new MockCommandLoader([builtinCommand]);
|
|
196
|
-
const mockLoader2 = new MockCommandLoader([
|
|
197
|
-
userCommand,
|
|
198
|
-
extensionCommand1,
|
|
199
|
-
extensionCommand2,
|
|
200
|
-
]);
|
|
201
|
-
|
|
202
|
-
const service = await CommandService.create(
|
|
203
|
-
[mockLoader1, mockLoader2],
|
|
204
|
-
new AbortController().signal,
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
const commands = service.getCommands();
|
|
208
|
-
expect(commands).toHaveLength(4);
|
|
209
|
-
|
|
210
|
-
// Built-in command keeps original name
|
|
211
|
-
const deployBuiltin = commands.find(
|
|
212
|
-
(cmd) => cmd.name === 'deploy' && !cmd.extensionName,
|
|
213
|
-
);
|
|
214
|
-
expect(deployBuiltin).toBeDefined();
|
|
215
|
-
expect(deployBuiltin?.kind).toBe(CommandKind.BUILT_IN);
|
|
216
|
-
|
|
217
|
-
// Extension command conflicting with built-in gets renamed
|
|
218
|
-
const deployExtension = commands.find(
|
|
219
|
-
(cmd) => cmd.name === 'firebase.deploy',
|
|
220
|
-
);
|
|
221
|
-
expect(deployExtension).toBeDefined();
|
|
222
|
-
expect(deployExtension?.extensionName).toBe('firebase');
|
|
223
|
-
|
|
224
|
-
// User command keeps original name
|
|
225
|
-
const syncUser = commands.find(
|
|
226
|
-
(cmd) => cmd.name === 'sync' && !cmd.extensionName,
|
|
227
|
-
);
|
|
228
|
-
expect(syncUser).toBeDefined();
|
|
229
|
-
expect(syncUser?.kind).toBe(CommandKind.FILE);
|
|
230
|
-
|
|
231
|
-
// Extension command conflicting with user command gets renamed
|
|
232
|
-
const syncExtension = commands.find(
|
|
233
|
-
(cmd) => cmd.name === 'git-helper.sync',
|
|
234
|
-
);
|
|
235
|
-
expect(syncExtension).toBeDefined();
|
|
236
|
-
expect(syncExtension?.extensionName).toBe('git-helper');
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
it('should handle user/project command override correctly', async () => {
|
|
240
|
-
const builtinCommand = createMockCommand('help', CommandKind.BUILT_IN);
|
|
241
|
-
const userCommand = createMockCommand('help', CommandKind.FILE);
|
|
242
|
-
const projectCommand = createMockCommand('deploy', CommandKind.FILE);
|
|
243
|
-
const userDeployCommand = createMockCommand('deploy', CommandKind.FILE);
|
|
244
|
-
|
|
245
|
-
const mockLoader1 = new MockCommandLoader([builtinCommand]);
|
|
246
|
-
const mockLoader2 = new MockCommandLoader([
|
|
247
|
-
userCommand,
|
|
248
|
-
userDeployCommand,
|
|
249
|
-
projectCommand,
|
|
250
|
-
]);
|
|
251
|
-
|
|
252
|
-
const service = await CommandService.create(
|
|
253
|
-
[mockLoader1, mockLoader2],
|
|
254
|
-
new AbortController().signal,
|
|
255
|
-
);
|
|
256
|
-
|
|
257
|
-
const commands = service.getCommands();
|
|
258
|
-
expect(commands).toHaveLength(2);
|
|
259
|
-
|
|
260
|
-
// User command overrides built-in
|
|
261
|
-
const helpCommand = commands.find((cmd) => cmd.name === 'help');
|
|
262
|
-
expect(helpCommand).toBeDefined();
|
|
263
|
-
expect(helpCommand?.kind).toBe(CommandKind.FILE);
|
|
264
|
-
|
|
265
|
-
// Project command overrides user command (last wins)
|
|
266
|
-
const deployCommand = commands.find((cmd) => cmd.name === 'deploy');
|
|
267
|
-
expect(deployCommand).toBeDefined();
|
|
268
|
-
expect(deployCommand?.kind).toBe(CommandKind.FILE);
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
it('should handle secondary conflicts when renaming extension commands', async () => {
|
|
272
|
-
// User has both /deploy and /gcp.deploy commands
|
|
273
|
-
const userCommand1 = createMockCommand('deploy', CommandKind.FILE);
|
|
274
|
-
const userCommand2 = createMockCommand('gcp.deploy', CommandKind.FILE);
|
|
275
|
-
|
|
276
|
-
// Extension also has a deploy command that will conflict with user's /deploy
|
|
277
|
-
const extensionCommand = {
|
|
278
|
-
...createMockCommand('deploy', CommandKind.FILE),
|
|
279
|
-
extensionName: 'gcp',
|
|
280
|
-
description: '[gcp] Deploy to Google Cloud',
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
const mockLoader = new MockCommandLoader([
|
|
284
|
-
userCommand1,
|
|
285
|
-
userCommand2,
|
|
286
|
-
extensionCommand,
|
|
287
|
-
]);
|
|
288
|
-
|
|
289
|
-
const service = await CommandService.create(
|
|
290
|
-
[mockLoader],
|
|
291
|
-
new AbortController().signal,
|
|
292
|
-
);
|
|
293
|
-
|
|
294
|
-
const commands = service.getCommands();
|
|
295
|
-
expect(commands).toHaveLength(3);
|
|
296
|
-
|
|
297
|
-
// Original user command keeps its name
|
|
298
|
-
const deployUser = commands.find(
|
|
299
|
-
(cmd) => cmd.name === 'deploy' && !cmd.extensionName,
|
|
300
|
-
);
|
|
301
|
-
expect(deployUser).toBeDefined();
|
|
302
|
-
|
|
303
|
-
// User's dot notation command keeps its name
|
|
304
|
-
const gcpDeployUser = commands.find(
|
|
305
|
-
(cmd) => cmd.name === 'gcp.deploy' && !cmd.extensionName,
|
|
306
|
-
);
|
|
307
|
-
expect(gcpDeployUser).toBeDefined();
|
|
308
|
-
|
|
309
|
-
// Extension command gets renamed with suffix due to secondary conflict
|
|
310
|
-
const deployExtension = commands.find(
|
|
311
|
-
(cmd) => cmd.name === 'gcp.deploy1' && cmd.extensionName === 'gcp',
|
|
312
|
-
);
|
|
313
|
-
expect(deployExtension).toBeDefined();
|
|
314
|
-
expect(deployExtension?.description).toBe('[gcp] Deploy to Google Cloud');
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
it('should handle multiple secondary conflicts with incrementing suffixes', async () => {
|
|
318
|
-
// User has /deploy, /gcp.deploy, and /gcp.deploy1
|
|
319
|
-
const userCommand1 = createMockCommand('deploy', CommandKind.FILE);
|
|
320
|
-
const userCommand2 = createMockCommand('gcp.deploy', CommandKind.FILE);
|
|
321
|
-
const userCommand3 = createMockCommand('gcp.deploy1', CommandKind.FILE);
|
|
322
|
-
|
|
323
|
-
// Extension has a deploy command
|
|
324
|
-
const extensionCommand = {
|
|
325
|
-
...createMockCommand('deploy', CommandKind.FILE),
|
|
326
|
-
extensionName: 'gcp',
|
|
327
|
-
description: '[gcp] Deploy to Google Cloud',
|
|
328
|
-
};
|
|
329
|
-
|
|
330
|
-
const mockLoader = new MockCommandLoader([
|
|
331
|
-
userCommand1,
|
|
332
|
-
userCommand2,
|
|
333
|
-
userCommand3,
|
|
334
|
-
extensionCommand,
|
|
335
|
-
]);
|
|
336
|
-
|
|
337
|
-
const service = await CommandService.create(
|
|
338
|
-
[mockLoader],
|
|
339
|
-
new AbortController().signal,
|
|
340
|
-
);
|
|
341
|
-
|
|
342
|
-
const commands = service.getCommands();
|
|
343
|
-
expect(commands).toHaveLength(4);
|
|
344
|
-
|
|
345
|
-
// Extension command gets renamed with suffix 2 due to multiple conflicts
|
|
346
|
-
const deployExtension = commands.find(
|
|
347
|
-
(cmd) => cmd.name === 'gcp.deploy2' && cmd.extensionName === 'gcp',
|
|
348
|
-
);
|
|
349
|
-
expect(deployExtension).toBeDefined();
|
|
350
|
-
expect(deployExtension?.description).toBe('[gcp] Deploy to Google Cloud');
|
|
351
|
-
});
|
|
352
|
-
});
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2025 Google LLC
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { SlashCommand } from '../ui/commands/types.js';
|
|
8
|
-
import { ICommandLoader } from './types.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Orchestrates the discovery and loading of all slash commands for the CLI.
|
|
12
|
-
*
|
|
13
|
-
* This service operates on a provider-based loader pattern. It is initialized
|
|
14
|
-
* with an array of `ICommandLoader` instances, each responsible for fetching
|
|
15
|
-
* commands from a specific source (e.g., built-in code, local files).
|
|
16
|
-
*
|
|
17
|
-
* The CommandService is responsible for invoking these loaders, aggregating their
|
|
18
|
-
* results, and resolving any name conflicts. This architecture allows the command
|
|
19
|
-
* system to be extended with new sources without modifying the service itself.
|
|
20
|
-
*/
|
|
21
|
-
export class CommandService {
|
|
22
|
-
/**
|
|
23
|
-
* Private constructor to enforce the use of the async factory.
|
|
24
|
-
* @param commands A readonly array of the fully loaded and de-duplicated commands.
|
|
25
|
-
*/
|
|
26
|
-
private constructor(private readonly commands: readonly SlashCommand[]) {}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Asynchronously creates and initializes a new CommandService instance.
|
|
30
|
-
*
|
|
31
|
-
* This factory method orchestrates the entire command loading process. It
|
|
32
|
-
* runs all provided loaders in parallel, aggregates their results, handles
|
|
33
|
-
* name conflicts for extension commands by renaming them, and then returns a
|
|
34
|
-
* fully constructed `CommandService` instance.
|
|
35
|
-
*
|
|
36
|
-
* Conflict resolution:
|
|
37
|
-
* - Extension commands that conflict with existing commands are renamed to
|
|
38
|
-
* `extensionName.commandName`
|
|
39
|
-
* - Non-extension commands (built-in, user, project) override earlier commands
|
|
40
|
-
* with the same name based on loader order
|
|
41
|
-
*
|
|
42
|
-
* @param loaders An array of objects that conform to the `ICommandLoader`
|
|
43
|
-
* interface. Built-in commands should come first, followed by FileCommandLoader.
|
|
44
|
-
* @param signal An AbortSignal to cancel the loading process.
|
|
45
|
-
* @returns A promise that resolves to a new, fully initialized `CommandService` instance.
|
|
46
|
-
*/
|
|
47
|
-
static async create(
|
|
48
|
-
loaders: ICommandLoader[],
|
|
49
|
-
signal: AbortSignal,
|
|
50
|
-
): Promise<CommandService> {
|
|
51
|
-
const results = await Promise.allSettled(
|
|
52
|
-
loaders.map((loader) => loader.loadCommands(signal)),
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
const allCommands: SlashCommand[] = [];
|
|
56
|
-
for (const result of results) {
|
|
57
|
-
if (result.status === 'fulfilled') {
|
|
58
|
-
allCommands.push(...result.value);
|
|
59
|
-
} else {
|
|
60
|
-
console.error('Command loader failed:', result.reason);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const commandMap = new Map<string, SlashCommand>();
|
|
65
|
-
for (const cmd of allCommands) {
|
|
66
|
-
let finalName = cmd.name;
|
|
67
|
-
|
|
68
|
-
// Extension commands get renamed if they conflict with existing commands
|
|
69
|
-
if (cmd.extensionName && commandMap.has(cmd.name)) {
|
|
70
|
-
let renamedName = `${cmd.extensionName}.${cmd.name}`;
|
|
71
|
-
let suffix = 1;
|
|
72
|
-
|
|
73
|
-
// Keep trying until we find a name that doesn't conflict
|
|
74
|
-
while (commandMap.has(renamedName)) {
|
|
75
|
-
renamedName = `${cmd.extensionName}.${cmd.name}${suffix}`;
|
|
76
|
-
suffix++;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
finalName = renamedName;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
commandMap.set(finalName, {
|
|
83
|
-
...cmd,
|
|
84
|
-
name: finalName,
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const finalCommands = Object.freeze(Array.from(commandMap.values()));
|
|
89
|
-
return new CommandService(finalCommands);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Retrieves the currently loaded and de-duplicated list of slash commands.
|
|
94
|
-
*
|
|
95
|
-
* This method is a safe accessor for the service's state. It returns a
|
|
96
|
-
* readonly array, preventing consumers from modifying the service's internal state.
|
|
97
|
-
*
|
|
98
|
-
* @returns A readonly, unified array of available `SlashCommand` objects.
|
|
99
|
-
*/
|
|
100
|
-
getCommands(): readonly SlashCommand[] {
|
|
101
|
-
return this.commands;
|
|
102
|
-
}
|
|
103
|
-
}
|