@vybestack/llxprt-code 0.5.0 → 0.6.0
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/README.md +0 -244
- package/dist/package.json +15 -6
- package/dist/src/auth/gemini-oauth-provider.d.ts +18 -0
- package/dist/src/auth/gemini-oauth-provider.js +140 -78
- package/dist/src/auth/gemini-oauth-provider.js.map +1 -1
- package/dist/src/auth/local-oauth-callback.spec.js +29 -2
- package/dist/src/auth/local-oauth-callback.spec.js.map +1 -1
- package/dist/src/commands/extensions/disable.d.ts +1 -2
- package/dist/src/commands/extensions/disable.js +15 -3
- package/dist/src/commands/extensions/disable.js.map +1 -1
- package/dist/src/commands/extensions/enable.d.ts +1 -2
- package/dist/src/commands/extensions/enable.js +17 -6
- package/dist/src/commands/extensions/enable.js.map +1 -1
- package/dist/src/commands/extensions/install.d.ts +3 -1
- package/dist/src/commands/extensions/install.js +63 -12
- package/dist/src/commands/extensions/install.js.map +1 -1
- package/dist/src/commands/extensions/install.test.js +166 -13
- package/dist/src/commands/extensions/install.test.js.map +1 -1
- package/dist/src/commands/extensions/link.js +2 -2
- package/dist/src/commands/extensions/link.js.map +1 -1
- package/dist/src/commands/extensions/list.d.ts +1 -1
- package/dist/src/commands/extensions/list.js +3 -2
- package/dist/src/commands/extensions/list.js.map +1 -1
- package/dist/src/commands/extensions/new.test.js +2 -2
- package/dist/src/commands/extensions/new.test.js.map +1 -1
- package/dist/src/commands/extensions/uninstall.js +1 -1
- package/dist/src/commands/extensions/uninstall.js.map +1 -1
- package/dist/src/commands/extensions/uninstall.test.js +4 -1
- package/dist/src/commands/extensions/uninstall.test.js.map +1 -1
- package/dist/src/commands/extensions/update.d.ts +2 -2
- package/dist/src/commands/extensions/update.js +68 -19
- package/dist/src/commands/extensions/update.js.map +1 -1
- package/dist/src/commands/mcp/add.js +6 -1
- package/dist/src/commands/mcp/add.js.map +1 -1
- package/dist/src/commands/mcp/list.js +3 -2
- package/dist/src/commands/mcp/list.js.map +1 -1
- package/dist/src/config/__tests__/profileBootstrap.test.js +1351 -1
- package/dist/src/config/__tests__/profileBootstrap.test.js.map +1 -1
- package/dist/src/config/config.d.ts +4 -1
- package/dist/src/config/config.js +172 -69
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.loadMemory.test.js +6 -3
- package/dist/src/config/config.loadMemory.test.js.map +1 -1
- package/dist/src/config/extension.d.ts +48 -14
- package/dist/src/config/extension.js +263 -142
- package/dist/src/config/extension.js.map +1 -1
- package/dist/src/config/extensions/extensionEnablement.d.ts +47 -0
- package/dist/src/config/extensions/extensionEnablement.js +188 -0
- package/dist/src/config/extensions/extensionEnablement.js.map +1 -0
- package/dist/src/config/extensions/extensionEnablement.test.d.ts +6 -0
- package/dist/src/config/extensions/extensionEnablement.test.js +333 -0
- package/dist/src/config/extensions/extensionEnablement.test.js.map +1 -0
- package/dist/src/config/extensions/github.d.ts +37 -0
- package/dist/src/config/extensions/github.js +348 -0
- package/dist/src/config/extensions/github.js.map +1 -0
- package/dist/src/config/extensions/github.test.d.ts +6 -0
- package/dist/src/config/extensions/github.test.js +340 -0
- package/dist/src/config/extensions/github.test.js.map +1 -0
- package/dist/src/config/extensions/update.d.ts +19 -0
- package/dist/src/config/extensions/update.js +118 -0
- package/dist/src/config/extensions/update.js.map +1 -0
- package/dist/src/config/extensions/update.test.d.ts +6 -0
- package/dist/src/config/extensions/update.test.js +340 -0
- package/dist/src/config/extensions/update.test.js.map +1 -0
- package/dist/src/config/extensions/variableSchema.d.ts +8 -0
- package/dist/src/config/extensions/variableSchema.js +4 -0
- package/dist/src/config/extensions/variableSchema.js.map +1 -1
- package/dist/src/config/keyBindings.d.ts +1 -0
- package/dist/src/config/keyBindings.js +3 -1
- package/dist/src/config/keyBindings.js.map +1 -1
- package/dist/src/config/paths.d.ts +8 -0
- package/dist/src/config/paths.js +11 -0
- package/dist/src/config/paths.js.map +1 -0
- package/dist/src/config/profileBootstrap.d.ts +13 -0
- package/dist/src/config/profileBootstrap.js +369 -15
- package/dist/src/config/profileBootstrap.js.map +1 -1
- package/dist/src/config/settings.d.ts +14 -4
- package/dist/src/config/settings.js +161 -99
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +510 -216
- package/dist/src/config/settingsSchema.js +468 -214
- package/dist/src/config/settingsSchema.js.map +1 -1
- package/dist/src/config/settingsSchema.test.js +18 -31
- package/dist/src/config/settingsSchema.test.js.map +1 -1
- package/dist/src/config/trustedFolders.d.ts +6 -3
- package/dist/src/config/trustedFolders.js +35 -13
- package/dist/src/config/trustedFolders.js.map +1 -1
- package/dist/src/config/trustedFolders.test.js +83 -9
- package/dist/src/config/trustedFolders.test.js.map +1 -1
- package/dist/src/coreToolToggle.test.d.ts +6 -0
- package/dist/src/coreToolToggle.test.js +427 -0
- package/dist/src/coreToolToggle.test.js.map +1 -0
- package/dist/src/extensions/extensionAutoUpdater.d.ts +76 -0
- package/dist/src/extensions/extensionAutoUpdater.js +279 -0
- package/dist/src/extensions/extensionAutoUpdater.js.map +1 -0
- package/dist/src/extensions/extensionAutoUpdater.test.d.ts +6 -0
- package/dist/src/extensions/extensionAutoUpdater.test.js +146 -0
- package/dist/src/extensions/extensionAutoUpdater.test.js.map +1 -0
- package/dist/src/gemini.js +93 -63
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.js +121 -1
- package/dist/src/gemini.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +1 -1
- package/dist/src/generated/git-commit.js +1 -1
- package/dist/src/generated/git-commit.js.map +1 -1
- package/dist/src/integration-tests/cli-args.integration.test.js +299 -0
- package/dist/src/integration-tests/cli-args.integration.test.js.map +1 -1
- package/dist/src/nonInteractiveCli.d.ts +2 -1
- package/dist/src/nonInteractiveCli.js +29 -16
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/nonInteractiveCliCommands.d.ts +17 -0
- package/dist/src/nonInteractiveCliCommands.js +81 -0
- package/dist/src/nonInteractiveCliCommands.js.map +1 -0
- package/dist/src/runtime/runtimeSettings.test.js +2 -0
- package/dist/src/runtime/runtimeSettings.test.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.d.ts +3 -3
- package/dist/src/services/BuiltinCommandLoader.js +7 -0
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.test.js +37 -0
- package/dist/src/services/BuiltinCommandLoader.test.js.map +1 -1
- package/dist/src/services/McpPromptLoader.js +39 -34
- package/dist/src/services/McpPromptLoader.js.map +1 -1
- package/dist/src/settings/ephemeralSettings.js +56 -0
- package/dist/src/settings/ephemeralSettings.js.map +1 -1
- package/dist/src/test-utils/createExtension.d.ts +15 -0
- package/dist/src/test-utils/createExtension.js +24 -0
- package/dist/src/test-utils/createExtension.js.map +1 -0
- package/dist/src/test-utils/mockCommandContext.js +4 -2
- package/dist/src/test-utils/mockCommandContext.js.map +1 -1
- package/dist/src/test-utils/render.d.ts +3 -1
- package/dist/src/test-utils/render.js +4 -1
- package/dist/src/test-utils/render.js.map +1 -1
- package/dist/src/ui/App.d.ts +18 -3
- package/dist/src/ui/App.js +32 -873
- package/dist/src/ui/App.js.map +1 -1
- package/dist/src/ui/AppContainer.d.ts +19 -0
- package/dist/src/ui/AppContainer.js +1187 -0
- package/dist/src/ui/AppContainer.js.map +1 -0
- package/dist/src/ui/IdeIntegrationNudge.d.ts +2 -2
- package/dist/src/ui/IdeIntegrationNudge.js +4 -7
- package/dist/src/ui/IdeIntegrationNudge.js.map +1 -1
- package/dist/src/ui/commands/chatCommand.js +214 -58
- package/dist/src/ui/commands/chatCommand.js.map +1 -1
- package/dist/src/ui/commands/clearCommand.js +1 -2
- package/dist/src/ui/commands/clearCommand.js.map +1 -1
- package/dist/src/ui/commands/diagnosticsCommand.js +2 -2
- package/dist/src/ui/commands/diagnosticsCommand.js.map +1 -1
- package/dist/src/ui/commands/directoryCommand.js +3 -2
- package/dist/src/ui/commands/directoryCommand.js.map +1 -1
- package/dist/src/ui/commands/docsCommand.js +1 -1
- package/dist/src/ui/commands/docsCommand.js.map +1 -1
- package/dist/src/ui/commands/extensionsCommand.d.ts +1 -1
- package/dist/src/ui/commands/extensionsCommand.js +92 -17
- package/dist/src/ui/commands/extensionsCommand.js.map +1 -1
- package/dist/src/ui/commands/helpCommand.js +6 -5
- package/dist/src/ui/commands/helpCommand.js.map +1 -1
- package/dist/src/ui/commands/ideCommand.js +7 -7
- package/dist/src/ui/commands/ideCommand.js.map +1 -1
- package/dist/src/ui/commands/loggingCommand.js +1 -1
- package/dist/src/ui/commands/loggingCommand.js.map +1 -1
- package/dist/src/ui/commands/mcpCommand.js +11 -3
- package/dist/src/ui/commands/mcpCommand.js.map +1 -1
- package/dist/src/ui/commands/memoryCommand.js +21 -3
- package/dist/src/ui/commands/memoryCommand.js.map +1 -1
- package/dist/src/ui/commands/permissionsCommand.d.ts +7 -0
- package/dist/src/ui/commands/permissionsCommand.js +16 -0
- package/dist/src/ui/commands/permissionsCommand.js.map +1 -0
- package/dist/src/ui/commands/permissionsCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/permissionsCommand.test.js +55 -0
- package/dist/src/ui/commands/permissionsCommand.test.js.map +1 -0
- package/dist/src/ui/commands/policiesCommand.d.ts +10 -0
- package/dist/src/ui/commands/policiesCommand.js +112 -0
- package/dist/src/ui/commands/policiesCommand.js.map +1 -0
- package/dist/src/ui/commands/policiesCommand.test.d.ts +6 -0
- package/dist/src/ui/commands/policiesCommand.test.js +224 -0
- package/dist/src/ui/commands/policiesCommand.test.js.map +1 -0
- package/dist/src/ui/commands/setCommand.js +105 -30
- package/dist/src/ui/commands/setCommand.js.map +1 -1
- package/dist/src/ui/commands/setCommand.test.js +1 -1
- package/dist/src/ui/commands/setCommand.test.js.map +1 -1
- package/dist/src/ui/commands/statsCommand.js +11 -1
- package/dist/src/ui/commands/statsCommand.js.map +1 -1
- package/dist/src/ui/commands/test/subagentCommand.test.js +6 -1
- package/dist/src/ui/commands/test/subagentCommand.test.js.map +1 -1
- package/dist/src/ui/commands/types.d.ts +19 -23
- package/dist/src/ui/commands/types.js +1 -1
- package/dist/src/ui/commands/types.js.map +1 -1
- package/dist/src/ui/commands/uiprofileCommand.d.ts +7 -0
- package/dist/src/ui/commands/uiprofileCommand.js +23 -0
- package/dist/src/ui/commands/uiprofileCommand.js.map +1 -0
- package/dist/src/ui/components/AuthDialog.js +4 -0
- package/dist/src/ui/components/AuthDialog.js.map +1 -1
- package/dist/src/ui/components/AuthDialog.test.js +32 -32
- package/dist/src/ui/components/AuthDialog.test.js.map +1 -1
- package/dist/src/ui/components/CacheStatsDisplay.d.ts +7 -0
- package/dist/src/ui/components/CacheStatsDisplay.js +35 -0
- package/dist/src/ui/components/CacheStatsDisplay.js.map +1 -0
- package/dist/src/ui/components/CacheStatsDisplay.test.d.ts +6 -0
- package/dist/src/ui/components/CacheStatsDisplay.test.js +118 -0
- package/dist/src/ui/components/CacheStatsDisplay.test.js.map +1 -0
- package/dist/src/ui/components/CliSpinner.d.ts +10 -0
- package/dist/src/ui/components/CliSpinner.js +20 -0
- package/dist/src/ui/components/CliSpinner.js.map +1 -0
- package/dist/src/ui/components/Composer.d.ts +17 -0
- package/dist/src/ui/components/Composer.js +16 -0
- package/dist/src/ui/components/Composer.js.map +1 -0
- package/dist/src/ui/components/ConsentPrompt.d.ts +13 -0
- package/dist/src/ui/components/ConsentPrompt.js +18 -0
- package/dist/src/ui/components/ConsentPrompt.js.map +1 -0
- package/dist/src/ui/components/ConsentPrompt.test.d.ts +6 -0
- package/dist/src/ui/components/ConsentPrompt.test.js +67 -0
- package/dist/src/ui/components/ConsentPrompt.test.js.map +1 -0
- package/dist/src/ui/components/DebugProfiler.d.ts +15 -0
- package/dist/src/ui/components/DebugProfiler.js +137 -13
- package/dist/src/ui/components/DebugProfiler.js.map +1 -1
- package/dist/src/ui/components/DebugProfiler.test.d.ts +6 -0
- package/dist/src/ui/components/DebugProfiler.test.js +131 -0
- package/dist/src/ui/components/DebugProfiler.test.js.map +1 -0
- package/dist/src/ui/components/DialogManager.d.ts +16 -0
- package/dist/src/ui/components/DialogManager.js +131 -0
- package/dist/src/ui/components/DialogManager.js.map +1 -0
- package/dist/src/ui/components/EditorSettingsDialog.js +18 -8
- package/dist/src/ui/components/EditorSettingsDialog.js.map +1 -1
- package/dist/src/ui/components/FolderTrustDialog.js +4 -0
- package/dist/src/ui/components/FolderTrustDialog.js.map +1 -1
- package/dist/src/ui/components/FolderTrustDialog.test.js +2 -2
- package/dist/src/ui/components/FolderTrustDialog.test.js.map +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.d.ts +6 -2
- package/dist/src/ui/components/HistoryItemDisplay.js +10 -2
- package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.test.js +90 -10
- package/dist/src/ui/components/HistoryItemDisplay.test.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.d.ts +6 -0
- package/dist/src/ui/components/InputPrompt.js +52 -18
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/LoadProfileDialog.js +13 -9
- package/dist/src/ui/components/LoadProfileDialog.js.map +1 -1
- package/dist/src/ui/components/LoadingIndicator.js +1 -1
- package/dist/src/ui/components/LoadingIndicator.js.map +1 -1
- package/dist/src/ui/components/LoadingIndicator.test.js +6 -0
- package/dist/src/ui/components/LoadingIndicator.test.js.map +1 -1
- package/dist/src/ui/components/LoggingDialog.js +14 -10
- package/dist/src/ui/components/LoggingDialog.js.map +1 -1
- package/dist/src/ui/components/Notifications.d.ts +14 -0
- package/dist/src/ui/components/Notifications.js +34 -0
- package/dist/src/ui/components/Notifications.js.map +1 -0
- package/dist/src/ui/components/OAuthCodeDialog.js +2 -1
- package/dist/src/ui/components/OAuthCodeDialog.js.map +1 -1
- package/dist/src/ui/components/PermissionsModifyTrustDialog.d.ts +14 -0
- package/dist/src/ui/components/PermissionsModifyTrustDialog.js +115 -0
- package/dist/src/ui/components/PermissionsModifyTrustDialog.js.map +1 -0
- package/dist/src/ui/components/PermissionsModifyTrustDialog.test.d.ts +6 -0
- package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js +98 -0
- package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js.map +1 -0
- package/dist/src/ui/components/ProviderDialog.js +23 -18
- package/dist/src/ui/components/ProviderDialog.js.map +1 -1
- package/dist/src/ui/components/ProviderModelDialog.js +24 -18
- package/dist/src/ui/components/ProviderModelDialog.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.d.ts +12 -2
- package/dist/src/ui/components/SettingsDialog.js +253 -23
- package/dist/src/ui/components/SettingsDialog.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.test.js +90 -8
- package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
- package/dist/src/ui/components/ShellConfirmationDialog.js +3 -0
- package/dist/src/ui/components/ShellConfirmationDialog.js.map +1 -1
- package/dist/src/ui/components/ThemeDialog.js +6 -4
- package/dist/src/ui/components/ThemeDialog.js.map +1 -1
- package/dist/src/ui/components/ToolsDialog.js +6 -4
- package/dist/src/ui/components/ToolsDialog.js.map +1 -1
- package/dist/src/ui/components/WorkspaceMigrationDialog.js +5 -3
- package/dist/src/ui/components/WorkspaceMigrationDialog.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js +37 -6
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js +9 -0
- package/dist/src/ui/components/messages/ToolConfirmationMessage.test.js.map +1 -1
- package/dist/src/ui/components/messages/ToolGroupMessage.js +7 -3
- package/dist/src/ui/components/messages/ToolGroupMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolMessage.js +7 -3
- package/dist/src/ui/components/messages/ToolMessage.js.map +1 -1
- package/dist/src/ui/components/messages/WarningMessage.d.ts +11 -0
- package/dist/src/ui/components/messages/WarningMessage.js +10 -0
- package/dist/src/ui/components/messages/WarningMessage.js.map +1 -0
- package/dist/src/ui/components/messages/WarningMessage.test.d.ts +6 -0
- package/dist/src/ui/components/messages/WarningMessage.test.js +15 -0
- package/dist/src/ui/components/messages/WarningMessage.test.js.map +1 -0
- package/dist/src/ui/components/shared/BaseSelectionList.d.ts +38 -0
- package/dist/src/ui/components/shared/BaseSelectionList.js +76 -0
- package/dist/src/ui/components/shared/BaseSelectionList.js.map +1 -0
- package/dist/src/ui/components/shared/BaseSelectionList.test.d.ts +6 -0
- package/dist/src/ui/components/shared/BaseSelectionList.test.js +376 -0
- package/dist/src/ui/components/shared/BaseSelectionList.test.js.map +1 -0
- package/dist/src/ui/components/shared/RadioButtonSelect.d.ts +4 -5
- package/dist/src/ui/components/shared/RadioButtonSelect.js +11 -117
- package/dist/src/ui/components/shared/RadioButtonSelect.js.map +1 -1
- package/dist/src/ui/components/shared/RadioButtonSelect.test.d.ts +1 -1
- package/dist/src/ui/components/shared/RadioButtonSelect.test.js +116 -95
- package/dist/src/ui/components/shared/RadioButtonSelect.test.js.map +1 -1
- package/dist/src/ui/components/shared/text-buffer.d.ts +6 -0
- package/dist/src/ui/components/shared/text-buffer.js +71 -4
- package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
- package/dist/src/ui/components/views/ChatList.d.ts +12 -0
- package/dist/src/ui/components/views/ChatList.js +17 -0
- package/dist/src/ui/components/views/ChatList.js.map +1 -0
- package/dist/src/ui/components/views/ChatList.test.d.ts +6 -0
- package/dist/src/ui/components/views/ChatList.test.js +42 -0
- package/dist/src/ui/components/views/ChatList.test.js.map +1 -0
- package/dist/src/ui/constants.d.ts +1 -0
- package/dist/src/ui/constants.js +1 -0
- package/dist/src/ui/constants.js.map +1 -1
- package/dist/src/ui/contexts/FocusContext.d.ts +7 -0
- package/dist/src/ui/contexts/FocusContext.js +9 -0
- package/dist/src/ui/contexts/FocusContext.js.map +1 -0
- package/dist/src/ui/contexts/KeypressContext.d.ts +1 -1
- package/dist/src/ui/contexts/KeypressContext.js +63 -4
- package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.test.js +156 -0
- package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
- package/dist/src/ui/contexts/SessionContext.d.ts +6 -0
- package/dist/src/ui/contexts/SessionContext.js +107 -5
- package/dist/src/ui/contexts/SessionContext.js.map +1 -1
- package/dist/src/ui/contexts/UIActionsContext.d.ts +82 -0
- package/dist/src/ui/contexts/UIActionsContext.js +20 -0
- package/dist/src/ui/contexts/UIActionsContext.js.map +1 -0
- package/dist/src/ui/contexts/UIStateContext.d.ts +121 -0
- package/dist/src/ui/contexts/UIStateContext.js +20 -0
- package/dist/src/ui/contexts/UIStateContext.js.map +1 -0
- package/dist/src/ui/contexts/VimModeContext.js +4 -4
- package/dist/src/ui/contexts/VimModeContext.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.d.ts +29 -6
- package/dist/src/ui/hooks/slashCommandProcessor.js +150 -155
- package/dist/src/ui/hooks/slashCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/useBracketedPaste.js +3 -4
- package/dist/src/ui/hooks/useBracketedPaste.js.map +1 -1
- package/dist/src/ui/hooks/useEditorSettings.js +1 -1
- package/dist/src/ui/hooks/useEditorSettings.js.map +1 -1
- package/dist/src/ui/hooks/useExtensionAutoUpdate.d.ts +13 -0
- package/dist/src/ui/hooks/useExtensionAutoUpdate.js +40 -0
- package/dist/src/ui/hooks/useExtensionAutoUpdate.js.map +1 -0
- package/dist/src/ui/hooks/useExtensionUpdates.d.ts +21 -0
- package/dist/src/ui/hooks/useExtensionUpdates.js +168 -0
- package/dist/src/ui/hooks/useExtensionUpdates.js.map +1 -0
- package/dist/src/ui/hooks/useExtensionUpdates.test.d.ts +6 -0
- package/dist/src/ui/hooks/useExtensionUpdates.test.js +243 -0
- package/dist/src/ui/hooks/useExtensionUpdates.test.js.map +1 -0
- package/dist/src/ui/hooks/useFlickerDetector.d.ts +22 -0
- package/dist/src/ui/hooks/useFlickerDetector.js +38 -0
- package/dist/src/ui/hooks/useFlickerDetector.js.map +1 -0
- package/dist/src/ui/hooks/useFlickerDetector.test.d.ts +6 -0
- package/dist/src/ui/hooks/useFlickerDetector.test.js +142 -0
- package/dist/src/ui/hooks/useFlickerDetector.test.js.map +1 -0
- package/dist/src/ui/hooks/useGeminiStream.d.ts +1 -1
- package/dist/src/ui/hooks/useGeminiStream.integration.test.js +1 -1
- package/dist/src/ui/hooks/useGeminiStream.integration.test.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +41 -18
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useMemoryMonitor.d.ts +13 -0
- package/dist/src/ui/hooks/useMemoryMonitor.js +28 -0
- package/dist/src/ui/hooks/useMemoryMonitor.js.map +1 -0
- package/dist/src/ui/hooks/usePermissionsModifyTrust.d.ts +34 -0
- package/dist/src/ui/hooks/usePermissionsModifyTrust.js +90 -0
- package/dist/src/ui/hooks/usePermissionsModifyTrust.js.map +1 -0
- package/dist/src/ui/hooks/usePermissionsModifyTrust.test.d.ts +6 -0
- package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js +60 -0
- package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js.map +1 -0
- package/dist/src/ui/hooks/useReactToolScheduler.d.ts +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.js +5 -1
- package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
- package/dist/src/ui/hooks/useSelectionList.d.ts +34 -0
- package/dist/src/ui/hooks/useSelectionList.js +292 -0
- package/dist/src/ui/hooks/useSelectionList.js.map +1 -0
- package/dist/src/ui/hooks/useSelectionList.test.d.ts +6 -0
- package/dist/src/ui/hooks/useSelectionList.test.js +726 -0
- package/dist/src/ui/hooks/useSelectionList.test.js.map +1 -0
- package/dist/src/ui/hooks/useShowMemoryCommand.js +1 -1
- package/dist/src/ui/hooks/useShowMemoryCommand.js.map +1 -1
- package/dist/src/ui/hooks/useStateAndRef.d.ts +1 -1
- package/dist/src/ui/hooks/useStateAndRef.js +2 -2
- package/dist/src/ui/hooks/useStateAndRef.js.map +1 -1
- package/dist/src/ui/hooks/useStaticHistoryRefresh.d.ts +13 -0
- package/dist/src/ui/hooks/useStaticHistoryRefresh.js +35 -0
- package/dist/src/ui/hooks/useStaticHistoryRefresh.js.map +1 -0
- package/dist/src/ui/hooks/useStaticHistoryRefresh.test.d.ts +6 -0
- package/dist/src/ui/hooks/useStaticHistoryRefresh.test.js +42 -0
- package/dist/src/ui/hooks/useStaticHistoryRefresh.test.js.map +1 -0
- package/dist/src/ui/hooks/useThemeCommand.js +7 -7
- package/dist/src/ui/hooks/useThemeCommand.js.map +1 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js +17 -20
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
- package/dist/src/ui/keyMatchers.test.js +6 -0
- package/dist/src/ui/keyMatchers.test.js.map +1 -1
- package/dist/src/ui/layouts/DefaultAppLayout.d.ts +23 -0
- package/dist/src/ui/layouts/DefaultAppLayout.js +76 -0
- package/dist/src/ui/layouts/DefaultAppLayout.js.map +1 -0
- package/dist/src/ui/noninteractive/nonInteractiveUi.d.ts +12 -0
- package/dist/src/ui/noninteractive/nonInteractiveUi.js +31 -0
- package/dist/src/ui/noninteractive/nonInteractiveUi.js.map +1 -0
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.js +2 -2
- package/dist/src/ui/privacy/CloudFreePrivacyNotice.js.map +1 -1
- package/dist/src/ui/privacy/MultiProviderPrivacyNotice.d.ts +11 -0
- package/dist/src/ui/privacy/MultiProviderPrivacyNotice.js +92 -0
- package/dist/src/ui/privacy/MultiProviderPrivacyNotice.js.map +1 -0
- package/dist/src/ui/privacy/MultiProviderPrivacyNotice.test.d.ts +6 -0
- package/dist/src/ui/privacy/MultiProviderPrivacyNotice.test.js +106 -0
- package/dist/src/ui/privacy/MultiProviderPrivacyNotice.test.js.map +1 -0
- package/dist/src/ui/privacy/PrivacyNotice.js +4 -9
- package/dist/src/ui/privacy/PrivacyNotice.js.map +1 -1
- package/dist/src/ui/state/extensions.d.ts +61 -0
- package/dist/src/ui/state/extensions.js +84 -0
- package/dist/src/ui/state/extensions.js.map +1 -0
- package/dist/src/ui/themes/theme.js +2 -2
- package/dist/src/ui/themes/theme.js.map +1 -1
- package/dist/src/ui/types.d.ts +58 -2
- package/dist/src/ui/types.js +6 -0
- package/dist/src/ui/types.js.map +1 -1
- package/dist/src/ui/utils/MarkdownDisplay.js +1 -2
- package/dist/src/ui/utils/MarkdownDisplay.js.map +1 -1
- package/dist/src/ui/utils/MarkdownDisplay.test.d.ts +1 -1
- package/dist/src/ui/utils/MarkdownDisplay.test.js +94 -104
- package/dist/src/ui/utils/MarkdownDisplay.test.js.map +1 -1
- package/dist/src/ui/utils/bracketedPaste.d.ts +9 -0
- package/dist/src/ui/utils/bracketedPaste.js +14 -0
- package/dist/src/ui/utils/bracketedPaste.js.map +1 -0
- package/dist/src/ui/utils/displayUtils.d.ts +1 -0
- package/dist/src/ui/utils/displayUtils.js +4 -1
- package/dist/src/ui/utils/displayUtils.js.map +1 -1
- package/dist/src/ui/utils/displayUtils.test.js +36 -17
- package/dist/src/ui/utils/displayUtils.test.js.map +1 -1
- package/dist/src/ui/utils/highlight.d.ts +2 -1
- package/dist/src/ui/utils/highlight.js +52 -8
- package/dist/src/ui/utils/highlight.js.map +1 -1
- package/dist/src/ui/utils/highlight.test.js +15 -14
- package/dist/src/ui/utils/highlight.test.js.map +1 -1
- package/dist/src/ui/utils/kittyProtocolDetector.d.ts +1 -0
- package/dist/src/ui/utils/kittyProtocolDetector.js +11 -3
- package/dist/src/ui/utils/kittyProtocolDetector.js.map +1 -1
- package/dist/src/ui/utils/terminalSequences.d.ts +22 -0
- package/dist/src/ui/utils/terminalSequences.js +23 -0
- package/dist/src/ui/utils/terminalSequences.js.map +1 -0
- package/dist/src/ui/utils/textUtils.d.ts +10 -0
- package/dist/src/ui/utils/textUtils.js +82 -1
- package/dist/src/ui/utils/textUtils.js.map +1 -1
- package/dist/src/ui/utils/textUtils.test.d.ts +6 -0
- package/dist/src/ui/utils/textUtils.test.js +132 -0
- package/dist/src/ui/utils/textUtils.test.js.map +1 -0
- package/dist/src/utils/bootstrap.d.ts +24 -0
- package/dist/src/utils/bootstrap.js +55 -0
- package/dist/src/utils/bootstrap.js.map +1 -0
- package/dist/src/utils/bootstrap.test.d.ts +6 -0
- package/dist/src/utils/bootstrap.test.js +103 -0
- package/dist/src/utils/bootstrap.test.js.map +1 -0
- package/dist/src/utils/cleanup.d.ts +6 -0
- package/dist/src/utils/cleanup.js +14 -0
- package/dist/src/utils/cleanup.js.map +1 -1
- package/dist/src/utils/commands.d.ts +17 -0
- package/dist/src/utils/commands.js +60 -0
- package/dist/src/utils/commands.js.map +1 -0
- package/dist/src/utils/dialogScopeUtils.d.ts +3 -0
- package/dist/src/utils/dialogScopeUtils.js +11 -2
- package/dist/src/utils/dialogScopeUtils.js.map +1 -1
- package/dist/src/utils/dynamicSettings.d.ts +20 -0
- package/dist/src/utils/dynamicSettings.js +110 -0
- package/dist/src/utils/dynamicSettings.js.map +1 -0
- package/dist/src/utils/dynamicSettings.test.d.ts +6 -0
- package/dist/src/utils/dynamicSettings.test.js +329 -0
- package/dist/src/utils/dynamicSettings.test.js.map +1 -0
- package/dist/src/utils/events.d.ts +3 -1
- package/dist/src/utils/events.js +2 -0
- package/dist/src/utils/events.js.map +1 -1
- package/dist/src/utils/handleAutoUpdate.js +4 -1
- package/dist/src/utils/handleAutoUpdate.js.map +1 -1
- package/dist/src/utils/installationInfo.d.ts +1 -0
- package/dist/src/utils/installationInfo.js +5 -3
- package/dist/src/utils/installationInfo.js.map +1 -1
- package/dist/src/utils/relaunch.d.ts +16 -0
- package/dist/src/utils/relaunch.js +34 -0
- package/dist/src/utils/relaunch.js.map +1 -0
- package/dist/src/utils/relaunch.test.d.ts +6 -0
- package/dist/src/utils/relaunch.test.js +96 -0
- package/dist/src/utils/relaunch.test.js.map +1 -0
- package/dist/src/utils/sessionCleanup.d.ts +22 -0
- package/dist/src/utils/sessionCleanup.integration.test.d.ts +6 -0
- package/dist/src/utils/sessionCleanup.integration.test.js +174 -0
- package/dist/src/utils/sessionCleanup.integration.test.js.map +1 -0
- package/dist/src/utils/sessionCleanup.js +213 -0
- package/dist/src/utils/sessionCleanup.js.map +1 -0
- package/dist/src/utils/sessionCleanup.test.d.ts +6 -0
- package/dist/src/utils/sessionCleanup.test.js +1144 -0
- package/dist/src/utils/sessionCleanup.test.js.map +1 -0
- package/dist/src/utils/sessionUtils.d.ts +37 -0
- package/dist/src/utils/sessionUtils.js +71 -0
- package/dist/src/utils/sessionUtils.js.map +1 -0
- package/dist/src/utils/settingsUtils.d.ts +6 -3
- package/dist/src/utils/settingsUtils.js +39 -11
- package/dist/src/utils/settingsUtils.js.map +1 -1
- package/dist/src/utils/settingsUtils.test.js +96 -96
- package/dist/src/utils/settingsUtils.test.js.map +1 -1
- package/dist/src/utils/singleSettingSaver.js +5 -0
- package/dist/src/utils/singleSettingSaver.js.map +1 -1
- package/dist/src/utils/windowTitle.d.ts +12 -0
- package/dist/src/utils/windowTitle.js +19 -0
- package/dist/src/utils/windowTitle.js.map +1 -0
- package/dist/src/utils/windowTitle.test.d.ts +6 -0
- package/dist/src/utils/windowTitle.test.js +49 -0
- package/dist/src/utils/windowTitle.test.js.map +1 -0
- package/dist/src/zed-integration/acp.js +1 -2
- package/dist/src/zed-integration/acp.js.map +1 -1
- package/dist/src/zed-integration/fileSystemService.d.ts +1 -0
- package/dist/src/zed-integration/fileSystemService.js +3 -0
- package/dist/src/zed-integration/fileSystemService.js.map +1 -1
- package/dist/src/zed-integration/schema.d.ts +212 -212
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +15 -6
- package/dist/src/ui/App.quittingMessages.test.d.ts +0 -1
- package/dist/src/ui/App.quittingMessages.test.js +0 -14
- package/dist/src/ui/App.quittingMessages.test.js.map +0 -1
|
@@ -0,0 +1,1187 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2025 Vybestack LLC
|
|
5
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
6
|
+
*/
|
|
7
|
+
import { useCallback, useEffect, useLayoutEffect, useMemo, useState, useRef, } from 'react';
|
|
8
|
+
import { measureElement, useStdin, useStdout } from 'ink';
|
|
9
|
+
import { StreamingState, MessageType, ToolCallStatus, } from './types.js';
|
|
10
|
+
import { useTerminalSize } from './hooks/useTerminalSize.js';
|
|
11
|
+
import { useResponsive } from './hooks/useResponsive.js';
|
|
12
|
+
import { useGeminiStream } from './hooks/useGeminiStream.js';
|
|
13
|
+
import { useLoadingIndicator } from './hooks/useLoadingIndicator.js';
|
|
14
|
+
import { useThemeCommand } from './hooks/useThemeCommand.js';
|
|
15
|
+
import { useAuthCommand } from './hooks/useAuthCommand.js';
|
|
16
|
+
import { useFolderTrust } from './hooks/useFolderTrust.js';
|
|
17
|
+
import { useIdeTrustListener } from './hooks/useIdeTrustListener.js';
|
|
18
|
+
import { useEditorSettings } from './hooks/useEditorSettings.js';
|
|
19
|
+
import { useSlashCommandProcessor } from './hooks/slashCommandProcessor.js';
|
|
20
|
+
import { useAutoAcceptIndicator } from './hooks/useAutoAcceptIndicator.js';
|
|
21
|
+
import { useConsoleMessages } from './hooks/useConsoleMessages.js';
|
|
22
|
+
import { useExtensionAutoUpdate } from './hooks/useExtensionAutoUpdate.js';
|
|
23
|
+
import { useExtensionUpdates } from './hooks/useExtensionUpdates.js';
|
|
24
|
+
import { loadHierarchicalLlxprtMemory } from '../config/config.js';
|
|
25
|
+
import { DEFAULT_HISTORY_MAX_BYTES, DEFAULT_HISTORY_MAX_ITEMS, } from '../constants/historyLimits.js';
|
|
26
|
+
import { SettingScope } from '../config/settings.js';
|
|
27
|
+
import { ConsolePatcher } from './utils/ConsolePatcher.js';
|
|
28
|
+
import { registerCleanup } from '../utils/cleanup.js';
|
|
29
|
+
import { useHistory } from './hooks/useHistoryManager.js';
|
|
30
|
+
import { useInputHistoryStore } from './hooks/useInputHistoryStore.js';
|
|
31
|
+
import { useMemoryMonitor } from './hooks/useMemoryMonitor.js';
|
|
32
|
+
import { useTodoPausePreserver, TodoPausePreserver, } from './hooks/useTodoPausePreserver.js';
|
|
33
|
+
import process from 'node:process';
|
|
34
|
+
import { getErrorMessage, getAllLlxprtMdFilenames, isEditorAvailable, ideContext,
|
|
35
|
+
// type IdeInfo, // TODO: Fix IDE integration
|
|
36
|
+
getSettingsService, DebugLogger, uiTelemetryService, } from '@vybestack/llxprt-code-core';
|
|
37
|
+
import { validateAuthMethod } from '../config/auth.js';
|
|
38
|
+
import { useLogger } from './hooks/useLogger.js';
|
|
39
|
+
import { useSessionStats } from './contexts/SessionContext.js';
|
|
40
|
+
import { useGitBranchName } from './hooks/useGitBranchName.js';
|
|
41
|
+
import { useFocus } from './hooks/useFocus.js';
|
|
42
|
+
import { useBracketedPaste } from './hooks/useBracketedPaste.js';
|
|
43
|
+
import { useTextBuffer } from './components/shared/text-buffer.js';
|
|
44
|
+
import { useVimMode } from './contexts/VimModeContext.js';
|
|
45
|
+
import { useVim } from './hooks/vim.js';
|
|
46
|
+
import { useKeypress } from './hooks/useKeypress.js';
|
|
47
|
+
import { keyMatchers, Command } from './keyMatchers.js';
|
|
48
|
+
import * as fs from 'fs';
|
|
49
|
+
import ansiEscapes from 'ansi-escapes';
|
|
50
|
+
import { useSettingsCommand } from './hooks/useSettingsCommand.js';
|
|
51
|
+
import { setUpdateHandler } from '../utils/handleAutoUpdate.js';
|
|
52
|
+
import { appEvents, AppEvent } from '../utils/events.js';
|
|
53
|
+
import { useRuntimeApi } from './contexts/RuntimeContext.js';
|
|
54
|
+
import { useProviderModelDialog } from './hooks/useProviderModelDialog.js';
|
|
55
|
+
import { useProviderDialog } from './hooks/useProviderDialog.js';
|
|
56
|
+
import { useLoadProfileDialog } from './hooks/useLoadProfileDialog.js';
|
|
57
|
+
import { useToolsDialog } from './hooks/useToolsDialog.js';
|
|
58
|
+
import { shouldUpdateTokenMetrics, toTokenMetricsSnapshot, } from './utils/tokenMetricsTracker.js';
|
|
59
|
+
import { useStaticHistoryRefresh } from './hooks/useStaticHistoryRefresh.js';
|
|
60
|
+
import { useTodoContext } from './contexts/TodoContext.js';
|
|
61
|
+
import { useWorkspaceMigration } from './hooks/useWorkspaceMigration.js';
|
|
62
|
+
import { useFlickerDetector } from './hooks/useFlickerDetector.js';
|
|
63
|
+
import { isWorkspaceTrusted } from '../config/trustedFolders.js';
|
|
64
|
+
import { globalOAuthUI } from '../auth/global-oauth-ui.js';
|
|
65
|
+
import { UIStateProvider } from './contexts/UIStateContext.js';
|
|
66
|
+
import { UIActionsProvider, } from './contexts/UIActionsContext.js';
|
|
67
|
+
import { DefaultAppLayout } from './layouts/DefaultAppLayout.js';
|
|
68
|
+
import { disableBracketedPaste, enableBracketedPaste, } from './utils/bracketedPaste.js';
|
|
69
|
+
import { enableSupportedProtocol } from './utils/kittyProtocolDetector.js';
|
|
70
|
+
import { ENABLE_FOCUS_TRACKING, DISABLE_FOCUS_TRACKING, SHOW_CURSOR, } from './utils/terminalSequences.js';
|
|
71
|
+
const CTRL_EXIT_PROMPT_DURATION_MS = 1000;
|
|
72
|
+
const debug = new DebugLogger('llxprt:ui:appcontainer');
|
|
73
|
+
const selectionLogger = new DebugLogger('llxprt:ui:selection');
|
|
74
|
+
function isToolExecuting(pendingHistoryItems) {
|
|
75
|
+
return pendingHistoryItems.some((item) => {
|
|
76
|
+
if (item && item.type === 'tool_group') {
|
|
77
|
+
return item.tools.some((tool) => ToolCallStatus.Executing === tool.status);
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
export const AppContainer = (props) => {
|
|
83
|
+
debug.log('AppContainer architecture active (v2)');
|
|
84
|
+
const { config, settings, startupWarnings = [], appState, appDispatch, } = props;
|
|
85
|
+
const runtime = useRuntimeApi();
|
|
86
|
+
const isFocused = useFocus();
|
|
87
|
+
const { isNarrow } = useResponsive();
|
|
88
|
+
useBracketedPaste();
|
|
89
|
+
const [updateInfo, setUpdateInfo] = useState(null);
|
|
90
|
+
const { stdout } = useStdout();
|
|
91
|
+
const { stdin, setRawMode } = useStdin();
|
|
92
|
+
const nightly = props.version.includes('nightly'); // TODO: Use for nightly-specific features
|
|
93
|
+
const historyLimits = useMemo(() => ({
|
|
94
|
+
maxItems: typeof settings.merged.ui?.historyMaxItems === 'number'
|
|
95
|
+
? settings.merged.ui.historyMaxItems
|
|
96
|
+
: DEFAULT_HISTORY_MAX_ITEMS,
|
|
97
|
+
maxBytes: typeof settings.merged.ui?.historyMaxBytes === 'number'
|
|
98
|
+
? settings.merged.ui.historyMaxBytes
|
|
99
|
+
: DEFAULT_HISTORY_MAX_BYTES,
|
|
100
|
+
}), [settings.merged.ui?.historyMaxItems, settings.merged.ui?.historyMaxBytes]);
|
|
101
|
+
const { history, addItem, clearItems, loadHistory } = useHistory(historyLimits);
|
|
102
|
+
useMemoryMonitor({ addItem });
|
|
103
|
+
const { updateTodos } = useTodoContext();
|
|
104
|
+
const todoPauseController = useMemo(() => new TodoPausePreserver(), []);
|
|
105
|
+
const registerTodoPause = useCallback(() => {
|
|
106
|
+
todoPauseController.registerTodoPause();
|
|
107
|
+
}, [todoPauseController]);
|
|
108
|
+
const [idePromptAnswered, setIdePromptAnswered] = useState(false);
|
|
109
|
+
const currentIDE = config.getIdeClient()?.getCurrentIde();
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
const ideClient = config.getIdeClient();
|
|
112
|
+
if (ideClient) {
|
|
113
|
+
registerCleanup(() => ideClient.disconnect());
|
|
114
|
+
}
|
|
115
|
+
}, [config]);
|
|
116
|
+
const shouldShowIdePrompt = currentIDE &&
|
|
117
|
+
!config.getIdeMode() &&
|
|
118
|
+
!settings.merged.hasSeenIdeIntegrationNudge &&
|
|
119
|
+
!idePromptAnswered;
|
|
120
|
+
useEffect(() => {
|
|
121
|
+
const cleanup = setUpdateHandler(addItem, setUpdateInfo);
|
|
122
|
+
// Attach addItem to OAuth providers for displaying auth URLs
|
|
123
|
+
if (addItem) {
|
|
124
|
+
const oauthManager = runtime.getCliOAuthManager();
|
|
125
|
+
if (oauthManager) {
|
|
126
|
+
const providersMap = oauthManager.providers;
|
|
127
|
+
if (providersMap instanceof Map) {
|
|
128
|
+
for (const provider of providersMap.values()) {
|
|
129
|
+
const candidate = provider;
|
|
130
|
+
candidate.setAddItem?.(addItem);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return cleanup;
|
|
136
|
+
}, [addItem, runtime]);
|
|
137
|
+
// Set global OAuth addItem callback for all OAuth flows
|
|
138
|
+
useEffect(() => {
|
|
139
|
+
global.__oauth_add_item = addItem;
|
|
140
|
+
globalOAuthUI.setAddItem(addItem);
|
|
141
|
+
return () => {
|
|
142
|
+
delete global.__oauth_add_item;
|
|
143
|
+
globalOAuthUI.clearAddItem();
|
|
144
|
+
};
|
|
145
|
+
}, [addItem]);
|
|
146
|
+
const { consoleMessages, handleNewMessage, clearConsoleMessages: clearConsoleMessagesState, } = useConsoleMessages();
|
|
147
|
+
useExtensionAutoUpdate({
|
|
148
|
+
settings,
|
|
149
|
+
onConsoleMessage: handleNewMessage,
|
|
150
|
+
});
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
const consolePatcher = new ConsolePatcher({
|
|
153
|
+
onNewMessage: handleNewMessage,
|
|
154
|
+
debugMode: config.getDebugMode(),
|
|
155
|
+
});
|
|
156
|
+
consolePatcher.patch();
|
|
157
|
+
registerCleanup(consolePatcher.cleanup);
|
|
158
|
+
}, [handleNewMessage, config]);
|
|
159
|
+
const { stats: sessionStats, updateHistoryTokenCount } = useSessionStats();
|
|
160
|
+
const historyTokenCleanupRef = useRef(null);
|
|
161
|
+
const lastHistoryServiceRef = useRef(null);
|
|
162
|
+
const lastPublishedHistoryTokensRef = useRef(null);
|
|
163
|
+
const tokenLogger = useMemo(() => new DebugLogger('llxprt:ui:tokentracking'), []);
|
|
164
|
+
// Set up history token count listener
|
|
165
|
+
useEffect(() => {
|
|
166
|
+
let intervalCleared = false;
|
|
167
|
+
// Poll continuously to detect when the history service changes (e.g., after compression)
|
|
168
|
+
const checkInterval = setInterval(() => {
|
|
169
|
+
if (intervalCleared)
|
|
170
|
+
return;
|
|
171
|
+
const geminiClient = config.getGeminiClient();
|
|
172
|
+
// Check if chat is initialized first
|
|
173
|
+
if (geminiClient?.hasChatInitialized?.()) {
|
|
174
|
+
const historyService = geminiClient.getHistoryService?.();
|
|
175
|
+
if (!historyService && lastHistoryServiceRef.current === null) {
|
|
176
|
+
tokenLogger.debug(() => 'No history service available yet');
|
|
177
|
+
}
|
|
178
|
+
else if (historyService) {
|
|
179
|
+
// Always get the current token count even if not a new instance
|
|
180
|
+
const currentTokens = historyService.getTotalTokens();
|
|
181
|
+
if (currentTokens > 0 &&
|
|
182
|
+
currentTokens !== lastPublishedHistoryTokensRef.current) {
|
|
183
|
+
lastPublishedHistoryTokensRef.current = currentTokens;
|
|
184
|
+
updateHistoryTokenCount(currentTokens);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// Check if we have a new history service instance (happens after compression)
|
|
188
|
+
if (historyService &&
|
|
189
|
+
historyService !== lastHistoryServiceRef.current) {
|
|
190
|
+
tokenLogger.debug(() => 'Found new history service, setting up listener');
|
|
191
|
+
// Clean up old listener if it exists
|
|
192
|
+
if (historyTokenCleanupRef.current) {
|
|
193
|
+
historyTokenCleanupRef.current();
|
|
194
|
+
historyTokenCleanupRef.current = null;
|
|
195
|
+
}
|
|
196
|
+
// Store reference to current history service
|
|
197
|
+
lastHistoryServiceRef.current = historyService;
|
|
198
|
+
const handleTokensUpdated = (event) => {
|
|
199
|
+
tokenLogger.debug(() => `Received tokensUpdated event: totalTokens=${event.totalTokens}`);
|
|
200
|
+
if (event.totalTokens !== lastPublishedHistoryTokensRef.current) {
|
|
201
|
+
lastPublishedHistoryTokensRef.current = event.totalTokens;
|
|
202
|
+
updateHistoryTokenCount(event.totalTokens);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
historyService.on('tokensUpdated', handleTokensUpdated);
|
|
206
|
+
// Initialize with current token count
|
|
207
|
+
const currentTokens = historyService.getTotalTokens();
|
|
208
|
+
tokenLogger.debug(() => `Initial token count: ${currentTokens}`);
|
|
209
|
+
lastPublishedHistoryTokensRef.current = currentTokens;
|
|
210
|
+
updateHistoryTokenCount(currentTokens);
|
|
211
|
+
// Store cleanup function for later
|
|
212
|
+
historyTokenCleanupRef.current = () => {
|
|
213
|
+
historyService.off('tokensUpdated', handleTokensUpdated);
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}, 100); // Check every 100ms
|
|
218
|
+
return () => {
|
|
219
|
+
clearInterval(checkInterval);
|
|
220
|
+
intervalCleared = true;
|
|
221
|
+
// Clean up the event listener if it was set up
|
|
222
|
+
if (historyTokenCleanupRef.current) {
|
|
223
|
+
historyTokenCleanupRef.current();
|
|
224
|
+
historyTokenCleanupRef.current = null;
|
|
225
|
+
}
|
|
226
|
+
lastHistoryServiceRef.current = null;
|
|
227
|
+
lastPublishedHistoryTokensRef.current = null;
|
|
228
|
+
};
|
|
229
|
+
}, [config, updateHistoryTokenCount, tokenLogger]);
|
|
230
|
+
const [_staticNeedsRefresh, setStaticNeedsRefresh] = useState(false);
|
|
231
|
+
const [staticKey, setStaticKey] = useState(0);
|
|
232
|
+
const externalEditorStateRef = useRef(null);
|
|
233
|
+
const keypressRefreshRef = useRef(() => { });
|
|
234
|
+
const restoreTerminalStateAfterEditor = useCallback(() => {
|
|
235
|
+
const editorState = externalEditorStateRef.current;
|
|
236
|
+
if (!stdin) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
const readStream = stdin;
|
|
240
|
+
if (editorState?.paused && typeof readStream.resume === 'function') {
|
|
241
|
+
readStream.resume();
|
|
242
|
+
}
|
|
243
|
+
if (editorState?.rawModeManaged && setRawMode) {
|
|
244
|
+
try {
|
|
245
|
+
setRawMode(true);
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
console.error('Failed to re-enable raw mode:', error);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
if (keypressRefreshRef.current) {
|
|
252
|
+
keypressRefreshRef.current();
|
|
253
|
+
debug.debug(() => 'Keypress refresh requested after external editor closed');
|
|
254
|
+
}
|
|
255
|
+
externalEditorStateRef.current = null;
|
|
256
|
+
}, [setRawMode, stdin]);
|
|
257
|
+
const refreshStatic = useCallback(() => {
|
|
258
|
+
stdout.write(ansiEscapes.clearTerminal);
|
|
259
|
+
setStaticKey((prev) => prev + 1);
|
|
260
|
+
restoreTerminalStateAfterEditor();
|
|
261
|
+
// Re-send terminal control sequences
|
|
262
|
+
enableBracketedPaste();
|
|
263
|
+
enableSupportedProtocol();
|
|
264
|
+
stdout.write(ENABLE_FOCUS_TRACKING);
|
|
265
|
+
stdout.write(SHOW_CURSOR);
|
|
266
|
+
}, [restoreTerminalStateAfterEditor, setStaticKey, stdout]);
|
|
267
|
+
const handleExternalEditorOpen = useCallback(() => {
|
|
268
|
+
if (!stdin) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
const readStream = stdin;
|
|
272
|
+
externalEditorStateRef.current = {
|
|
273
|
+
paused: false,
|
|
274
|
+
rawModeManaged: false,
|
|
275
|
+
};
|
|
276
|
+
if (typeof readStream.pause === 'function') {
|
|
277
|
+
readStream.pause();
|
|
278
|
+
externalEditorStateRef.current.paused = true;
|
|
279
|
+
}
|
|
280
|
+
if (setRawMode) {
|
|
281
|
+
try {
|
|
282
|
+
setRawMode(false);
|
|
283
|
+
externalEditorStateRef.current.rawModeManaged = true;
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
console.error('Failed to disable raw mode:', error);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
disableBracketedPaste();
|
|
290
|
+
stdout.write(DISABLE_FOCUS_TRACKING);
|
|
291
|
+
stdout.write(SHOW_CURSOR);
|
|
292
|
+
}, [setRawMode, stdin, stdout]);
|
|
293
|
+
useStaticHistoryRefresh(history, refreshStatic);
|
|
294
|
+
const [llxprtMdFileCount, setLlxprtMdFileCount] = useState(0);
|
|
295
|
+
const [debugMessage, setDebugMessage] = useState('');
|
|
296
|
+
const [themeError, _setThemeError] = useState(null);
|
|
297
|
+
const [authError, setAuthError] = useState(null);
|
|
298
|
+
const [editorError, _setEditorError] = useState(null);
|
|
299
|
+
const [footerHeight, setFooterHeight] = useState(0);
|
|
300
|
+
// Token metrics state for live updates
|
|
301
|
+
const [tokenMetrics, setTokenMetrics] = useState({
|
|
302
|
+
tokensPerMinute: 0,
|
|
303
|
+
throttleWaitTimeMs: 0,
|
|
304
|
+
sessionTokenTotal: 0,
|
|
305
|
+
});
|
|
306
|
+
const tokenMetricsSnapshotRef = useRef(null);
|
|
307
|
+
const [_corgiMode, setCorgiMode] = useState(false);
|
|
308
|
+
const [_isTrustedFolderState, _setIsTrustedFolder] = useState(isWorkspaceTrusted(settings.merged));
|
|
309
|
+
const [currentModel, setCurrentModel] = useState(config.getModel());
|
|
310
|
+
const [shellModeActive, setShellModeActive] = useState(false);
|
|
311
|
+
const [showErrorDetails, setShowErrorDetails] = useState(false);
|
|
312
|
+
const [showToolDescriptions, setShowToolDescriptions] = useState(false);
|
|
313
|
+
const [showDebugProfiler, setShowDebugProfiler] = useState(false);
|
|
314
|
+
const [ctrlCPressedOnce, setCtrlCPressedOnce] = useState(false);
|
|
315
|
+
const [quittingMessages, setQuittingMessages] = useState(null);
|
|
316
|
+
const ctrlCTimerRef = useRef(null);
|
|
317
|
+
const [ctrlDPressedOnce, setCtrlDPressedOnce] = useState(false);
|
|
318
|
+
const ctrlDTimerRef = useRef(null);
|
|
319
|
+
const [constrainHeight, setConstrainHeight] = useState(true);
|
|
320
|
+
const [showPrivacyNotice, setShowPrivacyNotice] = useState(false);
|
|
321
|
+
const [ideContextState, setIdeContextState] = useState();
|
|
322
|
+
const [showEscapePrompt, setShowEscapePrompt] = useState(false);
|
|
323
|
+
const [showIdeRestartPrompt, setShowIdeRestartPrompt] = useState(false);
|
|
324
|
+
const [isProcessing, setIsProcessing] = useState(false);
|
|
325
|
+
const [providerModels, setProviderModels] = useState([]);
|
|
326
|
+
const [isPermissionsDialogOpen, setIsPermissionsDialogOpen] = useState(false);
|
|
327
|
+
const openPermissionsDialog = useCallback(() => {
|
|
328
|
+
setIsPermissionsDialogOpen(true);
|
|
329
|
+
}, []);
|
|
330
|
+
const closePermissionsDialog = useCallback(() => {
|
|
331
|
+
setIsPermissionsDialogOpen(false);
|
|
332
|
+
}, []);
|
|
333
|
+
const [isLoggingDialogOpen, setIsLoggingDialogOpen] = useState(false);
|
|
334
|
+
const [loggingDialogData, setLoggingDialogData] = useState({ entries: [] });
|
|
335
|
+
const openLoggingDialog = useCallback((data) => {
|
|
336
|
+
setLoggingDialogData(data || { entries: [] });
|
|
337
|
+
setIsLoggingDialogOpen(true);
|
|
338
|
+
}, []);
|
|
339
|
+
const closeLoggingDialog = useCallback(() => {
|
|
340
|
+
setIsLoggingDialogOpen(false);
|
|
341
|
+
}, []);
|
|
342
|
+
const { showWorkspaceMigrationDialog, workspaceExtensions, onWorkspaceMigrationDialogOpen, onWorkspaceMigrationDialogClose, } = useWorkspaceMigration(settings);
|
|
343
|
+
const extensions = config.getExtensions();
|
|
344
|
+
const { extensionsUpdateState, dispatchExtensionStateUpdate, confirmUpdateExtensionRequests, addConfirmUpdateExtensionRequest, } = useExtensionUpdates(extensions, addItem, config.getWorkingDir());
|
|
345
|
+
useEffect(() => {
|
|
346
|
+
const unsubscribe = ideContext.subscribeToIdeContext(setIdeContextState);
|
|
347
|
+
// Set the initial value
|
|
348
|
+
setIdeContextState(ideContext.getIdeContext());
|
|
349
|
+
return unsubscribe;
|
|
350
|
+
}, []);
|
|
351
|
+
// Update currentModel when settings change - get it from the SAME place as diagnostics
|
|
352
|
+
useEffect(() => {
|
|
353
|
+
const updateModel = async () => {
|
|
354
|
+
const settingsService = getSettingsService();
|
|
355
|
+
// Try to get from SettingsService first (same as diagnostics does)
|
|
356
|
+
if (settingsService && settingsService.getDiagnosticsData) {
|
|
357
|
+
try {
|
|
358
|
+
const diagnosticsData = await settingsService.getDiagnosticsData();
|
|
359
|
+
if (diagnosticsData && diagnosticsData.model) {
|
|
360
|
+
setCurrentModel(diagnosticsData.model);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
catch (_error) {
|
|
365
|
+
// Fall through to config
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
// Otherwise use config (which is what diagnostics falls back to)
|
|
369
|
+
setCurrentModel(config.getModel());
|
|
370
|
+
};
|
|
371
|
+
// Update immediately
|
|
372
|
+
updateModel();
|
|
373
|
+
// Also listen for any changes if SettingsService is available
|
|
374
|
+
const settingsService = getSettingsService();
|
|
375
|
+
if (settingsService) {
|
|
376
|
+
settingsService.on('settings-changed', updateModel);
|
|
377
|
+
return () => {
|
|
378
|
+
settingsService.off('settings-changed', updateModel);
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
return undefined;
|
|
382
|
+
}, [config]);
|
|
383
|
+
useEffect(() => {
|
|
384
|
+
const openDebugConsole = () => {
|
|
385
|
+
setShowErrorDetails(true);
|
|
386
|
+
setConstrainHeight(false); // Make sure the user sees the full message.
|
|
387
|
+
};
|
|
388
|
+
appEvents.on(AppEvent.OpenDebugConsole, openDebugConsole);
|
|
389
|
+
const logErrorHandler = (errorMessage) => {
|
|
390
|
+
handleNewMessage({
|
|
391
|
+
type: 'error',
|
|
392
|
+
content: String(errorMessage),
|
|
393
|
+
count: 1,
|
|
394
|
+
});
|
|
395
|
+
};
|
|
396
|
+
appEvents.on(AppEvent.LogError, logErrorHandler);
|
|
397
|
+
return () => {
|
|
398
|
+
appEvents.off(AppEvent.OpenDebugConsole, openDebugConsole);
|
|
399
|
+
appEvents.off(AppEvent.LogError, logErrorHandler);
|
|
400
|
+
};
|
|
401
|
+
}, [handleNewMessage]);
|
|
402
|
+
const openPrivacyNotice = useCallback(() => {
|
|
403
|
+
setShowPrivacyNotice(true);
|
|
404
|
+
}, []);
|
|
405
|
+
const handleEscapePromptChange = useCallback((showPrompt) => {
|
|
406
|
+
setShowEscapePrompt(showPrompt);
|
|
407
|
+
}, []);
|
|
408
|
+
const initialPromptSubmitted = useRef(false);
|
|
409
|
+
const errorCount = useMemo(() => consoleMessages
|
|
410
|
+
.filter((msg) => msg.type === 'error')
|
|
411
|
+
.reduce((total, msg) => total + msg.count, 0), [consoleMessages]);
|
|
412
|
+
const { isThemeDialogOpen, openThemeDialog, handleThemeSelect, handleThemeHighlight, } = useThemeCommand(settings, appState, addItem);
|
|
413
|
+
const { isSettingsDialogOpen, openSettingsDialog, closeSettingsDialog } = useSettingsCommand();
|
|
414
|
+
const { isFolderTrustDialogOpen, handleFolderTrustSelect, isRestarting } = useFolderTrust(settings, config);
|
|
415
|
+
const { needsRestart: ideNeedsRestart } = useIdeTrustListener(config);
|
|
416
|
+
useEffect(() => {
|
|
417
|
+
if (ideNeedsRestart) {
|
|
418
|
+
// IDE trust changed, force a restart.
|
|
419
|
+
setShowIdeRestartPrompt(true);
|
|
420
|
+
}
|
|
421
|
+
}, [ideNeedsRestart]);
|
|
422
|
+
useKeypress((key) => {
|
|
423
|
+
if (key.name === 'r' || key.name === 'R') {
|
|
424
|
+
process.exit(0);
|
|
425
|
+
}
|
|
426
|
+
}, { isActive: showIdeRestartPrompt });
|
|
427
|
+
const { isAuthDialogOpen, openAuthDialog, handleAuthSelect, isAuthenticating, cancelAuthentication, } = useAuthCommand(settings, appState, config);
|
|
428
|
+
useEffect(() => {
|
|
429
|
+
if (settings.merged.selectedAuthType && !settings.merged.useExternalAuth) {
|
|
430
|
+
const error = validateAuthMethod(settings.merged.selectedAuthType);
|
|
431
|
+
if (error) {
|
|
432
|
+
setAuthError(error);
|
|
433
|
+
// Don't automatically open auth dialog - user must use /auth command
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}, [
|
|
437
|
+
settings.merged.selectedAuthType,
|
|
438
|
+
settings.merged.useExternalAuth,
|
|
439
|
+
setAuthError,
|
|
440
|
+
]);
|
|
441
|
+
// Check for OAuth code needed flag
|
|
442
|
+
useEffect(() => {
|
|
443
|
+
const checkOAuthFlag = setInterval(() => {
|
|
444
|
+
if (global.__oauth_needs_code) {
|
|
445
|
+
// Clear the flag
|
|
446
|
+
global.__oauth_needs_code = false;
|
|
447
|
+
// Open the OAuth code dialog
|
|
448
|
+
appDispatch({ type: 'OPEN_DIALOG', payload: 'oauthCode' });
|
|
449
|
+
}
|
|
450
|
+
}, 100); // Check every 100ms
|
|
451
|
+
return () => clearInterval(checkOAuthFlag);
|
|
452
|
+
}, [appDispatch]);
|
|
453
|
+
const { isEditorDialogOpen, openEditorDialog, handleEditorSelect, exitEditorDialog, } = useEditorSettings(settings, appState, addItem);
|
|
454
|
+
const { showDialog: isProviderDialogOpen, openDialog: openProviderDialog, handleSelect: handleProviderSelect, closeDialog: exitProviderDialog, providers: providerOptions, currentProvider: selectedProvider, } = useProviderDialog({
|
|
455
|
+
addMessage: (msg) => addItem({ type: msg.type, text: msg.content }, msg.timestamp.getTime()),
|
|
456
|
+
appState,
|
|
457
|
+
config,
|
|
458
|
+
});
|
|
459
|
+
const { showDialog: isProviderModelDialogOpen, openDialog: openProviderModelDialogRaw, handleSelect: handleProviderModelChange, closeDialog: exitProviderModelDialog, } = useProviderModelDialog({
|
|
460
|
+
addMessage: (msg) => addItem({ type: msg.type, text: msg.content }, msg.timestamp.getTime()),
|
|
461
|
+
appState,
|
|
462
|
+
});
|
|
463
|
+
const openProviderModelDialog = useCallback(async () => {
|
|
464
|
+
try {
|
|
465
|
+
const models = await runtime.listAvailableModels();
|
|
466
|
+
setProviderModels(models);
|
|
467
|
+
}
|
|
468
|
+
catch (e) {
|
|
469
|
+
console.error('Failed to load models:', e);
|
|
470
|
+
setProviderModels([]);
|
|
471
|
+
}
|
|
472
|
+
await openProviderModelDialogRaw();
|
|
473
|
+
}, [openProviderModelDialogRaw, runtime]);
|
|
474
|
+
// Watch for model changes from config
|
|
475
|
+
useEffect(() => {
|
|
476
|
+
const checkModelChange = () => {
|
|
477
|
+
const configModel = config.getModel();
|
|
478
|
+
const providerModel = runtime.getActiveModelName();
|
|
479
|
+
const effectiveModel = providerModel && providerModel.trim() !== ''
|
|
480
|
+
? providerModel
|
|
481
|
+
: configModel;
|
|
482
|
+
if (effectiveModel !== currentModel) {
|
|
483
|
+
console.debug(`[Model Update] Updating footer from ${currentModel} to ${effectiveModel}`);
|
|
484
|
+
setCurrentModel(effectiveModel);
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
// Check immediately
|
|
488
|
+
checkModelChange();
|
|
489
|
+
// Check periodically (every 500ms)
|
|
490
|
+
const interval = setInterval(checkModelChange, 500);
|
|
491
|
+
return () => clearInterval(interval);
|
|
492
|
+
}, [config, currentModel, runtime]); // Include currentModel in dependencies
|
|
493
|
+
const toggleCorgiMode = useCallback(() => {
|
|
494
|
+
setCorgiMode((prev) => !prev);
|
|
495
|
+
}, []);
|
|
496
|
+
const toggleDebugProfiler = useCallback(() => {
|
|
497
|
+
setShowDebugProfiler((prev) => !prev);
|
|
498
|
+
}, []);
|
|
499
|
+
const { showDialog: isLoadProfileDialogOpen, openDialog: openLoadProfileDialog, handleSelect: handleProfileSelect, closeDialog: exitLoadProfileDialog, profiles, } = useLoadProfileDialog({
|
|
500
|
+
addMessage: (msg) => addItem({ type: msg.type, text: msg.content }, msg.timestamp.getTime()),
|
|
501
|
+
appState,
|
|
502
|
+
config,
|
|
503
|
+
settings,
|
|
504
|
+
});
|
|
505
|
+
const { showDialog: isToolsDialogOpen, openDialog: openToolsDialogRaw, closeDialog: exitToolsDialog, action: toolsDialogAction, availableTools: toolsDialogTools, disabledTools: toolsDialogDisabledTools, handleSelect: handleToolsSelect, } = useToolsDialog({
|
|
506
|
+
addMessage: (msg) => addItem({ type: msg.type, text: msg.content }, msg.timestamp.getTime()),
|
|
507
|
+
appState,
|
|
508
|
+
config,
|
|
509
|
+
});
|
|
510
|
+
const openToolsDialog = useCallback((action) => {
|
|
511
|
+
openToolsDialogRaw(action);
|
|
512
|
+
}, [openToolsDialogRaw]);
|
|
513
|
+
const performMemoryRefresh = useCallback(async () => {
|
|
514
|
+
addItem({
|
|
515
|
+
type: MessageType.INFO,
|
|
516
|
+
text: 'Refreshing hierarchical memory (LLXPRT.md or other context files)...',
|
|
517
|
+
}, Date.now());
|
|
518
|
+
try {
|
|
519
|
+
const { memoryContent, fileCount } = await loadHierarchicalLlxprtMemory(process.cwd(), settings.merged.loadMemoryFromIncludeDirectories
|
|
520
|
+
? config.getWorkspaceContext().getDirectories()
|
|
521
|
+
: [], config.getDebugMode(), config.getFileService(), settings.merged, config.getExtensionContextFilePaths(), config.getFolderTrust(), settings.merged.ui?.memoryImportFormat || 'tree', // Use setting or default to 'tree'
|
|
522
|
+
config.getFileFilteringOptions());
|
|
523
|
+
config.setUserMemory(memoryContent);
|
|
524
|
+
config.setLlxprtMdFileCount(fileCount);
|
|
525
|
+
setLlxprtMdFileCount(fileCount);
|
|
526
|
+
addItem({
|
|
527
|
+
type: MessageType.INFO,
|
|
528
|
+
text: `Memory refreshed successfully. ${memoryContent.length > 0 ? `Loaded ${memoryContent.length} characters from ${fileCount} file(s).` : 'No memory content found.'}`,
|
|
529
|
+
}, Date.now());
|
|
530
|
+
if (config.getDebugMode()) {
|
|
531
|
+
console.log(`[DEBUG] Refreshed memory content in config: ${memoryContent.substring(0, 200)}...`);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
catch (error) {
|
|
535
|
+
const errorMessage = getErrorMessage(error);
|
|
536
|
+
addItem({
|
|
537
|
+
type: MessageType.ERROR,
|
|
538
|
+
text: `Error refreshing memory: ${errorMessage}`,
|
|
539
|
+
}, Date.now());
|
|
540
|
+
console.error('Error refreshing memory:', error);
|
|
541
|
+
}
|
|
542
|
+
}, [config, addItem, settings.merged]);
|
|
543
|
+
// Poll for token metrics updates
|
|
544
|
+
useEffect(() => {
|
|
545
|
+
const updateTokenMetrics = () => {
|
|
546
|
+
const metrics = runtime.getActiveProviderMetrics();
|
|
547
|
+
const usage = runtime.getSessionTokenUsage();
|
|
548
|
+
if (!shouldUpdateTokenMetrics(tokenMetricsSnapshotRef.current, metrics, usage)) {
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
const snapshot = toTokenMetricsSnapshot(metrics, usage);
|
|
552
|
+
tokenMetricsSnapshotRef.current = snapshot;
|
|
553
|
+
setTokenMetrics({
|
|
554
|
+
tokensPerMinute: snapshot.tokensPerMinute,
|
|
555
|
+
throttleWaitTimeMs: snapshot.throttleWaitTimeMs,
|
|
556
|
+
sessionTokenTotal: snapshot.sessionTokenTotal,
|
|
557
|
+
});
|
|
558
|
+
uiTelemetryService.setTokenTrackingMetrics({
|
|
559
|
+
tokensPerMinute: snapshot.tokensPerMinute,
|
|
560
|
+
throttleWaitTimeMs: snapshot.throttleWaitTimeMs,
|
|
561
|
+
sessionTokenUsage: usage,
|
|
562
|
+
});
|
|
563
|
+
};
|
|
564
|
+
// Update immediately
|
|
565
|
+
updateTokenMetrics();
|
|
566
|
+
// Poll every second to show live updates
|
|
567
|
+
const interval = setInterval(updateTokenMetrics, 1000);
|
|
568
|
+
return () => clearInterval(interval);
|
|
569
|
+
}, [runtime]);
|
|
570
|
+
// Terminal and UI setup
|
|
571
|
+
const { rows: terminalHeight, columns: terminalWidth } = useTerminalSize();
|
|
572
|
+
const isInitialMount = useRef(true);
|
|
573
|
+
const widthFraction = 0.9;
|
|
574
|
+
// Calculate inputWidth accounting for:
|
|
575
|
+
// - Prompt: 2 chars ("! " or "> ")
|
|
576
|
+
// - Padding: 2 chars (paddingX={1} on each side in InputPrompt)
|
|
577
|
+
// - Additional margin: 2 chars (for proper wrapping)
|
|
578
|
+
const inputWidth = Math.max(20, Math.floor(terminalWidth * widthFraction) - 6);
|
|
579
|
+
const suggestionsWidth = Math.max(60, Math.floor(terminalWidth * 0.8));
|
|
580
|
+
// Utility callbacks
|
|
581
|
+
const isValidPath = useCallback((filePath) => {
|
|
582
|
+
try {
|
|
583
|
+
return fs.existsSync(filePath) && fs.statSync(filePath).isFile();
|
|
584
|
+
}
|
|
585
|
+
catch (_e) {
|
|
586
|
+
return false;
|
|
587
|
+
}
|
|
588
|
+
}, []);
|
|
589
|
+
const getPreferredEditor = useCallback(() => {
|
|
590
|
+
const editorType = settings.merged.ui?.preferredEditor;
|
|
591
|
+
const isValidEditor = isEditorAvailable(editorType);
|
|
592
|
+
if (!isValidEditor) {
|
|
593
|
+
openEditorDialog();
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
return editorType;
|
|
597
|
+
}, [settings, openEditorDialog]);
|
|
598
|
+
const onAuthError = useCallback(() => {
|
|
599
|
+
setAuthError('reauth required');
|
|
600
|
+
// Open the auth dialog when authentication errors occur
|
|
601
|
+
appDispatch({ type: 'OPEN_DIALOG', payload: 'auth' });
|
|
602
|
+
}, [setAuthError, appDispatch]);
|
|
603
|
+
const handleAuthTimeout = useCallback(() => {
|
|
604
|
+
setAuthError('Authentication timed out. Please try again.');
|
|
605
|
+
cancelAuthentication();
|
|
606
|
+
// NEVER automatically open auth dialog - user must use /auth
|
|
607
|
+
}, [setAuthError, cancelAuthentication]);
|
|
608
|
+
const handlePrivacyNoticeExit = useCallback(() => {
|
|
609
|
+
setShowPrivacyNotice(false);
|
|
610
|
+
}, []);
|
|
611
|
+
// Core hooks and processors
|
|
612
|
+
const { vimEnabled: vimModeEnabled, vimMode, toggleVimEnabled, } = useVimMode();
|
|
613
|
+
const slashCommandProcessorActions = useMemo(() => ({
|
|
614
|
+
openAuthDialog,
|
|
615
|
+
openThemeDialog,
|
|
616
|
+
openEditorDialog,
|
|
617
|
+
openPrivacyNotice,
|
|
618
|
+
openSettingsDialog,
|
|
619
|
+
openLoggingDialog,
|
|
620
|
+
openProviderModelDialog,
|
|
621
|
+
openPermissionsDialog,
|
|
622
|
+
openProviderDialog,
|
|
623
|
+
openLoadProfileDialog,
|
|
624
|
+
quit: setQuittingMessages,
|
|
625
|
+
setDebugMessage,
|
|
626
|
+
toggleCorgiMode,
|
|
627
|
+
toggleDebugProfiler,
|
|
628
|
+
dispatchExtensionStateUpdate,
|
|
629
|
+
addConfirmUpdateExtensionRequest,
|
|
630
|
+
}), [
|
|
631
|
+
openAuthDialog,
|
|
632
|
+
openThemeDialog,
|
|
633
|
+
openEditorDialog,
|
|
634
|
+
openPrivacyNotice,
|
|
635
|
+
openSettingsDialog,
|
|
636
|
+
openLoggingDialog,
|
|
637
|
+
openProviderModelDialog,
|
|
638
|
+
openPermissionsDialog,
|
|
639
|
+
openProviderDialog,
|
|
640
|
+
openLoadProfileDialog,
|
|
641
|
+
setQuittingMessages,
|
|
642
|
+
setDebugMessage,
|
|
643
|
+
toggleCorgiMode,
|
|
644
|
+
toggleDebugProfiler,
|
|
645
|
+
dispatchExtensionStateUpdate,
|
|
646
|
+
addConfirmUpdateExtensionRequest,
|
|
647
|
+
]);
|
|
648
|
+
const { handleSlashCommand, slashCommands, pendingHistoryItems: pendingSlashCommandHistoryItems, commandContext, shellConfirmationRequest, confirmationRequest, } = useSlashCommandProcessor(config, settings, addItem, clearItems, loadHistory, refreshStatic, toggleVimEnabled, setIsProcessing, setLlxprtMdFileCount, slashCommandProcessorActions, extensionsUpdateState, true);
|
|
649
|
+
// Memoize viewport to ensure it updates when inputWidth changes
|
|
650
|
+
const viewport = useMemo(() => ({ height: 10, width: inputWidth }), [inputWidth]);
|
|
651
|
+
const buffer = useTextBuffer({
|
|
652
|
+
initialText: '',
|
|
653
|
+
viewport,
|
|
654
|
+
stdin,
|
|
655
|
+
setRawMode,
|
|
656
|
+
isValidPath,
|
|
657
|
+
shellModeActive,
|
|
658
|
+
});
|
|
659
|
+
// Independent input history management (unaffected by /clear)
|
|
660
|
+
const inputHistoryStore = useInputHistoryStore();
|
|
661
|
+
const handleUserCancel = useCallback(() => {
|
|
662
|
+
const lastUserMessage = inputHistoryStore.inputHistory.at(-1);
|
|
663
|
+
if (lastUserMessage) {
|
|
664
|
+
buffer.setText(lastUserMessage);
|
|
665
|
+
}
|
|
666
|
+
}, [buffer, inputHistoryStore.inputHistory]);
|
|
667
|
+
const handleOAuthCodeDialogClose = useCallback(() => {
|
|
668
|
+
appDispatch({ type: 'CLOSE_DIALOG', payload: 'oauthCode' });
|
|
669
|
+
}, [appDispatch]);
|
|
670
|
+
const handleOAuthCodeSubmit = useCallback(async (code) => {
|
|
671
|
+
const provider = global
|
|
672
|
+
.__oauth_provider;
|
|
673
|
+
if (provider === 'anthropic') {
|
|
674
|
+
const oauthManager = runtime.getCliOAuthManager();
|
|
675
|
+
if (oauthManager) {
|
|
676
|
+
const anthropicProvider = oauthManager.getProvider('anthropic');
|
|
677
|
+
if (anthropicProvider && 'submitAuthCode' in anthropicProvider) {
|
|
678
|
+
anthropicProvider.submitAuthCode(code);
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
}, [runtime]);
|
|
683
|
+
const { streamingState, submitQuery, initError, pendingHistoryItems: pendingGeminiHistoryItems, thought, cancelOngoingRequest, } = useGeminiStream(config.getGeminiClient(), history, addItem, config, settings, setDebugMessage, handleSlashCommand, shellModeActive, getPreferredEditor, onAuthError, performMemoryRefresh, refreshStatic, handleUserCancel, registerTodoPause, handleExternalEditorOpen);
|
|
684
|
+
const pendingHistoryItems = useMemo(() => [...pendingSlashCommandHistoryItems, ...pendingGeminiHistoryItems], [pendingSlashCommandHistoryItems, pendingGeminiHistoryItems]);
|
|
685
|
+
// Update the cancel handler with message queue support
|
|
686
|
+
const cancelHandlerRef = useRef(null);
|
|
687
|
+
cancelHandlerRef.current = useCallback(() => {
|
|
688
|
+
if (isToolExecuting(pendingHistoryItems)) {
|
|
689
|
+
buffer.setText(''); // Just clear the prompt
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
const lastUserMessage = inputHistoryStore.inputHistory.at(-1);
|
|
693
|
+
const textToSet = lastUserMessage || '';
|
|
694
|
+
if (textToSet) {
|
|
695
|
+
buffer.setText(textToSet);
|
|
696
|
+
}
|
|
697
|
+
}, [buffer, inputHistoryStore.inputHistory, pendingHistoryItems]);
|
|
698
|
+
// Input handling - queue messages for processing
|
|
699
|
+
const handleFinalSubmit = useCallback((submittedValue) => {
|
|
700
|
+
const trimmedValue = submittedValue.trim();
|
|
701
|
+
if (trimmedValue.length > 0) {
|
|
702
|
+
// Add to independent input history
|
|
703
|
+
inputHistoryStore.addInput(trimmedValue);
|
|
704
|
+
submitQuery(trimmedValue);
|
|
705
|
+
}
|
|
706
|
+
}, [submitQuery, inputHistoryStore]);
|
|
707
|
+
const { handleUserInputSubmit } = useTodoPausePreserver({
|
|
708
|
+
controller: todoPauseController,
|
|
709
|
+
updateTodos,
|
|
710
|
+
handleFinalSubmit,
|
|
711
|
+
});
|
|
712
|
+
const handleIdePromptComplete = useCallback((result) => {
|
|
713
|
+
if (result.userSelection === 'yes') {
|
|
714
|
+
if (result.isExtensionPreInstalled) {
|
|
715
|
+
handleSlashCommand('/ide enable');
|
|
716
|
+
}
|
|
717
|
+
else {
|
|
718
|
+
handleSlashCommand('/ide install');
|
|
719
|
+
}
|
|
720
|
+
settings.setValue(SettingScope.User, 'hasSeenIdeIntegrationNudge', true);
|
|
721
|
+
}
|
|
722
|
+
else if (result.userSelection === 'dismiss') {
|
|
723
|
+
settings.setValue(SettingScope.User, 'hasSeenIdeIntegrationNudge', true);
|
|
724
|
+
}
|
|
725
|
+
setIdePromptAnswered(true);
|
|
726
|
+
}, [handleSlashCommand, settings]);
|
|
727
|
+
const { handleInput: vimHandleInput } = useVim(buffer, handleFinalSubmit);
|
|
728
|
+
const { elapsedTime, currentLoadingPhrase } = useLoadingIndicator(streamingState, settings.merged.ui?.customWittyPhrases);
|
|
729
|
+
const showAutoAcceptIndicator = useAutoAcceptIndicator({ config, addItem });
|
|
730
|
+
const handleExit = useCallback((pressedOnce, setPressedOnce, timerRef) => {
|
|
731
|
+
if (pressedOnce) {
|
|
732
|
+
if (timerRef.current) {
|
|
733
|
+
clearTimeout(timerRef.current);
|
|
734
|
+
}
|
|
735
|
+
// Directly invoke the central command handler.
|
|
736
|
+
handleSlashCommand('/quit');
|
|
737
|
+
}
|
|
738
|
+
else {
|
|
739
|
+
setPressedOnce(true);
|
|
740
|
+
timerRef.current = setTimeout(() => {
|
|
741
|
+
setPressedOnce(false);
|
|
742
|
+
timerRef.current = null;
|
|
743
|
+
}, CTRL_EXIT_PROMPT_DURATION_MS);
|
|
744
|
+
}
|
|
745
|
+
}, [handleSlashCommand]);
|
|
746
|
+
const handleSettingsRestart = useCallback(() => {
|
|
747
|
+
handleSlashCommand('/quit');
|
|
748
|
+
}, [handleSlashCommand]);
|
|
749
|
+
const handleGlobalKeypress = useCallback((key) => {
|
|
750
|
+
// Debug log keystrokes if enabled
|
|
751
|
+
if (settings.merged.debugKeystrokeLogging) {
|
|
752
|
+
console.log('[DEBUG] Keystroke:', JSON.stringify(key));
|
|
753
|
+
}
|
|
754
|
+
// Handle exit keys BEFORE dialog visibility check so exit prompts work even when dialogs are open
|
|
755
|
+
if (keyMatchers[Command.QUIT](key)) {
|
|
756
|
+
// When authenticating, let AuthInProgress component handle Ctrl+C.
|
|
757
|
+
if (isAuthenticating) {
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
760
|
+
if (!ctrlCPressedOnce) {
|
|
761
|
+
cancelOngoingRequest?.();
|
|
762
|
+
}
|
|
763
|
+
if (!ctrlCPressedOnce) {
|
|
764
|
+
setCtrlCPressedOnce(true);
|
|
765
|
+
ctrlCTimerRef.current = setTimeout(() => {
|
|
766
|
+
setCtrlCPressedOnce(false);
|
|
767
|
+
ctrlCTimerRef.current = null;
|
|
768
|
+
}, CTRL_EXIT_PROMPT_DURATION_MS);
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
handleExit(ctrlCPressedOnce, setCtrlCPressedOnce, ctrlCTimerRef);
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
else if (keyMatchers[Command.EXIT](key)) {
|
|
775
|
+
if (buffer.text.length > 0) {
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
778
|
+
handleExit(ctrlDPressedOnce, setCtrlDPressedOnce, ctrlDTimerRef);
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
let enteringConstrainHeightMode = false;
|
|
782
|
+
if (!constrainHeight) {
|
|
783
|
+
enteringConstrainHeightMode = true;
|
|
784
|
+
setConstrainHeight(true);
|
|
785
|
+
}
|
|
786
|
+
if (keyMatchers[Command.SHOW_ERROR_DETAILS](key)) {
|
|
787
|
+
setShowErrorDetails((prev) => !prev);
|
|
788
|
+
}
|
|
789
|
+
else if (keyMatchers[Command.TOGGLE_TOOL_DESCRIPTIONS](key)) {
|
|
790
|
+
const newValue = !showToolDescriptions;
|
|
791
|
+
setShowToolDescriptions(newValue);
|
|
792
|
+
const mcpServers = config.getMcpServers();
|
|
793
|
+
if (Object.keys(mcpServers || {}).length > 0) {
|
|
794
|
+
handleSlashCommand(newValue ? '/mcp desc' : '/mcp nodesc');
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
else if (keyMatchers[Command.TOGGLE_IDE_CONTEXT_DETAIL](key) &&
|
|
798
|
+
config.getIdeMode() &&
|
|
799
|
+
ideContextState) {
|
|
800
|
+
// Show IDE status when in IDE mode and context is available.
|
|
801
|
+
handleSlashCommand('/ide status');
|
|
802
|
+
}
|
|
803
|
+
else if (keyMatchers[Command.SHOW_MORE_LINES](key) &&
|
|
804
|
+
!enteringConstrainHeightMode) {
|
|
805
|
+
setConstrainHeight(false);
|
|
806
|
+
}
|
|
807
|
+
}, [
|
|
808
|
+
constrainHeight,
|
|
809
|
+
setConstrainHeight,
|
|
810
|
+
setShowErrorDetails,
|
|
811
|
+
showToolDescriptions,
|
|
812
|
+
setShowToolDescriptions,
|
|
813
|
+
config,
|
|
814
|
+
ideContextState,
|
|
815
|
+
handleExit,
|
|
816
|
+
ctrlCPressedOnce,
|
|
817
|
+
setCtrlCPressedOnce,
|
|
818
|
+
ctrlCTimerRef,
|
|
819
|
+
buffer.text.length,
|
|
820
|
+
ctrlDPressedOnce,
|
|
821
|
+
setCtrlDPressedOnce,
|
|
822
|
+
ctrlDTimerRef,
|
|
823
|
+
handleSlashCommand,
|
|
824
|
+
isAuthenticating,
|
|
825
|
+
cancelOngoingRequest,
|
|
826
|
+
settings.merged.debugKeystrokeLogging,
|
|
827
|
+
]);
|
|
828
|
+
const { refresh: globalKeypressRefresh } = useKeypress(handleGlobalKeypress, {
|
|
829
|
+
isActive: true,
|
|
830
|
+
});
|
|
831
|
+
useEffect(() => {
|
|
832
|
+
keypressRefreshRef.current = globalKeypressRefresh;
|
|
833
|
+
}, [globalKeypressRefresh]);
|
|
834
|
+
useEffect(() => {
|
|
835
|
+
if (config) {
|
|
836
|
+
setLlxprtMdFileCount(config.getLlxprtMdFileCount());
|
|
837
|
+
}
|
|
838
|
+
}, [config, config.getLlxprtMdFileCount]);
|
|
839
|
+
const logger = useLogger(config.storage);
|
|
840
|
+
// Initialize independent input history from logger
|
|
841
|
+
useEffect(() => {
|
|
842
|
+
inputHistoryStore.initializeFromLogger(logger);
|
|
843
|
+
}, [logger, inputHistoryStore]);
|
|
844
|
+
// Handle process exit when quit command is issued
|
|
845
|
+
useEffect(() => {
|
|
846
|
+
if (quittingMessages) {
|
|
847
|
+
// Allow UI to render the quit message briefly before exiting
|
|
848
|
+
const timer = setTimeout(() => {
|
|
849
|
+
process.exit(0);
|
|
850
|
+
}, 100); // 100ms delay to show quit screen
|
|
851
|
+
return () => clearTimeout(timer);
|
|
852
|
+
}
|
|
853
|
+
return undefined;
|
|
854
|
+
}, [quittingMessages]);
|
|
855
|
+
const isInputActive = (streamingState === StreamingState.Idle ||
|
|
856
|
+
streamingState === StreamingState.Responding) &&
|
|
857
|
+
!initError &&
|
|
858
|
+
!isProcessing;
|
|
859
|
+
useEffect(() => {
|
|
860
|
+
if (selectionLogger.enabled) {
|
|
861
|
+
if (confirmationRequest) {
|
|
862
|
+
selectionLogger.debug(() => 'Confirmation dialog opened');
|
|
863
|
+
}
|
|
864
|
+
else {
|
|
865
|
+
selectionLogger.debug(() => 'Confirmation dialog closed');
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
}, [confirmationRequest]);
|
|
869
|
+
const handleClearScreen = useCallback(() => {
|
|
870
|
+
clearItems();
|
|
871
|
+
clearConsoleMessagesState();
|
|
872
|
+
console.clear();
|
|
873
|
+
refreshStatic();
|
|
874
|
+
}, [clearItems, clearConsoleMessagesState, refreshStatic]);
|
|
875
|
+
const handleConfirmationSelect = useCallback((value) => {
|
|
876
|
+
if (confirmationRequest) {
|
|
877
|
+
if (selectionLogger.enabled) {
|
|
878
|
+
selectionLogger.debug(() => `AppContainer.handleConfirmationSelect value=${value} hasRequest=${Boolean(confirmationRequest)}`);
|
|
879
|
+
}
|
|
880
|
+
confirmationRequest.onConfirm(value);
|
|
881
|
+
}
|
|
882
|
+
}, [confirmationRequest]);
|
|
883
|
+
const mainControlsRef = useRef(null);
|
|
884
|
+
const pendingHistoryItemRef = useRef(null);
|
|
885
|
+
const rootUiRef = useRef(null);
|
|
886
|
+
useLayoutEffect(() => {
|
|
887
|
+
if (mainControlsRef.current) {
|
|
888
|
+
const fullFooterMeasurement = measureElement(mainControlsRef.current);
|
|
889
|
+
setFooterHeight(fullFooterMeasurement.height);
|
|
890
|
+
}
|
|
891
|
+
}, [terminalHeight, consoleMessages, showErrorDetails]);
|
|
892
|
+
const staticExtraHeight = /* margins and padding */ 3;
|
|
893
|
+
const availableTerminalHeight = useMemo(() => terminalHeight - footerHeight - staticExtraHeight, [terminalHeight, footerHeight]);
|
|
894
|
+
// Flicker detection - measures root UI element vs terminal height
|
|
895
|
+
// to detect overflow that could cause flickering (issue #456)
|
|
896
|
+
// This is for TELEMETRY ONLY - actual prevention is via availableTerminalHeight
|
|
897
|
+
useFlickerDetector(rootUiRef, terminalHeight, constrainHeight);
|
|
898
|
+
// Listen for Flicker events for additional corrective actions
|
|
899
|
+
useEffect(() => {
|
|
900
|
+
const handleFlicker = (data) => {
|
|
901
|
+
debug.log(`Flicker event received: overflow=${data.overflow}, content=${data.contentHeight}, terminal=${data.terminalHeight}`);
|
|
902
|
+
// When flicker is detected, ensure constrainHeight is enabled
|
|
903
|
+
// This provides a feedback loop to keep the UI constrained
|
|
904
|
+
if (!constrainHeight) {
|
|
905
|
+
setConstrainHeight(true);
|
|
906
|
+
}
|
|
907
|
+
};
|
|
908
|
+
appEvents.on(AppEvent.Flicker, handleFlicker);
|
|
909
|
+
return () => {
|
|
910
|
+
appEvents.off(AppEvent.Flicker, handleFlicker);
|
|
911
|
+
};
|
|
912
|
+
}, [constrainHeight]);
|
|
913
|
+
useEffect(() => {
|
|
914
|
+
// skip refreshing Static during first mount
|
|
915
|
+
if (isInitialMount.current) {
|
|
916
|
+
isInitialMount.current = false;
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
// debounce so it doesn't fire up too often during resize
|
|
920
|
+
const handler = setTimeout(() => {
|
|
921
|
+
if (streamingState === StreamingState.Idle) {
|
|
922
|
+
refreshStatic();
|
|
923
|
+
}
|
|
924
|
+
else {
|
|
925
|
+
setStaticNeedsRefresh(true);
|
|
926
|
+
}
|
|
927
|
+
}, 300);
|
|
928
|
+
return () => {
|
|
929
|
+
clearTimeout(handler);
|
|
930
|
+
};
|
|
931
|
+
}, [terminalWidth, terminalHeight, refreshStatic, streamingState]);
|
|
932
|
+
useEffect(() => {
|
|
933
|
+
if (streamingState === StreamingState.Idle && _staticNeedsRefresh) {
|
|
934
|
+
setStaticNeedsRefresh(false);
|
|
935
|
+
refreshStatic();
|
|
936
|
+
}
|
|
937
|
+
}, [streamingState, refreshStatic, _staticNeedsRefresh]);
|
|
938
|
+
const filteredConsoleMessages = useMemo(() => {
|
|
939
|
+
if (config.getDebugMode()) {
|
|
940
|
+
return consoleMessages;
|
|
941
|
+
}
|
|
942
|
+
return consoleMessages.filter((msg) => msg.type !== 'debug');
|
|
943
|
+
}, [consoleMessages, config]);
|
|
944
|
+
const branchName = useGitBranchName(config.getTargetDir());
|
|
945
|
+
const contextFileNames = useMemo(() => {
|
|
946
|
+
const fromSettings = settings.merged.ui?.contextFileName;
|
|
947
|
+
if (fromSettings) {
|
|
948
|
+
return Array.isArray(fromSettings) ? fromSettings : [fromSettings];
|
|
949
|
+
}
|
|
950
|
+
return getAllLlxprtMdFilenames();
|
|
951
|
+
}, [settings.merged.ui?.contextFileName]);
|
|
952
|
+
const initialPrompt = useMemo(() => config.getQuestion(), [config]);
|
|
953
|
+
const geminiClient = config.getGeminiClient();
|
|
954
|
+
useEffect(() => {
|
|
955
|
+
if (initialPrompt &&
|
|
956
|
+
!initialPromptSubmitted.current &&
|
|
957
|
+
!isAuthenticating &&
|
|
958
|
+
!isAuthDialogOpen &&
|
|
959
|
+
!isThemeDialogOpen &&
|
|
960
|
+
!isEditorDialogOpen &&
|
|
961
|
+
!isProviderDialogOpen &&
|
|
962
|
+
!isProviderModelDialogOpen &&
|
|
963
|
+
!isToolsDialogOpen &&
|
|
964
|
+
!showPrivacyNotice &&
|
|
965
|
+
geminiClient) {
|
|
966
|
+
submitQuery(initialPrompt);
|
|
967
|
+
initialPromptSubmitted.current = true;
|
|
968
|
+
}
|
|
969
|
+
}, [
|
|
970
|
+
initialPrompt,
|
|
971
|
+
submitQuery,
|
|
972
|
+
isAuthenticating,
|
|
973
|
+
isAuthDialogOpen,
|
|
974
|
+
isThemeDialogOpen,
|
|
975
|
+
isEditorDialogOpen,
|
|
976
|
+
isProviderDialogOpen,
|
|
977
|
+
isProviderModelDialogOpen,
|
|
978
|
+
isToolsDialogOpen,
|
|
979
|
+
showPrivacyNotice,
|
|
980
|
+
geminiClient,
|
|
981
|
+
]);
|
|
982
|
+
const mainAreaWidth = Math.floor(terminalWidth * 0.9);
|
|
983
|
+
// Detect PowerShell for file reference syntax tip
|
|
984
|
+
const isPowerShell = process.env.PSModulePath !== undefined ||
|
|
985
|
+
process.env.PSVERSION !== undefined;
|
|
986
|
+
const placeholder = vimModeEnabled
|
|
987
|
+
? " Press 'i' for INSERT mode and 'Esc' for NORMAL mode."
|
|
988
|
+
: isPowerShell
|
|
989
|
+
? ' Type your message, @path/to/file or +path/to/file'
|
|
990
|
+
: ' Type your message or @path/to/file';
|
|
991
|
+
// Build UIState object
|
|
992
|
+
const uiState = {
|
|
993
|
+
// Core app context
|
|
994
|
+
config,
|
|
995
|
+
settings,
|
|
996
|
+
// Terminal dimensions
|
|
997
|
+
terminalWidth,
|
|
998
|
+
terminalHeight,
|
|
999
|
+
mainAreaWidth,
|
|
1000
|
+
inputWidth,
|
|
1001
|
+
suggestionsWidth,
|
|
1002
|
+
// History and streaming
|
|
1003
|
+
history,
|
|
1004
|
+
pendingHistoryItems,
|
|
1005
|
+
streamingState,
|
|
1006
|
+
thought,
|
|
1007
|
+
// Input buffer
|
|
1008
|
+
buffer,
|
|
1009
|
+
shellModeActive,
|
|
1010
|
+
// Dialog states
|
|
1011
|
+
isThemeDialogOpen,
|
|
1012
|
+
isSettingsDialogOpen,
|
|
1013
|
+
isAuthDialogOpen,
|
|
1014
|
+
isAuthenticating,
|
|
1015
|
+
isEditorDialogOpen,
|
|
1016
|
+
isProviderDialogOpen,
|
|
1017
|
+
isProviderModelDialogOpen,
|
|
1018
|
+
isLoadProfileDialogOpen,
|
|
1019
|
+
isToolsDialogOpen,
|
|
1020
|
+
isFolderTrustDialogOpen,
|
|
1021
|
+
showWorkspaceMigrationDialog,
|
|
1022
|
+
showPrivacyNotice,
|
|
1023
|
+
isOAuthCodeDialogOpen: appState.openDialogs.oauthCode,
|
|
1024
|
+
isPermissionsDialogOpen,
|
|
1025
|
+
isLoggingDialogOpen,
|
|
1026
|
+
// Dialog data
|
|
1027
|
+
providerOptions,
|
|
1028
|
+
selectedProvider,
|
|
1029
|
+
providerModels,
|
|
1030
|
+
currentModel,
|
|
1031
|
+
profiles,
|
|
1032
|
+
toolsDialogAction,
|
|
1033
|
+
toolsDialogTools,
|
|
1034
|
+
toolsDialogDisabledTools,
|
|
1035
|
+
workspaceExtensions,
|
|
1036
|
+
loggingDialogData,
|
|
1037
|
+
// Confirmation requests
|
|
1038
|
+
shellConfirmationRequest,
|
|
1039
|
+
confirmationRequest,
|
|
1040
|
+
confirmUpdateExtensionRequests,
|
|
1041
|
+
// Exit/warning states
|
|
1042
|
+
ctrlCPressedOnce,
|
|
1043
|
+
ctrlDPressedOnce,
|
|
1044
|
+
showEscapePrompt,
|
|
1045
|
+
showIdeRestartPrompt,
|
|
1046
|
+
quittingMessages,
|
|
1047
|
+
// Display options
|
|
1048
|
+
constrainHeight,
|
|
1049
|
+
showErrorDetails,
|
|
1050
|
+
showToolDescriptions,
|
|
1051
|
+
isNarrow,
|
|
1052
|
+
vimModeEnabled,
|
|
1053
|
+
vimMode,
|
|
1054
|
+
// Context and status
|
|
1055
|
+
ideContextState,
|
|
1056
|
+
llxprtMdFileCount,
|
|
1057
|
+
branchName,
|
|
1058
|
+
errorCount,
|
|
1059
|
+
// Console and messages
|
|
1060
|
+
consoleMessages: filteredConsoleMessages,
|
|
1061
|
+
// Loading and status
|
|
1062
|
+
elapsedTime,
|
|
1063
|
+
currentLoadingPhrase,
|
|
1064
|
+
showAutoAcceptIndicator,
|
|
1065
|
+
// Token metrics
|
|
1066
|
+
tokenMetrics,
|
|
1067
|
+
historyTokenCount: sessionStats.historyTokenCount,
|
|
1068
|
+
// Error states
|
|
1069
|
+
initError,
|
|
1070
|
+
authError,
|
|
1071
|
+
themeError,
|
|
1072
|
+
editorError,
|
|
1073
|
+
// Processing states
|
|
1074
|
+
isProcessing,
|
|
1075
|
+
isInputActive,
|
|
1076
|
+
isFocused,
|
|
1077
|
+
// Refs for flicker detection
|
|
1078
|
+
rootUiRef,
|
|
1079
|
+
pendingHistoryItemRef,
|
|
1080
|
+
// Slash commands
|
|
1081
|
+
slashCommands,
|
|
1082
|
+
commandContext,
|
|
1083
|
+
// IDE prompt
|
|
1084
|
+
shouldShowIdePrompt: !!shouldShowIdePrompt,
|
|
1085
|
+
currentIDE,
|
|
1086
|
+
// Trust
|
|
1087
|
+
isRestarting,
|
|
1088
|
+
isTrustedFolder: config.isTrustedFolder(),
|
|
1089
|
+
// Input history
|
|
1090
|
+
inputHistory: inputHistoryStore.inputHistory,
|
|
1091
|
+
// Static key for refreshing
|
|
1092
|
+
staticKey,
|
|
1093
|
+
// Debug
|
|
1094
|
+
debugMessage,
|
|
1095
|
+
showDebugProfiler,
|
|
1096
|
+
// Footer height
|
|
1097
|
+
footerHeight,
|
|
1098
|
+
// Placeholder text
|
|
1099
|
+
placeholder,
|
|
1100
|
+
// Available terminal height for content (after footer measurement)
|
|
1101
|
+
availableTerminalHeight,
|
|
1102
|
+
};
|
|
1103
|
+
// Build UIActions object
|
|
1104
|
+
const uiActions = {
|
|
1105
|
+
// History actions
|
|
1106
|
+
addItem,
|
|
1107
|
+
clearItems,
|
|
1108
|
+
loadHistory,
|
|
1109
|
+
refreshStatic,
|
|
1110
|
+
// Input actions
|
|
1111
|
+
handleUserInputSubmit,
|
|
1112
|
+
handleClearScreen,
|
|
1113
|
+
// Theme dialog
|
|
1114
|
+
openThemeDialog,
|
|
1115
|
+
handleThemeSelect,
|
|
1116
|
+
handleThemeHighlight,
|
|
1117
|
+
// Settings dialog
|
|
1118
|
+
openSettingsDialog,
|
|
1119
|
+
closeSettingsDialog,
|
|
1120
|
+
handleSettingsRestart,
|
|
1121
|
+
// Auth dialog
|
|
1122
|
+
openAuthDialog,
|
|
1123
|
+
handleAuthSelect,
|
|
1124
|
+
cancelAuthentication,
|
|
1125
|
+
handleAuthTimeout,
|
|
1126
|
+
// Editor dialog
|
|
1127
|
+
openEditorDialog,
|
|
1128
|
+
handleEditorSelect,
|
|
1129
|
+
exitEditorDialog,
|
|
1130
|
+
// Provider dialog
|
|
1131
|
+
openProviderDialog,
|
|
1132
|
+
handleProviderSelect,
|
|
1133
|
+
exitProviderDialog,
|
|
1134
|
+
// Provider model dialog
|
|
1135
|
+
openProviderModelDialog,
|
|
1136
|
+
handleProviderModelChange,
|
|
1137
|
+
exitProviderModelDialog,
|
|
1138
|
+
// Load profile dialog
|
|
1139
|
+
openLoadProfileDialog,
|
|
1140
|
+
handleProfileSelect,
|
|
1141
|
+
exitLoadProfileDialog,
|
|
1142
|
+
// Tools dialog
|
|
1143
|
+
openToolsDialog,
|
|
1144
|
+
handleToolsSelect,
|
|
1145
|
+
exitToolsDialog,
|
|
1146
|
+
// Folder trust dialog
|
|
1147
|
+
handleFolderTrustSelect,
|
|
1148
|
+
// Permissions dialog
|
|
1149
|
+
openPermissionsDialog,
|
|
1150
|
+
closePermissionsDialog,
|
|
1151
|
+
// Logging dialog
|
|
1152
|
+
openLoggingDialog,
|
|
1153
|
+
closeLoggingDialog,
|
|
1154
|
+
// Workspace migration dialog
|
|
1155
|
+
onWorkspaceMigrationDialogOpen,
|
|
1156
|
+
onWorkspaceMigrationDialogClose,
|
|
1157
|
+
// Privacy notice
|
|
1158
|
+
openPrivacyNotice,
|
|
1159
|
+
handlePrivacyNoticeExit,
|
|
1160
|
+
// OAuth code dialog
|
|
1161
|
+
handleOAuthCodeDialogClose,
|
|
1162
|
+
handleOAuthCodeSubmit,
|
|
1163
|
+
// Confirmation handlers
|
|
1164
|
+
handleConfirmationSelect,
|
|
1165
|
+
// IDE prompt
|
|
1166
|
+
handleIdePromptComplete,
|
|
1167
|
+
// Vim
|
|
1168
|
+
vimHandleInput,
|
|
1169
|
+
toggleVimEnabled,
|
|
1170
|
+
// Slash commands
|
|
1171
|
+
handleSlashCommand,
|
|
1172
|
+
// Memory
|
|
1173
|
+
performMemoryRefresh,
|
|
1174
|
+
// Display toggles
|
|
1175
|
+
setShowErrorDetails,
|
|
1176
|
+
setShowToolDescriptions,
|
|
1177
|
+
setConstrainHeight,
|
|
1178
|
+
// Shell mode
|
|
1179
|
+
setShellModeActive,
|
|
1180
|
+
// Escape prompt
|
|
1181
|
+
handleEscapePromptChange,
|
|
1182
|
+
// Cancel ongoing request
|
|
1183
|
+
cancelOngoingRequest,
|
|
1184
|
+
};
|
|
1185
|
+
return (_jsx(UIStateProvider, { value: uiState, children: _jsx(UIActionsProvider, { value: uiActions, children: _jsx(DefaultAppLayout, { config: config, settings: settings, startupWarnings: startupWarnings, version: props.version, nightly: nightly, mainControlsRef: mainControlsRef, availableTerminalHeight: availableTerminalHeight, contextFileNames: contextFileNames, updateInfo: updateInfo }) }) }));
|
|
1186
|
+
};
|
|
1187
|
+
//# sourceMappingURL=AppContainer.js.map
|