@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
|
@@ -5,20 +5,28 @@ import UserQuestionService from '@deepseek-ai/dsh-user-questions';
|
|
|
5
5
|
import * as toolAskUser from '@deepseek-ai/dsh-tool-ask-user';
|
|
6
6
|
import { createChannel } from './channel.js';
|
|
7
7
|
import { createChildStderrReporter, installChildStderrGuard } from './childStderr.js';
|
|
8
|
-
import { logForDebugging } from '
|
|
8
|
+
import { logForDebugging } from '../utils/debug.js';
|
|
9
9
|
import { QuestionStore } from './questions.js';
|
|
10
10
|
import { ApprovalStore } from './approvals.js';
|
|
11
11
|
import { registerPackagedSkills } from './packaged-skills.js';
|
|
12
|
-
import { readActivityFrames } from '
|
|
13
|
-
import { readModelPref } from '
|
|
14
|
-
import { explicitModelRoute, recordedModelRoute, resolveModelRoute, validateModelRoute } from '
|
|
15
|
-
import { readPresetPref } from '
|
|
12
|
+
import { readActivityFrames } from '../activityPrefs.js';
|
|
13
|
+
import { readModelPref } from '../modelPrefs.js';
|
|
14
|
+
import { explicitModelRoute, recordedModelRoute, resolveModelRoute, validateModelRoute } from '../modelRoute.js';
|
|
15
|
+
import { readPresetPref } from '../presetPrefs.js';
|
|
16
16
|
import { composePreset, resolvePersistedPreset, runningPresetOf } from './presets.js';
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
17
|
+
import { ensureLegacySessionEventTypes } from './compat/index.js';
|
|
18
|
+
import { clearResumeTarget, writeResumeTarget } from '../sessionHistory.js';
|
|
19
|
+
import { resolveSessionCwd } from '../utils/workspaceRoot.js';
|
|
20
|
+
import { checkForTuiUpdate, installedTuiVersion, isVersionNewer, resolveDshProfileName, resolveTuiUpdateTarget, updateTuiAndRestart } from '../update.js';
|
|
21
|
+
import { isLang, resolveStartupLang, setLang, t } from '../i18n.js';
|
|
22
|
+
import { detectLegacyEnv, migrateLegacyDataDir, RENAMED_ENV } from '../utils/paths.js';
|
|
23
|
+
import { Chat } from '../screens/Chat.js';
|
|
24
|
+
import { attachSessionToWorkspace } from './workspace.js';
|
|
25
|
+
import { render, ThemeProvider, AlternateScreen } from '../ui.js';
|
|
26
|
+
import instances from '../ink/instances.js';
|
|
27
|
+
import { cursorMove, DISABLE_KITTY_KEYBOARD, DISABLE_MODIFY_OTHER_KEYS, DISABLE_WIN32_INPUT_MODE } from '../ink/termio/csi.js';
|
|
28
|
+
import { DBP, DFE, DISABLE_MOUSE_TRACKING, EXIT_ALT_SCREEN, SHOW_CURSOR } from '../ink/termio/dec.js';
|
|
29
|
+
import { CLEAR_ITERM2_PROGRESS, CLEAR_TAB_STATUS, supportsTabStatus, wrapForMultiplexer } from '../ink/termio/osc.js';
|
|
22
30
|
/**
|
|
23
31
|
* Claude Code style interactive TUI front door for DeepSeek Harness agents.
|
|
24
32
|
*
|
|
@@ -32,23 +40,43 @@ export async function apply(ctx, config) {
|
|
|
32
40
|
if (!process.stdout.isTTY) {
|
|
33
41
|
throw new Error('dsh-tui requires an interactive terminal (stdout must be a TTY).');
|
|
34
42
|
}
|
|
35
|
-
//
|
|
43
|
+
// Data-directory rename (~/.dsh-cc → ~/.dsh-tui, issue #120): copy the
|
|
44
|
+
// legacy directory before ANY preference read below (resolveStartupLang
|
|
45
|
+
// already touches lang.json). Copy, not move — old launchers keep working
|
|
46
|
+
// and the user deletes the legacy directory themselves.
|
|
47
|
+
const migrated = migrateLegacyDataDir();
|
|
48
|
+
// UI language resolution: DSH_TUI_LANG env var wins, then cordis.yml
|
|
36
49
|
// `lang`, then the persisted `/lang` choice, then `zh`. Must settle
|
|
37
50
|
// before the first render so every module resolves strings in the same
|
|
38
51
|
// language.
|
|
39
|
-
const envLang = process.env.
|
|
52
|
+
const envLang = process.env.DSH_TUI_LANG;
|
|
40
53
|
setLang(isLang(envLang) ? envLang : isLang(config.lang) ? config.lang : resolveStartupLang());
|
|
54
|
+
// Rename notices must land before the first render — stderr writes break
|
|
55
|
+
// the fullscreen UI once it is up. The bin launcher prints the same
|
|
56
|
+
// warnings; this covers direct `dsh --profile dsh-tui` boots.
|
|
57
|
+
if (migrated) {
|
|
58
|
+
ctx.logger.warn('dsh-tui: data directory copied from ~/.dsh-cc to ~/.dsh-tui (legacy kept)');
|
|
59
|
+
if (process.stderr.isTTY) {
|
|
60
|
+
process.stderr.write(`\n[dsh-tui] ${t('legacy-dir-migrated')}\n`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
for (const oldName of detectLegacyEnv()) {
|
|
64
|
+
ctx.logger.warn(`dsh-tui: env ${oldName} renamed to ${RENAMED_ENV[oldName]}; the old name no longer takes effect`);
|
|
65
|
+
if (process.stderr.isTTY) {
|
|
66
|
+
process.stderr.write(`\n[dsh-tui] ${t('legacy-env-renamed', { old: oldName, new: RENAMED_ENV[oldName] })}\n`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
41
69
|
// /update restart verification: the pre-update process stamps the version
|
|
42
70
|
// it was leaving behind; if the freshly loaded one is not newer, the
|
|
43
71
|
// package manager "succeeded" without actually moving the version (mirror
|
|
44
72
|
// lag, cached manifest, wrong profile). Say so instead of silently
|
|
45
73
|
// pretending the update landed.
|
|
46
74
|
{
|
|
47
|
-
const updatedFrom = process.env.
|
|
75
|
+
const updatedFrom = process.env.DSH_TUI_UPDATED_FROM;
|
|
48
76
|
if (updatedFrom !== undefined) {
|
|
49
77
|
// Assigning undefined would stringify to "undefined" and leak the
|
|
50
78
|
// marker into every child process; remove it for real.
|
|
51
|
-
delete process.env.
|
|
79
|
+
delete process.env.DSH_TUI_UPDATED_FROM;
|
|
52
80
|
const now = installedTuiVersion();
|
|
53
81
|
if (now === undefined || !isVersionNewer(now, updatedFrom)) {
|
|
54
82
|
ctx.logger.warn(`dsh-tui: /update restarted but the version did not advance (still ${now ?? 'unknown'}, was ${updatedFrom})`);
|
|
@@ -74,10 +102,22 @@ export async function apply(ctx, config) {
|
|
|
74
102
|
// Packaged skills (/audit, /bug, …): contribute them through the host's
|
|
75
103
|
// skill registry so they resolve with zero manual copying.
|
|
76
104
|
registerPackagedSkills(ctx);
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
105
|
+
// Yield to an incumbent provider instead of crashing the whole plugin tree
|
|
106
|
+
// (issue #98): the harness allows exactly ONE user-questions provider per
|
|
107
|
+
// context, and stacking this TUI onto a profile that already carries
|
|
108
|
+
// @deepseek-ai/dsh-web-app (its api-gateway registers first) used to fail
|
|
109
|
+
// the boot with DUPLICATE_PROVIDER. The incumbent UI then owns questionnaire
|
|
110
|
+
// rendering; this TUI's ask_user_question requests are answered there.
|
|
111
|
+
try {
|
|
112
|
+
userQuestions.registerProvider({
|
|
113
|
+
ask: request => questionStore.ask(request),
|
|
114
|
+
});
|
|
115
|
+
ctx.effect(() => () => questionStore.rejectAll());
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
if (error.code !== 'DUPLICATE_PROVIDER')
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
81
121
|
// Child-process stderr guard (issue #17): MCP servers spawned with an
|
|
82
122
|
// inherited stderr (the MCP SDK's stdio default) write straight to the
|
|
83
123
|
// terminal device from the child process, bypassing the renderer's own
|
|
@@ -111,20 +151,61 @@ export async function apply(ctx, config) {
|
|
|
111
151
|
model: config.model,
|
|
112
152
|
};
|
|
113
153
|
// Atomic route resolution (issue #67): a complete cordis.yml route wins
|
|
114
|
-
// whole, else the persisted `/model` choice wins whole, else
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
|
|
119
|
-
const
|
|
154
|
+
// whole, else the persisted `/model` choice wins whole, else Harness's
|
|
155
|
+
// provider-neutral agent-default-model selection. The local DeepSeek pair
|
|
156
|
+
// remains the final fallback for bare embedders without that service. This
|
|
157
|
+
// lets optional provider bundles supply the same default to Web and TUI
|
|
158
|
+
// without patching this front door by name.
|
|
159
|
+
const configuredDefault = ctx.get('agentDefaultModel')?.currentSelection?.();
|
|
160
|
+
const harnessDefault = typeof configuredDefault?.provider === 'string'
|
|
161
|
+
&& configuredDefault.provider.length > 0
|
|
162
|
+
&& typeof configuredDefault.model === 'string'
|
|
163
|
+
&& configuredDefault.model.length > 0
|
|
164
|
+
? { provider: configuredDefault.provider, model: configuredDefault.model }
|
|
165
|
+
: undefined;
|
|
166
|
+
const startupRoute = resolveModelRoute(configuredRoute, readModelPref(), harnessDefault);
|
|
167
|
+
// Session cwd (issue #96): explicit cordis.yml `cwd` wins; otherwise the
|
|
168
|
+
// git worktree root containing the launch directory (the launch directory
|
|
169
|
+
// itself outside any worktree), so `@` completion and mention expansion
|
|
170
|
+
// see the repository, not an arbitrary launch subdirectory. Resolved ONCE
|
|
171
|
+
// here — the agent meta and the channel must agree.
|
|
172
|
+
const requestedWorkspace = config.workspace ?? process.env.DSH_TUI_WORKSPACE_TARGET;
|
|
173
|
+
const initialWorkspace = requestedWorkspace === undefined
|
|
174
|
+
? undefined
|
|
175
|
+
: await ctx.tuiWorkspaces.resolve(requestedWorkspace);
|
|
176
|
+
if (requestedWorkspace !== undefined && initialWorkspace === undefined) {
|
|
177
|
+
throw new Error(`dsh-tui: unsupported or unavailable workspace target: ${requestedWorkspace}`);
|
|
178
|
+
}
|
|
179
|
+
const sessionCwd = initialWorkspace?.cwd ?? resolveSessionCwd(config.cwd);
|
|
180
|
+
const meta = { cwd: sessionCwd };
|
|
120
181
|
const { agent, handle, agentPreset, route: createdRoute } = await resolveAgent(ctx, config.sessionId, configuredRoute, startupRoute, meta, config.preset);
|
|
182
|
+
try {
|
|
183
|
+
// Opening a persisted TUI session is an explicit ownership action too.
|
|
184
|
+
// Older TUI versions only wrote the Session log, so attaching on every
|
|
185
|
+
// startup repairs those durable-but-ungrouped sessions idempotently.
|
|
186
|
+
const attached = await attachSessionToWorkspace(ctx, meta.cwd, agent.session.id);
|
|
187
|
+
if (!attached) {
|
|
188
|
+
ctx.logger.warn(`dsh-tui: session "${agent.session.id}" has no workspace ownership because workspaceRegistry is not mounted`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
// The Session is already published and durable, matching Web's partial
|
|
193
|
+
// failure contract. Keep the TUI usable but make the missing ownership
|
|
194
|
+
// loud instead of silently leaving the conversation Ungrouped.
|
|
195
|
+
ctx.logger.warn(`dsh-tui: session "${agent.session.id}" workspace attachment failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
196
|
+
}
|
|
121
197
|
// Status-line route: the exact route the agent runs with — on create the
|
|
122
198
|
// validated startup resolution, on resume the route the target session's
|
|
123
199
|
// own records carry (a complete cordis.yml pin wins over them).
|
|
124
200
|
const displayRoute = createdRoute ?? startupRoute;
|
|
125
201
|
const channel = createChannel(ctx, agent, {
|
|
126
202
|
model: displayRoute.model,
|
|
127
|
-
|
|
203
|
+
// A RESUMED session keeps its persisted header cwd (issue #96 review):
|
|
204
|
+
// pre-upgrade sessions recorded the launch directory, and re-resolving
|
|
205
|
+
// from the current launch directory would split @ expansion / file
|
|
206
|
+
// completion (state.cwd) from the agent's own workspace record. Fresh
|
|
207
|
+
// sessions record sessionCwd at creation, so both agree there.
|
|
208
|
+
cwd: agent.session.header.cwd ?? sessionCwd,
|
|
128
209
|
provider: displayRoute.provider,
|
|
129
210
|
// Raw cordis.yml route (undefined when unset): the channel's
|
|
130
211
|
// new-session path re-resolves prefs against these, and resume passes
|
|
@@ -142,6 +223,9 @@ export async function apply(ctx, config) {
|
|
|
142
223
|
// persisted `/preset` choice; undefined adopts the roster default.
|
|
143
224
|
configuredPreset: config.preset,
|
|
144
225
|
agentPreset,
|
|
226
|
+
// Shift+Tab session-mode cycle (undefined → the built-in default/
|
|
227
|
+
// plan/full cycle in sessionModes.ts).
|
|
228
|
+
modes: config.modes,
|
|
145
229
|
handle,
|
|
146
230
|
});
|
|
147
231
|
// DSH approval seam: the permission layer asks ApprovalService.request(),
|
|
@@ -189,66 +273,44 @@ export async function apply(ctx, config) {
|
|
|
189
273
|
// Mirror the funnel's internal exited flag for the /update and
|
|
190
274
|
// background-check guards that still read the outer one.
|
|
191
275
|
exited = true;
|
|
192
|
-
try {
|
|
193
|
-
writeResumeTarget(channel.agentId);
|
|
194
|
-
}
|
|
195
|
-
catch {
|
|
196
|
-
// Best effort — the resume marker is a launcher nicety; a stale
|
|
197
|
-
// marker must never block a clean exit.
|
|
198
|
-
}
|
|
199
|
-
try {
|
|
200
|
-
instance?.unmount();
|
|
201
|
-
}
|
|
202
|
-
catch {
|
|
203
|
-
// The terminal state may already be gone (broken pipe, alt session);
|
|
204
|
-
// the exit path must never throw.
|
|
205
|
-
}
|
|
206
276
|
if (error !== undefined) {
|
|
207
|
-
// Error-driven unmount (render crash): stay loud and exit non-zero.
|
|
208
|
-
// A success code + resume hint here would tell wrappers/CI the
|
|
209
|
-
// session ended cleanly while the TUI actually crashed.
|
|
210
277
|
const message = error instanceof Error ? error.message : String(error);
|
|
211
278
|
ctx.logger.error(`dsh-tui: exit after error: ${message}`);
|
|
212
|
-
|
|
213
|
-
process.stderr.write(`\ndsh-tui crashed: ${message}\n`);
|
|
214
|
-
}
|
|
215
|
-
disposeRootAndExit(ctx, 1);
|
|
279
|
+
void finishExit(ctx, instance, config.fullscreen === true, undefined, `dsh-tui crashed: ${message}`, () => disposeRootAndExit(ctx, 1));
|
|
216
280
|
return;
|
|
217
281
|
}
|
|
218
282
|
if (updateRequested) {
|
|
219
|
-
|
|
220
|
-
|
|
283
|
+
try {
|
|
284
|
+
writeResumeTarget(channel.agentId);
|
|
285
|
+
}
|
|
286
|
+
catch {
|
|
287
|
+
// Resume persistence is best effort and must never block an update.
|
|
221
288
|
}
|
|
222
|
-
|
|
223
|
-
// updateRequested only flips when onUpdate exists, which itself
|
|
224
|
-
// requires a resolved profile — narrow for the call below.
|
|
225
|
-
const updateProfile = profile;
|
|
226
|
-
if (updateProfile === undefined) {
|
|
227
|
-
process.stderr.write('\ndsh-tui update aborted: no dsh profile resolved.\n');
|
|
228
|
-
process.exit(1);
|
|
229
|
-
}
|
|
230
|
-
void updateTuiAndRestart(channel.agentId, updateProfile).then(({ updateCode, restartCode }) => {
|
|
231
|
-
if (updateCode !== 0) {
|
|
232
|
-
// The session survives: its log lives in DSH persistence and
|
|
233
|
-
// resume.txt was already written. A bare non-zero exit would
|
|
234
|
-
// drop the user into a shell with no way back in.
|
|
235
|
-
process.stderr.write(`\ndsh-tui update failed (exit ${updateCode}). Your session is preserved — resume with:\n` +
|
|
236
|
-
`${resumeCommand(profile, channel.agentId)}\n\n`);
|
|
237
|
-
}
|
|
238
|
-
process.exit(restartCode);
|
|
239
|
-
}, updateError => {
|
|
240
|
-
const message = updateError instanceof Error ? updateError.message : String(updateError);
|
|
241
|
-
process.stderr.write(`\ndsh-tui update failed: ${message}. Your session is preserved — resume with:\n` +
|
|
242
|
-
`${resumeCommand(profile, channel.agentId)}\n\n`);
|
|
243
|
-
process.exit(1);
|
|
244
|
-
});
|
|
245
|
-
});
|
|
289
|
+
void finishExit(ctx, instance, config.fullscreen === true, 'Updating @deepseek-harness-tui/dsh-tui and restarting…', undefined, () => runUpdate(ctx, profile, channel.agentId));
|
|
246
290
|
return;
|
|
247
291
|
}
|
|
248
|
-
|
|
249
|
-
|
|
292
|
+
// Judge against the live session behind the channel (channel.agentId),
|
|
293
|
+
// not the boot-time agent captured above: /resume, /new and /model swap
|
|
294
|
+
// the active agent, so the captured reference can go stale (see
|
|
295
|
+
// isExitResumable).
|
|
296
|
+
const resumable = isExitResumable({
|
|
297
|
+
pendingCount: channel.pending.length,
|
|
298
|
+
liveAgent: ctx.agents.get(SessionId(channel.agentId)),
|
|
299
|
+
startupAgent: agent,
|
|
300
|
+
});
|
|
301
|
+
try {
|
|
302
|
+
if (resumable)
|
|
303
|
+
writeResumeTarget(channel.agentId);
|
|
304
|
+
else
|
|
305
|
+
clearResumeTarget();
|
|
250
306
|
}
|
|
251
|
-
|
|
307
|
+
catch {
|
|
308
|
+
// Resume persistence is best effort and must never block shutdown.
|
|
309
|
+
}
|
|
310
|
+
const hint = resumable
|
|
311
|
+
? `Resume with the command below:\n${resumeCommand(profile, channel.agentId)}`
|
|
312
|
+
: undefined;
|
|
313
|
+
void finishExit(ctx, instance, config.fullscreen === true, hint, undefined, () => disposeRootAndExit(ctx, 0));
|
|
252
314
|
},
|
|
253
315
|
});
|
|
254
316
|
const handleExit = funnel.handleExit;
|
|
@@ -256,6 +318,9 @@ export async function apply(ctx, config) {
|
|
|
256
318
|
channel,
|
|
257
319
|
questionStore,
|
|
258
320
|
approvalStore,
|
|
321
|
+
// The trajectory scene enters the alt screen itself in inline mode; in
|
|
322
|
+
// fullscreen the tree is already wrapped below, so it must not nest.
|
|
323
|
+
fullscreen: config.fullscreen === true,
|
|
259
324
|
onExit: () => handleExit(),
|
|
260
325
|
// Only a `dsh --profile <name>` launch has a profile installation for
|
|
261
326
|
// `/update` to act on; source checkouts and `--config` overlays get the
|
|
@@ -278,7 +343,7 @@ export async function apply(ctx, config) {
|
|
|
278
343
|
}
|
|
279
344
|
channel.notify(t('update-starting'));
|
|
280
345
|
updateRequested = true;
|
|
281
|
-
|
|
346
|
+
handleExit();
|
|
282
347
|
});
|
|
283
348
|
},
|
|
284
349
|
});
|
|
@@ -343,6 +408,10 @@ async function resolveAgent(ctx, requestedSessionId, configuredRoute, startupRou
|
|
|
343
408
|
return { agent: existing, agentPreset: runningPresetOf(existing.session) };
|
|
344
409
|
}
|
|
345
410
|
try {
|
|
411
|
+
// Compat boundary: register vouched-for legacy event types before the
|
|
412
|
+
// strict read path (issue #153) — same seam as the /resume picker,
|
|
413
|
+
// here for the launch-time --resume flow. In-process only.
|
|
414
|
+
ensureLegacySessionEventTypes();
|
|
346
415
|
// The resumed session keeps the preset its log records (last
|
|
347
416
|
// `agent-preset/selected` wins over the creation header), never the
|
|
348
417
|
// caller's current preference.
|
|
@@ -430,6 +499,136 @@ export function createExitFunnel(deps) {
|
|
|
430
499
|
},
|
|
431
500
|
};
|
|
432
501
|
}
|
|
502
|
+
/**
|
|
503
|
+
* Whether a user exit should leave the resume marker (and print the resume
|
|
504
|
+
* hint). Must be judged against the LIVE session behind the channel, not the
|
|
505
|
+
* boot-time agent apply() captured: /resume, /new and /model swap the active
|
|
506
|
+
* agent (channel.agentId follows, the old handle is disposed), so the
|
|
507
|
+
* captured reference can point at a stale session — wiping a marker the
|
|
508
|
+
* resume path just wrote (boot empty → /resume into history) or rewriting it
|
|
509
|
+
* to a fresh empty session (boot with history → /new). `liveAgent` is the
|
|
510
|
+
* registry lookup of channel.agentId; it falls back to the captured agent
|
|
511
|
+
* when the lookup misses. Exported for scripts/verify-exit-resume-marker.
|
|
512
|
+
*/
|
|
513
|
+
export function isExitResumable(deps) {
|
|
514
|
+
const agent = deps.liveAgent ?? deps.startupAgent;
|
|
515
|
+
return (deps.pendingCount > 0 ||
|
|
516
|
+
agent.session.events.some(event => event.type === 'user/message' && event.data.source.kind === 'user'));
|
|
517
|
+
}
|
|
518
|
+
/** Finish terminal I/O before handing control to a process-level exit action. */
|
|
519
|
+
async function finishExit(ctx, instance, fullscreen, notice, stderrNotice, done) {
|
|
520
|
+
try {
|
|
521
|
+
const runtime = readInkShutdownState(instances.get(process.stdout));
|
|
522
|
+
if (runtime === undefined && instance !== undefined) {
|
|
523
|
+
ctx.logger.debug('dsh-tui: Ink runtime unavailable during shutdown; using generic terminal cleanup');
|
|
524
|
+
}
|
|
525
|
+
const cursor = fullscreen ? '' : cursorMoveToFrameEnd(runtime);
|
|
526
|
+
try {
|
|
527
|
+
runtime?.detachForShutdown?.();
|
|
528
|
+
}
|
|
529
|
+
catch {
|
|
530
|
+
ctx.logger.debug('dsh-tui: Ink shutdown detach failed; continuing with generic terminal cleanup');
|
|
531
|
+
}
|
|
532
|
+
const cleanup = [
|
|
533
|
+
fullscreen ? EXIT_ALT_SCREEN : '',
|
|
534
|
+
cursor,
|
|
535
|
+
DISABLE_MOUSE_TRACKING,
|
|
536
|
+
DISABLE_MODIFY_OTHER_KEYS,
|
|
537
|
+
DISABLE_KITTY_KEYBOARD,
|
|
538
|
+
DISABLE_WIN32_INPUT_MODE,
|
|
539
|
+
DFE,
|
|
540
|
+
DBP,
|
|
541
|
+
SHOW_CURSOR,
|
|
542
|
+
CLEAR_ITERM2_PROGRESS,
|
|
543
|
+
supportsTabStatus() ? wrapForMultiplexer(CLEAR_TAB_STATUS) : '',
|
|
544
|
+
].join('');
|
|
545
|
+
const suffix = notice === undefined ? '' : `${notice}\n`;
|
|
546
|
+
await writeStream(process.stdout, `${cleanup}\r\n${suffix}`);
|
|
547
|
+
if (stderrNotice !== undefined) {
|
|
548
|
+
await writeStream(process.stderr, `\n${stderrNotice}\n`);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
catch {
|
|
552
|
+
ctx.logger.debug('dsh-tui: terminal cleanup failed; continuing with process shutdown');
|
|
553
|
+
}
|
|
554
|
+
done();
|
|
555
|
+
}
|
|
556
|
+
function readInkShutdownState(value) {
|
|
557
|
+
if (value === null || typeof value !== 'object')
|
|
558
|
+
return undefined;
|
|
559
|
+
const candidate = value;
|
|
560
|
+
if (candidate.detachForShutdown !== undefined && typeof candidate.detachForShutdown !== 'function')
|
|
561
|
+
return undefined;
|
|
562
|
+
if (candidate.frontFrame !== undefined && !isFrameState(candidate.frontFrame))
|
|
563
|
+
return undefined;
|
|
564
|
+
if (candidate.displayCursor !== undefined && candidate.displayCursor !== null && !isCursorState(candidate.displayCursor))
|
|
565
|
+
return undefined;
|
|
566
|
+
return value;
|
|
567
|
+
}
|
|
568
|
+
function isFrameState(value) {
|
|
569
|
+
if (value === null || typeof value !== 'object')
|
|
570
|
+
return false;
|
|
571
|
+
const cursor = value.cursor;
|
|
572
|
+
return cursor === undefined || isCursorState(cursor);
|
|
573
|
+
}
|
|
574
|
+
function isCursorState(value) {
|
|
575
|
+
if (value === null || typeof value !== 'object')
|
|
576
|
+
return false;
|
|
577
|
+
const cursor = value;
|
|
578
|
+
return typeof cursor.x === 'number' && typeof cursor.y === 'number';
|
|
579
|
+
}
|
|
580
|
+
function cursorMoveToFrameEnd(runtime) {
|
|
581
|
+
const frame = runtime?.frontFrame?.cursor;
|
|
582
|
+
if (frame === undefined)
|
|
583
|
+
return '';
|
|
584
|
+
const parked = runtime?.displayCursor ?? frame;
|
|
585
|
+
return cursorMove(frame.x - parked.x, frame.y - parked.y);
|
|
586
|
+
}
|
|
587
|
+
function writeStream(stream, data) {
|
|
588
|
+
if (data.length === 0)
|
|
589
|
+
return Promise.resolve();
|
|
590
|
+
return new Promise(resolve => {
|
|
591
|
+
let settled = false;
|
|
592
|
+
const finish = () => {
|
|
593
|
+
if (settled)
|
|
594
|
+
return;
|
|
595
|
+
settled = true;
|
|
596
|
+
resolve();
|
|
597
|
+
};
|
|
598
|
+
const timer = setTimeout(finish, 1000);
|
|
599
|
+
timer.unref();
|
|
600
|
+
try {
|
|
601
|
+
stream.write(data, () => {
|
|
602
|
+
clearTimeout(timer);
|
|
603
|
+
finish();
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
catch {
|
|
607
|
+
clearTimeout(timer);
|
|
608
|
+
finish();
|
|
609
|
+
}
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
function runUpdate(ctx, profile, sessionId) {
|
|
613
|
+
disposeRootAndThen(ctx, () => {
|
|
614
|
+
if (profile === undefined) {
|
|
615
|
+
process.stderr.write(`\n${t('update-aborted-no-profile')}\n`);
|
|
616
|
+
process.exit(1);
|
|
617
|
+
}
|
|
618
|
+
void updateTuiAndRestart(sessionId, profile).then(({ updateCode, restartCode }) => {
|
|
619
|
+
if (updateCode !== 0) {
|
|
620
|
+
process.stderr.write(`\ndsh-tui update failed (exit ${updateCode}). Your session is preserved — resume with:\n` +
|
|
621
|
+
`${resumeCommand(profile, sessionId)}\n\n`);
|
|
622
|
+
}
|
|
623
|
+
process.exit(restartCode);
|
|
624
|
+
}, updateError => {
|
|
625
|
+
const message = updateError instanceof Error ? updateError.message : String(updateError);
|
|
626
|
+
process.stderr.write(`\ndsh-tui update failed: ${message}. Your session is preserved — resume with:\n` +
|
|
627
|
+
`${resumeCommand(profile, sessionId)}\n\n`);
|
|
628
|
+
process.exit(1);
|
|
629
|
+
});
|
|
630
|
+
});
|
|
631
|
+
}
|
|
433
632
|
/**
|
|
434
633
|
* Dispose the whole application before process exit, with a bounded fallback.
|
|
435
634
|
* Mirrors the deleted dsh-tui front-door exit semantics.
|
|
@@ -440,15 +639,16 @@ function disposeRootAndExit(ctx, code) {
|
|
|
440
639
|
/**
|
|
441
640
|
* The real way back into a session after the TUI process is gone. The
|
|
442
641
|
* package ships no `dsh-tui` bin — resuming means feeding the session id
|
|
443
|
-
* through `
|
|
444
|
-
*
|
|
445
|
-
*
|
|
642
|
+
* through `DSH_TUI_RESUME_SESSION` (what cordis.patch.yml's `sessionId`
|
|
643
|
+
* reads; the pre-rename DSH_CC_ spelling still works, issue #120) and
|
|
644
|
+
* booting the same profile; on Windows the repo's dsh-tui.cmd wrapper
|
|
645
|
+
* does this via --resume + ~/.dsh-tui/resume.txt.
|
|
446
646
|
*/
|
|
447
647
|
function resumeCommand(profile, sessionId) {
|
|
448
648
|
const boot = profile === undefined ? 'dsh --config cordis.yml' : `dsh --profile ${profile}`;
|
|
449
649
|
return process.platform === 'win32'
|
|
450
650
|
? `dsh-tui --resume ${sessionId}`
|
|
451
|
-
: `
|
|
651
|
+
: `DSH_TUI_RESUME_SESSION=${sessionId} ${boot}`;
|
|
452
652
|
}
|
|
453
653
|
/**
|
|
454
654
|
* Dispose the Cordis tree, then run a process-level handoff action. The
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/presets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAGzD,0EAA0E;AAC1E,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAA;IACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,+DAA+D;AAC/D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,IAAI,IAAI,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,CAAA;IAC3C,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;IAC9C,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;IAC/D,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;IAClE,yEAAyE;IACzE,UAAU,CAAC,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,OAAO,CAAA;KAAE,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAC3D;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,gBAAgB,GAAG,SAAS,CAEnE;AAED,kEAAkE;AAClE,MAAM,WAAW,iBAAiB;IAChC,kFAAkF;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAA;CAC5B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAmBhG;AAED;;;;;;;;;GASG;AACH,wBAAsB,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAqB5G;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACvC,MAAM,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAChC,MAAM,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;CACnD,GAAG,MAAM,GAAG,SAAS,CAErB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAKpG"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/provider` wizard — interactively adds an LLM provider route at runtime.
|
|
3
|
+
*
|
|
4
|
+
* The wizard is a sequence of `QuestionStore` asks (the same panel the
|
|
5
|
+
* model-facing `ask_user_question` tool uses), so it needs no UI state of
|
|
6
|
+
* its own. All side effects go through {@link ProviderSetupHost}, which the
|
|
7
|
+
* channel implements over the dsh settings/credentials/llm seams:
|
|
8
|
+
*
|
|
9
|
+
* profile → settings `llm-pi-ai.providers.<route>` (dsh-llm-pi-ai watches
|
|
10
|
+
* the section and registers the route without a restart)
|
|
11
|
+
* key → credentials store (`~/.dsh/.credentials.yaml`, 0600), named by
|
|
12
|
+
* the derived `<ROUTE>_API_KEY` env-style ref the profile's
|
|
13
|
+
* `apiKeyEnv` points at
|
|
14
|
+
*
|
|
15
|
+
* The module is React-free so `scripts/verify-provider-wizard.mjs` can drive
|
|
16
|
+
* it headless with a stubbed host and scripted answers.
|
|
17
|
+
*/
|
|
18
|
+
import { type AskUserQuestionAnswer, type AskUserQuestionRequest } from '@deepseek-ai/dsh-user-questions';
|
|
19
|
+
import type { LlmDiscoveredModel } from '@deepseek-ai/dsh-llm';
|
|
20
|
+
/** Route id rule shared with the dsh configuration surface (web Models page). */
|
|
21
|
+
export declare const PROVIDER_ROUTE_ID: RegExp;
|
|
22
|
+
/** Wire protocols dsh-llm-pi-ai can serve on a manually declared route. */
|
|
23
|
+
export declare const PROVIDER_PROTOCOLS: readonly ["openai-completions", "openai-responses", "anthropic-messages"];
|
|
24
|
+
/**
|
|
25
|
+
* Derive the credential ref for a route, matching the official web UI
|
|
26
|
+
* convention so TUI- and web-added providers resolve the same key.
|
|
27
|
+
*/
|
|
28
|
+
export declare function deriveKeyRef(route: string): string;
|
|
29
|
+
/** One catalog route the mounted adapters offer for activation. */
|
|
30
|
+
export interface CatalogProviderCandidate {
|
|
31
|
+
readonly provider: string;
|
|
32
|
+
readonly displayName: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Runtime capabilities the wizard needs, implemented by the channel over
|
|
36
|
+
* `ctx.settings` / `ctx.credentials` / `ctx.llm`. `undefined` from
|
|
37
|
+
* `channel.providerSetup()` means the bare cordis.yml start (no dsh-base
|
|
38
|
+
* services) and the command refuses to run.
|
|
39
|
+
*/
|
|
40
|
+
export interface ProviderSetupHost {
|
|
41
|
+
/** Catalog routes activatable via the `llm-pi-ai` settings section. */
|
|
42
|
+
listCatalogProviders(): readonly CatalogProviderCandidate[];
|
|
43
|
+
/** Whether a profile (any layer) already exists for the route. */
|
|
44
|
+
routeExists(route: string): boolean;
|
|
45
|
+
/** Interrogate a draft endpoint; the draft key is never persisted. */
|
|
46
|
+
discoverModels(request: {
|
|
47
|
+
provider?: string;
|
|
48
|
+
baseURL?: string;
|
|
49
|
+
api?: string;
|
|
50
|
+
apiKey?: string;
|
|
51
|
+
}): Promise<readonly LlmDiscoveredModel[]>;
|
|
52
|
+
/** Whether the process environment already provides this ref (shadow). */
|
|
53
|
+
envShadows(ref: string): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Read the currently stored value for rollback purposes; undefined when no
|
|
56
|
+
* credential exists under the ref. Only called when {@link envShadows} is
|
|
57
|
+
* false, so the value comes from a writable/seeded store, never the env.
|
|
58
|
+
*/
|
|
59
|
+
readCredential(ref: string): Promise<string | undefined>;
|
|
60
|
+
/** Persist the key under the ref; rejects when env-shadowed or invalid. */
|
|
61
|
+
writeCredential(ref: string, value: string): void | Promise<void>;
|
|
62
|
+
/** Best-effort rollback of a just-written credential. */
|
|
63
|
+
removeCredential(ref: string): void | Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Persist the provider profile under `llm-pi-ai.providers.<route>`;
|
|
66
|
+
* rejects when the adapter's validation deems it unserviceable.
|
|
67
|
+
*/
|
|
68
|
+
writeProfile(route: string, profile: Record<string, unknown>): Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
export interface ProviderWizardDeps {
|
|
71
|
+
readonly host: ProviderSetupHost;
|
|
72
|
+
readonly ask: (request: AskUserQuestionRequest, options?: {
|
|
73
|
+
redact?: boolean;
|
|
74
|
+
}) => Promise<AskUserQuestionAnswer>;
|
|
75
|
+
readonly notify: (text: string, options?: {
|
|
76
|
+
color?: 'error' | 'warning' | 'success';
|
|
77
|
+
timeoutMs?: number;
|
|
78
|
+
}) => void;
|
|
79
|
+
readonly pushLocal: (title: string, lines: readonly string[]) => void;
|
|
80
|
+
/** Live turn state; the model-switch question is skipped while working. */
|
|
81
|
+
readonly working: () => boolean;
|
|
82
|
+
readonly switchModel: (provider: string, model: string) => Promise<boolean>;
|
|
83
|
+
}
|
|
84
|
+
export type ProviderWizardOutcome = 'added' | 'cancelled' | 'failed';
|
|
85
|
+
/**
|
|
86
|
+
* Run the add-provider wizard. Resolves 'cancelled' when the user dismisses
|
|
87
|
+
* any question (Esc) — nothing has been written at that point by design:
|
|
88
|
+
* all asks complete before the first side effect.
|
|
89
|
+
*/
|
|
90
|
+
export declare function runProviderWizard(deps: ProviderWizardDeps): Promise<ProviderWizardOutcome>;
|
|
91
|
+
//# sourceMappingURL=providerWizard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providerWizard.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/providerWizard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAEL,KAAK,qBAAqB,EAE1B,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAA;AACxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAE9D,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,QAAoC,CAAA;AAElE,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,2EAIrB,CAAA;AAEV;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,mEAAmE;AACnE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAC7B;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,oBAAoB,IAAI,SAAS,wBAAwB,EAAE,CAAA;IAC3D,kEAAkE;IAClE,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;IACnC,sEAAsE;IACtE,cAAc,CAAC,OAAO,EAAE;QACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;QACjB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,MAAM,CAAC,EAAE,MAAM,CAAA;KAChB,GAAG,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAAA;IAC1C,0EAA0E;IAC1E,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;IAChC;;;;OAIG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IACxD,2EAA2E;IAC3E,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACjE,yDAAyD;IACzD,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnD;;;OAGG;IACH,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7E;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAA;IAChC,QAAQ,CAAC,GAAG,EAAE,CACZ,OAAO,EAAE,sBAAsB,EAC/B,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAC3B,OAAO,CAAC,qBAAqB,CAAC,CAAA;IACnC,QAAQ,CAAC,MAAM,EAAE,CACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KACtE,IAAI,CAAA;IACT,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAA;IACrE,2EAA2E;IAC3E,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAA;IAC/B,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CAC5E;AAED,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,WAAW,GAAG,QAAQ,CAAA;AAgDpE;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,qBAAqB,CAAC,CA4MhC"}
|