跳过主要内容
P

dsh-locator

perrylink/dsh-locator

DSH 跨平台全盘毫秒级文件搜索,自建索引与 Everything 风格查询,提供 Agent 工具及 Web 面板(Ctrl+Shift+F)。

安装

dsh plugin --profile web add github:perrylink/dsh-locator

README

🔎 dsh-locator

给 DeepSeek Harness 的全盘文件搜索:先按名字找,再按内容找,找到就能打开。

索引由插件自己维护,不装 Everything,也不依赖 es.exe。Windows、macOS、Linux 用同一套工具和同一个面板。

npm version npm downloads CI version License DSH plugin Node Gitee GitCode

简体中文 · English · Español · Português · हिन्दी

dsh plugin --profile web add dsh-locator

官方仓库是 GitHub PerryLink/dsh-locator,Gitee 和 GitCode 是自动同步的镜像。这个插件属于 DSH 插件家族,Apache-2.0;如果它帮你省了时间,点个 ⭐ 就行。

它解决什么问题

找文件通常分两种情况。

一种是你记得名字,但不记得放在哪。glob 和 grep 每次都要重新遍历工作区,知道目录时很快,只记得半个文件名时就很慢。Everything 在 Windows 上很好用,可惜只支持 Windows;把它包一层,macOS、Linux、WSL 和远程机器仍然用不了。

另一种是你记得某句话、某个结论、某段代码,却想不起在哪个文件、哪次对话里。这时只搜文件名没有用。

dsh-locator 把这两件事放在一起:

  • 一份常驻的文件名/路径索引,百万条记录也能在几十毫秒内返回;
  • 一份内容索引,覆盖文本文件和 DSH 会话消息,支持中文和子串;
  • 找到之后可以直接打开文件、定位到文件夹,或者跳到对应的会话。

安装

# npm(推荐)
dsh plugin --profile web add dsh-locator

# 直接跟 GitHub 主仓
dsh plugin --profile web add github:PerryLink/dsh-locator

# 从源码
pnpm install
pnpm build
pnpm build:engine
dsh plugin --profile web add /绝对路径/dsh-locator

# 从 tarball
npm pack
dsh plugin --profile web add /绝对路径/dsh-locator-0.7.0.tgz

npm 包里已经带了六个平台的预编译引擎:linux-x64、linux-arm64、win32-x64、win32-arm64、darwin-x64、darwin-arm64。

如果装进一个正在运行的 Web profile,装完刷新一下页面(F5)。宿主工具可能会热挂载,但浏览器面板是页面加载时从 boot graph 里取的。headless/TUI profile 不会显示面板。

第一次运行

默认索引你的主目录,快照放在系统缓存目录:

平台默认位置
Windows%LOCALAPPDATA%\dsh-locator
macOS~/Library/Application Support/dsh-locator
Linux$XDG_CACHE_HOME/dsh-locator 或 ~/.cache/dsh-locator

第一次扫描要读盘,之后启动直接加载快照。扫描期间搜索照常可用:返回已经索引的部分,并带 indexing: true,面板底栏也会提示“索引构建中”。

默认跳过 node_modules、.git、.svn、.hg、.cache、__pycache__、.venv、venv、.next。

两种搜索

Everything 风格的查询语法,返回路径、大小、修改时间、扩展名、类型。适合“我记得文件名里有 report”“找上周改过的 PDF”这类问题。

按内容找:locator_find

在文本文件和 DSH 会话消息里搜正文,返回命中片段,以及来源信息。

  • 文件命中带路径,直接打开或定位;
  • 会话命中带 sessionId 和 messageId,可以跳回那次对话;
  • 中文和英文子串都能搜,不要求分词。
  • 启动后每 2 分钟做一次增量刷新,只重读 mtime 变化的文件/会话;也可以手动触发全量重建。

内容索引在后台构建,刚启动时可能只覆盖了一部分,工具和面板都会显示构建状态。默认只索引 4MB 以内的文本文件,最多 20 万个文件、最近 200 个会话,内容总量上限 2GB;这些都能在配置里改。

Web 面板

搜索面板:勾选“搜内容”后在文件正文中搜索,显示命中片段和路径

在 Web GUI 里按 Ctrl+Shift+F,或者点侧栏底部的放大镜。

  • 空查询按修改时间列出最近的条目;输入后 110ms 防抖,和工具用同一套语法。
  • 点列头可以按名称、大小、修改时间、路径排序。
  • 勾选“只看文件”“只看目录”过滤类型;勾选“搜内容”切换到正文/会话搜索。
  • ↑/↓ 选择,Enter 复制路径,Ctrl+O 打开,Ctrl+Enter 把 @"路径" 插进输入框。
  • 双击文件结果会在文件管理器里定位;双击会话结果会打开对应会话,并尝试滚动到命中的那句话。
  • 面板文案跟随 navigator.language(中/英/西/葡/印地语)。

面板通过几个同源路由工作:/dsh-locator/search、/dsh-locator/content、/dsh-locator/status、/dsh-locator/reveal、/dsh-locator/open。不另起服务,也不占额外端口。

工具一览

工具作用
locator_search按文件名/路径搜索,支持 ext:、size:、dm:、path: 等过滤。
locator_find按文件正文和会话内容搜索,返回片段与 sessionId/messageId。
locator_status查看根目录、条目数、监听状态、内容索引进度和引擎版本。
locator_rebuild后台重建文件名索引;新索引就绪前,搜索继续使用旧的。
locator_reindex重建/刷新内容索引:默认增量,full: true 全量。
locator_export把文件名索引导出成只读 SQLite,方便外部工具查询。

查询语法

report                  文件名里同时包含这些词
"two words"             完整短语
*.go  ?                 通配符
ext:pdf,docx            按扩展名
ext:!tmp                排除某类扩展名
path:src                路径里包含 src
size:>10mb  1kb..2mb    按大小
dm:today  dm:thisweek   按修改日期
folder:  file:          只看目录 / 只看文件
!tmp                    排除包含 tmp 的
case:1  wholeword:1     区分大小写 / 全词匹配

配置

配置项默认值说明
roots主目录要索引的目录。
excludesnode_modules 等按目录名或路径跳过的 glob。
watchtrue是否监听文件系统变化。
refreshIntervalMs30 分钟没有原生监听时的重建周期。
scanWorkers0扫描并发;0 表示按 CPU 数。
windowsUsnfalseWindows 上尝试 USN/MFT 快路径,需要管理员权限。
memoryLimitMB0引擎的 Go 软堆上限;0 表示交给 GOMEMLIMIT/GOGC。
contentIndextrue是否构建文件正文/会话内容索引。
contentMaxFileBytes4000000单个文本文件最多读多少字节。
contentMaxTotalBytes2000000000内容库总量上限;0 表示不限制。
contentMaxFiles200000最多索引多少个文件;0 表示不限制。
contentMaxSessions200最多索引最近多少个会话;0 表示全部。
contentRefreshMs120000内容增量刷新周期;0 关闭自动刷新。
contentSessionDirs$DSH_HOME/sessions额外的会话目录。
stateDir系统缓存快照和内容数据库的位置。

平台支持

平台扫描实时更新
Linux并行遍历inotify,递归监听
Windows并行遍历,或管理员下的 USN/MFTReadDirectoryChangesW;USN 模式下重启会补日志
macOS并行遍历发布版二进制用 FSEvents;CGO_ENABLED=0 构建回退到 kqueue

Windows 的 USN 快路径默认关闭(windowsUsn: true)。它需要管理员权限和启用中的卷变更日志;任何一步失败都会回退到普通遍历,不会让搜索不可用。USN 扫描成功后会记下日志游标,重启时先补上停机期间的变更,再开始服务。

性能

  • 约 124 万条记录:热查询 25–35ms;扫描进行中查询约 2ms。
  • Windows CI 上 C:\Windows 16.4 万条用 USN 索引约 7.8 秒,查询 9.6ms。
  • 导出 124 万行 SQLite:约 477MB,6.4 秒。
  • 内容索引是后台任务,首次构建时间取决于文本文件数量和会话日志大小。

设计

架构:文件系统 → 扫描/监听 → 紧凑快照 → 查询引擎 → agent 工具 / Web 面板

  • 文件名索引:Go 引擎维护一份紧凑快照。记录只存名字在 arena 里的偏移和父记录 id,完整路径在返回结果时重建。
  • 并行扫描:目录读取协程消费有界队列,每个目录批量写入,保证父目录先于子目录。
  • 查询:解析一次查询,分片并行匹配,用有界堆选出前 offset+limit 条,不排序全部命中。
  • 内容索引:宿主侧 SQLite FTS5,trigram 分词,支持中文和子串;文件清单来自引擎已有的扫描结果,会话日志用 Node 自带的 zstd 解压。
  • 跳转:文件走 /reveal 和 /open;会话通过 uiWorkspace.openSession(sessionId) 打开,再在页面里定位命中文字。
  • 协议:引擎通过 stdio 上的 NDJSON 通信,不监听端口;Web 面板只走同源宿主路由。

从源码构建

需要 Node ^22.19 || >=24.9、pnpm、Go 1.22+。

pnpm install
pnpm build
pnpm build:engine:all
pnpm check

Go 引擎在 engine/ 下,测试用 cd engine && go test ./...。macOS 的 FSEvents 版本需要 cgo,由 macOS CI 构建。

限制

  • 内容索引只处理文本类文件;PDF、Word、图片里的文字暂时不提取。
  • 文件名索引不是文件系统驱动,只覆盖配置的根目录。
  • Linux inotify 每个目录占一个描述符,目录特别多时可能碰到内核上限;插件会报警,快照仍然可用。
  • 通过 WSL 写入 /mnt/c 的文件,Windows 端可能收不到通知,需要重建对应根目录。
  • 会话内容来自本地日志;如果会话还没落盘,搜不到最新几条消息。
  • macOS 的发布版二进制用 FSEvents;CGO_ENABLED=0 构建只有 kqueue,目录上限 4096。

安全与隐私

索引完全在本地,不联网、不上传、不埋点。快照和内容数据库里有文件名、路径和正文,请把它们当作私有数据。插件不会修改、移动或删除被索引的文件。

许可证

Apache-2.0。

相关插件