前言¶
在 DeepSeek Harness(DSH)里给对话附上本地文件,核心链路已经由官方客户端包负责:校验、上传进度、附件条、提示文案等都在 @deepseek-ai/dsh-client-ui-conversation、@deepseek-ai/dsh-client-file-upload、@deepseek-ai/dsh-client-ui-attachment 等模块里完成。从 DSH 0.1.7 起,核心还能识别拖入的是文件夹,但在浏览器里会拒绝整夹拖入——addFiles() 里若未检测到桌面宿主桥接(globalThis.__DSH_HOST_PATHS__),会提示文件夹只能在桌面应用中添加。桌面端则会把文件夹变成 @path/ 引用芯片,而不是展开成多个可上传文件。
若你主要在浏览器里用 DSH Web profile,又希望一次拖入整个项目目录、让里面的文件走原生上传与附件展示,就需要在「不重复造一套 UI / 上传管线」的前提下,只补上核心没有的那一步:把文件夹展开成单个文件,再交回内置 intake。下面介绍社区插件 dsh-file-drop(维护者 xuechengzou,分类:联网工具)如何承担这一 gap-only 角色。
这是什么¶
dsh-file-drop 是面向 DSH Web composer 附件入口的轻量扩展:拖入文件夹时,用 webkitGetAsEntry() 遍历目录(上限 2000 个文件、16 层深度),收集到的文件会以「仅含文件的普通 drop 事件」重新派发,交给核心原有的 bubble 阶段监听器。因此校验、限额、通知、附件条、流式上传与进度展示与直接拖多个文件时一致,插件本身不渲染 rail、全屏遮罩或 toast,也不写入 drops/ 或注入 @drops/... 引用。
Host 侧 lib/index.js 为 intentional no-op(inject 为空),不改动 ctx.fileUploads / profile 启动行为。版本 2.0.0 相对 1.x 的定位变化在 README 中有说明:1.x 曾自建一套 chip rail 与 capture 阶段 drop 监听并 stopPropagation(),会挡住内置拖放;当前版本只做文件夹展开与 hand-off。
核心功能¶
文件夹展开并交回内置 intake¶
仅在拖放项里确实存在目录 entry 时介入;普通文件拖放立即返回,不修改行为。展开完成后合成 file-only 的 drop,核心的验证、上传路径与 UI 全部沿用官方实现。
有意覆盖的浏览器策略(DSH 0.1.7+)¶
在浏览器中 __DSH_HOST_PATHS__ 不会被赋值, stock 行为是拒绝文件夹拖入。启用本插件后,浏览器可接受拖入文件夹并按单文件加入附件;禁用或移除插件则恢复 0.1.7 及之后默认逻辑(浏览器拒夹、桌面为引用芯片)。README 说明这一覆盖是产品层面的 deliberate choice;hand-off 不含目录语义,展开结果走普通上传路径。
非干扰与 fail-safe¶
README 列出的保证包括:不碰纯文件拖放、不渲染额外 UI、无 Host 注入、无并行存储;若 composer 未挂载或浏览器不支持 directory-entry API,插件不介入,保留核心原有行为。
兼容性说明¶
开发与验证针对 DSH 0.1.6-alpha.2,并在 0.1.7-alpha.1(文件夹契约变更)与 0.2.0-rc.1 上复验。插件只依赖 composer 隐藏 file input 的存在探测([data-composer-card] input[type="file"])与 document drop 事件;README 称 0.2.0 中 addFiles() 的 directoryDesktopOnly 门控与 0.1.7 一致。
安装与启用¶
插件需加入 web profile。官方 README 给出的安装方式为本地目录路径(非 github:owner/repo 一键名):
dsh plugin --profile web add <path-to-this-directory>
将 <path-to-this-directory> 换成本地 clone 或解压后的插件根目录路径。
启用还需同时满足 profile 两层状态(README 原文):
~/.dsh/profiles/web/cordis.patch.yml中需有 force-enable 行:- id: dsh-file-drop且disabled: false。~/.dsh/profiles/web/.dsh-market/state.json的disabled数组里不能仍包含dsh-file-drop;市场会在每次启动时重应用禁用列表,陈旧条目会压住 patch 层的启用。
force-enable 行应放在任意 # <plugin>: begin/end 标记块之外——那些块会由所属插件重写。修改启用状态后需要重启 DSH,或在插件市场面板切换后再刷新页面,浏览器侧 loader 才会加载 client fiber。
典型用法¶
README 未提供独立「业务场景脚本」,可复现的用法即 Web 对话 composer 上的拖放操作:
- 按上一节安装并启用插件,重启或刷新后打开 DSH Web 对话页。
- 从系统文件管理器将整个文件夹拖入 composer 拖放区域(须为含目录 entry 的拖放;纯多文件拖放由核心直接处理,插件不参与)。
- 观察附件条与上传进度:应出现文件夹内各文件的上传卡片,行为与逐个拖入文件相同,而非 stock 浏览器下的「仅桌面可添加文件夹」提示。
仓库内测试命令(用于验证 manifest 与展开逻辑,非最终用户必跑项):
node test/package.test.mjs
node test/logic.test.mjs
适用场景与注意¶
适合谁: 主要在浏览器使用 DSH Web profile、需要一次性拖入目录内大量源码或文档、且希望完全沿用官方附件 UI 与上传限制的智能体或 Harness 使用者。
权限与安全: 插件 client 代码随 DSH Web 进程在浏览器中运行;展开后的文件仍走核心上传与模型侧只读 host path 契约(README 所述)。安装前应阅读 GitHub 仓库 源码与 MIT 许可证(package.json 中 version 为 2.0.0),自行评估是否纳入 profile。
与核心的边界: 本插件不替代桌面端的 @path/ 文件夹引用芯片行为;若需要 stock 0.1.7+ 浏览器拒夹策略,禁用插件即可。遍历上限为 2000 文件 / 16 层,超大目录需自行拆分或改用单文件拖入。
生态说明: DSH 采用「一切皆插件」的扩展方式;SkillHub 目录页 为社区插件索引,与 DeepSeek / 幻方无官方从属关系。
结尾¶
dsh-file-drop 在 DSH 2.x 附件管线已完备的前提下,只补「浏览器拖文件夹 → 展开为多文件 → 交回内置 intake」这一缺口,避免重复 UI 或与 capture 阶段抢事件。需要本地路径安装、正确配置 web profile 启用项并重启或刷新后,即可在 Web composer 里用文件夹拖放批量挂附件。
- 目录页:https://www.skillhub.cn/plugins/xuechengzou/dsh-file-drop
- GitHub:https://github.com/xuechengzou/dsh-file-drop