@deepseek-harness-tui/dsh-tui 0.5.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/LICENSE +21 -0
- package/README.md +235 -0
- package/bin/dsh-tui.js +95 -0
- package/cordis.patch.yml +218 -0
- package/cordis.yml +185 -0
- package/lib/invariant.js +28 -0
- package/lib/types/activityPrefs.d.ts +29 -0
- package/lib/types/activityPrefs.d.ts.map +1 -0
- package/lib/types/activityPrefs.js +60 -0
- package/lib/types/bootstrap/state.d.ts +13 -0
- package/lib/types/bootstrap/state.d.ts.map +1 -0
- package/lib/types/bootstrap/state.js +12 -0
- package/lib/types/cc/cliHighlight.d.ts +20 -0
- package/lib/types/cc/cliHighlight.d.ts.map +1 -0
- package/lib/types/cc/cliHighlight.js +53 -0
- package/lib/types/cc/figures.d.ts +59 -0
- package/lib/types/cc/figures.d.ts.map +1 -0
- package/lib/types/cc/figures.js +69 -0
- package/lib/types/cc/format.d.ts +26 -0
- package/lib/types/cc/format.d.ts.map +1 -0
- package/lib/types/cc/format.js +55 -0
- package/lib/types/cc/hash.d.ts +25 -0
- package/lib/types/cc/hash.d.ts.map +1 -0
- package/lib/types/cc/hash.js +41 -0
- package/lib/types/cc/hyperlink.d.ts +21 -0
- package/lib/types/cc/hyperlink.d.ts.map +1 -0
- package/lib/types/cc/hyperlink.js +31 -0
- package/lib/types/cc/markdown.d.ts +43 -0
- package/lib/types/cc/markdown.d.ts.map +1 -0
- package/lib/types/cc/markdown.js +345 -0
- package/lib/types/cc/spinnerVerbs.d.ts +3 -0
- package/lib/types/cc/spinnerVerbs.d.ts.map +1 -0
- package/lib/types/cc/spinnerVerbs.js +190 -0
- package/lib/types/cc/terminal.d.ts +15 -0
- package/lib/types/cc/terminal.d.ts.map +1 -0
- package/lib/types/cc/terminal.js +84 -0
- package/lib/types/channel.d.ts +672 -0
- package/lib/types/channel.d.ts.map +1 -0
- package/lib/types/channel.js +2427 -0
- package/lib/types/childStderr.d.ts +63 -0
- package/lib/types/childStderr.d.ts.map +1 -0
- package/lib/types/childStderr.js +161 -0
- package/lib/types/commands.d.ts +55 -0
- package/lib/types/commands.d.ts.map +1 -0
- package/lib/types/commands.js +101 -0
- package/lib/types/components/ActivityLine.d.ts +29 -0
- package/lib/types/components/ActivityLine.d.ts.map +1 -0
- package/lib/types/components/ActivityLine.js +47 -0
- package/lib/types/components/ActivityPicker.d.ts +13 -0
- package/lib/types/components/ActivityPicker.d.ts.map +1 -0
- package/lib/types/components/ActivityPicker.js +24 -0
- package/lib/types/components/CommandSuggestions.d.ts +14 -0
- package/lib/types/components/CommandSuggestions.d.ts.map +1 -0
- package/lib/types/components/CommandSuggestions.js +33 -0
- package/lib/types/components/FileSuggestions.d.ts +12 -0
- package/lib/types/components/FileSuggestions.d.ts.map +1 -0
- package/lib/types/components/FileSuggestions.js +26 -0
- package/lib/types/components/GoalTodoPanel.d.ts +13 -0
- package/lib/types/components/GoalTodoPanel.d.ts.map +1 -0
- package/lib/types/components/GoalTodoPanel.js +57 -0
- package/lib/types/components/HelpMenu.d.ts +12 -0
- package/lib/types/components/HelpMenu.d.ts.map +1 -0
- package/lib/types/components/HelpMenu.js +12 -0
- package/lib/types/components/HistorySearchDialog.d.ts +16 -0
- package/lib/types/components/HistorySearchDialog.d.ts.map +1 -0
- package/lib/types/components/HistorySearchDialog.js +31 -0
- package/lib/types/components/InterruptedByUser.d.ts +7 -0
- package/lib/types/components/InterruptedByUser.d.ts.map +1 -0
- package/lib/types/components/InterruptedByUser.js +9 -0
- package/lib/types/components/LoadedContextPanel.d.ts +20 -0
- package/lib/types/components/LoadedContextPanel.d.ts.map +1 -0
- package/lib/types/components/LoadedContextPanel.js +30 -0
- package/lib/types/components/LogoV2.d.ts +23 -0
- package/lib/types/components/LogoV2.d.ts.map +1 -0
- package/lib/types/components/LogoV2.js +95 -0
- package/lib/types/components/Markdown.d.ts +24 -0
- package/lib/types/components/Markdown.d.ts.map +1 -0
- package/lib/types/components/Markdown.js +106 -0
- package/lib/types/components/MarkdownTable.d.ts +17 -0
- package/lib/types/components/MarkdownTable.d.ts.map +1 -0
- package/lib/types/components/MarkdownTable.js +272 -0
- package/lib/types/components/MessageList.d.ts +41 -0
- package/lib/types/components/MessageList.d.ts.map +1 -0
- package/lib/types/components/MessageList.js +303 -0
- package/lib/types/components/ModelPicker.d.ts +14 -0
- package/lib/types/components/ModelPicker.d.ts.map +1 -0
- package/lib/types/components/ModelPicker.js +15 -0
- package/lib/types/components/PresetPicker.d.ts +17 -0
- package/lib/types/components/PresetPicker.d.ts.map +1 -0
- package/lib/types/components/PresetPicker.js +25 -0
- package/lib/types/components/PromptInput.d.ts +67 -0
- package/lib/types/components/PromptInput.d.ts.map +1 -0
- package/lib/types/components/PromptInput.js +778 -0
- package/lib/types/components/ResumePicker.d.ts +15 -0
- package/lib/types/components/ResumePicker.d.ts.map +1 -0
- package/lib/types/components/ResumePicker.js +34 -0
- package/lib/types/components/RewindPicker.d.ts +14 -0
- package/lib/types/components/RewindPicker.d.ts.map +1 -0
- package/lib/types/components/RewindPicker.js +23 -0
- package/lib/types/components/SearchBox.d.ts +20 -0
- package/lib/types/components/SearchBox.d.ts.map +1 -0
- package/lib/types/components/SearchBox.js +33 -0
- package/lib/types/components/Select.d.ts +22 -0
- package/lib/types/components/Select.d.ts.map +1 -0
- package/lib/types/components/Select.js +19 -0
- package/lib/types/components/Spinner/GlimmerMessage.d.ts +19 -0
- package/lib/types/components/Spinner/GlimmerMessage.d.ts.map +1 -0
- package/lib/types/components/Spinner/GlimmerMessage.js +78 -0
- package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts +31 -0
- package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts.map +1 -0
- package/lib/types/components/Spinner/SpinnerAnimationRow.js +162 -0
- package/lib/types/components/Spinner/SpinnerGlyph.d.ts +16 -0
- package/lib/types/components/Spinner/SpinnerGlyph.d.ts.map +1 -0
- package/lib/types/components/Spinner/SpinnerGlyph.js +36 -0
- package/lib/types/components/Spinner/spinnerMode.d.ts +6 -0
- package/lib/types/components/Spinner/spinnerMode.d.ts.map +1 -0
- package/lib/types/components/Spinner/spinnerMode.js +1 -0
- package/lib/types/components/Spinner/spinnerUtils.d.ts +41 -0
- package/lib/types/components/Spinner/spinnerUtils.d.ts.map +1 -0
- package/lib/types/components/Spinner/spinnerUtils.js +104 -0
- package/lib/types/components/Spinner/useStalledAnimation.d.ts +16 -0
- package/lib/types/components/Spinner/useStalledAnimation.d.ts.map +1 -0
- package/lib/types/components/Spinner/useStalledAnimation.js +71 -0
- package/lib/types/components/StreamingMarkdown.d.ts +12 -0
- package/lib/types/components/StreamingMarkdown.d.ts.map +1 -0
- package/lib/types/components/StreamingMarkdown.js +39 -0
- package/lib/types/components/ThemePicker.d.ts +22 -0
- package/lib/types/components/ThemePicker.d.ts.map +1 -0
- package/lib/types/components/ThemePicker.js +51 -0
- package/lib/types/components/ThinkingToggle.d.ts +17 -0
- package/lib/types/components/ThinkingToggle.d.ts.map +1 -0
- package/lib/types/components/ThinkingToggle.js +30 -0
- package/lib/types/components/ToolUseLoader.d.ts +13 -0
- package/lib/types/components/ToolUseLoader.d.ts.map +1 -0
- package/lib/types/components/ToolUseLoader.js +17 -0
- package/lib/types/components/Whale.d.ts +22 -0
- package/lib/types/components/Whale.d.ts.map +1 -0
- package/lib/types/components/Whale.js +78 -0
- package/lib/types/components/WorkingSpinner.d.ts +26 -0
- package/lib/types/components/WorkingSpinner.d.ts.map +1 -0
- package/lib/types/components/WorkingSpinner.js +68 -0
- package/lib/types/components/activityFrames.d.ts +31 -0
- package/lib/types/components/activityFrames.d.ts.map +1 -0
- package/lib/types/components/activityFrames.js +83 -0
- package/lib/types/components/bigfont.d.ts +28 -0
- package/lib/types/components/bigfont.d.ts.map +1 -0
- package/lib/types/components/bigfont.js +91 -0
- package/lib/types/components/design-system/Byline.d.ts +14 -0
- package/lib/types/components/design-system/Byline.d.ts.map +1 -0
- package/lib/types/components/design-system/Byline.js +17 -0
- package/lib/types/components/design-system/Divider.d.ts +40 -0
- package/lib/types/components/design-system/Divider.d.ts.map +1 -0
- package/lib/types/components/design-system/Divider.js +24 -0
- package/lib/types/components/design-system/KeyboardShortcutHint.d.ts +19 -0
- package/lib/types/components/design-system/KeyboardShortcutHint.d.ts.map +1 -0
- package/lib/types/components/design-system/KeyboardShortcutHint.js +14 -0
- package/lib/types/components/design-system/ListItem.d.ts +36 -0
- package/lib/types/components/design-system/ListItem.d.ts.map +1 -0
- package/lib/types/components/design-system/ListItem.js +48 -0
- package/lib/types/components/design-system/LoadingState.d.ts +19 -0
- package/lib/types/components/design-system/LoadingState.d.ts.map +1 -0
- package/lib/types/components/design-system/LoadingState.js +22 -0
- package/lib/types/components/design-system/Pane.d.ts +17 -0
- package/lib/types/components/design-system/Pane.d.ts.map +1 -0
- package/lib/types/components/design-system/Pane.js +15 -0
- package/lib/types/components/design-system/ProgressBar.d.ts +22 -0
- package/lib/types/components/design-system/ProgressBar.d.ts.map +1 -0
- package/lib/types/components/design-system/ProgressBar.js +27 -0
- package/lib/types/components/design-system/StatusIcon.d.ts +15 -0
- package/lib/types/components/design-system/StatusIcon.d.ts.map +1 -0
- package/lib/types/components/design-system/StatusIcon.js +20 -0
- package/lib/types/components/design-system/ThemeProvider.d.ts +11 -0
- package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -0
- package/lib/types/components/design-system/ThemeProvider.js +135 -0
- package/lib/types/components/design-system/ThemedBox.d.ts +37 -0
- package/lib/types/components/design-system/ThemedBox.d.ts.map +1 -0
- package/lib/types/components/design-system/ThemedBox.js +26 -0
- package/lib/types/components/design-system/ThemedText.d.ts +56 -0
- package/lib/types/components/design-system/ThemedText.d.ts.map +1 -0
- package/lib/types/components/design-system/ThemedText.js +45 -0
- package/lib/types/components/messages/AssistantTextMessage.d.ts +18 -0
- package/lib/types/components/messages/AssistantTextMessage.d.ts.map +1 -0
- package/lib/types/components/messages/AssistantTextMessage.js +15 -0
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts +23 -0
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -0
- package/lib/types/components/messages/AssistantThinkingMessage.js +23 -0
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +23 -0
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -0
- package/lib/types/components/messages/AssistantToolUseMessage.js +220 -0
- package/lib/types/components/messages/MessageMetadata.d.ts +15 -0
- package/lib/types/components/messages/MessageMetadata.d.ts.map +1 -0
- package/lib/types/components/messages/MessageMetadata.js +20 -0
- package/lib/types/components/messages/UserPromptMessage.d.ts +19 -0
- package/lib/types/components/messages/UserPromptMessage.d.ts.map +1 -0
- package/lib/types/components/messages/UserPromptMessage.js +15 -0
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts +39 -0
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -0
- package/lib/types/components/questions/AskUserQuestionPanel.js +228 -0
- package/lib/types/components/shimmer.d.ts +35 -0
- package/lib/types/components/shimmer.d.ts.map +1 -0
- package/lib/types/components/shimmer.js +43 -0
- package/lib/types/components/whaleFrames.d.ts +25 -0
- package/lib/types/components/whaleFrames.d.ts.map +1 -0
- package/lib/types/components/whaleFrames.js +419 -0
- package/lib/types/customTheme.d.ts +104 -0
- package/lib/types/customTheme.d.ts.map +1 -0
- package/lib/types/customTheme.js +268 -0
- package/lib/types/effortPrefs.d.ts +22 -0
- package/lib/types/effortPrefs.d.ts.map +1 -0
- package/lib/types/effortPrefs.js +45 -0
- package/lib/types/history.d.ts +24 -0
- package/lib/types/history.d.ts.map +1 -0
- package/lib/types/history.js +75 -0
- package/lib/types/hooks/useBlink.d.ts +11 -0
- package/lib/types/hooks/useBlink.d.ts.map +1 -0
- package/lib/types/hooks/useBlink.js +20 -0
- package/lib/types/i18n.d.ts +926 -0
- package/lib/types/i18n.d.ts.map +1 -0
- package/lib/types/i18n.js +356 -0
- package/lib/types/index.d.ts +70 -0
- package/lib/types/index.d.ts.map +1 -0
- package/lib/types/index.js +31 -0
- package/lib/types/ink/Ansi.d.ts +11 -0
- package/lib/types/ink/Ansi.d.ts.map +1 -0
- package/lib/types/ink/Ansi.js +269 -0
- package/lib/types/ink/bidi.d.ts +18 -0
- package/lib/types/ink/bidi.d.ts.map +1 -0
- package/lib/types/ink/bidi.js +119 -0
- package/lib/types/ink/clearTerminal.d.ts +22 -0
- package/lib/types/ink/clearTerminal.d.ts.map +1 -0
- package/lib/types/ink/clearTerminal.js +72 -0
- package/lib/types/ink/colorize.d.ts +33 -0
- package/lib/types/ink/colorize.d.ts.map +1 -0
- package/lib/types/ink/colorize.js +213 -0
- package/lib/types/ink/components/AlternateScreen.d.ts +22 -0
- package/lib/types/ink/components/AlternateScreen.d.ts.map +1 -0
- package/lib/types/ink/components/AlternateScreen.js +74 -0
- package/lib/types/ink/components/App.d.ts +73 -0
- package/lib/types/ink/components/App.d.ts.map +1 -0
- package/lib/types/ink/components/App.js +597 -0
- package/lib/types/ink/components/AppContext.d.ts +15 -0
- package/lib/types/ink/components/AppContext.d.ts.map +1 -0
- package/lib/types/ink/components/AppContext.js +11 -0
- package/lib/types/ink/components/Box.d.ts +49 -0
- package/lib/types/ink/components/Box.d.ts.map +1 -0
- package/lib/types/ink/components/Box.js +153 -0
- package/lib/types/ink/components/Button.d.ts +37 -0
- package/lib/types/ink/components/Button.d.ts.map +1 -0
- package/lib/types/ink/components/Button.js +166 -0
- package/lib/types/ink/components/ClockContext.d.ts +10 -0
- package/lib/types/ink/components/ClockContext.d.ts.map +1 -0
- package/lib/types/ink/components/ClockContext.js +108 -0
- package/lib/types/ink/components/CursorDeclarationContext.d.ts +30 -0
- package/lib/types/ink/components/CursorDeclarationContext.d.ts.map +1 -0
- package/lib/types/ink/components/CursorDeclarationContext.js +6 -0
- package/lib/types/ink/components/ErrorOverview.d.ts +7 -0
- package/lib/types/ink/components/ErrorOverview.d.ts.map +1 -0
- package/lib/types/ink/components/ErrorOverview.js +49 -0
- package/lib/types/ink/components/Link.d.ts +8 -0
- package/lib/types/ink/components/Link.d.ts.map +1 -0
- package/lib/types/ink/components/Link.js +33 -0
- package/lib/types/ink/components/Newline.d.ts +13 -0
- package/lib/types/ink/components/Newline.d.ts.map +1 -0
- package/lib/types/ink/components/Newline.js +29 -0
- package/lib/types/ink/components/NoSelect.d.ts +20 -0
- package/lib/types/ink/components/NoSelect.d.ts.map +1 -0
- package/lib/types/ink/components/NoSelect.js +56 -0
- package/lib/types/ink/components/RawAnsi.d.ts +17 -0
- package/lib/types/ink/components/RawAnsi.d.ts.map +1 -0
- package/lib/types/ink/components/RawAnsi.js +45 -0
- package/lib/types/ink/components/ScrollBox.d.ts +78 -0
- package/lib/types/ink/components/ScrollBox.d.ts.map +1 -0
- package/lib/types/ink/components/ScrollBox.js +174 -0
- package/lib/types/ink/components/Spacer.d.ts +6 -0
- package/lib/types/ink/components/Spacer.d.ts.map +1 -0
- package/lib/types/ink/components/Spacer.js +19 -0
- package/lib/types/ink/components/StdinContext.d.ts +32 -0
- package/lib/types/ink/components/StdinContext.d.ts.map +1 -0
- package/lib/types/ink/components/StdinContext.js +16 -0
- package/lib/types/ink/components/TerminalFocusContext.d.ts +11 -0
- package/lib/types/ink/components/TerminalFocusContext.d.ts.map +1 -0
- package/lib/types/ink/components/TerminalFocusContext.js +45 -0
- package/lib/types/ink/components/TerminalSizeContext.d.ts +6 -0
- package/lib/types/ink/components/TerminalSizeContext.d.ts.map +1 -0
- package/lib/types/ink/components/TerminalSizeContext.js +3 -0
- package/lib/types/ink/components/Text.d.ts +56 -0
- package/lib/types/ink/components/Text.d.ts.map +1 -0
- package/lib/types/ink/components/Text.js +194 -0
- package/lib/types/ink/constants.d.ts +3 -0
- package/lib/types/ink/constants.d.ts.map +1 -0
- package/lib/types/ink/constants.js +2 -0
- package/lib/types/ink/cursor.d.ts +11 -0
- package/lib/types/ink/cursor.d.ts.map +1 -0
- package/lib/types/ink/cursor.js +1 -0
- package/lib/types/ink/devtools.d.ts +7 -0
- package/lib/types/ink/devtools.d.ts.map +1 -0
- package/lib/types/ink/devtools.js +1 -0
- package/lib/types/ink/dom.d.ts +178 -0
- package/lib/types/ink/dom.d.ts.map +1 -0
- package/lib/types/ink/dom.js +424 -0
- package/lib/types/ink/events/click-event.d.ts +32 -0
- package/lib/types/ink/events/click-event.d.ts.map +1 -0
- package/lib/types/ink/events/click-event.js +36 -0
- package/lib/types/ink/events/dispatcher.d.ts +63 -0
- package/lib/types/ink/events/dispatcher.d.ts.map +1 -0
- package/lib/types/ink/events/dispatcher.js +194 -0
- package/lib/types/ink/events/emitter.d.ts +20 -0
- package/lib/types/ink/events/emitter.d.ts.map +1 -0
- package/lib/types/ink/events/emitter.js +43 -0
- package/lib/types/ink/events/event-handlers.d.ts +47 -0
- package/lib/types/ink/events/event-handlers.d.ts.map +1 -0
- package/lib/types/ink/events/event-handlers.js +30 -0
- package/lib/types/ink/events/event.d.ts +19 -0
- package/lib/types/ink/events/event.d.ts.map +1 -0
- package/lib/types/ink/events/event.js +22 -0
- package/lib/types/ink/events/focus-event.d.ts +19 -0
- package/lib/types/ink/events/focus-event.d.ts.map +1 -0
- package/lib/types/ink/events/focus-event.js +21 -0
- package/lib/types/ink/events/input-event.d.ts +53 -0
- package/lib/types/ink/events/input-event.d.ts.map +1 -0
- package/lib/types/ink/events/input-event.js +180 -0
- package/lib/types/ink/events/keyboard-event.d.ts +40 -0
- package/lib/types/ink/events/keyboard-event.d.ts.map +1 -0
- package/lib/types/ink/events/keyboard-event.js +65 -0
- package/lib/types/ink/events/paste-event.d.ts +11 -0
- package/lib/types/ink/events/paste-event.d.ts.map +1 -0
- package/lib/types/ink/events/paste-event.js +13 -0
- package/lib/types/ink/events/resize-event.d.ts +13 -0
- package/lib/types/ink/events/resize-event.d.ts.map +1 -0
- package/lib/types/ink/events/resize-event.js +16 -0
- package/lib/types/ink/events/terminal-event.d.ts +112 -0
- package/lib/types/ink/events/terminal-event.d.ts.map +1 -0
- package/lib/types/ink/events/terminal-event.js +131 -0
- package/lib/types/ink/events/terminal-focus-event.d.ts +21 -0
- package/lib/types/ink/events/terminal-focus-event.d.ts.map +1 -0
- package/lib/types/ink/events/terminal-focus-event.js +18 -0
- package/lib/types/ink/focus.d.ts +74 -0
- package/lib/types/ink/focus.d.ts.map +1 -0
- package/lib/types/ink/focus.js +188 -0
- package/lib/types/ink/frame.d.ts +119 -0
- package/lib/types/ink/frame.d.ts.map +1 -0
- package/lib/types/ink/frame.js +43 -0
- package/lib/types/ink/get-max-width.d.ts +20 -0
- package/lib/types/ink/get-max-width.d.ts.map +1 -0
- package/lib/types/ink/get-max-width.js +25 -0
- package/lib/types/ink/hit-test.d.ts +47 -0
- package/lib/types/ink/hit-test.d.ts.map +1 -0
- package/lib/types/ink/hit-test.js +126 -0
- package/lib/types/ink/hooks/use-animation-frame.d.ts +27 -0
- package/lib/types/ink/hooks/use-animation-frame.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-animation-frame.js +48 -0
- package/lib/types/ink/hooks/use-app.d.ts +8 -0
- package/lib/types/ink/hooks/use-app.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-app.js +8 -0
- package/lib/types/ink/hooks/use-copy-on-select.d.ts +22 -0
- package/lib/types/ink/hooks/use-copy-on-select.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-copy-on-select.js +40 -0
- package/lib/types/ink/hooks/use-declared-cursor.d.ts +31 -0
- package/lib/types/ink/hooks/use-declared-cursor.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-declared-cursor.js +65 -0
- package/lib/types/ink/hooks/use-input.d.ts +41 -0
- package/lib/types/ink/hooks/use-input.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-input.js +73 -0
- package/lib/types/ink/hooks/use-interval.d.ts +23 -0
- package/lib/types/ink/hooks/use-interval.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-interval.js +58 -0
- package/lib/types/ink/hooks/use-search-highlight.d.ts +34 -0
- package/lib/types/ink/hooks/use-search-highlight.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-search-highlight.js +35 -0
- package/lib/types/ink/hooks/use-selection.d.ts +44 -0
- package/lib/types/ink/hooks/use-selection.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-selection.js +64 -0
- package/lib/types/ink/hooks/use-stdin.d.ts +8 -0
- package/lib/types/ink/hooks/use-stdin.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-stdin.js +8 -0
- package/lib/types/ink/hooks/use-tab-status.d.ts +18 -0
- package/lib/types/ink/hooks/use-tab-status.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-tab-status.js +58 -0
- package/lib/types/ink/hooks/use-terminal-focus.d.ts +11 -0
- package/lib/types/ink/hooks/use-terminal-focus.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-terminal-focus.js +15 -0
- package/lib/types/ink/hooks/use-terminal-size.d.ts +6 -0
- package/lib/types/ink/hooks/use-terminal-size.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-terminal-size.js +12 -0
- package/lib/types/ink/hooks/use-terminal-title.d.ts +14 -0
- package/lib/types/ink/hooks/use-terminal-title.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-terminal-title.js +30 -0
- package/lib/types/ink/hooks/use-terminal-viewport.d.ts +32 -0
- package/lib/types/ink/hooks/use-terminal-viewport.d.ts.map +1 -0
- package/lib/types/ink/hooks/use-terminal-viewport.js +79 -0
- package/lib/types/ink/ink.d.ts +370 -0
- package/lib/types/ink/ink.d.ts.map +1 -0
- package/lib/types/ink/ink.js +1665 -0
- package/lib/types/ink/instances.d.ts +10 -0
- package/lib/types/ink/instances.d.ts.map +1 -0
- package/lib/types/ink/instances.js +13 -0
- package/lib/types/ink/layout/engine.d.ts +7 -0
- package/lib/types/ink/layout/engine.d.ts.map +1 -0
- package/lib/types/ink/layout/engine.js +8 -0
- package/lib/types/ink/layout/geometry.d.ts +86 -0
- package/lib/types/ink/layout/geometry.d.ts.map +1 -0
- package/lib/types/ink/layout/geometry.js +95 -0
- package/lib/types/ink/layout/node.d.ts +151 -0
- package/lib/types/ink/layout/node.d.ts.map +1 -0
- package/lib/types/ink/layout/node.js +72 -0
- package/lib/types/ink/layout/yoga.d.ts +69 -0
- package/lib/types/ink/layout/yoga.d.ts.map +1 -0
- package/lib/types/ink/layout/yoga.js +249 -0
- package/lib/types/ink/line-width-cache.d.ts +9 -0
- package/lib/types/ink/line-width-cache.d.ts.map +1 -0
- package/lib/types/ink/line-width-cache.js +45 -0
- package/lib/types/ink/log-update.d.ts +57 -0
- package/lib/types/ink/log-update.d.ts.map +1 -0
- package/lib/types/ink/log-update.js +710 -0
- package/lib/types/ink/measure-element.d.ts +19 -0
- package/lib/types/ink/measure-element.d.ts.map +1 -0
- package/lib/types/ink/measure-element.js +10 -0
- package/lib/types/ink/measure-text.d.ts +13 -0
- package/lib/types/ink/measure-text.d.ts.map +1 -0
- package/lib/types/ink/measure-text.js +38 -0
- package/lib/types/ink/node-cache.d.ts +33 -0
- package/lib/types/ink/node-cache.d.ts.map +1 -0
- package/lib/types/ink/node-cache.js +42 -0
- package/lib/types/ink/optimizer.d.ts +18 -0
- package/lib/types/ink/optimizer.d.ts.map +1 -0
- package/lib/types/ink/optimizer.js +83 -0
- package/lib/types/ink/output.d.ts +200 -0
- package/lib/types/ink/output.d.ts.map +1 -0
- package/lib/types/ink/output.js +663 -0
- package/lib/types/ink/parse-keypress.d.ts +132 -0
- package/lib/types/ink/parse-keypress.d.ts.map +1 -0
- package/lib/types/ink/parse-keypress.js +707 -0
- package/lib/types/ink/reconciler.d.ts +43 -0
- package/lib/types/ink/reconciler.d.ts.map +1 -0
- package/lib/types/ink/reconciler.js +413 -0
- package/lib/types/ink/render-border.d.ts +36 -0
- package/lib/types/ink/render-border.d.ts.map +1 -0
- package/lib/types/ink/render-border.js +143 -0
- package/lib/types/ink/render-node-to-output.d.ts +93 -0
- package/lib/types/ink/render-node-to-output.d.ts.map +1 -0
- package/lib/types/ink/render-node-to-output.js +1290 -0
- package/lib/types/ink/render-to-screen.d.ts +65 -0
- package/lib/types/ink/render-to-screen.d.ts.map +1 -0
- package/lib/types/ink/render-to-screen.js +189 -0
- package/lib/types/ink/renderer.d.ts +24 -0
- package/lib/types/ink/renderer.d.ts.map +1 -0
- package/lib/types/ink/renderer.js +136 -0
- package/lib/types/ink/root.d.ts +91 -0
- package/lib/types/ink/root.d.ts.map +1 -0
- package/lib/types/ink/root.js +93 -0
- package/lib/types/ink/screen.d.ts +443 -0
- package/lib/types/ink/screen.d.ts.map +1 -0
- package/lib/types/ink/screen.js +1295 -0
- package/lib/types/ink/searchHighlight.d.ts +25 -0
- package/lib/types/ink/searchHighlight.d.ts.map +1 -0
- package/lib/types/ink/searchHighlight.js +82 -0
- package/lib/types/ink/selection.d.ts +323 -0
- package/lib/types/ink/selection.d.ts.map +1 -0
- package/lib/types/ink/selection.js +881 -0
- package/lib/types/ink/squash-text-nodes.d.ts +30 -0
- package/lib/types/ink/squash-text-nodes.d.ts.map +1 -0
- package/lib/types/ink/squash-text-nodes.js +63 -0
- package/lib/types/ink/stringWidth.d.ts +11 -0
- package/lib/types/ink/stringWidth.d.ts.map +1 -0
- package/lib/types/ink/stringWidth.js +209 -0
- package/lib/types/ink/styles.d.ts +324 -0
- package/lib/types/ink/styles.d.ts.map +1 -0
- package/lib/types/ink/styles.js +307 -0
- package/lib/types/ink/supports-hyperlinks.d.ts +20 -0
- package/lib/types/ink/supports-hyperlinks.d.ts.map +1 -0
- package/lib/types/ink/supports-hyperlinks.js +44 -0
- package/lib/types/ink/tabstops.d.ts +9 -0
- package/lib/types/ink/tabstops.d.ts.map +1 -0
- package/lib/types/ink/tabstops.js +46 -0
- package/lib/types/ink/terminal-focus-state.d.ts +35 -0
- package/lib/types/ink/terminal-focus-state.d.ts.map +1 -0
- package/lib/types/ink/terminal-focus-state.js +57 -0
- package/lib/types/ink/terminal-querier.d.ts +161 -0
- package/lib/types/ink/terminal-querier.d.ts.map +1 -0
- package/lib/types/ink/terminal-querier.js +204 -0
- package/lib/types/ink/terminal.d.ts +80 -0
- package/lib/types/ink/terminal.d.ts.map +1 -0
- package/lib/types/ink/terminal.js +268 -0
- package/lib/types/ink/termio/ansi.d.ts +75 -0
- package/lib/types/ink/termio/ansi.d.ts.map +1 -0
- package/lib/types/ink/termio/ansi.js +79 -0
- package/lib/types/ink/termio/csi.d.ts +253 -0
- package/lib/types/ink/termio/csi.d.ts.map +1 -0
- package/lib/types/ink/termio/csi.js +347 -0
- package/lib/types/ink/termio/dec.d.ts +61 -0
- package/lib/types/ink/termio/dec.d.ts.map +1 -0
- package/lib/types/ink/termio/dec.js +76 -0
- package/lib/types/ink/termio/esc.d.ts +15 -0
- package/lib/types/ink/termio/esc.d.ts.map +1 -0
- package/lib/types/ink/termio/esc.js +57 -0
- package/lib/types/ink/termio/osc.d.ts +208 -0
- package/lib/types/ink/termio/osc.d.ts.map +1 -0
- package/lib/types/ink/termio/osc.js +466 -0
- package/lib/types/ink/termio/parser.d.ts +46 -0
- package/lib/types/ink/termio/parser.d.ts.map +1 -0
- package/lib/types/ink/termio/parser.js +366 -0
- package/lib/types/ink/termio/sgr.d.ts +17 -0
- package/lib/types/ink/termio/sgr.d.ts.map +1 -0
- package/lib/types/ink/termio/sgr.js +300 -0
- package/lib/types/ink/termio/tokenize.d.ts +50 -0
- package/lib/types/ink/termio/tokenize.d.ts.map +1 -0
- package/lib/types/ink/termio/tokenize.js +266 -0
- package/lib/types/ink/termio/types.d.ts +211 -0
- package/lib/types/ink/termio/types.d.ts.map +1 -0
- package/lib/types/ink/termio/types.js +68 -0
- package/lib/types/ink/termio.d.ts +25 -0
- package/lib/types/ink/termio.d.ts.map +1 -0
- package/lib/types/ink/termio.js +24 -0
- package/lib/types/ink/truncateToWidth.d.ts +7 -0
- package/lib/types/ink/truncateToWidth.d.ts.map +1 -0
- package/lib/types/ink/truncateToWidth.js +18 -0
- package/lib/types/ink/useTerminalNotification.d.ts +45 -0
- package/lib/types/ink/useTerminalNotification.d.ts.map +1 -0
- package/lib/types/ink/useTerminalNotification.js +70 -0
- package/lib/types/ink/warn.d.ts +7 -0
- package/lib/types/ink/warn.d.ts.map +1 -0
- package/lib/types/ink/warn.js +15 -0
- package/lib/types/ink/widest-line.d.ts +7 -0
- package/lib/types/ink/widest-line.d.ts.map +1 -0
- package/lib/types/ink/widest-line.js +19 -0
- package/lib/types/ink/wrap-text.d.ts +10 -0
- package/lib/types/ink/wrap-text.d.ts.map +1 -0
- package/lib/types/ink/wrap-text.js +61 -0
- package/lib/types/ink/wrapAnsi.d.ts +18 -0
- package/lib/types/ink/wrapAnsi.d.ts.map +1 -0
- package/lib/types/ink/wrapAnsi.js +16 -0
- package/lib/types/invariant.d.ts +20 -0
- package/lib/types/invariant.d.ts.map +1 -0
- package/lib/types/invariant.js +26 -0
- package/lib/types/modelPrefs.d.ts +37 -0
- package/lib/types/modelPrefs.d.ts.map +1 -0
- package/lib/types/modelPrefs.js +66 -0
- package/lib/types/modelRoute.d.ts +79 -0
- package/lib/types/modelRoute.d.ts.map +1 -0
- package/lib/types/modelRoute.js +96 -0
- package/lib/types/native-ts/yoga-layout/enums.d.ts +183 -0
- package/lib/types/native-ts/yoga-layout/enums.d.ts.map +1 -0
- package/lib/types/native-ts/yoga-layout/enums.js +150 -0
- package/lib/types/native-ts/yoga-layout/index.d.ts +788 -0
- package/lib/types/native-ts/yoga-layout/index.d.ts.map +1 -0
- package/lib/types/native-ts/yoga-layout/index.js +2571 -0
- package/lib/types/packaged-skills.d.ts +10 -0
- package/lib/types/packaged-skills.d.ts.map +1 -0
- package/lib/types/packaged-skills.js +63 -0
- package/lib/types/plugin.d.ts +33 -0
- package/lib/types/plugin.d.ts.map +1 -0
- package/lib/types/plugin.js +454 -0
- package/lib/types/presetPrefs.d.ts +29 -0
- package/lib/types/presetPrefs.d.ts.map +1 -0
- package/lib/types/presetPrefs.js +61 -0
- package/lib/types/presets.d.ts +110 -0
- package/lib/types/presets.d.ts.map +1 -0
- package/lib/types/presets.js +114 -0
- package/lib/types/questions.d.ts +97 -0
- package/lib/types/questions.d.ts.map +1 -0
- package/lib/types/questions.js +201 -0
- package/lib/types/screens/Chat.d.ts +23 -0
- package/lib/types/screens/Chat.d.ts.map +1 -0
- package/lib/types/screens/Chat.js +1263 -0
- package/lib/types/screens/StatusLine.d.ts +16 -0
- package/lib/types/screens/StatusLine.d.ts.map +1 -0
- package/lib/types/screens/StatusLine.js +105 -0
- package/lib/types/screens/StatusMetrics.d.ts +87 -0
- package/lib/types/screens/StatusMetrics.d.ts.map +1 -0
- package/lib/types/screens/StatusMetrics.js +252 -0
- package/lib/types/sessionHistory.d.ts +32 -0
- package/lib/types/sessionHistory.d.ts.map +1 -0
- package/lib/types/sessionHistory.js +87 -0
- package/lib/types/theme.d.ts +115 -0
- package/lib/types/theme.d.ts.map +1 -0
- package/lib/types/theme.js +300 -0
- package/lib/types/themePrefs.d.ts +28 -0
- package/lib/types/themePrefs.d.ts.map +1 -0
- package/lib/types/themePrefs.js +59 -0
- package/lib/types/ui.d.ts +28 -0
- package/lib/types/ui.d.ts.map +1 -0
- package/lib/types/ui.js +25 -0
- package/lib/types/update.d.ts +76 -0
- package/lib/types/update.d.ts.map +1 -0
- package/lib/types/update.js +203 -0
- package/lib/types/utils/clipboard.d.ts +43 -0
- package/lib/types/utils/clipboard.d.ts.map +1 -0
- package/lib/types/utils/clipboard.js +82 -0
- package/lib/types/utils/debug.d.ts +8 -0
- package/lib/types/utils/debug.d.ts.map +1 -0
- package/lib/types/utils/debug.js +12 -0
- package/lib/types/utils/earlyInput.d.ts +7 -0
- package/lib/types/utils/earlyInput.d.ts.map +1 -0
- package/lib/types/utils/earlyInput.js +6 -0
- package/lib/types/utils/env.d.ts +10 -0
- package/lib/types/utils/env.d.ts.map +1 -0
- package/lib/types/utils/env.js +9 -0
- package/lib/types/utils/envUtils.d.ts +8 -0
- package/lib/types/utils/envUtils.d.ts.map +1 -0
- package/lib/types/utils/envUtils.js +13 -0
- package/lib/types/utils/execFileNoThrow.d.ts +34 -0
- package/lib/types/utils/execFileNoThrow.d.ts.map +1 -0
- package/lib/types/utils/execFileNoThrow.js +31 -0
- package/lib/types/utils/fullscreen.d.ts +8 -0
- package/lib/types/utils/fullscreen.d.ts.map +1 -0
- package/lib/types/utils/fullscreen.js +10 -0
- package/lib/types/utils/intl.d.ts +7 -0
- package/lib/types/utils/intl.d.ts.map +1 -0
- package/lib/types/utils/intl.js +9 -0
- package/lib/types/utils/loaded-context.d.ts +20 -0
- package/lib/types/utils/loaded-context.d.ts.map +1 -0
- package/lib/types/utils/loaded-context.js +36 -0
- package/lib/types/utils/log.d.ts +7 -0
- package/lib/types/utils/log.d.ts.map +1 -0
- package/lib/types/utils/log.js +9 -0
- package/lib/types/utils/mentions.d.ts +30 -0
- package/lib/types/utils/mentions.d.ts.map +1 -0
- package/lib/types/utils/mentions.js +72 -0
- package/lib/types/utils/narration.d.ts +11 -0
- package/lib/types/utils/narration.d.ts.map +1 -0
- package/lib/types/utils/narration.js +16 -0
- package/lib/types/utils/semver.d.ts +9 -0
- package/lib/types/utils/semver.d.ts.map +1 -0
- package/lib/types/utils/semver.js +24 -0
- package/lib/types/utils/sliceAnsi.d.ts +12 -0
- package/lib/types/utils/sliceAnsi.d.ts.map +1 -0
- package/lib/types/utils/sliceAnsi.js +79 -0
- package/lib/types/working-activity.d.ts +19 -0
- package/lib/types/working-activity.d.ts.map +1 -0
- package/lib/types/working-activity.js +18 -0
- package/package.json +141 -0
- package/skills/audit/SKILL.md +24 -0
- package/skills/bug/SKILL.md +27 -0
- package/skills/pr-comments/SKILL.md +20 -0
- package/skills/practice/SKILL.md +22 -0
- package/skills/release-notes/SKILL.md +25 -0
- package/skills/review/SKILL.md +25 -0
- package/skills/vuln-check/SKILL.md +25 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import { type Screen, StylePool } from './screen.js';
|
|
3
|
+
/** Position of a match within a rendered message, relative to the message's
|
|
4
|
+
* own bounding box (row 0 = message top). Stable across scroll — to
|
|
5
|
+
* highlight on the real screen, add the message's screen-row offset. */
|
|
6
|
+
export type MatchPosition = {
|
|
7
|
+
row: number;
|
|
8
|
+
col: number;
|
|
9
|
+
/** Number of CELLS the match spans (= query.length for ASCII, more
|
|
10
|
+
* for wide chars in the query). */
|
|
11
|
+
len: number;
|
|
12
|
+
};
|
|
13
|
+
/** Render a React element (wrapped in all contexts the component needs —
|
|
14
|
+
* caller's job) to an isolated Screen buffer at the given width. Returns
|
|
15
|
+
* the Screen + natural height (from yoga). Used for search: render ONE
|
|
16
|
+
* message, scan its Screen for the query, get exact (row, col) positions.
|
|
17
|
+
*
|
|
18
|
+
* ~1-3ms per call (yoga alloc + calculateLayout + paint). The
|
|
19
|
+
* flushSyncWork cross-root leak measured ~0.0003ms/call growth — fine
|
|
20
|
+
* for on-demand single-message rendering, pathological for render-all-
|
|
21
|
+
* 8k-upfront. Cache per (msg, query, width) upstream.
|
|
22
|
+
*
|
|
23
|
+
* Unmounts between calls. Root/container/pools persist for reuse.
|
|
24
|
+
*
|
|
25
|
+
* @param el - the React element to render.
|
|
26
|
+
* @param width - the render width in columns.
|
|
27
|
+
* @returns the painted screen buffer and the yoga-computed content height.
|
|
28
|
+
*/
|
|
29
|
+
export declare function renderToScreen(el: ReactElement, width: number): {
|
|
30
|
+
screen: Screen;
|
|
31
|
+
height: number;
|
|
32
|
+
};
|
|
33
|
+
/** Scan a Screen buffer for all occurrences of query. Returns positions
|
|
34
|
+
* relative to the buffer (row 0 = buffer top). Same cell-skip logic as
|
|
35
|
+
* applySearchHighlight (SpacerTail/SpacerHead/noSelect) so positions
|
|
36
|
+
* match what the overlay highlight would find. Case-insensitive.
|
|
37
|
+
*
|
|
38
|
+
* For the side-render use: this Screen is the FULL message (natural
|
|
39
|
+
* height, not viewport-clipped). Positions are stable — to highlight
|
|
40
|
+
* on the real screen, add the message's screen offset (lo).
|
|
41
|
+
*
|
|
42
|
+
* @param screen - the screen buffer to scan.
|
|
43
|
+
* @param query - the substring to search for, matched case-insensitively.
|
|
44
|
+
* @returns the match positions relative to the buffer, or an empty list.
|
|
45
|
+
*/
|
|
46
|
+
export declare function scanPositions(screen: Screen, query: string): MatchPosition[];
|
|
47
|
+
/** Write CURRENT (yellow+bold+underline) at positions[currentIdx] +
|
|
48
|
+
* rowOffset. OTHER positions are NOT styled here — the scan-highlight
|
|
49
|
+
* (applySearchHighlight with null hint) does inverse for all visible
|
|
50
|
+
* matches, including these. Two-layer: scan = 'you could go here',
|
|
51
|
+
* position = 'you ARE here'. Writing inverse again here would be a
|
|
52
|
+
* no-op (withInverse idempotent) but wasted work.
|
|
53
|
+
*
|
|
54
|
+
* Positions are message-relative (row 0 = message top). rowOffset =
|
|
55
|
+
* message's current screen-top (lo). Clips outside [0, height).
|
|
56
|
+
*
|
|
57
|
+
* @param screen - the screen buffer to style.
|
|
58
|
+
* @param stylePool - the style pool providing the current-match transform.
|
|
59
|
+
* @param positions - the message-relative match positions.
|
|
60
|
+
* @param rowOffset - the message's current screen-top row.
|
|
61
|
+
* @param currentIdx - index into positions of the match to highlight.
|
|
62
|
+
* @returns true when the highlight was written, false when out of range.
|
|
63
|
+
*/
|
|
64
|
+
export declare function applyPositionedHighlight(screen: Screen, stylePool: StylePool, positions: MatchPosition[], rowOffset: number, currentIdx: number): boolean;
|
|
65
|
+
//# sourceMappingURL=render-to-screen.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-to-screen.d.ts","sourceRoot":"","sources":["../../../src/ink/render-to-screen.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAUzC,OAAO,EAML,KAAK,MAAM,EACX,SAAS,EAEV,MAAM,aAAa,CAAA;AAEpB;;yEAEyE;AACzE,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX;wCACoC;IACpC,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAgBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAC5B,EAAE,EAAE,YAAY,EAChB,KAAK,EAAE,MAAM,GACZ;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CA6EpC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,aAAa,EAAE,CAoD5E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,aAAa,EAAE,EAC1B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAaT"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import noop from 'lodash-es/noop.js';
|
|
2
|
+
import { LegacyRoot } from 'react-reconciler/constants.js';
|
|
3
|
+
import { logForDebugging } from '../utils/debug.js';
|
|
4
|
+
import { createNode } from './dom.js';
|
|
5
|
+
import { FocusManager } from './focus.js';
|
|
6
|
+
import Output from './output.js';
|
|
7
|
+
import reconciler from './reconciler.js';
|
|
8
|
+
import renderNodeToOutput, { resetLayoutShifted, } from './render-node-to-output.js';
|
|
9
|
+
import { CharPool, cellAtIndex, createScreen, HyperlinkPool, StylePool, setCellStyleId, } from './screen.js';
|
|
10
|
+
// Shared across calls. Pools accumulate style/char interns — reusing them
|
|
11
|
+
// means later calls hit cache more. Root/container reuse saves the
|
|
12
|
+
// createContainer cost (~1ms). LegacyRoot: all work sync, no scheduling —
|
|
13
|
+
// ConcurrentRoot's scheduler backlog leaks across roots via flushSyncWork.
|
|
14
|
+
let root;
|
|
15
|
+
let container;
|
|
16
|
+
let stylePool;
|
|
17
|
+
let charPool;
|
|
18
|
+
let hyperlinkPool;
|
|
19
|
+
let output;
|
|
20
|
+
const timing = { reconcile: 0, yoga: 0, paint: 0, scan: 0, calls: 0 };
|
|
21
|
+
const LOG_EVERY = 20;
|
|
22
|
+
/** Render a React element (wrapped in all contexts the component needs —
|
|
23
|
+
* caller's job) to an isolated Screen buffer at the given width. Returns
|
|
24
|
+
* the Screen + natural height (from yoga). Used for search: render ONE
|
|
25
|
+
* message, scan its Screen for the query, get exact (row, col) positions.
|
|
26
|
+
*
|
|
27
|
+
* ~1-3ms per call (yoga alloc + calculateLayout + paint). The
|
|
28
|
+
* flushSyncWork cross-root leak measured ~0.0003ms/call growth — fine
|
|
29
|
+
* for on-demand single-message rendering, pathological for render-all-
|
|
30
|
+
* 8k-upfront. Cache per (msg, query, width) upstream.
|
|
31
|
+
*
|
|
32
|
+
* Unmounts between calls. Root/container/pools persist for reuse.
|
|
33
|
+
*
|
|
34
|
+
* @param el - the React element to render.
|
|
35
|
+
* @param width - the render width in columns.
|
|
36
|
+
* @returns the painted screen buffer and the yoga-computed content height.
|
|
37
|
+
*/
|
|
38
|
+
export function renderToScreen(el, width) {
|
|
39
|
+
if (!root) {
|
|
40
|
+
root = createNode('ink-root');
|
|
41
|
+
root.focusManager = new FocusManager(() => false);
|
|
42
|
+
stylePool = new StylePool();
|
|
43
|
+
charPool = new CharPool();
|
|
44
|
+
hyperlinkPool = new HyperlinkPool();
|
|
45
|
+
// @ts-ignore -- ported CC build; type drift tolerated react-reconciler 0.33 takes 10 args; @types says 11
|
|
46
|
+
container = reconciler.createContainer(root, LegacyRoot, null, false, null, 'search-render', noop, noop, noop, noop);
|
|
47
|
+
}
|
|
48
|
+
const t0 = performance.now();
|
|
49
|
+
// @ts-ignore -- ported CC build; type drift tolerated updateContainerSync exists but not in @types
|
|
50
|
+
reconciler.updateContainerSync(el, container, null, noop);
|
|
51
|
+
// @ts-ignore -- ported CC build; type drift tolerated flushSyncWork exists but not in @types
|
|
52
|
+
reconciler.flushSyncWork();
|
|
53
|
+
const t1 = performance.now();
|
|
54
|
+
// Yoga layout. Root might not have a yogaNode if the tree is empty.
|
|
55
|
+
root.yogaNode?.setWidth(width);
|
|
56
|
+
root.yogaNode?.calculateLayout(width);
|
|
57
|
+
const height = Math.ceil(root.yogaNode?.getComputedHeight() ?? 0);
|
|
58
|
+
const t2 = performance.now();
|
|
59
|
+
// Paint to a fresh Screen. Width = given, height = yoga's natural.
|
|
60
|
+
// No alt-screen, no prevScreen (every call is fresh).
|
|
61
|
+
const screen = createScreen(width, Math.max(1, height), // avoid 0-height Screen (createScreen may choke)
|
|
62
|
+
stylePool, charPool, hyperlinkPool);
|
|
63
|
+
if (!output) {
|
|
64
|
+
output = new Output({ width, height, stylePool: stylePool, screen });
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
output.reset(width, height, screen);
|
|
68
|
+
}
|
|
69
|
+
resetLayoutShifted();
|
|
70
|
+
renderNodeToOutput(root, output, { prevScreen: undefined });
|
|
71
|
+
// renderNodeToOutput queues writes into Output; .get() flushes the
|
|
72
|
+
// queue into the Screen's cell arrays. Without this the screen is
|
|
73
|
+
// blank (constructor-zero).
|
|
74
|
+
const rendered = output.get();
|
|
75
|
+
const t3 = performance.now();
|
|
76
|
+
// Unmount so next call gets a fresh tree. Leaves root/container/pools.
|
|
77
|
+
// @ts-ignore -- ported CC build; type drift tolerated updateContainerSync exists but not in @types
|
|
78
|
+
reconciler.updateContainerSync(null, container, null, noop);
|
|
79
|
+
// @ts-ignore -- ported CC build; type drift tolerated flushSyncWork exists but not in @types
|
|
80
|
+
reconciler.flushSyncWork();
|
|
81
|
+
timing.reconcile += t1 - t0;
|
|
82
|
+
timing.yoga += t2 - t1;
|
|
83
|
+
timing.paint += t3 - t2;
|
|
84
|
+
if (++timing.calls % LOG_EVERY === 0) {
|
|
85
|
+
const total = timing.reconcile + timing.yoga + timing.paint + timing.scan;
|
|
86
|
+
logForDebugging(`renderToScreen: ${timing.calls} calls · ` +
|
|
87
|
+
`reconcile=${timing.reconcile.toFixed(1)}ms yoga=${timing.yoga.toFixed(1)}ms ` +
|
|
88
|
+
`paint=${timing.paint.toFixed(1)}ms scan=${timing.scan.toFixed(1)}ms · ` +
|
|
89
|
+
`total=${total.toFixed(1)}ms · avg ${(total / timing.calls).toFixed(2)}ms/call`);
|
|
90
|
+
}
|
|
91
|
+
return { screen: rendered, height };
|
|
92
|
+
}
|
|
93
|
+
/** Scan a Screen buffer for all occurrences of query. Returns positions
|
|
94
|
+
* relative to the buffer (row 0 = buffer top). Same cell-skip logic as
|
|
95
|
+
* applySearchHighlight (SpacerTail/SpacerHead/noSelect) so positions
|
|
96
|
+
* match what the overlay highlight would find. Case-insensitive.
|
|
97
|
+
*
|
|
98
|
+
* For the side-render use: this Screen is the FULL message (natural
|
|
99
|
+
* height, not viewport-clipped). Positions are stable — to highlight
|
|
100
|
+
* on the real screen, add the message's screen offset (lo).
|
|
101
|
+
*
|
|
102
|
+
* @param screen - the screen buffer to scan.
|
|
103
|
+
* @param query - the substring to search for, matched case-insensitively.
|
|
104
|
+
* @returns the match positions relative to the buffer, or an empty list.
|
|
105
|
+
*/
|
|
106
|
+
export function scanPositions(screen, query) {
|
|
107
|
+
const lq = query.toLowerCase();
|
|
108
|
+
if (!lq)
|
|
109
|
+
return [];
|
|
110
|
+
const qlen = lq.length;
|
|
111
|
+
const w = screen.width;
|
|
112
|
+
const h = screen.height;
|
|
113
|
+
const noSelect = screen.noSelect;
|
|
114
|
+
const positions = [];
|
|
115
|
+
const t0 = performance.now();
|
|
116
|
+
for (let row = 0; row < h; row++) {
|
|
117
|
+
const rowOff = row * w;
|
|
118
|
+
// Same text-build as applySearchHighlight. Keep in sync — or extract
|
|
119
|
+
// to a shared helper (TODO once both are stable). codeUnitToCell
|
|
120
|
+
// maps indexOf positions (code units in the LOWERCASED text) to cell
|
|
121
|
+
// indices in colOf — surrogate pairs (emoji) and multi-unit lowercase
|
|
122
|
+
// (Turkish İ → i + U+0307) make text.length > colOf.length.
|
|
123
|
+
let text = '';
|
|
124
|
+
const colOf = [];
|
|
125
|
+
const codeUnitToCell = [];
|
|
126
|
+
for (let col = 0; col < w; col++) {
|
|
127
|
+
const idx = rowOff + col;
|
|
128
|
+
const cell = cellAtIndex(screen, idx);
|
|
129
|
+
if (cell.width === 2 /* CellWidth.SpacerTail */ ||
|
|
130
|
+
cell.width === 3 /* CellWidth.SpacerHead */ ||
|
|
131
|
+
noSelect[idx] === 1) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const lc = cell.char.toLowerCase();
|
|
135
|
+
const cellIdx = colOf.length;
|
|
136
|
+
for (let i = 0; i < lc.length; i++) {
|
|
137
|
+
codeUnitToCell.push(cellIdx);
|
|
138
|
+
}
|
|
139
|
+
text += lc;
|
|
140
|
+
colOf.push(col);
|
|
141
|
+
}
|
|
142
|
+
// Non-overlapping — same advance as applySearchHighlight.
|
|
143
|
+
let pos = text.indexOf(lq);
|
|
144
|
+
while (pos >= 0) {
|
|
145
|
+
const startCi = codeUnitToCell[pos];
|
|
146
|
+
const endCi = codeUnitToCell[pos + qlen - 1];
|
|
147
|
+
const col = colOf[startCi];
|
|
148
|
+
const endCol = colOf[endCi] + 1;
|
|
149
|
+
positions.push({ row, col, len: endCol - col });
|
|
150
|
+
pos = text.indexOf(lq, pos + qlen);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
timing.scan += performance.now() - t0;
|
|
154
|
+
return positions;
|
|
155
|
+
}
|
|
156
|
+
/** Write CURRENT (yellow+bold+underline) at positions[currentIdx] +
|
|
157
|
+
* rowOffset. OTHER positions are NOT styled here — the scan-highlight
|
|
158
|
+
* (applySearchHighlight with null hint) does inverse for all visible
|
|
159
|
+
* matches, including these. Two-layer: scan = 'you could go here',
|
|
160
|
+
* position = 'you ARE here'. Writing inverse again here would be a
|
|
161
|
+
* no-op (withInverse idempotent) but wasted work.
|
|
162
|
+
*
|
|
163
|
+
* Positions are message-relative (row 0 = message top). rowOffset =
|
|
164
|
+
* message's current screen-top (lo). Clips outside [0, height).
|
|
165
|
+
*
|
|
166
|
+
* @param screen - the screen buffer to style.
|
|
167
|
+
* @param stylePool - the style pool providing the current-match transform.
|
|
168
|
+
* @param positions - the message-relative match positions.
|
|
169
|
+
* @param rowOffset - the message's current screen-top row.
|
|
170
|
+
* @param currentIdx - index into positions of the match to highlight.
|
|
171
|
+
* @returns true when the highlight was written, false when out of range.
|
|
172
|
+
*/
|
|
173
|
+
export function applyPositionedHighlight(screen, stylePool, positions, rowOffset, currentIdx) {
|
|
174
|
+
if (currentIdx < 0 || currentIdx >= positions.length)
|
|
175
|
+
return false;
|
|
176
|
+
const p = positions[currentIdx];
|
|
177
|
+
const row = p.row + rowOffset;
|
|
178
|
+
if (row < 0 || row >= screen.height)
|
|
179
|
+
return false;
|
|
180
|
+
const transform = (id) => stylePool.withCurrentMatch(id);
|
|
181
|
+
const rowOff = row * screen.width;
|
|
182
|
+
for (let col = p.col; col < p.col + p.len; col++) {
|
|
183
|
+
if (col < 0 || col >= screen.width)
|
|
184
|
+
continue;
|
|
185
|
+
const cell = cellAtIndex(screen, rowOff + col);
|
|
186
|
+
setCellStyleId(screen, col, row, transform(cell.styleId));
|
|
187
|
+
}
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type DOMElement } from './dom.js';
|
|
2
|
+
import type { Frame } from './frame.js';
|
|
3
|
+
import { type StylePool } from './screen.js';
|
|
4
|
+
/** Options controlling one renderer pass over the DOM tree. */
|
|
5
|
+
export type RenderOptions = {
|
|
6
|
+
frontFrame: Frame;
|
|
7
|
+
backFrame: Frame;
|
|
8
|
+
isTTY: boolean;
|
|
9
|
+
terminalWidth: number;
|
|
10
|
+
terminalRows: number;
|
|
11
|
+
altScreen: boolean;
|
|
12
|
+
prevFrameContaminated: boolean;
|
|
13
|
+
};
|
|
14
|
+
/** Renders the DOM tree into a frame for the given options. */
|
|
15
|
+
export type Renderer = (options: RenderOptions) => Frame;
|
|
16
|
+
/**
|
|
17
|
+
* Create the renderer function for a root DOM node. The returned renderer
|
|
18
|
+
* reuses an Output across frames so its character cache persists.
|
|
19
|
+
* @param node - the root DOM node to render.
|
|
20
|
+
* @param stylePool - the style pool used for all frames.
|
|
21
|
+
* @returns a function that renders one frame from the given options.
|
|
22
|
+
*/
|
|
23
|
+
export default function createRenderer(node: DOMElement, stylePool: StylePool): Renderer;
|
|
24
|
+
//# sourceMappingURL=renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../../src/ink/renderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAa,MAAM,UAAU,CAAA;AACrD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAUvC,OAAO,EAAgB,KAAK,SAAS,EAAE,MAAM,aAAa,CAAA;AAE1D,+DAA+D;AAC/D,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,KAAK,CAAA;IACjB,SAAS,EAAE,KAAK,CAAA;IAChB,KAAK,EAAE,OAAO,CAAA;IACd,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,OAAO,CAAA;IAKlB,qBAAqB,EAAE,OAAO,CAAA;CAC/B,CAAA;AAED,+DAA+D;AAC/D,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,EAAE,aAAa,KAAK,KAAK,CAAA;AAExD;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,cAAc,CACpC,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,SAAS,GACnB,QAAQ,CAgJV"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { logForDebugging } from '../utils/debug.js';
|
|
2
|
+
import { markDirty } from './dom.js';
|
|
3
|
+
import { consumeAbsoluteRemovedFlag } from './node-cache.js';
|
|
4
|
+
import Output from './output.js';
|
|
5
|
+
import renderNodeToOutput, { getScrollDrainNode, getScrollHint, resetLayoutShifted, resetScrollDrainNode, resetScrollHint, } from './render-node-to-output.js';
|
|
6
|
+
import { createScreen } from './screen.js';
|
|
7
|
+
/**
|
|
8
|
+
* Create the renderer function for a root DOM node. The returned renderer
|
|
9
|
+
* reuses an Output across frames so its character cache persists.
|
|
10
|
+
* @param node - the root DOM node to render.
|
|
11
|
+
* @param stylePool - the style pool used for all frames.
|
|
12
|
+
* @returns a function that renders one frame from the given options.
|
|
13
|
+
*/
|
|
14
|
+
export default function createRenderer(node, stylePool) {
|
|
15
|
+
// Reuse Output across frames so charCache (tokenize + grapheme clustering)
|
|
16
|
+
// persists — most lines don't change between renders.
|
|
17
|
+
let output;
|
|
18
|
+
return options => {
|
|
19
|
+
const { frontFrame, backFrame, isTTY, terminalWidth, terminalRows } = options;
|
|
20
|
+
const prevScreen = frontFrame.screen;
|
|
21
|
+
const backScreen = backFrame.screen;
|
|
22
|
+
// Read pools from the back buffer's screen — pools may be replaced
|
|
23
|
+
// between frames (generational reset), so we can't capture them in the closure
|
|
24
|
+
const charPool = backScreen.charPool;
|
|
25
|
+
const hyperlinkPool = backScreen.hyperlinkPool;
|
|
26
|
+
// Return empty frame if yoga node doesn't exist or layout hasn't been computed yet.
|
|
27
|
+
// getComputedHeight() returns NaN before calculateLayout() is called.
|
|
28
|
+
// Also check for invalid dimensions (negative, Infinity) that would cause RangeError
|
|
29
|
+
// when creating arrays.
|
|
30
|
+
const computedHeight = node.yogaNode?.getComputedHeight();
|
|
31
|
+
const computedWidth = node.yogaNode?.getComputedWidth();
|
|
32
|
+
const hasInvalidHeight = computedHeight === undefined ||
|
|
33
|
+
!Number.isFinite(computedHeight) ||
|
|
34
|
+
computedHeight < 0;
|
|
35
|
+
const hasInvalidWidth = computedWidth === undefined ||
|
|
36
|
+
!Number.isFinite(computedWidth) ||
|
|
37
|
+
computedWidth < 0;
|
|
38
|
+
if (!node.yogaNode || hasInvalidHeight || hasInvalidWidth) {
|
|
39
|
+
// Log to help diagnose root cause (visible with --debug flag)
|
|
40
|
+
if (node.yogaNode && (hasInvalidHeight || hasInvalidWidth)) {
|
|
41
|
+
logForDebugging(`Invalid yoga dimensions: width=${computedWidth}, height=${computedHeight}, ` +
|
|
42
|
+
`childNodes=${node.childNodes.length}, terminalWidth=${terminalWidth}, terminalRows=${terminalRows}`);
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
screen: createScreen(terminalWidth, 0, stylePool, charPool, hyperlinkPool),
|
|
46
|
+
viewport: { width: terminalWidth, height: terminalRows },
|
|
47
|
+
cursor: { x: 0, y: 0, visible: true },
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
const width = Math.floor(node.yogaNode.getComputedWidth());
|
|
51
|
+
const yogaHeight = Math.floor(node.yogaNode.getComputedHeight());
|
|
52
|
+
// Alt-screen: the screen buffer IS the alt buffer — always exactly
|
|
53
|
+
// terminalRows tall. <AlternateScreen> wraps children in <Box
|
|
54
|
+
// height={rows} flexShrink={0}>, so yogaHeight should equal
|
|
55
|
+
// terminalRows. But if something renders as a SIBLING of that Box
|
|
56
|
+
// (bug: MessageSelector was outside <FullscreenLayout>), yogaHeight
|
|
57
|
+
// exceeds rows and every assumption below (viewport +1 hack, cursor.y
|
|
58
|
+
// clamp, log-update's heightDelta===0 fast path) breaks, desyncing
|
|
59
|
+
// virtual/physical cursors. Clamping here enforces the invariant:
|
|
60
|
+
// overflow writes land at y >= screen.height and setCellAt drops
|
|
61
|
+
// them. The sibling is invisible (obvious, easy to find) instead of
|
|
62
|
+
// corrupting the whole terminal.
|
|
63
|
+
const height = options.altScreen ? terminalRows : yogaHeight;
|
|
64
|
+
if (options.altScreen && yogaHeight > terminalRows) {
|
|
65
|
+
logForDebugging(`alt-screen: yoga height ${yogaHeight} > terminalRows ${terminalRows} — ` +
|
|
66
|
+
`something is rendering outside <AlternateScreen>. Overflow clipped.`, { level: 'warn' });
|
|
67
|
+
}
|
|
68
|
+
const screen = backScreen ??
|
|
69
|
+
createScreen(width, height, stylePool, charPool, hyperlinkPool);
|
|
70
|
+
if (output) {
|
|
71
|
+
output.reset(width, height, screen);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
output = new Output({ width, height, stylePool, screen });
|
|
75
|
+
}
|
|
76
|
+
resetLayoutShifted();
|
|
77
|
+
resetScrollHint();
|
|
78
|
+
resetScrollDrainNode();
|
|
79
|
+
// prevFrameContaminated: selection overlay mutated the returned screen
|
|
80
|
+
// buffer post-render (in ink.tsx), resetFramesForAltScreen() replaced it
|
|
81
|
+
// with blanks, or forceRedraw() reset it to 0×0. Blit on the NEXT frame
|
|
82
|
+
// would copy stale inverted cells / blanks / nothing. When clean, blit
|
|
83
|
+
// restores the O(unchanged) fast path for steady-state frames (spinner
|
|
84
|
+
// tick, text stream).
|
|
85
|
+
// Removing an absolute-positioned node poisons prevScreen: it may
|
|
86
|
+
// have painted over non-siblings (e.g. an overlay over a ScrollBox
|
|
87
|
+
// earlier in tree order), so their blits would restore the removed
|
|
88
|
+
// node's pixels. hasRemovedChild only shields direct siblings.
|
|
89
|
+
// Normal-flow removals don't paint cross-subtree and are fine.
|
|
90
|
+
const absoluteRemoved = consumeAbsoluteRemovedFlag();
|
|
91
|
+
renderNodeToOutput(node, output, {
|
|
92
|
+
prevScreen: absoluteRemoved || options.prevFrameContaminated
|
|
93
|
+
? undefined
|
|
94
|
+
: prevScreen,
|
|
95
|
+
});
|
|
96
|
+
const renderedScreen = output.get();
|
|
97
|
+
// Drain continuation: render cleared scrollbox.dirty, so next frame's
|
|
98
|
+
// root blit would skip the subtree. markDirty walks ancestors so the
|
|
99
|
+
// next frame descends. Done AFTER render so the clear-dirty at the end
|
|
100
|
+
// of renderNodeToOutput doesn't overwrite this.
|
|
101
|
+
const drainNode = getScrollDrainNode();
|
|
102
|
+
if (drainNode)
|
|
103
|
+
markDirty(drainNode);
|
|
104
|
+
return {
|
|
105
|
+
scrollHint: options.altScreen ? getScrollHint() : null,
|
|
106
|
+
scrollDrainPending: drainNode !== null,
|
|
107
|
+
screen: renderedScreen,
|
|
108
|
+
viewport: {
|
|
109
|
+
width: terminalWidth,
|
|
110
|
+
// Alt screen: fake viewport.height = rows + 1 so that
|
|
111
|
+
// shouldClearScreen()'s `screen.height >= viewport.height` check
|
|
112
|
+
// (which treats exactly-filling content as "overflows" for
|
|
113
|
+
// scrollback purposes) never fires. Alt-screen content is always
|
|
114
|
+
// exactly `rows` tall (via <Box height={rows}>) but never
|
|
115
|
+
// scrolls — the cursor.y clamp below keeps the cursor-restore
|
|
116
|
+
// from emitting an LF. With the standard diff path, every frame
|
|
117
|
+
// is incremental; no fullResetSequence_CAUSES_FLICKER.
|
|
118
|
+
height: options.altScreen ? terminalRows + 1 : terminalRows,
|
|
119
|
+
},
|
|
120
|
+
cursor: {
|
|
121
|
+
x: 0,
|
|
122
|
+
// In the alt screen, keep the cursor inside the viewport. When
|
|
123
|
+
// screen.height === terminalRows exactly (content fills the alt
|
|
124
|
+
// screen), cursor.y = screen.height would trigger log-update's
|
|
125
|
+
// cursor-restore LF at the last row, scrolling one row off the top
|
|
126
|
+
// of the alt buffer and desyncing the diff's cursor model. The
|
|
127
|
+
// cursor is hidden so its position only matters for diff coords.
|
|
128
|
+
y: options.altScreen
|
|
129
|
+
? Math.max(0, Math.min(screen.height, terminalRows) - 1)
|
|
130
|
+
: screen.height,
|
|
131
|
+
// Hide cursor when there's dynamic output to render (only in TTY mode)
|
|
132
|
+
visible: !isTTY || screen.height === 0,
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { FrameEvent } from './frame.js';
|
|
3
|
+
import Ink from './ink.js';
|
|
4
|
+
/** Options for mounting an Ink app. */
|
|
5
|
+
export type RenderOptions = {
|
|
6
|
+
/**
|
|
7
|
+
* Output stream where app will be rendered.
|
|
8
|
+
*
|
|
9
|
+
* @default process.stdout
|
|
10
|
+
*/
|
|
11
|
+
stdout?: NodeJS.WriteStream;
|
|
12
|
+
/**
|
|
13
|
+
* Input stream where app will listen for input.
|
|
14
|
+
*
|
|
15
|
+
* @default process.stdin
|
|
16
|
+
*/
|
|
17
|
+
stdin?: NodeJS.ReadStream;
|
|
18
|
+
/**
|
|
19
|
+
* Error stream.
|
|
20
|
+
* @default process.stderr
|
|
21
|
+
*/
|
|
22
|
+
stderr?: NodeJS.WriteStream;
|
|
23
|
+
/**
|
|
24
|
+
* Configure whether Ink should listen to Ctrl+C keyboard input and exit the app. This is needed in case `process.stdin` is in raw mode, because then Ctrl+C is ignored by default and process is expected to handle it manually.
|
|
25
|
+
*
|
|
26
|
+
* @default true
|
|
27
|
+
*/
|
|
28
|
+
exitOnCtrlC?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Patch console methods to ensure console output doesn't mix with Ink output.
|
|
31
|
+
*
|
|
32
|
+
* @default true
|
|
33
|
+
*/
|
|
34
|
+
patchConsole?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Called after each frame render with timing and flicker information.
|
|
37
|
+
*/
|
|
38
|
+
onFrame?: (event: FrameEvent) => void;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* The handle returned by renderSync for an actively rendering Ink app.
|
|
42
|
+
*/
|
|
43
|
+
export type Instance = {
|
|
44
|
+
/**
|
|
45
|
+
* Replace previous root node with a new one or update props of the current root node.
|
|
46
|
+
*/
|
|
47
|
+
rerender: Ink['render'];
|
|
48
|
+
/**
|
|
49
|
+
* Manually unmount the whole Ink app.
|
|
50
|
+
*/
|
|
51
|
+
unmount: Ink['unmount'];
|
|
52
|
+
/**
|
|
53
|
+
* Returns a promise, which resolves when app is unmounted.
|
|
54
|
+
*/
|
|
55
|
+
waitUntilExit: Ink['waitUntilExit'];
|
|
56
|
+
cleanup: () => void;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* A managed Ink root, similar to react-dom's createRoot API.
|
|
60
|
+
* Separates instance creation from rendering so the same root
|
|
61
|
+
* can be reused for multiple sequential screens.
|
|
62
|
+
*/
|
|
63
|
+
export type Root = {
|
|
64
|
+
render: (node: ReactNode) => void;
|
|
65
|
+
unmount: () => void;
|
|
66
|
+
waitUntilExit: () => Promise<void>;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Mount a component and render the output.
|
|
70
|
+
* @param node - the React element to render.
|
|
71
|
+
* @param options - the output stream or render options.
|
|
72
|
+
* @returns an instance handle for the running app.
|
|
73
|
+
*/
|
|
74
|
+
export declare const renderSync: (node: ReactNode, options?: NodeJS.WriteStream | RenderOptions) => Instance;
|
|
75
|
+
/**
|
|
76
|
+
* Asynchronous render entry point that preserves a microtask boundary
|
|
77
|
+
* before the first synchronous render, letting async startup work settle.
|
|
78
|
+
* @param node - the React element to render.
|
|
79
|
+
* @param options - the output stream or render options.
|
|
80
|
+
* @returns a promise resolving to the instance handle once mounted.
|
|
81
|
+
*/
|
|
82
|
+
declare const wrappedRender: (node: ReactNode, options?: NodeJS.WriteStream | RenderOptions) => Promise<Instance>;
|
|
83
|
+
export default wrappedRender;
|
|
84
|
+
/**
|
|
85
|
+
* Create an Ink root without rendering anything yet.
|
|
86
|
+
* Like react-dom's createRoot — call root.render() to mount a tree.
|
|
87
|
+
* @param options - the render options; defaults match renderSync defaults.
|
|
88
|
+
* @returns a promise resolving to the managed root.
|
|
89
|
+
*/
|
|
90
|
+
export declare function createRoot(options?: RenderOptions): Promise<Root>;
|
|
91
|
+
//# sourceMappingURL=root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../../src/ink/root.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,GAAmC,MAAM,UAAU,CAAA;AAG1D,uCAAuC;AACvC,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,CAAA;IAC3B;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,CAAA;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAA;IAErB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IAEtB;;OAEG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;CACtC,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG;IACrB;;OAEG;IACH,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAA;IACvB;;OAEG;IACH,OAAO,EAAE,GAAG,CAAC,SAAS,CAAC,CAAA;IACvB;;OAEG;IACH,aAAa,EAAE,GAAG,CAAC,eAAe,CAAC,CAAA;IACnC,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,CAAA;AAED;;;;GAIG;AACH,MAAM,MAAM,IAAI,GAAG;IACjB,MAAM,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACjC,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CACnC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GACrB,MAAM,SAAS,EACf,UAAU,MAAM,CAAC,WAAW,GAAG,aAAa,KAC3C,QA0BF,CAAA;AAED;;;;;;GAMG;AACH,QAAA,MAAM,aAAa,GACjB,MAAM,SAAS,EACf,UAAU,MAAM,CAAC,WAAW,GAAG,aAAa,KAC3C,OAAO,CAAC,QAAQ,CAWlB,CAAA;AAED,eAAe,aAAa,CAAA;AAE5B;;;;;GAKG;AACH,wBAAsB,UAAU,CAC9B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA6Bf"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { logForDebugging } from '../utils/debug.js';
|
|
2
|
+
import { Stream } from 'stream';
|
|
3
|
+
import Ink from './ink.js';
|
|
4
|
+
import instances from './instances.js';
|
|
5
|
+
/**
|
|
6
|
+
* Mount a component and render the output.
|
|
7
|
+
* @param node - the React element to render.
|
|
8
|
+
* @param options - the output stream or render options.
|
|
9
|
+
* @returns an instance handle for the running app.
|
|
10
|
+
*/
|
|
11
|
+
export const renderSync = (node, options) => {
|
|
12
|
+
const opts = getOptions(options);
|
|
13
|
+
const inkOptions = {
|
|
14
|
+
stdout: process.stdout,
|
|
15
|
+
stdin: process.stdin,
|
|
16
|
+
stderr: process.stderr,
|
|
17
|
+
exitOnCtrlC: true,
|
|
18
|
+
patchConsole: true,
|
|
19
|
+
...opts,
|
|
20
|
+
};
|
|
21
|
+
const instance = getInstance(inkOptions.stdout, () => new Ink(inkOptions));
|
|
22
|
+
instance.render(node);
|
|
23
|
+
return {
|
|
24
|
+
rerender: instance.render,
|
|
25
|
+
unmount() {
|
|
26
|
+
instance.unmount();
|
|
27
|
+
},
|
|
28
|
+
waitUntilExit: instance.waitUntilExit,
|
|
29
|
+
cleanup: () => instances.delete(inkOptions.stdout),
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Asynchronous render entry point that preserves a microtask boundary
|
|
34
|
+
* before the first synchronous render, letting async startup work settle.
|
|
35
|
+
* @param node - the React element to render.
|
|
36
|
+
* @param options - the output stream or render options.
|
|
37
|
+
* @returns a promise resolving to the instance handle once mounted.
|
|
38
|
+
*/
|
|
39
|
+
const wrappedRender = async (node, options) => {
|
|
40
|
+
// Preserve the microtask boundary that `await loadYoga()` used to provide.
|
|
41
|
+
// Without it, the first render fires synchronously before async startup work
|
|
42
|
+
// (e.g. useReplBridge notification state) settles, and the subsequent Static
|
|
43
|
+
// write overwrites scrollback instead of appending below the logo.
|
|
44
|
+
await Promise.resolve();
|
|
45
|
+
const instance = renderSync(node, options);
|
|
46
|
+
logForDebugging(`[render] first ink render: ${Math.round(process.uptime() * 1000)}ms since process start`);
|
|
47
|
+
return instance;
|
|
48
|
+
};
|
|
49
|
+
export default wrappedRender;
|
|
50
|
+
/**
|
|
51
|
+
* Create an Ink root without rendering anything yet.
|
|
52
|
+
* Like react-dom's createRoot — call root.render() to mount a tree.
|
|
53
|
+
* @param options - the render options; defaults match renderSync defaults.
|
|
54
|
+
* @returns a promise resolving to the managed root.
|
|
55
|
+
*/
|
|
56
|
+
export async function createRoot(options = {}) {
|
|
57
|
+
const { stdout = process.stdout, stdin = process.stdin, stderr = process.stderr, exitOnCtrlC = true, patchConsole = true, onFrame, } = options;
|
|
58
|
+
// See wrappedRender — preserve microtask boundary from the old WASM await.
|
|
59
|
+
await Promise.resolve();
|
|
60
|
+
const instance = new Ink({
|
|
61
|
+
stdout,
|
|
62
|
+
stdin,
|
|
63
|
+
stderr,
|
|
64
|
+
exitOnCtrlC,
|
|
65
|
+
patchConsole,
|
|
66
|
+
onFrame,
|
|
67
|
+
});
|
|
68
|
+
// Register in the instances map so that code that looks up the Ink
|
|
69
|
+
// instance by stdout (e.g. external editor pause/resume) can find it.
|
|
70
|
+
instances.set(stdout, instance);
|
|
71
|
+
return {
|
|
72
|
+
render: node => instance.render(node),
|
|
73
|
+
unmount: () => instance.unmount(),
|
|
74
|
+
waitUntilExit: () => instance.waitUntilExit(),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const getOptions = (stdout = {}) => {
|
|
78
|
+
if (stdout instanceof Stream) {
|
|
79
|
+
return {
|
|
80
|
+
stdout,
|
|
81
|
+
stdin: process.stdin,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return stdout;
|
|
85
|
+
};
|
|
86
|
+
const getInstance = (stdout, createInstance) => {
|
|
87
|
+
let instance = instances.get(stdout);
|
|
88
|
+
if (!instance) {
|
|
89
|
+
instance = createInstance();
|
|
90
|
+
instances.set(stdout, instance);
|
|
91
|
+
}
|
|
92
|
+
return instance;
|
|
93
|
+
};
|