@deepseek-harness-tui/dsh-tui 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -21
- package/bin/dsh-tui.js +115 -25
- package/cordis.patch.yml +69 -17
- package/cordis.yml +50 -12
- package/lib/types/activityPrefs.d.ts +1 -1
- package/lib/types/activityPrefs.js +3 -3
- package/lib/types/cc/figures.d.ts +27 -20
- package/lib/types/cc/figures.d.ts.map +1 -1
- package/lib/types/cc/figures.js +43 -34
- package/lib/types/cc/format.d.ts +18 -9
- package/lib/types/cc/format.d.ts.map +1 -1
- package/lib/types/cc/format.js +26 -18
- package/lib/types/cc/markdown.d.ts +31 -16
- package/lib/types/cc/markdown.d.ts.map +1 -1
- package/lib/types/cc/markdown.js +283 -260
- package/lib/types/cc/terminal.d.ts +10 -7
- package/lib/types/cc/terminal.d.ts.map +1 -1
- package/lib/types/cc/terminal.js +62 -50
- package/lib/types/command-trees.d.ts +3 -0
- package/lib/types/command-trees.d.ts.map +1 -0
- package/lib/types/command-trees.js +4 -0
- package/lib/types/commands.d.ts +37 -1
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +68 -3
- package/lib/types/components/ActivityLine.d.ts +1 -1
- package/lib/types/components/ActivityLine.d.ts.map +1 -1
- package/lib/types/components/ActivityPicker.d.ts.map +1 -1
- package/lib/types/components/ActivityPicker.js +3 -4
- package/lib/types/components/BtwPanel.d.ts +16 -0
- package/lib/types/components/BtwPanel.d.ts.map +1 -0
- package/lib/types/components/BtwPanel.js +47 -0
- package/lib/types/components/CommandSuggestions.d.ts +4 -2
- package/lib/types/components/CommandSuggestions.d.ts.map +1 -1
- package/lib/types/components/CommandSuggestions.js +2 -2
- package/lib/types/components/EffortSlider.d.ts +15 -0
- package/lib/types/components/EffortSlider.d.ts.map +1 -0
- package/lib/types/components/EffortSlider.js +17 -0
- package/lib/types/components/GoalTodoPanel.d.ts +1 -1
- package/lib/types/components/GoalTodoPanel.d.ts.map +1 -1
- package/lib/types/components/HelpMenu.d.ts +5 -2
- package/lib/types/components/HelpMenu.d.ts.map +1 -1
- package/lib/types/components/HelpMenu.js +8 -3
- package/lib/types/components/HistorySearchDialog.d.ts +1 -1
- package/lib/types/components/HistorySearchDialog.d.ts.map +1 -1
- package/lib/types/components/HistorySearchDialog.js +21 -10
- package/lib/types/components/InterruptedByUser.d.ts +2 -2
- package/lib/types/components/InterruptedByUser.d.ts.map +1 -1
- package/lib/types/components/InterruptedByUser.js +4 -3
- package/lib/types/components/LoadedContextPanel.d.ts +1 -1
- package/lib/types/components/LoadedContextPanel.d.ts.map +1 -1
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +2 -1
- package/lib/types/components/Markdown.d.ts +11 -11
- package/lib/types/components/Markdown.d.ts.map +1 -1
- package/lib/types/components/Markdown.js +63 -57
- package/lib/types/components/MarkdownTable.d.ts +1 -1
- package/lib/types/components/MarkdownTable.js +2 -2
- package/lib/types/components/MessageList.d.ts +10 -2
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +17 -10
- package/lib/types/components/ModelPicker.d.ts +4 -1
- package/lib/types/components/ModelPicker.d.ts.map +1 -1
- package/lib/types/components/ModelPicker.js +16 -4
- package/lib/types/components/OverlayAbove.d.ts +20 -0
- package/lib/types/components/OverlayAbove.d.ts.map +1 -0
- package/lib/types/components/OverlayAbove.js +18 -0
- package/lib/types/components/PresetPicker.d.ts +1 -1
- package/lib/types/components/PresetPicker.d.ts.map +1 -1
- package/lib/types/components/PresetPicker.js +2 -3
- package/lib/types/components/PromptInput.d.ts +5 -4
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +186 -39
- package/lib/types/components/ResumePicker.d.ts +15 -4
- package/lib/types/components/ResumePicker.d.ts.map +1 -1
- package/lib/types/components/ResumePicker.js +25 -9
- package/lib/types/components/RewindPicker.d.ts +1 -1
- package/lib/types/components/RewindPicker.d.ts.map +1 -1
- package/lib/types/components/RewindPicker.js +14 -5
- package/lib/types/components/SearchBox.d.ts +1 -1
- package/lib/types/components/SearchBox.js +1 -1
- package/lib/types/components/Spinner/GlimmerMessage.d.ts +1 -2
- package/lib/types/components/Spinner/GlimmerMessage.d.ts.map +1 -1
- package/lib/types/components/Spinner/GlimmerMessage.js +1 -2
- package/lib/types/components/Spinner/SpinnerAnimationRow.d.ts +1 -1
- package/lib/types/components/Spinner/SpinnerAnimationRow.js +2 -2
- package/lib/types/components/Spinner/SpinnerGlyph.d.ts +1 -1
- package/lib/types/components/Spinner/SpinnerGlyph.js +1 -1
- package/lib/types/components/Spinner/spinnerUtils.d.ts +13 -18
- package/lib/types/components/Spinner/spinnerUtils.d.ts.map +1 -1
- package/lib/types/components/Spinner/spinnerUtils.js +67 -71
- package/lib/types/components/Spinner/useStalledAnimation.d.ts +1 -2
- package/lib/types/components/Spinner/useStalledAnimation.d.ts.map +1 -1
- package/lib/types/components/Spinner/useStalledAnimation.js +1 -2
- package/lib/types/components/StreamingMarkdown.d.ts +1 -1
- package/lib/types/components/StreamingMarkdown.js +1 -1
- package/lib/types/components/ThemePicker.d.ts +13 -9
- package/lib/types/components/ThemePicker.d.ts.map +1 -1
- package/lib/types/components/ThemePicker.js +21 -15
- package/lib/types/components/ThinkingToggle.d.ts +1 -1
- package/lib/types/components/ThinkingToggle.d.ts.map +1 -1
- package/lib/types/components/ThinkingToggle.js +8 -8
- package/lib/types/components/ToolUseLoader.d.ts +1 -1
- package/lib/types/components/ToolUseLoader.js +1 -1
- package/lib/types/components/WorkingSpinner.d.ts +2 -2
- package/lib/types/components/WorkingSpinner.js +2 -2
- package/lib/types/components/WorkspaceFlowPicker.d.ts +15 -0
- package/lib/types/components/WorkspaceFlowPicker.d.ts.map +1 -0
- package/lib/types/components/WorkspaceFlowPicker.js +19 -0
- package/lib/types/components/WorkspacePicker.d.ts +9 -0
- package/lib/types/components/WorkspacePicker.d.ts.map +1 -0
- package/lib/types/components/WorkspacePicker.js +13 -0
- package/lib/types/components/approvals/ApprovalPanel.d.ts +1 -1
- package/lib/types/components/approvals/ApprovalPanel.d.ts.map +1 -1
- package/lib/types/components/approvals/ApprovalPanel.js +2 -1
- package/lib/types/components/design-system/Byline.d.ts +1 -1
- package/lib/types/components/design-system/Byline.js +1 -1
- package/lib/types/components/design-system/Divider.d.ts +1 -1
- package/lib/types/components/design-system/Divider.js +1 -1
- package/lib/types/components/design-system/HintLine.d.ts +12 -0
- package/lib/types/components/design-system/HintLine.d.ts.map +1 -0
- package/lib/types/components/design-system/HintLine.js +15 -0
- package/lib/types/components/design-system/KeyboardShortcutHint.d.ts +1 -1
- package/lib/types/components/design-system/KeyboardShortcutHint.js +1 -1
- package/lib/types/components/design-system/ListItem.d.ts +2 -2
- package/lib/types/components/design-system/ListItem.d.ts.map +1 -1
- package/lib/types/components/design-system/ListItem.js +35 -3
- package/lib/types/components/design-system/LoadingState.d.ts +1 -2
- package/lib/types/components/design-system/LoadingState.d.ts.map +1 -1
- package/lib/types/components/design-system/LoadingState.js +1 -2
- package/lib/types/components/design-system/Pane.d.ts +2 -2
- package/lib/types/components/design-system/Pane.js +2 -2
- package/lib/types/components/design-system/ProgressBar.d.ts +1 -2
- package/lib/types/components/design-system/ProgressBar.d.ts.map +1 -1
- package/lib/types/components/design-system/ProgressBar.js +1 -2
- package/lib/types/components/design-system/StatusIcon.d.ts +2 -2
- package/lib/types/components/design-system/StatusIcon.js +2 -2
- package/lib/types/components/design-system/ThemeProvider.d.ts +1 -1
- package/lib/types/components/design-system/ThemeProvider.d.ts.map +1 -1
- package/lib/types/components/design-system/ThemeProvider.js +87 -26
- package/lib/types/components/design-system/ThemedBox.d.ts +1 -1
- package/lib/types/components/design-system/ThemedBox.js +1 -1
- package/lib/types/components/design-system/ThemedText.d.ts +2 -2
- package/lib/types/components/design-system/ThemedText.js +2 -2
- package/lib/types/components/listWindow.d.ts +26 -0
- package/lib/types/components/listWindow.d.ts.map +1 -0
- package/lib/types/components/listWindow.js +47 -0
- package/lib/types/components/messages/AssistantTextMessage.d.ts +1 -2
- package/lib/types/components/messages/AssistantTextMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantTextMessage.js +1 -2
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts +2 -2
- package/lib/types/components/messages/AssistantThinkingMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantThinkingMessage.js +6 -6
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts +12 -4
- package/lib/types/components/messages/AssistantToolUseMessage.d.ts.map +1 -1
- package/lib/types/components/messages/AssistantToolUseMessage.js +9 -5
- package/lib/types/components/messages/MessageMetadata.d.ts +1 -1
- package/lib/types/components/messages/MessageMetadata.js +1 -1
- package/lib/types/components/messages/UserPromptMessage.d.ts +1 -1
- package/lib/types/components/messages/UserPromptMessage.js +1 -1
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts +5 -1
- package/lib/types/components/questions/AskUserQuestionPanel.d.ts.map +1 -1
- package/lib/types/components/questions/AskUserQuestionPanel.js +11 -9
- package/lib/types/components/questions/PlanReviewPanel.d.ts +1 -1
- package/lib/types/components/questions/PlanReviewPanel.d.ts.map +1 -1
- package/lib/types/components/questions/PlanReviewPanel.js +3 -2
- package/lib/types/components/trajectory/HotspotView.d.ts +14 -0
- package/lib/types/components/trajectory/HotspotView.d.ts.map +1 -0
- package/lib/types/components/trajectory/HotspotView.js +83 -0
- package/lib/types/components/trajectory/Inspector.d.ts +31 -0
- package/lib/types/components/trajectory/Inspector.d.ts.map +1 -0
- package/lib/types/components/trajectory/Inspector.js +67 -0
- package/lib/types/components/trajectory/Ledger.d.ts +20 -0
- package/lib/types/components/trajectory/Ledger.d.ts.map +1 -0
- package/lib/types/components/trajectory/Ledger.js +112 -0
- package/lib/types/components/trajectory/MiniWake.d.ts +24 -0
- package/lib/types/components/trajectory/MiniWake.d.ts.map +1 -0
- package/lib/types/components/trajectory/MiniWake.js +99 -0
- package/lib/types/components/trajectory/WaveBand.d.ts +33 -0
- package/lib/types/components/trajectory/WaveBand.d.ts.map +1 -0
- package/lib/types/components/trajectory/WaveBand.js +145 -0
- package/lib/types/customTheme.d.ts +6 -6
- package/lib/types/customTheme.d.ts.map +1 -1
- package/lib/types/customTheme.js +15 -12
- package/lib/types/dsh-adapter/approvals.d.ts.map +1 -0
- package/lib/types/{channel.d.ts → dsh-adapter/channel.d.ts} +184 -43
- package/lib/types/dsh-adapter/channel.d.ts.map +1 -0
- package/lib/types/{channel.js → dsh-adapter/channel.js} +972 -201
- package/lib/types/dsh-adapter/childStderr.d.ts.map +1 -0
- package/lib/types/{childStderr.js → dsh-adapter/childStderr.js} +1 -1
- package/lib/types/dsh-adapter/command-trees.d.ts +27 -0
- package/lib/types/dsh-adapter/command-trees.d.ts.map +1 -0
- package/lib/types/dsh-adapter/command-trees.js +42 -0
- package/lib/types/dsh-adapter/compat/index.d.ts +22 -0
- package/lib/types/dsh-adapter/compat/index.d.ts.map +1 -0
- package/lib/types/{compat → dsh-adapter/compat}/index.js +7 -4
- package/lib/types/dsh-adapter/compat/sessionLog.d.ts +86 -0
- package/lib/types/dsh-adapter/compat/sessionLog.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/sessionLog.js +347 -0
- package/lib/types/dsh-adapter/contract.d.ts +20 -0
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -0
- package/lib/types/dsh-adapter/contract.js +109 -0
- package/lib/types/dsh-adapter/index.d.ts +80 -0
- package/lib/types/dsh-adapter/index.d.ts.map +1 -0
- package/lib/types/dsh-adapter/index.js +45 -0
- package/lib/types/dsh-adapter/invariant.d.ts.map +1 -0
- package/lib/types/dsh-adapter/packaged-skills.d.ts.map +1 -0
- package/lib/types/{plugin.d.ts → dsh-adapter/plugin.d.ts} +17 -0
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -0
- package/lib/types/{plugin.js → dsh-adapter/plugin.js} +280 -80
- package/lib/types/dsh-adapter/presets.d.ts.map +1 -0
- package/lib/types/dsh-adapter/providerWizard.d.ts +91 -0
- package/lib/types/dsh-adapter/providerWizard.d.ts.map +1 -0
- package/lib/types/dsh-adapter/providerWizard.js +332 -0
- package/lib/types/{questions.d.ts → dsh-adapter/questions.d.ts} +7 -2
- package/lib/types/dsh-adapter/questions.d.ts.map +1 -0
- package/lib/types/{questions.js → dsh-adapter/questions.js} +15 -7
- package/lib/types/dsh-adapter/sideQuestion.d.ts +38 -0
- package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -0
- package/lib/types/dsh-adapter/sideQuestion.js +69 -0
- package/lib/types/dsh-adapter/trajectory/aggregate.d.ts +46 -0
- package/lib/types/dsh-adapter/trajectory/aggregate.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/aggregate.js +207 -0
- package/lib/types/dsh-adapter/trajectory/guards.d.ts +177 -0
- package/lib/types/dsh-adapter/trajectory/guards.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/guards.js +235 -0
- package/lib/types/dsh-adapter/trajectory/index.d.ts +16 -0
- package/lib/types/dsh-adapter/trajectory/index.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/index.js +15 -0
- package/lib/types/dsh-adapter/trajectory/inspect.d.ts +40 -0
- package/lib/types/dsh-adapter/trajectory/inspect.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/inspect.js +160 -0
- package/lib/types/dsh-adapter/trajectory/projection.d.ts +128 -0
- package/lib/types/dsh-adapter/trajectory/projection.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/projection.js +653 -0
- package/lib/types/dsh-adapter/trajectory/types.d.ts +232 -0
- package/lib/types/dsh-adapter/trajectory/types.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/types.js +70 -0
- package/lib/types/dsh-adapter/trajectory/wave.d.ts +45 -0
- package/lib/types/dsh-adapter/trajectory/wave.d.ts.map +1 -0
- package/lib/types/dsh-adapter/trajectory/wave.js +210 -0
- package/lib/types/dsh-adapter/types.d.ts +23 -0
- package/lib/types/dsh-adapter/types.d.ts.map +1 -0
- package/lib/types/dsh-adapter/types.js +1 -0
- package/lib/types/dsh-adapter/workspace.d.ts +22 -0
- package/lib/types/dsh-adapter/workspace.d.ts.map +1 -0
- package/lib/types/dsh-adapter/workspace.js +16 -0
- package/lib/types/dsh-adapter/workspaces.d.ts +118 -0
- package/lib/types/dsh-adapter/workspaces.d.ts.map +1 -0
- package/lib/types/dsh-adapter/workspaces.js +290 -0
- package/lib/types/effortPrefs.d.ts +1 -1
- package/lib/types/effortPrefs.js +3 -3
- package/lib/types/history.js +2 -2
- package/lib/types/hooks/useBlink.d.ts +1 -1
- package/lib/types/hooks/useBlink.js +1 -1
- package/lib/types/i18n.d.ts +977 -36
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +307 -30
- package/lib/types/index.d.ts +1 -69
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +3 -31
- package/lib/types/ink/components/App.d.ts.map +1 -1
- package/lib/types/ink/components/App.js +33 -19
- package/lib/types/ink/dom.d.ts +15 -0
- package/lib/types/ink/dom.d.ts.map +1 -1
- package/lib/types/ink/dom.js +32 -0
- package/lib/types/ink/hooks/use-input.d.ts.map +1 -1
- package/lib/types/ink/hooks/use-input.js +8 -0
- package/lib/types/ink/hooks/use-terminal-size.d.ts +1 -1
- package/lib/types/ink/hooks/use-terminal-size.js +1 -1
- package/lib/types/ink/ink.d.ts.map +1 -1
- package/lib/types/ink/ink.js +109 -28
- package/lib/types/ink/input-suppression.d.ts +20 -0
- package/lib/types/ink/input-suppression.d.ts.map +1 -0
- package/lib/types/ink/input-suppression.js +26 -0
- package/lib/types/ink/log-update.js +21 -6
- package/lib/types/ink/parse-keypress.d.ts +31 -0
- package/lib/types/ink/parse-keypress.d.ts.map +1 -1
- package/lib/types/ink/parse-keypress.js +442 -8
- package/lib/types/ink/terminal-querier.d.ts +5 -1
- package/lib/types/ink/terminal-querier.d.ts.map +1 -1
- package/lib/types/ink/terminal-querier.js +27 -3
- package/lib/types/ink/terminal.d.ts +18 -0
- package/lib/types/ink/terminal.d.ts.map +1 -1
- package/lib/types/ink/terminal.js +32 -4
- package/lib/types/ink/termio/csi.d.ts +10 -0
- package/lib/types/ink/termio/csi.d.ts.map +1 -1
- package/lib/types/ink/termio/csi.js +20 -0
- package/lib/types/ink/termio/tokenize.js +10 -0
- package/lib/types/modelPrefs.d.ts +1 -1
- package/lib/types/modelPrefs.js +3 -3
- package/lib/types/presetPrefs.d.ts +1 -1
- package/lib/types/presetPrefs.js +3 -3
- package/lib/types/screens/Chat.d.ts +20 -4
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +655 -55
- package/lib/types/screens/StatusLine.d.ts +17 -2
- package/lib/types/screens/StatusLine.d.ts.map +1 -1
- package/lib/types/screens/StatusLine.js +12 -4
- package/lib/types/screens/TrajectoryScene.d.ts +16 -0
- package/lib/types/screens/TrajectoryScene.d.ts.map +1 -0
- package/lib/types/screens/TrajectoryScene.js +305 -0
- package/lib/types/sessionHistory.d.ts +9 -1
- package/lib/types/sessionHistory.d.ts.map +1 -1
- package/lib/types/sessionHistory.js +56 -16
- package/lib/types/sessionModes.d.ts +29 -0
- package/lib/types/sessionModes.d.ts.map +1 -0
- package/lib/types/sessionModes.js +45 -0
- package/lib/types/theme.d.ts +27 -3
- package/lib/types/theme.d.ts.map +1 -1
- package/lib/types/theme.js +48 -4
- package/lib/types/themePrefs.d.ts +3 -3
- package/lib/types/themePrefs.js +5 -5
- package/lib/types/trajectory/format.d.ts +100 -0
- package/lib/types/trajectory/format.d.ts.map +1 -0
- package/lib/types/trajectory/format.js +213 -0
- package/lib/types/trajectory/motion.d.ts +99 -0
- package/lib/types/trajectory/motion.d.ts.map +1 -0
- package/lib/types/trajectory/motion.js +143 -0
- package/lib/types/trajectory/query.d.ts +83 -0
- package/lib/types/trajectory/query.d.ts.map +1 -0
- package/lib/types/trajectory/query.js +187 -0
- package/lib/types/trajectoryPrefs.d.ts +36 -0
- package/lib/types/trajectoryPrefs.d.ts.map +1 -0
- package/lib/types/trajectoryPrefs.js +65 -0
- package/lib/types/update.d.ts +3 -3
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +18 -7
- package/lib/types/utils/clipboard.d.ts +101 -29
- package/lib/types/utils/clipboard.d.ts.map +1 -1
- package/lib/types/utils/clipboard.js +533 -55
- package/lib/types/utils/debug.d.ts +1 -1
- package/lib/types/utils/debug.js +2 -2
- package/lib/types/utils/execFileNoThrow.d.ts.map +1 -1
- package/lib/types/utils/execFileNoThrow.js +16 -6
- package/lib/types/utils/externalEditor.d.ts +115 -0
- package/lib/types/utils/externalEditor.d.ts.map +1 -0
- package/lib/types/utils/externalEditor.js +270 -0
- package/lib/types/utils/fullscreen.d.ts +2 -2
- package/lib/types/utils/fullscreen.js +3 -3
- package/lib/types/utils/loaded-context.d.ts +1 -1
- package/lib/types/utils/loaded-context.d.ts.map +1 -1
- package/lib/types/utils/modifiers.d.ts +24 -0
- package/lib/types/utils/modifiers.d.ts.map +1 -1
- package/lib/types/utils/modifiers.js +27 -0
- package/lib/types/utils/paths.d.ts +45 -0
- package/lib/types/utils/paths.d.ts.map +1 -0
- package/lib/types/utils/paths.js +69 -0
- package/lib/types/utils/shellQuote.d.ts +14 -0
- package/lib/types/utils/shellQuote.d.ts.map +1 -0
- package/lib/types/utils/shellQuote.js +39 -0
- package/lib/types/utils/workspaceRoot.d.ts +21 -0
- package/lib/types/utils/workspaceRoot.d.ts.map +1 -0
- package/lib/types/utils/workspaceRoot.js +47 -0
- package/lib/types/workspaces.d.ts +3 -0
- package/lib/types/workspaces.d.ts.map +1 -0
- package/lib/types/workspaces.js +4 -0
- package/package.json +26 -8
- package/lib/types/approvals.d.ts.map +0 -1
- package/lib/types/channel.d.ts.map +0 -1
- package/lib/types/childStderr.d.ts.map +0 -1
- package/lib/types/compat/index.d.ts +0 -20
- package/lib/types/compat/index.d.ts.map +0 -1
- package/lib/types/compat/sessionLog.d.ts +0 -40
- package/lib/types/compat/sessionLog.d.ts.map +0 -1
- package/lib/types/compat/sessionLog.js +0 -226
- package/lib/types/invariant.d.ts.map +0 -1
- package/lib/types/packaged-skills.d.ts.map +0 -1
- package/lib/types/plugin.d.ts.map +0 -1
- package/lib/types/presets.d.ts.map +0 -1
- package/lib/types/questions.d.ts.map +0 -1
- /package/lib/types/{approvals.d.ts → dsh-adapter/approvals.d.ts} +0 -0
- /package/lib/types/{approvals.js → dsh-adapter/approvals.js} +0 -0
- /package/lib/types/{childStderr.d.ts → dsh-adapter/childStderr.d.ts} +0 -0
- /package/lib/types/{invariant.d.ts → dsh-adapter/invariant.d.ts} +0 -0
- /package/lib/types/{invariant.js → dsh-adapter/invariant.js} +0 -0
- /package/lib/types/{packaged-skills.d.ts → dsh-adapter/packaged-skills.d.ts} +0 -0
- /package/lib/types/{packaged-skills.js → dsh-adapter/packaged-skills.js} +0 -0
- /package/lib/types/{presets.d.ts → dsh-adapter/presets.d.ts} +0 -0
- /package/lib/types/{presets.js → dsh-adapter/presets.js} +0 -0
|
@@ -10,19 +10,29 @@ import { spawn } from 'node:child_process';
|
|
|
10
10
|
export function execFileNoThrow(file, args, options) {
|
|
11
11
|
return new Promise(resolve => {
|
|
12
12
|
const child = spawn(file, args ?? [], { timeout: options?.timeout, cwd: options?.cwd });
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
// Collect raw bytes and decode once at close: per-chunk toString() splits
|
|
14
|
+
// multi-byte UTF-8 characters straddling a chunk boundary into U+FFFD.
|
|
15
|
+
const stdoutChunks = [];
|
|
16
|
+
const stderrChunks = [];
|
|
15
17
|
child.stdout.on('data', (chunk) => {
|
|
16
|
-
|
|
18
|
+
stdoutChunks.push(chunk);
|
|
17
19
|
});
|
|
18
20
|
child.stderr.on('data', (chunk) => {
|
|
19
|
-
|
|
21
|
+
stderrChunks.push(chunk);
|
|
20
22
|
});
|
|
21
23
|
child.on('error', () => {
|
|
22
|
-
resolve({
|
|
24
|
+
resolve({
|
|
25
|
+
code: 1,
|
|
26
|
+
stdout: Buffer.concat(stdoutChunks).toString('utf8'),
|
|
27
|
+
stderr: Buffer.concat(stderrChunks).toString('utf8'),
|
|
28
|
+
});
|
|
23
29
|
});
|
|
24
30
|
child.on('close', code => {
|
|
25
|
-
resolve({
|
|
31
|
+
resolve({
|
|
32
|
+
code,
|
|
33
|
+
stdout: Buffer.concat(stdoutChunks).toString('utf8'),
|
|
34
|
+
stderr: Buffer.concat(stderrChunks).toString('utf8'),
|
|
35
|
+
});
|
|
26
36
|
});
|
|
27
37
|
if (options?.input !== undefined)
|
|
28
38
|
child.stdin.write(options.input);
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External editor round-trip for the prompt input (issue #123): Ctrl+X dumps
|
|
3
|
+
* the current draft into a temp file, hands the terminal to `$VISUAL` /
|
|
4
|
+
* `$EDITOR` (nvim, vim, nano, `code --wait`, …), and returns the saved text
|
|
5
|
+
* for the input to adopt.
|
|
6
|
+
*
|
|
7
|
+
* Terminal handover reuses the Ink core's editor handoff pair —
|
|
8
|
+
* `enterAlternateScreen()` pauses rendering, suspends raw-mode stdin, and
|
|
9
|
+
* drops the extended key reporting that non-CSI-u editors (nano) choke on;
|
|
10
|
+
* `exitAlternateScreen()` re-enters the alt screen (vim's rmcup pops back to
|
|
11
|
+
* the main screen on quit), repaints, and resumes stdin. See ink.tsx. The
|
|
12
|
+
* saved file is read back BEFORE stdin is resumed: resuming earlier would
|
|
13
|
+
* let keystrokes typed right at editor exit race the prompt's `setValue`
|
|
14
|
+
* and get overwritten. The restore is attempted whenever the handover was
|
|
15
|
+
* attempted (a partially-failed enter still gets an exit pass), and a
|
|
16
|
+
* failing restore never overrides the outcome.
|
|
17
|
+
*
|
|
18
|
+
* Editor resolution order mirrors readline's edit-and-execute-command:
|
|
19
|
+
* `$VISUAL` → `$EDITOR` → `vi` on POSIX (always present). Windows has no
|
|
20
|
+
* console-editor guarantee and `notepad` does not block, so an unresolved
|
|
21
|
+
* editor there reports `unavailable` and the UI asks the user to set
|
|
22
|
+
* `$EDITOR`. The variable may carry arguments (`EDITOR="code --wait"`), so
|
|
23
|
+
* the command line is split quote-aware before spawning.
|
|
24
|
+
*
|
|
25
|
+
* Windows launch: libuv resolves bare names to `.exe` on PATH but will NOT
|
|
26
|
+
* execute `.cmd`/`.bat` shims (VS Code's `code` on PATH is `code.cmd`), and
|
|
27
|
+
* `spawn(..., {shell: true})` with arguments triggers DEP0190 on Node 24+.
|
|
28
|
+
* So bare commands are resolved against PATH/PATHEXT up front, and shim
|
|
29
|
+
* scripts go through an explicit `$comspec /d /s /c` whose payload is built
|
|
30
|
+
* with the cross-spawn quoting protocol (vendored in shellQuote.ts) and
|
|
31
|
+
* passed with `windowsVerbatimArguments: true` — without verbatim, libuv
|
|
32
|
+
* re-quotes the already-quoted payload and corrupts paths containing
|
|
33
|
+
* spaces (a stock VS Code install path has them).
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Outcome of one editor round-trip; the caller maps these to UI feedback:
|
|
37
|
+
* - `edited`: the saved content differs from the draft — adopt `text`
|
|
38
|
+
* - `unchanged`: the file matches the draft (modulo newline convention), or
|
|
39
|
+
* the editor exited non-zero (`:cq` abort semantics) — keep the draft
|
|
40
|
+
* - `unavailable`: no editor could be resolved (Windows without `$EDITOR`)
|
|
41
|
+
* - `failed`: the editor process or the temp-file round-trip errored
|
|
42
|
+
* (`message` names the failed command or carries the fs error)
|
|
43
|
+
*/
|
|
44
|
+
export type EditorOutcome = {
|
|
45
|
+
kind: 'edited';
|
|
46
|
+
text: string;
|
|
47
|
+
} | {
|
|
48
|
+
kind: 'unchanged';
|
|
49
|
+
} | {
|
|
50
|
+
kind: 'unavailable';
|
|
51
|
+
} | {
|
|
52
|
+
kind: 'failed';
|
|
53
|
+
message: string;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Split an `$EDITOR`-style command line into argv, honoring single/double
|
|
57
|
+
* quotes (`code --wait`, `"C:\Program Files\...\nvim.exe" -f`).
|
|
58
|
+
*/
|
|
59
|
+
export declare function splitEditorCommand(commandLine: string): string[];
|
|
60
|
+
/**
|
|
61
|
+
* Resolve the editor argv from the environment. `$VISUAL` wins over
|
|
62
|
+
* `$EDITOR` (readline convention); POSIX falls back to `vi`, Windows has no
|
|
63
|
+
* blocking console editor fallback and returns undefined. `platform` is a
|
|
64
|
+
* parameter so the Windows branch is unit-testable from CI's Linux runners.
|
|
65
|
+
*/
|
|
66
|
+
export declare function resolveEditorCommand(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): string[] | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Windows shim resolution: a bare command like `code` usually lives on PATH
|
|
69
|
+
* as `code.cmd`, which libuv refuses to execute directly. Walk PATH with
|
|
70
|
+
* PATHEXT (case-insensitive on Windows; both casings tried for tests on
|
|
71
|
+
* case-sensitive filesystems) and report whether the resolved file needs
|
|
72
|
+
* cmd.exe to run. Commands carrying an explicit extension are used as-is;
|
|
73
|
+
* unresolved names fall back to the bare command (spawn then resolves
|
|
74
|
+
* `.exe`, or fails into the `failed` outcome).
|
|
75
|
+
*/
|
|
76
|
+
export declare function resolveWindowsShim(command: string, env?: NodeJS.ProcessEnv): {
|
|
77
|
+
command: string;
|
|
78
|
+
viaCmd: boolean;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Build the `comspec /d /s /c` spawn descriptor for a `.cmd`/`.bat` editor,
|
|
82
|
+
* following the cross-spawn protocol: the command is normalized first
|
|
83
|
+
* (explicit forward-slash paths like `C:/Program Files/.../code.cmd` must
|
|
84
|
+
* become backslash form — cross-spawn's path.normalize step, without which
|
|
85
|
+
* Windows can ENOENT), then command and arguments are escaped, joined, and
|
|
86
|
+
* wrapped in one pair of quotes (`/s` strips exactly those), and passed
|
|
87
|
+
* with `windowsVerbatimArguments` so libuv does not re-quote the payload.
|
|
88
|
+
* Exported for tests — the assembly is pure.
|
|
89
|
+
*/
|
|
90
|
+
export declare function buildCmdExeSpawn(command: string, args: readonly string[], env?: NodeJS.ProcessEnv): {
|
|
91
|
+
file: string;
|
|
92
|
+
args: string[];
|
|
93
|
+
verbatim: true;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Edit `draft` in the user's editor and report what happened. Never throws:
|
|
97
|
+
* every filesystem, spawn, or terminal-restore failure maps to a `failed`
|
|
98
|
+
* outcome (or is swallowed in the finally) so the UI notifies instead of
|
|
99
|
+
* dying on an unhandled rejection.
|
|
100
|
+
*
|
|
101
|
+
* The Ink instance is looked up lazily (same pattern as Chat's Ctrl+L
|
|
102
|
+
* redraw) so the util stays usable in tests and non-TTY contexts: without a
|
|
103
|
+
* live instance the handover escapes are skipped and the editor simply
|
|
104
|
+
* inherits stdio.
|
|
105
|
+
*
|
|
106
|
+
* Newline handling: the saved file is compared against the draft with BOTH
|
|
107
|
+
* sides CRLF-normalized, so an editor that only converts line endings (or
|
|
108
|
+
* a draft that already carries `\r\n`) never counts as an edit. Otherwise
|
|
109
|
+
* ONE trailing newline is stripped when the normalized draft did not end
|
|
110
|
+
* with one — that is the terminating newline editors append on save, not
|
|
111
|
+
* user content. Trailing blank lines the user actually added (or had in
|
|
112
|
+
* the draft, e.g. from Shift+Enter) survive untouched.
|
|
113
|
+
*/
|
|
114
|
+
export declare function editInExternalEditor(draft: string): Promise<EditorOutcome>;
|
|
115
|
+
//# sourceMappingURL=externalEditor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"externalEditor.d.ts","sourceRoot":"","sources":["../../../src/utils/externalEditor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAUH;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAEvC;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CA0BhE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,MAAM,EAAE,GAAG,SAAS,CAOtB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,CAqBtC;AAKD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAA;CAAE,CAalD;AA8CD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAsDhF"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External editor round-trip for the prompt input (issue #123): Ctrl+X dumps
|
|
3
|
+
* the current draft into a temp file, hands the terminal to `$VISUAL` /
|
|
4
|
+
* `$EDITOR` (nvim, vim, nano, `code --wait`, …), and returns the saved text
|
|
5
|
+
* for the input to adopt.
|
|
6
|
+
*
|
|
7
|
+
* Terminal handover reuses the Ink core's editor handoff pair —
|
|
8
|
+
* `enterAlternateScreen()` pauses rendering, suspends raw-mode stdin, and
|
|
9
|
+
* drops the extended key reporting that non-CSI-u editors (nano) choke on;
|
|
10
|
+
* `exitAlternateScreen()` re-enters the alt screen (vim's rmcup pops back to
|
|
11
|
+
* the main screen on quit), repaints, and resumes stdin. See ink.tsx. The
|
|
12
|
+
* saved file is read back BEFORE stdin is resumed: resuming earlier would
|
|
13
|
+
* let keystrokes typed right at editor exit race the prompt's `setValue`
|
|
14
|
+
* and get overwritten. The restore is attempted whenever the handover was
|
|
15
|
+
* attempted (a partially-failed enter still gets an exit pass), and a
|
|
16
|
+
* failing restore never overrides the outcome.
|
|
17
|
+
*
|
|
18
|
+
* Editor resolution order mirrors readline's edit-and-execute-command:
|
|
19
|
+
* `$VISUAL` → `$EDITOR` → `vi` on POSIX (always present). Windows has no
|
|
20
|
+
* console-editor guarantee and `notepad` does not block, so an unresolved
|
|
21
|
+
* editor there reports `unavailable` and the UI asks the user to set
|
|
22
|
+
* `$EDITOR`. The variable may carry arguments (`EDITOR="code --wait"`), so
|
|
23
|
+
* the command line is split quote-aware before spawning.
|
|
24
|
+
*
|
|
25
|
+
* Windows launch: libuv resolves bare names to `.exe` on PATH but will NOT
|
|
26
|
+
* execute `.cmd`/`.bat` shims (VS Code's `code` on PATH is `code.cmd`), and
|
|
27
|
+
* `spawn(..., {shell: true})` with arguments triggers DEP0190 on Node 24+.
|
|
28
|
+
* So bare commands are resolved against PATH/PATHEXT up front, and shim
|
|
29
|
+
* scripts go through an explicit `$comspec /d /s /c` whose payload is built
|
|
30
|
+
* with the cross-spawn quoting protocol (vendored in shellQuote.ts) and
|
|
31
|
+
* passed with `windowsVerbatimArguments: true` — without verbatim, libuv
|
|
32
|
+
* re-quotes the already-quoted payload and corrupts paths containing
|
|
33
|
+
* spaces (a stock VS Code install path has them).
|
|
34
|
+
*/
|
|
35
|
+
import { spawn } from 'node:child_process';
|
|
36
|
+
import { existsSync } from 'node:fs';
|
|
37
|
+
import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
|
|
38
|
+
import { tmpdir } from 'node:os';
|
|
39
|
+
import { delimiter, join, win32 } from 'node:path';
|
|
40
|
+
import instances from '../ink/instances.js';
|
|
41
|
+
import { cmdEscapeArgument, cmdEscapeCommand } from './shellQuote.js';
|
|
42
|
+
/**
|
|
43
|
+
* Split an `$EDITOR`-style command line into argv, honoring single/double
|
|
44
|
+
* quotes (`code --wait`, `"C:\Program Files\...\nvim.exe" -f`).
|
|
45
|
+
*/
|
|
46
|
+
export function splitEditorCommand(commandLine) {
|
|
47
|
+
const args = [];
|
|
48
|
+
let current = '';
|
|
49
|
+
let quote = null;
|
|
50
|
+
let hasToken = false;
|
|
51
|
+
for (const ch of commandLine) {
|
|
52
|
+
if (quote !== null) {
|
|
53
|
+
if (ch === quote)
|
|
54
|
+
quote = null;
|
|
55
|
+
else
|
|
56
|
+
current += ch;
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (ch === '"' || ch === "'") {
|
|
60
|
+
quote = ch;
|
|
61
|
+
hasToken = true;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (/\s/.test(ch)) {
|
|
65
|
+
if (current !== '' || hasToken)
|
|
66
|
+
args.push(current);
|
|
67
|
+
current = '';
|
|
68
|
+
hasToken = false;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
current += ch;
|
|
72
|
+
}
|
|
73
|
+
if (current !== '' || hasToken)
|
|
74
|
+
args.push(current);
|
|
75
|
+
return args;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Resolve the editor argv from the environment. `$VISUAL` wins over
|
|
79
|
+
* `$EDITOR` (readline convention); POSIX falls back to `vi`, Windows has no
|
|
80
|
+
* blocking console editor fallback and returns undefined. `platform` is a
|
|
81
|
+
* parameter so the Windows branch is unit-testable from CI's Linux runners.
|
|
82
|
+
*/
|
|
83
|
+
export function resolveEditorCommand(env = process.env, platform = process.platform) {
|
|
84
|
+
const raw = (env.VISUAL ?? '').trim() || (env.EDITOR ?? '').trim();
|
|
85
|
+
if (raw !== '') {
|
|
86
|
+
const args = splitEditorCommand(raw);
|
|
87
|
+
return args.length > 0 ? args : undefined;
|
|
88
|
+
}
|
|
89
|
+
return platform === 'win32' ? undefined : ['vi'];
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Windows shim resolution: a bare command like `code` usually lives on PATH
|
|
93
|
+
* as `code.cmd`, which libuv refuses to execute directly. Walk PATH with
|
|
94
|
+
* PATHEXT (case-insensitive on Windows; both casings tried for tests on
|
|
95
|
+
* case-sensitive filesystems) and report whether the resolved file needs
|
|
96
|
+
* cmd.exe to run. Commands carrying an explicit extension are used as-is;
|
|
97
|
+
* unresolved names fall back to the bare command (spawn then resolves
|
|
98
|
+
* `.exe`, or fails into the `failed` outcome).
|
|
99
|
+
*/
|
|
100
|
+
export function resolveWindowsShim(command, env = process.env) {
|
|
101
|
+
if (/\.[a-z0-9]+$/i.test(command)) {
|
|
102
|
+
return { command, viaCmd: /\.(cmd|bat)$/i.test(command) };
|
|
103
|
+
}
|
|
104
|
+
const extensions = (env.PATHEXT ?? '.COM;.EXE;.BAT;.CMD')
|
|
105
|
+
.split(';')
|
|
106
|
+
.map(ext => ext.trim())
|
|
107
|
+
.filter(ext => ext !== '');
|
|
108
|
+
const pathValue = env.PATH ?? env.Path ?? env.path ?? '';
|
|
109
|
+
for (const dir of pathValue.split(delimiter)) {
|
|
110
|
+
if (dir === '')
|
|
111
|
+
continue;
|
|
112
|
+
for (const ext of extensions) {
|
|
113
|
+
for (const casing of [ext, ext.toLowerCase()]) {
|
|
114
|
+
const candidate = join(dir, command + casing);
|
|
115
|
+
if (existsSync(candidate)) {
|
|
116
|
+
return { command: candidate, viaCmd: /\.(cmd|bat)$/i.test(candidate) };
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return { command, viaCmd: false };
|
|
122
|
+
}
|
|
123
|
+
/** npm-generated node shims re-invoke node, parsing the line a second time. */
|
|
124
|
+
const CMD_SHIM_RE = /node_modules[\\/]\.bin[\\/][^\\/]+\.cmd$/i;
|
|
125
|
+
/**
|
|
126
|
+
* Build the `comspec /d /s /c` spawn descriptor for a `.cmd`/`.bat` editor,
|
|
127
|
+
* following the cross-spawn protocol: the command is normalized first
|
|
128
|
+
* (explicit forward-slash paths like `C:/Program Files/.../code.cmd` must
|
|
129
|
+
* become backslash form — cross-spawn's path.normalize step, without which
|
|
130
|
+
* Windows can ENOENT), then command and arguments are escaped, joined, and
|
|
131
|
+
* wrapped in one pair of quotes (`/s` strips exactly those), and passed
|
|
132
|
+
* with `windowsVerbatimArguments` so libuv does not re-quote the payload.
|
|
133
|
+
* Exported for tests — the assembly is pure.
|
|
134
|
+
*/
|
|
135
|
+
export function buildCmdExeSpawn(command, args, env = process.env) {
|
|
136
|
+
const normalized = win32.normalize(command);
|
|
137
|
+
const line = [
|
|
138
|
+
cmdEscapeCommand(normalized),
|
|
139
|
+
...args.map(arg => cmdEscapeArgument(arg, CMD_SHIM_RE.test(normalized))),
|
|
140
|
+
].join(' ');
|
|
141
|
+
return {
|
|
142
|
+
// `||`, not `??`: a present-but-empty ComSpec must fall back too
|
|
143
|
+
// (cross-spawn semantics); spawning an empty file name fails outright.
|
|
144
|
+
file: env.comspec || 'cmd.exe',
|
|
145
|
+
args: ['/d', '/s', '/c', `"${line}"`],
|
|
146
|
+
verbatim: true,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Run the editor to completion with the terminal attached; resolves to the
|
|
151
|
+
* exit code, or -1 when the process could not start — including a
|
|
152
|
+
* SYNCHRONOUS spawn failure (e.g. an empty command string), which would
|
|
153
|
+
* otherwise reject the promise and skip every cleanup step.
|
|
154
|
+
*/
|
|
155
|
+
function runEditor(argv, file) {
|
|
156
|
+
return new Promise(resolve => {
|
|
157
|
+
let settled = false;
|
|
158
|
+
const finish = (code) => {
|
|
159
|
+
if (settled)
|
|
160
|
+
return;
|
|
161
|
+
settled = true;
|
|
162
|
+
resolve(code);
|
|
163
|
+
};
|
|
164
|
+
let child;
|
|
165
|
+
try {
|
|
166
|
+
if (process.platform === 'win32') {
|
|
167
|
+
const shim = resolveWindowsShim(argv[0]);
|
|
168
|
+
if (shim.viaCmd) {
|
|
169
|
+
const cmd = buildCmdExeSpawn(shim.command, [...argv.slice(1), file]);
|
|
170
|
+
child = spawn(cmd.file, cmd.args, {
|
|
171
|
+
stdio: 'inherit',
|
|
172
|
+
windowsVerbatimArguments: cmd.verbatim,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
child = spawn(shim.command, [...argv.slice(1), file], { stdio: 'inherit' });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
child = spawn(argv[0], [...argv.slice(1), file], { stdio: 'inherit' });
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
finish(-1);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
child.once('error', () => finish(-1));
|
|
188
|
+
child.once('close', code => finish(code ?? 1));
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/** Error text for the `failed` outcome, err.message when available. */
|
|
192
|
+
function errorMessage(error) {
|
|
193
|
+
return error instanceof Error ? error.message : String(error);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Edit `draft` in the user's editor and report what happened. Never throws:
|
|
197
|
+
* every filesystem, spawn, or terminal-restore failure maps to a `failed`
|
|
198
|
+
* outcome (or is swallowed in the finally) so the UI notifies instead of
|
|
199
|
+
* dying on an unhandled rejection.
|
|
200
|
+
*
|
|
201
|
+
* The Ink instance is looked up lazily (same pattern as Chat's Ctrl+L
|
|
202
|
+
* redraw) so the util stays usable in tests and non-TTY contexts: without a
|
|
203
|
+
* live instance the handover escapes are skipped and the editor simply
|
|
204
|
+
* inherits stdio.
|
|
205
|
+
*
|
|
206
|
+
* Newline handling: the saved file is compared against the draft with BOTH
|
|
207
|
+
* sides CRLF-normalized, so an editor that only converts line endings (or
|
|
208
|
+
* a draft that already carries `\r\n`) never counts as an edit. Otherwise
|
|
209
|
+
* ONE trailing newline is stripped when the normalized draft did not end
|
|
210
|
+
* with one — that is the terminating newline editors append on save, not
|
|
211
|
+
* user content. Trailing blank lines the user actually added (or had in
|
|
212
|
+
* the draft, e.g. from Shift+Enter) survive untouched.
|
|
213
|
+
*/
|
|
214
|
+
export async function editInExternalEditor(draft) {
|
|
215
|
+
const argv = resolveEditorCommand();
|
|
216
|
+
if (argv === undefined)
|
|
217
|
+
return { kind: 'unavailable' };
|
|
218
|
+
const ink = instances.get(process.stdout) ??
|
|
219
|
+
// Test harnesses render onto a fake stdout — fall back to the process's
|
|
220
|
+
// single live instance so the handover path stays exercisable there.
|
|
221
|
+
(instances.size === 1 ? [...instances.values()][0] : undefined);
|
|
222
|
+
let handed = false;
|
|
223
|
+
let dir;
|
|
224
|
+
try {
|
|
225
|
+
dir = await mkdtemp(join(tmpdir(), 'dsh-tui-prompt-'));
|
|
226
|
+
// .md so markdown-aware editors highlight the draft like a chat message.
|
|
227
|
+
const file = join(dir, 'input.md');
|
|
228
|
+
await writeFile(file, draft, 'utf8');
|
|
229
|
+
// Mark the handover as attempted BEFORE entering: if enter fails after
|
|
230
|
+
// suspending stdin, the finally must still run the restore pass.
|
|
231
|
+
handed = ink !== undefined;
|
|
232
|
+
ink?.enterAlternateScreen();
|
|
233
|
+
const code = await runEditor(argv, file);
|
|
234
|
+
// Read back BEFORE the finally resumes stdin — keystrokes typed the
|
|
235
|
+
// moment the editor exits must not race the prompt adopting the result.
|
|
236
|
+
const saved = await readFile(file, 'utf8').catch(() => null);
|
|
237
|
+
if (code === -1)
|
|
238
|
+
return { kind: 'failed', message: argv[0] };
|
|
239
|
+
if (code !== 0 || saved === null)
|
|
240
|
+
return { kind: 'unchanged' };
|
|
241
|
+
const normalized = saved.replace(/\r\n/g, '\n');
|
|
242
|
+
const draftNormalized = draft.replace(/\r\n/g, '\n');
|
|
243
|
+
if (normalized === draftNormalized)
|
|
244
|
+
return { kind: 'unchanged' };
|
|
245
|
+
const text = !draftNormalized.endsWith('\n') && normalized.endsWith('\n')
|
|
246
|
+
? normalized.slice(0, -1)
|
|
247
|
+
: normalized;
|
|
248
|
+
return text === draftNormalized ? { kind: 'unchanged' } : { kind: 'edited', text };
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
return { kind: 'failed', message: errorMessage(error) };
|
|
252
|
+
}
|
|
253
|
+
finally {
|
|
254
|
+
// Cleanup runs before the restore: when the finally ends, stdin must
|
|
255
|
+
// come back to a fully settled state. Both steps are best-effort — a
|
|
256
|
+
// failure here never overrides the outcome produced above.
|
|
257
|
+
if (dir !== undefined) {
|
|
258
|
+
await rm(dir, { recursive: true, force: true }).catch(() => { });
|
|
259
|
+
}
|
|
260
|
+
if (handed) {
|
|
261
|
+
try {
|
|
262
|
+
ink?.exitAlternateScreen();
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
// A stuck alt screen is visible to the user; a rejection on top of
|
|
266
|
+
// a valid outcome is strictly worse — swallow and keep the outcome.
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Whether mouse click handling is disabled for the ported Ink core. dsh-tui
|
|
3
|
-
* reads its own env flag (`
|
|
3
|
+
* reads its own env flag (`DSH_TUI_DISABLE_MOUSE`); the original module
|
|
4
4
|
* consulted Claude Code's fullscreen state.
|
|
5
|
-
* @returns True when
|
|
5
|
+
* @returns True when DSH_TUI_DISABLE_MOUSE is set to a truthy value.
|
|
6
6
|
*/
|
|
7
7
|
export declare function isMouseClicksDisabled(): boolean;
|
|
8
8
|
//# sourceMappingURL=fullscreen.d.ts.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { isEnvTruthy } from './envUtils.js';
|
|
2
2
|
/**
|
|
3
3
|
* Whether mouse click handling is disabled for the ported Ink core. dsh-tui
|
|
4
|
-
* reads its own env flag (`
|
|
4
|
+
* reads its own env flag (`DSH_TUI_DISABLE_MOUSE`); the original module
|
|
5
5
|
* consulted Claude Code's fullscreen state.
|
|
6
|
-
* @returns True when
|
|
6
|
+
* @returns True when DSH_TUI_DISABLE_MOUSE is set to a truthy value.
|
|
7
7
|
*/
|
|
8
8
|
export function isMouseClicksDisabled() {
|
|
9
|
-
return isEnvTruthy(process.env.
|
|
9
|
+
return isEnvTruthy(process.env.DSH_TUI_DISABLE_MOUSE);
|
|
10
10
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loaded-context.d.ts","sourceRoot":"","sources":["../../../src/utils/loaded-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"loaded-context.d.ts","sourceRoot":"","sources":["../../../src/utils/loaded-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAG9D,0EAA0E;AAC1E,eAAO,MAAM,uBAAuB,MAAM,CAAA;AAE1C;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAA0B,GAAG,MAAM,CAGvF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAQrE"}
|
|
@@ -16,4 +16,28 @@ export declare function isMod(key: {
|
|
|
16
16
|
* "ctrl+" everywhere else. Pair with the bare key, e.g. `${modLabel}o`.
|
|
17
17
|
*/
|
|
18
18
|
export declare const modLabel: string;
|
|
19
|
+
/**
|
|
20
|
+
* Modal-confirm guard. Since #110 the input pipeline can deliver Enter WITH
|
|
21
|
+
* modifiers: Option+Enter arrives as meta+return (ESC CR), and on
|
|
22
|
+
* extended-keys terminals (kitty CSI-u / modifyOtherKeys) Shift/Ctrl+Enter
|
|
23
|
+
* arrive as return+modifier. A bare `key.return` in a decision dialog would
|
|
24
|
+
* let those commit by accident — approving a permission escalation or
|
|
25
|
+
* confirming an irreversible session delete when the user only wanted a
|
|
26
|
+
* newline. Only a modifier-free Enter may commit a modal.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isPlainReturn(key: {
|
|
29
|
+
return?: boolean;
|
|
30
|
+
ctrl?: boolean;
|
|
31
|
+
meta?: boolean;
|
|
32
|
+
shift?: boolean;
|
|
33
|
+
super?: boolean;
|
|
34
|
+
}): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Modal Enter recognition across parsed key events and Windows ConPTY's raw
|
|
37
|
+
* CR/LF fallback. PromptInput already handled both forms; shared modal
|
|
38
|
+
* pickers must do the same or their UI can render while Enter appears inert.
|
|
39
|
+
*/
|
|
40
|
+
export declare function isPlainReturnInput(input: string, key: Parameters<typeof isPlainReturn>[0] & {
|
|
41
|
+
isPasted?: boolean;
|
|
42
|
+
}): boolean;
|
|
19
43
|
//# sourceMappingURL=modifiers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"modifiers.d.ts","sourceRoot":"","sources":["../../../src/utils/modifiers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,KAAK,SAAgC,CAAA;AAElD,yEAAyE;AACzE,wBAAgB,KAAK,CAAC,GAAG,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAEvE;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ,QAAwB,CAAA"}
|
|
1
|
+
{"version":3,"file":"modifiers.d.ts","sourceRoot":"","sources":["../../../src/utils/modifiers.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,KAAK,SAAgC,CAAA;AAElD,yEAAyE;AACzE,wBAAgB,KAAK,CAAC,GAAG,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAEvE;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ,QAAwB,CAAA;AAE7C;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE;IACjC,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB,GAAG,OAAO,CAEV;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAChE,OAAO,CAOT"}
|
|
@@ -15,3 +15,30 @@ export function isMod(key) {
|
|
|
15
15
|
* "ctrl+" everywhere else. Pair with the bare key, e.g. `${modLabel}o`.
|
|
16
16
|
*/
|
|
17
17
|
export const modLabel = isMac ? '⌘' : 'ctrl+';
|
|
18
|
+
/**
|
|
19
|
+
* Modal-confirm guard. Since #110 the input pipeline can deliver Enter WITH
|
|
20
|
+
* modifiers: Option+Enter arrives as meta+return (ESC CR), and on
|
|
21
|
+
* extended-keys terminals (kitty CSI-u / modifyOtherKeys) Shift/Ctrl+Enter
|
|
22
|
+
* arrive as return+modifier. A bare `key.return` in a decision dialog would
|
|
23
|
+
* let those commit by accident — approving a permission escalation or
|
|
24
|
+
* confirming an irreversible session delete when the user only wanted a
|
|
25
|
+
* newline. Only a modifier-free Enter may commit a modal.
|
|
26
|
+
*/
|
|
27
|
+
export function isPlainReturn(key) {
|
|
28
|
+
return !!key.return && !key.ctrl && !key.meta && !key.shift && !key.super;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Modal Enter recognition across parsed key events and Windows ConPTY's raw
|
|
32
|
+
* CR/LF fallback. PromptInput already handled both forms; shared modal
|
|
33
|
+
* pickers must do the same or their UI can render while Enter appears inert.
|
|
34
|
+
*/
|
|
35
|
+
export function isPlainReturnInput(input, key) {
|
|
36
|
+
if (isPlainReturn(key))
|
|
37
|
+
return true;
|
|
38
|
+
// Bracketed paste can deliver a chunk that is all line breaks — that is
|
|
39
|
+
// pasted content, not an Enter press, and must never confirm a modal.
|
|
40
|
+
if (key.isPasted === true)
|
|
41
|
+
return false;
|
|
42
|
+
return /^[\r\n]+$/u.test(input)
|
|
43
|
+
&& !key.ctrl && !key.meta && !key.shift && !key.super;
|
|
44
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data-directory paths for the dsh-tui profile, renamed from `~/.dsh-cc` to
|
|
3
|
+
* `~/.dsh-tui` (issue #120). On first launch the legacy directory is COPIED
|
|
4
|
+
* (not moved) to the new location; afterwards only the new directory is read
|
|
5
|
+
* and written. The one exception is `resume.txt`, which sessionHistory
|
|
6
|
+
* dual-writes for old launchers — see the launcher contract there.
|
|
7
|
+
*
|
|
8
|
+
* The compiled copy (lib/types/utils/paths.js) is also imported by the bin
|
|
9
|
+
* launcher, mirroring the shellQuote precedent.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* The user's home directory. `os.homedir()` first; the USERPROFILE/HOME
|
|
13
|
+
* spellings are the last-resort fallback for stripped-down environments.
|
|
14
|
+
* @returns Absolute home path.
|
|
15
|
+
*/
|
|
16
|
+
export declare function homeDir(): string;
|
|
17
|
+
/** Data directory all preferences/history live in (`~/.dsh-tui`). */
|
|
18
|
+
export declare const DATA_DIR: string;
|
|
19
|
+
/** Pre-rename data directory (`~/.dsh-cc`), read only for migration. */
|
|
20
|
+
export declare const LEGACY_DATA_DIR: string;
|
|
21
|
+
/**
|
|
22
|
+
* Copy the legacy data directory to the new location on first launch.
|
|
23
|
+
* A copy (not a move) so old launchers keep working and the user can delete
|
|
24
|
+
* the legacy directory themselves once satisfied. No-op when the legacy
|
|
25
|
+
* directory is absent or the new one already exists.
|
|
26
|
+
* @param legacy - Legacy directory (injectable for tests).
|
|
27
|
+
* @param target - New directory (injectable for tests).
|
|
28
|
+
* @returns True when a migration copy happened.
|
|
29
|
+
*/
|
|
30
|
+
export declare function migrateLegacyDataDir(legacy?: string, target?: string): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Env vars renamed in issue #120 that no longer take effect: old name → new
|
|
33
|
+
* name. `DSH_CC_RESUME_SESSION` is deliberately absent — it remains a valid
|
|
34
|
+
* half of the dual-read launcher contract (see sessionHistory.ts).
|
|
35
|
+
*/
|
|
36
|
+
export declare const RENAMED_ENV: Readonly<Record<string, string>>;
|
|
37
|
+
/**
|
|
38
|
+
* Old env-var names still set in the environment (they no longer take
|
|
39
|
+
* effect). Used to print one deprecation line per name before the TUI
|
|
40
|
+
* renders — stderr writes break the fullscreen UI once it is up.
|
|
41
|
+
* @param env - Environment to scan (defaults to process.env; injectable).
|
|
42
|
+
* @returns The legacy names found, in RENAMED_ENV order.
|
|
43
|
+
*/
|
|
44
|
+
export declare function detectLegacyEnv(env?: NodeJS.ProcessEnv): string[];
|
|
45
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/utils/paths.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH;;;;GAIG;AACH,wBAAgB,OAAO,IAAI,MAAM,CAEhC;AAED,qEAAqE;AACrE,eAAO,MAAM,QAAQ,QAA8B,CAAA;AAEnD,wEAAwE;AACxE,eAAO,MAAM,eAAe,QAA6B,CAAA;AAEzD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,GAAE,MAAwB,EAChC,MAAM,GAAE,MAAiB,GACxB,OAAO,CAIT;AAED;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAaxD,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,EAAE,CAEV"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data-directory paths for the dsh-tui profile, renamed from `~/.dsh-cc` to
|
|
3
|
+
* `~/.dsh-tui` (issue #120). On first launch the legacy directory is COPIED
|
|
4
|
+
* (not moved) to the new location; afterwards only the new directory is read
|
|
5
|
+
* and written. The one exception is `resume.txt`, which sessionHistory
|
|
6
|
+
* dual-writes for old launchers — see the launcher contract there.
|
|
7
|
+
*
|
|
8
|
+
* The compiled copy (lib/types/utils/paths.js) is also imported by the bin
|
|
9
|
+
* launcher, mirroring the shellQuote precedent.
|
|
10
|
+
*/
|
|
11
|
+
import { cpSync, existsSync } from 'node:fs';
|
|
12
|
+
import { homedir } from 'node:os';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
/**
|
|
15
|
+
* The user's home directory. `os.homedir()` first; the USERPROFILE/HOME
|
|
16
|
+
* spellings are the last-resort fallback for stripped-down environments.
|
|
17
|
+
* @returns Absolute home path.
|
|
18
|
+
*/
|
|
19
|
+
export function homeDir() {
|
|
20
|
+
return homedir() || process.env.USERPROFILE || process.env.HOME || '';
|
|
21
|
+
}
|
|
22
|
+
/** Data directory all preferences/history live in (`~/.dsh-tui`). */
|
|
23
|
+
export const DATA_DIR = join(homeDir(), '.dsh-tui');
|
|
24
|
+
/** Pre-rename data directory (`~/.dsh-cc`), read only for migration. */
|
|
25
|
+
export const LEGACY_DATA_DIR = join(homeDir(), '.dsh-cc');
|
|
26
|
+
/**
|
|
27
|
+
* Copy the legacy data directory to the new location on first launch.
|
|
28
|
+
* A copy (not a move) so old launchers keep working and the user can delete
|
|
29
|
+
* the legacy directory themselves once satisfied. No-op when the legacy
|
|
30
|
+
* directory is absent or the new one already exists.
|
|
31
|
+
* @param legacy - Legacy directory (injectable for tests).
|
|
32
|
+
* @param target - New directory (injectable for tests).
|
|
33
|
+
* @returns True when a migration copy happened.
|
|
34
|
+
*/
|
|
35
|
+
export function migrateLegacyDataDir(legacy = LEGACY_DATA_DIR, target = DATA_DIR) {
|
|
36
|
+
if (!existsSync(legacy) || existsSync(target))
|
|
37
|
+
return false;
|
|
38
|
+
cpSync(legacy, target, { recursive: true });
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Env vars renamed in issue #120 that no longer take effect: old name → new
|
|
43
|
+
* name. `DSH_CC_RESUME_SESSION` is deliberately absent — it remains a valid
|
|
44
|
+
* half of the dual-read launcher contract (see sessionHistory.ts).
|
|
45
|
+
*/
|
|
46
|
+
export const RENAMED_ENV = {
|
|
47
|
+
CC_TUI_THEME: 'DSH_TUI_THEME',
|
|
48
|
+
CC_TUI_LANG: 'DSH_TUI_LANG',
|
|
49
|
+
CC_TUI_PERSONA: 'DSH_TUI_PERSONA',
|
|
50
|
+
CC_TUI_PRESET: 'DSH_TUI_PRESET',
|
|
51
|
+
CC_TUI_DISABLE_MOUSE: 'DSH_TUI_DISABLE_MOUSE',
|
|
52
|
+
CC_TUI_DEBUG: 'DSH_TUI_DEBUG',
|
|
53
|
+
CC_TUI_COMPACT_RATIO: 'DSH_TUI_COMPACT_RATIO',
|
|
54
|
+
CC_TUI_COMPACT_RETAIN: 'DSH_TUI_COMPACT_RETAIN',
|
|
55
|
+
DSH_CC_UPDATED_FROM: 'DSH_TUI_UPDATED_FROM',
|
|
56
|
+
DSH_CC_RENDER_LOG: 'DSH_TUI_RENDER_LOG',
|
|
57
|
+
DSH_CC_SESSION_ROOT: 'DSH_TUI_SESSION_ROOT',
|
|
58
|
+
DSH_CC_WORKSPACE: 'DSH_TUI_WORKSPACE',
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Old env-var names still set in the environment (they no longer take
|
|
62
|
+
* effect). Used to print one deprecation line per name before the TUI
|
|
63
|
+
* renders — stderr writes break the fullscreen UI once it is up.
|
|
64
|
+
* @param env - Environment to scan (defaults to process.env; injectable).
|
|
65
|
+
* @returns The legacy names found, in RENAMED_ENV order.
|
|
66
|
+
*/
|
|
67
|
+
export function detectLegacyEnv(env = process.env) {
|
|
68
|
+
return Object.keys(RENAMED_ENV).filter(name => env[name] !== undefined);
|
|
69
|
+
}
|