@deepseek-harness-tui/dsh-tui 0.6.1 → 0.7.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 +74 -21
- package/bin/dsh-tui.js +115 -25
- package/cordis.patch.yml +69 -17
- package/cordis.yml +50 -12
- package/lib/types/activityPrefs.d.ts +1 -1
- package/lib/types/activityPrefs.js +3 -3
- package/lib/types/cc/figures.d.ts +27 -20
- package/lib/types/cc/figures.d.ts.map +1 -1
- package/lib/types/cc/figures.js +43 -34
- package/lib/types/cc/format.d.ts +18 -9
- package/lib/types/cc/format.d.ts.map +1 -1
- package/lib/types/cc/format.js +26 -18
- package/lib/types/cc/markdown.d.ts +31 -16
- package/lib/types/cc/markdown.d.ts.map +1 -1
- package/lib/types/cc/markdown.js +283 -260
- package/lib/types/cc/terminal.d.ts +10 -7
- package/lib/types/cc/terminal.d.ts.map +1 -1
- package/lib/types/cc/terminal.js +62 -50
- package/lib/types/command-trees.d.ts +3 -0
- package/lib/types/command-trees.d.ts.map +1 -0
- package/lib/types/command-trees.js +4 -0
- package/lib/types/commands.d.ts +37 -1
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +68 -3
- package/lib/types/components/ActivityLine.d.ts +1 -1
- package/lib/types/components/ActivityLine.d.ts.map +1 -1
- package/lib/types/components/ActivityPicker.d.ts.map +1 -1
- package/lib/types/components/ActivityPicker.js +3 -4
- package/lib/types/components/BtwPanel.d.ts +16 -0
- package/lib/types/components/BtwPanel.d.ts.map +1 -0
- package/lib/types/components/BtwPanel.js +47 -0
- package/lib/types/components/CommandSuggestions.d.ts +4 -2
- package/lib/types/components/CommandSuggestions.d.ts.map +1 -1
- package/lib/types/components/CommandSuggestions.js +2 -2
- package/lib/types/components/EffortSlider.d.ts +15 -0
- package/lib/types/components/EffortSlider.d.ts.map +1 -0
- package/lib/types/components/EffortSlider.js +17 -0
- package/lib/types/components/GoalTodoPanel.d.ts +1 -1
- package/lib/types/components/GoalTodoPanel.d.ts.map +1 -1
- package/lib/types/components/HelpMenu.d.ts +5 -2
- package/lib/types/components/HelpMenu.d.ts.map +1 -1
- package/lib/types/components/HelpMenu.js +8 -3
- package/lib/types/components/HistorySearchDialog.d.ts +1 -1
- package/lib/types/components/HistorySearchDialog.d.ts.map +1 -1
- package/lib/types/components/HistorySearchDialog.js +21 -10
- package/lib/types/components/InterruptedByUser.d.ts +2 -2
- package/lib/types/components/InterruptedByUser.d.ts.map +1 -1
- package/lib/types/components/InterruptedByUser.js +4 -3
- package/lib/types/components/LoadedContextPanel.d.ts +1 -1
- package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +2 -1
- package/lib/types/components/Markdown.d.ts +11 -11
- package/lib/types/components/Markdown.d.ts.map +1 -1
- package/lib/types/components/Markdown.js +63 -57
- package/lib/types/components/MarkdownTable.d.ts +1 -1
- package/lib/types/components/MarkdownTable.js +2 -2
- package/lib/types/components/MessageList.d.ts +10 -2
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +17 -10
- package/lib/types/components/ModelPicker.d.ts +4 -1
- package/lib/types/components/ModelPicker.d.ts.map +1 -1
- package/lib/types/components/ModelPicker.js +16 -4
- package/lib/types/components/OverlayAbove.d.ts +20 -0
- package/lib/types/components/OverlayAbove.d.ts.map +1 -0
- package/lib/types/components/OverlayAbove.js +18 -0
- package/lib/types/components/PresetPicker.d.ts +1 -1
- package/lib/types/components/PresetPicker.d.ts.map +1 -1
- package/lib/types/components/PresetPicker.js +2 -3
- package/lib/types/components/PromptInput.d.ts +5 -4
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +186 -39
- package/lib/types/components/ResumePicker.d.ts +15 -4
- package/lib/types/components/ResumePicker.d.ts.map +1 -1
- package/lib/types/components/ResumePicker.js +25 -9
- package/lib/types/components/RewindPicker.d.ts +1 -1
- package/lib/types/components/RewindPicker.d.ts.map +1 -1
- package/lib/types/components/RewindPicker.js +14 -5
- package/lib/types/components/SearchBox.d.ts +1 -1
- package/lib/types/components/SearchBox.js +1 -1
- package/lib/types/components/Spinner/GlimmerMessage.d.ts +1 -2
- package/lib/types/components/Spinner/GlimmerMessage.d.ts.map +1 -1
- package/lib/types/components/Spinner/GlimmerMessage.js +1 -2
- package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts +1 -1
- package/lib/types/components/Spinner/SpinnerAnimationRow.js +2 -2
- package/lib/types/components/Spinner/SpinnerGlyph.d.ts +1 -1
- package/lib/types/components/Spinner/SpinnerGlyph.js +1 -1
- package/lib/types/components/Spinner/spinnerUtils.d.ts +13 -18
- package/lib/types/components/Spinner/spinnerUtils.d.ts.map +1 -1
- package/lib/types/components/Spinner/spinnerUtils.js +67 -71
- package/lib/types/components/Spinner/useStalledAnimation.d.ts +1 -2
- package/lib/types/components/Spinner/useStalledAnimation.d.ts.map +1 -1
- package/lib/types/components/Spinner/useStalledAnimation.js +1 -2
- package/lib/types/components/StreamingMarkdown.d.ts +1 -1
- package/lib/types/components/StreamingMarkdown.js +1 -1
- package/lib/types/components/ThemePicker.d.ts +13 -9
- package/lib/types/components/ThemePicker.d.ts.map +1 -1
- package/lib/types/components/ThemePicker.js +21 -15
- package/lib/types/components/ThinkingToggle.d.ts +1 -1
- package/lib/types/components/ThinkingToggle.d.ts.map +1 -1
- package/lib/types/components/ThinkingToggle.js +8 -8
- package/lib/types/components/ToolUseLoader.d.ts +1 -1
- package/lib/types/components/ToolUseLoader.js +1 -1
- package/lib/types/components/WorkingSpinner.d.ts +2 -2
- package/lib/types/components/WorkingSpinner.js +2 -2
- package/lib/types/components/WorkspaceFlowPicker.d.ts +15 -0
- package/lib/types/components/WorkspaceFlowPicker.d.ts.map +1 -0
- package/lib/types/components/WorkspaceFlowPicker.js +19 -0
- package/lib/types/components/WorkspacePicker.d.ts +9 -0
- package/lib/types/components/WorkspacePicker.d.ts.map +1 -0
- package/lib/types/components/WorkspacePicker.js +13 -0
- package/lib/types/components/approvals/ApprovalPanel.d.ts +1 -1
- package/lib/types/components/approvals/ApprovalPanel.d.ts.map +1 -1
- package/lib/types/components/approvals/ApprovalPanel.js +2 -1
- package/lib/types/components/design-system/Byline.d.ts +1 -1
- package/lib/types/components/design-system/Byline.js +1 -1
- package/lib/types/components/design-system/Divider.d.ts +1 -1
- package/lib/types/components/design-system/Divider.js +1 -1
- package/lib/types/components/design-system/HintLine.d.ts +12 -0
- package/lib/types/components/design-system/HintLine.d.ts.map +1 -0
- package/lib/types/components/design-system/HintLine.js +15 -0
- package/lib/types/components/design-system/KeyboardShortcutHint.d.ts +1 -1
- package/lib/types/components/design-system/KeyboardShortcutHint.js +1 -1
- package/lib/types/components/design-system/ListItem.d.ts +2 -2
- package/lib/types/components/design-system/ListItem.d.ts.map +1 -1
- package/lib/types/components/design-system/ListItem.js +35 -3
- package/lib/types/components/design-system/LoadingState.d.ts +1 -2
- package/lib/types/components/design-system/LoadingState.d.ts.map +1 -1
- package/lib/types/components/design-system/LoadingState.js +1 -2
- package/lib/types/components/design-system/Pane.d.ts +2 -2
- package/lib/types/components/design-system/Pane.js +2 -2
- package/lib/types/components/design-system/ProgressBar.d.ts +1 -2
- package/lib/types/components/design-system/ProgressBar.d.ts.map +1 -1
- package/lib/types/components/design-system/ProgressBar.js +1 -2
- package/lib/types/components/design-system/StatusIcon.d.ts +2 -2
- package/lib/types/components/design-system/StatusIcon.js +2 -2
- package/lib/types/components/design-system/ThemeProvider.d.ts +1 -1
- package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -1
- package/lib/types/components/design-system/ThemeProvider.js +87 -26
- package/lib/types/components/design-system/ThemedBox.d.ts +1 -1
- package/lib/types/components/design-system/ThemedBox.js +1 -1
- package/lib/types/components/design-system/ThemedText.d.ts +2 -2
- package/lib/types/components/design-system/ThemedText.js +2 -2
- package/lib/types/components/listWindow.d.ts +26 -0
- package/lib/types/components/listWindow.d.ts.map +1 -0
- package/lib/types/components/listWindow.js +47 -0
- package/lib/types/components/messages/AssistantTextMessage.d.ts +1 -2
- package/lib/types/components/messages/AssistantTextMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantTextMessage.js +1 -2
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts +2 -2
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantThinkingMessage.js +6 -6
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +12 -4
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +9 -5
- package/lib/types/components/messages/MessageMetadata.d.ts +1 -1
- package/lib/types/components/messages/MessageMetadata.js +1 -1
- package/lib/types/components/messages/UserPromptMessage.d.ts +1 -1
- package/lib/types/components/messages/UserPromptMessage.js +1 -1
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts +5 -1
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
- package/lib/types/components/questions/AskUserQuestionPanel.js +11 -9
- package/lib/types/components/questions/PlanReviewPanel.d.ts +1 -1
- package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
- package/lib/types/components/questions/PlanReviewPanel.js +3 -2
- package/lib/types/components/trajectory/HotspotView.d.ts +14 -0
- package/lib/types/components/trajectory/HotspotView.d.ts.map +1 -0
- package/lib/types/components/trajectory/HotspotView.js +83 -0
- package/lib/types/components/trajectory/Inspector.d.ts +31 -0
- package/lib/types/components/trajectory/Inspector.d.ts.map +1 -0
- package/lib/types/components/trajectory/Inspector.js +67 -0
- package/lib/types/components/trajectory/Ledger.d.ts +20 -0
- package/lib/types/components/trajectory/Ledger.d.ts.map +1 -0
- package/lib/types/components/trajectory/Ledger.js +112 -0
- package/lib/types/components/trajectory/MiniWake.d.ts +24 -0
- package/lib/types/components/trajectory/MiniWake.d.ts.map +1 -0
- package/lib/types/components/trajectory/MiniWake.js +99 -0
- package/lib/types/components/trajectory/WaveBand.d.ts +33 -0
- package/lib/types/components/trajectory/WaveBand.d.ts.map +1 -0
- package/lib/types/components/trajectory/WaveBand.js +145 -0
- package/lib/types/customTheme.d.ts +6 -6
- package/lib/types/customTheme.d.ts.map +1 -1
- package/lib/types/customTheme.js +15 -12
- package/lib/types/dsh-adapter/approvals.d.ts.map +1 -0
- package/lib/types/{channel.d.ts → dsh-adapter/channel.d.ts} +184 -43
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -0
- package/lib/types/{channel.js → dsh-adapter/channel.js} +972 -201
- package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -0
- package/lib/types/{childStderr.js → dsh-adapter/childStderr.js} +1 -1
- package/lib/types/dsh-adapter/command-trees.d.ts +27 -0
- package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -0
- package/lib/types/dsh-adapter/command-trees.js +42 -0
- package/lib/types/dsh-adapter/compat/index.d.ts +22 -0
- package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -0
- package/lib/types/{compat → dsh-adapter/compat}/index.js +7 -4
- package/lib/types/dsh-adapter/compat/sessionLog.d.ts +86 -0
- package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/sessionLog.js +347 -0
- package/lib/types/dsh-adapter/contract.d.ts +20 -0
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -0
- package/lib/types/dsh-adapter/contract.js +109 -0
- package/lib/types/dsh-adapter/index.d.ts +80 -0
- package/lib/types/dsh-adapter/index.d.ts.map +1 -0
- package/lib/types/dsh-adapter/index.js +45 -0
- package/lib/types/dsh-adapter/invariant.d.ts.map +1 -0
- package/lib/types/dsh-adapter/packaged-skills.d.ts.map +1 -0
- package/lib/types/{plugin.d.ts → dsh-adapter/plugin.d.ts} +17 -0
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -0
- package/lib/types/{plugin.js → dsh-adapter/plugin.js} +280 -80
- package/lib/types/dsh-adapter/presets.d.ts.map +1 -0
- package/lib/types/dsh-adapter/providerWizard.d.ts +91 -0
- package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -0
- package/lib/types/dsh-adapter/providerWizard.js +332 -0
- package/lib/types/{questions.d.ts → dsh-adapter/questions.d.ts} +7 -2
- package/lib/types/dsh-adapter/questions.d.ts.map +1 -0
- package/lib/types/{questions.js → dsh-adapter/questions.js} +15 -7
- package/lib/types/dsh-adapter/sideQuestion.d.ts +38 -0
- package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sideQuestion.js +69 -0
- package/lib/types/dsh-adapter/trajectory/aggregate.d.ts +46 -0
- package/lib/types/dsh-adapter/trajectory/aggregate.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/aggregate.js +207 -0
- package/lib/types/dsh-adapter/trajectory/guards.d.ts +177 -0
- package/lib/types/dsh-adapter/trajectory/guards.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/guards.js +235 -0
- package/lib/types/dsh-adapter/trajectory/index.d.ts +16 -0
- package/lib/types/dsh-adapter/trajectory/index.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/index.js +15 -0
- package/lib/types/dsh-adapter/trajectory/inspect.d.ts +40 -0
- package/lib/types/dsh-adapter/trajectory/inspect.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/inspect.js +160 -0
- package/lib/types/dsh-adapter/trajectory/projection.d.ts +128 -0
- package/lib/types/dsh-adapter/trajectory/projection.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/projection.js +653 -0
- package/lib/types/dsh-adapter/trajectory/types.d.ts +232 -0
- package/lib/types/dsh-adapter/trajectory/types.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/types.js +70 -0
- package/lib/types/dsh-adapter/trajectory/wave.d.ts +45 -0
- package/lib/types/dsh-adapter/trajectory/wave.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/wave.js +210 -0
- package/lib/types/dsh-adapter/types.d.ts +23 -0
- package/lib/types/dsh-adapter/types.d.ts.map +1 -0
- package/lib/types/dsh-adapter/types.js +1 -0
- package/lib/types/dsh-adapter/workspace.d.ts +22 -0
- package/lib/types/dsh-adapter/workspace.d.ts.map +1 -0
- package/lib/types/dsh-adapter/workspace.js +16 -0
- package/lib/types/dsh-adapter/workspaces.d.ts +118 -0
- package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -0
- package/lib/types/dsh-adapter/workspaces.js +290 -0
- package/lib/types/effortPrefs.d.ts +1 -1
- package/lib/types/effortPrefs.js +3 -3
- package/lib/types/history.js +2 -2
- package/lib/types/hooks/useBlink.d.ts +1 -1
- package/lib/types/hooks/useBlink.js +1 -1
- package/lib/types/i18n.d.ts +977 -36
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +307 -30
- package/lib/types/index.d.ts +1 -69
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +3 -31
- package/lib/types/ink/components/App.d.ts.map +1 -1
- package/lib/types/ink/components/App.js +33 -19
- package/lib/types/ink/dom.d.ts +15 -0
- package/lib/types/ink/dom.d.ts.map +1 -1
- package/lib/types/ink/dom.js +32 -0
- package/lib/types/ink/hooks/use-input.d.ts.map +1 -1
- package/lib/types/ink/hooks/use-input.js +8 -0
- package/lib/types/ink/hooks/use-terminal-size.d.ts +1 -1
- package/lib/types/ink/hooks/use-terminal-size.js +1 -1
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +109 -28
- package/lib/types/ink/input-suppression.d.ts +20 -0
- package/lib/types/ink/input-suppression.d.ts.map +1 -0
- package/lib/types/ink/input-suppression.js +26 -0
- package/lib/types/ink/log-update.js +21 -6
- package/lib/types/ink/parse-keypress.d.ts +31 -0
- package/lib/types/ink/parse-keypress.d.ts.map +1 -1
- package/lib/types/ink/parse-keypress.js +442 -8
- package/lib/types/ink/terminal-querier.d.ts +5 -1
- package/lib/types/ink/terminal-querier.d.ts.map +1 -1
- package/lib/types/ink/terminal-querier.js +27 -3
- package/lib/types/ink/terminal.d.ts +18 -0
- package/lib/types/ink/terminal.d.ts.map +1 -1
- package/lib/types/ink/terminal.js +32 -4
- package/lib/types/ink/termio/csi.d.ts +10 -0
- package/lib/types/ink/termio/csi.d.ts.map +1 -1
- package/lib/types/ink/termio/csi.js +20 -0
- package/lib/types/ink/termio/tokenize.js +10 -0
- package/lib/types/modelPrefs.d.ts +1 -1
- package/lib/types/modelPrefs.js +3 -3
- package/lib/types/presetPrefs.d.ts +1 -1
- package/lib/types/presetPrefs.js +3 -3
- package/lib/types/screens/Chat.d.ts +20 -4
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +655 -55
- package/lib/types/screens/StatusLine.d.ts +17 -2
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +12 -4
- package/lib/types/screens/TrajectoryScene.d.ts +16 -0
- package/lib/types/screens/TrajectoryScene.d.ts.map +1 -0
- package/lib/types/screens/TrajectoryScene.js +305 -0
- package/lib/types/sessionHistory.d.ts +9 -1
- package/lib/types/sessionHistory.d.ts.map +1 -1
- package/lib/types/sessionHistory.js +56 -16
- package/lib/types/sessionModes.d.ts +29 -0
- package/lib/types/sessionModes.d.ts.map +1 -0
- package/lib/types/sessionModes.js +45 -0
- package/lib/types/theme.d.ts +27 -3
- package/lib/types/theme.d.ts.map +1 -1
- package/lib/types/theme.js +48 -4
- package/lib/types/themePrefs.d.ts +3 -3
- package/lib/types/themePrefs.js +5 -5
- package/lib/types/trajectory/format.d.ts +100 -0
- package/lib/types/trajectory/format.d.ts.map +1 -0
- package/lib/types/trajectory/format.js +213 -0
- package/lib/types/trajectory/motion.d.ts +99 -0
- package/lib/types/trajectory/motion.d.ts.map +1 -0
- package/lib/types/trajectory/motion.js +143 -0
- package/lib/types/trajectory/query.d.ts +83 -0
- package/lib/types/trajectory/query.d.ts.map +1 -0
- package/lib/types/trajectory/query.js +187 -0
- package/lib/types/trajectoryPrefs.d.ts +36 -0
- package/lib/types/trajectoryPrefs.d.ts.map +1 -0
- package/lib/types/trajectoryPrefs.js +65 -0
- package/lib/types/update.d.ts +3 -3
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +18 -7
- package/lib/types/utils/clipboard.d.ts +101 -29
- package/lib/types/utils/clipboard.d.ts.map +1 -1
- package/lib/types/utils/clipboard.js +533 -55
- package/lib/types/utils/debug.d.ts +1 -1
- package/lib/types/utils/debug.js +2 -2
- package/lib/types/utils/execFileNoThrow.d.ts.map +1 -1
- package/lib/types/utils/execFileNoThrow.js +16 -6
- package/lib/types/utils/externalEditor.d.ts +115 -0
- package/lib/types/utils/externalEditor.d.ts.map +1 -0
- package/lib/types/utils/externalEditor.js +270 -0
- package/lib/types/utils/fullscreen.d.ts +2 -2
- package/lib/types/utils/fullscreen.js +3 -3
- package/lib/types/utils/loaded-context.d.ts +1 -1
- package/lib/types/utils/loaded-context.d.ts.map +1 -1
- package/lib/types/utils/modifiers.d.ts +24 -0
- package/lib/types/utils/modifiers.d.ts.map +1 -1
- package/lib/types/utils/modifiers.js +27 -0
- package/lib/types/utils/paths.d.ts +45 -0
- package/lib/types/utils/paths.d.ts.map +1 -0
- package/lib/types/utils/paths.js +69 -0
- package/lib/types/utils/shellQuote.d.ts +14 -0
- package/lib/types/utils/shellQuote.d.ts.map +1 -0
- package/lib/types/utils/shellQuote.js +39 -0
- package/lib/types/utils/workspaceRoot.d.ts +21 -0
- package/lib/types/utils/workspaceRoot.d.ts.map +1 -0
- package/lib/types/utils/workspaceRoot.js +47 -0
- package/lib/types/workspaces.d.ts +3 -0
- package/lib/types/workspaces.d.ts.map +1 -0
- package/lib/types/workspaces.js +4 -0
- package/package.json +25 -7
- package/lib/types/approvals.d.ts.map +0 -1
- package/lib/types/channel.d.ts.map +0 -1
- package/lib/types/childStderr.d.ts.map +0 -1
- package/lib/types/compat/index.d.ts +0 -20
- package/lib/types/compat/index.d.ts.map +0 -1
- package/lib/types/compat/sessionLog.d.ts +0 -40
- package/lib/types/compat/sessionLog.d.ts.map +0 -1
- package/lib/types/compat/sessionLog.js +0 -226
- package/lib/types/invariant.d.ts.map +0 -1
- package/lib/types/packaged-skills.d.ts.map +0 -1
- package/lib/types/plugin.d.ts.map +0 -1
- package/lib/types/presets.d.ts.map +0 -1
- package/lib/types/questions.d.ts.map +0 -1
- /package/lib/types/{approvals.d.ts → dsh-adapter/approvals.d.ts} +0 -0
- /package/lib/types/{approvals.js → dsh-adapter/approvals.js} +0 -0
- /package/lib/types/{childStderr.d.ts → dsh-adapter/childStderr.d.ts} +0 -0
- /package/lib/types/{invariant.d.ts → dsh-adapter/invariant.d.ts} +0 -0
- /package/lib/types/{invariant.js → dsh-adapter/invariant.js} +0 -0
- /package/lib/types/{packaged-skills.d.ts → dsh-adapter/packaged-skills.d.ts} +0 -0
- /package/lib/types/{packaged-skills.js → dsh-adapter/packaged-skills.js} +0 -0
- /package/lib/types/{presets.d.ts → dsh-adapter/presets.d.ts} +0 -0
- /package/lib/types/{presets.js → dsh-adapter/presets.js} +0 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input suppression window for terminal handoffs (issue #123): when stdin is
|
|
3
|
+
* handed to an external TUI (full-screen editor) and back, the tty can
|
|
4
|
+
* deliver a burst of bytes that are NOT user keystrokes — the editor's
|
|
5
|
+
* rmcup/mode-restore replies, CPR/DECRPM query responses, mouse-event
|
|
6
|
+
* fragments, or keystrokes typed into the canonical line buffer while raw
|
|
7
|
+
* mode was off. Parsed as input they are destructive: a stray ESC reads as
|
|
8
|
+
* the escape key (which CLEARS a non-empty prompt) and the rest lands as
|
|
9
|
+
* text garbage.
|
|
10
|
+
*
|
|
11
|
+
* resumeStdin() drains what is already buffered; this module covers what
|
|
12
|
+
* arrives LATE (terminal replies are async). use-input checks the window at
|
|
13
|
+
* the single choke point every component's input flows through, so no
|
|
14
|
+
* listener (Chat's ctrl+c/esc handling included) sees the burst.
|
|
15
|
+
*/
|
|
16
|
+
/** Suppress all parsed input for `ms` from now (monotonic extension). */
|
|
17
|
+
export declare function suppressInputFor(ms: number): void;
|
|
18
|
+
/** True while the post-handoff suppression window is open. */
|
|
19
|
+
export declare function isInputSuppressed(): boolean;
|
|
20
|
+
//# sourceMappingURL=input-suppression.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-suppression.d.ts","sourceRoot":"","sources":["../../../src/ink/input-suppression.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAGjD;AAED,8DAA8D;AAC9D,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input suppression window for terminal handoffs (issue #123): when stdin is
|
|
3
|
+
* handed to an external TUI (full-screen editor) and back, the tty can
|
|
4
|
+
* deliver a burst of bytes that are NOT user keystrokes — the editor's
|
|
5
|
+
* rmcup/mode-restore replies, CPR/DECRPM query responses, mouse-event
|
|
6
|
+
* fragments, or keystrokes typed into the canonical line buffer while raw
|
|
7
|
+
* mode was off. Parsed as input they are destructive: a stray ESC reads as
|
|
8
|
+
* the escape key (which CLEARS a non-empty prompt) and the rest lands as
|
|
9
|
+
* text garbage.
|
|
10
|
+
*
|
|
11
|
+
* resumeStdin() drains what is already buffered; this module covers what
|
|
12
|
+
* arrives LATE (terminal replies are async). use-input checks the window at
|
|
13
|
+
* the single choke point every component's input flows through, so no
|
|
14
|
+
* listener (Chat's ctrl+c/esc handling included) sees the burst.
|
|
15
|
+
*/
|
|
16
|
+
let suppressedUntil = 0;
|
|
17
|
+
/** Suppress all parsed input for `ms` from now (monotonic extension). */
|
|
18
|
+
export function suppressInputFor(ms) {
|
|
19
|
+
const until = Date.now() + ms;
|
|
20
|
+
if (until > suppressedUntil)
|
|
21
|
+
suppressedUntil = until;
|
|
22
|
+
}
|
|
23
|
+
/** True while the post-handoff suppression window is open. */
|
|
24
|
+
export function isInputSuppressed() {
|
|
25
|
+
return Date.now() < suppressedUntil;
|
|
26
|
+
}
|
|
@@ -452,9 +452,27 @@ function readLine(screen, y) {
|
|
|
452
452
|
return line.trimEnd();
|
|
453
453
|
}
|
|
454
454
|
function fullResetSequence_CAUSES_FLICKER(frame, reason, stylePool, debug) {
|
|
455
|
-
// After clearTerminal
|
|
456
|
-
|
|
457
|
-
|
|
455
|
+
// After clearTerminal the viewport is blank and the cursor is at (0, 0), so
|
|
456
|
+
// this paints downward from the top — and therefore must paint only what
|
|
457
|
+
// fits. Every row here ends in CR+LF, the bottom viewport row is reserved
|
|
458
|
+
// for the cursor park, and so at most viewportHeight-1 rows of content can
|
|
459
|
+
// land above it. Painting the whole frame regardless overflows as soon as
|
|
460
|
+
// the frame is as tall as the viewport: the trailing CR+LF is emitted on the
|
|
461
|
+
// bottom row, the terminal scrolls, and the frame's last row — the status
|
|
462
|
+
// hint, always the final row of the main screen — is carried off the bottom.
|
|
463
|
+
// A narrowing resize is what makes a frame reach full height (content wraps
|
|
464
|
+
// onto more rows while the row count stays put), which is why that direction
|
|
465
|
+
// lost its bottom row while widening never did.
|
|
466
|
+
//
|
|
467
|
+
// Painting the frame's tail instead keeps the same end state the in-place
|
|
468
|
+
// viewport repaint documents — frame rows [H-contentRows, H) on screen with
|
|
469
|
+
// the cursor parked one row below the last of them — so the next frame's
|
|
470
|
+
// bookkeeping needs no special case for having come through a reset.
|
|
471
|
+
const height = frame.screen.height;
|
|
472
|
+
const contentRows = Math.min(height, Math.max(1, frame.viewport.height - 1));
|
|
473
|
+
const startY = height - contentRows;
|
|
474
|
+
const screen = new VirtualScreen({ x: 0, y: startY }, frame.viewport.width);
|
|
475
|
+
renderFrameSlice(screen, frame, startY, height, stylePool);
|
|
458
476
|
return [{ type: 'clearTerminal', reason, debug }, ...screen.diff];
|
|
459
477
|
}
|
|
460
478
|
/**
|
|
@@ -507,9 +525,6 @@ function repaintViewportInPlace(prev, next, stylePool) {
|
|
|
507
525
|
renderFrameSlice(screen, next, startY, height, stylePool);
|
|
508
526
|
return [{ type: 'stdout', content: anchor }, ...screen.diff];
|
|
509
527
|
}
|
|
510
|
-
function renderFrame(screen, frame, stylePool) {
|
|
511
|
-
renderFrameSlice(screen, frame, 0, frame.screen.height, stylePool);
|
|
512
|
-
}
|
|
513
528
|
/**
|
|
514
529
|
* Render a slice of rows from the frame's screen.
|
|
515
530
|
* Each row is rendered followed by a newline. Cursor ends at (0, endY).
|
|
@@ -58,6 +58,17 @@ export type TerminalResponse =
|
|
|
58
58
|
type: 'xtversion';
|
|
59
59
|
name: string;
|
|
60
60
|
};
|
|
61
|
+
/** Mutable cross-call state for the decomposed-paste matcher. */
|
|
62
|
+
export type Win32PasteState = {
|
|
63
|
+
/** true between the decomposed start and end markers */
|
|
64
|
+
active: boolean;
|
|
65
|
+
/** progress into the marker pattern currently being matched */
|
|
66
|
+
matched: number;
|
|
67
|
+
/** keys held while a marker prefix match is in flight */
|
|
68
|
+
held: ParsedKey[];
|
|
69
|
+
/** collected paste content while active */
|
|
70
|
+
buffer: string;
|
|
71
|
+
};
|
|
61
72
|
/**
|
|
62
73
|
* Parser state carried between parseMultipleKeypresses calls: paste mode,
|
|
63
74
|
* buffered incomplete input, and the internal tokenizer instance.
|
|
@@ -66,6 +77,26 @@ export type KeyParseState = {
|
|
|
66
77
|
mode: 'NORMAL' | 'IN_PASTE';
|
|
67
78
|
incomplete: string;
|
|
68
79
|
pasteBuffer: string;
|
|
80
|
+
/**
|
|
81
|
+
* Pending high surrogate from a win32-input-mode record. Uc is a UTF-16
|
|
82
|
+
* code unit, so supplementary-plane characters (emoji, CJK ext-B) arrive
|
|
83
|
+
* as two consecutive records; the high half waits here for its low half.
|
|
84
|
+
*/
|
|
85
|
+
win32HighSurrogate?: number;
|
|
86
|
+
/**
|
|
87
|
+
* Pending high surrogate for the Alt+numpad synthesis path — separate
|
|
88
|
+
* from win32HighSurrogate because the two Alt rounds of one supplementary
|
|
89
|
+
* char interleave with keydown records (Alt-down, numpad digits) that
|
|
90
|
+
* would settle the regular slot before the low half arrives.
|
|
91
|
+
*/
|
|
92
|
+
win32AltHighSurrogate?: number;
|
|
93
|
+
/**
|
|
94
|
+
* Decomposed bracketed-paste tracking for win32-input-mode. Classic
|
|
95
|
+
* conhost synthesizes pastes as per-char KEY_EVENT_RECORDs — including
|
|
96
|
+
* the ESC[200~ / ESC[201~ markers themselves — so under W32IM the markers
|
|
97
|
+
* arrive as ordinary key records and must be reassembled here (issue #147).
|
|
98
|
+
*/
|
|
99
|
+
win32Paste?: Win32PasteState;
|
|
69
100
|
_tokenizer?: Tokenizer;
|
|
70
101
|
};
|
|
71
102
|
/** Initial `KeyParseState` for a fresh parser. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-keypress.d.ts","sourceRoot":"","sources":["../../../src/ink/parse-keypress.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"parse-keypress.d.ts","sourceRoot":"","sources":["../../../src/ink/parse-keypress.ts"],"names":[],"mappings":"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"}
|
|
@@ -25,6 +25,74 @@ const CSI_U_RE = /^\x1b\[(\d+)(?:;(\d+))?u/;
|
|
|
25
25
|
// Note param order is reversed vs CSI u (modifier first, keycode second).
|
|
26
26
|
// eslint-disable-next-line no-control-regex
|
|
27
27
|
const MODIFY_OTHER_KEYS_RE = /^\x1b\[27;(\d+);(\d+)~/;
|
|
28
|
+
// win32-input-mode (ConPTY, DECSET 9001): CSI Vk;Sc;Uc;Kd;Cs;Rc _
|
|
29
|
+
// One record per key event, carrying the full INPUT_RECORD state:
|
|
30
|
+
// Vk = virtual-key code (VK_RETURN=13, VK_ESCAPE=27, VK_UP=38, ...)
|
|
31
|
+
// Sc = scan code (unused — Vk+Uc fully determine the key)
|
|
32
|
+
// Uc = UTF-16 code unit of the produced character (0 for non-printing)
|
|
33
|
+
// Kd = keydown(1)/keyup(0)
|
|
34
|
+
// Cs = dwControlKeyState (0x01/0x02 Alt, 0x04/0x08 Ctrl, 0x10 Shift;
|
|
35
|
+
// also NUMLOCK 0x20 / CAPSLOCK 0x80 / ENHANCED 0x100 — mask before
|
|
36
|
+
// testing modifiers)
|
|
37
|
+
// Rc = repeat count
|
|
38
|
+
// All six fields are optional per spec #4999 and take their KEY_EVENT_RECORD
|
|
39
|
+
// defaults (Vk/Sc/Uc/Kd/Cs=0, Rc=1) when omitted or empty — a reduced 'a'
|
|
40
|
+
// keydown is legitimately `CSI 65;30;97;1_`. This is the only encoding that
|
|
41
|
+
// preserves Enter's Shift/Ctrl bits on Windows (issue #147). Enabled on
|
|
42
|
+
// win32 instead of kitty/modifyOtherKeys.
|
|
43
|
+
// eslint-disable-next-line no-control-regex
|
|
44
|
+
const WIN32_INPUT_RE = /^\x1b\[([\d;]*)_$/;
|
|
45
|
+
// dwControlKeyState modifier bits (others — NUMLOCK_ON 0x20, CAPSLOCK_ON
|
|
46
|
+
// 0x80, ENHANCED_KEY 0x100 — are state indicators, not pressed modifiers)
|
|
47
|
+
const WIN32_CS_ALT = 0x01 | 0x02;
|
|
48
|
+
const WIN32_CS_CTRL = 0x04 | 0x08;
|
|
49
|
+
const WIN32_CS_SHIFT = 0x10;
|
|
50
|
+
// Virtual-key codes that produce no input event of their own: the bare
|
|
51
|
+
// modifier keys. Their pressed state rides on the NEXT real key's Cs field,
|
|
52
|
+
// so both their keydown and keyup records are dropped.
|
|
53
|
+
const WIN32_VK_MODIFIER = new Set([16, 17, 18]); // VK_SHIFT, VK_CONTROL, VK_MENU
|
|
54
|
+
// Virtual-key code → key name for non-printing keys. Names match the
|
|
55
|
+
// keyName vocabulary below so input-event's nonAlphanumericKeys filter
|
|
56
|
+
// clears their raw sequence from text input. Printable keys are NOT here —
|
|
57
|
+
// they map through Uc (or Vk for Ctrl+letter, whose Uc is a control code).
|
|
58
|
+
const WIN32_VK_NAMES = {
|
|
59
|
+
8: 'backspace', // VK_BACK
|
|
60
|
+
9: 'tab', // VK_TAB
|
|
61
|
+
13: 'return', // VK_RETURN
|
|
62
|
+
27: 'escape', // VK_ESCAPE
|
|
63
|
+
32: 'space', // VK_SPACE
|
|
64
|
+
33: 'pageup', // VK_PRIOR
|
|
65
|
+
34: 'pagedown', // VK_NEXT
|
|
66
|
+
35: 'end', // VK_END
|
|
67
|
+
36: 'home', // VK_HOME
|
|
68
|
+
37: 'left', // VK_LEFT
|
|
69
|
+
38: 'up', // VK_UP
|
|
70
|
+
39: 'right', // VK_RIGHT
|
|
71
|
+
40: 'down', // VK_DOWN
|
|
72
|
+
45: 'insert', // VK_INSERT
|
|
73
|
+
46: 'delete', // VK_DELETE
|
|
74
|
+
};
|
|
75
|
+
// VK_F1 (112) .. VK_F12 (123)
|
|
76
|
+
for (let i = 0; i < 12; i++)
|
|
77
|
+
WIN32_VK_NAMES[112 + i] = `f${i + 1}`;
|
|
78
|
+
// OEM punctuation virtual-key codes → base character, used to recover
|
|
79
|
+
// Ctrl+<punctuation> combos (Ctrl+] etc.) whose Uc collapses to a control
|
|
80
|
+
// code. US-layout values; other layouts differ, but these combos are
|
|
81
|
+
// rare enough that a best-effort base key beats swallowing the event.
|
|
82
|
+
const WIN32_VK_OEM_CHARS = {
|
|
83
|
+
186: ';', // VK_OEM_1
|
|
84
|
+
187: '=', // VK_OEM_PLUS
|
|
85
|
+
188: ',', // VK_OEM_COMMA
|
|
86
|
+
189: '-', // VK_OEM_MINUS
|
|
87
|
+
190: '.', // VK_OEM_PERIOD
|
|
88
|
+
191: '/', // VK_OEM_2
|
|
89
|
+
192: '`', // VK_OEM_3
|
|
90
|
+
219: '[', // VK_OEM_4
|
|
91
|
+
220: '\\', // VK_OEM_5
|
|
92
|
+
221: ']', // VK_OEM_6
|
|
93
|
+
222: "'", // VK_OEM_7
|
|
94
|
+
226: '\\', // VK_OEM_102
|
|
95
|
+
};
|
|
28
96
|
// -- Terminal response patterns (inbound sequences from the terminal itself) --
|
|
29
97
|
// DECRPM: CSI ? Ps ; Pm $ y — response to DECRQM (request mode)
|
|
30
98
|
// eslint-disable-next-line no-control-regex
|
|
@@ -140,6 +208,302 @@ function splitNumericParams(params) {
|
|
|
140
208
|
return [];
|
|
141
209
|
return params.split(';').map(p => parseInt(p, 10));
|
|
142
210
|
}
|
|
211
|
+
/**
|
|
212
|
+
* Build a modifier-free text key from a win32 record (used for the
|
|
213
|
+
* Alt+numpad payload on Alt-release). `sequence` defaults to the char —
|
|
214
|
+
* space needs the literal ' ' so input-event lets it through as text.
|
|
215
|
+
*/
|
|
216
|
+
function win32TextKey(raw, name, sequence = name) {
|
|
217
|
+
return {
|
|
218
|
+
kind: 'key',
|
|
219
|
+
name,
|
|
220
|
+
fn: false,
|
|
221
|
+
ctrl: false,
|
|
222
|
+
meta: false,
|
|
223
|
+
shift: false,
|
|
224
|
+
option: false,
|
|
225
|
+
super: false,
|
|
226
|
+
sequence,
|
|
227
|
+
raw,
|
|
228
|
+
isPasted: false,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Translate a win32-input-mode record (CSI Vk;Sc;Uc;Kd;Cs;Rc _) into a
|
|
233
|
+
* ParsedKey, so the rest of the input pipeline sees the same key objects as
|
|
234
|
+
* on VT-protocol terminals (issue #147).
|
|
235
|
+
*
|
|
236
|
+
* @param ctx - surrogate-pair scratch state. Uc is a UTF-16 code unit, so a
|
|
237
|
+
* supplementary-plane character (emoji, CJK ext-B) arrives as two
|
|
238
|
+
* consecutive records; the high half waits in `ctx.high` for its low half.
|
|
239
|
+
* Mutated here, never on the caller's KeyParseState — the caller threads
|
|
240
|
+
* it into the next call's state.
|
|
241
|
+
* @returns `undefined` when `s` is not a win32 record (caller falls through
|
|
242
|
+
* to the VT parsers); `null` for a record that must be swallowed (keyup,
|
|
243
|
+
* bare modifier transition, orphaned surrogate half); otherwise the key
|
|
244
|
+
* plus its repeat count (Rc — ConPTY coalesces held-key repeats into one
|
|
245
|
+
* record).
|
|
246
|
+
*/
|
|
247
|
+
function parseWin32KeyEvent(s, ctx) {
|
|
248
|
+
const m = WIN32_INPUT_RE.exec(s);
|
|
249
|
+
if (!m)
|
|
250
|
+
return undefined;
|
|
251
|
+
const fields = m[1].split(';');
|
|
252
|
+
const num = (i, dflt) => {
|
|
253
|
+
const f = fields[i];
|
|
254
|
+
return f === undefined || f === '' ? dflt : parseInt(f, 10);
|
|
255
|
+
};
|
|
256
|
+
const vk = num(0, 0);
|
|
257
|
+
const uc = num(2, 0);
|
|
258
|
+
const keydown = num(3, 0) === 1;
|
|
259
|
+
const cs = num(4, 0);
|
|
260
|
+
// Rc coalesces auto-repeat; cap it so a corrupt/huge field can't flood the
|
|
261
|
+
// input queue (legitimate bursts arrive as separate records anyway).
|
|
262
|
+
const repeat = Math.max(1, Math.min(num(5, 1) || 1, 64));
|
|
263
|
+
// A line editor acts on keypresses only — keyup carries no meaning and
|
|
264
|
+
// would double every key if dispatched. Checked BEFORE settling a pending
|
|
265
|
+
// surrogate pair: CharToKeyEvents emits down+up per UTF-16 unit, so a
|
|
266
|
+
// supplementary character legitimately streams as high-down, high-up,
|
|
267
|
+
// low-down — a keyup must never clear the held high half.
|
|
268
|
+
if (!keydown) {
|
|
269
|
+
// Exception: Alt+numpad Unicode input (WindowsInbox's
|
|
270
|
+
// Feature_UseNumpadEventsForClipboardInput). The stream is Alt-down,
|
|
271
|
+
// digit records with no text, then a single Alt KEYUP whose Uc carries
|
|
272
|
+
// the composed character — the only payload in the stream. Ordinary
|
|
273
|
+
// keyups also carry Uc, so this is gated strictly on VK_MENU release
|
|
274
|
+
// with a nonzero Uc.
|
|
275
|
+
if (vk !== 18 || uc === 0)
|
|
276
|
+
return null;
|
|
277
|
+
// A supplementary-plane char is synthesized per UTF-16 unit: TWO Alt
|
|
278
|
+
// rounds, high half then low half, each riding its own Alt-up. The
|
|
279
|
+
// pending high waits in ctx.altHigh — a dedicated slot, because the
|
|
280
|
+
// next round's Alt-down/numpad records are keydowns that would settle
|
|
281
|
+
// the regular ctx.high before the low half ever arrives.
|
|
282
|
+
if (uc >= 0xd800 && uc <= 0xdbff) {
|
|
283
|
+
ctx.altHigh = uc;
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
if (uc >= 0xdc00 && uc <= 0xdfff) {
|
|
287
|
+
const high = ctx.altHigh;
|
|
288
|
+
ctx.altHigh = undefined;
|
|
289
|
+
if (high === undefined)
|
|
290
|
+
return null;
|
|
291
|
+
return { key: win32TextKey(s, String.fromCharCode(high, uc)), repeat: 1 };
|
|
292
|
+
}
|
|
293
|
+
// BMP payload: any pending synthesized high is orphaned by this char.
|
|
294
|
+
ctx.altHigh = undefined;
|
|
295
|
+
if (uc === 0x20) {
|
|
296
|
+
return { key: win32TextKey(s, 'space', ' '), repeat: 1 };
|
|
297
|
+
}
|
|
298
|
+
if (uc > 0x20 && !(uc >= 0x7f && uc <= 0x9f)) {
|
|
299
|
+
return { key: win32TextKey(s, String.fromCharCode(uc)), repeat: 1 };
|
|
300
|
+
}
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
// Every keydown settles a pending pair: a high half followed by anything
|
|
304
|
+
// but its low half is dropped, never combined across keys.
|
|
305
|
+
const highSurrogate = ctx.high;
|
|
306
|
+
ctx.high = undefined;
|
|
307
|
+
// The Alt+numpad pending high survives ONLY the synthesis stream's own
|
|
308
|
+
// filler records: a payload-free VK_MENU transition (the next round's
|
|
309
|
+
// Alt-down), or a payload-free numpad digit while Alt is held (Cs carries
|
|
310
|
+
// an Alt bit). Real Shift/Ctrl transitions and digits pressed without
|
|
311
|
+
// Alt are real input — they settle (drop) the pending high.
|
|
312
|
+
const altHeld = (cs & WIN32_CS_ALT) !== 0;
|
|
313
|
+
const isSynthesisFiller = (vk === 18 && uc === 0) || (vk >= 96 && vk <= 105 && uc === 0 && altHeld);
|
|
314
|
+
if (!isSynthesisFiller) {
|
|
315
|
+
ctx.altHigh = undefined;
|
|
316
|
+
}
|
|
317
|
+
// Bare modifier transitions: their state rides on the next real key's Cs.
|
|
318
|
+
if (WIN32_VK_MODIFIER.has(vk))
|
|
319
|
+
return null;
|
|
320
|
+
const shift = (cs & WIN32_CS_SHIFT) !== 0;
|
|
321
|
+
let ctrl = (cs & WIN32_CS_CTRL) !== 0;
|
|
322
|
+
let meta = (cs & WIN32_CS_ALT) !== 0;
|
|
323
|
+
const base = {
|
|
324
|
+
kind: 'key',
|
|
325
|
+
fn: false,
|
|
326
|
+
ctrl,
|
|
327
|
+
meta,
|
|
328
|
+
shift,
|
|
329
|
+
option: false,
|
|
330
|
+
super: false,
|
|
331
|
+
raw: s,
|
|
332
|
+
isPasted: false,
|
|
333
|
+
};
|
|
334
|
+
// Printable text comes through Uc, already shift/IME-composed by the
|
|
335
|
+
// console host — so it must win over the Vk name table: NumLock-on numpad
|
|
336
|
+
// keys legitimately carry the Ins/Del/Home/... cluster's Vk with the digit
|
|
337
|
+
// in Uc (tcell emits e.g. CSI 45;82;48;1;32;1_ for numpad 0), and only Uc
|
|
338
|
+
// (plus the ENHANCED_KEY bit, which text keys never set) tells them apart.
|
|
339
|
+
// "Printable" excludes C0, DEL and the C1 band (matching Windows
|
|
340
|
+
// Terminal's own codepoint > 0x20 && != 0x7f rule, extended over C1):
|
|
341
|
+
// Ctrl+8 / Ctrl+/ report Uc=0x7F and must reach the Ctrl recovery chain
|
|
342
|
+
// below.
|
|
343
|
+
let char;
|
|
344
|
+
if (uc >= 0xd800 && uc <= 0xdbff) {
|
|
345
|
+
ctx.high = uc;
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
if (uc >= 0xdc00 && uc <= 0xdfff) {
|
|
349
|
+
// Orphaned low half (no pending high): swallow immediately. Falling
|
|
350
|
+
// through to the Vk table would resurrect it as a named key — a stray
|
|
351
|
+
// CSI 32;57;56832;1;0;1_ must not become a Space.
|
|
352
|
+
if (highSurrogate === undefined)
|
|
353
|
+
return null;
|
|
354
|
+
char = String.fromCharCode(highSurrogate, uc);
|
|
355
|
+
}
|
|
356
|
+
else if (uc > 0x20 && !(uc >= 0x7f && uc <= 0x9f)) {
|
|
357
|
+
char = String.fromCharCode(uc);
|
|
358
|
+
}
|
|
359
|
+
// Space gets its own Vk-independent branch: spec-legal records omit Vk
|
|
360
|
+
// (CSI ;;32;1_) and Unicode-injected input arrives as VK_PACKET (231) —
|
|
361
|
+
// neither reaches the Vk=32 name entry below. Unlike graphic chars,
|
|
362
|
+
// space KEEPS ctrl/meta: Ctrl+Alt+Space is a binding, not AltGr text
|
|
363
|
+
// (input-event maps ctrl+space to ' ').
|
|
364
|
+
if (uc === 0x20) {
|
|
365
|
+
return { key: { ...base, name: 'space', sequence: ' ' }, repeat };
|
|
366
|
+
}
|
|
367
|
+
if (char !== undefined) {
|
|
368
|
+
// AltGr arrives as RightAlt + a synthesized LeftCtrl with the printable
|
|
369
|
+
// char in Uc — that's text input ('@', '€', '\', '|', braces on
|
|
370
|
+
// international layouts), not a Ctrl+Alt binding. Clearing the modifiers
|
|
371
|
+
// is required for the text to be insertable at all (PromptInput rejects
|
|
372
|
+
// input carrying ctrl/meta). Genuine Ctrl+Alt+<printable> bindings are
|
|
373
|
+
// indistinguishable from AltGr by Windows design.
|
|
374
|
+
if (ctrl && meta) {
|
|
375
|
+
ctrl = false;
|
|
376
|
+
meta = false;
|
|
377
|
+
}
|
|
378
|
+
return { key: { ...base, ctrl, meta, name: char, sequence: char }, repeat };
|
|
379
|
+
}
|
|
380
|
+
// Synthesized character records (conhost's SynthesizeKeyEvent: Vk=0,
|
|
381
|
+
// Sc=0, Cs=0) carry their entire payload in Uc — including the control
|
|
382
|
+
// chars that spell the bracketed-paste markers (ESC[200~ / ESC[201~).
|
|
383
|
+
// Map the editing-relevant ones to named keys so the decomposed-paste
|
|
384
|
+
// reassembler below can see the marker characters at all.
|
|
385
|
+
if (vk === 0) {
|
|
386
|
+
if (uc === 27)
|
|
387
|
+
return { key: { ...base, name: 'escape', sequence: s }, repeat };
|
|
388
|
+
if (uc === 13 || uc === 10)
|
|
389
|
+
return { key: { ...base, name: 'return', sequence: s }, repeat };
|
|
390
|
+
if (uc === 9)
|
|
391
|
+
return { key: { ...base, name: 'tab', sequence: s }, repeat };
|
|
392
|
+
if (uc === 8 || uc === 0x7f)
|
|
393
|
+
return { key: { ...base, name: 'backspace', sequence: s }, repeat };
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
// Non-printing keys by virtual-key code. sequence stays the raw record so
|
|
397
|
+
// input-event clears it via nonAlphanumericKeys ('space' isn't in that
|
|
398
|
+
// list — it needs the literal ' ' as sequence to reach text input).
|
|
399
|
+
const named = WIN32_VK_NAMES[vk];
|
|
400
|
+
if (named) {
|
|
401
|
+
return {
|
|
402
|
+
key: { ...base, name: named, sequence: named === 'space' ? ' ' : s },
|
|
403
|
+
repeat,
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
// Ctrl combos collapse Uc to a control code (Ctrl+C → 3, Ctrl+[ → 27,
|
|
407
|
+
// Ctrl+2 → 0). Recover the base key from Vk so the combination isn't
|
|
408
|
+
// swallowed: Ctrl+[ must stay usable as Escape (legacy VT parity — the
|
|
409
|
+
// \x1b byte), letters map to their name for bindings like Ctrl+C
|
|
410
|
+
// (exitOnCtrlC), punctuation via the OEM table.
|
|
411
|
+
if (ctrl) {
|
|
412
|
+
if (uc === 27) {
|
|
413
|
+
return { key: { ...base, name: 'escape', sequence: s }, repeat };
|
|
414
|
+
}
|
|
415
|
+
const baseChar = vk >= 65 && vk <= 90
|
|
416
|
+
? String.fromCharCode(vk + 32)
|
|
417
|
+
: vk >= 48 && vk <= 57
|
|
418
|
+
? String.fromCharCode(vk)
|
|
419
|
+
: WIN32_VK_OEM_CHARS[vk];
|
|
420
|
+
if (baseChar !== undefined) {
|
|
421
|
+
return { key: { ...base, name: baseChar, sequence: baseChar }, repeat };
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
// No usable payload (unmapped function key, dead key, Uc=0): swallow so
|
|
425
|
+
// the raw record can't leak into the prompt as text.
|
|
426
|
+
return null;
|
|
427
|
+
}
|
|
428
|
+
// Character spellings of CSI 200~ / CSI 201~ as key records: the ESC char
|
|
429
|
+
// arrives as a Vk=27 record (name 'escape'), the rest as text chars.
|
|
430
|
+
const WIN32_PASTE_START_CHARS = ['\x1b', '[', '2', '0', '0', '~'];
|
|
431
|
+
const WIN32_PASTE_END_CHARS = ['\x1b', '[', '2', '0', '1', '~'];
|
|
432
|
+
/**
|
|
433
|
+
* The text equivalent of a translated win32 key for paste purposes: chars
|
|
434
|
+
* map to themselves, named editing keys to their control char. Returns
|
|
435
|
+
* undefined for keys with no text meaning (arrows, F-keys).
|
|
436
|
+
*/
|
|
437
|
+
function win32RecordChar(key) {
|
|
438
|
+
switch (key.name) {
|
|
439
|
+
case 'escape':
|
|
440
|
+
return '\x1b';
|
|
441
|
+
case 'space':
|
|
442
|
+
return ' ';
|
|
443
|
+
case 'tab':
|
|
444
|
+
return '\t';
|
|
445
|
+
case 'return':
|
|
446
|
+
return '\n';
|
|
447
|
+
case 'backspace':
|
|
448
|
+
return '\x7f';
|
|
449
|
+
default:
|
|
450
|
+
// Text keys carry their char as BOTH name and sequence; named keys
|
|
451
|
+
// keep the raw CSI record as sequence. This avoids a UTF-16 length
|
|
452
|
+
// check — a supplementary-plane char (emoji, CJK ext-B) is a
|
|
453
|
+
// length-2 string but still text.
|
|
454
|
+
return key.sequence === key.name ? key.name : undefined;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Feed one translated win32 key through the decomposed-paste matcher.
|
|
459
|
+
* Returns the keys to emit (empty while holding a candidate prefix or
|
|
460
|
+
* collecting paste content).
|
|
461
|
+
*/
|
|
462
|
+
function feedWin32Paste(state, key) {
|
|
463
|
+
const pattern = state.active ? WIN32_PASTE_END_CHARS : WIN32_PASTE_START_CHARS;
|
|
464
|
+
// Marker chars never carry Ctrl/Alt in the synthesized stream; requiring
|
|
465
|
+
// this keeps a user's real Ctrl+[ from starting a phantom paste. Shift is
|
|
466
|
+
// allowed — '~' legitimately arrives with it.
|
|
467
|
+
const ch = key.ctrl || key.meta ? undefined : win32RecordChar(key);
|
|
468
|
+
if (ch !== undefined && ch === pattern[state.matched]) {
|
|
469
|
+
state.held.push(key);
|
|
470
|
+
state.matched++;
|
|
471
|
+
if (state.matched === pattern.length) {
|
|
472
|
+
state.matched = 0;
|
|
473
|
+
state.held = [];
|
|
474
|
+
if (!state.active) {
|
|
475
|
+
state.active = true;
|
|
476
|
+
state.buffer = '';
|
|
477
|
+
return [];
|
|
478
|
+
}
|
|
479
|
+
// End marker complete: the whole paste as a single event.
|
|
480
|
+
const paste = createPasteKey(state.buffer);
|
|
481
|
+
state.active = false;
|
|
482
|
+
state.buffer = '';
|
|
483
|
+
return [paste];
|
|
484
|
+
}
|
|
485
|
+
return [];
|
|
486
|
+
}
|
|
487
|
+
// Mismatch: release whatever prefix was held, then re-evaluate the
|
|
488
|
+
// current key from a clean match position (it may itself start a marker,
|
|
489
|
+
// e.g. ESC ESC [ 2 0 1 ~).
|
|
490
|
+
if (state.matched > 0) {
|
|
491
|
+
const held = state.held;
|
|
492
|
+
state.held = [];
|
|
493
|
+
state.matched = 0;
|
|
494
|
+
if (state.active) {
|
|
495
|
+
for (const k of held)
|
|
496
|
+
state.buffer += win32RecordChar(k) ?? '';
|
|
497
|
+
return feedWin32Paste(state, key);
|
|
498
|
+
}
|
|
499
|
+
return [...held, ...feedWin32Paste(state, key)];
|
|
500
|
+
}
|
|
501
|
+
if (state.active) {
|
|
502
|
+
state.buffer += win32RecordChar(key) ?? '';
|
|
503
|
+
return [];
|
|
504
|
+
}
|
|
505
|
+
return [key];
|
|
506
|
+
}
|
|
143
507
|
/** Initial `KeyParseState` for a fresh parser. */
|
|
144
508
|
export const INITIAL_STATE = {
|
|
145
509
|
mode: 'NORMAL',
|
|
@@ -185,6 +549,23 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
185
549
|
const keys = [];
|
|
186
550
|
let inPaste = prevState.mode === 'IN_PASTE';
|
|
187
551
|
let pasteBuffer = prevState.pasteBuffer;
|
|
552
|
+
// Surrogate-pair scratch for win32-input-mode records. Threaded through a
|
|
553
|
+
// local object so prevState is never mutated — App.tsx seeds the parser
|
|
554
|
+
// with the shared INITIAL_STATE singleton, and a pending high surrogate
|
|
555
|
+
// leaking into it would survive into fresh parser instances.
|
|
556
|
+
const win32Ctx = {
|
|
557
|
+
high: prevState.win32HighSurrogate,
|
|
558
|
+
altHigh: prevState.win32AltHighSurrogate,
|
|
559
|
+
};
|
|
560
|
+
// Decomposed-paste matcher state rides on a shared mutable object across
|
|
561
|
+
// calls (like _tokenizer). Fresh instances never touch INITIAL_STATE —
|
|
562
|
+
// the field stays undefined there and the object is created on demand.
|
|
563
|
+
const win32Paste = prevState.win32Paste ?? {
|
|
564
|
+
active: false,
|
|
565
|
+
matched: 0,
|
|
566
|
+
held: [],
|
|
567
|
+
buffer: '',
|
|
568
|
+
};
|
|
188
569
|
for (const token of tokens) {
|
|
189
570
|
if (token.type === 'sequence') {
|
|
190
571
|
if (token.value === PASTE_START) {
|
|
@@ -204,17 +585,33 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
204
585
|
pasteBuffer += token.value;
|
|
205
586
|
}
|
|
206
587
|
else {
|
|
207
|
-
const
|
|
208
|
-
if (
|
|
209
|
-
|
|
588
|
+
const win32 = parseWin32KeyEvent(token.value, win32Ctx);
|
|
589
|
+
if (win32 !== undefined) {
|
|
590
|
+
// win32-input-mode record. null means a swallowed event (keyup,
|
|
591
|
+
// bare modifier, orphaned surrogate) — the sequence is consumed
|
|
592
|
+
// either way and never reaches the VT keypress parser.
|
|
593
|
+
if (win32 !== null) {
|
|
594
|
+
// Keys pass through the decomposed-paste matcher: on classic
|
|
595
|
+
// conhost the bracketed-paste markers themselves arrive as key
|
|
596
|
+
// records and must be reassembled before dispatch.
|
|
597
|
+
for (let i = 0; i < win32.repeat; i++) {
|
|
598
|
+
keys.push(...feedWin32Paste(win32Paste, win32.key));
|
|
599
|
+
}
|
|
600
|
+
}
|
|
210
601
|
}
|
|
211
602
|
else {
|
|
212
|
-
const
|
|
213
|
-
if (
|
|
214
|
-
keys.push(
|
|
603
|
+
const response = parseTerminalResponse(token.value);
|
|
604
|
+
if (response) {
|
|
605
|
+
keys.push({ kind: 'response', sequence: token.value, response });
|
|
215
606
|
}
|
|
216
607
|
else {
|
|
217
|
-
|
|
608
|
+
const mouse = parseMouseEvent(token.value);
|
|
609
|
+
if (mouse) {
|
|
610
|
+
keys.push(mouse);
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
keys.push(parseKeypress(token.value));
|
|
614
|
+
}
|
|
218
615
|
}
|
|
219
616
|
}
|
|
220
617
|
}
|
|
@@ -251,11 +648,39 @@ export function parseMultipleKeypresses(prevState, input = '') {
|
|
|
251
648
|
inPaste = false;
|
|
252
649
|
pasteBuffer = '';
|
|
253
650
|
}
|
|
651
|
+
// Flush handling for the decomposed win32 paste: mid-paste (active) the
|
|
652
|
+
// 50ms quiet timer means the paste stream ended — finalize with whatever
|
|
653
|
+
// was collected (mirrors the VT IN_PASTE flush above; a truncated end
|
|
654
|
+
// marker must not strand the matcher and eat all future typing). Outside
|
|
655
|
+
// a paste, release any held marker-prefix keys (e.g. a lone Escape).
|
|
656
|
+
if (isFlush && win32Paste.active) {
|
|
657
|
+
let content = win32Paste.buffer;
|
|
658
|
+
for (const k of win32Paste.held)
|
|
659
|
+
content += win32RecordChar(k) ?? '';
|
|
660
|
+
keys.push(createPasteKey(content));
|
|
661
|
+
win32Paste.active = false;
|
|
662
|
+
win32Paste.buffer = '';
|
|
663
|
+
win32Paste.held = [];
|
|
664
|
+
win32Paste.matched = 0;
|
|
665
|
+
}
|
|
666
|
+
else if (isFlush && win32Paste.held.length > 0) {
|
|
667
|
+
keys.push(...win32Paste.held);
|
|
668
|
+
win32Paste.held = [];
|
|
669
|
+
win32Paste.matched = 0;
|
|
670
|
+
}
|
|
254
671
|
// Build new state
|
|
255
672
|
const newState = {
|
|
256
673
|
mode: inPaste ? 'IN_PASTE' : 'NORMAL',
|
|
257
|
-
incomplete
|
|
674
|
+
// App.tsx arms its flush timer whenever `incomplete` is non-empty. The
|
|
675
|
+
// tokenizer only reports raw bytes there, so paste-matcher holds (a
|
|
676
|
+
// marker prefix in flight, or an active paste) set a sentinel to get the
|
|
677
|
+
// same 50ms release — a lone Escape stays as responsive as in VT mode.
|
|
678
|
+
incomplete: tokenizer.buffer() ||
|
|
679
|
+
(win32Paste.held.length > 0 || win32Paste.active ? '\x1b' : ''),
|
|
258
680
|
pasteBuffer,
|
|
681
|
+
win32HighSurrogate: win32Ctx.high,
|
|
682
|
+
win32AltHighSurrogate: win32Ctx.altHigh,
|
|
683
|
+
win32Paste,
|
|
259
684
|
_tokenizer: tokenizer,
|
|
260
685
|
};
|
|
261
686
|
return [keys, newState];
|
|
@@ -603,6 +1028,15 @@ function parseKeypress(s = '') {
|
|
|
603
1028
|
key.raw = undefined;
|
|
604
1029
|
key.name = 'return';
|
|
605
1030
|
}
|
|
1031
|
+
else if (s === '\x1b\r' || s === '\x1b\n') {
|
|
1032
|
+
// Option+Enter on terminals without extended key reporting (Terminal.app,
|
|
1033
|
+
// default macOS terminal) sends ESC CR when "Use Option as Meta" is on —
|
|
1034
|
+
// the tokenizer passes CR through as text since it's not an ESC final
|
|
1035
|
+
// byte, so the pair arrives here as one chunk (issue #110).
|
|
1036
|
+
key.raw = undefined;
|
|
1037
|
+
key.name = 'return';
|
|
1038
|
+
key.meta = true;
|
|
1039
|
+
}
|
|
606
1040
|
else if (s === '\n') {
|
|
607
1041
|
key.name = 'enter';
|
|
608
1042
|
}
|