@deepseek-harness-tui/dsh-tui 0.15.0 → 0.16.1
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 +98 -8
- package/guide/dsh-tui-guide/claude-backend.en.md +8 -0
- package/guide/dsh-tui-guide/claude-backend.md +5 -0
- 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 +32 -9
- package/guide/dsh-tui-guide/getting-started.md +27 -8
- 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 +99 -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 +4 -3
- 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 +40 -13
- 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/install/pnpm-profile-add.d.ts.map +1 -1
- package/lib/types/dsh-adapter/install/pnpm-profile-add.js +9 -3
- 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/update.d.ts +31 -22
- package/lib/types/update.d.ts.map +1 -1
- package/lib/types/update.js +85 -42
- 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
|
@@ -2,7 +2,8 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
/**
|
|
3
3
|
* btw 侧栏面板:线程滚动 + Markdown + 底部 composer 连续追问。Esc 先退出
|
|
4
4
|
* composer 编辑(草稿保留),列表层不消费 Esc,再交宿主回聊天;Tab 在列表
|
|
5
|
-
* 与 composer 间切焦点;未消费的键交宿主(←/→
|
|
5
|
+
* 与 composer 间切焦点;未消费的键交宿主(←/→ 切面板——编辑层里光标贴到
|
|
6
|
+
* 行首/行尾后也让位)。
|
|
6
7
|
*
|
|
7
8
|
* badge 派生(镜像 jobs/agents 适配器):面板不可见期间完成的新 answer
|
|
8
9
|
* 增 info unread、失败 error level 计未读、运行中只亮点不计未读;进入
|
|
@@ -12,7 +13,7 @@ import React from 'react';
|
|
|
12
13
|
import { Box, Text } from '../../../ui.js';
|
|
13
14
|
import { t } from '../../../i18n.js';
|
|
14
15
|
import { panelStore } from '../PanelStore.js';
|
|
15
|
-
import { useSidePanelChannel } from '../SidePanelRuntimeContext.js';
|
|
16
|
+
import { useSidePanelChannel, useSidePanelFocusChat } from '../SidePanelRuntimeContext.js';
|
|
16
17
|
import { usePanelInput } from '../usePanelInput.js';
|
|
17
18
|
import { truncateWidth } from '../../../trajectory/format.js';
|
|
18
19
|
import { stringWidth } from '../../../ink/stringWidth.js';
|
|
@@ -30,12 +31,16 @@ function btwContextOptions() {
|
|
|
30
31
|
}
|
|
31
32
|
export function BtwPanelAdapter({ width, height, focused, visible }) {
|
|
32
33
|
const channel = useSidePanelChannel();
|
|
34
|
+
// 送聊天后把列焦点交回主输入框(宿主没接时 undefined = 焦点不动)。
|
|
35
|
+
const focusChat = useSidePanelFocusChat();
|
|
33
36
|
const sessionId = String(channel.agentId);
|
|
34
37
|
const thread = useBtwThread(sessionId);
|
|
35
38
|
const version = thread?.version ?? 0;
|
|
36
39
|
const busy = thread !== undefined && thread.activeTurnId !== null;
|
|
37
40
|
// 默认阅读层:箭头归导航(←/→ 切面板、↑/↓ 滚动);Enter/Tab/点击输入框
|
|
38
|
-
//
|
|
41
|
+
// 才进编辑层,箭头变光标——光标贴到行首/行尾后再按同一个键同样落回宿主
|
|
42
|
+
// 切面板(BtwComposer 的到头让位),所以底栏「←/→ 切换」在两层都成立;
|
|
43
|
+
// 聚焦状态另有边框高亮与框内提示兜底。
|
|
39
44
|
const [composerFocus, setComposerFocusState] = React.useState(false);
|
|
40
45
|
// 聚焦位也骑 ref:Enter 聚焦后紧接着的按键(两键之间没有重渲染)必须
|
|
41
46
|
// 已经看见编辑层——与 caret 同一款契约,否则第一个字符会被列表层吃掉。
|
|
@@ -71,8 +76,10 @@ export function BtwPanelAdapter({ width, height, focused, visible }) {
|
|
|
71
76
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- badge derives from the thread snapshot version
|
|
72
77
|
}, [version, visible]);
|
|
73
78
|
const attachTurn = React.useCallback((turn) => {
|
|
79
|
+
if (turn.phase !== 'completed')
|
|
80
|
+
return false;
|
|
74
81
|
if (typeof channel.attachContext !== 'function')
|
|
75
|
-
return;
|
|
82
|
+
return false;
|
|
76
83
|
channel.attachContext({
|
|
77
84
|
source: 'panel',
|
|
78
85
|
sourceId: turn.turnId,
|
|
@@ -81,7 +88,29 @@ export function BtwPanelAdapter({ width, height, focused, visible }) {
|
|
|
81
88
|
});
|
|
82
89
|
const staged = channel.attachedContexts.find(entry => entry.sourceId === turn.turnId);
|
|
83
90
|
channel.notify(staged?.truncated === true ? t('btw-thread-answer-truncated') : t('btw-thread-answer-attached'), { color: 'success' });
|
|
91
|
+
return true;
|
|
92
|
+
}, [channel]);
|
|
93
|
+
/** 该轮是否已经挂在主输入框上(sourceId = turnId;部分夹具没有这个面)。 */
|
|
94
|
+
const attachedEntryOf = React.useCallback((turnId) => {
|
|
95
|
+
// oxlint-disable-next-line typescript/no-unnecessary-condition -- runtime guard: partial fixture channels
|
|
96
|
+
return (channel.attachedContexts ?? []).find(entry => entry.sourceId === turnId);
|
|
84
97
|
}, [channel]);
|
|
98
|
+
/**
|
|
99
|
+
* `s` = 送聊天,再按一次 = 撤回(选中行 → 动作)。送出去之后把列焦点交回主
|
|
100
|
+
* 输入框:chip 就在眼前、可直接接着打字,toast 里那句「Esc 可撤」也才成立
|
|
101
|
+
* (剥 chip 的 Esc 只有主输入框有焦点才收得到)。
|
|
102
|
+
*/
|
|
103
|
+
const sendToChat = React.useCallback((turn) => {
|
|
104
|
+
const staged = attachedEntryOf(turn.turnId);
|
|
105
|
+
if (staged !== undefined) {
|
|
106
|
+
if (typeof channel.detachContext === 'function')
|
|
107
|
+
channel.detachContext(staged.id);
|
|
108
|
+
channel.notify(t('panel-context-detached'), { color: 'success' });
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (attachTurn(turn))
|
|
112
|
+
focusChat?.();
|
|
113
|
+
}, [attachTurn, attachedEntryOf, channel, focusChat]);
|
|
85
114
|
const submitDraft = React.useCallback(() => {
|
|
86
115
|
const text = btwThreads.get(sessionId)?.draft ?? '';
|
|
87
116
|
if (text.trim() === '')
|
|
@@ -111,6 +140,35 @@ export function BtwPanelAdapter({ width, height, focused, visible }) {
|
|
|
111
140
|
void setClipboard(latest.answer);
|
|
112
141
|
channel.notify(t('copied-chars', { n: latest.answer.length }), { timeoutMs: 1500 });
|
|
113
142
|
}, [sessionId, channel]);
|
|
143
|
+
// ── 选中轮:列表形态(composer 不聚焦)的键盘归它 ─────────────────────
|
|
144
|
+
// 选中态存在线程 store 里(与 draft 同理:面板与全屏场景共用),快照给的
|
|
145
|
+
// selectedTurnId 已经解析过「跟最后一条」——null 只在空线程上出现。
|
|
146
|
+
const turns = thread?.turns ?? [];
|
|
147
|
+
const selectedId = thread?.selectedTurnId ?? null;
|
|
148
|
+
const selectedTurn = turns.find(turn => turn.turnId === selectedId);
|
|
149
|
+
/** ↑/↓ 移动选中(夹在两端;到底再按 ↓ 由调用方回输入框)。 */
|
|
150
|
+
const moveSelection = React.useCallback((delta) => {
|
|
151
|
+
btwThreads.moveSelection(sessionId, delta);
|
|
152
|
+
}, [sessionId]);
|
|
153
|
+
/** 点标题行:选中那一轮并离开编辑层(高亮只在列表态显示,见 listActive)。 */
|
|
154
|
+
const selectTurn = React.useCallback((turnId) => {
|
|
155
|
+
btwThreads.select(sessionId, turnId);
|
|
156
|
+
setComposerFocus(false);
|
|
157
|
+
}, [sessionId, setComposerFocus]);
|
|
158
|
+
/** 选中轮本身(读实时线程,不依赖渲染期快照)。 */
|
|
159
|
+
const selectedTurnNow = React.useCallback(() => {
|
|
160
|
+
return btwThreads.selectedTurn(sessionId);
|
|
161
|
+
}, [sessionId]);
|
|
162
|
+
/** `c` = 复制选中轮的答案(选中轮还没答案时退回「最后一条已完成」)。 */
|
|
163
|
+
const copySelected = React.useCallback(() => {
|
|
164
|
+
const turn = selectedTurnNow();
|
|
165
|
+
if (turn !== undefined && turn.answer !== '') {
|
|
166
|
+
void setClipboard(turn.answer);
|
|
167
|
+
channel.notify(t('copied-chars', { n: turn.answer.length }), { timeoutMs: 1500 });
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
copyLatest();
|
|
171
|
+
}, [selectedTurnNow, copyLatest, channel]);
|
|
114
172
|
// ── 键盘:composer 层 > 列表层 > 宿主(未消费的键返回 false)──────────
|
|
115
173
|
const onKey = React.useCallback((input, key) => {
|
|
116
174
|
if (composerFocusRef.current) {
|
|
@@ -145,25 +203,36 @@ export function BtwPanelAdapter({ width, height, focused, visible }) {
|
|
|
145
203
|
newTopic();
|
|
146
204
|
return true;
|
|
147
205
|
}
|
|
206
|
+
// 选中轮 + s/c:与 jobs 面板同一套「选中行 → 动作」契约(s 再按一次撤回)。
|
|
148
207
|
if (input === 's' && key.ctrl !== true && key.meta !== true) {
|
|
149
|
-
const
|
|
150
|
-
if (
|
|
151
|
-
|
|
208
|
+
const turn = selectedTurnNow();
|
|
209
|
+
if (turn !== undefined)
|
|
210
|
+
sendToChat(turn);
|
|
152
211
|
return true;
|
|
153
212
|
}
|
|
154
213
|
if (input === 'c' && key.ctrl !== true && key.meta !== true) {
|
|
155
|
-
|
|
214
|
+
copySelected();
|
|
156
215
|
return true;
|
|
157
216
|
}
|
|
158
|
-
//
|
|
217
|
+
// 列表键盘:↑/↓ 只挪选中——滚动交给 BtwThreadView 的「最小揭示」:目标标题
|
|
218
|
+
// 已经在视口里就一动不动,出了视口才滚到恰好露出那一行。已经在最后一条时
|
|
219
|
+
// 再按 ↓ = 回输入框(与输入框里按 ↑ 上到标题互为往返)。
|
|
159
220
|
if (key.upArrow === true) {
|
|
160
|
-
|
|
221
|
+
moveSelection(-1);
|
|
161
222
|
return true;
|
|
162
223
|
}
|
|
163
224
|
if (key.downArrow === true) {
|
|
164
|
-
|
|
225
|
+
const list = btwThreads.get(sessionId)?.turns ?? [];
|
|
226
|
+
const current = btwThreads.selectedTurn(sessionId);
|
|
227
|
+
const at = current === undefined ? list.length - 1 : list.findIndex(turn => turn.turnId === current.turnId);
|
|
228
|
+
if (list.length === 0 || at === list.length - 1) {
|
|
229
|
+
setComposerFocus(true);
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
moveSelection(1);
|
|
165
233
|
return true;
|
|
166
234
|
}
|
|
235
|
+
// 翻页仍归滚动(列表里 ↑/↓ 已经改成移动选中了)。
|
|
167
236
|
if (key.pageUp === true) {
|
|
168
237
|
scrollRef.current?.scrollBy(-(height - 6));
|
|
169
238
|
return true;
|
|
@@ -175,7 +244,7 @@ export function BtwPanelAdapter({ width, height, focused, visible }) {
|
|
|
175
244
|
// 其余不独占:返回 false 交宿主(Esc 回聊天、←/→ 切面板、1-9 跳面板)。
|
|
176
245
|
return false;
|
|
177
246
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
178
|
-
}, [sessionId, submitDraft, newTopic,
|
|
247
|
+
}, [sessionId, submitDraft, newTopic, sendToChat, copySelected, moveSelection, selectedTurnNow, height, setCaret]);
|
|
179
248
|
usePanelInput(onKey, { active: focused && visible });
|
|
180
249
|
// ── 头部(只有线程后才画):首问标题 + 状态徽 + 新话题,下压一条细线 ──
|
|
181
250
|
// 空线程不画头部:标题没有内容,`新话题` 在空线程上也无事可做(清空/换题的
|
|
@@ -187,5 +256,27 @@ export function BtwPanelAdapter({ width, height, focused, visible }) {
|
|
|
187
256
|
const budget = Math.max(6, width - 2);
|
|
188
257
|
const titleRoom = budget - stringWidth(newLabel) - stringWidth(chip) - 4;
|
|
189
258
|
const header = turnCount === 0 ? null : (_jsxs(Box, { flexDirection: "column", width: "100%", flexShrink: 0, children: [_jsxs(Box, { flexDirection: "row", width: "100%", height: 1, paddingLeft: 1, children: [_jsx(Text, { bold: true, wrap: "truncate", children: truncateWidth(title, Math.max(2, titleRoom)) }), _jsx(Box, { flexGrow: 1, flexShrink: 1, children: _jsx(Text, { children: " " }) }), chip !== '' && (_jsx(Box, { flexShrink: 0, children: _jsxs(Text, { color: busy ? 'warning' : undefined, dimColor: !busy, children: [chip, " "] }) })), _jsx(Box, { flexShrink: 0, onClick: event => { event.stopImmediatePropagation(); newTopic(); }, children: _jsxs(Text, { color: "permission", children: ["[n] ", newLabel] }) })] }), _jsx(Box, { width: "100%", height: 1, children: _jsx(Text, { dimColor: true, children: '─'.repeat(Math.max(4, width - 2)) }) })] }));
|
|
190
|
-
|
|
259
|
+
// 选中高亮 + 光标声明只在列表态出现:光标在主输入框(列没聚焦)或侧栏输入框
|
|
260
|
+
// (composer 编辑层)时都不显示——用户要的是「列表拿着键盘」这个状态的指示,
|
|
261
|
+
// 不是常驻标记。
|
|
262
|
+
const listActive = focused && visible && !composerFocus;
|
|
263
|
+
// 底栏广告按层走(层内状态只有面板自己知道,所以由面板发、宿主只拼):
|
|
264
|
+
// - 列表层:有轮才说 s/c(已附加的那一轮同一个键是撤回);
|
|
265
|
+
// - 编辑层:s/c 在输入框里只是打字,只说「↑ 回标题」;
|
|
266
|
+
// - 空线程没有可选的轮,明确广告空串(连能力位那一段也不画,免得广告一个按
|
|
267
|
+
// 下去没反应的 s);
|
|
268
|
+
// - 光标在主输入框时面板根本收不到键,整段不画。
|
|
269
|
+
const selectedAttached = selectedTurn !== undefined && attachedEntryOf(selectedTurn.turnId) !== undefined;
|
|
270
|
+
const hintText = !focused || !visible
|
|
271
|
+
? ''
|
|
272
|
+
: composerFocus
|
|
273
|
+
? t('btw-hint-edit-back')
|
|
274
|
+
: turns.length === 0
|
|
275
|
+
? ''
|
|
276
|
+
: t(selectedAttached ? 'btw-list-hint-attached' : 'btw-list-hint');
|
|
277
|
+
React.useEffect(() => {
|
|
278
|
+
panelStore.setHint('btw', hintText);
|
|
279
|
+
return () => { panelStore.setHint('btw', ''); };
|
|
280
|
+
}, [hintText]);
|
|
281
|
+
return (_jsxs(Box, { flexDirection: "column", width: "100%", height: height, overflow: "hidden", children: [header, _jsx(BtwThreadView, { thread: thread, width: width, height: Math.max(3, height - (header === null ? 4 : 6)), alive: visible, selectedTurnId: listActive ? selectedId ?? undefined : undefined, onSelectTurn: selectTurn, scrollHandleRef: scrollRef }), _jsx(BtwComposer, { state: { text: thread?.draft ?? '', caret }, focused: composerFocus && focused && visible, busy: busy, notice: notice === undefined || notice === null ? undefined : notice, onActivate: activateComposer })] }));
|
|
191
282
|
}
|
|
@@ -3,12 +3,16 @@
|
|
|
3
3
|
* 滚动、composer 追问。Esc 返回侧栏,面板状态原样(mountPolicy=enabled
|
|
4
4
|
* 不卸载,thread 与 draft 都在线程 store)。
|
|
5
5
|
*
|
|
6
|
-
* 键层级:composer 编辑(Esc
|
|
6
|
+
* 键层级:composer 编辑(Esc 收起草稿、↑ 上到标题)> 场景动作(↑/↓ 选轮、
|
|
7
|
+
* s 送聊天/撤回、c 复制)> Esc 退出场景。选中态与侧栏面板同源(线程 store),
|
|
8
|
+
* 两个形态的键位与落点逐条对齐。
|
|
7
9
|
*/
|
|
8
10
|
import React from 'react';
|
|
9
11
|
import type { ChannelUi } from '../../../adapter/channel/ui-policy.js';
|
|
10
|
-
export declare function BtwThreadScene({ channel, onClose, }: {
|
|
12
|
+
export declare function BtwThreadScene({ channel, onClose, onFocusChat, }: {
|
|
11
13
|
readonly channel: ChannelUi;
|
|
12
14
|
readonly onClose: () => void;
|
|
15
|
+
/** 送聊天之后把焦点交回主输入框(宿主没接时只关场景)。 */
|
|
16
|
+
readonly onFocusChat?: (() => void) | undefined;
|
|
13
17
|
}): React.ReactNode;
|
|
14
18
|
//# sourceMappingURL=BtwThreadScene.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BtwThreadScene.d.ts","sourceRoot":"","sources":["../../../../../src/components/sidePanel/btw/BtwThreadScene.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"BtwThreadScene.d.ts","sourceRoot":"","sources":["../../../../../src/components/sidePanel/btw/BtwThreadScene.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAA;AAQtE,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,OAAO,EACP,WAAW,GACZ,EAAE;IACD,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAA;IAC5B,iCAAiC;IACjC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAA;CAChD,GAAG,KAAK,CAAC,SAAS,CAuKlB"}
|
|
@@ -4,7 +4,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
4
4
|
* 滚动、composer 追问。Esc 返回侧栏,面板状态原样(mountPolicy=enabled
|
|
5
5
|
* 不卸载,thread 与 draft 都在线程 store)。
|
|
6
6
|
*
|
|
7
|
-
* 键层级:composer 编辑(Esc
|
|
7
|
+
* 键层级:composer 编辑(Esc 收起草稿、↑ 上到标题)> 场景动作(↑/↓ 选轮、
|
|
8
|
+
* s 送聊天/撤回、c 复制)> Esc 退出场景。选中态与侧栏面板同源(线程 store),
|
|
9
|
+
* 两个形态的键位与落点逐条对齐。
|
|
8
10
|
*/
|
|
9
11
|
import React from 'react';
|
|
10
12
|
import { Box, Text, useInput, useTerminalSize } from '../../../ui.js';
|
|
@@ -14,7 +16,7 @@ import { btwThreads } from './threads.js';
|
|
|
14
16
|
import { getBtwContextBudget, getBtwContextTurns } from '../../../tuiDisplayPrefs.js';
|
|
15
17
|
import { BtwComposer, btwComposerKey } from './BtwComposer.js';
|
|
16
18
|
import { BtwThreadView } from './BtwThreadView.js';
|
|
17
|
-
export function BtwThreadScene({ channel, onClose, }) {
|
|
19
|
+
export function BtwThreadScene({ channel, onClose, onFocusChat, }) {
|
|
18
20
|
const { columns, rows } = useTerminalSize();
|
|
19
21
|
const sessionId = String(channel.agentId);
|
|
20
22
|
const thread = React.useSyncExternalStore(btwThreads.subscribe, () => btwThreads.get(sessionId));
|
|
@@ -29,11 +31,15 @@ export function BtwThreadScene({ channel, onClose, }) {
|
|
|
29
31
|
const [notice, setNotice] = React.useState(null);
|
|
30
32
|
const scrollRef = React.useRef(null);
|
|
31
33
|
const busy = thread !== undefined && thread.activeTurnId !== null;
|
|
34
|
+
// 选中轮与侧栏面板同源(线程 store):↑/↓ 移动、s 送聊天/撤回、c 复制。
|
|
35
|
+
const turns = thread?.turns ?? [];
|
|
36
|
+
const selectedId = thread?.selectedTurnId ?? null;
|
|
37
|
+
const selectedTurn = turns.find(turn => turn.turnId === selectedId);
|
|
32
38
|
const attachTurn = React.useCallback((turn) => {
|
|
33
39
|
if (turn.phase !== 'completed')
|
|
34
|
-
return;
|
|
40
|
+
return false;
|
|
35
41
|
if (typeof channel.attachContext !== 'function')
|
|
36
|
-
return;
|
|
42
|
+
return false;
|
|
37
43
|
channel.attachContext({
|
|
38
44
|
source: 'panel',
|
|
39
45
|
sourceId: turn.turnId,
|
|
@@ -42,7 +48,42 @@ export function BtwThreadScene({ channel, onClose, }) {
|
|
|
42
48
|
});
|
|
43
49
|
const staged = channel.attachedContexts.find(entry => entry.sourceId === turn.turnId);
|
|
44
50
|
channel.notify(staged?.truncated === true ? t('btw-thread-answer-truncated') : t('btw-thread-answer-attached'), { color: 'success' });
|
|
51
|
+
return true;
|
|
45
52
|
}, [channel]);
|
|
53
|
+
/**
|
|
54
|
+
* `s` = 送聊天,再按一次 = 撤回(与侧栏面板、jobs/companion 同一契约)。
|
|
55
|
+
* 送出去之后这个整屏场景就让位:关掉场景 + 焦点交回主输入框——等价于侧栏
|
|
56
|
+
* 形态里「面板留着、焦点回到输入框」,两种形态的落点一致。
|
|
57
|
+
*/
|
|
58
|
+
const sendToChat = React.useCallback((turn) => {
|
|
59
|
+
// oxlint-disable-next-line typescript/no-unnecessary-condition -- runtime guard: partial fixture channels
|
|
60
|
+
const staged = (channel.attachedContexts ?? []).find(entry => entry.sourceId === turn.turnId);
|
|
61
|
+
if (staged !== undefined) {
|
|
62
|
+
if (typeof channel.detachContext === 'function')
|
|
63
|
+
channel.detachContext(staged.id);
|
|
64
|
+
channel.notify(t('panel-context-detached'), { color: 'success' });
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (!attachTurn(turn))
|
|
68
|
+
return;
|
|
69
|
+
onFocusChat?.();
|
|
70
|
+
onClose();
|
|
71
|
+
}, [attachTurn, channel, onFocusChat, onClose]);
|
|
72
|
+
/** 点标题行:选中那一轮并离开编辑层(高亮只在列表态显示)。 */
|
|
73
|
+
const selectTurn = React.useCallback((turnId) => {
|
|
74
|
+
btwThreads.select(sessionId, turnId);
|
|
75
|
+
setComposerFocus(false);
|
|
76
|
+
}, [sessionId]);
|
|
77
|
+
const copySelected = React.useCallback(() => {
|
|
78
|
+
const turn = btwThreads.selectedTurn(sessionId);
|
|
79
|
+
const answer = turn !== undefined && turn.answer !== ''
|
|
80
|
+
? turn.answer
|
|
81
|
+
: [...(btwThreads.get(sessionId)?.turns ?? [])].reverse().find(candidate => candidate.phase === 'completed')?.answer;
|
|
82
|
+
if (answer === undefined)
|
|
83
|
+
return;
|
|
84
|
+
void setClipboard(answer);
|
|
85
|
+
channel.notify(t('copied-chars', { n: answer.length }), { timeoutMs: 1500 });
|
|
86
|
+
}, [sessionId, channel]);
|
|
46
87
|
useInput((input, key, event) => {
|
|
47
88
|
if (composerFocus) {
|
|
48
89
|
const text = btwThreads.get(sessionId)?.draft ?? '';
|
|
@@ -80,14 +121,23 @@ export function BtwThreadScene({ channel, onClose, }) {
|
|
|
80
121
|
onClose();
|
|
81
122
|
return;
|
|
82
123
|
}
|
|
124
|
+
// ↑/↓ 只挪选中,滚动交给 BtwThreadView 的「最小揭示」(出了视口才滚)。
|
|
83
125
|
if (key.upArrow) {
|
|
84
|
-
scrollRef.current?.scrollBy(-3);
|
|
85
126
|
event.stopImmediatePropagation();
|
|
127
|
+
btwThreads.moveSelection(sessionId, -1);
|
|
86
128
|
return;
|
|
87
129
|
}
|
|
88
130
|
if (key.downArrow) {
|
|
89
|
-
scrollRef.current?.scrollBy(3);
|
|
90
131
|
event.stopImmediatePropagation();
|
|
132
|
+
const list = btwThreads.get(sessionId)?.turns ?? [];
|
|
133
|
+
const current = btwThreads.selectedTurn(sessionId);
|
|
134
|
+
const at = current === undefined ? list.length - 1 : list.findIndex(turn => turn.turnId === current.turnId);
|
|
135
|
+
// 已在最后一条:↓ 回输入框(与输入框里按 ↑ 上到标题互为往返)。
|
|
136
|
+
if (list.length === 0 || at === list.length - 1) {
|
|
137
|
+
setComposerFocus(true);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
btwThreads.moveSelection(sessionId, 1);
|
|
91
141
|
return;
|
|
92
142
|
}
|
|
93
143
|
if (key.pageUp) {
|
|
@@ -114,20 +164,16 @@ export function BtwThreadScene({ channel, onClose, }) {
|
|
|
114
164
|
return;
|
|
115
165
|
}
|
|
116
166
|
if (input === 's' && !key.ctrl && !key.meta) {
|
|
117
|
-
const
|
|
118
|
-
if (
|
|
119
|
-
|
|
167
|
+
const turn = btwThreads.selectedTurn(sessionId);
|
|
168
|
+
if (turn !== undefined)
|
|
169
|
+
sendToChat(turn);
|
|
120
170
|
event.stopImmediatePropagation();
|
|
121
171
|
return;
|
|
122
172
|
}
|
|
123
173
|
if (input === 'c' && !key.ctrl && !key.meta) {
|
|
124
|
-
|
|
125
|
-
if (latest !== undefined) {
|
|
126
|
-
void setClipboard(latest.answer);
|
|
127
|
-
channel.notify(t('copied-chars', { n: latest.answer.length }), { timeoutMs: 1500 });
|
|
128
|
-
}
|
|
174
|
+
copySelected();
|
|
129
175
|
event.stopImmediatePropagation();
|
|
130
176
|
}
|
|
131
177
|
});
|
|
132
|
-
return (_jsxs(Box, { flexDirection: "column", width: columns, height: rows, paddingX: 1, children: [_jsxs(Box, { flexDirection: "row", width: "100%", height: 1, flexShrink: 0, children: [_jsx(Text, { color: "warning", bold: true, children: t('btw-fullscreen-title') }), _jsx(Text, { dimColor: true, wrap: "truncate", children: ' ' + t('btw-scene-hints') })] }), _jsx(BtwThreadView, { thread: thread, width: columns - 2, height: Math.max(3, rows - 4), alive: true,
|
|
178
|
+
return (_jsxs(Box, { flexDirection: "column", width: columns, height: rows, paddingX: 1, children: [_jsxs(Box, { flexDirection: "row", width: "100%", height: 1, flexShrink: 0, children: [_jsx(Text, { color: "warning", bold: true, children: t('btw-fullscreen-title') }), _jsx(Text, { dimColor: true, wrap: "truncate", children: ' ' + t('btw-scene-hints') })] }), _jsx(BtwThreadView, { thread: thread, width: columns - 2, height: Math.max(3, rows - 4), alive: true, selectedTurnId: composerFocus ? undefined : selectedId ?? undefined, onSelectTurn: selectTurn, scrollHandleRef: scrollRef }), _jsx(BtwComposer, { state: { text: thread?.draft ?? '', caret }, focused: composerFocus, busy: busy, notice: notice === null ? undefined : notice, onActivate: activateComposer })] }));
|
|
133
179
|
}
|
|
@@ -7,13 +7,23 @@
|
|
|
7
7
|
* 跟尾:默认跟随尾部;用户上滚后暂停 follow,
|
|
8
8
|
* 出现「有新回答」跳尾提示(点击回底)。ScrollBox 的 sticky 位就是
|
|
9
9
|
* follow 信号——上滚打破 sticky,scrollToBottom/贴底恢复。
|
|
10
|
+
*
|
|
11
|
+
* 消息区不是控件:点它跟点面板其它地方一样,只由宿主把列焦点交给面板
|
|
12
|
+
* (见 BtwComposer 的点击注释),注入/复制的入口是选中轮 + `s`/`c`。
|
|
13
|
+
* 选中只看标题那一行:反色只覆盖标题本身的字,终端光标也声明在那儿。
|
|
14
|
+
* 选中轮滚出视口时只滚到「恰好露出这一行」:往上走贴视口顶、往下走贴视口底;
|
|
15
|
+
* 已经在视口里就只挪高亮,不动滚动位置。
|
|
10
16
|
*/
|
|
11
17
|
import React from 'react';
|
|
12
18
|
import { type ScrollBoxHandle } from '../../../ui.js';
|
|
13
|
-
import type { BtwThreadSnapshot
|
|
19
|
+
import type { BtwThreadSnapshot } from './threads.js';
|
|
14
20
|
export declare function BtwThreadView({ thread, width, height,
|
|
15
21
|
/** 渲时钟的开关(面板不可见/场景失焦时停表)。 */
|
|
16
|
-
alive,
|
|
22
|
+
alive,
|
|
23
|
+
/** 当前选中的轮(标题反色 + 光标声明);undefined = 列表没有选中态。 */
|
|
24
|
+
selectedTurnId,
|
|
25
|
+
/** 点标题行把选中挪到那一轮(继续冒泡,宿主照旧拿列焦点)。 */
|
|
26
|
+
onSelectTurn,
|
|
17
27
|
/** 宿主(全屏场景/浮层)接管键盘滚动用的句柄透传。 */
|
|
18
28
|
scrollHandleRef, }: {
|
|
19
29
|
readonly thread: BtwThreadSnapshot | undefined;
|
|
@@ -21,8 +31,8 @@ scrollHandleRef, }: {
|
|
|
21
31
|
/** 滚动区行预算(含滚动区自身;跳尾提示一行另计)。 */
|
|
22
32
|
readonly height: number;
|
|
23
33
|
readonly alive: boolean;
|
|
24
|
-
|
|
25
|
-
readonly
|
|
34
|
+
readonly selectedTurnId?: string | undefined;
|
|
35
|
+
readonly onSelectTurn?: ((turnId: string) => void) | undefined;
|
|
26
36
|
readonly scrollHandleRef?: {
|
|
27
37
|
current: ScrollBoxHandle | null;
|
|
28
38
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BtwThreadView.d.ts","sourceRoot":"","sources":["../../../../../src/components/sidePanel/btw/BtwThreadView.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"BtwThreadView.d.ts","sourceRoot":"","sources":["../../../../../src/components/sidePanel/btw/BtwThreadView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAO3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AA2DrD,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,KAAK,EACL,MAAM;AACN,6BAA6B;AAC7B,KAAK;AACL,+CAA+C;AAC/C,cAAc;AACd,mCAAmC;AACnC,YAAY;AACZ,+BAA+B;AAC/B,eAAe,GAChB,EAAE;IACD,QAAQ,CAAC,MAAM,EAAE,iBAAiB,GAAG,SAAS,CAAA;IAC9C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5C,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAC9D,QAAQ,CAAC,eAAe,CAAC,EAAE;QAAE,OAAO,EAAE,eAAe,GAAG,IAAI,CAAA;KAAE,CAAA;CAC/D,GAAG,KAAK,CAAC,SAAS,CA6JlB"}
|
|
@@ -8,12 +8,19 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
8
8
|
* 跟尾:默认跟随尾部;用户上滚后暂停 follow,
|
|
9
9
|
* 出现「有新回答」跳尾提示(点击回底)。ScrollBox 的 sticky 位就是
|
|
10
10
|
* follow 信号——上滚打破 sticky,scrollToBottom/贴底恢复。
|
|
11
|
+
*
|
|
12
|
+
* 消息区不是控件:点它跟点面板其它地方一样,只由宿主把列焦点交给面板
|
|
13
|
+
* (见 BtwComposer 的点击注释),注入/复制的入口是选中轮 + `s`/`c`。
|
|
14
|
+
* 选中只看标题那一行:反色只覆盖标题本身的字,终端光标也声明在那儿。
|
|
15
|
+
* 选中轮滚出视口时只滚到「恰好露出这一行」:往上走贴视口顶、往下走贴视口底;
|
|
16
|
+
* 已经在视口里就只挪高亮,不动滚动位置。
|
|
11
17
|
*/
|
|
12
18
|
import React from 'react';
|
|
13
19
|
import { Box, Text, ScrollBox } from '../../../ui.js';
|
|
14
20
|
import { Markdown } from '../../Markdown.js';
|
|
15
21
|
import { SpinnerGlyph } from '../../Spinner/SpinnerGlyph.js';
|
|
16
22
|
import { t } from '../../../i18n.js';
|
|
23
|
+
import { useDeclaredCursor, useNativeCursor } from '../../../ink/hooks/use-declared-cursor.js';
|
|
17
24
|
import { getBtwContextTurns, subscribeBtwContextTurns } from '../../../tuiDisplayPrefs.js';
|
|
18
25
|
/** 80ms spinner 帧(只在有 running 轮且其还没收到首段文本时走时钟)。 */
|
|
19
26
|
const SPINNER_MS = 80;
|
|
@@ -21,9 +28,36 @@ const SPINNER_MS = 80;
|
|
|
21
28
|
function BtwEmptyState({ contextTurns }) {
|
|
22
29
|
return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, paddingX: 1, children: [_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "subtle", wrap: "truncate", children: t('btw-thread-empty') }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { color: "subtle", wrap: "wrap", children: t('btw-empty-lines') }) }), _jsx(Box, { marginTop: 1, children: _jsx(Text, { dimColor: true, italic: true, wrap: "wrap", children: t('btw-thread-context-recent', { n: contextTurns }) }) })] }));
|
|
23
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* 一轮的标题行(问题)。选中 = 只反色标题本身的字(不铺满整行),并把终端
|
|
33
|
+
* 光标声明在这一行上:按 ↑/↓ 时原生光标的拖尾是「在标题之间上下走」,而不是
|
|
34
|
+
* 掉到屏幕左下角(没有声明时渲染器的兜底位置)。点这一行 = 把高亮挪过来
|
|
35
|
+
* (`onSelect`),点击继续冒泡,宿主照旧拿到列焦点。
|
|
36
|
+
*/
|
|
37
|
+
function QuestionRow({ turnId, text, selected, onSelect, onRegister }) {
|
|
38
|
+
const native = useNativeCursor();
|
|
39
|
+
// 与 ListItem 同款:移动期间可见、静止 500ms 后收起,形状/闪烁归终端。
|
|
40
|
+
const cursorRef = useDeclaredCursor({ line: 0, column: 0, active: selected, visible: native, hideOnIdle: native });
|
|
41
|
+
// 组装 ref 时必须把 cursorRef 的 cleanup 转交出去(React 19 用返回值当卸载
|
|
42
|
+
// 清理),否则这一行被删掉时光标声明会留在原地。
|
|
43
|
+
const setNode = React.useCallback((node) => {
|
|
44
|
+
const cleanup = cursorRef(node);
|
|
45
|
+
onRegister?.(turnId, node);
|
|
46
|
+
return () => {
|
|
47
|
+
if (typeof cleanup === 'function')
|
|
48
|
+
cleanup();
|
|
49
|
+
onRegister?.(turnId, null);
|
|
50
|
+
};
|
|
51
|
+
}, [cursorRef, onRegister, turnId]);
|
|
52
|
+
return (_jsx(Box, { ref: setNode, onClick: onSelect === undefined ? undefined : () => onSelect(turnId), children: _jsx(Text, { color: "accent", bold: true, inverse: selected, wrap: "wrap", children: text }) }));
|
|
53
|
+
}
|
|
24
54
|
export function BtwThreadView({ thread, width, height,
|
|
25
55
|
/** 渲时钟的开关(面板不可见/场景失焦时停表)。 */
|
|
26
|
-
alive,
|
|
56
|
+
alive,
|
|
57
|
+
/** 当前选中的轮(标题反色 + 光标声明);undefined = 列表没有选中态。 */
|
|
58
|
+
selectedTurnId,
|
|
59
|
+
/** 点标题行把选中挪到那一轮(继续冒泡,宿主照旧拿列焦点)。 */
|
|
60
|
+
onSelectTurn,
|
|
27
61
|
/** 宿主(全屏场景/浮层)接管键盘滚动用的句柄透传。 */
|
|
28
62
|
scrollHandleRef, }) {
|
|
29
63
|
const localScrollRef = React.useRef(null);
|
|
@@ -77,6 +111,60 @@ scrollHandleRef, }) {
|
|
|
77
111
|
setPendingJump(true);
|
|
78
112
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
79
113
|
}, [version, answerLengths, follow]);
|
|
114
|
+
// ── 选中轮的最小滚动揭示 ─────────────────────────────────────────────
|
|
115
|
+
// 行节点表:QuestionRow 挂载时交进来;滚动位置一律走 ScrollBox 的
|
|
116
|
+
// scrollToElement(位置在渲染期读元素 Yoga top,不会用到过期数字)。
|
|
117
|
+
const rowNodes = React.useRef(new Map());
|
|
118
|
+
const registerRow = React.useCallback((turnId, node) => {
|
|
119
|
+
if (node === null)
|
|
120
|
+
rowNodes.current.delete(turnId);
|
|
121
|
+
else
|
|
122
|
+
rowNodes.current.set(turnId, node);
|
|
123
|
+
}, []);
|
|
124
|
+
/**
|
|
125
|
+
* 节点在滚动内容里的行号(不含滚动位移):沿祖先累加 Yoga top,直到撞上滚动
|
|
126
|
+
* 容器(ScrollBox 的节点上才有 scrollTop)。没撞到(浮层回退等无滚动区形态)
|
|
127
|
+
* 返回 undefined——宁可不滚,也不要按错误的坐标系乱跳。
|
|
128
|
+
*/
|
|
129
|
+
const contentRowOf = (node) => {
|
|
130
|
+
let rows = 0;
|
|
131
|
+
let current = node;
|
|
132
|
+
while (current !== undefined && current.parentNode !== undefined) {
|
|
133
|
+
if (current.parentNode.scrollTop !== undefined)
|
|
134
|
+
return rows;
|
|
135
|
+
rows += current.yogaNode?.getComputedTop() ?? 0;
|
|
136
|
+
current = current.parentNode;
|
|
137
|
+
}
|
|
138
|
+
return undefined;
|
|
139
|
+
};
|
|
140
|
+
const previousSelectedRef = React.useRef(undefined);
|
|
141
|
+
React.useLayoutEffect(() => {
|
|
142
|
+
const previous = previousSelectedRef.current;
|
|
143
|
+
previousSelectedRef.current = selectedTurnId;
|
|
144
|
+
// 从编辑层或主输入框回列表时也要揭示:长答案跟尾后,标题可能在视口外。
|
|
145
|
+
if (selectedTurnId === undefined || previous === selectedTurnId)
|
|
146
|
+
return;
|
|
147
|
+
const handle = scrollRef.current;
|
|
148
|
+
const node = rowNodes.current.get(selectedTurnId);
|
|
149
|
+
if (handle === null || node === undefined)
|
|
150
|
+
return;
|
|
151
|
+
const viewport = handle.getViewportHeight();
|
|
152
|
+
if (viewport <= 0)
|
|
153
|
+
return;
|
|
154
|
+
const rows = Math.max(1, Math.ceil(node.yogaNode?.getComputedHeight() ?? 1));
|
|
155
|
+
const top = contentRowOf(node);
|
|
156
|
+
if (top === undefined)
|
|
157
|
+
return;
|
|
158
|
+
const scrollTop = handle.getScrollTop();
|
|
159
|
+
// 用算好的内容行号直接 scrollTo:scrollToElement 读的是元素相对**父节点**的
|
|
160
|
+
// top,标题盒子嵌在 turn 里,用它会把滚动甩到内容顶部。布局已稳定(只有选中
|
|
161
|
+
// 变了),这里的数字不会过期。
|
|
162
|
+
// 往上走出视口 → 贴视口顶;往下走出视口 → 整行贴视口底(恰好露出,不多滚)。
|
|
163
|
+
if (top < scrollTop)
|
|
164
|
+
handle.scrollTo(top);
|
|
165
|
+
else if (top + rows > scrollTop + viewport)
|
|
166
|
+
handle.scrollTo(top + rows - viewport);
|
|
167
|
+
}, [selectedTurnId]);
|
|
80
168
|
const jumpTail = React.useCallback(() => {
|
|
81
169
|
scrollRef.current?.scrollToBottom();
|
|
82
170
|
setFollow(true);
|
|
@@ -84,10 +172,7 @@ scrollHandleRef, }) {
|
|
|
84
172
|
}, []);
|
|
85
173
|
if (thread === undefined || thread.turns.length === 0)
|
|
86
174
|
return _jsx(BtwEmptyState, { contextTurns: contextTurns });
|
|
87
|
-
return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, overflow: "hidden", paddingX: 1, children: [_jsx(ScrollBox, { ref: scrollRef, flexDirection: "column", flexGrow: 1, stickyScroll: true, children: thread.turns.map((turn, index) => (_jsxs(Box, { flexDirection: "column", children: [index > 0 && _jsx(Text, { dimColor: true, children: '┈'.repeat(Math.max(4, width - 2)) }), _jsx(
|
|
88
|
-
event.stopImmediatePropagation();
|
|
89
|
-
onAttachTurn(turn);
|
|
90
|
-
}, children: _jsx(Markdown, { cacheTokens: false, children: turn.answer }) })) : turn.phase === 'failed' || turn.phase === 'cancelled' ? (_jsxs(_Fragment, { children: [turn.answer !== '' && _jsx(Markdown, { cacheTokens: false, children: turn.answer }), turn.phase === 'failed'
|
|
175
|
+
return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, overflow: "hidden", paddingX: 1, children: [_jsx(ScrollBox, { ref: scrollRef, flexDirection: "column", flexGrow: 1, stickyScroll: true, children: thread.turns.map((turn, index) => (_jsxs(Box, { flexDirection: "column", children: [index > 0 && _jsx(Text, { dimColor: true, children: '┈'.repeat(Math.max(4, width - 2)) }), _jsx(QuestionRow, { turnId: turn.turnId, text: turn.question, selected: turn.turnId === selectedTurnId, onSelect: onSelectTurn, onRegister: registerRow }), _jsxs(Box, { marginLeft: 2, flexDirection: "column", children: [turn.phase === 'completed' ? (_jsx(Markdown, { cacheTokens: false, children: turn.answer })) : turn.phase === 'failed' || turn.phase === 'cancelled' ? (_jsxs(_Fragment, { children: [turn.answer !== '' && _jsx(Markdown, { cacheTokens: false, children: turn.answer }), turn.phase === 'failed'
|
|
91
176
|
? _jsxs(Text, { color: "error", wrap: "wrap", children: [t('btw-thread-error'), turn.error === undefined ? '' : ': ' + turn.error] })
|
|
92
177
|
: _jsx(Text, { dimColor: true, italic: true, children: t('btw-thread-cancelled') })] })) : turn.answer !== '' ? (_jsx(Markdown, { cacheTokens: false, children: turn.answer })) : (_jsxs(Box, { flexShrink: 0, children: [_jsx(SpinnerGlyph, { frame: frame, messageColor: "warning" }), _jsxs(Text, { color: "warning", children: [" ", t('btw-answering')] })] })), turn.omittedOlderCount > 0 && (_jsx(Text, { dimColor: true, italic: true, wrap: "truncate", children: t('btw-thread-context-omitted', { n: turn.omittedOlderCount }) }))] })] }, turn.turnId))) }), pendingJump && !follow && (_jsx(Box, { flexShrink: 0, onClick: event => { event.stopImmediatePropagation(); jumpTail(); }, children: _jsxs(Text, { color: "permission", children: ["\u2193 ", t('btw-thread-unread')] }) }))] }));
|
|
93
178
|
}
|
|
@@ -22,6 +22,9 @@ export interface BtwThreadSnapshot {
|
|
|
22
22
|
readonly turns: readonly BtwTurn[];
|
|
23
23
|
readonly activeTurnId: string | null;
|
|
24
24
|
readonly draft: string;
|
|
25
|
+
/** 列表选中的轮(`s` 送聊天 / `c` 复制的对象);null = 跟最后一条。
|
|
26
|
+
* 与 draft 同理放在 store 里:面板与全屏场景共用同一份选中态。 */
|
|
27
|
+
readonly selectedTurnId: string | null;
|
|
25
28
|
/** seen-through 标尺之后的完成/失败轮(cancelled 不计:用户自己中止,
|
|
26
29
|
* 不是没看到的新答案)。 */
|
|
27
30
|
readonly unread: {
|
|
@@ -55,6 +58,12 @@ export type BtwSubmitResult = {
|
|
|
55
58
|
readonly ok: false;
|
|
56
59
|
readonly reason: 'empty' | 'busy' | 'congested';
|
|
57
60
|
};
|
|
61
|
+
/**
|
|
62
|
+
* 有效选中轮:钉住的 id 还在就继续用它,否则跟最后一条(新轮到达自动跟尾、
|
|
63
|
+
* 轮被清掉/换话题自动落回)。面板与全屏场景共用这一条解析,保证两个形态
|
|
64
|
+
* 的选中语义逐字一致。
|
|
65
|
+
*/
|
|
66
|
+
export declare function effectiveSelectedTurnId(turns: readonly BtwTurn[], pinned: string | null): string | null;
|
|
58
67
|
/** 钳到 1–8;非有限值取默认 4。 */
|
|
59
68
|
export declare function normalizeRecentTurnsLimit(value: number | undefined): number;
|
|
60
69
|
export interface BtwContextSelection {
|
|
@@ -97,6 +106,15 @@ declare class BtwThreadStore {
|
|
|
97
106
|
*/
|
|
98
107
|
newTopic(sessionId: string): boolean;
|
|
99
108
|
setDraft(sessionId: string, text: string): void;
|
|
109
|
+
/** 指定选中某一轮(点标题行;null = 回到跟最后一条)。 */
|
|
110
|
+
select(sessionId: string, turnId: string | null): void;
|
|
111
|
+
/** 当前选中轮(实时解析,不依赖渲染期快照)。 */
|
|
112
|
+
selectedTurn(sessionId: string): BtwTurn | undefined;
|
|
113
|
+
/**
|
|
114
|
+
* ↑/↓ 移动选中:从当前有效选中出发、夹在两端(delta = ±1)。落点即钉住,
|
|
115
|
+
* 所以移动之后不再跟尾;返回新选中轮(线程为空 = undefined)。
|
|
116
|
+
*/
|
|
117
|
+
moveSelection(sessionId: string, delta: number): BtwTurn | undefined;
|
|
100
118
|
/** 看到最新线程:把已落定轮全部记为已读(running 轮落定时再见分晓)。 */
|
|
101
119
|
markSeen(sessionId: string): void;
|
|
102
120
|
/** 测试/多夹具隔离用:清空全部线程状态。 */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"threads.d.ts","sourceRoot":"","sources":["../../../../../src/components/sidePanel/btw/threads.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"threads.d.ts","sourceRoot":"","sources":["../../../../../src/components/sidePanel/btw/threads.ts"],"names":[],"mappings":"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"}
|