前言¶
DSH(DeepSeek Harness)在 present 时展示交付文件,卡片上只有「打开」「在侧栏预览」「显示文件位置」。想把文件发给别人,只能先打开、再另存为。浏览器做不到把文件列表写入系统剪贴板(Windows 需要 CF_HDROP),因此这个插件做了一件直接的事:在卡片菜单里增加「复制文件」等选项,通过本地宿主进程调用系统 API,把文件本体放进剪贴板。
插件定位¶
- 名称:dsh-copy-file
- 维护者:jimku233
- 简介:把 DSH 文件卡片里的「文件本体」放进系统剪贴板(CF_HDROP),配合 Windows 风格的卡片交互。
- 适用场景:需要在资源管理器、微信、飞书、邮件附件等地方粘贴文件的开发者与协作场景。
核心功能¶
1. 菜单新增三项¶
卡片右侧菜单新增以下行为(原有「打开方式」与「显示文件位置」保持不变):
| 菜单项 | 行为 |
|---|---|
| 复制文件 | 文件本体进剪贴板(CF_HDROP)。可在资源管理器、微信、飞书、邮件附件区 Ctrl+V |
| 复制全部 N 个文件 | 同一次 present 的全部文件一次放进剪贴板(仅当 N > 1 时出现) |
| 复制文件路径 | 把绝对路径作为文本放进剪贴板 |
2. 降级与提示¶
复制失败时,会自动降级为「复制路径」,并用 toast 说明原因(例如文件已被删除、剪贴板被占用、不支持的系统等),不会假装成功;若连路径都写不进剪贴板,才显示「复制失败,请重试」。
3. Windows 风格卡片交互¶
卡片默认启用 Windows 风格交互:
- 单击 = 选中(底色使用 DSH 自己的 hover 变深)
- 双击 = 在右侧栏打开预览(Enter / Space 同样可以)
- 选中后
Ctrl+C= 复制这个文件 - 拖动卡片:跟随鼠标的半透明 ghost(DSH 现成文件图标 + 小字号文件名)
- 在页面内松手 → 作为当前对话的附件(所有浏览器可用)
- 拖到资源管理器松手 → 落地一份副本(仅 Chromium)
支持范围¶
| 能力 | Edge / Chrome / Brave / Opera 等 Chromium | Firefox | Safari |
|---|---|---|---|
| 复制文件 / 复制全部 / 复制路径 | ✅ | ✅ | ✅ |
| 单击选中、双击预览、Ctrl+C | ✅ | ✅ | ✅ |
| 拖进对话(附件) | ✅ | ✅ | ✅(14.1+) |
| 拖到资源管理器落地副本 | ✅ | ❌ 浏览器不支持 | ❌ |
「复制」不挑浏览器:写剪贴板发生在本地宿主进程里,与浏览器无关。
「拖出去」只有 Chromium 行:靠 dataTransfer 的 DownloadURL,Firefox / Safari 没有这个能力,所以那两个浏览器上不会出现拖拽。
平台:Windows 11 + dsh web,已实测。macOS / Linux 的代码路径已实现(osascript / wl-copy·xclip),未测试,不建议作为成品使用。
安装与启用¶
前提:Node 22.19+、dsh 0.2.0-rc.2、已经能跑 dsh web。
# 1) 克隆到任意位置
git clone <this-repo> dsh-copy-file
# 2) 一键安装(幂等,可重复执行)
cd dsh-copy-file
powershell -ExecutionPolicy Bypass -File scripts/install.ps1
装完重启一次 dsh web,再刷新页面。
安装后,dsh.profile.bundles 末尾会追加 "dsh-copy-file",同时会在 %USERPROFILE%\.dsh\profiles\web\ 下创建 node_modules\dsh-copy-file\ 和安装记录 .dsh-copy-file\install.json。DSH 安装目录本身不会被修改。
典型用法¶
- 在聊天中让模型执行
present展示一个文件。 - 卡片右侧点击箭头,选择「复制文件」。
- 打开资源管理器或微信、飞书等窗口,
Ctrl+V即可粘贴文件本体。
若需要复制全部文件,在 present 同一次返回的多个文件卡片上选择「复制全部 N 个文件」即可。
适用场景与注意¶
- 适用人群:需要频繁把 DSH 交付文件粘贴到本地应用或协作工具的开发者与团队。
- 注意:
- 插件以当前 dsh 进程权限运行,安装前建议查看源码与许可证。
- 只适配 DSH 0.2.0-rc.2,不兼容其他版本。
- macOS / Linux 未测试,不建议在生产环境使用。
已知限制¶
- 拖到资源管理器只有 Chromium 可行(
DownloadURL)。微信 / 飞书聊天窗口是否识别取决于它们自己,最稳的方式是先复制、再在目标里粘贴。 - 任务栏永远不接受文件拖放:拖到任务栏图标上一定是「禁止」光标。要落地请拖进已打开文件夹的文件列表区或桌面。
DownloadURL只认文件系统落点:Explorer 侧栏的文件夹图标、任务栏、微信 / 飞书窗口都会拒绝拖放;拖动过程中 Windows 不会自动把目标窗口提到前台,建议先把文件夹窗口露出来再拖。- 路径超过 260 字符时,剪贴板本身能放,但个别粘贴目标可能截断。
- 会话工作区之外的文件会被拒绝(与「打开文件」能力一致)。
- 改名 / 移动文件后,卡片会指向旧路径,复制与预览会失败,此时「复制文件路径」仍可获取路径。
- macOS / Linux 未测试;Electron 桌面版未测试。
卸载¶
powershell -ExecutionPolicy Bypass -File scripts/uninstall.ps1
卸载会从 dsh.profile.bundles 中移除「dsh-copy-file」这一项,删除 node_modules\dsh-copy-file 和安装记录,并清理可能存在的 helper 进程与自启快捷方式(本版本默认都没有)。刷新页面即可,无需重启。
校验¶
powershell -ExecutionPolicy Bypass -File scripts/verify.ps1 # 已安装时
powershell -ExecutionPolicy Bypass -File scripts/verify.ps1 -ExpectAbsent # 卸载后
校验项包括:包文件完整性、lib/client.js 是否与当前安装的 DSH 上游一致、profile 清单、以及 dsh --profile web --dump-config 中「我们的行存在 / 原生行被禁用」的状态。
安全与隐私¶
插件遵循以下设计原则:
- 不监听任何端口:复制是一次性的
powershell.exe -STA子进程,跑完即退。 - 鉴权:复用 DSH 自己的登录 cookie + Host/Origin 栅栏(和
present.open同一条通道),不引入第二个 token。 - 路由参数:路由没有 path 参数,前端只能传
sessionId / seq / index。 - 越权访问:宿主从只追加的会话日志取声明,再经 Session 文件系统解析,还要
processPathFromHostPath往返一致(同名文件冒充不了),最终符号链接、目录、缺失文件都会被拒绝。 - 读写范围:不读文件内容(只
stat+ 把路径交给系统 API),不写系统目录,临时 JSON 用后即删。 - 联网:不联网、无遥测、不上传任何东西。
- 进程残留:子进程 8 秒超时强杀;卸载会清理 helper 与自启项。
已知攻击面:能调用这些路由的前提是已经登录这个本机 DSH,也就是能打开这个网页的人。
生态背景¶
DSH 的理念是「一切皆插件」。社区目录(如 SkillHub)与 DeepSeek / 幻方无官方从属关系。本插件为社区项目,由 jimku233 维护,开源协议为 MIT。
目录与源码¶
- 目录页:https://www.skillhub.cn/plugins/jimku233/dsh-copy-file
- GitHub:https://github.com/jimku233/dsh-copy-file