Back to home

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)?.sessionSessionFace = ObservableSnapshot<ConversationSnapshot>),用 useSyncExternalStore 订阅;用户消息按 chat.orderkind === '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 自动热更新,无需重启。

许可证

MIT

已知限制

  • 仅当会话处于 chat 视图且存在用户消息时显示;
  • 轨道固定在滚动容器左侧边缘,不随会话 header/composer 的几何变化重新 吸附(窗口 resize 与容器尺寸变化会重新测量);
  • 自动加载会拉取整个会话历史,超长会话会产生多次分页请求。