dsh-file-explorer:给 DeepSeek Harness 加一个 VSCode 风格的文件树与预览面板

前言

DSH 的侧边栏默认面向会话。当你同时开着多个工作区、又想在不改代码的前提下翻看项目里的 Markdown 文档和图片时,反复开终端 ls、cat、less 并不顺手。@vfvrpq/dsh-file-explorer 就是用来补这个缺口:它在左侧栏加一个图标入口,点进去是文件树加一个面板内的预览区,支持文本、Markdown 和图片。下面介绍它的能力、安装和配置。

这是什么

  • 插件名:@vfvrpq/dsh-file-explorer
  • 维护者:439436269-ctrl
  • 仓库:https://github.com/439436269-ctrl/dsh-file-explorer
  • 分类:客户端(宿主半随 Host 启动加载,客户端半由页面加载)
  • 许可:MIT
  • 定位:给 DeepSeek Harness 加一个 VSCode 风格的「文件夹 + 文件预览器」,左侧栏多一个图标入口,点开是主区域的文件树、打开的 tab 与文本 / Markdown / 图片预览。

需要说明的是,npm 上还有一个不带 scope 的 dsh-file-explorer,是另一个作者的同名插件。本包使用 @vfvrpq/ scope 区分,两者不冲突、可共存。

核心功能

安装后主要得到下面几样东西。

左侧栏入口注册在 sidebar.panellist 槽位,id 与主面板 key 同为 file-explorer,点图标即切换到面板。

文件树支持懒加载(展开才列目录)、文件夹优先排序、按后缀着色的类型徽标、隐藏文件开关,目录树宽度可拖动。

单击文件就在面板内预览:左边是树,右边是一张独立的预览卡片,带 tab、面包屑、行号或渲染后的 Markdown,状态栏显示字节数、行数、是否截断,不会跳走。展开过的文件夹会按根记住,刷新后树还在原处。

除了面板内预览,还有两个外发动作:

  • 面包屑旁的「在右侧打开」把当前文件送进会话的右侧文档预览(内置渲染器支持代码 / PDF / Office 等)。因为右侧栏属于会话,这个动作会让会话回来、面板让位。想每次都这样,把 openInRightPanel 设为 true。
  • 「用默认程序打开」按钮把当前文件交给系统默认程序(Windows start / macOS open / Linux xdg-open),POST 到认证路由 ?op=open。

预览能力分几类:

  • 文本:等宽字体、行号、自动换行开关,单文件默认最多 1 MiB、最多渲染 4000 行。
  • Markdown:标题 / 列表 / 引用 / 代码块 / 链接 / 图片,相对图片走原始字节路由,可一键切回源码。
  • 图片:png / jpg / gif / webp / avif / bmp / ico / svg。
  • 其它二进制:只显示类型与大小,不加载内容。

搜索按文件名在当前根目录内递归,受目录数、命中数、时间三重预算约束。

安装与启用

插件是标准 bundle,包内带 dsh.bundle.patch,适配 DSH 0.2 预览版。装进某个 profile 时会同时写入 dependencies 与 dsh.profile.bundles:

dsh plugin --profile desktop add @vfvrpq/dsh-file-explorer@0.1.0

或者手写进 profile 的 package.json:

{
  "dependencies": { "@vfvrpq/dsh-file-explorer": "0.1.0" },
  "dsh": { "profile": { "bundles": [ ..., "@vfvrpq/dsh-file-explorer" ] } }
}

也可以只在 profile 的 cordis.patch.yml 里挂一行。两种方式不要同时用,insert 不按 id 去重,会挂载两次:

- insert:
    - id: file-explorer
      name: "@vfvrpq/dsh-file-explorer"
      config:
        enabled: true

装好后重启一次 DSH(或让 Loader 重载),侧栏就会出现「文件浏览」图标。

这里有一个容易踩的坑:不要用 link: / 目录 junction 安装。@deepseek-ai/schemastery 由宿主在 profile 的 node_modules 里解析,软链会被 Node 还原成源码真实路径,从那里向上找不到宿主包,插件会以 failed to import 静默不激活。要用 npm 安装或 file: tar 包(真实拷贝)。

配置

配置层在 cordis.patch.yml 的 config 下,字段与默认值如下:

字段 默认值 说明
enabled true 关掉后路由不再响应,但侧栏入口仍在
routePath /api/file-explorer 认证路由,必须以 /api/ 开头才能吃到连接层的鉴权围栏
extraRoots [] 额外可浏览的绝对目录(除了工作区、默认目录、进程目录、主目录)
includeHome true 是否把用户主目录作为根
ignored [] 列表与搜索里隐藏的条目名,例如 node_modules
maxTextBytes 1048576 文本预览上限(超出截断并标注)
maxRawBytes 33554432 原始字节路由上限(图片预览)
defaultShowHidden false 文件树初始是否显示点文件
openInRightPanel false 设为 true 时点文件改为送进右侧栏文档预览;默认留在面板内预览
allowOpenWithDefaultApp true 是否显示「用默认程序打开」按钮;关掉后 ?op=open 直接 403
blockedOpenExtensions exe,com,bat,cmd,msi,scr,pif,vbs,vbe,ps1,reg,sh,command,app,desktop 启动器拒绝交给系统处理的后缀;设空数组表示不拦

权限模型

这个插件只读,并且不接受任意路径:

  1. 可浏览的根 = 已注册工作区 + 默认工作目录 + 进程目录 + 主目录 + extraRoots,去重后只保留真实存在的目录。
  2. 每次请求的 path 都用 ctx.fs.resolve 解析成稳定 target,再用 ctx.fs.contains(root, target) 证明它落在某个根内,否则 403。
  3. 路由挂在 /api/ 下,继承连接层的 Host/Origin 校验与会话 cookie 鉴权。
  4. 原始字节路由只对图片类型内联(带 nosniff + CSP sandbox),其它一律按附件下发。
  5. ?op=open 只接受 POST(GET 一律 405),只接受普通文件且拒绝可执行后缀,启动命令由平台决定,不拼接 shell 字符串。

适用场景与注意

适合想在 DSH 界面里直接浏览项目结构、阅读文档和查看图片的开发者,尤其是同时维护多个工作区、频繁翻看 Markdown 与截图的场景。

注意几点:

  • 插件在当前 dsh 进程权限下运行。安装前应自行检查源码与许可证(MIT),不要把它当成免审的信任边界。
  • 只读:不提供保存、重命名、删除,目的之一是避免和会话的写权限、审批策略打架。
  • 无语法高亮,只做行号与类型着色。
  • 单文件渲染上限 4000 行,文本读取上限 1 MiB,都可配。
  • 搜索是文件名子串匹配,不是内容检索;单次最多开 400 个目录、4 秒预算。
  • 二进制文件不给下载按钮,原始路由只服务图片内联。

结尾

它把 DSH 默认会话侧边栏之外补上了一块独立的、只读的文件浏览与预览区域,安装方式是标准的 profile bundle,配置项围绕根目录、大小上限与打开行为。

  • 目录页:https://www.skillhub.cn/plugins/439436269-ctrl/dsh-file-explorer
  • GitHub:https://github.com/439436269-ctrl/dsh-file-explorer
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜