@240xu/dsh-session-search

中文文档
0.1.11发布于 2026/10/21MITES Module零依赖近 30 天下载 1864

DSH网络插件:在所有持续会话日志(用户/助手/系统消息)上进行跨会话全文搜索. 以 $DSH HOME/cache/ session- search (0 write to ~/.dsh/ sessions) 为缓存的递增的 mtime+大小索引, 独立的 HTML 面板页面, 有栅栏的 HTT

中文使用文档
文档目录11 节
  1. 端点
  2. Agent 工具
  3. 安装
  4. 索引与性能取舍
  5. 权威依据与取舍(读了什么 → 采纳/拒绝)
  6. 已知重复(待 suite 聚合层收口)
  7. 开发
  8. License
  9. v0.1.4
  10. 0.1.5 · Bug 猎场修复(P1 毒化 + P2)
  11. 0.1.6 · 未来代际前视(P2)

@240xu/dsh-session-search

DSH web 插件:跨会话全文搜索。对 ~/.dsh/sessions 下全部会话日志(多帧 zstd,v3 格式)建立消息级全文索引,一条关键词查回所有历史会话的命中位置 (sessionId + seq ±60 字符窗口摘录)。

  • 零 npm 依赖(node:zlib zstd + 纯 JS);
  • 对 ~/.dsh/sessions 零写入:索引缓存是唯一写点,存 $DSH_HOME/cache/session-search/index.json(原子写 tmp+rename);
  • 侧边栏零触碰:无任何 sidebar 注册面,UI 是独立面板页 /api/session-search/panel(devkit 装了可由 Ctrl+K 命令指向该 URL);
  • 信任围栏硬门槛:全部路由先过 isTrustedApiRequest(回环 Host 挡 DNS rebinding + sec-fetch-site: cross-site 拒绝 + Origin 同源校验), 与 dsh-message-ops 0.2.1 同款(arch-review L4/L5 教训)。

端点

方法路径说明
GET/api/session-search?q=&limit=20&project=<slug 可选>跨会话搜索;大小写不敏感子串(indexOf,防 ReDoS);命中按会话 mtime 新→旧
GET/api/session-search/panel独立 HTML 面板页(搜索框 + 结果列表 + 「复制定位」)
POST/api/session-search/refresh手动触发增量刷新(Content-Type 必须 application/json)

Agent 工具

session_search(peer @deepseek-ai/dsh-tools,容错注册——tools 服务缺失或 包不可解析时只跳过工具,HTTP 面不受影响):参数 q(必填)、limit(1-100)、 project(slug 过滤)。输出每行 [slug] title/id seq N (type): snippet,定位符 在前、摘录在后(见「权威依据」节)。

安装

# 方式一:独立安装(推荐先这样试)
dsh plugin --profile web add @240xu/dsh-session-search

# 方式二:随聚合包安装(会带入本插件及另外三个插件 + 官方 Inspector)
dsh plugin --profile web add @240xu/dsh-plugin-hub

装完重启 dsh web。独立安装与聚合包安装可以共存,浏览器 UI 只显示一份; 宿主侧可能出现一行 already registered 警告,工具只保留一份,属已知噪音。

索引与性能取舍

  • 索引条目 = 每条 user/assistant/system message 的 {seq, type, text(截 500 字符)}; tool/call 与空文本不入索引(工具调用文本噪声大且无对话语义)。
  • 增量判定:会话日志 mtimeMs + size 与缓存一致 → 跳过;变更/新增重扫该会话; 消失的会话从缓存移除。
  • 检索:大小写不敏感 indexOf 线性扫描内存数组(按 mtime 新→旧的会话序遍历, 满 limit 即停)。本地规模(数千会话 × 数百条消息)亚秒级,未做倒排/分词。
  • 首次全量构建:逐帧解压每 8 帧 setImmediate 让出事件循环(大会话不冻结 GUI)。

权威依据与取舍(读了什么 → 采纳/拒绝)

  1. node:sqlite vs JSON 索引 — Node 22.5+ 内建 node:sqlite(DatabaseSync, Node v26 SQLite 文档)。拒绝迁移: 本插件索引是单进程、单对象(≤几 MB)的轻量投影,tmp+rename 原子写已满足 一致性;而检索核心是 CJK 子串匹配,SQLite FTS 默认分词器不处理 CJK 子串 (trigram tokenizer 需要额外配置且索引体积 ×3),换 schema 反而偏离「零依赖、 可整包删缓存」的目标。采纳路径:若未来语料涨到十万级消息或需要相关性 排序,再迁 node:sqlite(FTS5 + trigram),接口 SessionIndex.search() 不变。
  2. worker_threads — Node Worker threads 文档 建议 CPU 密集 JS 出主线程。暂缓:索引构建的耗时大头是 zstd 同步解压 + JSON.parse,已用帧间 setImmediate 让出(每 8 帧一次)把 GUI 卡顿压到帧级; worker 化的收益(彻底零阻塞)要付出每会话一次结构化克隆的序列化成本与 worker 生命周期管理,在「首次构建 < 数秒」的本地规模下不成比例。采纳阈值: 真实语料首次全量构建 > 5s 时再出 worker(readSessionFileAsync 的让出粒度 参数已预留调优空间)。
  3. snippet 策略 — Tavily Search Best Practices: 面向查询的短片段(chunks)优于整页摘要;max_results 过高反而稀释质量 (→ 本插件 limit 钳制 1-100、默认 20)。采纳:±60 字符窗口 + 首尾 … 的 query-aligned 摘录。Anthropic long-context prompting / Contextual Retrieval: 相关内容置于上下文前部、给出来源引用。采纳:工具输出与面板条目都是 「定位符(slug/session id/seq)在前、摘录在后」,让模型/用户先拿到 citation 再读内容;agent 多轮检索的 dedupe 思路(Tavily [...] 分隔符合并唯一内容) 留作工具输出的后续优化。

已知重复(待 suite 聚合层收口)

与生态其它插件存在有意复制(保持插件自包含、不跨包 import),待 @240xu/dsh-plugin-hub 聚合层提供共享工具后收口(agg-researcher L3 建议):

  • src/fence.js 的 isTrustedApiRequest ≡ dsh-message-ops ops-core.js 同款 (arch-review 要求的上线硬门槛,复制是安全侧的选择);
  • src/session-file.js 的多帧 zstd 帧扫描/读取 ≡ dsh-message-ops session-file.js、 dsh-session-lazy-view frames.js(同源实现,帧魔数扫描的取舍三处一致);
  • messageText(message 事件 → 首个非空 text 块)与 dsh-message-ops 重复。

开发

npm test            # 33 个零依赖测试(node --test,含围栏 403/415 与增量跳过)
node --check src/*.js

License

MIT

v0.1.4

  • 命中项新增「在 Timeline 打开」按钮:直达 lazy-view 时间线深链 /lazyview?session=<id>&seq=<seq>(lazy-view ≥0.3.0)。
  • 主搜索按钮触控目标提升至 ≥44×44px(.acts 辅助钮 36px 下限)。
  • 搜索请求飞行中按钮 disabled(含失败恢复),防重复点击。

0.1.5 · Bug 猎场修复(P1 毒化 + P2)

  • [P1] refresh 被 rejected promise 永久毒化:async IIFE 首个 await 前同步抛出 (如缓存目录被占位 → saveCache mkdirSync 抛)时,内层 finally 的 scanning=null 先于赋值执行,随后 rejected promise 永久挂上 → 索引/搜索 500 到进程重启,且坏缓存 无法自愈。改为先赋值再外挂 finally;loadCache 校验收紧(typeof null==='object' 陷阱:{"sessions":null} 现在走重建)。两条回归测试在原代码上实证全红。
  • [P2] 零变更不重写 index.json:脏标记(scanned/removed>0 才落盘)——原实现每次 搜索(GET 先 refresh)都同步 stringify 全缓存 + 写盘。

0.1.6 · 未来代际前视(P2)

  • 文件名泛扫 session.vN.jsonl.zstd(取 N 最大)——固定 v4/v3 字面量会让 dsh 发布 v5 后新会话文件永远发现不了(静默断索引);与 lazy-view artifact.js 同款做法。
  • header 版本 ≥5 正整数:warn + best-effort 索引(原 throw → per-session 静默 skip); 1/2/负数/非整数(损坏头)保持 fail loud。测试改语义 + 新增未来代际接受用例。

版本与发布记录

@240xu/dsh-session-search 共发布 11 个版本,首次发布于 2026/09/28;过去 12 个月发布了 11 个版本。

版本发布日期距今
0.1.11latest2026/10/2117 天前
0.1.102026/10/2019 天前
0.1.92026/10/1722 天前
0.1.82026/10/1722 天前
0.1.72026/10/1128 天前
0.1.62026/10/051 个月前

关于 @240xu/dsh-session-search 的常见问题

@240xu/dsh-session-search 是什么?

DSH网络插件:在所有持续会话日志(用户/助手/系统消息)上进行跨会话全文搜索. 以 $DSH HOME/cache/ session- search (0 write to ~/.dsh/ sessions) 为缓存的递增的 mtime+大小索引, 独立的 HTML 面板页面, 有栅栏的 HTT

如何安装 @240xu/dsh-session-search?

在项目目录运行 npm install @240xu/dsh-session-search,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@deepseek-ai/dsh-tools(^0.1.0-rc.6 || ^0.2.0-rc.1)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@240xu/dsh-session-search 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/240xu__dsh-session-search 是否存在。

@240xu/dsh-session-search 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@240xu/dsh-session-search 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=23.5。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@240xu/dsh-session-search 可以商用吗?

@240xu/dsh-session-search 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@240xu/dsh-session-search 的下载量有多少?

根据 npm 官方下载统计,@240xu/dsh-session-search 在 2026/10/05 – 2026/11/03 这 30 天内被下载 1,864 次,日均约 62 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@240xu/dsh-session-search 还在维护吗?

最新版本 0.1.11 发布于 2026/10/21(17 天前);至今共发布 11 个版本,其中过去 12 个月发布了 11 个;首次发布于 2026/09/28。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。