# dsh-navbar

> 给 DSH 对话页右缘加一条节点导航条，悬停看预览、点击跳转，支持滚动切换、加载更早历史和按会话精选消息。

## Metadata

- Author: [@vlln](https://github.com/vlln)
- Repo: <https://github.com/vlln/dsh-navbar.git>
- GitHub: [vlln/dsh-navbar](https://github.com/vlln/dsh-navbar)
- Stars: 50
- Language: TypeScript
- License: [MIT](https://spdx.org/licenses/MIT.html)
- Topics: `dsh`, `dsh-plugin`, `plugin`, `ui`
- Forks: 2
- Open Issues: 1
- Last push: 2026-08-20T22:20:54.000Z
- Added: 2026-08-13T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:vlln/dsh-navbar
```

## Wiki

## 一句话定位
给 DSH 对话页右缘加一条节点导航条：每条 user 消息对应一个圆点，悬停看消息预览，点击或滚动滚轮快速跳转到对应消息，并支持把某条 assistant 回复钉成「精选」方便回访。

## 核心能力
- 在对话区右缘渲染一条纵向节点串，每条 user 消息对应一个圆点；激活圆点（22px 品牌蓝胶囊）随当前阅读位置自动移动
- 悬停节点立即显示消息预览卡，显示对应消息气泡文本前 6 行（沿用官方 HoverCard 视觉，整条导航条含间隙都连续响应）
- 点击节点、点击导航条任意位置，或光标在导航条上滚动滚轮（阻止对话区滚动），都会平滑滚动到对应消息
- 节点超过 11 个时自动切到滑动窗口（激活 ±5），两端用更小圆点暗示还有更多；当前选中或精选的节点始终强制可见
- 顶部 ↑ 按钮在会话还有未加载的更早历史时出现：点击转发给官方「加载更早」控件，自动保持当前阅读位置；全部加载完后按钮自动隐藏
- assistant 消息操作条新增 📌 按钮（位于 copy 与 Good response 之间），点击把该回复钉为精选；对应节点变成金色细长椭圆盘，状态按会话存到浏览器本地，点击直达被精选的回复

## 技术实现
- **语言**: TypeScript（client bundle 由 tsdown 产出 CJS，浏览器通过 `window.__ModuleLoader__` 加载）
- **关键依赖**: `@deepseek-ai/cordis`（peerDependency）、`@deepseek-ai/dsh-client-ui-primitives`、`react`（仅 PinAction 按钮组件使用）
- **架构模式**: 官方 bundle 插件形态（`dsh.bundle` + dshClient 通道）。Node half（`src/index.mjs`）为空 `apply`，仅作为 bundle 挂载载体；所有行为都在浏览器端 `src/client/index.ts`（自渲染 DOM + 官方锚点契约）。零数据通道依赖，只读官方锚点属性（`data-time-hover-root`、`data-chat-flow`、`data-turn-tail`、`data-pending-steering`）驱动，不发请求、不注册工具、不改路由
- **入口文件**: `src/client/index.ts`（浏览器端）、`src/index.mjs`（Node half 空 apply）

## 适用场景
对话很长、来回翻找某一条 user 消息太慢时，用右缘节点条一眼定位、直接跳过去；想标记一条关键回复以后回访，用 📌 把它钉成精选节点；历史窗口还没加载完时，用顶部 ↑ 按钮边加载边定位，不用滚回顶部。

## 前置依赖与兼容性

| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH | >= 0.1.0-rc.5 | 通过 `package.json#engines.dsh` 声明；依赖官方 0806+ 在 user 行加入的 `data-time-hover-root` 锚点属性 |
| Node.js | >= 22.19.0 | 仅构建时需要（`tsdown` 打包脚本），运行时由浏览器加载 `lib/client.js` |
| 平台 | 跨平台 | 作为 DSH Web 端的浏览器内 UI 插件工作，操作系统无限制；不支持 DSH 桌面端（Node half 为空） |
| 原生模块 | 无 | 不引入任何原生依赖 |
| React | 18.x | client 端 PinAction 按钮组件由宿主注入 React |

## 安装方式
```bash
dsh plugin --profile web add github:vlln/dsh-navbar
```

## 配置项
本插件无需额外配置。无需命令行参数、无需 `cordis.yml` 配置、无需设置面板开关；安装重启 web profile 后自动生效。

## 常见问题

**Q: 安装后需要手动开启吗？**

A: 不需要。插件被 web profile 加载后自动在对话页生效；安装完重启 web profile 即可。在设置页「插件」面板可以停用或重新启用。

**Q: 节点条在哪些页面会显示？**

A: 仅在 Chat 视图（也兼容挂载的聚焦会话视图 `dsh-focus-chat`）的对话页显示；设置页等其他页面，以及 user 消息少于 2 条时自动隐藏。

**Q: 精选消息会跨设备同步吗？**

A: 不会。精选状态按会话存到浏览器 localStorage（键名 `dsh-navbar:pins:<sessionId>`），刷新后保留，但不跨设备、不跨浏览器同步。

**Q: 节点超过 11 个时会怎样？**

A: 自动切到滑动窗口：只显示当前激活附近的 11 个节点（±5），两端用更小的圆点暗示还有更多；当前选中或精选的节点始终强制显示在窗口内，不会因为窗口滑动而看不见。

**Q: 顶部 ↑ 加载更早历史按钮什么时候出现？**

A: 仅当当前会话还有未加载的更早消息时出现（由官方「加载更早」控件的存在判定），全部加载完后按钮自动隐藏；加载过程中按钮禁用并显示「加载中…」。

**Q: 卸载插件会清除精选数据吗？**

A: 不会。数据存在浏览器 localStorage，卸载插件或重启 DSH 不会自动清理；要清理就在浏览器开发者工具里删除 `dsh-navbar:pins:*` 开头的键。

**Q: 跳转后为什么有时位置会跳动一下？**

A: 插件按官方 follow 0811 之后的「读者输入账本」判定直接一步定位。0811 之前的基线版本（0808/0810）会先用 wheel 事件做兼容兜底，可能与官方流式渲染产生轻微抖动。

## 上手难度
入门 — 装上即用，无命令、无工具、无配置项；唯一可选交互是悬停/点击节点，或点击 📌 钉选消息。

## 已知问题与限制
- 仅支持 DSH Web 端，Node half 为空（`src/index.mjs` 仅 `export default function apply() {}`），不提供任何宿主侧能力
- 依赖官方 `data-time-hover-root` 行属性锚点；若官方 DOM 结构变更需同步适配（README 提到该属性自官方 0806 版本起加在 user 行上）
- 跳转适配官方 follow 的读者输入判定 0811 账本机制；旧版本（0808/0810）保留 wheel dispatch 兜底
- 节点条位置紧贴对话流列右缘 + 12px，钳制在视口内；当侧边栏折叠动画或窗口宽度变化使对话流列位置剧烈变化时，可能偶发位置抖一帧（已用 ResizeObserver + rAF 节流合并）
- 「加载更早历史」按钮转发给官方 `ChatView` 的 `loadOlderAnchored` 控件；若官方按钮结构或位置变更，本插件的定位逻辑需同步适配

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [dsh-navbar](https://deepseek-plugin.org/plugins/vlln/dsh-navbar)
Wiki generated by AI (model: `MiniMax-M3`)
