DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

CHIP-PHILO-GH /

CHIP-PHILO-GH/dsh-session-search

Verified

DSH 插件:跨会话内容检索 —— 按关键词搜历史会话正文,带本地索引与预热,零第三方依赖。

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@6f530368

dsh-session-search

CI License: MIT

只想要“照着做一遍”的封装版本(含安装、配置与排错表),见同名技能包 dsh-session-search;本仓库是代码本体。

让 DSH Web 左侧边栏的搜索框搜索范围由你自己定:时间范围(全部 / 最近 N 天)与搜索内容(我说的话 / DSH 的回复 / 项目名)都在搜索结果上方可改;选择存进官方设置文档,重开浏览器、重启 DSH 之后仍然是上次的选择。命中片段显示两行原文。

  • 宿主半边 lib/index.js:按「范围对象」改写侧边栏搜索的过滤条件(时间范围 + 内容来源),并把范围接到官方设置服务 ctx.settings 上。
  • 客户端半边 lib/client.js:在搜索结果上方给一个「范围」控件;命中片段从单行省略改成两行;把官方那条归因不准的提示换成带当前范围的说明。
  • 组合行 cordis.patch.yml:挂载本插件,并把官方全文索引打开(见下)。

为什么原来搜不到内容

DSH 的侧边栏搜索链路是:

搜索框 → 客户端 sessions.search → 远程 session.search → 宿主 SessionController.search
      → ctx.sessionQuery.searchSessions(...) → 官方 SQLite FTS5 全文索引

官方全文索引(@deepseek-ai/dsh-session-query-sqlite)在 web 组合里是可选能力, @deepseek-ai/dsh-web-app 把它那一行固定成 path: ':memory:' + openAt: never:

openAt: never … while search calls fail with SESSION_QUERY_SEARCH_DISABLED and SQLite is never opened; the Web sidebar search matches titles and workspace names only.

所以搜索框只能匹配名称;输关键词时页面还会在结果下方提示「内容搜索暂不可用,仅显示名称匹配」—— 这句话把原因归到「只能按名称匹配」,但真实原因通常是索引还没建好。本插件随后会把它换成说真话的提示。 要开内容搜索,官方给的做法就是在更靠后的补丁层(profile 的 cordis.patch.yml)覆盖这一行的 openAt。

本插件做了什么

  1. 开索引(profile 的 cordis.patch.yml,本插件的安装步骤之一):

    - id: session-query-sqlite
      config:
        path: '<DSH_HOME>\profiles\web\session-search.db'
        openAt: first-search
    

    openAt: first-search = 不在启动时开库,第一次搜索才建索引(Node 22 启动保持安静)。 索引是独立的派生库,只读会话日志、绝不写回;删掉这个文件即完全重建。

  2. 按范围改写过滤器(lib/index.js):在 ctx.sessionQuery 上包一层 searchSessions。 官方调用方原本发的是「user/message + assistant/message + current 表层」, 本插件丢掉它的 type 与 time 两条,换成当前范围给出的:

    过滤器 值 作用
    surface current 只看当前模型表层,忽略被替换的历史
    type user/message / assistant/message(按勾选,可同时) 决定搜「我说的话」「DSH 的回复」还是两者
    time from = 当地今天 00:00 往前 N-1 天 只看最近 N 天;范围为「全部」时不注入这条

    三种内容来源一个都不勾(例如「只看项目名」)时,正文检索没有意义:宿主直接回一个空页, 不调用官方索引,侧边栏于是只展示它自己的名称匹配结果。

    窗口取「整天边界」而不取 now - N×24h:语义上就是「最近 N 天(含今天)」, 且同一天内取值恒定 —— searchSessions 的分页游标绑定的是规范化后的确切请求, 逐次漂移会让翻页被判成 SESSION_QUERY_STALE_CURSOR。

    query / limit / cursor 原样透传,返回值不变,命中片段由官方索引给出。

  3. 范围可改、选择可留存(lib/client.js + lib/index.js):范围对象有默认值和用户选择两层。 默认值来自上面的组合行 config;用户在下拉面板里改的选择走官方设置服务 ctx.settings (命名空间 session-search),存进 settings.yaml:

    session-search:
      days: 7
      user: true
      assistant: true
      project: true
    

    所以改完立即生效(不需要重启),重开浏览器、重启 DSH 之后仍然是这份选择。 设置服务不在时自动退回浏览器 localStorage,面板底部会如实说明。

  4. 两行片段(lib/client.js):官方结果行把片段渲染成单行省略 (white-space:nowrap; text-overflow:ellipsis),这里补一条样式改成两行。 选择器用 [class*="searchResultSnippet"](class 哈希前缀随构建变化、局部名稳定), 写成双属性选择器是为了抬特异性,避免依赖样式插入顺序。移除本文件里的 css 数组即恢复单行。

  5. 索引预热(可选,默认开):索引是「首次搜索才建」, 会话日志积累得多时,第一次搜索要一次性为全部历史建索引(之后只增量对账)。 预热把这段时间挪到后台:启动后延迟 prewarmDelayMs(默认 45 秒)跑一次不可能命中的搜索, 失败静默忽略。不想要就设 prewarm: false。

搜索范围怎么改

搜索框在侧边栏展开、并且输入了关键词时,搜索结果上方会出现一条「范围」控件,右边实时显示当前范围与命中情况:

  1. 点搜索图标展开侧边栏搜索框,随便输一个关键词;
  2. 点结果上方的「范围」,面板里两组开关:时间范围(全部 / 1 天 / 3 天 / 7 天 / 30 天 / 自定义天数) 与搜索内容(我说的话 / DSH 的回复 / 项目名);
  3. 点一下立即生效,不用回车、不用重启;面板右下角会说明设置写到哪里;
  4. 「项目名」这一项管的是会话名 / 工作区名的名称匹配(由官方侧边栏自己完成): 勾上=名称命中照常出现;取消=只保留正文命中的结果行。它是名称匹配开关,不是工作目录过滤。
  5. 结果为空时提示会带上当前范围(例如「当前范围(最近 3 天 · 我说的话)内没有命中」), 索引还没建好时的提示会说明真实原因,而不是让你以为只能搜名称。

配置项(组合行 config)

字段 默认 含义
days 3 时间范围天数(含今天);0 = 不限时间(全部历史)
user true 搜我说的话
assistant false 搜 DSH 的回复
project true 名称匹配开关(会话名 / 工作区名)
userOnly 无 1.0.0 的旧写法:true ≈ user: true, assistant: false;false ≈ 两者都 true
prewarm true 启动后在后台预热一次全文索引
prewarmDelayMs 45000 预热延迟毫秒

安装

下文把 DSH 的配置目录记作 <DSH_HOME>:设过环境变量 DSH_HOME 就用它, 否则是 %USERPROFILE%\.dsh;profile 名以 web 为例。本仓库的检出目录记作 <REPO>。

安装三步,改完重启 dsh web 生效:

  1. 让插件出现在 profile 的 node_modules 里:<DSH_HOME>\profiles\web\node_modules\dsh-session-search。 Windows 上可以用 junction(不占额外空间,改仓库里的文件即刻生效):

    $home    = if ($env:DSH_HOME) { $env:DSH_HOME } else { Join-Path $env:USERPROFILE '.dsh' }
    $modules = Join-Path $home 'profiles\web\node_modules'
    New-Item -ItemType Directory -Force -Path $modules | Out-Null
    New-Item -ItemType Junction -Path (Join-Path $modules 'dsh-session-search') -Target '<REPO>'
    

    换成普通的目录副本同样可以:只要上面那个路径下能看到本仓库的内容即可。

  2. profile 的 package.json:dsh.profile.bundles 加 dsh-session-search, dependencies 加 "dsh-session-search": "link:<REPO>"(<REPO> 写成正斜杠路径)。

  3. profile 的 cordis.patch.yml:加开索引那一行(上面「本插件做了什么」第 1 点)。

回滚

删掉上面三处即可(插件行随 bundle 一起消失;开索引那行删掉后搜索回到「只匹配名称」)。 已有的选择存在 settings.yaml 的 session-search: 分节里,不需要了连同这个分节一起删; 索引文件 <DSH_HOME>\profiles\web\session-search.db 可直接删除,下次搜索自动重建。

测试

零依赖,不需要 DSH 在运行、不需要联网:

node test.mjs                  # 汇总入口:语法检查 + 两个验证台 + 文档一致性 + 仓库卫生
node tools/verify-host.cjs     # 宿主半边离线验证台
node tools/verify-client.cjs   # 客户端半边离线验证台

node test.mjs 会跑 node --check、上面两个验证台,再核对 README 的配置表字段与 lib/index.js 一致、README 与 README.en.md 结构对齐、package.json / LICENSE / CHANGELOG.md 的字段与列出的文件齐备。

两个验证台各自造桩:不连真实会话库、不读 profile、不写任何文件。

  • tools/verify-host.cjs(78 项):过滤器改写、字段透传、时间范围边界(含「全部」)、 内容来源组合、只看项目名的短路、旧配置兼容、范围归一化边界、设置 schema 与接线、卸载精确还原、 无服务时静默跳过、预热定时器登记与清理。
  • tools/verify-client.cjs(62 项):bundle 注册与 inject 声明、零 require、样式标记与去重键、 四条关键样式规则、范围控件落位与文案、改范围三处落地(本地 / localStorage / 设置服务)、 两种 body 类开关、设置就绪与不可用两条路径、DOM 变化降频与卸载还原。

这三条命令就是 CI 里跑的全部内容。

许可

MIT。插件本身可自由取用。 DSH 本体与官方全文索引(@deepseek-ai/dsh-session-query-sqlite、@deepseek-ai/dsh-web-app 等) 属上游项目,遵循各自的许可。

—/ 5

No ratings yet

Verified DSH bundle

Commit 6f5303689348

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout