dsh-folder-drop
把文件夹拖进 DeepSeek Harness,得到它的原生绝对路径。
Drag a folder into the DSH Desktop composer and get its real absolute path in the draft — no copy, no upload.
DSH 的 composer 原生只收文件。拖放链路只读 dataTransfer.files
(@deepseek-ai/dsh-client-ui-attachment 的 ComposerAttachments),文件选择器是没有
webkitdirectory 的 <input type="file" multiple>,粘贴只认 kind === "file" 的项;
而浏览器从不把目录内容当 File 交出来。结果是:拖文件夹要么毫无反应,要么在附件栏里
变成一个 0 字节空壳。
本插件补上这一段:目录拖进来 → 直接把路径写进草稿,交给 agent 自己的文件工具去读。
行为
| 拖放内容 | 结果 |
|---|---|
| 纯文件 / 纯图片 | 一行不碰,完全交回 DSH 原生附件链路 —— 附件栏、上传进度、失败重试、图片预览全部保持原样 |
| 含文件夹(可以与文件混拖) | 本插件独占本次拖放:把每一项的原生绝对路径按换行追加进当前草稿;同时补一个 synthetic dragend,让 DSH 的全屏拖放遮罩正常收起 |
| 含文件夹但取不到路径 | 通过 DSH 自己的 error 提示报出失败项名,绝不静默 |
写入走 DSH 公开的输入门面(不触碰输入框 DOM):
ctx.conversation.input.for(ctx.sessions.scope(sessionId)).setDraft(text)
路径从哪里来
按优先级依次尝试:
window.__DSH_DESKTOP_FILE_PATH__.getPathForFile(file)—— DSH Desktop 的preload.cjs已用contextBridge暴露的 ElectronwebUtils(拿到真实路径的正规入口)file.path—— 旧版 Electron 的历史属性entry.file()—— 个别 Chromium 版本只在目录项上给这条异步通道text/uri-list/text/plain里的file://URL —— 整批兜底
时序约束:Chromium 的 DataTransfer 保护模式让
items[i].webkitGetAsEntry()、items[i].getAsFile()、dataTransfer.getData()只在 drop 事件派发期间有效。 本插件在 drop 处理器的同步段把这些一次性读成快照,异步段只用快照 —— 改代码时别"优化"成惰性读取。
安装
# 从 GitHub 装
dsh plugin --profile desktop add github:chiyu-star499/dsh-folder-drop
# 或从本地目录装
dsh plugin --profile desktop add file:/path/to/dsh-folder-drop
profile 认准
desktop:DSH Desktop(GUI)跑的是desktopprofile;dsh/dsh web默认是web,装进web对 GUI 无效。装完必须重启 DSH Desktop:配置与插件装载改动不依赖
patchReload: live。
add file:<目录>实测是拷贝安装(不是软链)——改源码后需要重新add才会生效。
卸载
dsh plugin --profile desktop remove dsh-folder-drop
然后重启 DSH Desktop。插件不写任何状态文件,卸载即彻底还原;profile 的 package.json
与 cordis.patch.yml 由 dsh plugin 自动登记/移除。
兼容性
| 组件 | 版本 | 状态 |
|---|---|---|
| DSH Desktop | 2.0.13 | ✅ 真机验收通过 |
dsh 核心 |
0.1.5-rc.2 | ✅ |
依赖的是 ctx.sessions.scope() / ctx.conversation.input.for() / .setDraft() / .notify()
这些公开客户端服务面。核心里这几处若在后续版本改名,插件需要跟着改(见下方「开发」)。
开发
node ./scripts/build-client.mjs # src/client.js → lib/client.js(__ModuleLoader__ 外壳)
node ./scripts/smoke.mjs # 38 条断言:清单契约 / 产物形态 / 纯函数 / drop 行为
lib/client.js 是生成物,不要手改:改 src/client.js 后重跑构建,再重新 add。
客户端 bundle 的形态是 DSH 客户端模块系统要求的
window.__ModuleLoader__.load({ id, factory }) + 惰性 CJS factory;宿主按
package.json 的 exports["./client"] 解析入口,缺失 lib/client.js 会让插件激活直接失败。
已知边界
- 只处理 drop。文件夹没法粘贴,picker 也选不了目录 —— 那是 DSH 原生缺口,本插件不碰。
- 混拖时文件也走「插路径」而不是「附件上传」:DSH 的 drop 事件无法只拦掉其中一项。要附件上传就纯拖文件。
- 普通浏览器里没有 file-path 桥,拿不到本地路径;这时会明确报错,而不是插入错误的内容。
- 与
dsh-drag-and-drop、dsh-drop-to-path功能重叠,不要同时安装。
许可
MIT © 2026 chiyu-star499
API 用法参考了 dsh-drag-and-drop
(BSD-3-Clause)对 DSH 客户端服务面的用法;本插件为独立实现,且不需要它那套 host 侧定位引擎
(DSH Desktop 直接给真实路径)。
No comments yet. Be the first to write one.