magicOF2/dsh-turn-marks
DSH web UI plugin: Claude Code / Codex style turn-marks strip on the left edge of the conversation - one bar per user message, click to jump, hover for preview, active bar turns white.
Listed
1
Ui
Bundle verified
Preview
What it does
Left-edge turn-marks strip in chat: one bar per user message, click to jump to that message, hover for a preview, active bar turns white.
Best for
- Users navigating long DSH conversations with many user turns.
- Workflows that benefit from jumping directly to a prior user message and previewing it on hover.
- Users who want the active turn marker to follow manual scrolling.
Not ideal for
- Short conversations where direct scrolling is already sufficient.
- Users seeking markers for assistant messages as well; the strip represents user messages only.
- Non-Web DSH clients; this is a browser-side UI enhancement.
README
📌 dsh-turn-marks
会话左侧消息标记条 · Turn Marks for DSH Chat — 为 DeepSeek Harness Web UI 增加 Claude Code / Codex 桌面端同款「左侧消息条条」:每发一条消息就多一根小条, 点击跳转到该消息,悬停预览内容,当前消息对应的条条变白。
✨ 特性 / Features
- 每段一条:你在会话里每发送一条消息(用户消息 / turn),左侧就多一根灰色小条
- 密集排列:条条间距紧凑(上限 24px),消息少时聚拢在轨道中部,消息多时自适应填满,方便点选
- 点击跳转:点任意一根条条,会话框平滑滚动,让那条消息对齐视口最上方(内容不足时尽可能靠上并完整显示下方内容)
- 选中变白:点击过的(以及当前正显示在视口里的)条条变成白色,其余保持灰色
- 悬停预览:鼠标悬停在条条上,弹出气泡显示该条消息的时间与内容预览(前 180 字)
- 跟随滚动:手动滚动会话时,白色条条会自动跟随当前视口内的消息
- 零配置:纯浏览器端插件,无 Host 逻辑、无外部依赖、无网络请求
- 主题友好:颜色全部使用 DSH 主题 CSS 变量,浅色 / 深色模式自动适配
-
增量挂载:注册在
conversation.input.dock槽位,不替换任何原生组件,卸载干净
🎯 界面位置 / Where it lives
条条悬浮在对话内容区左边缘(消息流与窗口左缘之间的空隙),纵向等距排列, 像一根滚动条轨道一样贯穿整个会话高度:
┌────────────┬────────────────────────────────────────────┐
│ 侧边栏 │ 💬 会话标题 [对话] [轨迹] │
│ ├────────────────────────────────────────────┤
│ │ │
│ ▍ │ 第一条消息…… │
│ ▍ │ 回复 │
│ ▍ │ 第二条消息…… │
│ ▍ │ 回复 │
│ │ │
│ │ ┌──────────────────────────────────────┐ │
│ │ │ 输入框 │ │
│ │ └──────────────────────────────────────┘ │
└────────────┴────────────────────────────────────────────┘
📦 安装 / Installation
方式一:从 GitHub 安装(推荐给其他用户)
dsh plugin --profile web add https://github.com/magicOF2/dsh-turn-marks.git
方式二:本地开发 / 自用(链接方式)
git clone https://github.com/magicOF2/dsh-turn-marks.git ~/.dsh/external/dsh-turn-marks
dsh plugin --profile web add link:C:/Users/<你的用户名>/.dsh/external/dsh-turn-marks
⚠️ 安装后需要重启
dsh web,并在浏览器里 Ctrl+Shift+R 强制刷新一次。 之后插件随 GUI 自动加载,无需任何手动启用。
🖱️ 使用 / Usage
- 打开任意会话,发送几条消息 → 对话左侧出现对应数量的灰色小条
- 点击任意一条 → 会话平滑滚动到那条消息,条条变白
- 悬停任意一条 → 弹出该消息的预览气泡(编号 + 时间 + 内容前 180 字)
- 手动上下滚动 → 白色条条自动跟随视口内当前的消息
🔧 工作原理 / How it works(技术设计)
难度评估:低。这是一个纯前端(浏览器端)的增量 UI 插件,约 200 行代码, 不需要 Host 逻辑、不需要后端、不需要持久化。核心就是「数据 + 定位 + 交互」三件事。
1. 数据来源:会话快照(Conversation Snapshot)
插件挂载在 conversation.input.dock 槽位(会话输入区上方的一个增量行)。
该槽位的 owner 会传入 session: ConversationSnapshot(每次会话快照变化都会
自动重新渲染),因此插件无需任何订阅/轮询即可拿到实时数据:
- 用户消息 =
session.nodes中kind === 'user'的节点(UserMessageNode) - 每个节点含
seq(序号)、time(时间戳)、content(内容块数组)
2. 定位:稳定 DOM 锚点 + 滚动数学
会话界面(dsh-client-ui-conversation)渲染时带有稳定的数据标记:
| 标记 | 含义 |
|---|---|
[data-conversation-scroll] |
会话的滚动容器(scrollport) |
[data-chat-flow-kind="user"] |
每一条用户消息行 |
[data-composer-seat] |
底部输入区座位(用于计算条条轨道底部) |
- 条条轨道是
position: fixed的悬浮条,贴住 scrollport 左缘; 用ResizeObserver+resize事件重新测量几何,保证窗口/布局变化后仍对齐 -
视图守卫:
MutationObserver(rAF 节流)监视 scrollport 的子节点变化, 只有检测到[data-chat-flow-kind="user"]聊天行时才显示条条 —— 保证首条消息渲染后立即出现,且在「轨迹」等非聊天视图下自动隐藏 -
密集排列:条条按中心距 ≤
BAR_SPACING(24px)排列——消息少时紧凑聚拢 (整簇在轨道内垂直居中),消息多时间距自动收缩填满整条轨道; 每根条条有 20×20px 的点击热区(可见的 4×14px 圆点居中),好点、好悬停 -
点击跳转:
row.getBoundingClientRect().top - port.getBoundingClientRect().top得到该消息在 scrollport 内的偏移,滚动目标为min(max(0, scrollTop + offset - TOP_MARGIN), scrollHeight - clientHeight)—— 消息对齐视口顶部(留 8px 边距);若下方内容不足以填满视口, 则钳制到最大滚动位置,让消息尽可能靠上、下方内容完整可见
3. 交互:白条跟随 + 悬停预览
- 点击:跳转并把该条标记为 active(变白)
-
滚动跟随:监听 scrollport 的
scroll事件(rAF 节流),找到视口顶部附近 的用户消息行,把它的条条置为白色 —— 手动滚动时白条自动同步 -
悬停预览:从
content块中提取文本(type: 'text'取text,图片显示[图片]),截断到 180 字,用固定定位气泡显示在条条右侧
4. 主题与生命周期
- 颜色全部使用 DSH 主题变量(
--dsw-alias-label-primary/secondary/tertiary、--dsw-alias-bg-overlay、--dsw-alias-border-l2),深浅色自动适配 - 包级
<style>由插件自建自删;槽位注册随插件 stop 自动移除,无残留
🧪 测试 / Testing
纯逻辑(条距、聚簇居中、滚动目标钳制、预览提取)被抽成 _internals 纯函数,
可用 Node 直接对真实 bundle 代码跑单元测试(无需浏览器):
node test/logic.test.js
覆盖内容:previewOf(文本拼接 / 图片标记 / 截断 / 空白折叠)、spacingOf
(密集上限 / 多消息收缩)、clusterTopOf(垂直居中 / 不越界)、barTopOf
(递增 / 在轨道内)、scrollTargetOf(顶部对齐 / 负值钳制 / 底部钳制)。
运行时行为在开发环境验证过:槽位 conversation.input.dock 增量注册
(dyn/tmks-1 · turn-marks · order 30 · active),与原生 todo/goal/queue 条目共存,
无渲染错误;切换「轨迹」视图时条条自动隐藏(聊天行不存在)。
🧩 已知限制 / Known limits
- 条条只统计已加载窗口内的用户消息(加载更早历史后条条数会自动增加)
- 非聊天视图(如「轨迹」)下条条自动隐藏
- 点击跳转依赖消息行已渲染;加载更多历史时若行尚未出现,点击无效果(下次快照变化后恢复)
🧩 兼容性 / Compatibility
- DeepSeek Harness
0.1.0-rc.6及以上(开发环境验证版本),Cordis4.x - 现代浏览器(Chrome / Edge / Firefox / Safari 最新两个大版本)
- 纯前端实现,不依赖任何 API Key、无数据上传
🛠️ 开发 / Development
dsh-turn-marks/
├── lib/
│ ├── index.js Host 入口(空实现,仅占位 —— 纯前端插件)
│ └── client.js 浏览器端 bundle(__ModuleLoader__ 格式)
├── test/
│ └── logic.test.js 纯逻辑单元测试(node test/logic.test.js)
├── cordis.patch.yml profile 组合层插入条目
├── package.json 包清单(dsh.bundle / dsh.client 声明)
├── README.md
└── LICENSE MIT
本地迭代:
# 改完 lib/client.js 后,重启 dsh web + 浏览器强制刷新即可验证
git add -A && git commit -m "your change" && git push # 同步到 GitHub
可调参数(lib/client.js 顶部常量):
| 常量 | 默认 | 含义 |
|---|---|---|
GUTTER_INSET |
6 |
条条轨道距 scrollport 左缘的像素 |
GUTTER_TOP |
16 |
轨道顶部内边距 |
BAR_SPACING |
24 |
条条中心距上限(密集排列) |
HIT_SIZE |
20 |
单根条条的点击热区(px) |
BAR_HEIGHT |
14 |
单根条条可见高度(px) |
TOP_MARGIN |
8 |
点击跳转后消息距视口顶部的边距 |
PREVIEW_MAX |
180 |
预览截断字数 |
📄 License
English
A lightweight DSH (DeepSeek Harness) web plugin that adds a Claude Code / Codex desktop style “turn marks” strip to the left edge of the conversation: one small gray bar per user message (turn). Click a bar to smooth-scroll the chat to that message and turn it white; hover a bar to see a preview of that message (number, time, first 180 chars). The white bar also follows your manual scrolling automatically.
Highlights: no host logic · theme-aware (DSH CSS variables) · mounts
additively in the conversation.input.dock slot (nothing shipped is replaced) ·
pure front-end (~200 lines) · standard dsh.bundle plugin package, loads
automatically after install (no manual enable).
Install:
dsh plugin --profile web add https://github.com/magicOF2/dsh-turn-marks.git
Then restart dsh web and hard-refresh the browser once.
Frequently Asked QuestionsFAQ
Use the verified command dsh plugin --profile default add github:magicOF2/dsh-turn-marks in a DSH-enabled shell. The command resolves the public package metadata and keeps the plugin attached to the catalog identity shown on this page.
Compatibility follows the bundle and profile status shown above. If a profile is not detected, keep the plugin disabled there and check the repository documentation before enabling it in production.
The GitHub link and activity metadata are the source of truth for releases and maintenance. Revisit this page after a new release to confirm the catalog has observed the latest version.