@aragon-agent/tui 0.0.0-stage → 0.0.1
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/CHANGELOG.md +27 -0
- package/LICENSE +21 -0
- package/README.md +81 -2
- package/dist/index.d.ts +11 -0
- package/dist/index.js +11 -0
- package/dist/input/control-sequences.d.ts +71 -0
- package/dist/input/control-sequences.js +222 -0
- package/dist/input/csiu-keys.d.ts +66 -0
- package/dist/input/csiu-keys.js +181 -0
- package/dist/input/cursor-report.d.ts +61 -0
- package/dist/input/cursor-report.js +97 -0
- package/dist/input/enter-sequences.d.ts +64 -0
- package/dist/input/enter-sequences.js +153 -0
- package/dist/input/interrupt-gesture.d.ts +18 -0
- package/dist/input/interrupt-gesture.js +19 -0
- package/dist/input/keyboard-enhancement.d.ts +42 -0
- package/dist/input/keyboard-enhancement.js +65 -0
- package/dist/input/keymap.d.ts +20 -0
- package/dist/input/keymap.js +99 -0
- package/dist/input/limits.d.ts +118 -0
- package/dist/input/limits.js +109 -0
- package/dist/input/mouse-events.d.ts +87 -0
- package/dist/input/mouse-events.js +212 -0
- package/dist/input/paste-parse.d.ts +83 -0
- package/dist/input/paste-parse.js +107 -0
- package/dist/input/pointer-router.d.ts +11 -0
- package/dist/input/pointer-router.js +14 -0
- package/dist/input/stdin-filter.d.ts +112 -0
- package/dist/input/stdin-filter.js +657 -0
- package/dist/input/win32-input-mode.d.ts +61 -0
- package/dist/input/win32-input-mode.js +269 -0
- package/dist/model/agent/agent-mode.d.ts +108 -0
- package/dist/model/agent/agent-mode.js +121 -0
- package/dist/model/agent/entry-limits.d.ts +65 -0
- package/dist/model/agent/entry-limits.js +133 -0
- package/dist/model/agent/governance-view.d.ts +40 -0
- package/dist/model/agent/governance-view.js +40 -0
- package/dist/model/agent/invocation-card.d.ts +77 -0
- package/dist/model/agent/invocation-card.js +169 -0
- package/dist/model/agent/model-probe-limits.d.ts +39 -0
- package/dist/model/agent/model-probe-limits.js +25 -0
- package/dist/model/agent/model-probe.d.ts +104 -0
- package/dist/model/agent/model-probe.js +391 -0
- package/dist/model/agent/queued-messages.d.ts +23 -0
- package/dist/model/agent/queued-messages.js +49 -0
- package/dist/model/agent/reducer.d.ts +857 -0
- package/dist/model/agent/reducer.js +1646 -0
- package/dist/model/agent/retry-view.d.ts +68 -0
- package/dist/model/agent/retry-view.js +95 -0
- package/dist/model/agent/usage.d.ts +47 -0
- package/dist/model/agent/usage.js +84 -0
- package/dist/model/compaction/limits.d.ts +61 -0
- package/dist/model/compaction/limits.js +64 -0
- package/dist/model/compaction/meter.d.ts +276 -0
- package/dist/model/compaction/meter.js +512 -0
- package/dist/model/compaction/pressure.d.ts +163 -0
- package/dist/model/compaction/pressure.js +199 -0
- package/dist/model/compaction/reason-text.d.ts +36 -0
- package/dist/model/compaction/reason-text.js +78 -0
- package/dist/model/compaction/types.d.ts +360 -0
- package/dist/model/compaction/types.js +22 -0
- package/dist/model/config/governance-config.d.ts +125 -0
- package/dist/model/config/governance-config.js +164 -0
- package/dist/model/config/kit-resolution.d.ts +93 -0
- package/dist/model/config/kit-resolution.js +226 -0
- package/dist/model/config/model-kits.d.ts +225 -0
- package/dist/model/config/model-kits.js +302 -0
- package/dist/model/config/model-profile-resolution.d.ts +28 -0
- package/dist/model/config/model-profile-resolution.js +88 -0
- package/dist/model/config/model-profiles.d.ts +103 -0
- package/dist/model/config/model-profiles.js +188 -0
- package/dist/model/config/model-settings-types.d.ts +71 -0
- package/dist/model/config/model-settings-types.js +18 -0
- package/dist/model/config/schema.d.ts +1645 -0
- package/dist/model/config/schema.js +1383 -0
- package/dist/model/fast/limits.d.ts +152 -0
- package/dist/model/fast/limits.js +152 -0
- package/dist/model/fast/resolve.d.ts +44 -0
- package/dist/model/fast/resolve.js +107 -0
- package/dist/model/fast/task-summary-types.d.ts +66 -0
- package/dist/model/fast/task-summary-types.js +17 -0
- package/dist/model/fast/types.d.ts +141 -0
- package/dist/model/fast/types.js +14 -0
- package/dist/model/governance/governed-dispatch.d.ts +19 -0
- package/dist/model/governance/governed-dispatch.js +17 -0
- package/dist/model/governance/limits.d.ts +107 -0
- package/dist/model/governance/limits.js +131 -0
- package/dist/model/governance/posture.d.ts +35 -0
- package/dist/model/governance/posture.js +59 -0
- package/dist/model/governance/rules/events-table.d.ts +46 -0
- package/dist/model/governance/rules/events-table.js +94 -0
- package/dist/model/governance/types.d.ts +661 -0
- package/dist/model/governance/types.js +27 -0
- package/dist/model/logging/levels.d.ts +40 -0
- package/dist/model/logging/levels.js +59 -0
- package/dist/model/logging/log-port.d.ts +38 -0
- package/dist/model/logging/log-port.js +41 -0
- package/dist/model/logging/secret-registry.d.ts +32 -0
- package/dist/model/logging/secret-registry.js +73 -0
- package/dist/model/proc/limits.d.ts +214 -0
- package/dist/model/proc/limits.js +221 -0
- package/dist/model/proc/progress.d.ts +47 -0
- package/dist/model/proc/progress.js +163 -0
- package/dist/model/proc/types.d.ts +269 -0
- package/dist/model/proc/types.js +15 -0
- package/dist/model/proc/wait-view.d.ts +65 -0
- package/dist/model/proc/wait-view.js +66 -0
- package/dist/model/prompts/copy.d.ts +89 -0
- package/dist/model/prompts/copy.js +131 -0
- package/dist/model/prompts/fill.d.ts +51 -0
- package/dist/model/prompts/fill.js +46 -0
- package/dist/model/prompts/limits.d.ts +53 -0
- package/dist/model/prompts/limits.js +53 -0
- package/dist/model/prompts/search.d.ts +58 -0
- package/dist/model/prompts/search.js +146 -0
- package/dist/model/prompts/types.d.ts +204 -0
- package/dist/model/prompts/types.js +13 -0
- package/dist/model/prompts/validate.d.ts +22 -0
- package/dist/model/prompts/validate.js +69 -0
- package/dist/model/team/activity.d.ts +67 -0
- package/dist/model/team/activity.js +130 -0
- package/dist/model/team/limits.d.ts +308 -0
- package/dist/model/team/limits.js +330 -0
- package/dist/model/team/model.d.ts +104 -0
- package/dist/model/team/model.js +150 -0
- package/dist/model/team/panel-rows.d.ts +48 -0
- package/dist/model/team/panel-rows.js +75 -0
- package/dist/model/team/timeline.d.ts +74 -0
- package/dist/model/team/timeline.js +101 -0
- package/dist/model/team/types.d.ts +354 -0
- package/dist/model/team/types.js +13 -0
- package/dist/model/todo/acceptance.d.ts +120 -0
- package/dist/model/todo/acceptance.js +399 -0
- package/dist/model/todo/follow-through.d.ts +138 -0
- package/dist/model/todo/follow-through.js +248 -0
- package/dist/model/todo/limits.d.ts +152 -0
- package/dist/model/todo/limits.js +152 -0
- package/dist/model/todo/panel-rows.d.ts +45 -0
- package/dist/model/todo/panel-rows.js +70 -0
- package/dist/model/todo/plan-sections.d.ts +60 -0
- package/dist/model/todo/plan-sections.js +108 -0
- package/dist/model/todo/row-window.d.ts +51 -0
- package/dist/model/todo/row-window.js +107 -0
- package/dist/model/todo/types.d.ts +124 -0
- package/dist/model/todo/types.js +12 -0
- package/dist/model/tools/human-input.d.ts +212 -0
- package/dist/model/tools/human-input.js +265 -0
- package/dist/model/tools/patch.d.ts +115 -0
- package/dist/model/tools/patch.js +453 -0
- package/dist/model/tools/terminal-output.d.ts +115 -0
- package/dist/model/tools/terminal-output.js +201 -0
- package/dist/model/tools/tool-output-store.d.ts +68 -0
- package/dist/model/tools/tool-output-store.js +102 -0
- package/dist/model/update/limits.d.ts +111 -0
- package/dist/model/update/limits.js +111 -0
- package/dist/model/update/semver.d.ts +89 -0
- package/dist/model/update/semver.js +295 -0
- package/dist/model/update/types.d.ts +169 -0
- package/dist/model/update/types.js +68 -0
- package/dist/testing/governance-fixtures.d.ts +13 -0
- package/dist/testing/governance-fixtures.js +98 -0
- package/dist/testing/mini-vt.d.ts +28 -0
- package/dist/testing/mini-vt.js +158 -0
- package/dist/testing/render-at-width.d.ts +16 -0
- package/dist/testing/render-at-width.js +57 -0
- package/dist/testing/terminal-harness.d.ts +15 -0
- package/dist/testing/terminal-harness.js +40 -0
- package/dist/testing/vt-screen.d.ts +28 -0
- package/dist/testing/vt-screen.js +139 -0
- package/dist/ui/ActivityLine.d.ts +26 -0
- package/dist/ui/ActivityLine.js +51 -0
- package/dist/ui/AutocompletePopup.d.ts +23 -0
- package/dist/ui/AutocompletePopup.js +17 -0
- package/dist/ui/BottomStatusRow.d.ts +10 -0
- package/dist/ui/BottomStatusRow.js +9 -0
- package/dist/ui/Composer.d.ts +115 -0
- package/dist/ui/Composer.js +64 -0
- package/dist/ui/GovernancePanel.d.ts +50 -0
- package/dist/ui/GovernancePanel.js +77 -0
- package/dist/ui/GovernanceRun.d.ts +18 -0
- package/dist/ui/GovernanceRun.js +11 -0
- package/dist/ui/Header.d.ts +48 -0
- package/dist/ui/Header.js +27 -0
- package/dist/ui/Logo.d.ts +32 -0
- package/dist/ui/Logo.js +65 -0
- package/dist/ui/Markdown.d.ts +29 -0
- package/dist/ui/Markdown.js +116 -0
- package/dist/ui/PromptCaret.d.ts +11 -0
- package/dist/ui/PromptCaret.js +31 -0
- package/dist/ui/PromptInput.d.ts +192 -0
- package/dist/ui/PromptInput.js +689 -0
- package/dist/ui/QueuePanel.d.ts +8 -0
- package/dist/ui/QueuePanel.js +9 -0
- package/dist/ui/QueueStatusRow.d.ts +24 -0
- package/dist/ui/QueueStatusRow.js +51 -0
- package/dist/ui/ScrollbackShell.d.ts +132 -0
- package/dist/ui/ScrollbackShell.js +26 -0
- package/dist/ui/SessionOpener.d.ts +30 -0
- package/dist/ui/SessionOpener.js +12 -0
- package/dist/ui/StatusBar.d.ts +130 -0
- package/dist/ui/StatusBar.js +61 -0
- package/dist/ui/TeamPanel.d.ts +76 -0
- package/dist/ui/TeamPanel.js +103 -0
- package/dist/ui/ToastStack.d.ts +8 -0
- package/dist/ui/ToastStack.js +31 -0
- package/dist/ui/TodoPanel.d.ts +52 -0
- package/dist/ui/TodoPanel.js +214 -0
- package/dist/ui/Transcript.d.ts +105 -0
- package/dist/ui/Transcript.js +258 -0
- package/dist/ui/UpdateLine.d.ts +44 -0
- package/dist/ui/UpdateLine.js +129 -0
- package/dist/ui/activity-phrases.d.ts +33 -0
- package/dist/ui/activity-phrases.js +50 -0
- package/dist/ui/capabilities.d.ts +27 -0
- package/dist/ui/capabilities.js +65 -0
- package/dist/ui/clipboard-task.d.ts +29 -0
- package/dist/ui/clipboard-task.js +66 -0
- package/dist/ui/clipboard.d.ts +31 -0
- package/dist/ui/clipboard.js +157 -0
- package/dist/ui/color-runtime.d.ts +5 -0
- package/dist/ui/color-runtime.js +29 -0
- package/dist/ui/composer-input.d.ts +38 -0
- package/dist/ui/composer-input.js +79 -0
- package/dist/ui/composer-limits.d.ts +30 -0
- package/dist/ui/composer-limits.js +45 -0
- package/dist/ui/composer-rows.d.ts +73 -0
- package/dist/ui/composer-rows.js +129 -0
- package/dist/ui/console-bridge.d.ts +19 -0
- package/dist/ui/console-bridge.js +52 -0
- package/dist/ui/density.d.ts +26 -0
- package/dist/ui/density.js +34 -0
- package/dist/ui/display-tab.d.ts +51 -0
- package/dist/ui/display-tab.js +82 -0
- package/dist/ui/editor-navigation.d.ts +55 -0
- package/dist/ui/editor-navigation.js +96 -0
- package/dist/ui/editor-reducer.d.ts +108 -0
- package/dist/ui/editor-reducer.js +187 -0
- package/dist/ui/enter-frames.d.ts +47 -0
- package/dist/ui/enter-frames.js +117 -0
- package/dist/ui/entries/AssistantEntry.d.ts +37 -0
- package/dist/ui/entries/AssistantEntry.js +43 -0
- package/dist/ui/entries/CompactionCard.d.ts +88 -0
- package/dist/ui/entries/CompactionCard.js +222 -0
- package/dist/ui/entries/DiffView.d.ts +61 -0
- package/dist/ui/entries/DiffView.js +103 -0
- package/dist/ui/entries/EntryFrame.d.ts +23 -0
- package/dist/ui/entries/EntryFrame.js +6 -0
- package/dist/ui/entries/FastCard.d.ts +53 -0
- package/dist/ui/entries/FastCard.js +105 -0
- package/dist/ui/entries/GovernanceCard.d.ts +30 -0
- package/dist/ui/entries/GovernanceCard.js +32 -0
- package/dist/ui/entries/InvocationCard.d.ts +20 -0
- package/dist/ui/entries/InvocationCard.js +32 -0
- package/dist/ui/entries/QueuedEntry.d.ts +27 -0
- package/dist/ui/entries/QueuedEntry.js +33 -0
- package/dist/ui/entries/RetryCard.d.ts +56 -0
- package/dist/ui/entries/RetryCard.js +60 -0
- package/dist/ui/entries/ServiceCard.d.ts +82 -0
- package/dist/ui/entries/ServiceCard.js +151 -0
- package/dist/ui/entries/TeamCard.d.ts +55 -0
- package/dist/ui/entries/TeamCard.js +94 -0
- package/dist/ui/entries/TodoCard.d.ts +54 -0
- package/dist/ui/entries/TodoCard.js +98 -0
- package/dist/ui/entries/ToolCard.d.ts +81 -0
- package/dist/ui/entries/ToolCard.js +169 -0
- package/dist/ui/entries/ToolPreview.d.ts +59 -0
- package/dist/ui/entries/ToolPreview.js +208 -0
- package/dist/ui/entries/UserEntry.d.ts +36 -0
- package/dist/ui/entries/UserEntry.js +57 -0
- package/dist/ui/entries/WaitCard.d.ts +37 -0
- package/dist/ui/entries/WaitCard.js +92 -0
- package/dist/ui/exit-snapshot.d.ts +43 -0
- package/dist/ui/exit-snapshot.js +26 -0
- package/dist/ui/frame-differ.d.ts +166 -0
- package/dist/ui/frame-differ.js +354 -0
- package/dist/ui/frame-observer.d.ts +17 -0
- package/dist/ui/frame-observer.js +94 -0
- package/dist/ui/frame-parser.d.ts +7 -0
- package/dist/ui/frame-parser.js +18 -0
- package/dist/ui/gauge.d.ts +39 -0
- package/dist/ui/gauge.js +55 -0
- package/dist/ui/glyphs.d.ts +178 -0
- package/dist/ui/glyphs.js +165 -0
- package/dist/ui/governance-copy.d.ts +69 -0
- package/dist/ui/governance-copy.js +104 -0
- package/dist/ui/governance-status.d.ts +145 -0
- package/dist/ui/governance-status.js +326 -0
- package/dist/ui/gradient.d.ts +11 -0
- package/dist/ui/gradient.js +50 -0
- package/dist/ui/ink-runtime.d.ts +4 -0
- package/dist/ui/ink-runtime.js +51 -0
- package/dist/ui/interaction-copy.d.ts +84 -0
- package/dist/ui/interaction-copy.js +41 -0
- package/dist/ui/interaction-hints.d.ts +44 -0
- package/dist/ui/interaction-hints.js +97 -0
- package/dist/ui/layout/AppShell.d.ts +17 -0
- package/dist/ui/layout/AppShell.js +6 -0
- package/dist/ui/layout/Gutter.d.ts +67 -0
- package/dist/ui/layout/Gutter.js +42 -0
- package/dist/ui/layout/MeasuredEntry.d.ts +21 -0
- package/dist/ui/layout/MeasuredEntry.js +30 -0
- package/dist/ui/layout/OverlayFrame.d.ts +73 -0
- package/dist/ui/layout/OverlayFrame.js +110 -0
- package/dist/ui/layout/ScrollIndicator.d.ts +32 -0
- package/dist/ui/layout/ScrollIndicator.js +22 -0
- package/dist/ui/layout/ScrollViewport.d.ts +40 -0
- package/dist/ui/layout/ScrollViewport.js +222 -0
- package/dist/ui/layout/agents-board.d.ts +102 -0
- package/dist/ui/layout/agents-board.js +389 -0
- package/dist/ui/layout/autocomplete.d.ts +18 -0
- package/dist/ui/layout/autocomplete.js +26 -0
- package/dist/ui/layout/budget.d.ts +43 -0
- package/dist/ui/layout/budget.js +52 -0
- package/dist/ui/layout/cells.d.ts +61 -0
- package/dist/ui/layout/cells.js +156 -0
- package/dist/ui/layout/document-layout.d.ts +13 -0
- package/dist/ui/layout/document-layout.js +10 -0
- package/dist/ui/layout/follow-state.d.ts +138 -0
- package/dist/ui/layout/follow-state.js +148 -0
- package/dist/ui/layout/frame.d.ts +36 -0
- package/dist/ui/layout/frame.js +39 -0
- package/dist/ui/layout/governance-board.d.ts +121 -0
- package/dist/ui/layout/governance-board.js +382 -0
- package/dist/ui/layout/governance-card.d.ts +53 -0
- package/dist/ui/layout/governance-card.js +134 -0
- package/dist/ui/layout/governance-chip.d.ts +38 -0
- package/dist/ui/layout/governance-chip.js +64 -0
- package/dist/ui/layout/governance-panel.d.ts +85 -0
- package/dist/ui/layout/governance-panel.js +358 -0
- package/dist/ui/layout/governance-roster.d.ts +65 -0
- package/dist/ui/layout/governance-roster.js +275 -0
- package/dist/ui/layout/header-hints.d.ts +90 -0
- package/dist/ui/layout/header-hints.js +110 -0
- package/dist/ui/layout/header-left.d.ts +115 -0
- package/dist/ui/layout/header-left.js +206 -0
- package/dist/ui/layout/invocation-card.d.ts +41 -0
- package/dist/ui/layout/invocation-card.js +91 -0
- package/dist/ui/layout/kit-chip.d.ts +50 -0
- package/dist/ui/layout/kit-chip.js +81 -0
- package/dist/ui/layout/overlay-window.d.ts +43 -0
- package/dist/ui/layout/overlay-window.js +51 -0
- package/dist/ui/layout/queue-layout.d.ts +19 -0
- package/dist/ui/layout/queue-layout.js +26 -0
- package/dist/ui/layout/rail.d.ts +7 -0
- package/dist/ui/layout/rail.js +16 -0
- package/dist/ui/layout/scroll-indicator.d.ts +27 -0
- package/dist/ui/layout/scroll-indicator.js +36 -0
- package/dist/ui/layout/scroll.d.ts +37 -0
- package/dist/ui/layout/scroll.js +99 -0
- package/dist/ui/layout/scrollbar-geometry.d.ts +17 -0
- package/dist/ui/layout/scrollbar-geometry.js +13 -0
- package/dist/ui/layout/session-chip.d.ts +52 -0
- package/dist/ui/layout/session-chip.js +64 -0
- package/dist/ui/layout/shortcut-panel-layout.d.ts +191 -0
- package/dist/ui/layout/shortcut-panel-layout.js +321 -0
- package/dist/ui/layout/status-detail-layout.d.ts +9 -0
- package/dist/ui/layout/status-detail-layout.js +79 -0
- package/dist/ui/layout/status-layout.d.ts +140 -0
- package/dist/ui/layout/status-layout.js +262 -0
- package/dist/ui/layout/task-summary-cell.d.ts +61 -0
- package/dist/ui/layout/task-summary-cell.js +65 -0
- package/dist/ui/layout/team-panel.d.ts +18 -0
- package/dist/ui/layout/team-panel.js +25 -0
- package/dist/ui/layout/team-row.d.ts +139 -0
- package/dist/ui/layout/team-row.js +246 -0
- package/dist/ui/layout/todo-layout.d.ts +62 -0
- package/dist/ui/layout/todo-layout.js +102 -0
- package/dist/ui/layout/useTerminalSize.d.ts +13 -0
- package/dist/ui/layout/useTerminalSize.js +50 -0
- package/dist/ui/layout/viewport-geometry.d.ts +29 -0
- package/dist/ui/layout/viewport-geometry.js +28 -0
- package/dist/ui/layout/virtual-window.d.ts +112 -0
- package/dist/ui/layout/virtual-window.js +494 -0
- package/dist/ui/layout/wait-bar.d.ts +34 -0
- package/dist/ui/layout/wait-bar.js +48 -0
- package/dist/ui/layout/wrap-rows.d.ts +26 -0
- package/dist/ui/layout/wrap-rows.js +88 -0
- package/dist/ui/live-clamp.d.ts +14 -0
- package/dist/ui/live-clamp.js +46 -0
- package/dist/ui/markdown-blocks.d.ts +107 -0
- package/dist/ui/markdown-blocks.js +240 -0
- package/dist/ui/overlays/AgentsBoardOverlay.d.ts +57 -0
- package/dist/ui/overlays/AgentsBoardOverlay.js +183 -0
- package/dist/ui/overlays/ConfirmDialog.d.ts +31 -0
- package/dist/ui/overlays/ConfirmDialog.js +44 -0
- package/dist/ui/overlays/GovernanceBoardOverlay.d.ts +41 -0
- package/dist/ui/overlays/GovernanceBoardOverlay.js +76 -0
- package/dist/ui/overlays/GovernanceSettingsPage.d.ts +48 -0
- package/dist/ui/overlays/GovernanceSettingsPage.js +93 -0
- package/dist/ui/overlays/HelpOverlay.d.ts +29 -0
- package/dist/ui/overlays/HelpOverlay.js +232 -0
- package/dist/ui/overlays/KitEditor.d.ts +23 -0
- package/dist/ui/overlays/KitEditor.js +101 -0
- package/dist/ui/overlays/KitManager.d.ts +23 -0
- package/dist/ui/overlays/KitManager.js +104 -0
- package/dist/ui/overlays/KitPicker.d.ts +49 -0
- package/dist/ui/overlays/KitPicker.js +58 -0
- package/dist/ui/overlays/ModelDiscoveryList.d.ts +23 -0
- package/dist/ui/overlays/ModelDiscoveryList.js +161 -0
- package/dist/ui/overlays/ModelPicker.d.ts +26 -0
- package/dist/ui/overlays/ModelPicker.js +63 -0
- package/dist/ui/overlays/ModelProfileEditor.d.ts +29 -0
- package/dist/ui/overlays/ModelProfileEditor.js +168 -0
- package/dist/ui/overlays/ModelProfilePicker.d.ts +48 -0
- package/dist/ui/overlays/ModelProfilePicker.js +231 -0
- package/dist/ui/overlays/PlanReviewOverlay.d.ts +51 -0
- package/dist/ui/overlays/PlanReviewOverlay.js +132 -0
- package/dist/ui/overlays/PromptEditorPage.d.ts +48 -0
- package/dist/ui/overlays/PromptEditorPage.js +227 -0
- package/dist/ui/overlays/PromptLibraryOverlay.d.ts +37 -0
- package/dist/ui/overlays/PromptLibraryOverlay.js +191 -0
- package/dist/ui/overlays/PromptPicker.d.ts +36 -0
- package/dist/ui/overlays/PromptPicker.js +129 -0
- package/dist/ui/overlays/PromptTextArea.d.ts +86 -0
- package/dist/ui/overlays/PromptTextArea.js +141 -0
- package/dist/ui/overlays/QuestionOverlay.d.ts +39 -0
- package/dist/ui/overlays/QuestionOverlay.js +258 -0
- package/dist/ui/overlays/QueueOverlay.d.ts +22 -0
- package/dist/ui/overlays/QueueOverlay.js +79 -0
- package/dist/ui/overlays/SettingsScreen.d.ts +228 -0
- package/dist/ui/overlays/SettingsScreen.js +1037 -0
- package/dist/ui/overlays/ShortcutPanel.d.ts +39 -0
- package/dist/ui/overlays/ShortcutPanel.js +106 -0
- package/dist/ui/overlays/TeamFanoutPage.d.ts +51 -0
- package/dist/ui/overlays/TeamFanoutPage.js +90 -0
- package/dist/ui/overlays/governance-settings.d.ts +79 -0
- package/dist/ui/overlays/governance-settings.js +140 -0
- package/dist/ui/overlays/kit-picker-state.d.ts +87 -0
- package/dist/ui/overlays/kit-picker-state.js +136 -0
- package/dist/ui/overlays/kit-settings-state.d.ts +129 -0
- package/dist/ui/overlays/kit-settings-state.js +268 -0
- package/dist/ui/overlays/model-probe-view.d.ts +128 -0
- package/dist/ui/overlays/model-probe-view.js +225 -0
- package/dist/ui/overlays/model-profile-state.d.ts +177 -0
- package/dist/ui/overlays/model-profile-state.js +301 -0
- package/dist/ui/overlays/prompt-library-state.d.ts +162 -0
- package/dist/ui/overlays/prompt-library-state.js +335 -0
- package/dist/ui/overlays/prompt-picker-state.d.ts +71 -0
- package/dist/ui/overlays/prompt-picker-state.js +98 -0
- package/dist/ui/overlays/team-fanout-state.d.ts +106 -0
- package/dist/ui/overlays/team-fanout-state.js +155 -0
- package/dist/ui/overlays/use-model-probe.d.ts +30 -0
- package/dist/ui/overlays/use-model-probe.js +109 -0
- package/dist/ui/palettes.d.ts +112 -0
- package/dist/ui/palettes.js +130 -0
- package/dist/ui/paste-frames.d.ts +91 -0
- package/dist/ui/paste-frames.js +117 -0
- package/dist/ui/paste-tokens.d.ts +90 -0
- package/dist/ui/paste-tokens.js +147 -0
- package/dist/ui/render-cache.d.ts +81 -0
- package/dist/ui/render-cache.js +196 -0
- package/dist/ui/render-governor.d.ts +54 -0
- package/dist/ui/render-governor.js +78 -0
- package/dist/ui/run-metrics.d.ts +23 -0
- package/dist/ui/run-metrics.js +27 -0
- package/dist/ui/run-status-row.d.ts +63 -0
- package/dist/ui/run-status-row.js +54 -0
- package/dist/ui/screen.d.ts +107 -0
- package/dist/ui/screen.js +234 -0
- package/dist/ui/scrollback/LiveTail.d.ts +115 -0
- package/dist/ui/scrollback/LiveTail.js +48 -0
- package/dist/ui/scrollback/band.d.ts +114 -0
- package/dist/ui/scrollback/band.js +143 -0
- package/dist/ui/scrollback/budget.d.ts +90 -0
- package/dist/ui/scrollback/budget.js +100 -0
- package/dist/ui/scrollback/canvas.d.ts +100 -0
- package/dist/ui/scrollback/canvas.js +114 -0
- package/dist/ui/scrollback/cursor-probe.d.ts +71 -0
- package/dist/ui/scrollback/cursor-probe.js +133 -0
- package/dist/ui/scrollback/drain.d.ts +32 -0
- package/dist/ui/scrollback/drain.js +64 -0
- package/dist/ui/scrollback/exit-summary.d.ts +23 -0
- package/dist/ui/scrollback/exit-summary.js +25 -0
- package/dist/ui/scrollback/limits.d.ts +98 -0
- package/dist/ui/scrollback/limits.js +98 -0
- package/dist/ui/scrollback/live-preview.d.ts +34 -0
- package/dist/ui/scrollback/live-preview.js +130 -0
- package/dist/ui/scrollback/overflow-print.d.ts +108 -0
- package/dist/ui/scrollback/overflow-print.js +120 -0
- package/dist/ui/scrollback/renderer.d.ts +48 -0
- package/dist/ui/scrollback/renderer.js +186 -0
- package/dist/ui/scrollback/scrollback-writer.d.ts +174 -0
- package/dist/ui/scrollback/scrollback-writer.js +648 -0
- package/dist/ui/scrollback/settled-boundary.d.ts +42 -0
- package/dist/ui/scrollback/settled-boundary.js +109 -0
- package/dist/ui/scrollback/tail-anchor.d.ts +71 -0
- package/dist/ui/scrollback/tail-anchor.js +79 -0
- package/dist/ui/scrollback/tail-window.d.ts +73 -0
- package/dist/ui/scrollback/tail-window.js +89 -0
- package/dist/ui/scrollback/use-scrollback-view.d.ts +139 -0
- package/dist/ui/scrollback/use-scrollback-view.js +601 -0
- package/dist/ui/scrollback/writer-shapes.d.ts +127 -0
- package/dist/ui/scrollback/writer-shapes.js +159 -0
- package/dist/ui/scrollbar-controller.d.ts +30 -0
- package/dist/ui/scrollbar-controller.js +124 -0
- package/dist/ui/selection/highlight.d.ts +39 -0
- package/dist/ui/selection/highlight.js +64 -0
- package/dist/ui/selection/screen-mirror.d.ts +24 -0
- package/dist/ui/selection/screen-mirror.js +35 -0
- package/dist/ui/selection/selection-controller.d.ts +104 -0
- package/dist/ui/selection/selection-controller.js +372 -0
- package/dist/ui/selection/selection.d.ts +90 -0
- package/dist/ui/selection/selection.js +223 -0
- package/dist/ui/shortcuts.d.ts +81 -0
- package/dist/ui/shortcuts.js +221 -0
- package/dist/ui/status-feedback.d.ts +35 -0
- package/dist/ui/status-feedback.js +38 -0
- package/dist/ui/stdout-frame-writer.d.ts +74 -0
- package/dist/ui/stdout-frame-writer.js +155 -0
- package/dist/ui/team-status.d.ts +166 -0
- package/dist/ui/team-status.js +252 -0
- package/dist/ui/terminal-plan.d.ts +52 -0
- package/dist/ui/terminal-plan.js +49 -0
- package/dist/ui/theme.d.ts +96 -0
- package/dist/ui/theme.js +130 -0
- package/dist/ui/transcript-text.d.ts +41 -0
- package/dist/ui/transcript-text.js +282 -0
- package/dist/ui/use-height-store.d.ts +31 -0
- package/dist/ui/use-height-store.js +76 -0
- package/dist/ui/use-render-governor.d.ts +39 -0
- package/dist/ui/use-render-governor.js +57 -0
- package/dist/ui/use-wheel-routing.d.ts +57 -0
- package/dist/ui/use-wheel-routing.js +152 -0
- package/dist/ui/win-vt-force.d.ts +136 -0
- package/dist/ui/win-vt-force.js +237 -0
- package/dist/ui/win-vt-input.d.ts +57 -0
- package/dist/ui/win-vt-input.js +62 -0
- package/package.json +86 -4
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSI-u key translation (posix keyboard-enhancement section of the Shift+Enter
|
|
3
|
+
* newline fix).
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS EXISTS. On macOS/Linux the only lever that makes Shift+Enter
|
|
6
|
+
* distinguishable from Enter is asking the terminal to report modified keys in
|
|
7
|
+
* the CSI-u encoding: kitty's disambiguate mode (`CSI > 1 u`, pushed and popped
|
|
8
|
+
* with `CSI < u`) and xterm's `modifyOtherKeys=2` (`CSI > 4 ; 2 m`, reset with
|
|
9
|
+
* `CSI > 4 m`). iTerm2, kitty, ghostty, WezTerm, foot and Alacritty implement
|
|
10
|
+
* at least one of the two; a terminal implementing neither ignores both bytes,
|
|
11
|
+
* which the conhost probe confirmed is a harmless no-op.
|
|
12
|
+
*
|
|
13
|
+
* WHAT CHANGES IN THE STREAM -- AND WHAT NEVER DOES. Both modes re-encode only
|
|
14
|
+
* keys whose legacy encoding is ambiguous: Ctrl/Ctrl+Shift/Ctrl+Alt+letters and
|
|
15
|
+
* digits, the Enter family, the Escape key (kitty), and Backspace with
|
|
16
|
+
* modifiers. `modifyOtherKeys` is named for the OTHER keys: arrows, Home/End,
|
|
17
|
+
* PgUp/PgDn and F-keys keep their standard `\x1b[1;mA` / `\x1b[m~` encodings,
|
|
18
|
+
* and Shift+printable still types text. So the translator below only ever sees
|
|
19
|
+
* codepoints below 128 plus a few named control codes; anything else (a kitty
|
|
20
|
+
* functional-key code from a mode this app never pushes) passes through
|
|
21
|
+
* untouched, which is exactly the pre-enhancement behaviour.
|
|
22
|
+
*
|
|
23
|
+
* THE CONTRACT mirrors `win32-input-mode.ts`: split, translate back to the
|
|
24
|
+
* legacy bytes, with the modified-Enter family becoming `ENTER_NEWLINE_FRAME`.
|
|
25
|
+
* Pure: no node/React imports.
|
|
26
|
+
*/
|
|
27
|
+
import { ENTER_NEWLINE_FRAME, INDEX_KEY_FRAME } from './limits.js';
|
|
28
|
+
/** Enable / disable the two CSI-u report modes (posix side). */
|
|
29
|
+
export const CSI_U_ENABLE = '\x1b[>1u\x1b[>4;2m';
|
|
30
|
+
export const CSI_U_DISABLE = '\x1b[<u\x1b[>4m';
|
|
31
|
+
const isParamChar = (c) => (c >= '0' && c <= '9') || c === ';' || c === ':';
|
|
32
|
+
/**
|
|
33
|
+
* Split a chunk into text spans and CSI-u sequences.
|
|
34
|
+
*
|
|
35
|
+
* Grammar accepted: `ESC [ <params> u` where params are digits, `;` and `:`
|
|
36
|
+
* only, and at least one field exists. `\x1b[13;2u` is INCLUDED: with
|
|
37
|
+
* enhancement on, this module owns every `u`-terminated sequence and applies
|
|
38
|
+
* the same Enter semantics `enter-sequences.ts` defines.
|
|
39
|
+
*/
|
|
40
|
+
export function splitCsiUKeys(text) {
|
|
41
|
+
const segments = [];
|
|
42
|
+
let start = 0;
|
|
43
|
+
let index = 0;
|
|
44
|
+
while (index < text.length) {
|
|
45
|
+
if (text[index] !== '\x1b' || text[index + 1] !== '[') {
|
|
46
|
+
index += 1;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
let end = index + 2;
|
|
50
|
+
while (end < text.length && isParamChar(text[end]))
|
|
51
|
+
end += 1;
|
|
52
|
+
if (end >= text.length || text[end] !== 'u') {
|
|
53
|
+
index += 1;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const key = parseKey(text.slice(index + 2, end), text.slice(index, end + 1));
|
|
57
|
+
if (!key) {
|
|
58
|
+
index += 1;
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (index > start)
|
|
62
|
+
segments.push({ kind: 'text', text: text.slice(start, index) });
|
|
63
|
+
segments.push({ kind: 'key', key });
|
|
64
|
+
index = end + 1;
|
|
65
|
+
start = index;
|
|
66
|
+
}
|
|
67
|
+
if (start < text.length)
|
|
68
|
+
segments.push({ kind: 'text', text: text.slice(start) });
|
|
69
|
+
return segments;
|
|
70
|
+
}
|
|
71
|
+
/** Parse the parameter body of a CSI-u sequence, or null when malformed. */
|
|
72
|
+
function parseKey(body, seq) {
|
|
73
|
+
if (body.length === 0)
|
|
74
|
+
return null;
|
|
75
|
+
const fields = body.split(';');
|
|
76
|
+
const keyParts = fields[0]?.split(':').map(Number) ?? [];
|
|
77
|
+
if (keyParts.some((n) => !Number.isInteger(n) || n < 0 || n > 0x10ffff))
|
|
78
|
+
return null;
|
|
79
|
+
const code = keyParts[0];
|
|
80
|
+
if (code === undefined)
|
|
81
|
+
return null;
|
|
82
|
+
let mods = 0;
|
|
83
|
+
if (fields.length > 1) {
|
|
84
|
+
const modParts = fields[1]?.split(':').map(Number) ?? [];
|
|
85
|
+
if (modParts.some((n) => !Number.isInteger(n) || n < 0 || n > 64))
|
|
86
|
+
return null;
|
|
87
|
+
const m = modParts[0] ?? 0;
|
|
88
|
+
mods = Math.max(0, m - 1);
|
|
89
|
+
}
|
|
90
|
+
return { seq, code, alternates: keyParts.slice(1), mods };
|
|
91
|
+
}
|
|
92
|
+
/** Control code for Ctrl+letter (a-z -> 1-26), or the char itself. */
|
|
93
|
+
function ctrlByte(char) {
|
|
94
|
+
if (char >= 97 && char <= 122)
|
|
95
|
+
return char - 96;
|
|
96
|
+
if (char >= 65 && char <= 90)
|
|
97
|
+
return char - 64;
|
|
98
|
+
return char;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Translate one CSI-u sequence to the legacy bytes the same keypress would
|
|
102
|
+
* have produced without the report modes (Enter family excepted: a modified
|
|
103
|
+
* Enter becomes the newline frame). Unknown keys pass through unchanged.
|
|
104
|
+
*/
|
|
105
|
+
export function translateCsiUKey(key) {
|
|
106
|
+
const m = key.mods;
|
|
107
|
+
const ctrl = (m & 4) !== 0;
|
|
108
|
+
const alt = (m & 2) !== 0;
|
|
109
|
+
const shift = (m & 1) !== 0;
|
|
110
|
+
if (key.code === 13)
|
|
111
|
+
return m === 0 ? '\r' : ENTER_NEWLINE_FRAME;
|
|
112
|
+
if (key.code === 27)
|
|
113
|
+
return alt ? '\x1b\x1b' : '\x1b';
|
|
114
|
+
if (key.code === 9) {
|
|
115
|
+
// A modified Tab codepoint (modifyOtherKeys shape) mirrors the VK_TAB
|
|
116
|
+
// decision in win32-input-mode.ts: ctrl (without shift/alt) is the
|
|
117
|
+
// project-indexer trigger frame, shift stays Shift+Tab.
|
|
118
|
+
if (ctrl && !shift && !alt)
|
|
119
|
+
return INDEX_KEY_FRAME;
|
|
120
|
+
return shift ? '\x1b[Z' : '\t';
|
|
121
|
+
}
|
|
122
|
+
// Ctrl+I under kitty disambiguate arrives as codepoint 105 with the ctrl
|
|
123
|
+
// modifier; the generic printable branch below would fold it back onto the
|
|
124
|
+
// legacy Tab byte, which is exactly the ambiguity the frame exists to break.
|
|
125
|
+
if (key.code === 105 && ctrl && !shift && !alt)
|
|
126
|
+
return INDEX_KEY_FRAME;
|
|
127
|
+
if (key.code === 127) {
|
|
128
|
+
// POST-normalisation bytes, same rationale as VK_BACK in win32-input-mode.
|
|
129
|
+
if (alt)
|
|
130
|
+
return '\x1b\x08';
|
|
131
|
+
return '\x08';
|
|
132
|
+
}
|
|
133
|
+
if (key.code === 32) {
|
|
134
|
+
// Ctrl+Space is 0x00 in legacy xterm; plain/alt space is the character.
|
|
135
|
+
if (ctrl)
|
|
136
|
+
return alt ? '\x1b\x00' : '\x00';
|
|
137
|
+
return alt ? '\x1b ' : ' ';
|
|
138
|
+
}
|
|
139
|
+
if (key.code >= 32 && key.code <= 126) {
|
|
140
|
+
const char = String.fromCharCode(key.code);
|
|
141
|
+
if (ctrl) {
|
|
142
|
+
const code = ctrlByte(key.code);
|
|
143
|
+
const text = code === key.code ? char : String.fromCharCode(code);
|
|
144
|
+
return alt ? `\x1b${text}` : text;
|
|
145
|
+
}
|
|
146
|
+
if (alt)
|
|
147
|
+
return `\x1b${char}`;
|
|
148
|
+
if (shift && key.alternates.length > 0) {
|
|
149
|
+
const shifted = key.alternates[0];
|
|
150
|
+
if (shifted !== undefined && shifted > 0)
|
|
151
|
+
return String.fromCodePoint(shifted);
|
|
152
|
+
}
|
|
153
|
+
return char;
|
|
154
|
+
}
|
|
155
|
+
// Functional-key codes only appear under modes this app never pushes
|
|
156
|
+
// (kitty flags 2+); pass them through so behaviour matches the un-enhanced
|
|
157
|
+
// stream instead of inventing a translation.
|
|
158
|
+
return key.seq;
|
|
159
|
+
}
|
|
160
|
+
/** True when `s` is a PROPER prefix of some CSI-u sequence. */
|
|
161
|
+
function isCsiUPrefix(s) {
|
|
162
|
+
if (s.length < 3 || s[0] !== '\x1b' || s[1] !== '[')
|
|
163
|
+
return false;
|
|
164
|
+
for (let i = 2; i < s.length; i += 1) {
|
|
165
|
+
if (!isParamChar(s[i]))
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Length of the trailing run of `text` that could still complete into a
|
|
172
|
+
* CSI-u sequence, or 0. Longest match, mirroring the other families.
|
|
173
|
+
*/
|
|
174
|
+
export function trailingCsiUPrefixLength(text) {
|
|
175
|
+
const max = Math.min(text.length, 32);
|
|
176
|
+
for (let k = max; k >= 1; k -= 1) {
|
|
177
|
+
if (isCsiUPrefix(text.slice(text.length - k)))
|
|
178
|
+
return k;
|
|
179
|
+
}
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor Position Report parsing (tui-bottom-anchored-live-region §4.5).
|
|
3
|
+
*
|
|
4
|
+
* The bottom anchor needs one number the writer cannot compute: how many rows are
|
|
5
|
+
* left below the cursor. `ESC[6n` is the only way to ask, and the terminal answers
|
|
6
|
+
* with `ESC[<row>;<col>R` (DECXCPR adds a `?`: `ESC[?<row>;<col>R`) on STDIN —
|
|
7
|
+
* the same stream the user types on. Two things follow, and both live here:
|
|
8
|
+
*
|
|
9
|
+
* 1. THE ANSWER MUST BE STRIPPED BEFORE INK SEES IT. A report that reaches Ink
|
|
10
|
+
* travels the keystroke path: `[` is 0x5B, so `PromptInput`'s control-sequence
|
|
11
|
+
* guard passes it through and the user's draft gets `[12;1R` typed into it (the
|
|
12
|
+
* same class of accident the mouse filter exists to prevent).
|
|
13
|
+
* 2. THE ANSWER CAN ARRIVE IN TWO CHUNKS. ConPTY, tmux and a loaded SSH session
|
|
14
|
+
* all split reads at arbitrary points, and a half report (`ESC[12`) is worse
|
|
15
|
+
* than a whole one: `parse-keypress` has no branch for it.
|
|
16
|
+
*
|
|
17
|
+
* Pure functions only, mirroring `mouse-events.ts`: the filter owns the buffering
|
|
18
|
+
* and the timers, this module owns the shapes.
|
|
19
|
+
*/
|
|
20
|
+
/** The query for a Cursor Position Report (DSR 6). ASCII by construction. */
|
|
21
|
+
export declare const CURSOR_REPORT_QUERY = "\u001B[6n";
|
|
22
|
+
/** One parsed report. `row`/`col` are 1-based, exactly as the terminal sent them. */
|
|
23
|
+
export interface CursorReport {
|
|
24
|
+
row: number;
|
|
25
|
+
col: number;
|
|
26
|
+
}
|
|
27
|
+
export interface CursorReportSplit {
|
|
28
|
+
/** Text that survives stripping — everything that is not a report. */
|
|
29
|
+
text: string;
|
|
30
|
+
/** Reports found in this chunk, in order. */
|
|
31
|
+
reports: CursorReport[];
|
|
32
|
+
/** Trailing bytes that could still become a report; hand them to the next chunk. */
|
|
33
|
+
pending: string;
|
|
34
|
+
}
|
|
35
|
+
/** True when `s` is a non-empty proper prefix of a possible report. */
|
|
36
|
+
export declare function isCursorReportPrefix(s: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Split the reports out of one chunk.
|
|
39
|
+
*
|
|
40
|
+
* `pending` carries the tail that might still complete into a report. It is only
|
|
41
|
+
* ever the LAST fragment: the scan is left to right, so anything before a complete
|
|
42
|
+
* report is settled text.
|
|
43
|
+
*/
|
|
44
|
+
export declare function splitCursorReports(text: string): CursorReportSplit;
|
|
45
|
+
/**
|
|
46
|
+
* Length of the trailing run of `text` that is a proper prefix of a report, or 0.
|
|
47
|
+
*
|
|
48
|
+
* LONGEST MATCH WINS, unlike the mouse family's shortest-wins rule. The families are
|
|
49
|
+
* combined with `max()`, so only the longest answer ever survives, and a longer hold
|
|
50
|
+
* is never wrong here: `ESC[1` can still become `ESC[12;1R`, while the shorter
|
|
51
|
+
* answer `ESC` could not describe it. The bound is the longest report the terminals
|
|
52
|
+
* we target emit (DECXCPR with a `?` and three-digit coordinates).
|
|
53
|
+
*/
|
|
54
|
+
export declare function trailingCprPrefixLength(text: string): number;
|
|
55
|
+
/** The query bytes, as a function so call sites read as an action rather than a literal. */
|
|
56
|
+
export declare function formatCursorReportQuery(): string;
|
|
57
|
+
/**
|
|
58
|
+
* Rows left below a reported cursor row on a terminal of `rows` rows.
|
|
59
|
+
* `0` means the cursor is already on the last row; `null` when the height is unknown.
|
|
60
|
+
*/
|
|
61
|
+
export declare function spaceBelowFromReport(report: CursorReport, rows: number | undefined): number | null;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor Position Report parsing (tui-bottom-anchored-live-region §4.5).
|
|
3
|
+
*
|
|
4
|
+
* The bottom anchor needs one number the writer cannot compute: how many rows are
|
|
5
|
+
* left below the cursor. `ESC[6n` is the only way to ask, and the terminal answers
|
|
6
|
+
* with `ESC[<row>;<col>R` (DECXCPR adds a `?`: `ESC[?<row>;<col>R`) on STDIN —
|
|
7
|
+
* the same stream the user types on. Two things follow, and both live here:
|
|
8
|
+
*
|
|
9
|
+
* 1. THE ANSWER MUST BE STRIPPED BEFORE INK SEES IT. A report that reaches Ink
|
|
10
|
+
* travels the keystroke path: `[` is 0x5B, so `PromptInput`'s control-sequence
|
|
11
|
+
* guard passes it through and the user's draft gets `[12;1R` typed into it (the
|
|
12
|
+
* same class of accident the mouse filter exists to prevent).
|
|
13
|
+
* 2. THE ANSWER CAN ARRIVE IN TWO CHUNKS. ConPTY, tmux and a loaded SSH session
|
|
14
|
+
* all split reads at arbitrary points, and a half report (`ESC[12`) is worse
|
|
15
|
+
* than a whole one: `parse-keypress` has no branch for it.
|
|
16
|
+
*
|
|
17
|
+
* Pure functions only, mirroring `mouse-events.ts`: the filter owns the buffering
|
|
18
|
+
* and the timers, this module owns the shapes.
|
|
19
|
+
*/
|
|
20
|
+
/** The query for a Cursor Position Report (DSR 6). ASCII by construction. */
|
|
21
|
+
export const CURSOR_REPORT_QUERY = '\x1b[6n';
|
|
22
|
+
/**
|
|
23
|
+
* `ESC[<row>;<col>R`, with the DECXCPR `?` accepted. Anchored on `ESC[` plus digits
|
|
24
|
+
* and one `;`, which is what keeps it from matching a private-mode write such as
|
|
25
|
+
* `ESC[?25l` (that one ends in a letter this pattern cannot accept).
|
|
26
|
+
*
|
|
27
|
+
* Built per call rather than shared: a module-level `/g` regex carries `lastIndex`
|
|
28
|
+
* between calls, which turns a pure function into a stateful one.
|
|
29
|
+
*/
|
|
30
|
+
const reportPattern = () => /\x1b\[\??(\d+);(\d+)R/g;
|
|
31
|
+
/**
|
|
32
|
+
* A PROPER prefix of a report: `ESC`, `ESC[`, then an optional `?`, then digits, at
|
|
33
|
+
* most one `;`, then more digits. Nothing a keyboard produces matches past `ESC[`
|
|
34
|
+
* (arrow keys end in a letter), so the filter's 12 ms hold stays a rare path.
|
|
35
|
+
*/
|
|
36
|
+
const PREFIX = /^\x1b(\[(\?(\d*(;\d*)?)?|\d*(;\d*)?)?)?$/;
|
|
37
|
+
/** True when `s` is a non-empty proper prefix of a possible report. */
|
|
38
|
+
export function isCursorReportPrefix(s) {
|
|
39
|
+
return s.length > 0 && s.length < 24 && PREFIX.test(s);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Split the reports out of one chunk.
|
|
43
|
+
*
|
|
44
|
+
* `pending` carries the tail that might still complete into a report. It is only
|
|
45
|
+
* ever the LAST fragment: the scan is left to right, so anything before a complete
|
|
46
|
+
* report is settled text.
|
|
47
|
+
*/
|
|
48
|
+
export function splitCursorReports(text) {
|
|
49
|
+
const reports = [];
|
|
50
|
+
const pattern = reportPattern();
|
|
51
|
+
let out = '';
|
|
52
|
+
let index = 0;
|
|
53
|
+
for (let match = pattern.exec(text); match !== null; match = pattern.exec(text)) {
|
|
54
|
+
out += text.slice(index, match.index);
|
|
55
|
+
reports.push({ row: Number(match[1]), col: Number(match[2]) });
|
|
56
|
+
index = match.index + match[0].length;
|
|
57
|
+
}
|
|
58
|
+
out += text.slice(index);
|
|
59
|
+
const pendingLength = trailingCprPrefixLength(out);
|
|
60
|
+
if (pendingLength === 0)
|
|
61
|
+
return { text: out, reports, pending: '' };
|
|
62
|
+
return {
|
|
63
|
+
text: out.slice(0, out.length - pendingLength),
|
|
64
|
+
reports,
|
|
65
|
+
pending: out.slice(out.length - pendingLength),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Length of the trailing run of `text` that is a proper prefix of a report, or 0.
|
|
70
|
+
*
|
|
71
|
+
* LONGEST MATCH WINS, unlike the mouse family's shortest-wins rule. The families are
|
|
72
|
+
* combined with `max()`, so only the longest answer ever survives, and a longer hold
|
|
73
|
+
* is never wrong here: `ESC[1` can still become `ESC[12;1R`, while the shorter
|
|
74
|
+
* answer `ESC` could not describe it. The bound is the longest report the terminals
|
|
75
|
+
* we target emit (DECXCPR with a `?` and three-digit coordinates).
|
|
76
|
+
*/
|
|
77
|
+
export function trailingCprPrefixLength(text) {
|
|
78
|
+
const max = Math.min(text.length, 24);
|
|
79
|
+
for (let k = max; k >= 1; k -= 1) {
|
|
80
|
+
if (isCursorReportPrefix(text.slice(text.length - k)))
|
|
81
|
+
return k;
|
|
82
|
+
}
|
|
83
|
+
return 0;
|
|
84
|
+
}
|
|
85
|
+
/** The query bytes, as a function so call sites read as an action rather than a literal. */
|
|
86
|
+
export function formatCursorReportQuery() {
|
|
87
|
+
return CURSOR_REPORT_QUERY;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Rows left below a reported cursor row on a terminal of `rows` rows.
|
|
91
|
+
* `0` means the cursor is already on the last row; `null` when the height is unknown.
|
|
92
|
+
*/
|
|
93
|
+
export function spaceBelowFromReport(report, rows) {
|
|
94
|
+
if (rows === undefined || !Number.isFinite(rows) || rows < 1)
|
|
95
|
+
return null;
|
|
96
|
+
return Math.max(0, Math.floor(rows) - 1 - (report.row - 1));
|
|
97
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enter-family sequence recognition (tui-shift-enter-copy-queue §3.3) -- pure,
|
|
3
|
+
* stream-free, no node/React imports, callable from any test environment.
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS LIVES BELOW INK. Ink 5's `parse-keypress.js` calls `parseKeypress`
|
|
6
|
+
* ONCE per stdin chunk and hard-codes `shift: false` for the exact string
|
|
7
|
+
* `'\r'`, so a component can never see `key.return && key.shift` -- the
|
|
8
|
+
* `PromptInput` branch for it is dead code. Worse, terminals that DO encode a
|
|
9
|
+
* distinct Shift+Enter send CSI-u (`\x1b[13;2u`), which Ink's `fnKeyRe` does
|
|
10
|
+
* not match: the ESC is stripped by `use-input.js` and `'[13;2u'` falls through
|
|
11
|
+
* to the PRINTABLE branch, typing garbage into the draft. The only layer that
|
|
12
|
+
* sees the bytes before Ink mangles them is the stdin filter, which is where
|
|
13
|
+
* the mouse-report and paste-marker dialects are already translated.
|
|
14
|
+
*
|
|
15
|
+
* THE CONTRACT: rewrite every recognized sequence to ONE normalized token --
|
|
16
|
+
* `ENTER_NEWLINE_FRAME` for "this was a modified Enter, the user wants a
|
|
17
|
+
* newline" and `'\r'` for the unmodified CSI-u Enter some other program left
|
|
18
|
+
* behind. No state, no partial-output: `rewriteEnterSequences` is idempotent
|
|
19
|
+
* because its output contains none of its inputs.
|
|
20
|
+
*/
|
|
21
|
+
/** What one recognized sequence means, for tests and `/terminal-setup` copy. */
|
|
22
|
+
export interface EnterSequenceSpec {
|
|
23
|
+
/** The exact byte sequence a terminal sends for this key. */
|
|
24
|
+
readonly seq: string;
|
|
25
|
+
/** The chord it names, e.g. `'shift+enter'`, `'ctrl+alt+enter'`, `'enter'`. */
|
|
26
|
+
readonly meaning: string;
|
|
27
|
+
/** What `rewriteEnterSequences` replaces it with. */
|
|
28
|
+
readonly to: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* The recognition table (§3.3). CSI-u modifiers 2-8 cover Shift(2), Alt(3),
|
|
32
|
+
* Shift+Alt(4), Ctrl(5), Ctrl+Shift(6), Ctrl+Alt(7), Ctrl+Alt+Shift(8) as
|
|
33
|
+
* emitted by kitty/WezTerm keyboard-enhancement mode and by
|
|
34
|
+
* `modifyOtherKeys=2`; every one of them means "Enter with a modifier", and a
|
|
35
|
+
* modified Enter must NEVER submit the draft. `\x1b\r` / `\x1b\n` are the
|
|
36
|
+
* classic Alt+Enter encodings. `\x1b[13u` (no modifier field) is what a
|
|
37
|
+
* leftover kitty mode sends for a PLAIN Enter: it must submit, so it maps to
|
|
38
|
+
* `'\r'` rather than to a newline.
|
|
39
|
+
*/
|
|
40
|
+
export declare const ENTER_SEQUENCES: readonly EnterSequenceSpec[];
|
|
41
|
+
export type EnterSequenceSegment = {
|
|
42
|
+
kind: 'text';
|
|
43
|
+
text: string;
|
|
44
|
+
} | {
|
|
45
|
+
kind: 'newline';
|
|
46
|
+
} | {
|
|
47
|
+
kind: 'submit';
|
|
48
|
+
};
|
|
49
|
+
/** Split explicit keys using the recognition table; bare CR/LF remain text. */
|
|
50
|
+
export declare function splitEnterSequences(text: string): EnterSequenceSegment[];
|
|
51
|
+
/** Normalize explicit Enter keys without changing unknown sequences. */
|
|
52
|
+
export declare function rewriteEnterSequences(text: string): string;
|
|
53
|
+
/**
|
|
54
|
+
* Length of the trailing run of `text` that is a proper prefix of an
|
|
55
|
+
* Enter-family sequence, or 0.
|
|
56
|
+
*
|
|
57
|
+
* LONGEST MATCH, not shortest: unlike the mouse and paste families, a torn
|
|
58
|
+
* CSI-u sequence diverges from its siblings only at the LAST byte
|
|
59
|
+
* (`\x1b[13;` + `2u`), so every byte before the divergence point must be held
|
|
60
|
+
* back for the next chunk or the sequence is destroyed a byte early. Feeding
|
|
61
|
+
* the result into the filter's `keep = max(...)` alongside the other two
|
|
62
|
+
* families keeps every family's hold intact.
|
|
63
|
+
*/
|
|
64
|
+
export declare function trailingEnterPrefixLength(text: string): number;
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enter-family sequence recognition (tui-shift-enter-copy-queue §3.3) -- pure,
|
|
3
|
+
* stream-free, no node/React imports, callable from any test environment.
|
|
4
|
+
*
|
|
5
|
+
* WHY THIS LIVES BELOW INK. Ink 5's `parse-keypress.js` calls `parseKeypress`
|
|
6
|
+
* ONCE per stdin chunk and hard-codes `shift: false` for the exact string
|
|
7
|
+
* `'\r'`, so a component can never see `key.return && key.shift` -- the
|
|
8
|
+
* `PromptInput` branch for it is dead code. Worse, terminals that DO encode a
|
|
9
|
+
* distinct Shift+Enter send CSI-u (`\x1b[13;2u`), which Ink's `fnKeyRe` does
|
|
10
|
+
* not match: the ESC is stripped by `use-input.js` and `'[13;2u'` falls through
|
|
11
|
+
* to the PRINTABLE branch, typing garbage into the draft. The only layer that
|
|
12
|
+
* sees the bytes before Ink mangles them is the stdin filter, which is where
|
|
13
|
+
* the mouse-report and paste-marker dialects are already translated.
|
|
14
|
+
*
|
|
15
|
+
* THE CONTRACT: rewrite every recognized sequence to ONE normalized token --
|
|
16
|
+
* `ENTER_NEWLINE_FRAME` for "this was a modified Enter, the user wants a
|
|
17
|
+
* newline" and `'\r'` for the unmodified CSI-u Enter some other program left
|
|
18
|
+
* behind. No state, no partial-output: `rewriteEnterSequences` is idempotent
|
|
19
|
+
* because its output contains none of its inputs.
|
|
20
|
+
*/
|
|
21
|
+
import { ENTER_NEWLINE_FRAME } from './limits.js';
|
|
22
|
+
/**
|
|
23
|
+
* The recognition table (§3.3). CSI-u modifiers 2-8 cover Shift(2), Alt(3),
|
|
24
|
+
* Shift+Alt(4), Ctrl(5), Ctrl+Shift(6), Ctrl+Alt(7), Ctrl+Alt+Shift(8) as
|
|
25
|
+
* emitted by kitty/WezTerm keyboard-enhancement mode and by
|
|
26
|
+
* `modifyOtherKeys=2`; every one of them means "Enter with a modifier", and a
|
|
27
|
+
* modified Enter must NEVER submit the draft. `\x1b\r` / `\x1b\n` are the
|
|
28
|
+
* classic Alt+Enter encodings. `\x1b[13u` (no modifier field) is what a
|
|
29
|
+
* leftover kitty mode sends for a PLAIN Enter: it must submit, so it maps to
|
|
30
|
+
* `'\r'` rather than to a newline.
|
|
31
|
+
*/
|
|
32
|
+
export const ENTER_SEQUENCES = [
|
|
33
|
+
{ seq: '\x1b[13;1u', meaning: 'enter', to: '\r' },
|
|
34
|
+
{
|
|
35
|
+
seq: '\x1b[13;2u',
|
|
36
|
+
meaning: 'shift+enter',
|
|
37
|
+
to: ENTER_NEWLINE_FRAME,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
seq: '\x1b[13;3u',
|
|
41
|
+
meaning: 'alt+enter',
|
|
42
|
+
to: ENTER_NEWLINE_FRAME,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
seq: '\x1b[13;4u',
|
|
46
|
+
meaning: 'shift+alt+enter',
|
|
47
|
+
to: ENTER_NEWLINE_FRAME,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
seq: '\x1b[13;5u',
|
|
51
|
+
meaning: 'ctrl+enter',
|
|
52
|
+
to: ENTER_NEWLINE_FRAME,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
seq: '\x1b[13;6u',
|
|
56
|
+
meaning: 'ctrl+shift+enter',
|
|
57
|
+
to: ENTER_NEWLINE_FRAME,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
seq: '\x1b[13;7u',
|
|
61
|
+
meaning: 'ctrl+alt+enter',
|
|
62
|
+
to: ENTER_NEWLINE_FRAME,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
seq: '\x1b[13;8u',
|
|
66
|
+
meaning: 'ctrl+alt+shift+enter',
|
|
67
|
+
to: ENTER_NEWLINE_FRAME,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
seq: '\x1b\r',
|
|
71
|
+
meaning: 'alt+enter',
|
|
72
|
+
to: ENTER_NEWLINE_FRAME,
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
seq: '\x1b\n',
|
|
76
|
+
meaning: 'alt+enter',
|
|
77
|
+
to: ENTER_NEWLINE_FRAME,
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
seq: '\x1b[13u',
|
|
81
|
+
meaning: 'enter',
|
|
82
|
+
to: '\r',
|
|
83
|
+
},
|
|
84
|
+
];
|
|
85
|
+
/**
|
|
86
|
+
* Longest strict prefix any recognized sequence can have. Derived from the
|
|
87
|
+
* table rather than hard-coded so adding a sequence can never leave the hold
|
|
88
|
+
* ceiling behind: the longest sequence is 7 bytes, so a torn sequence can hold
|
|
89
|
+
* up to 6 of them.
|
|
90
|
+
*/
|
|
91
|
+
const MAX_ENTER_PREFIX = Math.max(...ENTER_SEQUENCES.map((s) => s.seq.length)) - 1;
|
|
92
|
+
/** Split explicit keys using the recognition table; bare CR/LF remain text. */
|
|
93
|
+
export function splitEnterSequences(text) {
|
|
94
|
+
const segments = [];
|
|
95
|
+
let start = 0;
|
|
96
|
+
let index = 0;
|
|
97
|
+
while (index < text.length) {
|
|
98
|
+
const match = text[index] === '\x1b'
|
|
99
|
+
? ENTER_SEQUENCES.find((spec) => text.startsWith(spec.seq, index)) : undefined;
|
|
100
|
+
if (!match) {
|
|
101
|
+
index += 1;
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (index > start)
|
|
105
|
+
segments.push({ kind: 'text', text: text.slice(start, index) });
|
|
106
|
+
segments.push({ kind: match.to === '\r' ? 'submit' : 'newline' });
|
|
107
|
+
index += match.seq.length;
|
|
108
|
+
start = index;
|
|
109
|
+
}
|
|
110
|
+
if (start < text.length)
|
|
111
|
+
segments.push({ kind: 'text', text: text.slice(start) });
|
|
112
|
+
return segments;
|
|
113
|
+
}
|
|
114
|
+
/** Normalize explicit Enter keys without changing unknown sequences. */
|
|
115
|
+
export function rewriteEnterSequences(text) {
|
|
116
|
+
return splitEnterSequences(text).map((segment) => {
|
|
117
|
+
if (segment.kind === 'text')
|
|
118
|
+
return segment.text;
|
|
119
|
+
return segment.kind === 'submit' ? '\r' : ENTER_NEWLINE_FRAME;
|
|
120
|
+
}).join('');
|
|
121
|
+
}
|
|
122
|
+
/** True when `s` is a PROPER prefix of some recognized sequence (never whole). */
|
|
123
|
+
function isEnterPrefix(s) {
|
|
124
|
+
if (s.length === 0 || s.length > MAX_ENTER_PREFIX)
|
|
125
|
+
return false;
|
|
126
|
+
for (const spec of ENTER_SEQUENCES) {
|
|
127
|
+
// `length >`, not `startsWith` alone: `startsWith` accepts the WHOLE
|
|
128
|
+
// sequence too, and holding a complete sequence back would add 12 ms
|
|
129
|
+
// of latency to a key that is ready to be rewritten right now.
|
|
130
|
+
if (spec.seq.length > s.length && spec.seq.startsWith(s))
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Length of the trailing run of `text` that is a proper prefix of an
|
|
137
|
+
* Enter-family sequence, or 0.
|
|
138
|
+
*
|
|
139
|
+
* LONGEST MATCH, not shortest: unlike the mouse and paste families, a torn
|
|
140
|
+
* CSI-u sequence diverges from its siblings only at the LAST byte
|
|
141
|
+
* (`\x1b[13;` + `2u`), so every byte before the divergence point must be held
|
|
142
|
+
* back for the next chunk or the sequence is destroyed a byte early. Feeding
|
|
143
|
+
* the result into the filter's `keep = max(...)` alongside the other two
|
|
144
|
+
* families keeps every family's hold intact.
|
|
145
|
+
*/
|
|
146
|
+
export function trailingEnterPrefixLength(text) {
|
|
147
|
+
const max = Math.min(text.length, MAX_ENTER_PREFIX);
|
|
148
|
+
for (let k = max; k >= 1; k -= 1) {
|
|
149
|
+
if (isEnterPrefix(text.slice(text.length - k)))
|
|
150
|
+
return k;
|
|
151
|
+
}
|
|
152
|
+
return 0;
|
|
153
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Confirmation window for two independent decoded Escape events. */
|
|
2
|
+
export declare const INTERRUPT_CONFIRM_MS = 1500;
|
|
3
|
+
export type InterruptGestureState = {
|
|
4
|
+
phase: 'ready';
|
|
5
|
+
} | {
|
|
6
|
+
phase: 'armed';
|
|
7
|
+
armedAt: number;
|
|
8
|
+
} | {
|
|
9
|
+
phase: 'stopping';
|
|
10
|
+
};
|
|
11
|
+
export interface InterruptGestureResult {
|
|
12
|
+
state: InterruptGestureState;
|
|
13
|
+
action: 'hint' | 'abort' | 'force-stop';
|
|
14
|
+
}
|
|
15
|
+
/** Advance using a monotonic clock; the caller owns the current run's lifetime. */
|
|
16
|
+
export declare function advanceInterruptGesture(state: InterruptGestureState, now: number): InterruptGestureResult;
|
|
17
|
+
/** Other input cancels confirmation, but cannot undo an already requested stop. */
|
|
18
|
+
export declare function cancelInterruptConfirmation(state: InterruptGestureState): InterruptGestureState;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Confirmation window for two independent decoded Escape events. */
|
|
2
|
+
export const INTERRUPT_CONFIRM_MS = 1500;
|
|
3
|
+
/** Advance using a monotonic clock; the caller owns the current run's lifetime. */
|
|
4
|
+
export function advanceInterruptGesture(state, now) {
|
|
5
|
+
if (state.phase === 'stopping') {
|
|
6
|
+
return { state: { phase: 'ready' }, action: 'force-stop' };
|
|
7
|
+
}
|
|
8
|
+
if (state.phase === 'armed') {
|
|
9
|
+
const elapsed = now - state.armedAt;
|
|
10
|
+
if (elapsed >= 0 && elapsed <= INTERRUPT_CONFIRM_MS) {
|
|
11
|
+
return { state: { phase: 'stopping' }, action: 'abort' };
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return { state: { phase: 'armed', armedAt: now }, action: 'hint' };
|
|
15
|
+
}
|
|
16
|
+
/** Other input cancels confirmation, but cannot undo an already requested stop. */
|
|
17
|
+
export function cancelInterruptConfirmation(state) {
|
|
18
|
+
return state.phase === 'armed' ? { phase: 'ready' } : state;
|
|
19
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keyboard-enhancement lifecycle (the Shift+Enter newline fix).
|
|
3
|
+
*
|
|
4
|
+
* WHY A LIFECYCLE MODULE AND NOT ANOTHER `screen.ts` MODE. The alternate
|
|
5
|
+
* screen is bound to fullscreen rendering; keyboard enhancement must run in
|
|
6
|
+
* every interactive session, inline included, because the composer is always
|
|
7
|
+
* there. It still follows the screen module's discipline: bytes are written
|
|
8
|
+
* ONLY for a TTY stdout, restore is idempotent, and the caller owns every
|
|
9
|
+
* decision -- this module is told the resolved capability and never derives
|
|
10
|
+
* one from config or environment.
|
|
11
|
+
*
|
|
12
|
+
* PLATFORM SPLIT, DECIDED BY BYTE-LEVEL PROBES (see
|
|
13
|
+
* docs/diagnoses/shift-enter-newline-dead-by-default):
|
|
14
|
+
*
|
|
15
|
+
* - win32: `?9001h` (win32-input-mode). It works through ConPTY on both
|
|
16
|
+
* conhost and Windows Terminal; kitty `CSI > 1 u` is swallowed there (a
|
|
17
|
+
* `CSI ? u` query never answers) and modifyOtherKeys is a no-op. Gated on
|
|
18
|
+
* the SAME `vtInputSupported` measurement the mouse feature uses: on Node
|
|
19
|
+
* < 22.17 / < 24.2 libuv never turns on `ENABLE_VIRTUAL_TERMINAL_INPUT`,
|
|
20
|
+
* so the records cannot reach the process and the mode would be a lie.
|
|
21
|
+
* - everything else: kitty disambiguate (`CSI > 1 u`) plus
|
|
22
|
+
* `modifyOtherKeys=2`. iTerm2 / kitty / ghostty / WezTerm / foot implement
|
|
23
|
+
* at least one; terminals that implement neither ignore both bytes.
|
|
24
|
+
*/
|
|
25
|
+
export interface KeyboardEnhancementHandle {
|
|
26
|
+
/** Idempotent; writes the disable bytes exactly once. */
|
|
27
|
+
restore(): void;
|
|
28
|
+
}
|
|
29
|
+
/** The handle a gated-out session reads: nothing was pushed, nothing unwinds. */
|
|
30
|
+
export declare const NOOP_KEYBOARD_ENHANCEMENT: KeyboardEnhancementHandle;
|
|
31
|
+
/**
|
|
32
|
+
* Ask the terminal to report modified keys distinctly. The returned handle's
|
|
33
|
+
* `restore()` hands the keyboard back; wire it into the same convergence
|
|
34
|
+
* point the screen restore uses so every exit path unwinds both.
|
|
35
|
+
*
|
|
36
|
+
* `vtInputSupported` is the measurement `cli.tsx` already resolves for the
|
|
37
|
+
* mouse gate; on win32 it decides between `?9001h` and nothing at all.
|
|
38
|
+
*/
|
|
39
|
+
export declare function enableKeyboardEnhancement(stdout: NodeJS.WriteStream | undefined, opts: {
|
|
40
|
+
readonly platform: string;
|
|
41
|
+
readonly vtInputSupported: boolean;
|
|
42
|
+
}): KeyboardEnhancementHandle;
|