@deepseek-harness-tui/dsh-tui 0.15.0 → 0.16.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 +92 -5
- package/guide/dsh-tui-guide/codex-backend.en.md +13 -3
- package/guide/dsh-tui-guide/codex-backend.md +9 -2
- package/guide/dsh-tui-guide/configuration.en.md +39 -2
- package/guide/dsh-tui-guide/configuration.md +34 -2
- package/guide/dsh-tui-guide/getting-started.en.md +15 -0
- package/guide/dsh-tui-guide/getting-started.md +15 -0
- package/guide/dsh-tui-guide/interaction.en.md +8 -1
- package/guide/dsh-tui-guide/interaction.md +8 -1
- package/guide/dsh-tui-guide/plugins.en.md +66 -5
- package/guide/dsh-tui-guide/plugins.md +37 -3
- package/guide/dsh-tui-guide/user-guide.en.md +3 -2
- package/guide/dsh-tui-guide/user-guide.md +3 -2
- package/lib/settings.json +1 -1
- package/lib/types/adapter/channel/projection.d.ts.map +1 -1
- package/lib/types/adapter/channel/projection.js +1 -0
- package/lib/types/adapter/channel/ui-policy.d.ts +1 -1
- package/lib/types/adapter/channel/ui-policy.d.ts.map +1 -1
- package/lib/types/adapter/channel/ui-policy.js +1 -0
- package/lib/types/adapter/ports/channel-catalog.d.ts +5 -1
- package/lib/types/adapter/ports/channel-catalog.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-settings.d.ts +5 -3
- package/lib/types/adapter/ports/channel-settings.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-ui.d.ts +7 -1
- package/lib/types/adapter/ports/channel-ui.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel-view.d.ts +47 -0
- package/lib/types/adapter/ports/channel-view.d.ts.map +1 -1
- package/lib/types/adapter/ports/channel.d.ts +2 -0
- package/lib/types/adapter/ports/channel.d.ts.map +1 -1
- package/lib/types/agent/events.d.ts +3 -2
- package/lib/types/agent/events.d.ts.map +1 -1
- package/lib/types/backends/codex/contract.d.ts +3 -0
- package/lib/types/backends/codex/contract.d.ts.map +1 -1
- package/lib/types/backends/codex/contract.js +3 -0
- package/lib/types/backends/codex/session/async-questions.d.ts +17 -0
- package/lib/types/backends/codex/session/async-questions.d.ts.map +1 -0
- package/lib/types/backends/codex/session/async-questions.js +89 -0
- package/lib/types/backends/codex/session/session.d.ts.map +1 -1
- package/lib/types/backends/codex/session/session.js +35 -9
- package/lib/types/backends/codex/text.d.ts +3 -3
- package/lib/types/backends/codex/text.js +1 -1
- package/lib/types/backends/codex/translate/items.d.ts.map +1 -1
- package/lib/types/backends/codex/translate/items.js +3 -1
- package/lib/types/backends/codex/translate/question-reply.d.ts +11 -0
- package/lib/types/backends/codex/translate/question-reply.d.ts.map +1 -0
- package/lib/types/backends/codex/translate/question-reply.js +53 -0
- package/lib/types/channel/projection.d.ts.map +1 -1
- package/lib/types/channel/projection.js +10 -0
- package/lib/types/commands.d.ts +10 -0
- package/lib/types/commands.d.ts.map +1 -1
- package/lib/types/commands.js +11 -2
- package/lib/types/components/CommandSuggestions.d.ts.map +1 -1
- package/lib/types/components/CommandSuggestions.js +4 -1
- package/lib/types/components/LogoV2.d.ts +4 -1
- package/lib/types/components/LogoV2.d.ts.map +1 -1
- package/lib/types/components/LogoV2.js +5 -3
- package/lib/types/components/MessageList.d.ts.map +1 -1
- package/lib/types/components/MessageList.js +95 -14
- package/lib/types/components/PermissionsPicker.d.ts +10 -1
- package/lib/types/components/PermissionsPicker.d.ts.map +1 -1
- package/lib/types/components/PermissionsPicker.js +24 -16
- package/lib/types/components/PluginInstallPane.d.ts +21 -0
- package/lib/types/components/PluginInstallPane.d.ts.map +1 -0
- package/lib/types/components/PluginInstallPane.js +84 -0
- package/lib/types/components/PluginManagePane.d.ts +21 -0
- package/lib/types/components/PluginManagePane.d.ts.map +1 -0
- package/lib/types/components/PluginManagePane.js +69 -0
- package/lib/types/components/PromptInput.d.ts.map +1 -1
- package/lib/types/components/PromptInput.js +7 -3
- package/lib/types/components/SubagentCard.d.ts +13 -1
- package/lib/types/components/SubagentCard.d.ts.map +1 -1
- package/lib/types/components/SubagentCard.js +27 -12
- package/lib/types/components/SubagentDashboard.d.ts +8 -1
- package/lib/types/components/SubagentDashboard.d.ts.map +1 -1
- package/lib/types/components/SubagentDashboard.js +58 -16
- package/lib/types/components/launchpadLayout.d.ts +14 -1
- package/lib/types/components/launchpadLayout.d.ts.map +1 -1
- package/lib/types/components/launchpadLayout.js +36 -17
- package/lib/types/components/messages/TeamMessageBubble.d.ts +20 -0
- package/lib/types/components/messages/TeamMessageBubble.d.ts.map +1 -0
- package/lib/types/components/messages/TeamMessageBubble.js +15 -0
- package/lib/types/components/sidePanel/PanelHost.d.ts.map +1 -1
- package/lib/types/components/sidePanel/PanelHost.js +5 -1
- package/lib/types/components/sidePanel/PanelStore.d.ts +8 -0
- package/lib/types/components/sidePanel/PanelStore.d.ts.map +1 -1
- package/lib/types/components/sidePanel/PanelStore.js +11 -0
- package/lib/types/components/sidePanel/SidePanelColumn.d.ts.map +1 -1
- package/lib/types/components/sidePanel/SidePanelColumn.js +13 -1
- package/lib/types/components/sidePanel/SidePanelRuntimeContext.d.ts +7 -0
- package/lib/types/components/sidePanel/SidePanelRuntimeContext.d.ts.map +1 -1
- package/lib/types/components/sidePanel/SidePanelRuntimeContext.js +4 -0
- package/lib/types/components/sidePanel/btw/BtwComposer.d.ts +3 -0
- package/lib/types/components/sidePanel/btw/BtwComposer.d.ts.map +1 -1
- package/lib/types/components/sidePanel/btw/BtwComposer.js +20 -8
- package/lib/types/components/sidePanel/btw/BtwPanelAdapter.d.ts +2 -1
- package/lib/types/components/sidePanel/btw/BtwPanelAdapter.d.ts.map +1 -1
- package/lib/types/components/sidePanel/btw/BtwPanelAdapter.js +104 -13
- package/lib/types/components/sidePanel/btw/BtwThreadScene.d.ts +6 -2
- package/lib/types/components/sidePanel/btw/BtwThreadScene.d.ts.map +1 -1
- package/lib/types/components/sidePanel/btw/BtwThreadScene.js +61 -15
- package/lib/types/components/sidePanel/btw/BtwThreadView.d.ts +14 -4
- package/lib/types/components/sidePanel/btw/BtwThreadView.d.ts.map +1 -1
- package/lib/types/components/sidePanel/btw/BtwThreadView.js +90 -5
- package/lib/types/components/sidePanel/btw/threads.d.ts +18 -0
- package/lib/types/components/sidePanel/btw/threads.d.ts.map +1 -1
- package/lib/types/components/sidePanel/btw/threads.js +51 -0
- package/lib/types/components/sidePanel/builtinPanels.d.ts.map +1 -1
- package/lib/types/components/sidePanel/builtinPanels.js +5 -1
- package/lib/types/components/sidePanel/companion/SplashMascot.d.ts +5 -1
- package/lib/types/components/sidePanel/companion/SplashMascot.d.ts.map +1 -1
- package/lib/types/components/sidePanel/companion/SplashMascot.js +19 -4
- package/lib/types/components/sidePanel/companion/skins.d.ts +8 -0
- package/lib/types/components/sidePanel/companion/skins.d.ts.map +1 -1
- package/lib/types/components/sidePanel/companion/skins.js +57 -12
- package/lib/types/components/sidePanel/types.d.ts +6 -0
- package/lib/types/components/sidePanel/types.d.ts.map +1 -1
- package/lib/types/components/splashArtRows.d.ts +29 -0
- package/lib/types/components/splashArtRows.d.ts.map +1 -0
- package/lib/types/components/splashArtRows.js +31 -0
- package/lib/types/components/teamRoster.d.ts +70 -0
- package/lib/types/components/teamRoster.d.ts.map +1 -0
- package/lib/types/components/teamRoster.js +78 -0
- package/lib/types/dsh-adapter/admission-loader.d.ts +82 -0
- package/lib/types/dsh-adapter/admission-loader.d.ts.map +1 -1
- package/lib/types/dsh-adapter/admission-loader.js +73 -28
- package/lib/types/dsh-adapter/agent-view.d.ts.map +1 -1
- package/lib/types/dsh-adapter/agent-view.js +3 -1
- package/lib/types/dsh-adapter/approvals.d.ts +7 -0
- package/lib/types/dsh-adapter/approvals.d.ts.map +1 -1
- package/lib/types/dsh-adapter/approvals.js +45 -1
- package/lib/types/dsh-adapter/backend/translate.d.ts.map +1 -1
- package/lib/types/dsh-adapter/backend/translate.js +68 -8
- package/lib/types/dsh-adapter/backend-assembly.d.ts +31 -0
- package/lib/types/dsh-adapter/backend-assembly.d.ts.map +1 -0
- package/lib/types/dsh-adapter/backend-assembly.js +225 -0
- package/lib/types/dsh-adapter/backend-contribution.d.ts +36 -0
- package/lib/types/dsh-adapter/backend-contribution.d.ts.map +1 -1
- package/lib/types/dsh-adapter/backend-contribution.js +41 -0
- package/lib/types/dsh-adapter/backend-registry.d.ts.map +1 -1
- package/lib/types/dsh-adapter/backend-registry.js +22 -3
- package/lib/types/dsh-adapter/backends.d.ts.map +1 -1
- package/lib/types/dsh-adapter/backends.js +4 -5
- package/lib/types/dsh-adapter/bundled-presets.d.ts.map +1 -1
- package/lib/types/dsh-adapter/bundled-presets.js +60 -3
- package/lib/types/dsh-adapter/channel/binding-events.d.ts +1 -0
- package/lib/types/dsh-adapter/channel/binding-events.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/binding-events.js +1 -0
- package/lib/types/dsh-adapter/channel/command-completions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/command-completions.js +64 -7
- package/lib/types/dsh-adapter/channel/compaction.d.ts +7 -2
- package/lib/types/dsh-adapter/channel/compaction.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/compaction.js +100 -26
- package/lib/types/dsh-adapter/channel/core/binding-feed.d.ts +3 -0
- package/lib/types/dsh-adapter/channel/core/binding-feed.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/core/binding-feed.js +2 -1
- package/lib/types/dsh-adapter/channel/core/compose.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/core/compose.js +12 -0
- package/lib/types/dsh-adapter/channel/extensions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/extensions.js +68 -8
- package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts +6 -0
- package/lib/types/dsh-adapter/channel/mode-permission-actions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/mode-permission-actions.js +104 -12
- package/lib/types/dsh-adapter/channel/model-actions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/model-actions.js +8 -1
- package/lib/types/dsh-adapter/channel/permissions.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/permissions.js +4 -1
- package/lib/types/dsh-adapter/channel/projection-helpers.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/projection-helpers.js +2 -0
- package/lib/types/dsh-adapter/channel/session-metadata.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-metadata.js +4 -3
- package/lib/types/dsh-adapter/channel/session-reset.js +2 -2
- package/lib/types/dsh-adapter/channel/session-resume.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/session-resume.js +7 -0
- package/lib/types/dsh-adapter/channel/settings-host.d.ts +3 -0
- package/lib/types/dsh-adapter/channel/settings-host.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/settings-host.js +135 -5
- package/lib/types/dsh-adapter/channel/state.d.ts +6 -0
- package/lib/types/dsh-adapter/channel/state.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/subagent-projection.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/subagent-projection.js +18 -6
- package/lib/types/dsh-adapter/channel/transcript.d.ts +7 -0
- package/lib/types/dsh-adapter/channel/transcript.d.ts.map +1 -1
- package/lib/types/dsh-adapter/channel/transcript.js +19 -2
- package/lib/types/dsh-adapter/compat/agent-team-0.2.0.d.ts +55 -0
- package/lib/types/dsh-adapter/compat/agent-team-0.2.0.d.ts.map +1 -0
- package/lib/types/dsh-adapter/compat/agent-team-0.2.0.js +96 -0
- package/lib/types/dsh-adapter/contract.d.ts +4 -4
- package/lib/types/dsh-adapter/contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/contract.js +5 -5
- package/lib/types/dsh-adapter/effect-ledger.d.ts +7 -0
- package/lib/types/dsh-adapter/effect-ledger.d.ts.map +1 -1
- package/lib/types/dsh-adapter/effect-ledger.js +8 -1
- package/lib/types/dsh-adapter/entry-slot.d.ts +3 -1
- package/lib/types/dsh-adapter/entry-slot.d.ts.map +1 -1
- package/lib/types/dsh-adapter/entry-slot.js +2 -2
- package/lib/types/dsh-adapter/fresh-agent.d.ts.map +1 -1
- package/lib/types/dsh-adapter/fresh-agent.js +6 -1
- package/lib/types/dsh-adapter/host-access.d.ts.map +1 -1
- package/lib/types/dsh-adapter/host-access.js +95 -0
- package/lib/types/dsh-adapter/host-contract.d.ts +1 -1
- package/lib/types/dsh-adapter/host-contract.d.ts.map +1 -1
- package/lib/types/dsh-adapter/host-contract.js +3 -2
- package/lib/types/dsh-adapter/host-dsh.d.ts +8 -2
- package/lib/types/dsh-adapter/host-dsh.d.ts.map +1 -1
- package/lib/types/dsh-adapter/host-dsh.js +45 -30
- package/lib/types/dsh-adapter/host-entry.js +35 -10
- package/lib/types/dsh-adapter/index.d.ts +9 -10
- package/lib/types/dsh-adapter/index.d.ts.map +1 -1
- package/lib/types/dsh-adapter/index.js +8 -6
- package/lib/types/dsh-adapter/invariant.d.ts +7 -2
- package/lib/types/dsh-adapter/invariant.d.ts.map +1 -1
- package/lib/types/dsh-adapter/invariant.js +6 -3
- package/lib/types/dsh-adapter/migrate/index.js +2 -2
- package/lib/types/dsh-adapter/panels.d.ts.map +1 -1
- package/lib/types/dsh-adapter/panels.js +6 -0
- package/lib/types/dsh-adapter/plugin-declaration.d.ts +99 -1
- package/lib/types/dsh-adapter/plugin-declaration.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin-declaration.js +132 -2
- package/lib/types/dsh-adapter/plugin-feed.d.ts +94 -0
- package/lib/types/dsh-adapter/plugin-feed.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugin-feed.js +135 -0
- package/lib/types/dsh-adapter/plugin-guard.d.ts +115 -0
- package/lib/types/dsh-adapter/plugin-guard.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugin-guard.js +108 -0
- package/lib/types/dsh-adapter/plugin-install.d.ts +160 -0
- package/lib/types/dsh-adapter/plugin-install.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugin-install.js +545 -0
- package/lib/types/dsh-adapter/plugin-manage.d.ts +178 -0
- package/lib/types/dsh-adapter/plugin-manage.d.ts.map +1 -0
- package/lib/types/dsh-adapter/plugin-manage.js +468 -0
- package/lib/types/dsh-adapter/plugin-manager.d.ts +78 -2
- package/lib/types/dsh-adapter/plugin-manager.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin-manager.js +32 -0
- package/lib/types/dsh-adapter/plugin.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugin.js +49 -2
- package/lib/types/dsh-adapter/plugins-info.d.ts +87 -1
- package/lib/types/dsh-adapter/plugins-info.d.ts.map +1 -1
- package/lib/types/dsh-adapter/plugins-info.js +131 -26
- package/lib/types/dsh-adapter/process-exit.d.ts +1 -1
- package/lib/types/dsh-adapter/process-exit.d.ts.map +1 -1
- package/lib/types/dsh-adapter/process-exit.js +1 -1
- package/lib/types/dsh-adapter/session-projection-store.d.ts +66 -0
- package/lib/types/dsh-adapter/session-projection-store.d.ts.map +1 -0
- package/lib/types/dsh-adapter/session-projection-store.js +149 -0
- package/lib/types/dsh-adapter/settingsEditor.js +2 -2
- package/lib/types/dsh-adapter/sideQuestion.d.ts +21 -0
- package/lib/types/dsh-adapter/sideQuestion.d.ts.map +1 -1
- package/lib/types/dsh-adapter/sideQuestion.js +53 -0
- package/lib/types/dsh-adapter/subagents.d.ts.map +1 -1
- package/lib/types/dsh-adapter/subagents.js +2 -1
- package/lib/types/dsh-adapter/team-mode.d.ts +74 -0
- package/lib/types/dsh-adapter/team-mode.d.ts.map +1 -0
- package/lib/types/dsh-adapter/team-mode.js +188 -0
- package/lib/types/dsh-adapter/team-roster.d.ts +67 -0
- package/lib/types/dsh-adapter/team-roster.d.ts.map +1 -0
- package/lib/types/dsh-adapter/team-roster.js +136 -0
- package/lib/types/dsh-adapter/team-tools.d.ts +58 -0
- package/lib/types/dsh-adapter/team-tools.d.ts.map +1 -0
- package/lib/types/dsh-adapter/team-tools.js +208 -0
- package/lib/types/dsh-adapter/types.d.ts +1 -1
- package/lib/types/dsh-adapter/types.d.ts.map +1 -1
- package/lib/types/i18n.d.ts +607 -16
- package/lib/types/i18n.d.ts.map +1 -1
- package/lib/types/i18n.js +295 -9
- package/lib/types/ink/components/ScrollBox.d.ts +9 -0
- package/lib/types/ink/components/ScrollBox.d.ts.map +1 -1
- package/lib/types/ink/components/ScrollBox.js +23 -0
- package/lib/types/ink/dom.d.ts.map +1 -1
- package/lib/types/kernelPrefs.d.ts +1 -1
- package/lib/types/kernelPrefs.d.ts.map +1 -1
- package/lib/types/native-ts/yoga-layout/index.d.ts.map +1 -1
- package/lib/types/native-ts/yoga-layout/index.js +8 -1
- package/lib/types/permissionPresetLabels.d.ts +25 -0
- package/lib/types/permissionPresetLabels.d.ts.map +1 -0
- package/lib/types/permissionPresetLabels.js +33 -0
- package/lib/types/preset-patch.d.ts +22 -0
- package/lib/types/preset-patch.d.ts.map +1 -0
- package/lib/types/preset-patch.js +14 -0
- package/lib/types/screens/Chat.d.ts +33 -1
- package/lib/types/screens/Chat.d.ts.map +1 -1
- package/lib/types/screens/Chat.js +301 -9
- package/lib/types/screens/Launchpad.d.ts +7 -1
- package/lib/types/screens/Launchpad.d.ts.map +1 -1
- package/lib/types/screens/Launchpad.js +19 -4
- package/lib/types/screens/Settings.d.ts.map +1 -1
- package/lib/types/screens/Settings.js +1 -0
- package/lib/types/screens/chat/usePluginWriteFlow.d.ts +68 -0
- package/lib/types/screens/chat/usePluginWriteFlow.d.ts.map +1 -0
- package/lib/types/screens/chat/usePluginWriteFlow.js +92 -0
- package/lib/types/screens/chatOverlay.d.ts +19 -1
- package/lib/types/screens/chatOverlay.d.ts.map +1 -1
- package/lib/types/sessionModes.d.ts +5 -3
- package/lib/types/sessionModes.d.ts.map +1 -1
- package/lib/types/sessionModes.js +9 -3
- package/lib/types/tips.js +2 -2
- package/lib/types/utils/paths.d.ts +11 -0
- package/lib/types/utils/paths.d.ts.map +1 -1
- package/lib/types/utils/paths.js +13 -0
- package/package.json +126 -120
- package/tui-profile/feed/README.md +63 -0
- package/tui-profile/feed/first-party.json +10 -0
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
## Highlights
|
|
28
28
|
|
|
29
29
|
- **Pixel whale pet** — three startup intros, click to wake; freezes after the first task.
|
|
30
|
-
- **Launchpad and first-run guide** — every ordinary launch lands on a landing page with a **real input box** (big text + whale + quick actions, dropping whole blocks on short/narrow terminals; on by default — /settings `launchpad` off boots straight into chat); command completion matches chat: `Tab` fills the input, `Enter` runs the command and clears it. The first run walks a four-step wizard (API key / language+theme / model+workspace / shortcuts), re-runnable with `/setup`.
|
|
30
|
+
- **Launchpad and first-run guide** — every ordinary launch lands on a landing page with a **real input box** (big text + whale + quick actions, dropping whole blocks on short/narrow terminals; whale-girl images use a compact native-canvas footprint instead of leaving a large gap before the title; on by default — /settings `launchpad` off boots straight into chat); command completion matches chat: `Tab` fills the input, `Enter` runs the command and clears it. The first run walks a four-step wizard (API key / language+theme / model+workspace / shortcuts), re-runnable with `/setup`.
|
|
31
31
|
- **Terminal-native UI** — streaming Markdown, tool cards, `/` and `@` completion, `#L12-14` ranges, history search, zh/en UI.
|
|
32
32
|
- **Task completion notifications** — DSH, Claude and Codex notify after successful live work settles, with no queued follow-up or active goal. The title is “dsh-TUI · Task complete”; the body shows the latest settled reply as a single-line plain-text preview (Markdown formatting removed, up to 200 characters). OSC 777/9 apply an additional 2048-byte sequence budget, including title and protocol bytes, preserving whole graphemes. No reply shows only the title; BEL only rings. `/settings` → Conversation: `taskNotifications` = `unfocused` (default), `always`, or `off`; `notificationMethod` = `auto` (default), `osc9`, or `bel`. Auto uses separate title/body fields on Ghostty/WezTerm (OSC 777) and Kitty (OSC 99); iTerm2/Warp and explicit `osc9` use a title prefix; other terminals ring the bell; delivery follows your terminal's notification/bell settings. tmux requires `set -g allow-passthrough on` for OSC notifications and `set -g focus-events on` for focus reporting. Terminals without focus reporting need `always`. Replay, cancellation and failures do not notify. Works in inline and fullscreen modes.
|
|
33
33
|
- **Native cursor** — focused text inputs inherit your terminal's cursor shape, color, blinking, and enabled animation or trail effects in both inline and fullscreen modes. The `/model` picker shows the same cursor during movement between provider tabs, model rows, and effort levels, then hides it after **0.5 seconds at rest**; clipped regions fall back to the model row. The session manager also moves this cursor between the workspace rail, session rows, and search box; typing claims the search caret, and navigation returns it to the focused row. Configure animation and trail effects in your terminal.
|
|
@@ -98,10 +98,15 @@ The `deepseek-official` API-key route needs `DEEPSEEK_API_KEY`. On DSH
|
|
|
98
98
|
and select the separate account route through `/model`. Other supported
|
|
99
99
|
accounts can sign in through `/provider` or `/auth` after startup.
|
|
100
100
|
|
|
101
|
-
The primary compatibility target is DSH `0.2.
|
|
101
|
+
The primary compatibility target is DSH `0.2.1-rc.2`. This adapter supports its
|
|
102
102
|
Shell API, V4 session messages, declarative presets, and profile-backed settings;
|
|
103
103
|
older supported hosts retain their compatibility paths. See [configuration](docs/configuration.en.md).
|
|
104
104
|
|
|
105
|
+
On DSH rc.2, `/settings` also selects DeepSeek Search / Fetch APIs and edits their
|
|
106
|
+
endpoint and result limits, supporting custom Loader entry IDs and a masked API
|
|
107
|
+
key input saved through DSH's credential store. Official Flash model labels show the `1017` release
|
|
108
|
+
marker while retaining the `deepseek-flash` model ID.
|
|
109
|
+
|
|
105
110
|
On DSH 0.1.7, `/settings` uses the TUI's actual Loader entry ID, including custom
|
|
106
111
|
IDs. It requires matching profile dependencies with `@deepseek-ai/schemastery`
|
|
107
112
|
3.18.3 or newer; an incompatible schema stops TUI startup with repair guidance
|
|
@@ -253,7 +258,9 @@ subscription credentials and `/channel` connections use private app-server proce
|
|
|
253
258
|
|
|
254
259
|
Streaming/tool cards, approvals, questions, steer/queue/interrupt, model and
|
|
255
260
|
effort controls, Plan, `/review`, `/diff`, `/usage`, `/init`, skills and MCP
|
|
256
|
-
share the existing UI.
|
|
261
|
+
share the existing UI. Async questions open the questionnaire while Codex
|
|
262
|
+
continues working; answers steer the turn (or queue if unavailable), and
|
|
263
|
+
dismissing the question leaves work running. **Shift+Tab only toggles Plan**, keeping its underlying
|
|
257
264
|
permission preset; Full Access requires an explicit choice. Existing Codex
|
|
258
265
|
settings are respected, not overwritten with defaults. `/login` offers
|
|
259
266
|
ChatGPT OAuth, a device code or an API key (the last writes to Codex’s own
|
|
@@ -270,7 +277,8 @@ start notice: Codex itself rejects every turn of that provider.
|
|
|
270
277
|
TPS includes hidden reasoning time and excludes tool execution time. Live
|
|
271
278
|
text estimates are corrected when Codex reports output token usage.
|
|
272
279
|
|
|
273
|
-
Native browsing/archive, fork/conversation rewind
|
|
280
|
+
Native browsing/archive, fork/conversation rewind (the first message requires
|
|
281
|
+
Codex app-server 0.160.1+), paged history, images,
|
|
274
282
|
subagents, polled background terminals, goals and `/btw`/`/recap` use the
|
|
275
283
|
existing surfaces. `/logout` removes only the matching dsh-auth credential;
|
|
276
284
|
already-loaded managed tokens require a normal restart, not native logout.
|
|
@@ -282,6 +290,58 @@ Using ChatGPT subscription tokens in third-party clients is subject to
|
|
|
282
290
|
OpenAI’s terms. Full instructions and current boundaries:
|
|
283
291
|
[Codex backend](docs/codex-backend.en.md).
|
|
284
292
|
|
|
293
|
+
### Experimental: DSH Agent Teams
|
|
294
|
+
|
|
295
|
+
DSH's experimental Agent Teams lets the session's agent (the Lead) create
|
|
296
|
+
named teammates that share the working directory, message each other and
|
|
297
|
+
coordinate on a shared task board. It is off by default. Install the
|
|
298
|
+
upstream bundle into the TUI profile once:
|
|
299
|
+
|
|
300
|
+
```sh
|
|
301
|
+
dsh plugin --profile dsh-tui add @deepseek-ai/dsh-experimental-agent-team-profile@0.2.1-rc.2
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Then switch it with `/team on` / `/team off` (`/team` alone reports the
|
|
305
|
+
bundle, the service and this session's teammates). The switch enables or
|
|
306
|
+
disables the bundle in the profile, so it persists across restarts, and on a
|
|
307
|
+
`dsh --profile` launch it applies at once — running sessions included: the
|
|
308
|
+
model is told which tools came and went. Turning it off while teammates run
|
|
309
|
+
asks first, and switching off stops them: the team service releases the
|
|
310
|
+
teammates still running as it unloads. Inside a teammate session the other
|
|
311
|
+
teammates' runs are not visible, so the question counts them as possibly
|
|
312
|
+
running. The team record stays in the session for the next `/team on`.
|
|
313
|
+
`/plugin enable|disable` on the bundle does the same.
|
|
314
|
+
|
|
315
|
+
Pin the version to exactly your installed DSH version (the command above
|
|
316
|
+
uses the primary line `0.2.1-rc.2`; on DSH `0.2.1-alpha.5`, `0.2.0-rc.1` or
|
|
317
|
+
`0.2.0-rc.2` install `…-profile@` that same version). The team packages ship in lockstep with DSH and pin
|
|
318
|
+
their DSH peers exactly, so neither the untagged install nor `next` works.
|
|
319
|
+
When the package is missing, `/team on` prints the command with your
|
|
320
|
+
DSH version filled in on those lines (`0.2.1-rc.2` when the version cannot
|
|
321
|
+
be read); on any other DSH version it asks you to switch DSH to one of those lines first, since
|
|
322
|
+
no team bundle installs there.
|
|
323
|
+
|
|
324
|
+
While a request carries `spawn_teammate`, dsh-TUI drops `subagent` /
|
|
325
|
+
`subagent_fork` from it, and the team's `send_message` / `list_agents` /
|
|
326
|
+
`interrupt_agent` / `wait_agent` take the place of the legacy controls of the
|
|
327
|
+
same names, so `spawn_teammate` is the delegation tool; with the team off
|
|
328
|
+
the legacy tools are back. Subagents that are not team members (workflow,
|
|
329
|
+
ralph) keep `subagent`. A teammate shows up as a subagent row, a message between
|
|
330
|
+
members as a `✉ <sender>` bubble in the receiving session (a teammate's
|
|
331
|
+
received messages show on its subagent detail as agent messages), and the
|
|
332
|
+
other team tools as one-line cards (`send_message` with its target and
|
|
333
|
+
`sent`). The agents dashboard (Ctrl+A) and the agents side
|
|
334
|
+
panel switch to a team view: each teammate under its member name with
|
|
335
|
+
`running` / `idle` / `provisioning` / `failed` (a teammate whose turn ended
|
|
336
|
+
is idle — a message wakes it — not done), the Lead line, the remaining
|
|
337
|
+
subagents, a read-only task board (status, owner, `blocked`, write-scope
|
|
338
|
+
warnings) and a banner when the team record was rejected.
|
|
339
|
+
|
|
340
|
+
Limits: the switch covers the whole profile, not one session (a launch
|
|
341
|
+
without the profile plugin service, or without hot reload, needs `dsh plugin`
|
|
342
|
+
and a restart); there is no "enter teammate session" yet, and `/export` leaves team messages out. Upstream limits apply: teammates share one working directory, a
|
|
343
|
+
team lives in one process, and a task owner is never released automatically.
|
|
344
|
+
|
|
285
345
|
## Keybindings & Mouse
|
|
286
346
|
|
|
287
347
|
`Enter` send · `Tab` complete · `Ctrl+Enter` interrupt and send · `Alt+Up` recall the last message · `Esc` dismiss, double-`Esc` rewinds · `Ctrl+B` side panel · `Ctrl+O` details · `Ctrl+R` history (`↑`/`↓` and `Ctrl+R` are scoped to the current project) · `Ctrl+V` paste · `Ctrl+Shift+E` fullscreen draft editor · `?` shortcuts · `←` open the session manager (DSH backgrounds the current session first).
|
|
@@ -400,8 +460,33 @@ questionnaire, or tool-card changes also need the matching regression scripts.
|
|
|
400
460
|
|
|
401
461
|
Plugin development: [admission & development guide](tui-profile/docs/plugin-admission-and-development.md) · [plugin-template](https://github.com/dsh-tui-ecosystem/plugin-template) · [dsh-tui-ecosystem](https://github.com/dsh-tui-ecosystem). Reference implementation: `dsh-working-activity`.
|
|
402
462
|
|
|
463
|
+
Exported plugin subcomponents are admitted using the nearest package manifest of their ESM entry, including import-only and conditional exports; they do not inherit an outer package's identity.
|
|
464
|
+
|
|
465
|
+
A backend plugin (the `tui.dsh/v1alpha1` `Backend` contribution family) is in the kernel picker after a restart: the boot scans the bundles the profile declares, admits and registers each package-root `dsh-plugin.json` declaration, and reads the implementation from the package's `backend` export — importing that module only when the backend is actually selected.
|
|
466
|
+
Each bundle may declare one backend, and its handler id must match the declaration. Entries awaiting authorization are neither probed nor loaded, including when explicitly requested at startup.
|
|
467
|
+
|
|
403
468
|
Seam grading and API notes: [Plugin development](docs/plugins.en.md). The organization maintains the listing only; it does not endorse community plugins.
|
|
404
469
|
|
|
470
|
+
Installing a plugin from inside the TUI: `/plugin install <package | path | git url>`. It goes through the host's profile plugin manager — a pre-install notice, a trust confirmation, cancellable progress, build-script approval and exact-version exemptions. Packages on the first-party feed this package ships (`tui-profile/feed/first-party.json`, pinned per release and decided offline) skip the trust confirmation, and only a spec that names that exact version qualifies: a bare name, a tag or a range is resolved again at install time, so it is confirmed with the person instead. What was confirmed is what gets installed — the run pins the exact `name@version` the inspection read — and a turn that is still running refuses the install (finish it, or `/new`, first). The same actions remain available from the CLI (`dsh plugin --profile dsh-tui …`).
|
|
471
|
+
|
|
472
|
+
A spec names one of three things:
|
|
473
|
+
|
|
474
|
+
```sh
|
|
475
|
+
/plugin install /path/to/repo
|
|
476
|
+
/plugin install https://github.com/exam/ple.git
|
|
477
|
+
/plugin install @scope/package@1.2.3
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
Typing `/plugin install ` lists these three shapes in the completion popup, and the same shapes follow the installed names on `/plugin info `. They are examples, never candidates: `Tab` leaves the draft exactly as it is, and `Enter` runs the line you typed — the subcommand's usage line while the spec is still empty, your own spec once it is not. No example can therefore be inserted or installed by accident, and a real path that merely starts like one is never swallowed.
|
|
481
|
+
|
|
482
|
+
During installation, `esc` attempts cancellation and keeps the pane open until the write settles; if cancellation is too late, it waits for the installation to finish. During exemption registration, it waits for the current write and stops subsequent grants and the retry. Exemptions already written remain.
|
|
483
|
+
|
|
484
|
+
Failed installs show up to six redacted log lines; lines larger than 16 KiB are omitted with a notice.
|
|
485
|
+
|
|
486
|
+
Managing what is installed: `/plugin remove <bundle>`, `/plugin enable <name | row id>` and `/plugin disable <name | row id>`. A bundle is a composition layer and a row is one patch entry, so the two are separate actions, and a bundle name is matched before any row identity. A module name shared by multiple rows requires a specific row ID. **Gate 2 refuses the three ways this app could switch itself off** — removing or disabling the bundle that provides it, the host layer `dsh-base`, or one of its own rows — and says which rule it broke, without calling the service at all; that holds whether or not hot reload is live, which is the path the host's own guard misses. `enable` is never refused by gate 2 (it is the repair action). Every enable and removal asks first; `disable` asks only about a host-layer row. The host does not attest installed package sources, so even an exact feed match requires confirmation before enabling.
|
|
487
|
+
|
|
488
|
+
These three actions have no cancellation — the service offers none — so `esc` only closes the pane while the write finishes and reports itself into the transcript. Enable and disable have no CLI verb either (the service writes them into the profile's own files), and a removal never deletes your own data: anything left under `~/.dsh-tui` is reported once and left for you to delete.
|
|
489
|
+
|
|
405
490
|
## Documentation
|
|
406
491
|
|
|
407
492
|
- **Start** — [Getting started](docs/getting-started.en.md) · [VS Code](docs/vscode.en.md)
|
|
@@ -437,7 +522,9 @@ Everything, bilingual: [docs/README.md](docs/README.md).
|
|
|
437
522
|
|
|
438
523
|
No sandbox of its own: dsh-TUI uses the active DSH profile's filesystem, shell, sandbox and approval policies. Permission presets come from the DSH `permissionPresets` registry.
|
|
439
524
|
|
|
440
|
-
**Permission persistence** (all three backends): the Claude and Codex backends keep their `/permission` picks in `~/.dsh-tui/backends/<id>/prefs.json`; the DSH pick is kept at `~/.dsh-tui/permission.json`. Every durable preset switch teaches it (picker, typed `/permission`, Shift+Tab static modes, or a switch the official command performed on its own), and a session that never customized its permission planes starts on the remembered preset — applied through the same official switch path. "Never customized" is about the user: the composition writes its own default preset into every fresh session at creation, and those events do not count. Plan-mode transients are excluded, a `DSH_PERMISSION_MODE` launch pin (this run's initial permission plane) outranks the file, and an identity the mounted roster no longer offers is skipped.
|
|
525
|
+
**Permission persistence** (all three backends): the Claude and Codex backends keep their `/permission` picks in `~/.dsh-tui/backends/<id>/prefs.json`; the DSH pick is kept at `~/.dsh-tui/permission.json`. Every durable preset switch teaches it (picker, typed `/permission`, Shift+Tab static modes, or a switch the official command performed on its own), and a session that never customized its permission planes starts on the remembered preset — applied through the same official switch path. "Never customized" is about the user: the composition writes its own default preset into every fresh session at creation, and those events do not count. Plan-mode transients and the experimental Auto review preset (see below) are excluded, a `DSH_PERMISSION_MODE` launch pin (this run's initial permission plane) outranks the file, and an identity the mounted roster no longer offers is skipped.
|
|
526
|
+
|
|
527
|
+
**Auto review** (DSH, experimental): when the `dsh-experimental-auto-review` plugin is enabled, the `auto` preset (shown as "Auto review", tagged `EXP`) appears in `/permission` and its completions live, and disappears when the plugin is removed. It is session-only: the model reviews every tool call before it runs, there is no file sandbox, and each call costs one extra model request; its approval prompts show the localized reason, and a subagent denial reads "Auto review denied; not executed". Picking it in the picker first shows a risk confirmation (`Enter` enables, `Esc` goes back; in fullscreen its Enable / Go back rows are clickable); a typed `/permission auto` switches directly. Once the current session has selected it, the picker skips the confirmation and Shift+Tab stops skipping it.
|
|
441
528
|
|
|
442
529
|
**Upstream auto-retry** (DSH): whenever a session binds (boot, `/model` switch, resume), the TUI seeds a retry policy — 5 attempts, transport-drop-aware failure codes including `STREAM_CLOSED` (a dropped upstream stream) — on **the provider route that session actually uses**, through the official `llm-pi-ai` settings section (the policy the kernel's `llm-retry` plugin executes). Only routes without an explicit `retryPolicy` are seeded — dormant channels are never written — and `upstreamRetry: false` in cordis.yml opts out.
|
|
443
530
|
|
|
@@ -184,13 +184,20 @@ changes during a turn apply to the next one, not to reasoning already in progres
|
|
|
184
184
|
- Command, file, network and permission approvals use server-provided choices. Allow-once,
|
|
185
185
|
session allowance or remembered rules appear only when supported. Questions and MCP forms
|
|
186
186
|
share the existing panel, with secret answers masked.
|
|
187
|
+
- Codex's `request_user_input_async` opens the questionnaire while the agent continues
|
|
188
|
+
working. The first suggestion is selected by default; free text is also available.
|
|
189
|
+
Answers use the native question-reply envelope to steer, falling back to a queued
|
|
190
|
+
follow-up when steering is unavailable. Dismissal closes that question without
|
|
191
|
+
interrupting. Turn completion, connection loss and exit withdraw unanswered questions;
|
|
192
|
+
historical resume never reopens old questionnaires. Codex's persisted echo renders
|
|
193
|
+
as a quoted question and answer, including when rebuilding history.
|
|
187
194
|
|
|
188
195
|
## Daily commands and input
|
|
189
196
|
|
|
190
197
|
| Entry | Behavior |
|
|
191
198
|
| --- | --- |
|
|
192
199
|
| `Enter` / `Tab` / `Ctrl+Enter` while working | Steer / queue a follow-up / interrupt and send now; non-steerable turns fall back to follow-up |
|
|
193
|
-
| `Esc` / `Ctrl+C` | Dismiss the focused panel or interrupt. Cancelling a
|
|
200
|
+
| `Esc` / `Ctrl+C` | Dismiss the focused panel or interrupt. Cancelling a blocking question interrupts its turn; dismissing an async question only closes that question |
|
|
194
201
|
| `/review` | Review uncommitted changes inline; requires idle state and consumes model usage |
|
|
195
202
|
| `/review base <branch>` / `/review commit <sha>` | Review against a branch or commit; other arguments are custom review instructions |
|
|
196
203
|
| `/diff` | Latest turn’s aggregated diff; otherwise try Git diff against the remote, then show an empty-state notice |
|
|
@@ -238,8 +245,11 @@ past tokens/cost. Fresh usage notifications update the readings.
|
|
|
238
245
|
- `/rename` changes the official thread title; `/color` stores a session accent, not a global theme.
|
|
239
246
|
- `/fork` creates a resumable copy without switching. Double `Esc` or `/rewind` conversation
|
|
240
247
|
rewind creates a copy before the selected question, returns the question to the composer
|
|
241
|
-
and preserves the original. Rewinding the first question creates an empty
|
|
242
|
-
|
|
248
|
+
and preserves the original. Rewinding the first question creates an empty, resumable fork.
|
|
249
|
+
First-question rewind, or rewind without a loaded predecessor, requires Codex app-server
|
|
250
|
+
**0.160.1+**, checked from the connection handshake. Older or unknown server versions
|
|
251
|
+
receive an explicit upgrade notice; rewind with a loaded predecessor keeps its existing path.
|
|
252
|
+
**File-only and conversation+files rewind are unsupported**; the Git working tree does not revert.
|
|
243
253
|
- Resume replays the newest 20 full turns before live continuation. Load older messages uses
|
|
244
254
|
prefetched full-item pages, not tool-omitting summaries. Retry when prefetch is still pending;
|
|
245
255
|
repeated failure reports a notice. Active resume deduplicates redelivered approvals and
|
|
@@ -149,13 +149,17 @@ Chat Completions 端点当作 Responses 使用。通过 `/channel` 选择/新建
|
|
|
149
149
|
的路径以新 thread 继续,原 thread 保留;批准计划不会暗中打开 Full Access。
|
|
150
150
|
- 命令、文件改动、网络/权限请求由 Codex 给出的选项驱动;允许本次、会话内允许、
|
|
151
151
|
记住规则等选项只在服务端支持时出现。问卷与 MCP 表单共用现有面板,保密答案掩码。
|
|
152
|
+
- Codex 的 `request_user_input_async` 在运行中打开问卷,智能体继续执行。建议答案默认
|
|
153
|
+
聚焦第一项,也可自由输入;提交通过原生问题回复信封插话,不可插话时排队到下一回合。
|
|
154
|
+
取消只关闭该题,不中断回合。回合结束、连接断开或退出时撤回未答问题;历史恢复不会
|
|
155
|
+
重新打开旧问卷。答案由 Codex 持久化回显投影成「问题 + 答案」,恢复历史时同样显示。
|
|
152
156
|
|
|
153
157
|
## 日常命令与输入
|
|
154
158
|
|
|
155
159
|
| 入口 | 行为 |
|
|
156
160
|
| --- | --- |
|
|
157
161
|
| 工作时 `Enter` / `Tab` / `Ctrl+Enter` | 插话(steer)/ 排队下一回合 / 打断并立即发送;不可 steer 时退为排队 |
|
|
158
|
-
| `Esc` / `Ctrl+C` |
|
|
162
|
+
| `Esc` / `Ctrl+C` | 按当前焦点关闭面板或中断;取消阻塞提问会中断相应回合,取消异步提问只关闭该题 |
|
|
159
163
|
| `/review` | 审查未提交改动,结果 inline 展示;需要空闲,消耗模型用量 |
|
|
160
164
|
| `/review base <branch>` / `/review commit <sha>` | 按分支基线或提交审查;其他参数作为自定义审查说明 |
|
|
161
165
|
| `/diff` | 最近回合的聚合 diff;没有时尝试相对远端的 Git diff,再无内容则提示 |
|
|
@@ -199,7 +203,10 @@ used = max(0, T - 12000)
|
|
|
199
203
|
- `/rename` 改官方 thread 标题;`/color` 只保存会话强调色,不改全局主题。
|
|
200
204
|
- `/fork` 创建可恢复副本,不自动切换;双击 `Esc` 或 `/rewind` 的对话回退在
|
|
201
205
|
所选提问之前创建副本并继续,提问回到输入框、原 thread 保留。首条提问回退会
|
|
202
|
-
|
|
206
|
+
得到可恢复的空分支。首条消息及上一回合未加载时的回退需要 Codex app-server
|
|
207
|
+
**0.160.1+**;按连接握手中的服务端版本判断,版本未知或更旧时明确拒绝并提示升级。
|
|
208
|
+
上一回合已加载时沿用原有回退方式。
|
|
209
|
+
**不支持文件回退或对话+文件回退**,Git 工作树不会随对话恢复。
|
|
203
210
|
- 恢复先回放最近 20 个完整回合,再接 live;加载更早消息使用预取的完整分页,
|
|
204
211
|
不拿省略工具项的 summary 当全转录。预取尚未就绪时可再试一次,连续失败会提示。
|
|
205
212
|
运行中的恢复会去重重发审批;历史没有的完整用量不伪造。
|
|
@@ -26,6 +26,43 @@ only for a genuinely new service.
|
|
|
26
26
|
> When a row is overridden, its `config` block is replaced as a whole. It is
|
|
27
27
|
> not deep-merged, so repeat every key that must remain active.
|
|
28
28
|
|
|
29
|
+
## Web search and fetch (DSH 0.2.1-rc.2)
|
|
30
|
+
|
|
31
|
+
The standard DSH profile loads the new DeepSeek Search / Fetch API providers,
|
|
32
|
+
while Messages search and local HTTP fetch remain the defaults. In `/settings`,
|
|
33
|
+
use the arrow keys in **Web search** to select **Search API** and **Fetch API**.
|
|
34
|
+
Each selection saves immediately and applies to the next operation. Choose
|
|
35
|
+
**Messages** / **HTTP** to restore the original providers. Enter accepts a custom
|
|
36
|
+
provider ID. Sections use the plugin's actual Loader entry ID, including custom IDs.
|
|
37
|
+
|
|
38
|
+
**Web search** has one **API key** input. Paste the key for the selected search API;
|
|
39
|
+
typing is masked and confirmation saves it in DSH's credential store, outside
|
|
40
|
+
profile configuration. Reopening shows only whether a key is configured. Blank
|
|
41
|
+
input preserves the saved key, and switching APIs selects that API's credential.
|
|
42
|
+
|
|
43
|
+
The **DeepSeek Search / Fetch API** section edits the API base URL,
|
|
44
|
+
result count (1–50), and **Send original question**. The base URL
|
|
45
|
+
includes the path prefix without `/search` or `/fetch`; its default is
|
|
46
|
+
`https://api.deepseek.com/v1/tools`. DSH supplies an authorized account token for the account route.
|
|
47
|
+
Search sends the first 128 characters of the latest user prompt by default;
|
|
48
|
+
the section can disable this. Messages search has its own endpoint and maximum
|
|
49
|
+
search count section.
|
|
50
|
+
|
|
51
|
+
The user profile patch can also select both providers:
|
|
52
|
+
|
|
53
|
+
```yaml
|
|
54
|
+
- id: web
|
|
55
|
+
config:
|
|
56
|
+
searchProvider: deepseek-search-api
|
|
57
|
+
fetchProvider: deepseek-fetch-api
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The TUI uses DSH's tools, authentication, cancellation and persisted results;
|
|
61
|
+
it does not make an additional model request. Older hosts and compositions
|
|
62
|
+
without the API plugin omit these new settings. The official `deepseek-official`
|
|
63
|
+
and `deepseek-account` routes show a `1017` marker for `DeepSeek-V4.1-Flash` in
|
|
64
|
+
the model list, retaining the original route IDs.
|
|
65
|
+
|
|
29
66
|
## Official request metadata and feedback reporting
|
|
30
67
|
|
|
31
68
|
The TUI bundle inherits reporting configuration from the installed official DSH
|
|
@@ -438,8 +475,8 @@ The `/provider` add branch signs in to ChatGPT/Codex (`openai-codex`), Claude
|
|
|
438
475
|
(`anthropic`), or Grok (`xai`) subscriptions. When the installed host's pi-ai
|
|
439
476
|
catalog ships the corresponding flows, it also offers OpenAI direct ChatGPT sign-in
|
|
440
477
|
(`openai`, using the OpenAI API rather than the legacy Codex backend) and Meta
|
|
441
|
-
Muse (`meta`). The primary validated DSH `0.2.
|
|
442
|
-
`
|
|
478
|
+
Muse (`meta`). The primary validated DSH `0.2.1-rc.2` development fixture resolves pi-ai
|
|
479
|
+
`1.2.0`, which includes Meta Muse and OpenAI direct sign-in.
|
|
443
480
|
`/auth status`, `/auth login [provider]`, and `/auth logout <provider>` use
|
|
444
481
|
that credential store for these pi-ai routes. Browser authorization tries to open the page
|
|
445
482
|
automatically and offers the authorization link and manual callback URL/code
|
|
@@ -25,6 +25,38 @@ Profile 启动按顺序叠加:
|
|
|
25
25
|
> 覆盖某一行时,`config` 是整块替换,不是逐字段深合并。需要继续生效的字段必须
|
|
26
26
|
> 在用户补丁中全部重写。
|
|
27
27
|
|
|
28
|
+
## 网页搜索与抓取(DSH 0.2.1-rc.2)
|
|
29
|
+
|
|
30
|
+
标准 DSH profile 会加载新的 DeepSeek Search / Fetch API 提供者,默认仍使用
|
|
31
|
+
Messages 搜索和本地 HTTP 抓取。在 `/settings` 的「网页搜索」分区,用左右键将
|
|
32
|
+
「搜索」选为「搜索 API」、「抓取」选为「抓取 API」;选择立即保存,从下一次操作
|
|
33
|
+
生效,不需要重启。切回 `Messages` / `HTTP` 可恢复原提供者。Enter 可输入第三方
|
|
34
|
+
提供者 ID。分区使用插件实际的 Loader 行 ID,也支持自定义 ID。
|
|
35
|
+
|
|
36
|
+
「网页搜索」分区只有一个 API key 输入框,可直接粘贴当前搜索 API 的密钥。
|
|
37
|
+
输入时显示掩码,确认后保存到 DSH 凭据库,不写入 profile 配置;重新打开只显示
|
|
38
|
+
是否已设置,不回显原值。留空保留已有密钥,切换搜索 API 后使用该 API 的凭据。
|
|
39
|
+
|
|
40
|
+
「DeepSeek 搜索 / 抓取 API」分区可修改 API 基础地址、搜索结果数
|
|
41
|
+
(1–50)和「发送原始问题」。基础地址包含路径前缀,不含 `/search` 或 `/fetch`,
|
|
42
|
+
默认 `https://api.deepseek.com/v1/tools`。账号路由由 DSH 使用已授权的账号令牌。
|
|
43
|
+
默认会将最近一条
|
|
44
|
+
用户提示的前 128 个字符随搜索请求发送,可在该分区关闭。Messages 搜索的端点与
|
|
45
|
+
最大搜索次数在独立分区设置。
|
|
46
|
+
|
|
47
|
+
也可通过用户 profile 补丁选择两个提供者:
|
|
48
|
+
|
|
49
|
+
```yaml
|
|
50
|
+
- id: web
|
|
51
|
+
config:
|
|
52
|
+
searchProvider: deepseek-search-api
|
|
53
|
+
fetchProvider: deepseek-fetch-api
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
TUI 沿用 DSH 的工具、鉴权、取消和结果持久化,不额外发起模型请求;旧宿主或未加载
|
|
57
|
+
API 插件的组合不显示这些新增设置。官方 `deepseek-official` / `deepseek-account`
|
|
58
|
+
路由的 `DeepSeek-V4.1-Flash` 在模型列表中显示 `1017` 标记,路由 ID 不变。
|
|
59
|
+
|
|
28
60
|
## 官方请求元数据与反馈上报
|
|
29
61
|
|
|
30
62
|
TUI bundle 继承已安装 DSH 官方组合的上报配置;上游未提供的服务不会由 TUI
|
|
@@ -382,8 +414,8 @@ Profile 模式不再使用旧的 `DSH_TUI_COMPACT_RATIO`、`DSH_TUI_COMPACT_RETA
|
|
|
382
414
|
`dsh-auth` 插件包**。`/provider` 的添加分支提供 ChatGPT/Codex(`openai-codex`)、
|
|
383
415
|
Claude(`anthropic`)、Grok(`xai`)订阅账号登录。宿主 pi-ai catalog 提供相应流程
|
|
384
416
|
时还可使用 OpenAI 直连 ChatGPT 登录(`openai`,使用 OpenAI API 而非旧版 Codex
|
|
385
|
-
后端)和 Meta Muse(`meta`)。当前主验证线 DSH `0.2.
|
|
386
|
-
`
|
|
417
|
+
后端)和 Meta Muse(`meta`)。当前主验证线 DSH `0.2.1-rc.2` 的开发依赖解析到 pi-ai
|
|
418
|
+
`1.2.0`,包含 Meta Muse 与 OpenAI 直连登录。`/auth status`、`/auth login [provider]`、
|
|
387
419
|
`/auth logout <provider>` 对这些 pi-ai 路由操作同一套凭据。浏览器授权会尝试自动打开页面,并在同一
|
|
388
420
|
问卷中提供授权链接与手动粘贴回调 URL/代码的输入;设备码流程在轮询期间显示可复制的
|
|
389
421
|
短码。无交互问卷服务的宿主会明确拒绝登录。
|
|
@@ -387,6 +387,21 @@ that starts `dsh`. Check `DEEPSEEK_BASE_URL` too for a custom endpoint. For
|
|
|
387
387
|
`deepseek-account` or a subscription model, inspect `/auth status` and sign in again with
|
|
388
388
|
`/auth login <provider>` if needed.
|
|
389
389
|
|
|
390
|
+
### The browser connects but dsh-tui cannot reach a self-hosted HTTPS endpoint (self-signed cert / private CA)
|
|
391
|
+
|
|
392
|
+
Self-hosted LLM token servers on a private network are often fronted with HTTPS certificates issued by Caddy, mkcert, Step CA, or similar, whose root certificate is not in Node.js's built-in Mozilla CA bundle. The browser and system `curl` then work fine, but after switching dsh-tui to that provider the TLS handshake fails with `self-signed certificate in certificate chain` or `UNABLE_TO_VERIFY_LEAF_SIGNATURE`.
|
|
393
|
+
|
|
394
|
+
The reason is that dsh-tui's HTTP requests run on Node.js's TLS layer, and Node.js trusts only two things: the Mozilla CA bundle compiled into it, plus the PEM file named by the `NODE_EXTRA_CA_CERTS` environment variable (merged with the built-in list). macOS Keychain "trust" settings have no effect on a Node.js process — Node does not call the system Security.framework, so the trust chain the browser and `curl` use is irrelevant here.
|
|
395
|
+
|
|
396
|
+
Export the root certificate as PEM and set the variable before launching dsh-tui:
|
|
397
|
+
|
|
398
|
+
```sh
|
|
399
|
+
export NODE_EXTRA_CA_CERTS=/path/to/your-ca-root.pem
|
|
400
|
+
dsh-tui
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
Note that `NODE_EXTRA_CA_CERTS` is a bootstrap-protected variable for the DSH launcher: no `.env` file may set it (neither the project directory's `.env` nor `~/.dsh/.env`), and putting it there makes startup fail with an error telling you to `export` it instead — it can only come from the shell environment that launches dsh. The same protected group covers other certificate / TLS variables such as `SSL_CERT_FILE`, `SSL_CERT_DIR`, and `NODE_TLS_REJECT_UNAUTHORIZED`.
|
|
404
|
+
|
|
390
405
|
### The activity row appears twice
|
|
391
406
|
|
|
392
407
|
Check whether `dsh-working-activity` was added separately to the profile. Keep
|
|
@@ -387,6 +387,21 @@ dsh plugin --profile dsh-tui add @deepseek-harness-tui/dsh-tui@latest
|
|
|
387
387
|
自定义端点同时检查 `DEEPSEEK_BASE_URL`。若使用 `deepseek-account` 或订阅模型,
|
|
388
388
|
用 `/auth status` 检查登录状态,必要时重新运行 `/auth login <provider>`。
|
|
389
389
|
|
|
390
|
+
### 浏览器能访问、dsh-tui 连不上自建 HTTPS 端点(自签证书 / 私有 CA)
|
|
391
|
+
|
|
392
|
+
内网自建的 LLM token 服务器常用 Caddy、mkcert、Step CA 等签发 HTTPS 证书,这类根证书不在 Node.js 内置的 Mozilla CA 列表里。于是浏览器和系统级 `curl` 都能正常访问,dsh-tui 切到该 provider 后却在 TLS 握手阶段失败,报 `self-signed certificate in certificate chain` 或 `UNABLE_TO_VERIFY_LEAF_SIGNATURE`。
|
|
393
|
+
|
|
394
|
+
原因是 dsh-tui 的 HTTP 请求跑在 Node.js 的 TLS 层上,而 Node.js 只信任两样东西:编译时打包的 Mozilla CA bundle,以及环境变量 `NODE_EXTRA_CA_CERTS` 指向的 PEM 文件(与内置列表合并)。macOS Keychain 里的「信任」设置对 Node.js 进程无效——Node 不调用系统的 Security.framework,浏览器和 `curl` 用的信任链跟它无关。
|
|
395
|
+
|
|
396
|
+
解决办法是把根证书导出成 PEM,在启动 dsh-tui 之前设置该变量:
|
|
397
|
+
|
|
398
|
+
```sh
|
|
399
|
+
export NODE_EXTRA_CA_CERTS=/path/to/your-ca-root.pem
|
|
400
|
+
dsh-tui
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
注意 `NODE_EXTRA_CA_CERTS` 属于 DSH 启动器的 bootstrap 保护变量:任何 `.env` 文件(项目目录的 `.env` 与 `~/.dsh/.env` 都算)都不允许设置它,写进去会在启动时直接报错退出并提示改用 `export`,只能由启动 dsh 的那个 Shell 环境继承。同组受保护的证书 / TLS 变量还有 `SSL_CERT_FILE`、`SSL_CERT_DIR`、`NODE_TLS_REJECT_UNAUTHORIZED` 等。
|
|
404
|
+
|
|
390
405
|
### 工作状态行重复
|
|
391
406
|
|
|
392
407
|
检查 profile 是否曾单独添加 `dsh-working-activity`。保留本包 patch 自动插入的
|
|
@@ -473,6 +473,13 @@ Notes:
|
|
|
473
473
|
and never reaches the main context or token counts (closing the panel discards it).
|
|
474
474
|
- **Never interrupts the running turn**: it can be triggered while the model is streaming; the main task keeps going.
|
|
475
475
|
- Inside the panel: `↑`/`↓` scroll, `Space`/`Enter`/`Esc` dismiss, `c` copies the answer; `Esc` cancels while the answer is still pending.
|
|
476
|
+
- The sidebar panel (when the panel column is open) has two layers: the default **reading layer** — `←`/`→` switch panels, `↑`/`↓` move the **selection** between turns, `PgUp`/`PgDn` page, `n` starts a new topic, `s` sends the **selected** turn's answer to the main composer (press `s` again to take it back), `c` copies the selected turn's answer; `Enter`/`Tab` (or a click on the input) enters the **editing layer** (`Esc` leaves one layer at a time: editing first, draft kept), where `←`/`→` move the caret first and, once the caret sits at the start/end, the same key falls through and switches panels again, while `↑` goes straight back up to the titles.
|
|
477
|
+
- The sidebar's bottom hint line **follows the layer** (the panel advertises it, the host only stitches it): with the cursor in the **list** it says `↑/↓ select · s to chat · c copy` (or `s unsend` for the attached turn); with the cursor in the **input** it drops s/c (there `s` is just a letter) and says `↑ select` instead. An empty thread advertises nothing there. The input box keeps only an `Enter to ask` placeholder.
|
|
478
|
+
- The selection shows itself in exactly two ways: the title's **text** is inverted (not the whole row) and the terminal cursor parks on that row — so `↑`/`↓` visibly walks the native caret between titles. Both are hidden while the cursor sits in the main input or the side composer: they mean "the list owns the keyboard". **Clicking a title row** moves the selection there too.
|
|
479
|
+
- Scrolling only happens when it must: a target title already inside the viewport scrolls nothing at all; one outside it scrolls just far enough to **exactly reveal** that row (flush to the top edge when walking up, flush to the bottom edge when walking down).
|
|
480
|
+
- **Focus returns to the main composer after sending**: the chip is right there, you can keep typing, and `Esc` removes it immediately (inside the panel `Esc` leaves the panel instead of dropping the chip).
|
|
481
|
+
- Clicking the **message area** (question or answer text) only hands the column focus to the panel, exactly like clicking anywhere else in it — it never injects anything; `s` is the only way in.
|
|
482
|
+
- The `⤢` full-screen scene shares the sidebar's keys and selection state (both read the same thread store); the only difference is that after sending it steps aside and returns you to the main composer.
|
|
476
483
|
- Triggering `/btw` again aborts the previous side question.
|
|
477
484
|
|
|
478
485
|
### Trajectory scene (/trace / Ctrl+T)
|
|
@@ -802,7 +809,7 @@ The command menu merges local commands with the DSH command registry. Type `/` t
|
|
|
802
809
|
|
|
803
810
|
**Account and policy**
|
|
804
811
|
|
|
805
|
-
- `/provider`, `/login`, `/logout`, `/permission`, `/add-dir`, `/hooks`, `/mcp`, `/plugin` — `list` shows the plugins you added (the installation-supplied bundles stay out); `check <path>` validates a plugin manifest, `info <id>` describes an installed entry or an install spec, `registries` lists where installations ask; bare `/plugin` gives the full diagnostics
|
|
812
|
+
- `/provider`, `/login`, `/logout`, `/permission`, `/add-dir`, `/hooks`, `/mcp`, `/plugin` — `list` shows the plugins you added (the installation-supplied bundles stay out); `install <spec>` installs a plugin into this profile (a pre-install notice and a trust confirmation; first-party packages on the packaged feed skip the confirmation; `esc` closes the pane, and during an install it attempts cancellation and waits for writes to settle, or for completion if too late; exemptions already written remain; blocked build scripts are approved in the pane, and an incompatible version can be exempted for that exact version); `remove <bundle>` / `enable <name|id>` / `disable <name|id>` are the lifecycle actions (a bundle name wins over a row identity; a module name matching multiple rows requires a specific row ID; gate 2 refuses the bundle providing this app, the host layer `dsh-base` and this package's own rows, with a reason and no service call, while every enable and removal asks first because installed sources cannot be verified; **no cancellation** — `esc` only closes the pane and the write goes on, and a removal does not delete your own data); `check <path>` validates a plugin manifest, `info <id>` describes an installed entry or an install spec, `registries` lists where installations ask; bare `/plugin` gives the full diagnostics.
|
|
806
813
|
- After `/auth login deepseek-account` or `/provider` signs in, a Platform-confirmed, unshown login bonus appears with its amount and expiry as a “Whale coupon” in the whale-maid dialog; Enter/Esc closes it.
|
|
807
814
|
|
|
808
815
|
**Skills**
|
|
@@ -461,6 +461,13 @@ Windows `dsh-tui.cmd --resume` 使用 `~/.dsh-tui/resume.txt` 中最后选择的
|
|
|
461
461
|
- **不进会话历史**:问答不写入 session log,也不会出现在主上下文与 token 计数里(关闭面板即消失)。
|
|
462
462
|
- **不打断主回合**:模型正在流式输出时也可以触发,主任务继续运行。
|
|
463
463
|
- 面板内 `↑`/`↓` 滚动,`Space`/`Enter`/`Esc` 关闭,`c` 复制答案;等待答案时 `Esc` 取消。
|
|
464
|
+
- 侧栏面板形态(面板列展开时)分两层:默认**阅读层**——`←`/`→` 切面板、`↑`/`↓` 在轮之间移动**选中**、`PgUp`/`PgDn` 翻页、`n` 新话题、`s` 把**选中轮**的答案送进主输入框(再按一次 `s` = 撤回)、`c` 复制选中轮的答案;`Enter`/`Tab`(或点击输入框)进**编辑层**(`Esc` 逐层退出:先退编辑、草稿保留),编辑层里 `←`/`→` 先移光标,光标贴到行首/行尾后再按同一个键就交回宿主切面板,`↑` 则直接回到标题(列表)。
|
|
465
|
+
- 侧栏那行底栏提示**按层换**(面板自己广告、宿主只拼):光标在**列表**里说 `↑/↓ 选择 · s 送聊天 · c 复制`(已附加的那一轮说 `s 撤回`),光标在**输入框**里则不说 s/c(那里 `s` 只是打字),改说 `↑ 选择`;空线程没有可选的轮,这一段不画。输入框里只留一句 `Enter 提问` 占位。
|
|
466
|
+
- 选中的标记只有两点:标题**文字**反色(不铺满整行),以及终端光标停在那一行(所以按 `↑`/`↓` 时原生光标的拖尾是在标题之间上下走)。光标在主输入框或侧栏输入框里时两者都不显示——它表示的是「列表正拿着键盘」。**点标题行**也能把选中挪到那一轮。
|
|
467
|
+
- 滚动只在必要时发生:目标标题已经在视口里就一行都不滚;走出视口才滚,而且只滚到**恰好露出**这一行(往上走贴视口顶、往下走贴视口底)。
|
|
468
|
+
- **送聊天之后焦点自动回主输入框**:chip 就在眼前、可以直接接着打字,`Esc` 也立刻能把它撤掉(在面板里按 `Esc` 是退出面板,不是撤 chip)。
|
|
469
|
+
- 点**消息区**(问题/答案正文)跟点面板其它地方一样,只把列焦点交给面板,不会注入任何东西——注入只有 `s` 一个入口。
|
|
470
|
+
- `⤢` 全屏场景与侧栏面板同一套键位与选中态(线程 store 共享),区别只是送完聊天后整屏场景让位、回到主输入框。
|
|
464
471
|
- 再次触发 `/btw` 会中止上一个侧问。
|
|
465
472
|
|
|
466
473
|
### 轨迹场景(/trace / Ctrl+T)
|
|
@@ -804,7 +811,7 @@ Claude 后端的审批来自 CLI:CLI 给出建议时多一个「始终允许
|
|
|
804
811
|
|
|
805
812
|
- `/provider`、`/login`、`/logout`、`/permission`、`/add-dir`、`/hooks`、`/mcp`。
|
|
806
813
|
- `/auth login deepseek-account` 或 `/provider` 完成 DeepSeek 登录后,若 Platform 返回尚未展示的登录赠金,鲸鱼女仆娘弹窗会显示“鲸鱼券”的金额与到期时间;按 Enter/Esc 关闭。
|
|
807
|
-
- `/plugin`:`list` 简洁列出你装的额外插件(不含安装自带);`check <路径>` 校验插件清单、`info <id>` 查已装条目或待装 spec、`registries` 列安装源;无参 `/plugin`
|
|
814
|
+
- `/plugin`:`list` 简洁列出你装的额外插件(不含安装自带);`install <spec>` 把插件装进当前 profile(装前提醒 + 信任确认,嫡系包按随包清单免确认;`esc` 收起面板,安装中尝试取消并等待写操作结束,来不及时等待安装完成,已登记的版本豁免保留;构建脚本被拦时在面板里批准,版本不兼容可登记精确版本豁免);`remove <bundle>` / `enable <名称|id>` / `disable <名称|id>` 是生命周期动作(bundle 名优先于行身份,模块名匹配多行时须改用具体行 ID;门禁 2 对提供本应用的 bundle、宿主层 `dsh-base` 与本包自己的行硬拒并给原因,任何启用与卸载都要确认(已装包来源无法验证);**没有取消**——`esc` 只关面板,写入继续,卸载不删你自己的数据);`check <路径>` 校验插件清单、`info <id>` 查已装条目或待装 spec、`registries` 列安装源;无参 `/plugin` 给完整诊断。
|
|
808
815
|
|
|
809
816
|
**Skills**
|
|
810
817
|
|
|
@@ -43,6 +43,10 @@ reference**, not a promise:
|
|
|
43
43
|
Also an experimental public surface:
|
|
44
44
|
|
|
45
45
|
- `@deepseek-harness-tui/dsh-tui/api` (types-only entry).
|
|
46
|
+
- **Rows inside a preset (experimental, seam VII)**: a bundle changes the `config` of a row
|
|
47
|
+
inside a preset dsh-TUI registers (for example, turning off `standard`'s
|
|
48
|
+
`compaction-basic` auto-compaction) with a `@deepseek-harness-tui/dsh-tui/preset-patch` row;
|
|
49
|
+
see seam VII of the [admission and development guide](../tui-profile/docs/plugin-admission-and-development.md).
|
|
46
50
|
- **Side panels (experimental, §18)**: `ctx.tuiPanels.register({ apiVersion:
|
|
47
51
|
1, id, title, icon?, component | compact })` registers a right-sidebar
|
|
48
52
|
panel (the host prefixes `<pluginId>:`; ≤4 panels per plugin, ≤32 globally;
|
|
@@ -59,11 +63,68 @@ Also an experimental public surface:
|
|
|
59
63
|
- **The backend contribution family (`tui.dsh/v1alpha1` `Backend`, seam XIV) has its
|
|
60
64
|
public surface frozen with the first published apiVersion**: the type surface
|
|
61
65
|
(`BackendSpec`, `validateBackendSpec`, `backendAdmission`) and conformance
|
|
62
|
-
(`TUI-BACKEND-001`) are usable, and the
|
|
63
|
-
registry → descriptor)
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
66
|
+
(`TUI-BACKEND-001`) are usable, and **both the admission chain (manifest →
|
|
67
|
+
registry → descriptor) and the install chain are wired**: the boot scans the
|
|
68
|
+
bundles the profile declares (`dsh.profile.bundles`, written by `/plugin install`
|
|
69
|
+
and by `dsh plugin add` alike), reads `dsh-plugin.json` from the package root
|
|
70
|
+
nearest the actual ESM entry, and registers what the validator and the admission
|
|
71
|
+
accept — so "install a third-party backend, restart, see it in the picker" holds.
|
|
72
|
+
Three boundaries: that scan runs **before** backend-choice registry membership
|
|
73
|
+
is checked (the Config schema checks syntax only, and the standalone entry's
|
|
74
|
+
full/light composition follows the final, assembled kernel); a backend's
|
|
75
|
+
implementation is read from its entry module's `backend` export
|
|
76
|
+
(`backendExport` is an in-tree private field, so a declaration cannot name another
|
|
77
|
+
export) and that module is imported only when the backend is actually selected;
|
|
78
|
+
and installing **without restarting** still does not put it in the picker — that
|
|
79
|
+
is not a promise.
|
|
80
|
+
Each bundle currently binds one `Backend` declaration. Its manifest must pass
|
|
81
|
+
canonical projection, including unique contribution identities, and the handler
|
|
82
|
+
id must match the declaration. Entries awaiting authorization stay registered
|
|
83
|
+
but are neither probed nor loaded; explicitly selecting one at startup fails too.
|
|
84
|
+
- **Installing a package is available in the terminal itself (C-4)**: `/plugin
|
|
85
|
+
install <spec>` goes through the host's `ctx.pluginManager` — a pre-install
|
|
86
|
+
notice, a trust confirmation decided by provenance of the package (the judge is
|
|
87
|
+
the packaged `tui-profile/feed/first-party.json`, decided offline; anything it
|
|
88
|
+
cannot vouch for falls back to the confirmation), and `esc` to close the pane.
|
|
89
|
+
During an install, it attempts cancellation and waits for profile writes to
|
|
90
|
+
settle: the service rolls the profile back on cancellation, or finishes the
|
|
91
|
+
install if applying has already made cancellation too late. Blocked build
|
|
92
|
+
scripts can be approved in the pane, and an incompatible version can receive
|
|
93
|
+
an **exact-version exemption**. Cancelling during exemption registration waits
|
|
94
|
+
for the current write and stops subsequent grants and the retry; exemptions
|
|
95
|
+
already written remain. **Known gaps**:
|
|
96
|
+
provenance is only a one-vote-to-veto seam with no online check at all (the
|
|
97
|
+
host service exposes no such API), and with no service the transcript reports
|
|
98
|
+
the CLI command and the reason instead of **running `dsh plugin` on the user's
|
|
99
|
+
behalf** (no pane opens: there is no flow to drive).
|
|
100
|
+
- **Lifecycle actions are available in the terminal itself (C-5)**: `/plugin remove
|
|
101
|
+
<bundle>`, `/plugin enable <name|id>` and `/plugin disable <name|id>` go through the
|
|
102
|
+
same host service. **A bundle and a row are two levels**: a bundle is a composition
|
|
103
|
+
layer (the profile manifest's `dsh.profile.bundles`), a row is one patch entry's
|
|
104
|
+
`disabled`. The argument resolves against one snapshot, a bundle name first and
|
|
105
|
+
exactly, then `entryId` → `patchId` → module name; nothing that matches is reported
|
|
106
|
+
with what is addressable rather than guessed at. A module name matching multiple rows
|
|
107
|
+
is refused with their row IDs; use a specific ID. **Gate 2** (this application may not
|
|
108
|
+
switch itself off) refuses three kinds of target hard — the bundle providing this app,
|
|
109
|
+
the host layer `@deepseek-ai/dsh-base`, and this application's own rows (those loading
|
|
110
|
+
a module of this package, **or inserted by its own patch**: measured, that patch inserts
|
|
111
|
+
17 rows and 8 of them load a first-party `@deepseek-ai/*` module, of which the host locks
|
|
112
|
+
exactly one) — with a reason line and **no service call at all**, and it does so whether or not hot
|
|
113
|
+
reload is live (the host's own `stop-profile` guard only fires without HMR, and this
|
|
114
|
+
profile runs `patchReload: live`). `enable` is never refused by gate 2: it is the
|
|
115
|
+
repair action, and refusing it would seal off the only in-UI way back from a profile
|
|
116
|
+
somebody edited by hand. The host's own lock (`management-required` / `unaddressable`)
|
|
117
|
+
refuses both directions and its reason is quoted as given. **Every `enable` and `remove` requires confirmation** (a removal lists the
|
|
118
|
+
rows and overrides it drops), while `disable` asks only about a row the host layer
|
|
119
|
+
owns (switching one off unloads services this app injects). The host does not attest
|
|
120
|
+
installed package sources: local and Git packages can claim the same name and version,
|
|
121
|
+
so an exact feed match cannot waive confirmation when enabling. These actions have **no
|
|
122
|
+
cancellation**: the service offers none, so `esc` only closes the pane while the write
|
|
123
|
+
finishes and reports itself into the transcript (same session). **Known gaps**: a
|
|
124
|
+
removal deletes no user data — `~/.dsh-tui/backends/<id>/`, grants and storage
|
|
125
|
+
namespaces are **reported once** and left for the person to delete; when a package's
|
|
126
|
+
declaration cannot be read, the flow says it could not judge rather than claiming the
|
|
127
|
+
removal was clean.
|
|
67
128
|
- `grants` is now the narrower `HostGrantFacade`; see that PR for migration
|
|
68
129
|
details.
|
|
69
130
|
- On `TuiSceneProps.channel` (`ChannelUi`), `minimal` / `setMinimal()` were
|
|
@@ -38,6 +38,9 @@
|
|
|
38
38
|
另:
|
|
39
39
|
|
|
40
40
|
- `@deepseek-harness-tui/dsh-tui/api`(纯类型入口)为实验性公开面。
|
|
41
|
+
- **preset 内的行(实验性,接缝七)**:bundle 用 `@deepseek-harness-tui/dsh-tui/preset-patch`
|
|
42
|
+
行改 dsh-TUI 注册的 preset 里某一行的 `config`(例如关掉 `standard` 的
|
|
43
|
+
`compaction-basic` 自动压缩),写法见[准入与开发指南](../tui-profile/docs/plugin-admission-and-development.md)接缝七。
|
|
41
44
|
- **侧栏 Panel(实验性,§18)**:`ctx.tuiPanels.register({ apiVersion: 1,
|
|
42
45
|
id, title, icon?, component | compact })` 向右侧栏注册面板(宿主自动加
|
|
43
46
|
`<pluginId>:` 前缀;每插件 ≤4 个、全局 ≤32 个;`open()` 限速每 5s 一次;
|
|
@@ -50,9 +53,40 @@
|
|
|
50
53
|
`ctx.tuiPluginHost.grants.corrupt` 已随 adapter 分层重构(#705)移除。
|
|
51
54
|
- **后端贡献族(`tui.dsh/v1alpha1` `Backend`,接缝十四)的公开面已随第一版 apiVersion 冻结**:类型面
|
|
52
55
|
(`BackendSpec`、`validateBackendSpec`、`backendAdmission`)与 conformance
|
|
53
|
-
(`TUI-BACKEND-001`)已可用,**准入链路(清单 → registry → descriptor
|
|
54
|
-
|
|
55
|
-
|
|
56
|
+
(`TUI-BACKEND-001`)已可用,**准入链路(清单 → registry → descriptor)与装链路都已接线**:
|
|
57
|
+
启动时扫 profile 声明的已装 bundle(`dsh.profile.bundles`——`/plugin install` 与 `dsh plugin add`
|
|
58
|
+
都写它),按**实际 ESM 入口最近的包根**读 `dsh-plugin.json`,校验 + 准入后注册,于是
|
|
59
|
+
「装一个第三方后端、重启后出现在 picker 里」成立。三条边界:这份扫描**早于**后端选择的注册表成员判定
|
|
60
|
+
(Config Schema 只校验语法,独立入口的完整/轻量组合由装配后的最终内核决定);后端实现从包入口模块的 `backend` 导出取
|
|
61
|
+
(`backendExport` 是 in-tree 私有项,声明里写不了别的导出名),模块只在真的选中时才 import;
|
|
62
|
+
装完**不重启**仍然不会出现在 picker 里——那不是承诺。
|
|
63
|
+
当前每个 bundle 只接一个 `Backend` 声明;清单须通过规范投影(含贡献身份唯一性),handler 的 id 必须与声明一致。
|
|
64
|
+
等待授权的条目仍注册身份,但不探测、不加载;启动参数或配置显式指定它也会报错。
|
|
65
|
+
- **装包本身已在终端里可用(C-4)**:`/plugin install <spec>` 走宿主
|
|
66
|
+
`ctx.pluginManager`,装前给提醒、按来源决定要不要确认信任(嫡系判据是随包发布的
|
|
67
|
+
`tui-profile/feed/first-party.json`,离线可判;验不过一律 fail closed 退回确认),
|
|
68
|
+
`esc` 收起面板;安装进行中会尝试取消,面板等写操作结束后才关闭。取消成功由服务回滚 profile,
|
|
69
|
+
已进入应用阶段而来不及时则等待安装完成。构建脚本被拦时在面板里批准,
|
|
70
|
+
版本不兼容可登记 **精确版本豁免**;登记期间取消会等待当前写入、停止后续登记和重试,
|
|
71
|
+
已写入的豁免保留。**已知缺口**:provenance 只留了「一票否决」的缝、
|
|
72
|
+
没有任何在线校验(宿主服务不暴露这类 API);服务缺席时由转录给出 CLI 命令与原因
|
|
73
|
+
(不弹面板:没有可驱动的流程),**不在 TUI 内代跑 `dsh plugin`**。
|
|
74
|
+
- **生命周期动作已在终端里可用(C-5)**:`/plugin remove <bundle>`、`/plugin enable
|
|
75
|
+
<名称|id>`、`/plugin disable <名称|id>` 走同一套宿主服务。**bundle 与行是两级语义**:
|
|
76
|
+
bundle 是组合层(写 profile 清单的 `dsh.profile.bundles`),行是 patch 的 `disabled`;
|
|
77
|
+
解析顺序是 bundle 名精确匹配优先,其次 `entryId` → `patchId` → 模块名,都不中就给可寻址
|
|
78
|
+
清单、不猜;模块名匹配多行时,列出行 ID 并拒绝写入,须改用具体 ID。**门禁 2**(不能自己杀自己)在 TUI 侧硬拒三类目标——提供本应用的 bundle、
|
|
79
|
+
宿主层 `@deepseek-ai/dsh-base`、本应用自己的行(加载本包模块的行,**或由本包 patch
|
|
80
|
+
插入的行**:实测本包的 patch 插入 17 行,其中 8 行加载的是首方 `@deepseek-ai/*` 模块,
|
|
81
|
+
上游只锁住其中一个)——拒绝时给一行原因且**不发起任何服务调用**,与 HMR 是否生效无关(上游 `stop-profile` 守卫只在没有 HMR 时生效,本 profile 是
|
|
82
|
+
`patchReload: live`,所以那道守卫靠不住)。`enable` 不因门禁 2 被拒:它是复原动作,把手工
|
|
83
|
+
改坏的 profile 关在门外等于封死唯一的 UI 退路;上游自己的锁(`management-required` /
|
|
84
|
+
`unaddressable`)则两个方向都拒,并原样转述上游的理由。**任何 `enable` 与 `remove` 都要确认**(卸载列出它会动的行数与覆盖数),
|
|
85
|
+
`disable` 只对宿主层自己的行问一句(关掉它会卸载本应用注入的服务)。宿主不提供
|
|
86
|
+
已装包的来源证明,本地或 Git 包也能声明嫡系的名称与版本,因此即使命中 feed 也不能免确认。这些动作**没有取消面**:
|
|
87
|
+
服务不提供,Esc 只关面板,写入照旧跑完并(在同一会话里)把结果写进转录。**已知缺口**:
|
|
88
|
+
卸载不删用户数据——`~/.dsh-tui/backends/<id>/`、grants、存储命名空间只**报告一次**,由
|
|
89
|
+
用户自己决定删不删;包内声明读不到时明说「判断不了」,不制造「已清理」的假象。
|
|
56
90
|
- `grants` 收窄为 `HostGrantFacade`,迁移细节见该 PR。
|
|
57
91
|
- `TuiSceneProps.channel`(`ChannelUi`)上的 `minimal` / `setMinimal()` 已更名为
|
|
58
92
|
`minimalUi` / `setMinimalUi()`;旧名保留为 **deprecated 别名**,读写同一个
|