liangmianya/dsh-synapse
liangmianya/dsh-synapseDeepSeek Harness 的可视化非线性对话工作区:把会话、追问与分支变成可浏览、可拖拽的对话地图。
侧边栏会话搜索开关,标题 / 内容一键切换:标题按会话标题过滤,内容经 DSH 自带全文索引搜索历史消息关键词,结果按会话聚合,附最强命中片段与消息类型标签。
给 DeepSeek Harness 侧边栏加一个自带索引的会话检索——标题/内容一键切换,还能按用户/回复/工具筛选 简体中文 · English · Français · Deutsch · Italiano · Русский · Español
DSH web 侧边栏搜索索引:在侧边栏底部新增 "搜索" 入口,浮层面板一键在 标题搜索 ↔ 内容搜索 间切换;内容模式按会话聚合展示标题与命中片段,并按 用户 / 回复 / 工具 分类筛选。自带独立索引(不依赖 DSH 官方全文索引),支持增量同步、非破坏性整理与快照导入导出。
本包只管搜索与索引。 会话历史的查看与清理(原"归档会话"面板)已迁至 `dsh-session-steward`(会话管家) 的「病案室」页签;本包仍会读取官方归档集合以把已归档会话排除出索引,但不再写入它——归档集合只有一个写方:会话管家。契约见 dsh-归档文件格式契约-20260914.md。无需修改 dsh 源码、无需提 PR:dsh plugin 命令组装 + bundle patch 装配的 cordis 客户端 + 插件宿主半。
前身:`dsh-session-search-toggle`。 那个版本依赖 @deepseek-ai/dsh-client-runtime 的 defineStore 提供设置行座位。DSH 0.1.2 把客户端引擎包改名/重构(dsh-client-runtime → dsh-client-store),旧写法在新宿主上无法加载——同一个插件没法用一份产物同时兼容两版。
本版(`dsh-search-index` 0.6.6)以 DSH 0.2.0–0.2.1-rc.3 为主线(peer 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3)。历史宿主线的支持由独立版本线承担:DSH 0.1.7 用 0.5.7(npm dist-tag dsh-0.1.7,compat/0.1.7 分支),更早的 0.1.1/0.1.2 用旧版产物,不再随本版演进。历史背景:
lib/client.js 在 0.1.1-rc.2 与 0.1.2-rc.1 上都能加载,没有任何版本号字符串分支。客户端 bundle 只 require react / react-dom,两者都在两版的共享模块表内。dsh-client-runtime,也不 import dsh-client-store,因此不受那次改名影响。StoreHandle / StoreInstance,契约由 @deepseek-ai/dsh-client-ui-slots 拥有、两版一致)。本插件用约 30 行本地实现替代 defineStore——只依赖 create() → { actions, getSnapshot, subscribe, clearPersisted },不涉及任何版本专属 specifier。settings.general.item 槽、SettingsScope.{getSnapshot,subscribe,set,unset}、sessionQuery 三个查询面在两版签名相同。▼ DSH 版本适配
| DSH 版本 | 状态 | 载体与关键差异 |
| --- | --- | --- |
| 0.2.0-rc.1 | ✅ | 本版 0.6.6;peer/engines = 0.2.0-rc.1 || 0.2.0-rc.2 || 0.2.1-rc.1 || 0.2.1-rc.2 || 0.2.1-rc.3,代码零修改(纯 caller 消费 slots/locale/configForms 席位) || 0.2.1-rc.1 | ✅ | 本版 0.6.6;0.2.1-a.2 起宿主把webRuntime更名webStartup,本版注入webStartup并走双名回退链 |
| 0.2.1-rc.2 | ✅ | 本版 0.6.6;声明面补票(宿主 peer 全部 npm 实测 rc.2 在版),代码零改动 |
| 0.2.1-rc.3 | ✅ | 本版 0.6.6;声明面补票(rc.3 契约面零断裂:闸门/settings/vendor/缝/会话 V4 零 diff,仅新增三域 More 菜单行槽),代码零改动 |
| 0.1.7-rc.1+ | ✅ | 0.5.7(dist-tag dsh-0.1.7);configForms 以 entry id 取句柄,旧宿主回退 settingsScope 按命名空间绑定 || 0.1.1-rc.2 | ✅(旧版产物,冻结) | store 引擎在 @deepseek-ai/dsh-client-runtime/client || 0.1.2-rc.1 | ✅(旧版产物,冻结) | 引擎改名 @deepseek-ai/dsh-client-store;本插件两个都不导入 |从旧名升级:本包由 dsh-session-search-toggle 改名而来,客户端注册 id、cordis patch id 与仓库地址同步改名。GitHub 会为重命名的仓库保留跳转,旧名仍可解析,但请把 profile 依赖换成新名,避免两个名字长期并存:
dsh plugin --profile web add github:drscrewdriver/dsh-search-index#master
dsh plugin --profile web remove dsh-session-search-toggle
dsh web # 重启设置命名空间仍是 switch-search(存储键保持稳定,不做迁移),因此旧配置在新包下继续生效。
工具 放开 tool/call 与 tool/result 事件进结果,直接搜到工具调用参数与返回值。session/event,改名(session/title)即刻折进索引,不必等下一轮同步(默认 30s)。dsh-session-steward)负责,本插件只读归档集合;未安装时那句提示会明说「当前未安装」——判定由宿主从插件自身的模块图解析得出,解析不出结果时走中性文案,绝不把"读不到"报成"未安装"。⌘K、Windows/Linux 渲染 Ctrl K,按运行系统就地判定;面板内的关闭键同样平台化(macOS esc / 其他 Esc)。平台识别走 UA-CH → `navigator.platform` → UA 串三级降级,隐私模式下不会把 Mac 用户降级成 Windows 符号。提示与绑定同源:胶囊上写的和弦就是 keydown 实际匹配的和弦,不存在"提示一个键、响应另一个键"。侧边栏搜索入口与搜索面板布局示意:
内容模式自己建库,不依赖 DSH 官方的 session-query-sqlite 全文索引。索引落在 src/host/:schema.ts 建表(含自建 FTS5 表 docs_fts),engine.ts 负责查询,extract.ts 从会话事件抽出可检索文本(含 tool/call 的工具名与参数、tool/result 的结果文本——这是"工具筛选"的数据基础)。DSH 的 sessionQuery 只被当作语料读取器(listSessions / readSession),不用来搜索。
索引是本插件自己的 SQLite 文件,与官方索引互不影响。可选持久化目录、可快照导出/导入、可整体重建。宿主激活时会巡检索引目录:index.building.sqlite 半成品在 active 存在时判为"上次重建未完成"直接丢弃;active 缺失时判为"崩溃发生在换名窗口",把最新归档回滚为 active。
archive-source.ts 读取官方存储中枢 ~/.dsh/storages/workspace.json 的 global.archivedSessionIds,把已归档(即已不可用)的会话排除出索引。归档集合只有一个写方——会话管家;本包只读不写。
同步是滚动的:sync.ts 的 SwitchWatermarkSync 维护每条会话的 version 水位,每轮只比对差异、只重灌有变化的会话,不做全量重建。索引文件本身按 archiveKeep 保留有限份数,旧的自动淘汰。
整理走影子索引:rebuild.ts 在 active 索引旁边从零构建 index.building.sqlite,构建期间 active 索引持续对外服务,搜索不会被阻塞。构建完成后切换是三次同步 rename(active → archive,shadow → active),是一个原子窗口。
这也决定了失败语义:影子还在 + active 还在 = 构建没完成,此时影子是废料,直接丢弃——active 从头到尾没有处在风险里。
# 方式一:从 GitHub 直装(推荐)——仓库已提交 lib/,无需本地构建
dsh plugin --profile web add github:drscrewdriver/dsh-search-index#master
# 方式二:本地路径/源码组装(见"开发"章节)
# 重启 dsh web —— 必做!运行中实例不热载 bundle 层
dsh web装完侧边栏底部出现 "搜索" 按钮;设置 → 插件出现 "搜索索引" 卡片。
⚠️ GitHub 网络可达性:github: 直装需要能连通 github.com;网络受限时请先配置可用代理或镜像加速,否则 add 会在拉取阶段卡住。
pnpm install # 含 @deepseek-ai client 包链 + tsdown/tsc
pnpm typecheck # tsc --noEmit
pnpm build # tsc(lib/types) + tsdown(lib/index.mjs + lib/client.js)src/
├── index.ts # 宿主半(node):Config schema + installSettingsSection + 路由
├── config.ts # 纯共享配置(enabled/defaultMode + 命名空间常量,client 免 schemastery)
├── host/ # 独立索引(宿主侧)
│ ├── schema.ts # 建表:docs / docs_fts(FTS5) / sessions / 水位
│ ├── engine.ts # 查询
│ ├── extract.ts # 从会话事件抽可检索文本(含 tool/call、tool/result)
│ ├── sync.ts # SwitchWatermarkSync:按 version 水位滚动增量同步
│ ├── rebuild.ts # 影子索引构建 + 原子切换 + 崩溃恢复巡检
│ ├── archive-source.ts # 读归档集合,把已归档会话排除出索引
│ └── snapshot.ts # 快照导出/导入
└── client/
└── index.ts # 浏览器半:sidebar.footer.action 入口 + 浮层面板 + settings.general.item 配置行/switch-search/api(list-sessions / content-search / search-status),浏览器信任围栏与 DSH /api 网关一致(loopback Host 或 trustedHosts,拒绝 cross-site)。settings 服务注册 switch-search 命名空间 + schemastery Config;client 半本地 store 座位 + settingsScope.bind 镜像读写;共享纯模块 src/config.ts 保持 client bundle 无 schemastery。packages/client/tsdown.client.ts 语义(__ModuleLoader__.load banner、平台模块 external 表、bundle purity gate)。.gitignore 不忽略 lib/。sidebar.workspaces(single slot),外部插件无法替换;本插件在侧边栏底部新增独立入口 sidebar.footer.action,二者并存、互不干扰。user/message + assistant/message;本插件用自建索引,放开 tool/call + tool/result,实现工具级筛选。session-query-sqlite 开不开都不影响本插件。src/*.ts 本地结构声明(npm 上 dsh client 包链不完整),构建时以 harness 源码核实为准。本项目是 drscrewdriver 维护的 DSH 插件系列之一。如果这个对你有用,其他插件多半也有用:
插件 · 一句话描述 dsh-input-traffic · DSH Web GUI 忙时输入队列:三档交通管制,拖拽重排,会话冻结 dsh-thinking-levels · 逐轮 reasoning_effort 控制:Auto 智能调度或手动固定档位 dsh-seatbelt-sandbox · macOS Seatbelt 沙箱适配器:libsandbox 原生 loader,接替弃用的 sandbox-exec dsh-prime-memory · 分层蒸馏记忆:L0~L3 自动蒸馏,模型每步前召回注入 dsh-search-index · 侧边栏会话搜索增强:标题/内容切换,按用户/回复/工具筛选
MIT