🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

文件树下载 Yingblock/dsh-plugin-files-download

DeepSeek Harness
Yingblock13 天前有提交已提供中文文档扫描:未发现敏感能力

在文件树每行添加下载按钮,一键保存原文件

29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/24 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Yingblock/dsh-plugin-files-download
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么[目录]—
dsh 原生插件 · ui
暂无时间戳·判据 →
装得上吗[实装验证]—
本站尚未做安装检查
暂无时间戳·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/03·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 13 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安全扫描自动 · 静态分析源码
v2.7.0
🟢 扫描:未发现敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。

扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DSH 网页界面文件树的每一行都有下载按钮,由一条带鉴权的流式 Host 路由提供。

README

由 DeepSeek 最新模型翻译生成
dsh-plugin-files-download(中文) 给 DSH Web GUI 的文件树每一行加一个下载按钮。点一下,文件就以原文件名保存到本地;字节由宿主流式发送,不进页面内存、没有大小上限。 文件 /home/me/project ├─ src/ ← 目录行:没有按钮 ├─ README.md ↓ ← 文件行:常驻下载按钮 └─ package.json ↓ 它做了什么 | 半 | 文件 | 职责 | | 宿主 | lib/index.js | 在 Connection 的鉴权围栏内注册 GET\|HEAD /api/workspace-file.download?sessionId=…&path=…。按 Remote 查找同样的方式解析会话工作区根,先 stat 拒绝不存在/目录/符号链接,再按 1 MiB 窗口经 ctx.workspaceFiles 流式输出,带 content-disposition: attachment 和原文件名。 | | 浏览器 | lib/client.js | 往文件树的 sidebar.right.files.row.actions seat 注册一个 cell。cell 就是指向该路由的 ,进度、取消、保存名都由浏览器下载管理器负责。
展开完整文档(README 剩余 1 节)
dsh-plugin-files-download(中文)

给 DSH Web GUI 的文件树每一行加一个下载按钮。点一下,文件就以原文件名保存到本地;字节由宿主流式发送,不进页面内存、没有大小上限。

文件 /home/me/project ├─ src/ ← 目录行:没有按钮 ├─ README.md ↓ ← 文件行:常驻下载按钮 └─ package.json ↓

它做了什么

| 半 | 文件 | 职责 |
| 宿主 | lib/index.js | 在 Connection 的鉴权围栏内注册 GET\|HEAD /api/workspace-file.download?sessionId=…&path=…。按 Remote 查找同样的方式解析会话工作区根,先 stat 拒绝不存在/目录/符号链接,再按 1 MiB 窗口经 ctx.workspaceFiles 流式输出,带 content-disposition: attachment 和原文件名。 |
| 浏览器 | lib/client.js | 往文件树的 sidebar.right.files.row.actions seat 注册一个 cell。cell 就是指向该路由的 ,进度、取消、保存名都由浏览器下载管理器负责。 |

不重写文件树:seat 由 @deepseek-ai/dsh-client-ui-sidebar-files 声明,本包只负责填充。

前置要求

所挂载的 @deepseek-ai/dsh-client-ui-sidebar-files 客户端 bundle 必须声明 sidebar.right.files.row.actions seat。早于该 seat 的官方版 DSH 没有它,此时本插件的注册会在浏览器端加载报告里明确报错,不会半渲染。补法见「需要先有这个 seat」。

- Node:>= 22(宿主半用了 AbortSignal.any 与 WHATWG ReadableStream)
- 浏览器:现代浏览器即可(下载是一次普通导航,不依赖任何客户端专有 API)

安装

包里是预构建好的 JavaScript,安装不需要构建步骤。

直接从 GitHub 装(pnpm 原样转发 git 规格)
dsh plugin --profile web add github:Yingblock/dsh-plugin-files-download

或从本地目录/压缩包装
dsh plugin --profile web add /path/to/dsh-plugin-files-download

也可以手动在 profile 的 cordis.patch.yml 里加一行:

- insert:
- id: files-download
name: dsh-plugin-files-download

装完必须重启 dsh web:客户端的 boot graph 只在启动时组装,开着的页面不会自己换。

重启后浏览器要硬刷新(Ctrl+Shift+R)。只有在跑 pnpm run dev:web 时,bundle 的 HMR 才会自动生效。

卸载

dsh plugin --profile web remove dsh-plugin-files-download

使用

1. 打开右侧栏的 文件 标签。
2. 每个文件行右侧常驻一个 ↓ 控件(不需要悬停);目录行没有。
3. 点它,浏览器按原文件名保存。

控件是对宿主路由的一次真实导航,不是页面内 fetch,所以几百 MB 的文件也是直写磁盘。

需要先有这个 seat

sidebar.right.files.row.actions 这个 seat 必须加在文件树自己的包里,因为行归它渲染。共 4 个文件,位于 packages/client/ui-sidebar-files:

| 文件 | 改动 |
| src/client/slot-contract.ts(新增) | 声明 seat:kind: 'single'、scope: 'session',owner props 为 { path, name } |
| src/client/index.ts | 文件树 body 注册时声明子 seat:children: { 'sidebar.right.files.row.actions': { kind: 'single', scope: 'session' } } |
| src/client/FilesBody.tsx | 文件行里渲染该 seat:renderSlot('sidebar.right.files.row.actions', { path, name }) |
| src/client/FilesBody.module.css | 行改 display:flex;操作容器 flex: 0 0 auto |

然后只重建这一个包:

tsc -b packages/client/ui-sidebar-files
pnpm --filter @deepseek-ai/dsh-client-ui-sidebar-files run bundle

再重启 dsh web 并硬刷新浏览器。

为什么必须是 single 而不是 keyed?
keyed seat 是按注册 key 分发的(entriesOfSlot(key).find(e => e.options.key === entryKey)),而它的键域是编译期固定的。文件行是运行期动态集合、插件无法预先枚举,用常量 key 注册就永远匹配不上树按行分发的 key —— cell 留在账本里但永远不渲染。正确形状是一个 single seat 每行渲染一次,把该行身份放在 owner props 里传下去。

自查

宿主侧(不带 cookie 就能看出路由在鉴权之后):

curl -s -o /dev/null -w '%{http_code}\n' \
'http://127.0.0.1:3080/api/workspace-file.download?sessionId=x&path=y'
401(未鉴权)

带 cookie 时的状态码:

| 情况 | 响应 |
| 正常 | 200,流式字节,content-disposition: attachment |
| 缺 sessionId/path | 400 missing sessionId or path query parameter |
| 会话不存在 | 404 session not found |
| 文件不存在 | 404 |
| 不是普通文件 | 422 |

浏览器控制台:

JSON.stringify(globalThis.__DSH_FILES_DOWNLOAD__)
// {"apply":true,"registered":true,"renders":9,"version":"single-seat"}
// renders 应等于当前渲染的文件行数

globalThis.__DSH_FILES_DOWNLOAD__ 是只读诊断对象,不产生 UI、无渲染开销。

已知边界

- 只支持文件,不做目录打包下载。
- 会话作用域:路由按活动会话 header 解析工作区根,冷会话回退到持久化的 header-only stat。GUI 当前会话总是活动的,正常使用无感。
- 读权限等同 ctx.fs:内置预览能读的文件就能下载,包括工作区之外的路径。
- 保存名取文件自身 basename:平台非法名或重名由浏览器处理,本包不改写。
- 按钮常驻可见(设计如此)。想改回悬停显示:在文件树样式里给 .actions 加 opacity: 0,并补 .item:hover .actions 规则。

许可

MIT,见 LICENSE。
预览分享卡片长什么样 ↓Yingblock/dsh-plugin-files-download
分享 · DeepSeek Harness Hub
Yingblock/dsh-plugin-files-download

在文件树每行添加下载按钮,一键保存原文件

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部