前言¶
在 DeepSeek Harness(DSH)里用侧边栏找历史对话时,很多人会发现:输入关键词后,往往只能匹配会话标题或工作区名,很难搜到某条 user/assistant 消息里的具体内容。这不是 UI 没做「内容搜索」,而是默认 bundle 里全文索引未打开,且官方 FTS5 对连续中文分词效果很差。下面介绍社区插件 dsh-plugin-session-fulltext,它用字面子串扫描替代 FTS,并补上点击结果后的定位、高亮与会话内上一个/下一个导航。
这是什么¶
dsh-plugin-session-fulltext 由 henrytunwang 维护,归类为客户端插件(一个包同时提供 Host 半与浏览器半)。定位是:在 DSH 侧边栏对当前 surface 的 user/message 与 assistant/message 做大小写不敏感的字面子串检索(literal substring),支持中文短词命中;点击搜索结果可滚到命中处并高亮,并在会话内用胶囊控件在全部命中间循环跳转。
- 目录页:https://www.skillhub.cn/plugins/henrytunwang/dsh-plugin-session-fulltext
- 源码与说明:https://github.com/henrytunwang/dsh-plugin-session-fulltext
- 许可证:MIT(见仓库
package.json) - 引擎要求:
dsh>=0.2.1-rc.2 <0.3.0
为什么需要它:DSH 自带搜索的两层逻辑¶
DSH 侧边栏搜索由两部分组成(见 @deepseek-ai/dsh-client-ui-workspace):
- 即时本地匹配:对标题与工作区名做子串匹配,所以常见感受是「只搜会话名称」。
- 250ms 防抖后的内容搜索:经
sessions.search→@deepseek-ai/dsh-api-session-controller→ctx.sessionQuery.searchSessions。
内容搜索依赖 @deepseek-ai/dsh-session-query-sqlite 的全文索引。base / web bundle 默认配置为:
- id: session-query-sqlite
config:
path: ':memory:'
openAt: never # 全文搜索被关闭
此时内容搜索会失败;客户端按设计静默忽略失败的内容搜索,元数据匹配仍可见,于是表现为「搜不到消息正文」。若把 openAt 改为 first-search 以启用官方 FTS5,分词器为 unicode61:连续中文常被当成一个 token,例如文档「今天我们来讨论全文搜索的实现方案」下,MATCH '全文搜索' 与 MATCH '搜索' 在 SQLite 3.51 实测均为 0 命中。
本插件不启用 FTS,而是在同一 service 上只替换 searchSessions,用内存中的字面子串扫描检索消息正文,其余读取、标题、trace、filterEvents 等能力保持不变。
核心功能¶
Host 侧:索引与查询¶
- 索引范围:
user/message+assistant/message,仅当前 surface(与api-session-controller过滤一致);tool 类事件不参与。 - 缓存:按 Session 缓存文档;live 会话用
session.seq判断失效,纯持久化会话只读一次。 - 预热:激活后默认
warmupDelayMs(2500ms)起后台逐 Session 建缓存并出让事件循环;README 实测 164 个会话、约 10.3M 字符约 8s 建完,内存约 30–40MB。 - 查询:每次搜索重新列会话(约几十 ms),再在内存子串扫描;同规模实测单次约 25–45ms。未预热的会话按需加载,刚启动即搜也能出结果(首次较慢)。
- 排序:命中次数多者优先 → 文档时间新者优先 → 会话创建时间新者优先;每会话取最佳文档生成最长
snippetChars(默认 240)字符的 snippet。 - 查询语义:不支持正则、分词或模糊匹配;多词以空格分隔时为 AND 语义。搜索被取消时沿用 DSH 的
AbortSignal语义。
浏览器侧:点击揭示与命中导航¶
lib/client.js 补全侧边栏缺失的跳转能力:
- 点击搜索结果后自动翻历史加载命中,滚到第一个命中并标黄(CSS Custom Highlight API),对应 turn 行闪一次描边。
- 会话右上角浮出
n / m 上一个 下一个 ×胶囊,可在本会话所有命中间循环;Esc或×关闭并清除高亮;切换会话或新搜索时自动收起。 - 点击结果后保留搜索框与结果列表(官方行为会清空),便于连续点下一条。
- 搜索框占位符改为「搜索会话名称与内容」;已归档行与 Unarchive 按钮不触发跳转。
- 页面加载后健康检查会在
~/.dsh/session-fulltext.log写入一次search "dsh-fulltext-client-probe"。
本插件不修改官方 session-query-sqlite 配置,保持 openAt: never 即可。
安装与启用¶
README 给出的 Desktop profile 安装示例(本地 link: 路径需按你本机插件目录替换):
dsh plugin --profile desktop add link:/Users/le.su/wtdshwkspace/dsh-plugins/session-fulltext
该命令会:
- 在
~/.dsh/profiles/desktop/package.json的dependencies里记录对应link:...; - 将
dsh-plugin-session-fulltext追加到dsh.profile.bundles; - Host 侧经 profile HMR 热更即可;首次安装或合并
dsh.client声明后需重启一次 App,以便 Web 组合把lib/client.js纳入浏览器 boot graph。之后改浏览器端代码可由dsh-client-hmr热替换。
package.json 中 dsh.bundle.patch 挂 Host 侧行,dsh.client 与 exports["./client"] 供 Web 组合加载客户端模块。
配置¶
在 bundle 的 cordis.patch.yml 里为插件行传参:
| 字段 | 默认 | 说明 |
|---|---|---|
debug |
false(示例 patch 可为 true) |
向 $DSH_HOME/session-fulltext.log 追加激活/预热/搜索日志 |
warmupDelayMs |
2500 |
启动后多久开始后台预热 |
snippetChars |
240 |
snippet 长度上限 |
types |
['user/message','assistant/message'] |
建索引的事件类型 |
调试日志路径:~/.dsh/session-fulltext.log。
典型用法¶
- 安装并重启 App 后,在侧边栏搜索框输入要找的字面串(中文短词如「合同」「飞书」「搜索」,或英文/代码片段如
session、HUMAIN)。 - 在结果列表中点击某条会话,视图会滚到首个命中并高亮;用右上角胶囊「上一个 / 下一个」在本会话内跳转。
- 在浏览器控制台可手动验证揭示逻辑:
__dshSessionFulltext.reveal('合同')
关闭与卸载¶
- 临时关闭:在 profile patch 里将
session-fulltext行设为disabled: true,或从dsh.profile.bundles移除并删除依赖。 - 卸载命令:
dsh plugin --profile desktop remove dsh-plugin-session-fulltext
适用场景与注意¶
适合:会话较多、需要按消息正文(尤其中文子串)检索历史,并希望在会话内快速定位与高亮命中的 DSH Desktop 用户。
已知限制(来自 README):
- 纯内存缓存,App 重启后需重新预热;启动后立刻搜索会边搜边建缓存。
- 每次查询会调用
listSessions,会话数量极大时耗时会线性增加。 - 仅索引当前 surface 的 user/assistant 消息。
安全与权限:插件以当前 DSH 进程权限运行,可读取会话内容与写入日志。安装前请自行审阅 GitHub 仓库 源码与 MIT 许可证;社区目录 SkillHub 为独立生态站点,与 DeepSeek / 幻方无官方从属关系。
结尾¶
dsh-plugin-session-fulltext 针对 DSH 默认「标题可搜、正文难搜」与官方 FTS 对 CJK 不友好的现状,用字面子串扫描与会话内导航补齐侧边栏全文检索体验。需要进一步了解安装细节、配置项与客户端行为时,请以仓库 README 为准: