DSH Hub
dsh-browser-fs cover

whitefirer/dsh-browser-fs

dsh-browser-fs

UIBrowser3 GitHub stars· updated 2026-08-20

dsh-browser-fs is a community DeepSeek Harness plugin. Read the repository README before installing.

Install

npx @deepseek-ai/dsh plugin --profile web add dsh-browser-fs

Restart `dsh web` after install. Bundle APIs can change during the developer preview.

README badge

dsh-browser-fs DSH Hub badge
[![DSH Hub](https://dshhub.dev/badge/dsh-browser-fs.svg)](https://dshhub.dev/plugins/dsh-browser-fs)

Paste this into your README. The star count updates with every catalog sync.

From the README

Excerpt from whitefirer/dsh-browser-fs, cleaned of badges and images.

dsh-browser-fs

中文 | English

让 dsh 的 agent 读写浏览器所在机器的本地文件。dsh 自带的 fs 工具只能摸宿主机; 远程部署时浏览器在别的机器上,agent 够不到你本地的文件。本插件补上这个缺口:

用户在 dsh web 页面里通过 File System Access API(showDirectoryPicker)授权一个本地 目录,句柄存 IndexedDB;agent 通过三个模型工具 list/read/write 该目录下的文件,工具 调用经插件自建的 WebSocket 通道转发到浏览器执行。

原理

双面插件(cordis 插件体系):

  • host 半src/index.ts,跑在 dsh 宿主 Node 进程)
    • ctx.webServer.registerUpgrade 注册精确路径 /browser-fs/ws 的 WS 通道;
    • ctx.tools.register 注册 browser_fs_list / browser_fs_read / browser_fs_write
    • execute 把 {type:'call', rpcId, op, args} 帧发给「持有授权句柄」的标签页,按 rpcId 配对 result 帧;exec.signal 接到 pending 的 abort(同时给浏览器发 cancel 帧)。
  • client 半src/client/,浏览器里跑)
    • 启动时从 IndexedDB 读回句柄并 queryPermission;连回 host 的 WS(断线指数退避重连);
    • 收到 call 帧后在授权目录上执行 File System Access 操作,回发 result 帧;
    • shell.overlay 层注册一张浮动卡片:显示连接/授权状态,提供 授权目录 / 重新授权 / 更换目录 / 解除授权 按钮。
    • 授权状态变化时广播 {type:'state', hasHandle, dirName};host 只把调用派给 hasHandle=true 的标签页(多个标签在线时的执行者选择)。

安装

# 从 npm 装(推荐,零脚本、无需构建授权)
dsh plugin --profile web add dsh-browser-fs

# 或直接从 GitHub 装(构建产物已入库,安装零脚本)
dsh plugin --profile web add github:whitefirer/dsh-browser-fs

# 本地开发:改代码后重装(改动需先 npm run build,产物 lib/ 已纳入版本库)
npm install
npm run build
dsh plugin --profile web add file:/abs/path/to/dsh-browser-fs
# 重启 dsh 后生效

dsh plugin add 会把本包装进 profile 的 dependencies,并因 manifest 里的 dsh.bundle.patch 声明自动把 dsh-browser-fs 追加进 dsh.profile.bundles 层栈 (patch 内容即本仓库的 cordis.patch.yml:insert 一行挂 host 半,config 含 wsPathrequestTimeoutMs)。

使用

  1. 打开 dsh web 页面,右下角出现「browser-fs 浏览器文件」卡片(未授权时默认展开; 授权后默认折叠成 📁 圆钮,点一下展开、按住可拖动,「—」收起;折叠状态存 localStorage,刷新保持,圆钮上的状态点颜色与卡片一致);
  2. 点「授权目录」,在系统选择器里选一个本地目录(需要 readwrite 权限);
  3. 卡片上的「目录内容」区可直接浏览授权目录:懒加载树(点目录行展开/收起, 每级上限 200 条,超出显示「…还有 N 项」),文件行显示大小并带「复制路径」 按钮(复制相对路径,方便贴给 AI);
  4. 之后 agent 即可使用三个工具:
    • browser_fs_list { path?, recursive? } — 列目录(相对路径/类型/大小,递归可选)
    • browser_fs_read { path, maxBytes? } — 读文本文件(默认上限 256 KiB,截断会标注)
    • browser_fs_write { path, content } — 写文本文件(自动创建父目录,返回字节数)

工具描述里明确告知模型:操作的是浏览器机器的本地盘,不是宿主机文件系统。

卡片界面语言跟随 dsh 的「设置 → 通用设置 → 语言」(插件订阅 dsh 客户端的 locale 服务,切换即时生效;无该服务的组合退回 <html lang>/浏览器语言)。

预览与刷新

「目录内容」树里点文件名弹出预览窗(遮罩 + 固定尺寸窗口 min(720px,92vw) × min(70vh,560px),不随内容伸缩;标题栏钉顶——文件名 + 大小/截断标注 + ✕,其下是相对路径行;内容区独立滚动;✕ / 点遮罩 / ESC 关闭):

  • 图片(png/jpg/jpeg/gif/webp/svg/ico/bmp):读 arrayBuffer 建 blob URL 用 <img> 展示(关闭时 revokeObjectURL);超过 8MB 不拉取,直接提示太大;
  • 其余按文本:只取前 64KB,UTF-8 解码,等宽 <pre> 展示,截断标注 「仅前 64KB」;解码后含 NUL 字符视为二进制,显示「二进制文件不支持预览」。

预览两模式同路径(完整/兼容后端的 readBlob 各自实现),兼容模式只读也能用。

文本预览带语法着色:按扩展名映射语言(js/ts/tsx/py/go/rs/java/c/cpp/h/sh/ yaml/json/toml/md/html/css/xml/sql 等,无映射退回纯文本),先截断前 64KB 再 着色。高亮基于 highlight.js 语言子集 + GitHub Dark 主题;为控制主包体积拆成 独立 chunk —— host 半经 /browser-fs/ws 同目录的 highlight.mjs 路由供给, 预览首次命中已映射语言时才动态加载(加载中先出纯文本并标注「语法着色加载中…」, 失败静默退回纯文本)。

卡片可拖拽换位:标题行是拖拽把手(鼠标/触摸均可,位移 >4px 才算拖拽, 不会吃掉折叠与按钮点击);拖动中面板/球直接贴合指针(钳位不介入),松手 与窗口 resize 时才收敛。球体始终完整留在视口内(贴边允许、不留隐性边距)。 展开面板从未拖过时以球位为锚推导初始位(球在右/下半屏就向左/上翻转展开, 仍出界再 clamp 进 10px 边距,宽高上限收到视口内);一旦被拖过就停在拖放 处(只做视口内 clamp、不再翻转),且跨收起/展开与页面刷新记忆(与球位同 一个 localStorage key dsh-browser-fs:card-pos)。收起态的 📁 圆钮在锚点位 (卡片左上角),圆球同样按住可拖——没移动过的松手才展开。卡片/圆球/预览窗 渲染在 body 级层级(z-100/200),压过常见覆盖层(如侧边栏插件面板),点击 不被别家插件抢走,同时低于 dsh 自身模态框(z-1000+)。

授权按钮行末尾的「↻」是刷新目录:

Related plugins