@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"childStderr.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/childStderr.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAsDH;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI,CA8BhF;AAED,0EAA0E;AAC1E,MAAM,WAAW,iBAAiB;IAChC,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAChG;AAED,MAAM,WAAW,0BAA0B;IACzC,qFAAqF;IACrF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,yFAAyF;IACzF,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,gCAAgC;IAChC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,iDAAiD;IACjD,OAAO,IAAI,IAAI,CAAA;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,0BAA+B,GACvC,mBAAmB,CA4CrB"}
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
* dependency tree does that.
|
|
27
27
|
*/
|
|
28
28
|
import childProcess from 'node:child_process';
|
|
29
|
-
import { t } from '
|
|
29
|
+
import { t } from '../i18n.js';
|
|
30
30
|
/** Strip ANSI escape sequences (CSI/OSC) so raw child output can't inject
|
|
31
31
|
* cursor moves or colors into the notification area. */
|
|
32
32
|
// eslint-disable-next-line no-control-regex -- intentional: matching terminal escape sequences
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Provider-neutral subcommand completion registry for terminal front doors. */
|
|
2
|
+
import { Context, Service } from '@deepseek-ai/cordis';
|
|
3
|
+
import type { CommandCompletionNode, LocalizedDescriptions } from '../commands.js';
|
|
4
|
+
export interface TuiCommandTreeProvider {
|
|
5
|
+
/** Root command name without `/`. Must match the command registry entry. */
|
|
6
|
+
root: string;
|
|
7
|
+
/** Optional provider-owned translations for the root command row. */
|
|
8
|
+
descriptions?: LocalizedDescriptions;
|
|
9
|
+
/** Children for the full canonical path, including `root` at index zero. */
|
|
10
|
+
children(canonicalPath: readonly string[]): readonly CommandCompletionNode[];
|
|
11
|
+
}
|
|
12
|
+
declare module '@deepseek-ai/cordis' {
|
|
13
|
+
interface Context {
|
|
14
|
+
tuiCommandTrees: TuiCommandTreeRuntime;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export declare const name = "dsh-tui-command-trees";
|
|
18
|
+
/** Small host-only registry; command execution remains owned by dsh-commands. */
|
|
19
|
+
export declare class TuiCommandTreeRuntime extends Service {
|
|
20
|
+
private readonly providers;
|
|
21
|
+
constructor(ctx: Context);
|
|
22
|
+
register(provider: TuiCommandTreeProvider): () => void;
|
|
23
|
+
children(canonicalPath: readonly string[]): readonly CommandCompletionNode[];
|
|
24
|
+
descriptions(root: string): LocalizedDescriptions | undefined;
|
|
25
|
+
}
|
|
26
|
+
export default TuiCommandTreeRuntime;
|
|
27
|
+
//# sourceMappingURL=command-trees.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-trees.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/command-trees.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAEhF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAElF,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAA;IACZ,qEAAqE;IACrE,YAAY,CAAC,EAAE,qBAAqB,CAAA;IACpC,4EAA4E;IAC5E,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,qBAAqB,EAAE,CAAA;CAC7E;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,OAAO;QACf,eAAe,EAAE,qBAAqB,CAAA;KACvC;CACF;AAED,eAAO,MAAM,IAAI,0BAA0B,CAAA;AAE3C,iFAAiF;AACjF,qBAAa,qBAAsB,SAAQ,OAAO;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA4C;gBAE1D,GAAG,EAAE,OAAO;IAIxB,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,GAAG,MAAM,IAAI;IAWtD,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,qBAAqB,EAAE;IAa5E,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS;CAG9D;AAED,eAAe,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** Provider-neutral subcommand completion registry for terminal front doors. */
|
|
2
|
+
import { Service } from '@deepseek-ai/cordis';
|
|
3
|
+
export const name = 'dsh-tui-command-trees';
|
|
4
|
+
/** Small host-only registry; command execution remains owned by dsh-commands. */
|
|
5
|
+
export class TuiCommandTreeRuntime extends Service {
|
|
6
|
+
providers = new Map();
|
|
7
|
+
constructor(ctx) {
|
|
8
|
+
super(ctx, 'tuiCommandTrees');
|
|
9
|
+
}
|
|
10
|
+
register(provider) {
|
|
11
|
+
const root = provider.root.trim().toLowerCase();
|
|
12
|
+
if (!/^[a-z][a-z0-9_-]*$/u.test(root))
|
|
13
|
+
throw new TypeError(`invalid TUI command-tree root: ${provider.root}`);
|
|
14
|
+
if (this.providers.has(root))
|
|
15
|
+
throw new Error(`TUI command-tree root "${root}" is already registered`);
|
|
16
|
+
const normalized = { ...provider, root };
|
|
17
|
+
this.providers.set(root, normalized);
|
|
18
|
+
return () => {
|
|
19
|
+
if (this.providers.get(root) === normalized)
|
|
20
|
+
this.providers.delete(root);
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
children(canonicalPath) {
|
|
24
|
+
const root = canonicalPath[0]?.toLowerCase();
|
|
25
|
+
if (root === undefined)
|
|
26
|
+
return [];
|
|
27
|
+
const provider = this.providers.get(root);
|
|
28
|
+
if (provider === undefined)
|
|
29
|
+
return [];
|
|
30
|
+
try {
|
|
31
|
+
return provider.children(canonicalPath);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Completion is optional UI metadata and must never block execution.
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
descriptions(root) {
|
|
39
|
+
return this.providers.get(root.trim().toLowerCase())?.descriptions;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export default TuiCommandTreeRuntime;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compat boundary — every inelegant patch aimed at the harness core lives
|
|
3
|
+
* here, behind one import seam, so the render/interaction code stays clean.
|
|
4
|
+
*
|
|
5
|
+
* House rules for modules in this directory:
|
|
6
|
+
* - Each patch carries its own capability probe and self-disables or
|
|
7
|
+
* degrades to pre-patch behavior when upstream absorbs the quirk.
|
|
8
|
+
* - A patch must never throw into the caller: failure means "act as if the
|
|
9
|
+
* patch did not exist".
|
|
10
|
+
* - A patch states plainly which upstream change would retire it.
|
|
11
|
+
*
|
|
12
|
+
* Current residents:
|
|
13
|
+
* - sessionLog: tolerant title reads plus offline rename/delete helpers for
|
|
14
|
+
* persisted sessions that are not currently owned by a live Agent, and
|
|
15
|
+
* the resume-seam registration of vouched-for legacy event types into
|
|
16
|
+
* every reachable KNOWN_SESSION_EVENT_TYPES copy — retiring the day
|
|
17
|
+
* upstream's shared catalog adopts the types or ships a real
|
|
18
|
+
* registration API (issue #153).
|
|
19
|
+
* @module @deepseek-harness-tui/dsh-tui/compat
|
|
20
|
+
*/
|
|
21
|
+
export { appendSessionTitle, deleteSessionLog, ensureLegacySessionEventTypes, LEGACY_SESSION_EVENT_TYPES, readSessionTitleFromLog, sessionsRoots, } from './sessionLog.js';
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/compat/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,6BAA6B,EAC7B,0BAA0B,EAC1B,uBAAuB,EACvB,aAAa,GACd,MAAM,iBAAiB,CAAA"}
|
|
@@ -10,9 +10,12 @@
|
|
|
10
10
|
* - A patch states plainly which upstream change would retire it.
|
|
11
11
|
*
|
|
12
12
|
* Current residents:
|
|
13
|
-
* - sessionLog:
|
|
14
|
-
*
|
|
15
|
-
*
|
|
13
|
+
* - sessionLog: tolerant title reads plus offline rename/delete helpers for
|
|
14
|
+
* persisted sessions that are not currently owned by a live Agent, and
|
|
15
|
+
* the resume-seam registration of vouched-for legacy event types into
|
|
16
|
+
* every reachable KNOWN_SESSION_EVENT_TYPES copy — retiring the day
|
|
17
|
+
* upstream's shared catalog adopts the types or ships a real
|
|
18
|
+
* registration API (issue #153).
|
|
16
19
|
* @module @deepseek-harness-tui/dsh-tui/compat
|
|
17
20
|
*/
|
|
18
|
-
export {
|
|
21
|
+
export { appendSessionTitle, deleteSessionLog, ensureLegacySessionEventTypes, LEGACY_SESSION_EVENT_TYPES, readSessionTitleFromLog, sessionsRoots, } from './sessionLog.js';
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Legacy third-party session-event types the TUI vouches for as ephemeral
|
|
3
|
+
* UI frames — safe for the strict read path to accept and skip. Exported
|
|
4
|
+
* for the regression verifier; grow it only with proof the type was always
|
|
5
|
+
* inert (never load-bearing for session reconstruction).
|
|
6
|
+
*/
|
|
7
|
+
export declare const LEGACY_SESSION_EVENT_TYPES: readonly string[];
|
|
8
|
+
/**
|
|
9
|
+
* Session-log storage roots, in priority order, mirroring the persistence
|
|
10
|
+
* backend's `root` resolution: cordis.patch.yml sets `DSH_TUI_SESSION_ROOT ?? dshHomePath(
|
|
11
|
+
* 'sessions')` where dshHomePath is `$DSH_HOME ?? ~/.dsh`; the unpatched
|
|
12
|
+
* cordis.yml base falls back to ~/.dsh-tui/sessions, kept here as the legacy
|
|
13
|
+
* last resort. Every candidate is scanned — the first hit wins, so an
|
|
14
|
+
* explicit DSH_TUI_SESSION_ROOT always outranks the defaults.
|
|
15
|
+
*/
|
|
16
|
+
export declare function sessionsRoots(): string[];
|
|
17
|
+
/**
|
|
18
|
+
* Register every {@link LEGACY_SESSION_EVENT_TYPES} type as known in EVERY
|
|
19
|
+
* reachable KNOWN_SESSION_EVENT_TYPES copy, ahead of the strict read path
|
|
20
|
+
* (`agents.resume` seed validation, `persistence.load`). Idempotent; never
|
|
21
|
+
* throws.
|
|
22
|
+
*
|
|
23
|
+
* Why a walk instead of a single import: a runtime can load dsh-session
|
|
24
|
+
* more than once (CLI tree vs profile tree, version overlap during
|
|
25
|
+
* upgrades, pnpm peer-context splits), and the strict validator — which
|
|
26
|
+
* lives in the dsh-session-persistence package — consults only ITS OWN
|
|
27
|
+
* tree's copy. Registering through one import leaves the other trees'
|
|
28
|
+
* copies untouched. So from EACH base anchor (this module = the dsh-tui
|
|
29
|
+
* tree, the process entry point = the launcher/CLI tree) the walk
|
|
30
|
+
* registers the tree's own dsh-session AND steps one edge further:
|
|
31
|
+
* resolve the validator package from that same tree, then register the
|
|
32
|
+
* dsh-session copy the validator's entry resolves. A branch that cannot
|
|
33
|
+
* be resolved simply is not there; resolved module paths are deduped.
|
|
34
|
+
*/
|
|
35
|
+
export declare function ensureLegacySessionEventTypes(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Read a session's display title from its persisted log, tolerantly.
|
|
38
|
+
*
|
|
39
|
+
* Why not `persistence.load()`: the backend validates every event against
|
|
40
|
+
* KNOWN_SESSION_EVENT_TYPES and throws the WHOLE load when a third-party
|
|
41
|
+
* plugin wrote an unmarked unknown type. A picker label is
|
|
42
|
+
* read-only UI state: decoding frames directly here keeps titles working
|
|
43
|
+
* for logs the strict path refuses, now and for future plugin event types.
|
|
44
|
+
*
|
|
45
|
+
* Title precedence: the LAST `session/title` event wins (a /rename append
|
|
46
|
+
* overrides the first-prompt auto title), falling back to the first user
|
|
47
|
+
* message text. `hasUserMessage` drives the picker's launch-artifact filter.
|
|
48
|
+
* @param sessionId - Session whose log should be read.
|
|
49
|
+
* @returns The title info, or undefined when the log is absent/undecodable.
|
|
50
|
+
*/
|
|
51
|
+
export declare function readSessionTitleFromLog(sessionId: string): {
|
|
52
|
+
title?: string;
|
|
53
|
+
hasUserMessage: boolean;
|
|
54
|
+
} | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Append a `session/title` event to a persisted session's log — the
|
|
57
|
+
* `/resume` picker rename for a NON-LIVE session (the live one goes through
|
|
58
|
+
* `session.append` in the channel). The backend flushes by appending zstd
|
|
59
|
+
* frames, so the new event lands as one more frame: existing bytes stay
|
|
60
|
+
* untouched (the frame-0 header invariant holds), and `last title wins` in
|
|
61
|
+
* {@link readSessionTitleFromLog} surfaces the new name. The seq continues
|
|
62
|
+
* the log's contiguity contract (seq = event count) by taking maxSeq + 1.
|
|
63
|
+
* The frame is APPEND-ONLY (O_APPEND), matching the backend's own flush
|
|
64
|
+
* discipline: this store is shared with dsh web (#24), and a
|
|
65
|
+
* read-concat-rewrite (tmp + rename) would silently drop a frame another
|
|
66
|
+
* writer lands between our read and replace. A single append never rewrites
|
|
67
|
+
* existing bytes, so concurrent frames all survive; the worst remaining
|
|
68
|
+
* race is a duplicate seq when the maxSeq read above passes another
|
|
69
|
+
* appender — benign next to lost frames, since last-title-wins keeps the
|
|
70
|
+
* rename semantics. Never throws.
|
|
71
|
+
* @param sessionId - Session to rename.
|
|
72
|
+
* @param title - New display title (already trimmed by the caller).
|
|
73
|
+
* @returns 'appended', or 'unavailable' when the log is absent/undecodable.
|
|
74
|
+
*/
|
|
75
|
+
export declare function appendSessionTitle(sessionId: string, title: string): 'appended' | 'unavailable';
|
|
76
|
+
/**
|
|
77
|
+
* Delete a persisted session's log directory (`<root>/<workspace>/<id>/`),
|
|
78
|
+
* the `/resume` picker delete. The directory holds only session.jsonl.zstd
|
|
79
|
+
* today; removing it whole keeps future sidecar files from orphaning. The
|
|
80
|
+
* backend's list() materializes entries from these logs, so the session
|
|
81
|
+
* drops out of the picker on the next refresh. Never throws.
|
|
82
|
+
* @param sessionId - Session to delete (must not be the live session).
|
|
83
|
+
* @returns 'deleted', or 'unavailable' when the log is absent.
|
|
84
|
+
*/
|
|
85
|
+
export declare function deleteSessionLog(sessionId: string): 'deleted' | 'unavailable';
|
|
86
|
+
//# sourceMappingURL=sessionLog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessionLog.d.ts","sourceRoot":"","sources":["../../../../src/dsh-adapter/compat/sessionLog.ts"],"names":[],"mappings":"AAqDA;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,EAAE,SAAS,MAAM,EAAwB,CAAA;AAKhF;;;;;;;GAOG;AACH,wBAAgB,aAAa,IAAI,MAAM,EAAE,CASxC;AAkED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,6BAA6B,IAAI,IAAI,CAkCpD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,GAChB;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAyBzD;AAyBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,aAAa,CAwB/F;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAwB7E"}
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-log compatibility helpers.
|
|
3
|
+
*
|
|
4
|
+
* Title lookup tolerates event types unknown to the current harness. Offline
|
|
5
|
+
* rename and delete support the `/resume` picker when no live Agent owns the
|
|
6
|
+
* selected persisted session. The resume seam registers vouched-for legacy
|
|
7
|
+
* event types into every reachable KNOWN_SESSION_EVENT_TYPES copy so the
|
|
8
|
+
* strict read path stops rejecting whole sessions over them (issue #153).
|
|
9
|
+
*
|
|
10
|
+
* Registration background: plugins like dsh-working-activity (< the publish
|
|
11
|
+
* cut) appended `activity/status` through `session.append`, but rc.6's
|
|
12
|
+
* append exposes no `ignorable` flag and the type is absent from
|
|
13
|
+
* KNOWN_SESSION_EVENT_TYPES — so resume's seed validation rejects the WHOLE
|
|
14
|
+
* session ("unknown to this harness and not marked ignorable"). Upstream's
|
|
15
|
+
* catalog header defers a registration surface "until such a consumer
|
|
16
|
+
* exists"; the working-activity plugin became that consumer at #119 and
|
|
17
|
+
* registers its type at load. Logs written BEFORE that cut, resumed in a
|
|
18
|
+
* process where the plugin's registration never ran (plugin unmounted, or
|
|
19
|
+
* a bare cordis.yml), still hit the rejection — this module is the consumer
|
|
20
|
+
* for exactly that residue.
|
|
21
|
+
*
|
|
22
|
+
* Why registration and NOT rewriting the log to mark events `ignorable`
|
|
23
|
+
* (the #107 approach, restored then replaced after review): the store is
|
|
24
|
+
* shared with dsh web (#24) and possibly a second TUI instance (#153), and
|
|
25
|
+
* a whole-file tmp+rename swap (a) loses frames an already-open appender
|
|
26
|
+
* lands on the replaced inode, (b) drops the backend's 0600 artifact mode,
|
|
27
|
+
* (c) re-encodes frames without the writer's checksum flag, and (d) dies on
|
|
28
|
+
* torn tails the backend itself can recover. Registration touches nothing
|
|
29
|
+
* on disk and degrades to exactly the pre-patch behavior when no copy
|
|
30
|
+
* resolves.
|
|
31
|
+
*
|
|
32
|
+
* Whitelist discipline: ONLY `activity/status` — the type the plugin
|
|
33
|
+
* provably wrote as ephemeral UI frames. Anything else unknown stays
|
|
34
|
+
* unknown: upstream's fail-closed ("likely written by a newer harness") is
|
|
35
|
+
* a feature — silently skipping a REQUIRED future event would reconstruct
|
|
36
|
+
* a wrong session. Retires the day upstream's shared catalog adopts the
|
|
37
|
+
* type or ships a real registration API (the add() calls become no-ops).
|
|
38
|
+
*
|
|
39
|
+
* @module @deepseek-harness-tui/dsh-tui/compat/sessionLog
|
|
40
|
+
*/
|
|
41
|
+
import { createRequire } from 'node:module';
|
|
42
|
+
import { appendFileSync, existsSync, readdirSync, readFileSync, realpathSync, rmSync, } from 'node:fs';
|
|
43
|
+
import { dirname, join, sep } from 'node:path';
|
|
44
|
+
import { zstdCompressSync, zstdDecompressSync } from 'node:zlib';
|
|
45
|
+
import { homeDir } from '../../utils/paths.js';
|
|
46
|
+
/**
|
|
47
|
+
* Legacy third-party session-event types the TUI vouches for as ephemeral
|
|
48
|
+
* UI frames — safe for the strict read path to accept and skip. Exported
|
|
49
|
+
* for the regression verifier; grow it only with proof the type was always
|
|
50
|
+
* inert (never load-bearing for session reconstruction).
|
|
51
|
+
*/
|
|
52
|
+
export const LEGACY_SESSION_EVENT_TYPES = ['activity/status'];
|
|
53
|
+
/** Zstd frame magic number, little-endian (0xFD2FB528). */
|
|
54
|
+
const ZSTD_MAGIC = 0xfd2fb528;
|
|
55
|
+
/**
|
|
56
|
+
* Session-log storage roots, in priority order, mirroring the persistence
|
|
57
|
+
* backend's `root` resolution: cordis.patch.yml sets `DSH_TUI_SESSION_ROOT ?? dshHomePath(
|
|
58
|
+
* 'sessions')` where dshHomePath is `$DSH_HOME ?? ~/.dsh`; the unpatched
|
|
59
|
+
* cordis.yml base falls back to ~/.dsh-tui/sessions, kept here as the legacy
|
|
60
|
+
* last resort. Every candidate is scanned — the first hit wins, so an
|
|
61
|
+
* explicit DSH_TUI_SESSION_ROOT always outranks the defaults.
|
|
62
|
+
*/
|
|
63
|
+
export function sessionsRoots() {
|
|
64
|
+
const home = homeDir();
|
|
65
|
+
const roots = [];
|
|
66
|
+
const override = process.env.DSH_TUI_SESSION_ROOT;
|
|
67
|
+
if (override !== undefined && override.trim().length > 0)
|
|
68
|
+
roots.push(override);
|
|
69
|
+
const dshHome = process.env.DSH_HOME;
|
|
70
|
+
roots.push(join(dshHome !== undefined && dshHome.trim().length > 0 ? dshHome : join(home, '.dsh'), 'sessions'));
|
|
71
|
+
roots.push(join(home, '.dsh-tui', 'sessions'));
|
|
72
|
+
return [...new Set(roots)];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Session ids reach path.join() below from picker/channel callers, and
|
|
76
|
+
* deleteSessionLog recursively removes the resolved parent directory — so
|
|
77
|
+
* an id must be a single safe path segment. Real ids are UUIDs or
|
|
78
|
+
* `session-<uuid>`; anything with separators, dots, or shell-y characters
|
|
79
|
+
* is rejected outright (treated as "no such session").
|
|
80
|
+
*/
|
|
81
|
+
function isSafeSessionId(sessionId) {
|
|
82
|
+
return /^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(sessionId);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Locate a session's log by scanning workspace directories for the session
|
|
86
|
+
* id — deliberately NOT replicating the persistence plugin's workspace-key
|
|
87
|
+
* sanitization, so the helpers survive upstream key-scheme changes.
|
|
88
|
+
* @param sessionId - Session id (directory name under each workspace dir).
|
|
89
|
+
* @returns Absolute path of session.jsonl.zstd, or undefined when absent.
|
|
90
|
+
*/
|
|
91
|
+
function findSessionLogFile(sessionId) {
|
|
92
|
+
if (!isSafeSessionId(sessionId))
|
|
93
|
+
return undefined;
|
|
94
|
+
for (const root of sessionsRoots()) {
|
|
95
|
+
let workspaces;
|
|
96
|
+
try {
|
|
97
|
+
workspaces = readdirSync(root);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
for (const ws of workspaces) {
|
|
103
|
+
const candidate = join(root, ws, sessionId, 'session.jsonl.zstd');
|
|
104
|
+
if (existsSync(candidate))
|
|
105
|
+
return candidate;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Decode a (possibly multi-frame) zstd jsonl log. Frames are split by magic
|
|
112
|
+
* scan; any frame failing to decode or any line failing to parse throws, so
|
|
113
|
+
* callers abort instead of acting on a log they did not fully understand.
|
|
114
|
+
* @param buf - Raw file bytes.
|
|
115
|
+
* @returns Parsed event envelopes, in log order.
|
|
116
|
+
*/
|
|
117
|
+
function decodeEvents(buf) {
|
|
118
|
+
const offsets = [];
|
|
119
|
+
for (let i = 0; i + 4 <= buf.length; i++) {
|
|
120
|
+
if (buf.readUInt32LE(i) === ZSTD_MAGIC)
|
|
121
|
+
offsets.push(i);
|
|
122
|
+
}
|
|
123
|
+
if (offsets.length === 0)
|
|
124
|
+
throw new Error('no zstd frame found');
|
|
125
|
+
return offsets.flatMap((start, i) => {
|
|
126
|
+
const end = i + 1 < offsets.length ? offsets[i + 1] : buf.length;
|
|
127
|
+
const text = zstdDecompressSync(buf.subarray(start, end)).toString('utf8');
|
|
128
|
+
return text
|
|
129
|
+
.split('\n')
|
|
130
|
+
.filter((line) => line.length > 0)
|
|
131
|
+
.map((line) => {
|
|
132
|
+
const parsed = JSON.parse(line);
|
|
133
|
+
if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
134
|
+
throw new Error('session log line is not an event envelope');
|
|
135
|
+
}
|
|
136
|
+
return parsed;
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Register every {@link LEGACY_SESSION_EVENT_TYPES} type as known in EVERY
|
|
142
|
+
* reachable KNOWN_SESSION_EVENT_TYPES copy, ahead of the strict read path
|
|
143
|
+
* (`agents.resume` seed validation, `persistence.load`). Idempotent; never
|
|
144
|
+
* throws.
|
|
145
|
+
*
|
|
146
|
+
* Why a walk instead of a single import: a runtime can load dsh-session
|
|
147
|
+
* more than once (CLI tree vs profile tree, version overlap during
|
|
148
|
+
* upgrades, pnpm peer-context splits), and the strict validator — which
|
|
149
|
+
* lives in the dsh-session-persistence package — consults only ITS OWN
|
|
150
|
+
* tree's copy. Registering through one import leaves the other trees'
|
|
151
|
+
* copies untouched. So from EACH base anchor (this module = the dsh-tui
|
|
152
|
+
* tree, the process entry point = the launcher/CLI tree) the walk
|
|
153
|
+
* registers the tree's own dsh-session AND steps one edge further:
|
|
154
|
+
* resolve the validator package from that same tree, then register the
|
|
155
|
+
* dsh-session copy the validator's entry resolves. A branch that cannot
|
|
156
|
+
* be resolved simply is not there; resolved module paths are deduped.
|
|
157
|
+
*/
|
|
158
|
+
export function ensureLegacySessionEventTypes() {
|
|
159
|
+
const roots = [import.meta.url, process.argv[1]].filter((anchor) => typeof anchor === 'string' && anchor.length > 0);
|
|
160
|
+
const visitedAnchors = new Set();
|
|
161
|
+
const registeredCopies = new Set();
|
|
162
|
+
const walk = (anchor) => {
|
|
163
|
+
if (visitedAnchors.has(anchor))
|
|
164
|
+
return;
|
|
165
|
+
visitedAnchors.add(anchor);
|
|
166
|
+
let req;
|
|
167
|
+
try {
|
|
168
|
+
req = createRequire(anchor);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const copy = req.resolve('@deepseek-ai/dsh-session');
|
|
175
|
+
if (!registeredCopies.has(copy)) {
|
|
176
|
+
registeredCopies.add(copy);
|
|
177
|
+
const mod = req(copy);
|
|
178
|
+
for (const type of LEGACY_SESSION_EVENT_TYPES) {
|
|
179
|
+
mod.KNOWN_SESSION_EVENT_TYPES?.add(type);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// No resolvable dsh-session copy from this anchor — nothing here.
|
|
185
|
+
}
|
|
186
|
+
try {
|
|
187
|
+
walk(req.resolve('@deepseek-ai/dsh-session-persistence'));
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
// Validator package not reachable from this tree — nothing to cover.
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
for (const root of roots)
|
|
194
|
+
walk(root);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Read a session's display title from its persisted log, tolerantly.
|
|
198
|
+
*
|
|
199
|
+
* Why not `persistence.load()`: the backend validates every event against
|
|
200
|
+
* KNOWN_SESSION_EVENT_TYPES and throws the WHOLE load when a third-party
|
|
201
|
+
* plugin wrote an unmarked unknown type. A picker label is
|
|
202
|
+
* read-only UI state: decoding frames directly here keeps titles working
|
|
203
|
+
* for logs the strict path refuses, now and for future plugin event types.
|
|
204
|
+
*
|
|
205
|
+
* Title precedence: the LAST `session/title` event wins (a /rename append
|
|
206
|
+
* overrides the first-prompt auto title), falling back to the first user
|
|
207
|
+
* message text. `hasUserMessage` drives the picker's launch-artifact filter.
|
|
208
|
+
* @param sessionId - Session whose log should be read.
|
|
209
|
+
* @returns The title info, or undefined when the log is absent/undecodable.
|
|
210
|
+
*/
|
|
211
|
+
export function readSessionTitleFromLog(sessionId) {
|
|
212
|
+
try {
|
|
213
|
+
const file = findSessionLogFile(sessionId);
|
|
214
|
+
if (file === undefined)
|
|
215
|
+
return undefined;
|
|
216
|
+
const events = decodeEvents(readFileSync(file));
|
|
217
|
+
let titled;
|
|
218
|
+
let firstUser;
|
|
219
|
+
let hasUserMessage = false;
|
|
220
|
+
for (const event of events) {
|
|
221
|
+
if (event['type'] === 'session/title') {
|
|
222
|
+
const title = event['data']?.['title'];
|
|
223
|
+
if (typeof title === 'string' && title.trim().length > 0)
|
|
224
|
+
titled = title;
|
|
225
|
+
}
|
|
226
|
+
else if (event['type'] === 'user/message') {
|
|
227
|
+
hasUserMessage = true;
|
|
228
|
+
if (firstUser === undefined) {
|
|
229
|
+
firstUser = firstTextOfContent(event['data']?.['content']);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return { title: titled ?? firstUser, hasUserMessage };
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
return undefined;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Extract the first text block from a user/message `content` payload.
|
|
241
|
+
* Content is normally a block array; a bare string is accepted defensively.
|
|
242
|
+
* @param content - The event's content field.
|
|
243
|
+
* @returns The trimmed text, or undefined when no text block exists.
|
|
244
|
+
*/
|
|
245
|
+
function firstTextOfContent(content) {
|
|
246
|
+
if (typeof content === 'string')
|
|
247
|
+
return content.trim() || undefined;
|
|
248
|
+
if (!Array.isArray(content))
|
|
249
|
+
return undefined;
|
|
250
|
+
for (const block of content) {
|
|
251
|
+
if (block !== null &&
|
|
252
|
+
typeof block === 'object' &&
|
|
253
|
+
block.type === 'text' &&
|
|
254
|
+
typeof block.text === 'string') {
|
|
255
|
+
const text = (block.text).trim();
|
|
256
|
+
if (text.length > 0)
|
|
257
|
+
return text;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return undefined;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Append a `session/title` event to a persisted session's log — the
|
|
264
|
+
* `/resume` picker rename for a NON-LIVE session (the live one goes through
|
|
265
|
+
* `session.append` in the channel). The backend flushes by appending zstd
|
|
266
|
+
* frames, so the new event lands as one more frame: existing bytes stay
|
|
267
|
+
* untouched (the frame-0 header invariant holds), and `last title wins` in
|
|
268
|
+
* {@link readSessionTitleFromLog} surfaces the new name. The seq continues
|
|
269
|
+
* the log's contiguity contract (seq = event count) by taking maxSeq + 1.
|
|
270
|
+
* The frame is APPEND-ONLY (O_APPEND), matching the backend's own flush
|
|
271
|
+
* discipline: this store is shared with dsh web (#24), and a
|
|
272
|
+
* read-concat-rewrite (tmp + rename) would silently drop a frame another
|
|
273
|
+
* writer lands between our read and replace. A single append never rewrites
|
|
274
|
+
* existing bytes, so concurrent frames all survive; the worst remaining
|
|
275
|
+
* race is a duplicate seq when the maxSeq read above passes another
|
|
276
|
+
* appender — benign next to lost frames, since last-title-wins keeps the
|
|
277
|
+
* rename semantics. Never throws.
|
|
278
|
+
* @param sessionId - Session to rename.
|
|
279
|
+
* @param title - New display title (already trimmed by the caller).
|
|
280
|
+
* @returns 'appended', or 'unavailable' when the log is absent/undecodable.
|
|
281
|
+
*/
|
|
282
|
+
export function appendSessionTitle(sessionId, title) {
|
|
283
|
+
try {
|
|
284
|
+
const file = findSessionLogFile(sessionId);
|
|
285
|
+
if (file === undefined)
|
|
286
|
+
return 'unavailable';
|
|
287
|
+
const events = decodeEvents(readFileSync(file));
|
|
288
|
+
let maxSeq = -1;
|
|
289
|
+
for (const event of events) {
|
|
290
|
+
const seq = event['seq'];
|
|
291
|
+
if (typeof seq === 'number' && seq > maxSeq)
|
|
292
|
+
maxSeq = seq;
|
|
293
|
+
}
|
|
294
|
+
// Same envelope shape as a manual /rename append ({ title } only); the
|
|
295
|
+
// seed validator asks only for type/seq/time/data on non-message types.
|
|
296
|
+
const event = {
|
|
297
|
+
type: 'session/title',
|
|
298
|
+
seq: maxSeq + 1,
|
|
299
|
+
time: Date.now(),
|
|
300
|
+
data: { title },
|
|
301
|
+
};
|
|
302
|
+
const frame = zstdCompressSync(Buffer.from(JSON.stringify(event) + '\n', 'utf8'));
|
|
303
|
+
appendFileSync(file, frame);
|
|
304
|
+
return 'appended';
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
return 'unavailable';
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Delete a persisted session's log directory (`<root>/<workspace>/<id>/`),
|
|
312
|
+
* the `/resume` picker delete. The directory holds only session.jsonl.zstd
|
|
313
|
+
* today; removing it whole keeps future sidecar files from orphaning. The
|
|
314
|
+
* backend's list() materializes entries from these logs, so the session
|
|
315
|
+
* drops out of the picker on the next refresh. Never throws.
|
|
316
|
+
* @param sessionId - Session to delete (must not be the live session).
|
|
317
|
+
* @returns 'deleted', or 'unavailable' when the log is absent.
|
|
318
|
+
*/
|
|
319
|
+
export function deleteSessionLog(sessionId) {
|
|
320
|
+
try {
|
|
321
|
+
const file = findSessionLogFile(sessionId);
|
|
322
|
+
if (file === undefined)
|
|
323
|
+
return 'unavailable';
|
|
324
|
+
const dir = dirname(file);
|
|
325
|
+
// Containment must hold after resolving symlinks, not just lexically:
|
|
326
|
+
// a symlinked workspace directory (<root>/<ws -> /outside>/<id>) would
|
|
327
|
+
// steer the recursive rm outside the sessions root even with a clean
|
|
328
|
+
// whitelisted id. realpath BOTH sides — the root itself may legitimately
|
|
329
|
+
// live behind a symlink (macOS /tmp -> /private/tmp).
|
|
330
|
+
const realDir = realpathSync(dir);
|
|
331
|
+
const contained = sessionsRoots().some(root => {
|
|
332
|
+
try {
|
|
333
|
+
return realDir.startsWith(realpathSync(root) + sep);
|
|
334
|
+
}
|
|
335
|
+
catch {
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
if (!contained)
|
|
340
|
+
return 'unavailable';
|
|
341
|
+
rmSync(dir, { recursive: true, force: true });
|
|
342
|
+
return 'deleted';
|
|
343
|
+
}
|
|
344
|
+
catch {
|
|
345
|
+
return 'unavailable';
|
|
346
|
+
}
|
|
347
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export declare const UPSTREAM_VALIDATED_VERSION = "0.1.0-rc.6";
|
|
2
|
+
/**
|
|
3
|
+
* Framework packages version on their own lines; the contract validates
|
|
4
|
+
* their MAJOR (breaking surface), not the harness rc number.
|
|
5
|
+
*/
|
|
6
|
+
export declare const UPSTREAM_FRAMEWORK_MAJORS: Record<string, number>;
|
|
7
|
+
/** Official packages the adapter consumes at runtime or as types. */
|
|
8
|
+
export declare const UPSTREAM_BLESSED_PACKAGES: readonly ["@deepseek-ai/cordis", "@deepseek-ai/schemastery", "@deepseek-ai/dsh-invariants", "@deepseek-ai/dsh-agent", "@deepseek-ai/dsh-agent-instructions", "@deepseek-ai/dsh-agent-presets", "@deepseek-ai/dsh-commands", "@deepseek-ai/dsh-cordis-host-runner", "@deepseek-ai/dsh-llm", "@deepseek-ai/dsh-persona", "@deepseek-ai/dsh-session", "@deepseek-ai/dsh-skill", "@deepseek-ai/dsh-storage", "@deepseek-ai/dsh-storage-domain", "@deepseek-ai/dsh-storage-json", "@deepseek-ai/dsh-workspace", "@deepseek-ai/dsh-system-prompt", "@deepseek-ai/dsh-terminal", "@deepseek-ai/dsh-terminal-bash", "@deepseek-ai/dsh-tool-ask-user", "@deepseek-ai/dsh-tool-bash-persistent", "@deepseek-ai/dsh-tool-cordis", "@deepseek-ai/dsh-user-approval", "@deepseek-ai/dsh-user-questions"];
|
|
9
|
+
export interface UpstreamDriftEntry {
|
|
10
|
+
package: string;
|
|
11
|
+
installed: string | undefined;
|
|
12
|
+
validated: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function installedUpstreamVersions(): Record<string, string | undefined>;
|
|
15
|
+
/**
|
|
16
|
+
* Report every blessed package whose installed version is NOT the validated
|
|
17
|
+
* release line. Empty array = the running install matches the contract.
|
|
18
|
+
*/
|
|
19
|
+
export declare function upstreamDrift(): UpstreamDriftEntry[];
|
|
20
|
+
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../src/dsh-adapter/contract.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,0BAA0B,eAAe,CAAA;AAEtD;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAG5D,CAAA;AAED,qEAAqE;AACrE,eAAO,MAAM,yBAAyB,6vBAyB5B,CAAA;AAEV,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,SAAS,EAAE,MAAM,CAAA;CAClB;AAWD,wBAAgB,yBAAyB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAgB9E;AAOD;;;GAGG;AACH,wBAAgB,aAAa,IAAI,kBAAkB,EAAE,CAsBpD"}
|