wuzehao888
dsh-plugin-message-nav
DSH web plugin: left-side message navigation rail — one numbered tick per user message, click to jump, hover preview, scroll-follow highlight, auto-loads full history
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 16, 2026
- Updated
- Aug 16, 2026
Introduction
dsh-plugin-message-nav
左侧消息导航轨道插件(DSH Web 客户端插件)。
功能
- 在会话消息区左侧渲染一条垂直导航轨道,高度按刻度内容动态自适应 (最高为消息区高度的 1/3)且垂直居中,上下带 4px padding、 圆角浅灰背景;刻度较多放不下时轨道内部可滚动(隐藏滚动条)浏览全部刻度;
- 每条用户消息一个刻度,刻度上显示消息序号(数字);
- 打开会话即自动加载全部历史:会话窗口默认只拉取尾部一页(50 条),
插件会循环调用
session.loadOlder()(每页 50 条)直到hasMore === false, 让轨道一次性列出会话中的所有用户消息,无需手动点击"加载更早"; - 点击刻度:平滑滚动消息区,跳转到该条用户消息;
- 悬停刻度:浮层预览该条消息的文本内容;
- 跟随滚动高亮:当前视口内最近的用户消息刻度高亮(主题色)。
结构
dsh-plugin-message-nav/
├── package.json # dsh.client 声明(platform: web)+ exports
└── lib/
├── index.js # host 侧 loader 条目(无 host 行为)
├── invariant.js # invariant 伴生插件
└── client.js # 浏览器 bundle:shell.overlay 条目
浏览器 bundle 是手写的 window.__ModuleLoader__.load({ id, factory }) CJS
工厂,无需构建步骤;依赖只取平台 seed 词(react)。
实现要点
- 挂载点:
shell.overlay(frame 级悬浮层,root 作用域,list 槽,点击 穿透默认关闭,条目 opt-in 指针事件); - 数据源:
ctx.sessions.binding(current)?.session(SessionFace=ObservableSnapshot<ConversationSnapshot>),用useSyncExternalStore订阅;用户消息按chat.order中kind === 'user' | 'steering'过滤; - 刻度定位:轨道高度动态 = 刻度数 × 间距(
TICK_SPACING = 26px)+ 上下 padding(RAIL_PADDING = 4px),封顶为滚动容器高度 × 1/3 (RAIL_HEIGHT_RATIO),垂直居中,左缘留RAIL_LEFT_INSET = 4px; 刻度按固定间距等距排列在轨道内容里,内容超出轨道可视高度时轨道内部滚动 (overflow-y: auto,隐藏滚动条),当前高亮刻度自动保持可见(scrollTo跟随); - 跳转:对滚动容器
scrollTo({ top, behavior: 'smooth' }); - 高亮:滚动监听 + 顺序查找视口顶部最近的用户消息;
- 自动加载:effect 观察
snapshot.hasMore / loadingOlder / openState,在会话 打开且仍有更早历史时调用session.loadOlder();以窗口首个锚点 seq 是否 前进来判断分页是否推进,未推进(失败)即停止,避免死循环。
安装
方式一:通过 dsh plugin 命令(推荐)
# 在 web profile 中安装本插件(pnpm 可用时)
dsh plugin --profile web add dsh-plugin-message-nav
# 在 profile 的 cordis.patch.yml 注册 dsh.client 行
# - insert:
# - id: message-nav
# name: 'dsh-plugin-message-nav'
方式二:本地链接(无 pnpm 环境)
# 1. 链接插件包到 profile 的 node_modules
ln -s <repo>/dsh-plugin-message-nav ~/.dsh/profiles/web/node_modules/dsh-plugin-message-nav
# 2. 在 profile 的 cordis.patch.yml 注册 dsh.client 行
# - insert:
# - id: message-nav
# name: 'dsh-plugin-message-nav'
# 3. 重启 web 服务器(patch 热更新在无 --expose-internals 时不可用)
dsh --profile web
重启后刷新浏览器页面,会话消息区左侧即出现导航轨道。
开发期修改 lib/client.js 后由 client-hmr 自动热更新,无需重启。
许可证
已知限制
- 仅当会话处于 chat 视图且存在用户消息时显示;
- 轨道固定在滚动容器左侧边缘,不随会话 header/composer 的几何变化重新 吸附(窗口 resize 与容器尺寸变化会重新测量);
- 自动加载会拉取整个会话历史,超长会话会产生多次分页请求。