在使用 DeepSeek Harness (DSH) web 版进行长对话开发时,快速定位特定提问位置、回溯对话上下文是一个常见痛点。官方 deepseek.com 网页版通过右侧的「问题条」解决了这个问题。
下面介绍的 dsh-question-rail 插件复刻了这一体验。它会在对话界面的右侧边缘生成一条竖向的问题栏,常态下收起为窄列小横线,鼠标靠近时向右展开,列出当前会话每一轮的用户提问,点击后平滑滚动定位到对话对应位置。
插件简介¶
dsh-question-rail 是一个 DSH web 插件,由开发者 LeonSone 维护,开源协议为 MIT。
该插件主要解决以下问题:
* 快速定位:无需手动滚动长对话即可跳转到任意提问轮次。
* 上下文概览:在对话栏收起或展开状态下,都能快速识别当前会话的提问列表。
* 视觉一致性:模仿官方界面风格,提供透明的主题适配。
核心功能¶
插件具备以下技术特性:
-
单次渲染,两种状态
展开与收起状态使用同一组 DOM 元素(.qrl_item)。收起时仅显示右侧的竖线标记;鼠标悬停时通过 CSS 展开面板,显示完整问题文本。两者共享相同的样式和间距。 -
跳转到任意轮次
点击问题条中的任意一条,对话会平滑滚动到对应的提问位置。该位置由data-chat-anchor-key锚点标识,并伴随高亮环闪烁。 -
仅对话视图
插件通过读取当前会话的view状态进行渲染门控。它只在与view === "chat"匹配时显示,在「轨迹」、「上下文」、「Design」、「PPT」或空主页视图时自动隐藏。 -
完整历史加载
DSH 的会话历史是分页窗口化的(hasMore)。该插件会自动循环调用session.loadOlder(),直到hasMore === false,从而列出所有轮次的提问,而非仅当前窗口内的内容。 -
性能优化
- 仅订阅当前会话(
useSessions选择current)。 - 使用渲染签名(question set + active view)而非整个
ConversationSnapshot,避免在流式输出或工具调用时触发不必要的重渲染。 - 实现了跳过打字和稳定的处理程序。
- 仅订阅当前会话(
-
主题与可访问性
- 主题感知:面板文本及悬停详情框跟随
body[data-ds-dark-theme]变化。暗色模式下文字为白色,亮色模式下文字为黑色。面板本身透明,无卡片或边框。 - 键盘支持:每个问题项均为
role="button",支持tabIndex=0,可通过 Enter 或 Space 键触发。
- 主题感知:面板文本及悬停详情框跟随
安装与启用¶
插件通过 DSH 的包管理机制安装。
dsh plugin --profile web add github:LeonSone/dsh-question-rail
安装后,该包会被添加到 dsh.profile.bundles。由于插件声明了 dsh.bundle,它会被自动包含在构建中。
注意:新安装的客户端包需要重启
dsh web或无头运行器。重启后,请刷新浏览器(Cmd/Ctrl+Shift+R)以加载新包。
使用方法¶
启用后,在聊天界面中操作:
- 展开/收起:将鼠标移动到对话区域的右侧边缘,问题条会从竖线展开为列表。
- 查看文本:鼠标悬停在列表中的某一项上,左侧会浮现一个详情框,显示完整的问题文本(最大高度 50vh)。
- 跳转定位:点击列表中的问题,对话流会自动平滑滚动至该提问处,并高亮显示。
- 视图适配:切换到非对话视图(如轨迹、PPT 等)时,右侧边缘的问题条会自动消失。
技术实现要点¶
- 节点半部分:
lib/index.js为空,仅包含一个空的apply()函数。这是为了满足 Cordis 加载器的发现机制,确保dsh-client-modules能发布客户端资源。 - 浏览器半部分:
lib/client.js通过window.__ModuleLoader__.load注册,并在apply(ctx)中注入到shell.overlay插槽。 - 数据源:直接读取
ConversationSnapshot.nodes,提取user或steering类型的轮次,并映射到聊天锚点key。
生态链接¶
- GitHub 仓库:https://github.com/LeonSone/dsh-question-rail
- 技能目录:https://www.skillhub.cn/plugins/LeonSone/dsh-question-rail
该插件属于 DSH 插件生态,与 DeepSeek 或幻方公司无官方从属关系。