DeepSeek Harness plugin

dsh-message-minimap

用户消息导航条插件:在 DeepSeek Harness Web GUI 会话聊天窗左侧显示一条迷你导航条(minimap),用刻度标出每一条用户消息的位置,悬停预览消息摘要,点击/拖动即可快速跳转定位。

Jump to install

Source facts

Repository
AFAP/dsh-message-minimap
Latest update
Aug 22, 2026
Category
Memory
GitHub stars
1
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/AFAP/dsh-message-minimap
Plugin: dsh-message-minimap
Author: AFAP

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer3 files
README.mdSource · read only

用户消息导航条 · Message Minimap

<div align="center"> <b>中文</b> · <a href="README.en.md">English</a> </div>

> 在 DeepSeek Harness Web GUI 会话聊天窗的左边缘显示一条迷你导航条:每一条你发送的消息都是刻度,悬停看摘要,点击即跳转,拖动可快速扫读长会话。

![License: MIT](LICENSE)

---

1. 它解决了什么问题

长会话里想回看"我之前是怎么说的"时,只能一路滚轮硬翻。AI 的回复往往又长又密,自己发过的消息被埋在中间很难找。

本插件在聊天窗左边缘加一条细导航条(类似 VS Code 的 minimap):

聊天滚动窗 (overflow-y: auto,长会话分页加载)
  │  每条用户消息 = 一个刻度(含未加载的历史,来自会话日志)
  │  视口内的消息刻度 = 加粗高亮
  │
  ▼  悬停刻度 → 预览卡片(第几条 / 共几条 + 消息摘要 + 时间行)
  ▼  点击刻度 → 平滑滚动到该消息(未加载的先自动向上翻页)
  ▼  点击/拖动轨道 → 按比例跳转

只读:客户端只读取浏览器中已渲染的会话 DOM(聊天节点带有稳定的 data-chat-flow-kind / data-chat-flow-key 锚点),滚动的是既有的聊天滚动容器;宿主半部只新增一个只读路由 GET /api/message-minimap-messages,从会话日志($DSH_HOME/sessions)提取全量用户消息的摘要(每条最多 140 字符 + 时间戳),用于覆盖"加载更多"还没渲染的历史刻度。不修改、不删除任何文件。

2. 功能特性

  • ✅ 聊天窗左侧一条紧凑居中的导航条(不铺满全高),不干扰布局。
  • 每条用户消息一个刻度,在刻度列上均匀分布(上旧下新),不随消息长短散开。
  • 长会话分页也不怕:刻度覆盖全部用户消息(含"加载更多"未渲染的历史,数据来自会话日志);点击未加载的刻度会自动向上翻页,加载到后平滑跳转(按消息 id 精确对齐,中间页即使不含用户消息也不会中断)。
  • 跳转精确:刻度与消息按日志中的消息 id 双向关联(DOM 锚点 data-chat-flow-key 内嵌该 id),不再依赖"DOM 是全长列表尾部"的位置假设——API 时序、插队/分岔消息、加载页不含用户消息都不会导致跳偏。
  • 当前视口内的消息刻度自动加粗高亮,随滚动实时更新。
  • 鼠标扫过刻度列时鱼眼放大:指针下的刻度变得最长,邻近刻度按距离渐次微长(余弦衰减 + CSS 过渡),一眼定位。
  • 悬停刻度弹出预览卡片:我的消息 · 3 / 12 + 消息文本摘要(最多 140 字符、7 行)+ 独立时间行。
  • 点击刻度平滑滚动到该消息(停靠在视口上方约 18% 处)。
  • 点击/按住拖动轨道背景按比例跳转,像滚动条一样快速扫读。
  • ✅ 流式输出、加载历史、切换会话、窗口缩放时自动跟随(MutationObserver + scroll/resize + 轮询兜底)。
  • ✅ 内容未溢出、无用户消息、或在新会话引导页时自动隐藏,不干扰布局。
  • ✅ 中英双语界面文案,跟随界面语言。
  • ✅ 键盘可达:刻度是原生 <button>,可 Tab 聚焦后回车跳转。

MVP 暂不支持:不标注 AI 消息/错误/分支;不做按文本搜索刻度;不做持久化开关(始终自动显示/隐藏)。

效果预览

悬停刻度:预览卡片(摘要 + 独立时间行)
![悬停刻度预览](screenshot/rail-hover.png)

3. 目录结构

dsh-message-minimap/   # 仓库根 = npm 包根
├── package.json            # dsh.bundle.patch + dsh.client(浏览器端声明)+ exports["./client"]
├── cordis.patch.yml        # 组合行:仅插入一行插件记录(无路由、无配置)
├── LICENSE                 # MIT
├── screenshot/             # 效果截图(README「效果预览」用)
└── lib/
    ├── index.js            # 宿主半部:/api/message-minimap-messages(读会话日志 → 全量用户消息摘要,零依赖)
    └── client.js           # 浏览器 bundle:导航条(conversation.session.header.utilities 挂载)

4. 快速开始

一键安装(GitHub):

dsh plugin --profile web add github:AFAP/dsh-message-minimap

然后重启 dsh web 生效。

> 安装后插件位于 $DSH_HOME\profiles\web\node_modules\dsh-message-minimap(pnpm 从 GitHub 克隆),与源码仓库位置无关。

升级:

dsh plugin --profile web update dsh-message-minimap

卸载:

dsh plugin --profile web remove dsh-message-minimap

从源码目录手动安装(等价验证用)

dsh plugin --profile web add "D:\path\to\dsh-message-minimap"

验证是否加载成功

打开一个有多条往返消息、内容已溢出可滚动的会话 → 聊天窗左边缘出现一条带刻度的细条,悬停刻度能看到消息摘要即可。

5. 使用

1. 打开任意历史会话(或聊到内容超过一屏)。 2. 看聊天窗左侧居中的导航条:每个小刻度是你发过的一条消息当前在视口内的消息刻度会加粗高亮。 3. 悬停刻度:右侧弹出预览卡,显示"我的消息 · n / 总数"与消息开头内容。 4. 点击刻度:平滑滚动到那条消息;若它还没被"加载更多"渲染出来,会自动向上翻页加载后再跳转。 5. 点击或按住拖动刻度以外的轨道:按比例跳转(等价于滚动条拖拽)。 6. 会话太短(不足一屏)、没有用户消息、或在空白新会话页时,导航条自动隐藏。

6. API 速查

GET /api/message-minimap-messages?sessionId=<sessionId>
  • 需要浏览器信任围栏通过(loopback / trustedHosts + 同源校验),否则 403
  • 未知 sessionId 返回 404;缺失 sessionId 返回 400
  • 只返回摘要:每条消息的 seq、稳定消息 id、 epoch 时间、最多 140 字符的折叠摘要、是否含图片;不返回完整内容,不返回其他类型记录。

响应示例:

{
  "total": 14,
  "messages": [
    { "seq": 7, "id": "msg_2xj9k…", "time": 1786975510788, "text": "我需要你参考 …", "image": true }
  ]
}

7. 实现要点

关注点做法
锚点来源会话包给每个聊天节点渲染 data-chat-flow-kind / data-chat-flow-key 的稳定包裹层;用户消息 kind 为 "user";分页列带有 data-chat-flow
全量数据宿主半部读会话日志(session.jsonl / .zstd,按帧解压、容忍写入中的残帧),只保留 source.kind === "user"user/message 记录;按 (size, mtime) 缓存。每条记录额外返回日志消息 iddata.id)。
分页对齐API 行 ↔ DOM 节点按消息 id 关联:用户气泡的 flow key 形如 <长度>:input-message<id>,客户端从中解析出 id 后与 API 行精确配对——刻度是否已加载只取决于该 id 是否出现在 DOM 中,与数量无关。点击未加载的刻度时循环拉取上一页(优先会话级 conversation.loadOlder() 服务,兜底点"加载更多"按钮),以目标 key 是否出现为进度信号(一页 50 条事件里没有用户消息也不会误判为无进展),直至目标进入 DOM 平滑跳转、分页按钮消失、或达到页数上限;无 id 的旧宿主自动回退到位置对齐。
降级宿主路由不可达(403/404/网络)时自动退回"仅已加载消息"刻度,即纯 DOM 模式。
滚动容器从第一个可见 flow item 向上找最近的 overflow-y: auto/scroll 祖先;导出布局(data-conversation-scroll,不滚动)下自动隐藏。
几何映射刻度列紧凑居中(间距固定 10px,高 ≈ min(10px × 数量 + 28px, 窗高 × 0.55)),刻度按序号均匀分布;拖动轨道时按比例换算滚动位置;消息内容偏移只用于跳转目标与"视口内"判定。
数据同步MutationObserver(childList/subtree/characterData,覆盖流式输出)+ 容器 scroll + ResizeObserver + 1s 轮询兜底(应对迟挂载/会话切换),rAF 节流 + 浅比较避免渲染抖动;全量列表 5s 轻量拉取(宿主按 mtime 缓存)。
挂载点conversation.session.header.utilities 槽位(活动会话常驻),组件本身只渲染 position: fixed 的轨道,无内联占位。
样式与官方包一致地注入 <style data-plugin-css>,全部使用 DSW 主题变量,自动适配明暗主题。

8. 日志与排错

现象排查方向
看不到导航条确认已重启 dsh web;会话需已有用户消息且内容可滚动;F12 Console 搜 dsh-message-minimap
刻度只覆盖最近一段宿主路由未生效:Network 里查 /api/message-minimap-messages403=信任围栏、404=会话未找到);路由不可达时插件会降级为只显示已加载段。
点击早期刻度没跳转0.4.3 起按消息 id 精确跳转:插件会自动向上翻页(每秒重试触发一次,跨越不含用户消息的页)直到目标消息出现;若历史耗尽仍不存在(分岔/已删除消息),会停在原地不跳偏。放弃时 Console 会输出 [dsh-message-minimap] 警告——设 localStorage.dmm.debug=1 后重载复现,可拿到完整翻页日志。
刻度位置偏移偶发的图片/附件异步加载会改变高度——MutationObserver 会自动校正;若持续异常,滚动一下或缩放窗口触发重算。
点击不跳转检查是否在导出/打印式布局(data-conversation-scroll)下——该布局无内部滚动容器,插件自动隐藏。
样式异常确认主题变量(--dsw-*)存在;本插件不自带配色,全部跟随 DSW 主题。

9. 安全与合规

  • 只读:不修改 DOM 业务结构、不拦截事件(除自身轨道)、不修改/删除任何文件;宿主只读会话日志。
  • 路径红线:会话日志$DSH_HOME/sessions 下的会话 id 编码段定位,绝不接受客户端传来的路径;id 单段转义,杜绝目录穿越。
  • 浏览器信任围栏/api/message-minimap-messages 仅接受 loopback 或声明 trustedHosts 的同源请求,拒绝 sec-fetch-site: cross-site 与 Origin 不同的请求。
  • 信息最小化:只返回每条用户消息的 seqid、时间、最多 140 字符摘要与图片标记;不返回完整内容、不返回其他类型记录。
  • 无持久化:不写 localStorage / cookie;卸载即无痕。

10. 开发与构建

纯 JS 无构建步骤。lib/index.js 宿主半部零外部依赖(仅 node: 内置);lib/client.js 是经典脚本(window.__ModuleLoader__.load),由 client 模块系统按 /plugins/dsh-message-minimap/client.js 直接服务。

11. License

MIT © AFAP