dsh-host-file-explorer:在 DSH 里浏览宿主机文件

前言

做 DSH 插件开发或智能体调试时,经常需要在浏览器界面里确认宿主机上的目录结构、配置文件内容或某张图片。此前这类操作要么跳回终端敲命令,要么让插件自己实现一份文件树组件。下面介绍的插件直接在 DSH 左侧边栏加了一个文件管理面板,把宿主机的文件浏览、预览、下载和上传收进界面里。

  • 插件名称:ccfeeling/dsh-host-file-explorer(npm 包名 @local/dsh-host-file-explorer,版本 1.2.0)
  • 维护者:ccfeeling
  • 许可证:MIT
  • 分类:客户端插件
  • 来源:社区插件目录(非 DeepSeek / 幻方官方应用商店),GitHub 仓库为 https://github.com/ccfeeling/dsh-host-file-explorer

定位

这是一个标准的 DSH bundle,由 Host 半和 Client 半组成。Host 半在 ctx.hostFiles 上挂了一个服务,基于 node:fs/promises 提供七个动词;Client 半在侧边栏注册 host-files 面板,提供目录列表、文本与图片预览、文件下载、文件上传和新建文件夹,并支持十二种界面语言。

所有读取都经过 Host/Client Remote 通道——也就是智能体自身文件系统工具所使用的同一条边界——而不是绕过去直接访问文件系统。

核心功能

功能清单如下,全部来自 README:

  • 目录列表:目录在前、文件在后,每项带类型、大小、修改时间,隐藏项以变暗样式展示。
  • 文本预览:读取文本文件的前 256 KiB 并渲染;二进制文件会自行报告而不打印乱码。
  • 图片预览:PNG、JPEG、GIF、WebP、AVIF、SVG 以内联方式显示,而不是按文本读取。
  • 下载:通过 Harness 的认证文件路由交给浏览器,保留文件原名。
  • 上传:把浏览器中的文件作为一次 Remote 调用发送到当前打开的目录,字节随命令携带,不经过浏览器文件路由。
  • 新建文件夹:在当前目录下创建单段子目录。
  • 路径导航:可跳转到绝对路径、返回上级,还有 HOME、tmp、cwd、文件系统根的快捷键。

安装与启用

有三种安装方式,按使用场景选择。

第一种是插件管理器安装(README 推荐)。先克隆仓库,再从本地路径安装:

# clone
git clone https://github.com/ccfeeling/dsh-host-file-explorer.git

# 安装到某个 DSH profile,profile 名称与路径按自己环境替换
dsh plugin --profile web add /path/to/dsh-host-file-explorer

对应的 tool call 是 plugin_manager { action: 'install_bundle', target: '<local path>' }。

第二种是从插件市场安装。该插件收录在 awesome-dsh-plugin 列表中,因此可以直接从 GitHub 安装:

dsh plugin --profile web add github:ccfeeling/dsh-host-file-explorer

第三种是作为 profile 依赖声明。编辑 ~/.dsh/profiles/<profile>/package.json:

{
  "dependencies": {
    "@local/dsh-host-file-explorer": "link:/abs/path/to/dsh-host-file-explorer"
  }
}

安装完成后,侧边栏会在 Plugins 和 Schedules 之后出现一个文件夹图标,点击即打开面板。

一个与 profile 依赖相关的坑:如果 profile 里有会随包发布 agent skills 的依赖(例如 dsh-answer-me-with-html),pnpm 10.11+ 和 12.x 在 skills 目录未声明时会拒绝安装并抛出 ERR_PNPM_NO_AGENT_SKILLS_DIR。在该 profile 的 pnpm-workspace.yaml 里加一段即可:

skills:
  dirs: []

底层架构

插件的代码结构如下:

index.js   (Host)    ctx.hostFiles  ——  七个动词,基于 node:fs/promises
client.js  (Client)  侧边栏入口 + 主面板 + Remote 命名空间挂载

Host 半用原型标记 @deepseek-ai/dsh-typert-protocol/remote-methods 声明 Remote 传输,让网关在 SRC 模式下能发现这些方法:

方法 参数 返回
roots() — HOME、tmp、cwd、文件系统根
list(path, signal) path { path, parent, home, entries[{ name, path, kind, size, modified, mime, hidden }], truncated }
stat(path, signal) path { path, kind, size, modified, mime }
read(path, signal) path { path, size, modified, binary, truncated, text }
mkdir(path, name, signal) path, name { path }
upload(path, name, data, signal) path, name, data { path, size }
limits() — 单个下载允许的最大字节数

这里有个签名约束:signal 必须是最后一个参数。网关用 Function.prototype.toString() 解析方法签名来推导线上参数,签名写错会导致调用失败。

关于文件如何到达浏览器:页面本身不走 Remote 通道传文件字节,而是向 Host 询问文件在 Harness 认证文件路由上的地址(与文档预览中 Markdown 图片所用的路线相同),浏览器复用页面已持有的会话去取。下载保留原名,预览拿到原始 Content-Type,所以 PNG 就按 PNG 渲染。单次响应受 Harness 附件字节上限约束(默认 20 MiB);面板会先从 Host 读取这个上限,遇到超限的下载直接拒绝并说明原因,而不是启动注定失败的传输。

Client 半手写了一个 Typert Remote 贡献,用 ctx.remote.$mount(...) 挂载,随后注册两个槽位:

  • sidebar.panellist:id host-files,order 30,带独立的文件夹图标;
  • main:key host-files,即侧边栏按钮打开的面板。

两个开发陷阱

README 特别强调了两点,扩展或复制该插件时需要留意。

第一,命名空间不能声明为插件自己的 inject。挂载出来的 remote.hostFiles 是一个独立的服务,且只有在本插件挂载之后才存在;若有 fiber 去等它,会永远等不到,插件也就无法启动。要用 Cordis mixin 的入口直接从共享 store 读取:

const namespace = ctx.get('remote.hostFiles');

官方插件能写 inject: ['remote.agentPresets'],是因为有别的包挂载了那些命名空间,消费者可以直接声明依赖;本插件不能这么写,正因如此。

第二,Client 半不依赖任何 Harness client 包。它只用 react 和 zod,样式用 --dsw-alias-* 主题变量实现,没有从 @deepseek-ai/dsh-client-ui-primitives 及其同类包导入任何东西。

权限与边界

使用前需要明确这些限制:

  • 插件以 Harness 进程自身的权限读取宿主机文件系统,账户能读到什么,它就能读到什么。这是宿主机文件浏览器的固有属性,因此只在你信任的机器和账户上启用。
  • 能力范围是只读,加上新建文件夹和上传文件。它不能修改、删除或重命名已有文件,上传也从不覆盖同名文件。
  • 单次列表最多返回 2000 项,单次预览最多读 256 KiB。
  • 单次下载不超过 Harness 附件字节上限(默认 20 MiB),面板会在超限下载开始前说明原因。

安装第三方插件前,建议先读一遍源码和许可证(本插件为 MIT),确认下载与上传的目录范围符合预期。

小结

这个插件的价值在于把宿主机文件系统的操作收敛进 DSH 界面,同时复用智能体已有的 Remote 通道,不引入额外的越权路径。对于需要在 Web 端核对配置文件、查看图片或收发文件的 DSH 用户和插件开发者,它是一个可以直接安装的客户端工具。

  • 目录页:https://www.skillhub.cn/plugins/ccfeeling/dsh-host-file-explorer
  • GitHub:https://github.com/ccfeeling/dsh-host-file-explorer

开发阶段可以使用 README 提供的命令做基本检查:

node --check index.js
node --check client.js
npm pack --dry-run      # 查看实际发布的文件列表
羽毛球分组比赛记分
小程序二维码

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

小夜