@machina.ai/cell-cli 1.11.0-rc1 → 1.13.0-rc1
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/package.json +12 -10
- package/dist/src/commands/extensions/disable.d.ts +1 -1
- package/dist/src/commands/extensions/disable.js +15 -7
- package/dist/src/commands/extensions/disable.js.map +1 -1
- package/dist/src/commands/extensions/enable.d.ts +1 -1
- package/dist/src/commands/extensions/enable.js +15 -7
- package/dist/src/commands/extensions/enable.js.map +1 -1
- package/dist/src/commands/extensions/install.js +14 -3
- package/dist/src/commands/extensions/install.js.map +1 -1
- package/dist/src/commands/extensions/install.test.js +39 -19
- package/dist/src/commands/extensions/install.test.js.map +1 -1
- package/dist/src/commands/extensions/link.js +14 -3
- package/dist/src/commands/extensions/link.js.map +1 -1
- package/dist/src/commands/extensions/list.js +13 -4
- package/dist/src/commands/extensions/list.js.map +1 -1
- package/dist/src/commands/extensions/uninstall.js +13 -2
- package/dist/src/commands/extensions/uninstall.js.map +1 -1
- package/dist/src/commands/extensions/update.js +18 -13
- package/dist/src/commands/extensions/update.js.map +1 -1
- package/dist/src/commands/extensions/validate.d.ts +12 -0
- package/dist/src/commands/extensions/validate.js +83 -0
- package/dist/src/commands/extensions/validate.js.map +1 -0
- package/dist/src/commands/extensions/validate.test.js +93 -0
- package/dist/src/commands/extensions/validate.test.js.map +1 -0
- package/dist/src/commands/extensions.js +3 -0
- package/dist/src/commands/extensions.js.map +1 -1
- package/dist/src/commands/mcp/add.test.js +3 -0
- package/dist/src/commands/mcp/add.test.js.map +1 -1
- package/dist/src/commands/mcp/list.js +10 -3
- package/dist/src/commands/mcp/list.js.map +1 -1
- package/dist/src/commands/mcp/list.test.js +37 -27
- package/dist/src/commands/mcp/list.test.js.map +1 -1
- package/dist/src/config/auth.js +0 -5
- package/dist/src/config/auth.js.map +1 -1
- package/dist/src/config/config.d.ts +6 -3
- package/dist/src/config/config.js +65 -80
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +235 -212
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/extension-manager.d.ts +63 -0
- package/dist/src/config/extension-manager.js +450 -0
- package/dist/src/config/extension-manager.js.map +1 -0
- package/dist/src/config/extension.d.ts +4 -51
- package/dist/src/config/extension.js +1 -535
- package/dist/src/config/extension.js.map +1 -1
- package/dist/src/config/extension.test.js +525 -201
- package/dist/src/config/extension.test.js.map +1 -1
- package/dist/src/config/extensions/consent.d.ts +38 -0
- package/dist/src/config/extensions/consent.js +123 -0
- package/dist/src/config/extensions/consent.js.map +1 -0
- package/dist/src/config/extensions/extensionEnablement.d.ts +1 -1
- package/dist/src/config/extensions/extensionEnablement.js +4 -3
- package/dist/src/config/extensions/extensionEnablement.js.map +1 -1
- package/dist/src/config/extensions/extensionEnablement.test.js +10 -10
- package/dist/src/config/extensions/extensionEnablement.test.js.map +1 -1
- package/dist/src/config/extensions/extensionSettings.d.ts +15 -0
- package/dist/src/config/extensions/extensionSettings.js +113 -0
- package/dist/src/config/extensions/extensionSettings.js.map +1 -0
- package/dist/src/config/extensions/extensionSettings.test.d.ts +6 -0
- package/dist/src/config/extensions/extensionSettings.test.js +254 -0
- package/dist/src/config/extensions/extensionSettings.test.js.map +1 -0
- package/dist/src/config/extensions/github.d.ts +2 -2
- package/dist/src/config/extensions/github.js +5 -10
- package/dist/src/config/extensions/github.js.map +1 -1
- package/dist/src/config/extensions/github.test.js +153 -167
- package/dist/src/config/extensions/github.test.js.map +1 -1
- package/dist/src/config/extensions/github_fetch.d.ts +1 -1
- package/dist/src/config/extensions/github_fetch.js +13 -1
- package/dist/src/config/extensions/github_fetch.js.map +1 -1
- package/dist/src/config/extensions/github_fetch.test.d.ts +6 -0
- package/dist/src/config/extensions/github_fetch.test.js +169 -0
- package/dist/src/config/extensions/github_fetch.test.js.map +1 -0
- package/dist/src/config/extensions/storage.d.ts +14 -0
- package/dist/src/config/extensions/storage.js +32 -0
- package/dist/src/config/extensions/storage.js.map +1 -0
- package/dist/src/config/extensions/update.d.ts +4 -4
- package/dist/src/config/extensions/update.js +39 -39
- package/dist/src/config/extensions/update.js.map +1 -1
- package/dist/src/config/extensions/update.test.js +72 -74
- package/dist/src/config/extensions/update.test.js.map +1 -1
- package/dist/src/config/extensions/variableSchema.d.ts +0 -6
- package/dist/src/config/extensions/variableSchema.js.map +1 -1
- package/dist/src/config/extensions/variables.d.ts +4 -0
- package/dist/src/config/extensions/variables.js +6 -0
- package/dist/src/config/extensions/variables.js.map +1 -1
- package/dist/src/config/keyBindings.d.ts +3 -0
- package/dist/src/config/keyBindings.js +30 -8
- package/dist/src/config/keyBindings.js.map +1 -1
- package/dist/src/config/keyBindings.test.js +17 -0
- package/dist/src/config/keyBindings.test.js.map +1 -1
- package/dist/src/config/policies/read-only.toml +56 -0
- package/dist/src/config/policies/write.toml +63 -0
- package/dist/src/config/policies/yolo.toml +31 -0
- package/dist/src/config/policy-engine.integration.test.js +41 -38
- package/dist/src/config/policy-engine.integration.test.js.map +1 -1
- package/dist/src/config/policy.d.ts +2 -2
- package/dist/src/config/policy.js +10 -148
- package/dist/src/config/policy.js.map +1 -1
- package/dist/src/config/sandboxConfig.d.ts +1 -1
- package/dist/src/config/sandboxConfig.js +6 -3
- package/dist/src/config/sandboxConfig.js.map +1 -1
- package/dist/src/config/settings.d.ts +2 -1
- package/dist/src/config/settings.js +58 -18
- package/dist/src/config/settings.js.map +1 -1
- package/dist/src/config/settings.test.js +128 -69
- package/dist/src/config/settings.test.js.map +1 -1
- package/dist/src/config/settingsSchema.d.ts +170 -28
- package/dist/src/config/settingsSchema.js +418 -27
- package/dist/src/config/settingsSchema.js.map +1 -1
- package/dist/src/config/settingsSchema.test.js +42 -1
- package/dist/src/config/settingsSchema.test.js.map +1 -1
- package/dist/src/config/trustedFolders.d.ts +1 -1
- package/dist/src/config/trustedFolders.js +4 -2
- package/dist/src/config/trustedFolders.js.map +1 -1
- package/dist/src/core/initializer.js +2 -1
- package/dist/src/core/initializer.js.map +1 -1
- package/dist/src/gemini.d.ts +1 -1
- package/dist/src/gemini.js +46 -16
- package/dist/src/gemini.js.map +1 -1
- package/dist/src/gemini.test.js +88 -30
- package/dist/src/gemini.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/nonInteractiveCli.d.ts +9 -1
- package/dist/src/nonInteractiveCli.js +114 -7
- package/dist/src/nonInteractiveCli.js.map +1 -1
- package/dist/src/nonInteractiveCli.test.js +355 -112
- package/dist/src/nonInteractiveCli.test.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.js +4 -0
- package/dist/src/services/BuiltinCommandLoader.js.map +1 -1
- package/dist/src/services/BuiltinCommandLoader.test.js +22 -0
- package/dist/src/services/BuiltinCommandLoader.test.js.map +1 -1
- package/dist/src/services/FeedbackService.js +2 -2
- package/dist/src/services/FeedbackService.js.map +1 -1
- package/dist/src/services/McpPromptLoader.js +2 -2
- package/dist/src/services/McpPromptLoader.js.map +1 -1
- package/dist/src/services/McpPromptLoader.test.js +4 -2
- package/dist/src/services/McpPromptLoader.test.js.map +1 -1
- package/dist/src/test-utils/async.d.ts +9 -0
- package/dist/src/test-utils/async.js +29 -0
- package/dist/src/test-utils/async.js.map +1 -0
- package/dist/src/test-utils/createExtension.d.ts +3 -1
- package/dist/src/test-utils/createExtension.js +3 -3
- package/dist/src/test-utils/createExtension.js.map +1 -1
- package/dist/src/test-utils/render.d.ts +16 -2
- package/dist/src/test-utils/render.js +66 -4
- package/dist/src/test-utils/render.js.map +1 -1
- package/dist/src/test-utils/render.test.d.ts +6 -0
- package/dist/src/test-utils/render.test.js +79 -0
- package/dist/src/test-utils/render.test.js.map +1 -0
- package/dist/src/ui/App.test.js +1 -1
- package/dist/src/ui/App.test.js.map +1 -1
- package/dist/src/ui/AppContainer.js +181 -65
- package/dist/src/ui/AppContainer.js.map +1 -1
- package/dist/src/ui/AppContainer.test.js +505 -147
- package/dist/src/ui/AppContainer.test.js.map +1 -1
- package/dist/src/ui/IdeIntegrationNudge.js +1 -1
- package/dist/src/ui/IdeIntegrationNudge.js.map +1 -1
- package/dist/src/ui/auth/ApiAuthDialog.d.ts +14 -0
- package/dist/src/ui/auth/ApiAuthDialog.js +26 -0
- package/dist/src/ui/auth/ApiAuthDialog.js.map +1 -0
- package/dist/src/ui/auth/ApiAuthDialog.test.d.ts +6 -0
- package/dist/src/ui/auth/ApiAuthDialog.test.js +91 -0
- package/dist/src/ui/auth/ApiAuthDialog.test.js.map +1 -0
- package/dist/src/ui/auth/AuthDialog.js +7 -3
- package/dist/src/ui/auth/AuthDialog.js.map +1 -1
- package/dist/src/ui/auth/useAuth.d.ts +2 -0
- package/dist/src/ui/auth/useAuth.js +31 -2
- package/dist/src/ui/auth/useAuth.js.map +1 -1
- package/dist/src/ui/colors.js +3 -0
- package/dist/src/ui/colors.js.map +1 -1
- package/dist/src/ui/commands/directoryCommand.js +1 -1
- package/dist/src/ui/commands/directoryCommand.js.map +1 -1
- package/dist/src/ui/commands/extensionsCommand.js +64 -11
- package/dist/src/ui/commands/extensionsCommand.js.map +1 -1
- package/dist/src/ui/commands/extensionsCommand.test.js +72 -1
- package/dist/src/ui/commands/extensionsCommand.test.js.map +1 -1
- package/dist/src/ui/commands/mcpCommand.js +14 -14
- package/dist/src/ui/commands/mcpCommand.js.map +1 -1
- package/dist/src/ui/commands/mcpCommand.test.js +4 -0
- package/dist/src/ui/commands/mcpCommand.test.js.map +1 -1
- package/dist/src/ui/commands/memoryCommand.js +1 -1
- package/dist/src/ui/commands/memoryCommand.js.map +1 -1
- package/dist/src/ui/commands/memoryCommand.test.js +3 -1
- package/dist/src/ui/commands/memoryCommand.test.js.map +1 -1
- package/dist/src/ui/commands/policiesCommand.d.ts +7 -0
- package/dist/src/ui/commands/policiesCommand.js +59 -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 +83 -0
- package/dist/src/ui/commands/policiesCommand.test.js.map +1 -0
- package/dist/src/ui/components/AnsiOutput.test.js +1 -1
- package/dist/src/ui/components/AnsiOutput.test.js.map +1 -1
- package/dist/src/ui/components/AsciiArt.d.ts +3 -3
- package/dist/src/ui/components/AsciiArt.js +3 -3
- package/dist/src/ui/components/Composer.js +1 -1
- package/dist/src/ui/components/Composer.js.map +1 -1
- package/dist/src/ui/components/Composer.test.js +5 -2
- package/dist/src/ui/components/Composer.test.js.map +1 -1
- package/dist/src/ui/components/ConfigInitDisplay.js +4 -6
- package/dist/src/ui/components/ConfigInitDisplay.js.map +1 -1
- package/dist/src/ui/components/ConsentPrompt.test.js +18 -8
- package/dist/src/ui/components/ConsentPrompt.test.js.map +1 -1
- package/dist/src/ui/components/ConsoleSummaryDisplay.js +1 -1
- package/dist/src/ui/components/ConsoleSummaryDisplay.js.map +1 -1
- package/dist/src/ui/components/ContextSummaryDisplay.test.js +11 -6
- package/dist/src/ui/components/ContextSummaryDisplay.test.js.map +1 -1
- package/dist/src/ui/components/DetailedMessagesDisplay.js +1 -1
- package/dist/src/ui/components/DetailedMessagesDisplay.js.map +1 -1
- package/dist/src/ui/components/DialogManager.js +4 -0
- package/dist/src/ui/components/DialogManager.js.map +1 -1
- package/dist/src/ui/components/FolderTrustDialog.test.js +2 -1
- package/dist/src/ui/components/FolderTrustDialog.test.js.map +1 -1
- package/dist/src/ui/components/Footer.js +4 -3
- package/dist/src/ui/components/Footer.js.map +1 -1
- package/dist/src/ui/components/Footer.test.js +83 -0
- package/dist/src/ui/components/Footer.test.js.map +1 -1
- package/dist/src/ui/components/Header.test.js +13 -5
- package/dist/src/ui/components/Header.test.js.map +1 -1
- package/dist/src/ui/components/Help.test.js +5 -4
- package/dist/src/ui/components/Help.test.js.map +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.js +1 -1
- package/dist/src/ui/components/HistoryItemDisplay.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.js +27 -8
- package/dist/src/ui/components/InputPrompt.js.map +1 -1
- package/dist/src/ui/components/InputPrompt.test.js +776 -727
- package/dist/src/ui/components/InputPrompt.test.js.map +1 -1
- package/dist/src/ui/components/LoadingIndicator.js +2 -2
- package/dist/src/ui/components/LoadingIndicator.js.map +1 -1
- package/dist/src/ui/components/LoadingIndicator.test.js +28 -15
- package/dist/src/ui/components/LoadingIndicator.test.js.map +1 -1
- package/dist/src/ui/components/LoopDetectionConfirmation.js +1 -1
- package/dist/src/ui/components/LoopDetectionConfirmation.js.map +1 -1
- package/dist/src/ui/components/LoopDetectionConfirmation.test.js +2 -2
- package/dist/src/ui/components/LoopDetectionConfirmation.test.js.map +1 -1
- package/dist/src/ui/components/MainContent.js +15 -4
- package/dist/src/ui/components/MainContent.js.map +1 -1
- package/dist/src/ui/components/ModelDialog.js +1 -1
- package/dist/src/ui/components/ModelDialog.js.map +1 -1
- package/dist/src/ui/components/ModelDialog.test.js +23 -13
- package/dist/src/ui/components/ModelDialog.test.js.map +1 -1
- package/dist/src/ui/components/ModelStatsDisplay.test.js +1 -1
- package/dist/src/ui/components/ModelStatsDisplay.test.js.map +1 -1
- package/dist/src/ui/components/Notifications.js +38 -5
- package/dist/src/ui/components/Notifications.js.map +1 -1
- package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js +2 -2
- package/dist/src/ui/components/PermissionsModifyTrustDialog.test.js.map +1 -1
- package/dist/src/ui/components/PrepareLabel.test.js +14 -8
- package/dist/src/ui/components/PrepareLabel.test.js.map +1 -1
- package/dist/src/ui/components/ProQuotaDialog.test.js +14 -6
- package/dist/src/ui/components/ProQuotaDialog.test.js.map +1 -1
- package/dist/src/ui/components/QueuedMessageDisplay.test.js +11 -6
- package/dist/src/ui/components/QueuedMessageDisplay.test.js.map +1 -1
- package/dist/src/ui/components/SessionSummaryDisplay.test.js +1 -1
- package/dist/src/ui/components/SessionSummaryDisplay.test.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.js +32 -25
- package/dist/src/ui/components/SettingsDialog.js.map +1 -1
- package/dist/src/ui/components/SettingsDialog.test.js +428 -532
- package/dist/src/ui/components/SettingsDialog.test.js.map +1 -1
- package/dist/src/ui/components/ShellConfirmationDialog.js +1 -1
- package/dist/src/ui/components/ShellConfirmationDialog.js.map +1 -1
- package/dist/src/ui/components/ShellConfirmationDialog.test.js +2 -2
- package/dist/src/ui/components/ShellConfirmationDialog.test.js.map +1 -1
- package/dist/src/ui/components/StatsDisplay.test.js +1 -1
- package/dist/src/ui/components/StatsDisplay.test.js.map +1 -1
- package/dist/src/ui/components/SuggestionsDisplay.js +1 -1
- package/dist/src/ui/components/SuggestionsDisplay.js.map +1 -1
- package/dist/src/ui/components/ThemeDialog.test.js +2 -2
- package/dist/src/ui/components/ThemeDialog.test.js.map +1 -1
- package/dist/src/ui/components/ToolStatsDisplay.test.js +1 -1
- package/dist/src/ui/components/ToolStatsDisplay.test.js.map +1 -1
- package/dist/src/ui/components/messages/CompressionMessage.test.js +25 -17
- package/dist/src/ui/components/messages/CompressionMessage.test.js.map +1 -1
- package/dist/src/ui/components/messages/DiffRenderer.test.js +1 -1
- package/dist/src/ui/components/messages/DiffRenderer.test.js.map +1 -1
- package/dist/src/ui/components/messages/InfoMessage.js +1 -1
- package/dist/src/ui/components/messages/InfoMessage.js.map +1 -1
- package/dist/src/ui/components/messages/Todo.js +27 -5
- package/dist/src/ui/components/messages/Todo.js.map +1 -1
- package/dist/src/ui/components/messages/Todo.test.js +20 -8
- package/dist/src/ui/components/messages/Todo.test.js.map +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js +1 -1
- package/dist/src/ui/components/messages/ToolConfirmationMessage.js.map +1 -1
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js +29 -15
- package/dist/src/ui/components/messages/ToolGroupMessage.test.js.map +1 -1
- package/dist/src/ui/components/messages/WarningMessage.js +2 -2
- package/dist/src/ui/components/messages/WarningMessage.js.map +1 -1
- package/dist/src/ui/components/shared/BaseSelectionList.test.js +1 -1
- package/dist/src/ui/components/shared/BaseSelectionList.test.js.map +1 -1
- package/dist/src/ui/components/shared/MaxSizedBox.test.js +43 -22
- package/dist/src/ui/components/shared/MaxSizedBox.test.js.map +1 -1
- package/dist/src/ui/components/shared/TextInput.d.ts +15 -0
- package/dist/src/ui/components/shared/TextInput.js +38 -0
- package/dist/src/ui/components/shared/TextInput.js.map +1 -0
- package/dist/src/ui/components/shared/TextInput.test.d.ts +6 -0
- package/dist/src/ui/components/shared/TextInput.test.js +242 -0
- package/dist/src/ui/components/shared/TextInput.test.js.map +1 -0
- package/dist/src/ui/components/shared/text-buffer.d.ts +9 -2
- package/dist/src/ui/components/shared/text-buffer.js +51 -13
- package/dist/src/ui/components/shared/text-buffer.js.map +1 -1
- package/dist/src/ui/components/shared/text-buffer.test.js +385 -202
- package/dist/src/ui/components/shared/text-buffer.test.js.map +1 -1
- package/dist/src/ui/components/views/ChatList.test.js +7 -4
- package/dist/src/ui/components/views/ChatList.test.js.map +1 -1
- package/dist/src/ui/components/views/ExtensionsList.d.ts +7 -1
- package/dist/src/ui/components/views/ExtensionsList.js +9 -11
- package/dist/src/ui/components/views/ExtensionsList.js.map +1 -1
- package/dist/src/ui/components/views/ExtensionsList.test.js +43 -22
- package/dist/src/ui/components/views/ExtensionsList.test.js.map +1 -1
- package/dist/src/ui/components/views/McpStatus.test.js +23 -12
- package/dist/src/ui/components/views/McpStatus.test.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.d.ts +3 -2
- package/dist/src/ui/contexts/KeypressContext.js +610 -540
- package/dist/src/ui/contexts/KeypressContext.js.map +1 -1
- package/dist/src/ui/contexts/KeypressContext.test.js +438 -718
- package/dist/src/ui/contexts/KeypressContext.test.js.map +1 -1
- package/dist/src/ui/contexts/MouseContext.d.ts +21 -0
- package/dist/src/ui/contexts/MouseContext.js +89 -0
- package/dist/src/ui/contexts/MouseContext.js.map +1 -0
- package/dist/src/ui/contexts/MouseContext.test.d.ts +6 -0
- package/dist/src/ui/contexts/MouseContext.test.js +164 -0
- package/dist/src/ui/contexts/MouseContext.test.js.map +1 -0
- package/dist/src/ui/contexts/SessionContext.test.js +35 -17
- package/dist/src/ui/contexts/SessionContext.test.js.map +1 -1
- package/dist/src/ui/contexts/UIActionsContext.d.ts +2 -0
- package/dist/src/ui/contexts/UIActionsContext.js.map +1 -1
- package/dist/src/ui/contexts/UIStateContext.d.ts +2 -0
- package/dist/src/ui/contexts/UIStateContext.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.js +31 -9
- package/dist/src/ui/hooks/atCommandProcessor.js.map +1 -1
- package/dist/src/ui/hooks/atCommandProcessor.test.js +163 -64
- package/dist/src/ui/hooks/atCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/shellCommandProcessor.test.js +64 -35
- package/dist/src/ui/hooks/shellCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/slashCommandProcessor.test.js +193 -165
- package/dist/src/ui/hooks/slashCommandProcessor.test.js.map +1 -1
- package/dist/src/ui/hooks/useAtCompletion.test.js +16 -5
- package/dist/src/ui/hooks/useAtCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useAutoAcceptIndicator.js +10 -0
- package/dist/src/ui/hooks/useAutoAcceptIndicator.js.map +1 -1
- package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js +32 -1
- package/dist/src/ui/hooks/useAutoAcceptIndicator.test.js.map +1 -1
- package/dist/src/ui/hooks/useCommandCompletion.test.js +66 -64
- package/dist/src/ui/hooks/useCommandCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useConsoleMessages.test.js +26 -9
- package/dist/src/ui/hooks/useConsoleMessages.test.js.map +1 -1
- package/dist/src/ui/hooks/useEditorSettings.test.js +40 -34
- package/dist/src/ui/hooks/useEditorSettings.test.js.map +1 -1
- package/dist/src/ui/hooks/useExtensionUpdates.d.ts +14 -5
- package/dist/src/ui/hooks/useExtensionUpdates.js +18 -13
- package/dist/src/ui/hooks/useExtensionUpdates.js.map +1 -1
- package/dist/src/ui/hooks/useExtensionUpdates.test.js +49 -44
- package/dist/src/ui/hooks/useExtensionUpdates.test.js.map +1 -1
- package/dist/src/ui/hooks/useFlickerDetector.test.js +9 -5
- package/dist/src/ui/hooks/useFlickerDetector.test.js.map +1 -1
- package/dist/src/ui/hooks/useFocus.test.js +25 -9
- package/dist/src/ui/hooks/useFocus.test.js.map +1 -1
- package/dist/src/ui/hooks/useFolderTrust.test.js +46 -22
- package/dist/src/ui/hooks/useFolderTrust.test.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.js +56 -19
- package/dist/src/ui/hooks/useGeminiStream.js.map +1 -1
- package/dist/src/ui/hooks/useGeminiStream.test.js +260 -411
- package/dist/src/ui/hooks/useGeminiStream.test.js.map +1 -1
- package/dist/src/ui/hooks/useGitBranchName.js +4 -0
- package/dist/src/ui/hooks/useGitBranchName.js.map +1 -1
- package/dist/src/ui/hooks/useGitBranchName.test.js +46 -34
- package/dist/src/ui/hooks/useGitBranchName.test.js.map +1 -1
- package/dist/src/ui/hooks/useHistoryManager.test.js +2 -1
- package/dist/src/ui/hooks/useHistoryManager.test.js.map +1 -1
- package/dist/src/ui/hooks/useIdeTrustListener.test.js +40 -9
- package/dist/src/ui/hooks/useIdeTrustListener.test.js.map +1 -1
- package/dist/src/ui/hooks/useInputHistory.test.js +2 -1
- package/dist/src/ui/hooks/useInputHistory.test.js.map +1 -1
- package/dist/src/ui/hooks/useInputHistoryStore.test.js +2 -1
- package/dist/src/ui/hooks/useInputHistoryStore.test.js.map +1 -1
- package/dist/src/ui/hooks/useKeypress.test.js +103 -114
- package/dist/src/ui/hooks/useKeypress.test.js.map +1 -1
- package/dist/src/ui/hooks/useLoadingIndicator.test.js +24 -6
- package/dist/src/ui/hooks/useLoadingIndicator.test.js.map +1 -1
- package/dist/src/ui/hooks/useMemoryMonitor.test.js +10 -5
- package/dist/src/ui/hooks/useMemoryMonitor.test.js.map +1 -1
- package/dist/src/ui/hooks/useMessageQueue.test.js +62 -45
- package/dist/src/ui/hooks/useMessageQueue.test.js.map +1 -1
- package/dist/src/ui/hooks/useModelCommand.test.js +21 -11
- package/dist/src/ui/hooks/useModelCommand.test.js.map +1 -1
- package/dist/src/ui/hooks/useMouse.d.ts +17 -0
- package/dist/src/ui/hooks/useMouse.js +27 -0
- package/dist/src/ui/hooks/useMouse.js.map +1 -0
- package/dist/src/ui/hooks/useMouse.test.d.ts +6 -0
- package/dist/src/ui/hooks/useMouse.test.js +57 -0
- package/dist/src/ui/hooks/useMouse.test.js.map +1 -0
- package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js +2 -2
- package/dist/src/ui/hooks/usePermissionsModifyTrust.test.js.map +1 -1
- package/dist/src/ui/hooks/usePhraseCycler.js +1 -1
- package/dist/src/ui/hooks/usePhraseCycler.js.map +1 -1
- package/dist/src/ui/hooks/usePhraseCycler.test.js +109 -106
- package/dist/src/ui/hooks/usePhraseCycler.test.js.map +1 -1
- package/dist/src/ui/hooks/usePrivacySettings.test.js +26 -6
- package/dist/src/ui/hooks/usePrivacySettings.test.js.map +1 -1
- package/dist/src/ui/hooks/usePromptCompletion.js +2 -2
- package/dist/src/ui/hooks/usePromptCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useQuotaAndFallback.js +13 -14
- package/dist/src/ui/hooks/useQuotaAndFallback.js.map +1 -1
- package/dist/src/ui/hooks/useQuotaAndFallback.test.js +55 -48
- package/dist/src/ui/hooks/useQuotaAndFallback.test.js.map +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.d.ts +8 -1
- package/dist/src/ui/hooks/useReactToolScheduler.js +59 -34
- package/dist/src/ui/hooks/useReactToolScheduler.js.map +1 -1
- package/dist/src/ui/hooks/useReactToolScheduler.test.d.ts +6 -0
- package/dist/src/ui/hooks/useReactToolScheduler.test.js +65 -0
- package/dist/src/ui/hooks/useReactToolScheduler.test.js.map +1 -0
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.js +2 -2
- package/dist/src/ui/hooks/useReverseSearchCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useSelectionList.js +5 -4
- package/dist/src/ui/hooks/useSelectionList.js.map +1 -1
- package/dist/src/ui/hooks/useSelectionList.test.js +272 -183
- package/dist/src/ui/hooks/useSelectionList.test.js.map +1 -1
- package/dist/src/ui/hooks/useShellHistory.test.js +52 -20
- package/dist/src/ui/hooks/useShellHistory.test.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.js +18 -7
- package/dist/src/ui/hooks/useSlashCompletion.js.map +1 -1
- package/dist/src/ui/hooks/useSlashCompletion.test.js +275 -137
- package/dist/src/ui/hooks/useSlashCompletion.test.js.map +1 -1
- package/dist/src/ui/hooks/useTimer.test.js +43 -14
- package/dist/src/ui/hooks/useTimer.test.js.map +1 -1
- package/dist/src/ui/hooks/useToolScheduler.test.js +226 -242
- package/dist/src/ui/hooks/useToolScheduler.test.js.map +1 -1
- package/dist/src/ui/hooks/vim.test.js +235 -355
- package/dist/src/ui/hooks/vim.test.js.map +1 -1
- package/dist/src/ui/keyMatchers.test.js +30 -3
- package/dist/src/ui/keyMatchers.test.js.map +1 -1
- package/dist/src/ui/state/extensions.d.ts +1 -0
- package/dist/src/ui/state/extensions.js +1 -0
- package/dist/src/ui/state/extensions.js.map +1 -1
- package/dist/src/ui/themes/ansi-light.js +1 -0
- package/dist/src/ui/themes/ansi-light.js.map +1 -1
- package/dist/src/ui/themes/ansi.js +1 -0
- package/dist/src/ui/themes/ansi.js.map +1 -1
- package/dist/src/ui/themes/atom-one-dark.js +2 -0
- package/dist/src/ui/themes/atom-one-dark.js.map +1 -1
- package/dist/src/ui/themes/ayu-light.js +2 -0
- package/dist/src/ui/themes/ayu-light.js.map +1 -1
- package/dist/src/ui/themes/ayu.js +2 -0
- package/dist/src/ui/themes/ayu.js.map +1 -1
- package/dist/src/ui/themes/color-utils.d.ts +1 -0
- package/dist/src/ui/themes/color-utils.js +6 -0
- package/dist/src/ui/themes/color-utils.js.map +1 -1
- package/dist/src/ui/themes/color-utils.test.js +13 -1
- package/dist/src/ui/themes/color-utils.test.js.map +1 -1
- package/dist/src/ui/themes/dracula.js +2 -0
- package/dist/src/ui/themes/dracula.js.map +1 -1
- package/dist/src/ui/themes/github-dark.js +2 -0
- package/dist/src/ui/themes/github-dark.js.map +1 -1
- package/dist/src/ui/themes/github-light.js +2 -0
- package/dist/src/ui/themes/github-light.js.map +1 -1
- package/dist/src/ui/themes/googlecode.js +2 -0
- package/dist/src/ui/themes/googlecode.js.map +1 -1
- package/dist/src/ui/themes/no-color.js +3 -0
- package/dist/src/ui/themes/no-color.js.map +1 -1
- package/dist/src/ui/themes/semantic-tokens.d.ts +2 -0
- package/dist/src/ui/themes/semantic-tokens.js +6 -0
- package/dist/src/ui/themes/semantic-tokens.js.map +1 -1
- package/dist/src/ui/themes/shades-of-purple.js +2 -0
- package/dist/src/ui/themes/shades-of-purple.js.map +1 -1
- package/dist/src/ui/themes/theme.d.ts +3 -0
- package/dist/src/ui/themes/theme.js +14 -3
- package/dist/src/ui/themes/theme.js.map +1 -1
- package/dist/src/ui/themes/theme.test.js +67 -1
- package/dist/src/ui/themes/theme.test.js.map +1 -1
- package/dist/src/ui/themes/xcode.js +2 -0
- package/dist/src/ui/themes/xcode.js.map +1 -1
- package/dist/src/ui/types.d.ts +3 -1
- package/dist/src/ui/types.js +2 -0
- package/dist/src/ui/types.js.map +1 -1
- package/dist/src/ui/utils/CodeColorizer.js +2 -1
- package/dist/src/ui/utils/CodeColorizer.js.map +1 -1
- package/dist/src/ui/utils/InlineMarkdownRenderer.d.ts +1 -0
- package/dist/src/ui/utils/InlineMarkdownRenderer.js +11 -10
- package/dist/src/ui/utils/InlineMarkdownRenderer.js.map +1 -1
- package/dist/src/ui/utils/MarkdownDisplay.js +11 -9
- package/dist/src/ui/utils/MarkdownDisplay.js.map +1 -1
- package/dist/src/ui/utils/clipboardUtils.js +2 -2
- package/dist/src/ui/utils/clipboardUtils.js.map +1 -1
- package/dist/src/ui/utils/input.d.ts +17 -0
- package/dist/src/ui/utils/input.js +51 -0
- package/dist/src/ui/utils/input.js.map +1 -0
- package/dist/src/ui/utils/input.test.d.ts +6 -0
- package/dist/src/ui/utils/input.test.js +44 -0
- package/dist/src/ui/utils/input.test.js.map +1 -0
- package/dist/src/ui/utils/kittyProtocolDetector.js +13 -4
- package/dist/src/ui/utils/kittyProtocolDetector.js.map +1 -1
- package/dist/src/ui/utils/mouse.d.ts +31 -0
- package/dist/src/ui/utils/mouse.js +164 -0
- package/dist/src/ui/utils/mouse.js.map +1 -0
- package/dist/src/ui/utils/mouse.test.d.ts +6 -0
- package/dist/src/ui/utils/mouse.test.js +131 -0
- package/dist/src/ui/utils/mouse.test.js.map +1 -0
- package/dist/src/ui/utils/textOutput.d.ts +25 -0
- package/dist/src/ui/utils/textOutput.js +49 -0
- package/dist/src/ui/utils/textOutput.js.map +1 -0
- package/dist/src/ui/utils/textOutput.test.d.ts +6 -0
- package/dist/src/ui/utils/textOutput.test.js +79 -0
- package/dist/src/ui/utils/textOutput.test.js.map +1 -0
- package/dist/src/ui/utils/updateCheck.d.ts +7 -1
- package/dist/src/ui/utils/updateCheck.js +33 -29
- package/dist/src/ui/utils/updateCheck.js.map +1 -1
- package/dist/src/ui/utils/updateCheck.test.js +24 -50
- package/dist/src/ui/utils/updateCheck.test.js.map +1 -1
- package/dist/src/utils/commentJson.js +2 -2
- package/dist/src/utils/commentJson.js.map +1 -1
- package/dist/src/utils/commentJson.test.js +7 -6
- package/dist/src/utils/commentJson.test.js.map +1 -1
- package/dist/src/utils/envVarResolver.d.ts +2 -2
- package/dist/src/utils/envVarResolver.js +10 -7
- package/dist/src/utils/envVarResolver.js.map +1 -1
- package/dist/src/utils/events.d.ts +11 -2
- package/dist/src/utils/events.js +1 -0
- package/dist/src/utils/events.js.map +1 -1
- package/dist/src/utils/handleAutoUpdate.js +9 -3
- package/dist/src/utils/handleAutoUpdate.js.map +1 -1
- package/dist/src/utils/sandbox.js +16 -18
- package/dist/src/utils/sandbox.js.map +1 -1
- package/dist/src/utils/version.js +6 -2
- package/dist/src/utils/version.js.map +1 -1
- package/dist/src/zed-integration/acp.js +2 -1
- package/dist/src/zed-integration/acp.js.map +1 -1
- package/dist/src/zed-integration/schema.d.ts +4 -4
- package/dist/src/zed-integration/zedIntegration.d.ts +2 -2
- package/dist/src/zed-integration/zedIntegration.js +12 -19
- package/dist/src/zed-integration/zedIntegration.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +14 -14
- package/dist/src/config/policy.test.js +0 -360
- package/dist/src/config/policy.test.js.map +0 -1
- package/dist/src/utils/package.d.ts +0 -12
- package/dist/src/utils/package.js +0 -24
- package/dist/src/utils/package.js.map +0 -1
- /package/dist/src/{config/policy.test.d.ts → commands/extensions/validate.test.d.ts} +0 -0
|
@@ -5,205 +5,211 @@ import { createContext, useCallback, useContext, useEffect, useRef, } from 'reac
|
|
|
5
5
|
import readline from 'node:readline';
|
|
6
6
|
import { PassThrough } from 'node:stream';
|
|
7
7
|
import { BACKSLASH_ENTER_DETECTION_WINDOW_MS, CHAR_CODE_ESC, KITTY_CTRL_C, KITTY_KEYCODE_BACKSPACE, KITTY_KEYCODE_ENTER, KITTY_KEYCODE_NUMPAD_ENTER, KITTY_KEYCODE_TAB, MAX_KITTY_SEQUENCE_LENGTH, KITTY_MODIFIER_BASE, KITTY_MODIFIER_EVENT_TYPES_OFFSET, MODIFIER_SHIFT_BIT, MODIFIER_ALT_BIT, MODIFIER_CTRL_BIT, } from '../utils/platformConstants.js';
|
|
8
|
+
import { ESC, couldBeMouseSequence } from '../utils/input.js';
|
|
8
9
|
import { FOCUS_IN, FOCUS_OUT } from '../hooks/useFocus.js';
|
|
9
|
-
|
|
10
|
-
export const
|
|
11
|
-
export const
|
|
10
|
+
import { isIncompleteMouseSequence, parseMouseEvent } from '../utils/mouse.js';
|
|
11
|
+
export const PASTE_MODE_START = `${ESC}[200~`;
|
|
12
|
+
export const PASTE_MODE_END = `${ESC}[201~`;
|
|
12
13
|
export const DRAG_COMPLETION_TIMEOUT_MS = 100; // Broadcast full path after 100ms if no more input
|
|
13
14
|
export const KITTY_SEQUENCE_TIMEOUT_MS = 50; // Flush incomplete kitty sequences after 50ms
|
|
15
|
+
export const PASTE_CODE_TIMEOUT_MS = 50; // Flush incomplete paste code after 50ms
|
|
14
16
|
export const SINGLE_QUOTE = "'";
|
|
15
17
|
export const DOUBLE_QUOTE = '"';
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
'\
|
|
20
|
-
'\
|
|
21
|
-
'\
|
|
22
|
-
'\u0192': 'f',
|
|
23
|
-
'\u00A9': 'g',
|
|
24
|
-
'\u02D9': 'h',
|
|
25
|
-
'\u02C6': 'i',
|
|
26
|
-
'\u2206': 'j',
|
|
27
|
-
'\u02DA': 'k',
|
|
28
|
-
'\u00AC': 'l',
|
|
29
|
-
'\u00B5': 'm',
|
|
30
|
-
'\u02DC': 'n',
|
|
31
|
-
'\u00F8': 'o',
|
|
32
|
-
'\u03C0': 'p',
|
|
33
|
-
'\u0153': 'q',
|
|
34
|
-
'\u00AE': 'r',
|
|
35
|
-
'\u00DF': 's',
|
|
36
|
-
'\u2020': 't',
|
|
37
|
-
'\u00A8': 'u',
|
|
38
|
-
'\u221A': 'v',
|
|
39
|
-
'\u2211': 'w',
|
|
40
|
-
'\u2248': 'x',
|
|
41
|
-
'\u00A5': 'y',
|
|
42
|
-
'\u03A9': 'z',
|
|
18
|
+
// On Mac, hitting alt+char will yield funny characters.
|
|
19
|
+
// Remap these three since we listen for them.
|
|
20
|
+
const MAC_ALT_KEY_CHARACTER_MAP = {
|
|
21
|
+
'\u222B': 'b', // "∫" back one word
|
|
22
|
+
'\u0192': 'f', // "ƒ" forward one word
|
|
23
|
+
'\u00B5': 'm', // "µ" toggle markup view
|
|
43
24
|
};
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
25
|
+
/**
|
|
26
|
+
* Maps symbols from parameterized functional keys `\x1b[1;1<letter>`
|
|
27
|
+
* to their corresponding key names (e.g., 'up', 'f1').
|
|
28
|
+
*/
|
|
29
|
+
const LEGACY_FUNC_TO_NAME = {
|
|
30
|
+
A: 'up',
|
|
31
|
+
B: 'down',
|
|
32
|
+
C: 'right',
|
|
33
|
+
D: 'left',
|
|
34
|
+
H: 'home',
|
|
35
|
+
F: 'end',
|
|
36
|
+
P: 'f1',
|
|
37
|
+
Q: 'f2',
|
|
38
|
+
R: 'f3',
|
|
39
|
+
S: 'f4',
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Maps key codes from tilde-coded functional keys `\x1b[<code>~`
|
|
43
|
+
* to their corresponding key names.
|
|
44
|
+
*/
|
|
45
|
+
const TILDE_KEYCODE_TO_NAME = {
|
|
46
|
+
1: 'home',
|
|
47
|
+
2: 'insert',
|
|
48
|
+
3: 'delete',
|
|
49
|
+
4: 'end',
|
|
50
|
+
5: 'pageup',
|
|
51
|
+
6: 'pagedown',
|
|
52
|
+
11: 'f1',
|
|
53
|
+
12: 'f2',
|
|
54
|
+
13: 'f3',
|
|
55
|
+
14: 'f4',
|
|
56
|
+
15: 'f5',
|
|
57
|
+
17: 'f6', // skipping 16 is intentional
|
|
58
|
+
18: 'f7',
|
|
59
|
+
19: 'f8',
|
|
60
|
+
20: 'f9',
|
|
61
|
+
21: 'f10',
|
|
62
|
+
23: 'f11', // skipping 22 is intentional
|
|
63
|
+
24: 'f12',
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Check if a buffer could potentially be a valid kitty sequence or its prefix.
|
|
67
|
+
*/
|
|
68
|
+
function couldBeKittySequence(buffer) {
|
|
69
|
+
// Kitty sequences always start with ESC[.
|
|
70
|
+
if (buffer.length === 0)
|
|
71
|
+
return true;
|
|
72
|
+
if (buffer === ESC || buffer === `${ESC}[`)
|
|
73
|
+
return true;
|
|
74
|
+
if (!buffer.startsWith(`${ESC}[`))
|
|
75
|
+
return false;
|
|
76
|
+
if (couldBeMouseSequence(buffer))
|
|
77
|
+
return true;
|
|
78
|
+
// Check for known kitty sequence patterns:
|
|
79
|
+
// 1. ESC[<digit> - could be CSI-u or tilde-coded
|
|
80
|
+
// 2. ESC[1;<digit> - parameterized functional
|
|
81
|
+
// 3. ESC[<letter> - legacy functional keys
|
|
82
|
+
// 4. ESC[Z - reverse tab
|
|
83
|
+
const afterCSI = buffer.slice(2);
|
|
84
|
+
// Check if it starts with a digit (could be CSI-u or parameterized)
|
|
85
|
+
if (/^\d/.test(afterCSI))
|
|
86
|
+
return true;
|
|
87
|
+
// Check for known single-letter sequences
|
|
88
|
+
if (/^[ABCDHFPQRSZ]/.test(afterCSI))
|
|
89
|
+
return true;
|
|
90
|
+
// Check for 1; pattern (parameterized sequences)
|
|
91
|
+
if (/^1;\d/.test(afterCSI))
|
|
92
|
+
return true;
|
|
93
|
+
// Anything else starting with ESC[ that doesn't match our patterns
|
|
94
|
+
// is likely not a kitty sequence we handle
|
|
95
|
+
return false;
|
|
51
96
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Parses a single complete kitty/parameterized/legacy sequence from the start
|
|
99
|
+
* of the buffer.
|
|
100
|
+
*
|
|
101
|
+
* This enables peel-and-continue parsing for batched input, allowing us to
|
|
102
|
+
* "peel off" one complete event when multiple sequences arrive in a single
|
|
103
|
+
* chunk, preventing buffer overflow and fragmentation.
|
|
104
|
+
*
|
|
105
|
+
* @param buffer - The input buffer string to parse.
|
|
106
|
+
* @returns The parsed Key and the number of characters consumed, or null if
|
|
107
|
+
* no complete sequence is found at the start of the buffer.
|
|
108
|
+
*/
|
|
109
|
+
function parseKittyPrefix(buffer) {
|
|
110
|
+
// In older terminals ESC [ Z was used as Cursor Backward Tabulation (CBT)
|
|
111
|
+
// In newer terminals the same functionality of key combination for moving
|
|
112
|
+
// backward through focusable elements is Shift+Tab, hence we will
|
|
113
|
+
// map ESC [ Z to Shift+Tab
|
|
114
|
+
// 0) Reverse Tab (legacy): ESC [ Z
|
|
115
|
+
// Treat as Shift+Tab for UI purposes.
|
|
116
|
+
// Regex parts:
|
|
117
|
+
// ^ - start of buffer
|
|
118
|
+
// ESC [ - CSI introducer
|
|
119
|
+
// Z - legacy reverse tab
|
|
120
|
+
const revTabLegacy = new RegExp(`^${ESC}\\[Z`);
|
|
121
|
+
let m = buffer.match(revTabLegacy);
|
|
122
|
+
if (m) {
|
|
123
|
+
return {
|
|
124
|
+
key: {
|
|
125
|
+
name: 'tab',
|
|
126
|
+
ctrl: false,
|
|
127
|
+
meta: false,
|
|
128
|
+
shift: true,
|
|
129
|
+
paste: false,
|
|
130
|
+
sequence: buffer.slice(0, m[0].length),
|
|
131
|
+
kittyProtocol: false,
|
|
132
|
+
},
|
|
133
|
+
length: m[0].length,
|
|
70
134
|
};
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
135
|
+
}
|
|
136
|
+
// 1) Reverse Tab (parameterized): ESC [ 1 ; <mods> Z
|
|
137
|
+
// Parameterized reverse Tab: ESC [ 1 ; <mods> Z
|
|
138
|
+
const revTabParam = new RegExp(`^${ESC}\\[1;(\\d+)Z`);
|
|
139
|
+
m = buffer.match(revTabParam);
|
|
140
|
+
if (m) {
|
|
141
|
+
let mods = parseInt(m[1], 10);
|
|
142
|
+
if (mods >= KITTY_MODIFIER_EVENT_TYPES_OFFSET) {
|
|
143
|
+
mods -= KITTY_MODIFIER_EVENT_TYPES_OFFSET;
|
|
74
144
|
}
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
145
|
+
const bits = mods - KITTY_MODIFIER_BASE;
|
|
146
|
+
const alt = (bits & MODIFIER_ALT_BIT) === MODIFIER_ALT_BIT;
|
|
147
|
+
const ctrl = (bits & MODIFIER_CTRL_BIT) === MODIFIER_CTRL_BIT;
|
|
148
|
+
return {
|
|
149
|
+
key: {
|
|
150
|
+
name: 'tab',
|
|
151
|
+
ctrl,
|
|
152
|
+
meta: alt,
|
|
153
|
+
// Reverse tab implies Shift behavior; force shift regardless of mods
|
|
154
|
+
shift: true,
|
|
155
|
+
paste: false,
|
|
156
|
+
sequence: buffer.slice(0, m[0].length),
|
|
157
|
+
kittyProtocol: true,
|
|
158
|
+
},
|
|
159
|
+
length: m[0].length,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
// 2) Parameterized functional: ESC [ 1 ; <mods> (A|B|C|D|H|F|P|Q|R|S)
|
|
163
|
+
// 2) Parameterized functional: ESC [ 1 ; <mods> (A|B|C|D|H|F|P|Q|R|S)
|
|
164
|
+
// Arrows, Home/End, F1–F4 with modifiers encoded in <mods>.
|
|
165
|
+
const arrowPrefix = new RegExp(`^${ESC}\\[1;(\\d+)([ABCDHFPQSR])`);
|
|
166
|
+
m = buffer.match(arrowPrefix);
|
|
167
|
+
if (m) {
|
|
168
|
+
let mods = parseInt(m[1], 10);
|
|
169
|
+
if (mods >= KITTY_MODIFIER_EVENT_TYPES_OFFSET) {
|
|
170
|
+
mods -= KITTY_MODIFIER_EVENT_TYPES_OFFSET;
|
|
82
171
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
// 4. ESC[Z - reverse tab
|
|
103
|
-
const afterCSI = buffer.slice(2);
|
|
104
|
-
// Check if it starts with a digit (could be CSI-u or parameterized)
|
|
105
|
-
if (/^\d/.test(afterCSI))
|
|
106
|
-
return true;
|
|
107
|
-
// Check for known single-letter sequences
|
|
108
|
-
if (/^[ABCDHFPQRSZ]/.test(afterCSI))
|
|
109
|
-
return true;
|
|
110
|
-
// Check for 1; pattern (parameterized sequences)
|
|
111
|
-
if (/^1;\d/.test(afterCSI))
|
|
112
|
-
return true;
|
|
113
|
-
// Anything else starting with ESC[ that doesn't match our patterns
|
|
114
|
-
// is likely not a kitty sequence we handle
|
|
115
|
-
return false;
|
|
172
|
+
const bits = mods - KITTY_MODIFIER_BASE;
|
|
173
|
+
const shift = (bits & MODIFIER_SHIFT_BIT) === MODIFIER_SHIFT_BIT;
|
|
174
|
+
const alt = (bits & MODIFIER_ALT_BIT) === MODIFIER_ALT_BIT;
|
|
175
|
+
const ctrl = (bits & MODIFIER_CTRL_BIT) === MODIFIER_CTRL_BIT;
|
|
176
|
+
const sym = m[2];
|
|
177
|
+
const name = LEGACY_FUNC_TO_NAME[sym] || '';
|
|
178
|
+
if (!name)
|
|
179
|
+
return null;
|
|
180
|
+
return {
|
|
181
|
+
key: {
|
|
182
|
+
name,
|
|
183
|
+
ctrl,
|
|
184
|
+
meta: alt,
|
|
185
|
+
shift,
|
|
186
|
+
paste: false,
|
|
187
|
+
sequence: buffer.slice(0, m[0].length),
|
|
188
|
+
kittyProtocol: true,
|
|
189
|
+
},
|
|
190
|
+
length: m[0].length,
|
|
116
191
|
};
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (
|
|
138
|
-
return {
|
|
139
|
-
key: {
|
|
140
|
-
name: 'tab',
|
|
141
|
-
ctrl: false,
|
|
142
|
-
meta: false,
|
|
143
|
-
shift: true,
|
|
144
|
-
paste: false,
|
|
145
|
-
sequence: buffer.slice(0, m[0].length),
|
|
146
|
-
kittyProtocol: true,
|
|
147
|
-
},
|
|
148
|
-
length: m[0].length,
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
// 1) Reverse Tab (parameterized): ESC [ 1 ; <mods> Z
|
|
152
|
-
// Parameterized reverse Tab: ESC [ 1 ; <mods> Z
|
|
153
|
-
const revTabParam = new RegExp(`^${ESC}\\[1;(\\d+)Z`);
|
|
154
|
-
m = buffer.match(revTabParam);
|
|
155
|
-
if (m) {
|
|
156
|
-
let mods = parseInt(m[1], 10);
|
|
157
|
-
if (mods >= KITTY_MODIFIER_EVENT_TYPES_OFFSET) {
|
|
158
|
-
mods -= KITTY_MODIFIER_EVENT_TYPES_OFFSET;
|
|
159
|
-
}
|
|
160
|
-
const bits = mods - KITTY_MODIFIER_BASE;
|
|
161
|
-
const alt = (bits & MODIFIER_ALT_BIT) === MODIFIER_ALT_BIT;
|
|
162
|
-
const ctrl = (bits & MODIFIER_CTRL_BIT) === MODIFIER_CTRL_BIT;
|
|
163
|
-
return {
|
|
164
|
-
key: {
|
|
165
|
-
name: 'tab',
|
|
166
|
-
ctrl,
|
|
167
|
-
meta: alt,
|
|
168
|
-
// Reverse tab implies Shift behavior; force shift regardless of mods
|
|
169
|
-
shift: true,
|
|
170
|
-
paste: false,
|
|
171
|
-
sequence: buffer.slice(0, m[0].length),
|
|
172
|
-
kittyProtocol: true,
|
|
173
|
-
},
|
|
174
|
-
length: m[0].length,
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
// 2) Parameterized functional: ESC [ 1 ; <mods> (A|B|C|D|H|F|P|Q|R|S)
|
|
178
|
-
// 2) Parameterized functional: ESC [ 1 ; <mods> (A|B|C|D|H|F|P|Q|R|S)
|
|
179
|
-
// Arrows, Home/End, F1–F4 with modifiers encoded in <mods>.
|
|
180
|
-
const arrowPrefix = new RegExp(`^${ESC}\\[1;(\\d+)([ABCDHFPQSR])`);
|
|
181
|
-
m = buffer.match(arrowPrefix);
|
|
182
|
-
if (m) {
|
|
183
|
-
let mods = parseInt(m[1], 10);
|
|
184
|
-
if (mods >= KITTY_MODIFIER_EVENT_TYPES_OFFSET) {
|
|
185
|
-
mods -= KITTY_MODIFIER_EVENT_TYPES_OFFSET;
|
|
186
|
-
}
|
|
187
|
-
const bits = mods - KITTY_MODIFIER_BASE;
|
|
188
|
-
const shift = (bits & MODIFIER_SHIFT_BIT) === MODIFIER_SHIFT_BIT;
|
|
189
|
-
const alt = (bits & MODIFIER_ALT_BIT) === MODIFIER_ALT_BIT;
|
|
190
|
-
const ctrl = (bits & MODIFIER_CTRL_BIT) === MODIFIER_CTRL_BIT;
|
|
191
|
-
const sym = m[2];
|
|
192
|
-
const symbolToName = {
|
|
193
|
-
A: 'up',
|
|
194
|
-
B: 'down',
|
|
195
|
-
C: 'right',
|
|
196
|
-
D: 'left',
|
|
197
|
-
H: 'home',
|
|
198
|
-
F: 'end',
|
|
199
|
-
P: 'f1',
|
|
200
|
-
Q: 'f2',
|
|
201
|
-
R: 'f3',
|
|
202
|
-
S: 'f4',
|
|
203
|
-
};
|
|
204
|
-
const name = symbolToName[sym] || '';
|
|
205
|
-
if (!name)
|
|
206
|
-
return null;
|
|
192
|
+
}
|
|
193
|
+
// 3) CSI-u form: ESC [ <code> ; <mods> (u|~)
|
|
194
|
+
// 3) CSI-u and tilde-coded functional keys: ESC [ <code> ; <mods> (u|~)
|
|
195
|
+
// 'u' terminator: Kitty CSI-u; '~' terminator: tilde-coded function keys.
|
|
196
|
+
const csiUPrefix = new RegExp(`^${ESC}\\[(\\d+)(;(\\d+))?([u~])`);
|
|
197
|
+
m = buffer.match(csiUPrefix);
|
|
198
|
+
if (m) {
|
|
199
|
+
const keyCode = parseInt(m[1], 10);
|
|
200
|
+
let modifiers = m[3] ? parseInt(m[3], 10) : KITTY_MODIFIER_BASE;
|
|
201
|
+
if (modifiers >= KITTY_MODIFIER_EVENT_TYPES_OFFSET) {
|
|
202
|
+
modifiers -= KITTY_MODIFIER_EVENT_TYPES_OFFSET;
|
|
203
|
+
}
|
|
204
|
+
const modifierBits = modifiers - KITTY_MODIFIER_BASE;
|
|
205
|
+
const shift = (modifierBits & MODIFIER_SHIFT_BIT) === MODIFIER_SHIFT_BIT;
|
|
206
|
+
const alt = (modifierBits & MODIFIER_ALT_BIT) === MODIFIER_ALT_BIT;
|
|
207
|
+
const ctrl = (modifierBits & MODIFIER_CTRL_BIT) === MODIFIER_CTRL_BIT;
|
|
208
|
+
const terminator = m[4];
|
|
209
|
+
// Tilde-coded functional keys (Delete, Insert, PageUp/Down, Home/End)
|
|
210
|
+
if (terminator === '~') {
|
|
211
|
+
const name = TILDE_KEYCODE_TO_NAME[keyCode];
|
|
212
|
+
if (name) {
|
|
207
213
|
return {
|
|
208
214
|
key: {
|
|
209
215
|
name,
|
|
@@ -212,147 +218,210 @@ export function KeypressProvider({ children, kittyProtocolEnabled, config, debug
|
|
|
212
218
|
shift,
|
|
213
219
|
paste: false,
|
|
214
220
|
sequence: buffer.slice(0, m[0].length),
|
|
215
|
-
kittyProtocol:
|
|
221
|
+
kittyProtocol: false,
|
|
216
222
|
},
|
|
217
223
|
length: m[0].length,
|
|
218
224
|
};
|
|
219
225
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
226
|
+
}
|
|
227
|
+
const kittyKeyCodeToName = {
|
|
228
|
+
[CHAR_CODE_ESC]: 'escape',
|
|
229
|
+
[KITTY_KEYCODE_TAB]: 'tab',
|
|
230
|
+
[KITTY_KEYCODE_BACKSPACE]: 'backspace',
|
|
231
|
+
[KITTY_KEYCODE_ENTER]: 'return',
|
|
232
|
+
[KITTY_KEYCODE_NUMPAD_ENTER]: 'return',
|
|
233
|
+
};
|
|
234
|
+
const name = kittyKeyCodeToName[keyCode];
|
|
235
|
+
if (name) {
|
|
236
|
+
return {
|
|
237
|
+
key: {
|
|
238
|
+
name,
|
|
239
|
+
ctrl,
|
|
240
|
+
meta: alt,
|
|
241
|
+
shift,
|
|
242
|
+
paste: false,
|
|
243
|
+
sequence: buffer.slice(0, m[0].length),
|
|
244
|
+
kittyProtocol: true,
|
|
245
|
+
},
|
|
246
|
+
length: m[0].length,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
// Ctrl+letters and Alt+letters
|
|
250
|
+
if ((ctrl || alt) &&
|
|
251
|
+
keyCode >= 'a'.charCodeAt(0) &&
|
|
252
|
+
keyCode <= 'z'.charCodeAt(0)) {
|
|
253
|
+
const letter = String.fromCharCode(keyCode);
|
|
254
|
+
return {
|
|
255
|
+
key: {
|
|
256
|
+
name: letter,
|
|
257
|
+
ctrl,
|
|
258
|
+
meta: alt,
|
|
259
|
+
shift,
|
|
260
|
+
paste: false,
|
|
261
|
+
sequence: buffer.slice(0, m[0].length),
|
|
262
|
+
kittyProtocol: true,
|
|
263
|
+
},
|
|
264
|
+
length: m[0].length,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
// 4) Legacy function keys (no parameters): ESC [ (A|B|C|D|H|F)
|
|
269
|
+
// Arrows + Home/End without modifiers.
|
|
270
|
+
const legacyFuncKey = new RegExp(`^${ESC}\\[([ABCDHF])`);
|
|
271
|
+
m = buffer.match(legacyFuncKey);
|
|
272
|
+
if (m) {
|
|
273
|
+
const sym = m[1];
|
|
274
|
+
const name = LEGACY_FUNC_TO_NAME[sym];
|
|
275
|
+
return {
|
|
276
|
+
key: {
|
|
277
|
+
name,
|
|
278
|
+
ctrl: false,
|
|
279
|
+
meta: false,
|
|
280
|
+
shift: false,
|
|
281
|
+
paste: false,
|
|
282
|
+
sequence: buffer.slice(0, m[0].length),
|
|
283
|
+
kittyProtocol: false,
|
|
284
|
+
},
|
|
285
|
+
length: m[0].length,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Returns the first index before which we are certain there is no paste marker.
|
|
292
|
+
*/
|
|
293
|
+
function earliestPossiblePasteMarker(data) {
|
|
294
|
+
// Check data for full start-paste or end-paste markers.
|
|
295
|
+
const startIndex = data.indexOf(PASTE_MODE_START);
|
|
296
|
+
const endIndex = data.indexOf(PASTE_MODE_END);
|
|
297
|
+
if (startIndex !== -1 && endIndex !== -1) {
|
|
298
|
+
return Math.min(startIndex, endIndex);
|
|
299
|
+
}
|
|
300
|
+
else if (startIndex !== -1) {
|
|
301
|
+
return startIndex;
|
|
302
|
+
}
|
|
303
|
+
else if (endIndex !== -1) {
|
|
304
|
+
return endIndex;
|
|
305
|
+
}
|
|
306
|
+
// data contains no full start-paste or end-paste.
|
|
307
|
+
// Check if data ends with a prefix of start-paste or end-paste.
|
|
308
|
+
const codeLength = PASTE_MODE_START.length;
|
|
309
|
+
for (let i = Math.min(data.length, codeLength - 1); i > 0; i--) {
|
|
310
|
+
const candidate = data.slice(data.length - i);
|
|
311
|
+
if (PASTE_MODE_START.indexOf(candidate) === 0 ||
|
|
312
|
+
PASTE_MODE_END.indexOf(candidate) === 0) {
|
|
313
|
+
return data.length - i;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return data.length;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* A generator that takes in data chunks and spits out paste-start and
|
|
320
|
+
* paste-end keypresses. All non-paste marker data is passed to passthrough.
|
|
321
|
+
*/
|
|
322
|
+
function* pasteMarkerParser(passthrough, keypressHandler) {
|
|
323
|
+
while (true) {
|
|
324
|
+
let data = yield;
|
|
325
|
+
if (data.length === 0) {
|
|
326
|
+
continue; // we timed out
|
|
327
|
+
}
|
|
328
|
+
while (true) {
|
|
329
|
+
const index = earliestPossiblePasteMarker(data);
|
|
330
|
+
if (index === data.length) {
|
|
331
|
+
// no possible paste markers were found
|
|
332
|
+
passthrough.write(data);
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
if (index > 0) {
|
|
336
|
+
// snip off and send the part that doesn't have a paste marker
|
|
337
|
+
passthrough.write(data.slice(0, index));
|
|
338
|
+
data = data.slice(index);
|
|
339
|
+
}
|
|
340
|
+
// data starts with a possible paste marker
|
|
341
|
+
const codeLength = PASTE_MODE_START.length;
|
|
342
|
+
if (data.length < codeLength) {
|
|
343
|
+
// we have a prefix. Concat the next data and try again.
|
|
344
|
+
const newData = yield;
|
|
345
|
+
if (newData.length === 0) {
|
|
346
|
+
// we timed out. Just dump what we have and start over.
|
|
347
|
+
passthrough.write(data);
|
|
348
|
+
break;
|
|
315
349
|
}
|
|
350
|
+
data += newData;
|
|
316
351
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
D: 'left',
|
|
328
|
-
H: 'home',
|
|
329
|
-
F: 'end',
|
|
330
|
-
};
|
|
331
|
-
const name = nameMap[sym];
|
|
332
|
-
return {
|
|
333
|
-
key: {
|
|
334
|
-
name,
|
|
335
|
-
ctrl: false,
|
|
336
|
-
meta: false,
|
|
337
|
-
shift: false,
|
|
338
|
-
paste: false,
|
|
339
|
-
sequence: buffer.slice(0, m[0].length),
|
|
340
|
-
kittyProtocol: true,
|
|
341
|
-
},
|
|
342
|
-
length: m[0].length,
|
|
343
|
-
};
|
|
352
|
+
else if (data.startsWith(PASTE_MODE_START)) {
|
|
353
|
+
keypressHandler(undefined, {
|
|
354
|
+
name: 'paste-start',
|
|
355
|
+
ctrl: false,
|
|
356
|
+
meta: false,
|
|
357
|
+
shift: false,
|
|
358
|
+
paste: false,
|
|
359
|
+
sequence: '',
|
|
360
|
+
});
|
|
361
|
+
data = data.slice(PASTE_MODE_START.length);
|
|
344
362
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
363
|
+
else if (data.startsWith(PASTE_MODE_END)) {
|
|
364
|
+
keypressHandler(undefined, {
|
|
365
|
+
name: 'paste-end',
|
|
366
|
+
ctrl: false,
|
|
367
|
+
meta: false,
|
|
368
|
+
shift: false,
|
|
369
|
+
paste: false,
|
|
370
|
+
sequence: '',
|
|
371
|
+
});
|
|
372
|
+
data = data.slice(PASTE_MODE_END.length);
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
// This should never happen.
|
|
376
|
+
passthrough.write(data);
|
|
377
|
+
break;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
const KeypressContext = createContext(undefined);
|
|
383
|
+
export function useKeypressContext() {
|
|
384
|
+
const context = useContext(KeypressContext);
|
|
385
|
+
if (!context) {
|
|
386
|
+
throw new Error('useKeypressContext must be used within a KeypressProvider');
|
|
387
|
+
}
|
|
388
|
+
return context;
|
|
389
|
+
}
|
|
390
|
+
function shouldUsePassthrough() {
|
|
391
|
+
return process.env['PASTE_WORKAROUND'] !== 'false';
|
|
392
|
+
}
|
|
393
|
+
export function KeypressProvider({ children, kittyProtocolEnabled, config, debugKeystrokeLogging, }) {
|
|
394
|
+
const { stdin, setRawMode } = useStdin();
|
|
395
|
+
const subscribers = useRef(new Set()).current;
|
|
396
|
+
const subscribe = useCallback((handler) => subscribers.add(handler), [subscribers]);
|
|
397
|
+
const unsubscribe = useCallback((handler) => subscribers.delete(handler), [subscribers]);
|
|
398
|
+
const broadcast = useCallback((key) => subscribers.forEach((handler) => handler(key)), [subscribers]);
|
|
399
|
+
useEffect(() => {
|
|
400
|
+
const wasRaw = stdin.isRaw;
|
|
401
|
+
if (wasRaw === false) {
|
|
402
|
+
setRawMode(true);
|
|
403
|
+
}
|
|
404
|
+
const keypressStream = shouldUsePassthrough() ? new PassThrough() : null;
|
|
405
|
+
// If non-null that means we are in paste mode
|
|
406
|
+
let pasteBuffer = null;
|
|
407
|
+
// Used to turn "\" quickly followed by a "enter" into a shift enter
|
|
408
|
+
let backslashTimeout = null;
|
|
409
|
+
// Buffers incomplete sequences (Kitty or Mouse) and timer to flush it
|
|
410
|
+
let inputBuffer = '';
|
|
411
|
+
let inputTimeout = null;
|
|
412
|
+
// Used to detect filename drag-and-drops.
|
|
413
|
+
let dragBuffer = '';
|
|
414
|
+
let draggingTimer = null;
|
|
415
|
+
const clearDraggingTimer = () => {
|
|
416
|
+
if (draggingTimer) {
|
|
417
|
+
clearTimeout(draggingTimer);
|
|
418
|
+
draggingTimer = null;
|
|
350
419
|
}
|
|
351
420
|
};
|
|
352
|
-
const
|
|
353
|
-
if (
|
|
421
|
+
const flushInputBufferOnInterrupt = (reason) => {
|
|
422
|
+
if (inputBuffer) {
|
|
354
423
|
if (debugKeystrokeLogging) {
|
|
355
|
-
debugLogger.log(`[DEBUG]
|
|
424
|
+
debugLogger.log(`[DEBUG] Input sequence flushed due to ${reason}:`, JSON.stringify(inputBuffer));
|
|
356
425
|
}
|
|
357
426
|
broadcast({
|
|
358
427
|
name: '',
|
|
@@ -360,76 +429,73 @@ export function KeypressProvider({ children, kittyProtocolEnabled, config, debug
|
|
|
360
429
|
meta: false,
|
|
361
430
|
shift: false,
|
|
362
431
|
paste: false,
|
|
363
|
-
sequence:
|
|
432
|
+
sequence: inputBuffer,
|
|
364
433
|
});
|
|
365
|
-
|
|
434
|
+
inputBuffer = '';
|
|
366
435
|
}
|
|
367
|
-
if (
|
|
368
|
-
clearTimeout(
|
|
369
|
-
|
|
436
|
+
if (inputTimeout) {
|
|
437
|
+
clearTimeout(inputTimeout);
|
|
438
|
+
inputTimeout = null;
|
|
370
439
|
}
|
|
371
440
|
};
|
|
372
441
|
const handleKeypress = (_, key) => {
|
|
373
442
|
if (key.sequence === FOCUS_IN || key.sequence === FOCUS_OUT) {
|
|
374
|
-
|
|
443
|
+
flushInputBufferOnInterrupt('focus event');
|
|
375
444
|
return;
|
|
376
445
|
}
|
|
377
446
|
if (key.name === 'paste-start') {
|
|
378
|
-
|
|
379
|
-
|
|
447
|
+
flushInputBufferOnInterrupt('paste start');
|
|
448
|
+
pasteBuffer = Buffer.alloc(0);
|
|
380
449
|
return;
|
|
381
450
|
}
|
|
382
451
|
if (key.name === 'paste-end') {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
452
|
+
if (pasteBuffer !== null) {
|
|
453
|
+
broadcast({
|
|
454
|
+
name: '',
|
|
455
|
+
ctrl: false,
|
|
456
|
+
meta: false,
|
|
457
|
+
shift: false,
|
|
458
|
+
paste: true,
|
|
459
|
+
sequence: pasteBuffer.toString(),
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
pasteBuffer = null;
|
|
393
463
|
return;
|
|
394
464
|
}
|
|
395
|
-
if (
|
|
465
|
+
if (pasteBuffer !== null) {
|
|
396
466
|
pasteBuffer = Buffer.concat([pasteBuffer, Buffer.from(key.sequence)]);
|
|
397
467
|
return;
|
|
398
468
|
}
|
|
399
469
|
if (key.sequence === SINGLE_QUOTE ||
|
|
400
470
|
key.sequence === DOUBLE_QUOTE ||
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
dragBufferRef.current += key.sequence;
|
|
471
|
+
draggingTimer !== null) {
|
|
472
|
+
dragBuffer += key.sequence;
|
|
404
473
|
clearDraggingTimer();
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
const seq =
|
|
408
|
-
|
|
474
|
+
draggingTimer = setTimeout(() => {
|
|
475
|
+
draggingTimer = null;
|
|
476
|
+
const seq = dragBuffer;
|
|
477
|
+
dragBuffer = '';
|
|
409
478
|
if (seq) {
|
|
410
479
|
broadcast({ ...key, name: '', paste: true, sequence: seq });
|
|
411
480
|
}
|
|
412
481
|
}, DRAG_COMPLETION_TIMEOUT_MS);
|
|
413
482
|
return;
|
|
414
483
|
}
|
|
415
|
-
const mappedLetter =
|
|
416
|
-
if (mappedLetter && !key.meta) {
|
|
484
|
+
const mappedLetter = MAC_ALT_KEY_CHARACTER_MAP[key.sequence];
|
|
485
|
+
if (process.platform === 'darwin' && mappedLetter && !key.meta) {
|
|
417
486
|
broadcast({
|
|
418
487
|
name: mappedLetter,
|
|
419
488
|
ctrl: false,
|
|
420
489
|
meta: true,
|
|
421
490
|
shift: false,
|
|
422
|
-
paste:
|
|
491
|
+
paste: pasteBuffer !== null,
|
|
423
492
|
sequence: key.sequence,
|
|
424
493
|
});
|
|
425
494
|
return;
|
|
426
495
|
}
|
|
427
|
-
if (key.name === 'return' &&
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
backslashTimeout = null;
|
|
431
|
-
}
|
|
432
|
-
waitingForEnterAfterBackslash = false;
|
|
496
|
+
if (key.name === 'return' && backslashTimeout !== null) {
|
|
497
|
+
clearTimeout(backslashTimeout);
|
|
498
|
+
backslashTimeout = null;
|
|
433
499
|
broadcast({
|
|
434
500
|
...key,
|
|
435
501
|
shift: true,
|
|
@@ -439,20 +505,15 @@ export function KeypressProvider({ children, kittyProtocolEnabled, config, debug
|
|
|
439
505
|
}
|
|
440
506
|
if (key.sequence === '\\' && !key.name) {
|
|
441
507
|
// Corrected escaping for backslash
|
|
442
|
-
waitingForEnterAfterBackslash = true;
|
|
443
508
|
backslashTimeout = setTimeout(() => {
|
|
444
|
-
waitingForEnterAfterBackslash = false;
|
|
445
509
|
backslashTimeout = null;
|
|
446
510
|
broadcast(key);
|
|
447
511
|
}, BACKSLASH_ENTER_DETECTION_WINDOW_MS);
|
|
448
512
|
return;
|
|
449
513
|
}
|
|
450
|
-
if (
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
backslashTimeout = null;
|
|
454
|
-
}
|
|
455
|
-
waitingForEnterAfterBackslash = false;
|
|
514
|
+
if (backslashTimeout !== null && key.name !== 'return') {
|
|
515
|
+
clearTimeout(backslashTimeout);
|
|
516
|
+
backslashTimeout = null;
|
|
456
517
|
broadcast({
|
|
457
518
|
name: '',
|
|
458
519
|
sequence: '\\',
|
|
@@ -468,13 +529,13 @@ export function KeypressProvider({ children, kittyProtocolEnabled, config, debug
|
|
|
468
529
|
}
|
|
469
530
|
if ((key.ctrl && key.name === 'c') ||
|
|
470
531
|
key.sequence === `${ESC}${KITTY_CTRL_C}`) {
|
|
471
|
-
if (
|
|
472
|
-
debugLogger.log('[DEBUG]
|
|
532
|
+
if (inputBuffer && debugKeystrokeLogging) {
|
|
533
|
+
debugLogger.log('[DEBUG] Input buffer cleared on Ctrl+C:', inputBuffer);
|
|
473
534
|
}
|
|
474
|
-
|
|
475
|
-
if (
|
|
476
|
-
clearTimeout(
|
|
477
|
-
|
|
535
|
+
inputBuffer = '';
|
|
536
|
+
if (inputTimeout) {
|
|
537
|
+
clearTimeout(inputTimeout);
|
|
538
|
+
inputTimeout = null;
|
|
478
539
|
}
|
|
479
540
|
if (key.sequence === `${ESC}${KITTY_CTRL_C}`) {
|
|
480
541
|
broadcast({
|
|
@@ -492,196 +553,209 @@ export function KeypressProvider({ children, kittyProtocolEnabled, config, debug
|
|
|
492
553
|
}
|
|
493
554
|
return;
|
|
494
555
|
}
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
556
|
+
// Clear any pending timeout when new input arrives
|
|
557
|
+
if (inputTimeout) {
|
|
558
|
+
clearTimeout(inputTimeout);
|
|
559
|
+
inputTimeout = null;
|
|
560
|
+
}
|
|
561
|
+
// Always check if this could start a sequence we need to buffer (Kitty or Mouse)
|
|
562
|
+
// Other ESC sequences (like Alt+Key which is ESC+Key) should be let through if readline parsed them.
|
|
563
|
+
const shouldBuffer = couldBeKittySequence(key.sequence);
|
|
564
|
+
const isExcluded = [
|
|
565
|
+
PASTE_MODE_START,
|
|
566
|
+
PASTE_MODE_END,
|
|
567
|
+
FOCUS_IN,
|
|
568
|
+
FOCUS_OUT,
|
|
569
|
+
].some((prefix) => key.sequence.startsWith(prefix));
|
|
570
|
+
if (inputBuffer || (shouldBuffer && !isExcluded)) {
|
|
571
|
+
inputBuffer += key.sequence;
|
|
572
|
+
if (debugKeystrokeLogging && !couldBeMouseSequence(inputBuffer)) {
|
|
573
|
+
debugLogger.log('[DEBUG] Input buffer accumulating:', JSON.stringify(inputBuffer));
|
|
500
574
|
}
|
|
501
|
-
//
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
kittySequenceBuffer += key.sequence;
|
|
511
|
-
if (debugKeystrokeLogging) {
|
|
512
|
-
debugLogger.log('[DEBUG] Kitty buffer accumulating:', JSON.stringify(kittySequenceBuffer));
|
|
513
|
-
}
|
|
514
|
-
// Try immediate parsing
|
|
515
|
-
let remainingBuffer = kittySequenceBuffer;
|
|
516
|
-
let parsedAny = false;
|
|
517
|
-
while (remainingBuffer) {
|
|
518
|
-
const parsed = parseKittyPrefix(remainingBuffer);
|
|
519
|
-
if (parsed) {
|
|
575
|
+
// Try immediate parsing
|
|
576
|
+
let remainingBuffer = inputBuffer;
|
|
577
|
+
let parsedAny = false;
|
|
578
|
+
while (remainingBuffer) {
|
|
579
|
+
const parsed = parseKittyPrefix(remainingBuffer);
|
|
580
|
+
if (parsed) {
|
|
581
|
+
// If kitty protocol is disabled, only allow legacy/standard sequences.
|
|
582
|
+
// parseKittyPrefix returns true for kittyProtocol if it's a modern kitty sequence.
|
|
583
|
+
if (kittyProtocolEnabled || !parsed.key.kittyProtocol) {
|
|
520
584
|
if (debugKeystrokeLogging) {
|
|
521
585
|
const parsedSequence = remainingBuffer.slice(0, parsed.length);
|
|
522
|
-
debugLogger.log('[DEBUG]
|
|
586
|
+
debugLogger.log('[DEBUG] Sequence parsed successfully:', JSON.stringify(parsedSequence));
|
|
523
587
|
}
|
|
524
588
|
broadcast(parsed.key);
|
|
525
589
|
remainingBuffer = remainingBuffer.slice(parsed.length);
|
|
526
590
|
parsedAny = true;
|
|
591
|
+
continue;
|
|
527
592
|
}
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
debugLogger.log('[DEBUG] Not a kitty sequence, flushing:', JSON.stringify(remainingBuffer));
|
|
550
|
-
}
|
|
551
|
-
broadcast({
|
|
552
|
-
name: '',
|
|
553
|
-
ctrl: false,
|
|
554
|
-
meta: false,
|
|
555
|
-
shift: false,
|
|
556
|
-
paste: false,
|
|
557
|
-
sequence: remainingBuffer,
|
|
558
|
-
});
|
|
559
|
-
remainingBuffer = '';
|
|
560
|
-
parsedAny = true;
|
|
593
|
+
}
|
|
594
|
+
const mouseParsed = parseMouseEvent(remainingBuffer);
|
|
595
|
+
if (mouseParsed) {
|
|
596
|
+
// These are handled by the separate mouse sequence parser.
|
|
597
|
+
// All we need to do is make sure we don't get confused by these
|
|
598
|
+
// sequences.
|
|
599
|
+
remainingBuffer = remainingBuffer.slice(mouseParsed.length);
|
|
600
|
+
parsedAny = true;
|
|
601
|
+
continue;
|
|
602
|
+
}
|
|
603
|
+
// If we can't parse a sequence at the start, check if there's
|
|
604
|
+
// another ESC later in the buffer. If so, the data before it
|
|
605
|
+
// is garbage/incomplete and should be dropped so we can
|
|
606
|
+
// process the next sequence.
|
|
607
|
+
const nextEscIndex = remainingBuffer.indexOf(ESC, 1);
|
|
608
|
+
if (nextEscIndex !== -1) {
|
|
609
|
+
const garbage = remainingBuffer.slice(0, nextEscIndex);
|
|
610
|
+
// Special case: if garbage is exactly ESC, it's likely a rapid ESC press.
|
|
611
|
+
if (garbage === ESC) {
|
|
612
|
+
if (debugKeystrokeLogging) {
|
|
613
|
+
debugLogger.log('[DEBUG] Flushing rapid ESC before next ESC:', JSON.stringify(garbage));
|
|
561
614
|
}
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
ctrl: false,
|
|
575
|
-
meta: false,
|
|
576
|
-
shift: false,
|
|
577
|
-
paste: false,
|
|
578
|
-
sequence: remainingBuffer,
|
|
579
|
-
});
|
|
580
|
-
remainingBuffer = '';
|
|
581
|
-
parsedAny = true;
|
|
615
|
+
broadcast({
|
|
616
|
+
name: 'escape',
|
|
617
|
+
ctrl: false,
|
|
618
|
+
meta: true,
|
|
619
|
+
shift: false,
|
|
620
|
+
paste: false,
|
|
621
|
+
sequence: garbage,
|
|
622
|
+
});
|
|
623
|
+
}
|
|
624
|
+
else {
|
|
625
|
+
if (debugKeystrokeLogging) {
|
|
626
|
+
debugLogger.log('[DEBUG] Dropping incomplete sequence before next ESC:', JSON.stringify(garbage));
|
|
582
627
|
}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
628
|
+
}
|
|
629
|
+
// Continue parsing from next ESC
|
|
630
|
+
remainingBuffer = remainingBuffer.slice(nextEscIndex);
|
|
631
|
+
// We made progress, so we can continue the loop to parse the next sequence
|
|
632
|
+
continue;
|
|
633
|
+
}
|
|
634
|
+
// Check if buffer could become a valid sequence
|
|
635
|
+
const couldBeValidKitty = kittyProtocolEnabled && couldBeKittySequence(remainingBuffer);
|
|
636
|
+
const isMouse = isIncompleteMouseSequence(remainingBuffer);
|
|
637
|
+
const couldBeValid = couldBeValidKitty || isMouse;
|
|
638
|
+
if (!couldBeValid) {
|
|
639
|
+
// Not a valid sequence - flush as regular input immediately
|
|
640
|
+
if (debugKeystrokeLogging) {
|
|
641
|
+
debugLogger.log('[DEBUG] Not a valid sequence, flushing:', JSON.stringify(remainingBuffer));
|
|
642
|
+
}
|
|
643
|
+
broadcast({
|
|
644
|
+
name: '',
|
|
645
|
+
ctrl: false,
|
|
646
|
+
meta: false,
|
|
647
|
+
shift: false,
|
|
648
|
+
paste: false,
|
|
649
|
+
sequence: remainingBuffer,
|
|
650
|
+
});
|
|
651
|
+
remainingBuffer = '';
|
|
652
|
+
parsedAny = true;
|
|
653
|
+
}
|
|
654
|
+
else if (remainingBuffer.length > MAX_KITTY_SEQUENCE_LENGTH) {
|
|
655
|
+
// Buffer overflow - log and clear
|
|
656
|
+
if (debugKeystrokeLogging) {
|
|
657
|
+
debugLogger.log('[DEBUG] Input buffer overflow, clearing:', JSON.stringify(remainingBuffer));
|
|
658
|
+
}
|
|
659
|
+
if (config && kittyProtocolEnabled) {
|
|
660
|
+
const event = new KittySequenceOverflowEvent(remainingBuffer.length, remainingBuffer);
|
|
661
|
+
logKittySequenceOverflow(config, event);
|
|
662
|
+
}
|
|
663
|
+
// Flush as regular input
|
|
664
|
+
broadcast({
|
|
665
|
+
name: '',
|
|
666
|
+
ctrl: false,
|
|
667
|
+
meta: false,
|
|
668
|
+
shift: false,
|
|
669
|
+
paste: false,
|
|
670
|
+
sequence: remainingBuffer,
|
|
671
|
+
});
|
|
672
|
+
remainingBuffer = '';
|
|
673
|
+
parsedAny = true;
|
|
674
|
+
}
|
|
675
|
+
else {
|
|
676
|
+
if ((config?.getDebugMode() || debugKeystrokeLogging) &&
|
|
677
|
+
!couldBeMouseSequence(inputBuffer)) {
|
|
678
|
+
debugLogger.warn('Input sequence buffer has content:', JSON.stringify(inputBuffer));
|
|
679
|
+
}
|
|
680
|
+
// Could be valid but incomplete - set timeout
|
|
681
|
+
// Only set timeout if it's NOT a mouse sequence.
|
|
682
|
+
// Mouse sequences might be slow (e.g. over network) and we don't want to
|
|
683
|
+
// flush them as garbage keypresses.
|
|
684
|
+
// However, if it's just ESC or ESC[, it might be a user typing slowly,
|
|
685
|
+
// so we should still timeout in that case.
|
|
686
|
+
const isAmbiguousPrefix = remainingBuffer === ESC || remainingBuffer === `${ESC}[`;
|
|
687
|
+
if (!isMouse || isAmbiguousPrefix) {
|
|
688
|
+
inputTimeout = setTimeout(() => {
|
|
689
|
+
if (inputBuffer) {
|
|
690
|
+
if (debugKeystrokeLogging) {
|
|
691
|
+
debugLogger.log('[DEBUG] Input sequence timeout, flushing:', JSON.stringify(inputBuffer));
|
|
602
692
|
}
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
693
|
+
const isEscape = inputBuffer === ESC;
|
|
694
|
+
broadcast({
|
|
695
|
+
name: isEscape ? 'escape' : '',
|
|
696
|
+
ctrl: false,
|
|
697
|
+
meta: isEscape,
|
|
698
|
+
shift: false,
|
|
699
|
+
paste: false,
|
|
700
|
+
sequence: inputBuffer,
|
|
701
|
+
});
|
|
702
|
+
inputBuffer = '';
|
|
703
|
+
}
|
|
704
|
+
inputTimeout = null;
|
|
705
|
+
}, KITTY_SEQUENCE_TIMEOUT_MS);
|
|
706
|
+
}
|
|
707
|
+
else {
|
|
708
|
+
// It IS a mouse sequence and it's long enough to be unambiguously NOT just a user hitting ESC slowly.
|
|
709
|
+
// We just wait for more data.
|
|
710
|
+
if (inputTimeout) {
|
|
711
|
+
clearTimeout(inputTimeout);
|
|
712
|
+
inputTimeout = null;
|
|
606
713
|
}
|
|
607
714
|
}
|
|
715
|
+
break;
|
|
608
716
|
}
|
|
609
|
-
kittySequenceBuffer = remainingBuffer;
|
|
610
|
-
if (parsedAny || kittySequenceBuffer)
|
|
611
|
-
return;
|
|
612
717
|
}
|
|
718
|
+
inputBuffer = remainingBuffer;
|
|
719
|
+
if (parsedAny || inputBuffer)
|
|
720
|
+
return;
|
|
613
721
|
}
|
|
614
722
|
if (key.name === 'return' && key.sequence === `${ESC}\r`) {
|
|
615
723
|
key.meta = true;
|
|
616
724
|
}
|
|
617
|
-
broadcast({ ...key, paste:
|
|
618
|
-
};
|
|
619
|
-
const handleRawKeypress = (data) => {
|
|
620
|
-
const pasteModePrefixBuffer = Buffer.from(PASTE_MODE_PREFIX);
|
|
621
|
-
const pasteModeSuffixBuffer = Buffer.from(PASTE_MODE_SUFFIX);
|
|
622
|
-
let pos = 0;
|
|
623
|
-
while (pos < data.length) {
|
|
624
|
-
const prefixPos = data.indexOf(pasteModePrefixBuffer, pos);
|
|
625
|
-
const suffixPos = data.indexOf(pasteModeSuffixBuffer, pos);
|
|
626
|
-
const isPrefixNext = prefixPos !== -1 && (suffixPos === -1 || prefixPos < suffixPos);
|
|
627
|
-
const isSuffixNext = suffixPos !== -1 && (prefixPos === -1 || suffixPos < prefixPos);
|
|
628
|
-
let nextMarkerPos = -1;
|
|
629
|
-
let markerLength = 0;
|
|
630
|
-
if (isPrefixNext) {
|
|
631
|
-
nextMarkerPos = prefixPos;
|
|
632
|
-
}
|
|
633
|
-
else if (isSuffixNext) {
|
|
634
|
-
nextMarkerPos = suffixPos;
|
|
635
|
-
}
|
|
636
|
-
markerLength = pasteModeSuffixBuffer.length;
|
|
637
|
-
if (nextMarkerPos === -1) {
|
|
638
|
-
keypressStream.write(data.slice(pos));
|
|
639
|
-
return;
|
|
640
|
-
}
|
|
641
|
-
const nextData = data.slice(pos, nextMarkerPos);
|
|
642
|
-
if (nextData.length > 0) {
|
|
643
|
-
keypressStream.write(nextData);
|
|
644
|
-
}
|
|
645
|
-
const createPasteKeyEvent = (name) => ({
|
|
646
|
-
name,
|
|
647
|
-
ctrl: false,
|
|
648
|
-
meta: false,
|
|
649
|
-
shift: false,
|
|
650
|
-
paste: false,
|
|
651
|
-
sequence: '',
|
|
652
|
-
});
|
|
653
|
-
if (isPrefixNext) {
|
|
654
|
-
handleKeypress(undefined, createPasteKeyEvent('paste-start'));
|
|
655
|
-
}
|
|
656
|
-
else if (isSuffixNext) {
|
|
657
|
-
handleKeypress(undefined, createPasteKeyEvent('paste-end'));
|
|
658
|
-
}
|
|
659
|
-
pos = nextMarkerPos + markerLength;
|
|
660
|
-
}
|
|
725
|
+
broadcast({ ...key, paste: pasteBuffer !== null });
|
|
661
726
|
};
|
|
727
|
+
let cleanup = () => { };
|
|
662
728
|
let rl;
|
|
663
|
-
if (
|
|
729
|
+
if (keypressStream !== null) {
|
|
664
730
|
rl = readline.createInterface({
|
|
665
731
|
input: keypressStream,
|
|
666
732
|
escapeCodeTimeout: 0,
|
|
667
733
|
});
|
|
668
734
|
readline.emitKeypressEvents(keypressStream, rl);
|
|
735
|
+
const parser = pasteMarkerParser(keypressStream, handleKeypress);
|
|
736
|
+
parser.next(); // prime the generator so it starts listening.
|
|
737
|
+
let timeoutId;
|
|
738
|
+
const handleRawKeypress = (data) => {
|
|
739
|
+
clearTimeout(timeoutId);
|
|
740
|
+
parser.next(data);
|
|
741
|
+
timeoutId = setTimeout(() => parser.next(''), PASTE_CODE_TIMEOUT_MS);
|
|
742
|
+
};
|
|
669
743
|
keypressStream.on('keypress', handleKeypress);
|
|
744
|
+
process.stdin.setEncoding('utf8'); // so handleRawKeypress gets strings
|
|
670
745
|
stdin.on('data', handleRawKeypress);
|
|
746
|
+
cleanup = () => {
|
|
747
|
+
keypressStream.removeListener('keypress', handleKeypress);
|
|
748
|
+
stdin.removeListener('data', handleRawKeypress);
|
|
749
|
+
};
|
|
671
750
|
}
|
|
672
751
|
else {
|
|
673
752
|
rl = readline.createInterface({ input: stdin, escapeCodeTimeout: 0 });
|
|
674
753
|
readline.emitKeypressEvents(stdin, rl);
|
|
675
754
|
stdin.on('keypress', handleKeypress);
|
|
755
|
+
cleanup = () => stdin.removeListener('keypress', handleKeypress);
|
|
676
756
|
}
|
|
677
757
|
return () => {
|
|
678
|
-
|
|
679
|
-
keypressStream.removeListener('keypress', handleKeypress);
|
|
680
|
-
stdin.removeListener('data', handleRawKeypress);
|
|
681
|
-
}
|
|
682
|
-
else {
|
|
683
|
-
stdin.removeListener('keypress', handleKeypress);
|
|
684
|
-
}
|
|
758
|
+
cleanup();
|
|
685
759
|
rl.close();
|
|
686
760
|
// Restore the terminal to its original state.
|
|
687
761
|
if (wasRaw === false) {
|
|
@@ -691,24 +765,24 @@ export function KeypressProvider({ children, kittyProtocolEnabled, config, debug
|
|
|
691
765
|
clearTimeout(backslashTimeout);
|
|
692
766
|
backslashTimeout = null;
|
|
693
767
|
}
|
|
694
|
-
if (
|
|
695
|
-
clearTimeout(
|
|
696
|
-
|
|
768
|
+
if (inputTimeout) {
|
|
769
|
+
clearTimeout(inputTimeout);
|
|
770
|
+
inputTimeout = null;
|
|
697
771
|
}
|
|
698
772
|
// Flush any pending kitty sequence data to avoid data loss on exit.
|
|
699
|
-
if (
|
|
773
|
+
if (inputBuffer) {
|
|
700
774
|
broadcast({
|
|
701
775
|
name: '',
|
|
702
776
|
ctrl: false,
|
|
703
777
|
meta: false,
|
|
704
778
|
shift: false,
|
|
705
779
|
paste: false,
|
|
706
|
-
sequence:
|
|
780
|
+
sequence: inputBuffer,
|
|
707
781
|
});
|
|
708
|
-
|
|
782
|
+
inputBuffer = '';
|
|
709
783
|
}
|
|
710
784
|
// Flush any pending paste data to avoid data loss on exit.
|
|
711
|
-
if (
|
|
785
|
+
if (pasteBuffer !== null) {
|
|
712
786
|
broadcast({
|
|
713
787
|
name: '',
|
|
714
788
|
ctrl: false,
|
|
@@ -717,23 +791,19 @@ export function KeypressProvider({ children, kittyProtocolEnabled, config, debug
|
|
|
717
791
|
paste: true,
|
|
718
792
|
sequence: pasteBuffer.toString(),
|
|
719
793
|
});
|
|
720
|
-
pasteBuffer =
|
|
721
|
-
}
|
|
722
|
-
if (draggingTimerRef.current) {
|
|
723
|
-
clearTimeout(draggingTimerRef.current);
|
|
724
|
-
draggingTimerRef.current = null;
|
|
794
|
+
pasteBuffer = null;
|
|
725
795
|
}
|
|
726
|
-
|
|
796
|
+
clearDraggingTimer();
|
|
797
|
+
if (dragBuffer) {
|
|
727
798
|
broadcast({
|
|
728
799
|
name: '',
|
|
729
800
|
ctrl: false,
|
|
730
801
|
meta: false,
|
|
731
802
|
shift: false,
|
|
732
803
|
paste: true,
|
|
733
|
-
sequence:
|
|
804
|
+
sequence: dragBuffer,
|
|
734
805
|
});
|
|
735
|
-
|
|
736
|
-
dragBufferRef.current = '';
|
|
806
|
+
dragBuffer = '';
|
|
737
807
|
}
|
|
738
808
|
};
|
|
739
809
|
}, [
|
|
@@ -741,8 +811,8 @@ export function KeypressProvider({ children, kittyProtocolEnabled, config, debug
|
|
|
741
811
|
setRawMode,
|
|
742
812
|
kittyProtocolEnabled,
|
|
743
813
|
config,
|
|
744
|
-
subscribers,
|
|
745
814
|
debugKeystrokeLogging,
|
|
815
|
+
broadcast,
|
|
746
816
|
]);
|
|
747
817
|
return (_jsx(KeypressContext.Provider, { value: { subscribe, unsubscribe }, children: children }));
|
|
748
818
|
}
|