Vai al contenuto principale
X

dsh-user-question-nav

xiaomujiang/dsh-user-question-nav

Barra di navigazione delle domande in stile ChatGPT con pulsanti freccia su/giù — segni di spunta per ogni domanda sul bordo della chat, cassetto che si apre al passaggio del mouse elencando tutte le domande dell'utente con filtro di ricerca in tempo reale, salto con scorrimento fluido in un clic ed evidenziazione della domanda attiva sincronizzata con la posizione di scorrimento.

Installazione

dsh plugin --profile web add github:xiaomujiang/dsh-user-question-nav

README

dsh-user-question-nav

ChatGPT 风格的问题导航插件:在 DeepSeek Harness 对话区域右侧显示一个胶囊轨道,包含双箭头(⏫⏬)和刻度尺(tick marks),悬停停留 1 秒后自动展开贴边抽屉目录,列出全部用户问题,点击即可跳转。

核心功能

功能行为
胶囊轨道对话区右侧浮动的纵向轨道,包含上下箭头 + 刻度线(每条刻度对应一个用户问题)
悬停停留鼠标悬停在刻度区域 持续 1 秒后,贴边抽屉自动滑出,展示全部问题列表
快速扫过鼠标快速扫过刻度区域(少于 1 秒)不会打开抽屉,避免误触
进度条反馈悬停期间刻度区域底部出现蓝色进度条,1 秒填满后展开抽屉(无反馈的等待会让 UI 感觉卡顿)
贴边抽屉从对话区右缘内侧滑出的面板,包含搜索框 + 全部问题目录,每行显示 序号 · 问题原文
搜索过滤在抽屉顶部搜索框输入关键词,实时筛选问题列表,计数文案从「共 N 条」切换为「筛出 N 条」
一键跳转点击抽屉中的任意行 → 对话平滑滚动到对应问题(居中显示)
刻度同步滚动对话时,胶囊上的刻度自动跟随:当前问题刻度高亮为品牌蓝色,鼠标悬停的刻度加深
边界提示到达第一条/最后一条问题时,对应箭头变灰但仍可点击;点击时弹出气泡提示「已经是第一个问题」/「已经是最后一个问题」,1.5 秒自动消失
会话切换切换对话时分两步:旧滚动容器断开 → 自动回退默认位置 → MutationObserver + 轮询双通道等待新容器 → 重新挂载校准
位置漂移补偿文本区可能因上方面板折叠/展开而整体位移(自身尺寸不变),低频定时器(1s)检测并自动校准轨道/抽屉位置

交互合约

操作结果
鼠标在刻度区域停留 ≥ 1 秒抽屉打开,进度条填满
快速扫过 / 提前离开抽屉不打开
点击抽屉中任意行跳转到对应问题
悬停 / 点击 ⏫⏬ 箭头永不触发抽屉展开;直接跳转
抽屉打开时点击箭头箭头仍可点击(轨道 z-index 高于抽屉),抽屉保持打开
到达边界时点击已变灰的箭头弹出气泡提示,不跳转
在搜索框输入关键词实时过滤,计数文案切换为「筛出 N 条」
清空搜索框恢复全部行,计数文案切回「共 N 条」
切换会话自动重新挂载到新对话容器

安装

方式一:从 npm 一键安装(推荐)

要求:已安装并运行过一次 DeepSeek Harness Desktop

dsh plugin --profile desktop add dsh-user-question-nav

完成后 Cmd+Q 退出 DSH Desktop,重新打开。

方式二:从源码安装(开发者)

适合修改源码、二次开发:

git clone git@github.com:xiaomujiang/dsh-user-question-nav.git
cd dsh-user-question-nav
pnpm install && pnpm build
./install-user-question-nav.command
# Cmd+Q 退出 DSH Desktop,重新打开

升级

dsh plugin --profile desktop add dsh-user-question-nav@latest

完成后重启 DSH Desktop。

卸载

dsh plugin --profile desktop remove dsh-user-question-nav

效果预览

v0.2.0 预览 — 胶囊轨道 + 刻度 + 贴边抽屉

截图展示:右侧胶囊轨道(⏫ 双箭头 + 8 条刻度 + ⏬ 双箭头),鼠标悬停 1 秒后贴边抽屉展开,搜索框 + 8 行问题目录,第 4 条高亮为当前问题。

实现原理

挂载策略

apply()立即创建完整 DOM(轨道 + 抽屉)并挂载到 document.body,不等待对话区域出现。默认定位在视口右侧中间,然后异步查找对话滚动容器 ([data-conversation-scroll]),找到后自动校准位置到对话区右侧边缘。

刻度布局

  • PITCH_MAX (13px) / PITCH_MIN (4px):刻度中心距的上限和下限
  • 问题数少时用大间距,问题数多时压缩到最小 4px
  • 压缩触发条件:rail 可用高度 / 问题数量 < PITCH_MAX
  • 目标间距优先保证排在 rail 可用高度 之内;超出时才逐级压缩

导航逻辑

  1. 通过 [data-chat-flow-kind="user"] 选择器定位所有用户消息
  2. 消息中心位置(而非顶部)判断跳转目标,避免连续点击时选中同一消息
  3. scrollTo({ behavior: 'smooth' }) 平滑滚动到视口中间

当前问题识别 (updateCurrent)

  1. 已经滚到底部 → 最后一条就是当前
  2. 否则找「最后一个已经滚到视口上方的消息」(top ≤ 视口 top)
  3. 一条都没滚过去(在顶部)→ 第一条可见的消息

会话切换

  • MutationObserver 监听 body 变化,检测 scrollport 的 isConnected 状态
  • 旧 scrollport 断开 → 尝试重新查找 → 找到新容器自动挂载 → 没找到则重启轮询
  • 同时观察 [data-chat-flow]childList,消息增删时重建刻度/行

位置漂移

对话区域可能在不改变自身尺寸的情况下整体位移(上方出现横幅、面板折叠等),ResizeObserver 无法捕获这种情况。低频定时器(1 秒间隔)比对矩形位置,漂移超过 0.5px 则自动校准。

边界反馈

遵循项目「雷区.md #6」的既定决策:箭头到达边界时只变灰、不 disable。禁用按钮会让用户以为功能已坏。变灰按钮仍可点击,点击时弹出气泡提示。

图标区分

使用双箭头(⏫⏬)而非单箭头,与 DSH 自带的「回到底部」按钮(↓)明确区分。

开发

pnpm install        # 安装依赖
pnpm build          # 构建
pnpm typecheck      # 类型检查

端到端自检

# 在浏览器中打开 test/harness.html(需先 pnpm build)
open test/harness.html
# 或命令行无头执行(需要 Chrome):
# 参考 test/harness.html 内注释的 Chrome headless 命令

结构

dsh-user-question-nav/
├── dsh.plugin.json        # DSH 插件清单
├── package.json           # npm 包元数据 + dsh.client 配置
├── cordis.patch.yml       # 挂载声明
├── tsconfig.json          # TypeScript 配置
├── tsdown.config.ts       # 构建配置(host + 两个 client bundle)
├── install-user-question-nav.command  # 一键安装脚本
├── docs/
│   └── screenshot-v0.2.0.png  # 效果预览
├── design/
│   ├── rail-live-proto.html    # 交互原型(3 种模式切换)
│   ├── README.md               # 设计迭代记录
│   └── ...
├── test/
│   ├── harness.html            # 端到端自动检验(33 条断言)
│   └── preview.html            # 真实产物视觉预览
└── src/
    ├── index.ts           # Host 端(空壳)
    ├── invariant.ts       # 不变量
    └── client/
        └── index.ts       # 客户端逻辑(轨道 + 抽屉 + 导航)

版本历史

v0.2.0

  • 新增:胶囊轨道 + 刻度尺,每一条刻度对应一个用户问题
  • 新增:贴边抽屉目录,悬停停留 1 秒展开,搜索过滤 + 一键跳转
  • 新增:悬停进度条,停留 1 秒填满后展开(用户可见的等待反馈)
  • 新增:当前问题刻度高亮(蓝色),悬停刻度加深(深灰)
  • 改进updateCurrent 算法重写("滚到上方"判定 + 二分 + 底部兜底)
  • 改进:位置漂移低频兜底(ResizeObserver 盲区补偿)
  • 改进:会话切换恢复轮询,MutationObserver + 定时器双通道
  • 变更:按钮交互从 disabled 改为 data-dim + 气泡提示(遵循雷区.md #6)
  • 测试:33 条端到端自动检验全部通过

v0.1.3 及更早

  • 双箭头浮动按钮(⏫⏬)
  • 消息中心导航 + 平滑滚动
  • 会话切换自动重挂载
  • DSH-better-sidebar 风格挂载策略

参考项目

贡献

欢迎提 Issue 和 PR!

PR 流程

git checkout dev
git checkout -b feat/your-feature    # 或 fix/your-bugfix
# ... 修改代码 ...
git commit -m "feat: 你的功能"
git push -u origin feat/your-feature
# 在 GitHub 上创建 PR → base: dev
# review 通过后合并到 dev
# 稳定后从 dev 合并到 main 发版

许可

MIT

Plugin correlati