dsh-conv-search(对话内文本搜索)
English | 中文
为 DeepSeek Harness Web 界面提供对话内文本搜索——把你熟悉的 Ctrl+F 限定在当前对话中。浮动搜索栏会高亮渲染出的对话记录中的每一处匹配,并支持在匹配之间跳转,全程不改动 Harness 核心代码的任何一行。
解决的问题
- 长对话无法搜索:浏览器原生查找会搜遍整个页面(侧边栏、输入框、界面元素),且无法跟随仍在流式输出的对话。本插件只搜索当前对话的滚动区域,并在模型持续输出时保持同步。
- 无法在匹配之间跳转:原生查找没有「第 n / 共 total 个」的导航。本插件提供 Enter / Shift+Enter 与上一个/下一个按钮,支持循环跳转,并自动将当前匹配滚动到视野中央。
- 高亮不能与 React 冲突:对话 DOM 由 React 管理,流式输出期间持续重渲染。插件不采用包裹
<mark>节点的方式(那会改动 React 管理的文本节点、破坏协调机制),而是通过 CSS Custom Highlight API 绘制高亮——一种覆盖层绘制,能安然度过每一次重渲染,且无需任何 DOM 清理。
功能特性
- Ctrl/Cmd+F 打开浮动搜索栏(仅在对话已渲染时接管——否则浏览器原生查找不受影响);Esc 随时关闭,即使焦点仍在输入框内。
- 跨所有已渲染的聊天节点进行匹配:用户消息、助手文本、工具卡片、翻页加载的历史记录。两个切换按钮对齐浏览器/IDE 查找栏习惯:Aa(区分大小写)与 ab(全词匹配)——搜索错误码、函数名、API 标识符时必不可少。
- 实时
n / total计数,Enter(下一个)/ Shift+Enter(上一个)导航,支持循环;F3 / Ctrl+G 同样可用,与浏览器/IDE 查找栏习惯一致。 - 搜索历史:ArrowUp / ArrowDown 循环浏览最近的查询词(最新在前、去重),回退越过最新一条时会恢复你正在输入的草稿。
- 零结果查询会给出回应:计数变红、搜索栏边框随之变红、并给出一次性抖动(遵循
prefers-reduced-motion)。在无结果时反复按 Enter 会重新抖动,而非毫无反应。 - 当前匹配以更强的颜色绘制,并自动滚动进入视野。
- 头部操作按钮会镜像打开状态(
aria-pressed),你随时能知道搜索是否处于激活状态。 - 流式感知:MutationObserver 在输出流式进行或加载更早分页时(防抖后)重新搜索,且不会抢占你的滚动位置。当前匹配按身份(文本节点 + 偏移)锚定,因此翻页加载的更早内容或流式增量不会把光标跳到另一处匹配。
- 范围约束:输入框区域与插件自身的搜索栏被排除在外,你正在输入的草稿不会产生幽灵匹配。
- 通过
--dsw-alias-*设计令牌跟随 Harness 主题;根据文档语言自动切换中/英文界面。 - 对话头部操作按钮(搜索图标)通过
conversation.session.header.actions插槽注册——可叠加、可安全卸载的组合方式。
安装
需要 Node.js ≥ 22 与 pnpm(npm install -g pnpm)——dsh plugin add 通过 pnpm 把 bundle 装入 profile。
一键安装
dsh plugin add beijingwahw/dsh-conv-search --profile web
dsh web # 重启服务以加载插件> 常用进阶命令:升级 dsh plugin upgrade dsh-conv-search --profile web;卸载 dsh plugin remove dsh-conv-search --profile web;本地路径安装 dsh plugin add ./dsh-conv-search --profile web。
包内声明了 dsh.bundle.patch(挂载宿主注册行)与 dsh.client(在 /plugins/<id>/client.js 提供浏览器端)。lib/ 已提交,因此 GitHub tarball 无需构建步骤即可安装。
验证挂载:
dsh --profile web --dump-config | grep conv-search使用
| 操作 | 行为 |
|---|---|
Ctrl/Cmd+F(或头部搜索图标) | 打开搜索栏 |
| 输入 | 边输入边搜索(120 ms 防抖) |
Enter / F3 / Ctrl/Cmd+G | 下一个匹配(循环) |
Shift+Enter / Shift+F3 / Ctrl/Cmd+Shift+G | 上一个匹配(循环) |
ArrowUp / ArrowDown | 浏览历史查询词 |
Aa / ab 按钮 | 区分大小写 / 全词匹配 |
Esc | 关闭并清除所有高亮 |
工作原理
src/client/engine.ts—— 纯 DOM 辅助函数:文本节点遍历、不区分大小写的区间匹配、CSS.highlights绘制(dsh-conv-search绘制全部匹配,dsh-conv-search-active绘制当前匹配)、滚动定位。不依赖 cordis、不依赖 React——可针对 jsdom 做单元测试。src/client/controller.ts—— 浮动搜索栏(纯 DOM 实现,不与外壳的 React 版本耦合)、键盘捕获、防抖搜索、以及让高亮在流式输出期间保持正确的对话 MutationObserver。src/client/index.ts—— cordis 客户端半边:通过ctx.effect安装控制器,并通过ctx.slots.inject('conversation.session.header.actions', ...)注册头部操作按钮,使按钮随插槽声明与插件 fiber 的出现与消失而同步。src/index.ts—— 宿主半边是空的注册外壳;全部行为都在浏览器端。
模型体验
无。插件只在浏览器中读取已渲染的对话记录;不触碰任何提示词、消息、schema、流、工具或模型请求。
开发
pnpm install
pnpm run typecheck # 严格 TS,不产出
pnpm run build # tsdown:宿主 ESM + 浏览器客户端包;tsc 生成声明
pnpm test # vitest (jsdom):engine、controller、i18n客户端包强制执行 Harness 的纯净性规则:平台模块(react、cordis、已注入的客户端包)保持为 external,任何其他 @deepseek-ai/* 值导入都会导致构建失败。
已知限制与后续计划
- 匹配仅支持纯文本——不支持正则、不支持变音符号归一化、不支持跨节点短语匹配(被样式 span 拆开的短语无法命中)。
- 需要浏览器支持 CSS Custom Highlight API(Chrome/Edge 105+、Safari 17.2+、Firefox 132+)。在不支持的浏览器上,搜索栏仍会计数匹配,但不绘制高亮。
- 搜索栏位置固定(
top: 64px; right: 24px),暂不可拖拽。 - 搜索范围仅限当前对话列——侧边栏对话标题与设置页面有意排除在外。
排障
dsh plugin add时报'pnpm' 不是内部或外部命令→ 先安装 pnpm:npm install -g pnpm。dsh web报EADDRINUSE ... :3080→ 上一个dsh web仍占用端口。在其终端按 Ctrl+C 停掉;Windows 可用Get-NetTCPConnection -LocalPort 3080 | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force },或换端口启动:dsh web --port 3081。
许可证
MIT