拖入本地文件到 DSH Web UI,自动插入原始绝对路径而非上传文件内容,文件本体不上传、不复制、不移动。
- 语言
- JavaScript
- License
- BSD-3-Clause
- 分支
- main
安装
$ dsh plugin --profile web add dsh-drag-and-drop在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程
对话式安装
帮我安装 DeepSeek Harness 插件 bill9109/dsh-drag-and-drop:先查看仓库 https://github.com/bill9109/dsh-drag-and-drop 确认安全性,然后执行安装命令并验证插件加载成功。
把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。
一句话定位
在 DSH Web UI 中实现"拖入即插路径":把本地文件或文件夹从系统文件管理器拖到页面任意位置,插件会把原始的操作系统绝对路径写进当前会话输入框,文件本身不会上传、不会复制、不会移动。
核心能力
- 将本地文件或文件夹拖入 Web UI 任意位置,把原始绝对路径写进当前会话输入框
- 拖拽过程中显示全页面压暗 + 模糊提示,松手才提交
- 一次拖入多个文件/文件夹,每条路径占一行追加到草稿(不会覆盖已有输入)
- 支持 macOS、Linux、Windows 原生路径,含 Windows 盘符路径和 UNC 网络路径
- 当浏览器为安全原因隐藏路径时,按"当前 Workspace → 其他 Workspace → 桌面/文档/下载 → 三层浅层扫描 → 系统索引(Spotlight / plocate / locate / Everything)→ 受控目录搜索"顺序在机器上找回真实路径
- 多个候选同名同大小时用文件开头/中间/结尾三段采样指纹比对,大文件仍冲突才计算完整 SHA-256;全部相同则弹出候选列表由用户挑路径
技术实现
- 语言: TypeScript(同时编译出 Node 端 host bundle 和浏览器端 client bundle,已提交到
lib/) - 关键依赖:
@deepseek-ai/cordis(host 端 Cordis 上下文);@deepseek-ai/dsh-client-runtime、@deepseek-ai/dsh-client-ui-conversation(client 端运行时与对话服务);@deepseek-ai/dsh-host-webserver(注册/file-drop/locate路由) - 架构模式: DSH bundle 双端架构。host 半边通过 Cordis
effect在webServer上注册精确路径/file-drop/locate的 POST 路由,负责本机路径定位和指纹计算;client 半边通过cordis.patch.yml把插件挂到dsh.profile.bundles,并通过dsh.client.inject注入到 DSH 的运行时与对话 UI 服务,监听 window 上的dragenter/dragover/dragleave/drop事件,把解析后的路径通过conversation.input.for(scope).setDraft()写进输入状态服务(不直接改 DOM) - 入口文件:
src/index.ts(host)、src/client/index.ts(client)、cordis.patch.yml(bundle 注入点)
适用场景
你想让 DSH 直接操作本机上的真实文件——比如让 Agent 读 ~/Downloads/log.txt、改 ~/projects/foo/bar.py、跑 ~/scripts/build.sh,但浏览器出于沙箱安全不把拖入文件的真实路径交给网页,普通拖拽要么变成上传副本,要么只能手敲易错路径。这个插件在运行 DSH 的本机上把这条链路补齐:拖一下,原始绝对路径就在输入框里,文件本体始终不离开它所在的目录。
前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH | 未声明 | 仅在 package.json#dsh.client.platform 声明走 web profile,安装命令 --profile web |
| Node.js | ^20.0.0 或 >=22.0.0 | 来自 package.json#engines.node |
| 平台 | macOS / Linux / Windows | 跨平台运行;Linux 推荐 plocate,Windows 推荐 Everything CLI,Windows 下提供 PowerShell 兜底 |
| 原生模块 | 无 | 仅使用 Node.js 内置模块(node:os / node:path / node:fs/promises / node:crypto / node:child_process / node:http)和浏览器 WebCrypto |
安装方式
dsh plugin --profile web add github:bill9109/dsh-drag-and-drop
安装或升级后请重启 DSH Web 服务,再在浏览器做硬刷新(Cmd/Ctrl+Shift+R),客户端 bundle 只在全新页面加载时挂载。
配置项
本插件无需额外配置。安装即用,没有 Schema、没有 config.yaml、不读取环境变量。
常见问题
Q: 拖入文件会上传到服务器吗?会复制/移动文件吗?
A: 不会。插件只在浏览器读取拖入项的文件名、大小、修改时间等元数据;只有在多个候选同名同大小时,才会读取少量文件内容计算指纹用于比对。整个过程文件始终留在原目录,不上传、不复制、不移动、不修改、不删除。
Q: 安装后为什么没反应?
A: 客户端 bundle 只在全新页面加载时挂载,所以安装或升级后必须先重启 DSH Web 服务,再在浏览器做硬刷新(Cmd/Ctrl+Shift+R)。可以用 dsh --profile web --dump-config | grep drag-and-drop 确认 bundle 已注册到 profile。
Q: 大磁盘上拖入后等很久才出结果,怎么加快?
A: 拖入命中速度取决于本机索引。Linux 推荐安装 plocate,Windows 推荐安装 Everything CLI(提供 es.exe),插件会优先调用它们;macOS 自带 Spotlight,无需额外配置。把文件放在 Workspace 或常用目录内也能命中更快的浅层扫描路径。
Q: 拖入后插入了错误的同名文件副本,怎么办?
A: 候选先按完整文件名和大小过滤,再用文件开头/中间/结尾三段采样指纹比对;如果大文件采样后仍无法区分,才会计算完整 SHA-256;若仍有字节级相同的副本,插件会弹出候选路径列表让你点选。
Q: 拖入后浏览器弹了"不支持的图片格式"提示,正常吗?
A: 这是被插件主动替换过的:拖入文件/文件夹但目标不是图片时,原 toast 会显示为"不支持的图片格式:xxx(已由拖拽插件插入文件路径)"。插件告诉你"已被拖拽插件处理过",原始绝对路径已经写进会话输入框,不是真的失败。
Q: 文件夹能拖吗?一次拖多个会怎样?
A: 文件和文件夹都能拖。一次拖多个项目时,插件按"Workspace 优先 → 系统索引"的策略逐个解析,每个候选路径各占一行写入当前会话输入框的草稿;已经存在的草稿内容不会丢,会换行追加。
Q: 怎么升级、怎么卸载?
A: 升级用 dsh plugin --profile web update github:bill9109/dsh-drag-and-drop;卸载用 dsh plugin --profile web remove @omdsh-dev/dsh-drag-and-drop,之后再重启 Web 服务并硬刷新浏览器。如果是本地 checkout 安装,升级时直接对替换后的目录重新执行 add。
上手难度
入门 — 一条 dsh plugin 命令安装即用,无需配置文件、无需环境变量,安装后重启 Web + 硬刷浏览器就能生效。
已知问题与限制
- 拖入后浏览器隐藏路径、且文件位于所有可搜索根(当前/其他 Workspace、桌面/文档/下载、用户主目录、Linux 的
/mnt与/media、Windows 的固定盘)之外时无法定位,会弹"未能定位原始路径"toast(README.md:82) - 单次外部索引命令(Spotlight / plocate / locate / es.exe / PowerShell)3 秒超时,最多保留 100 个候选路径;超时或命中过多会回退到下一级搜索(
src/platform-search.ts:8-9、src/locator.ts:11) - 浅层三目录扫描每个搜索根最多展开 4,096 个直接子目录;递归搜索每个根最多访问 20,000 个目录项、最深 12 层(
src/locator.ts:11-15) - 文件夹结构匹配最多 10,000 个条目、最深 32 层,不跟随符号链接和 Windows junction(
src/directory.ts:3-4、src/directory-node.ts:18) - 大文件(> 8 MB)多候选采样指纹仍冲突时,会计算完整 SHA-256,对超大型文件可能耗时明显(
src/locator.ts:205-207、src/fingerprint.ts:36-51) - 拖入请求体(POST
/file-drop/locate)上限 4 MB,超出会被 host 拒绝(src/index.ts:8) - Windows 上 Everything CLI(
es.exe)输出使用控制台活动代码页(中文系统为 GBK),插件会同时用 UTF-8 与 GBK 解码并挑出能复现请求文件名的结果;如果你的系统代码页既不是 UTF-8 也不是 GBK,非 ASCII 文件名可能仍无法精确匹配(src/platform-search.ts:100-117) - 不读取
config.yaml,旧 README 描述的pnpm add + config.yaml流程已废弃(README.md:55) - 源码中未发现
TODO/FIXME/HACK/XXX注释;0.1.5 起新增的三层浅层扫描主要解决"深度 2 的文件被直接子项扫描漏掉、又被 20,000 项递归预算耗光"问题(CHANGELOG.md:14-19)
Install: dsh plugin --profile web add github:omdsh-dev/dsh-drag-and-drop
A DeepSeek Harness Web UI plugin: drag local files or folders onto any part of the page and their original absolute filesystem paths are inserted into the current conversation input — without uploading, moving, or copying anything.
Why this exists
A browser never hands a web page the real filesystem path of a dropped file — it exposes only a local file URI when it feels like it, and often nothing at all, for security. DSH, though, operates on real files: its tools read, run, and patch actual paths on the machine. Drop a file into an ordinary web input and you get either an upload (a copy that silently breaks the file's relationship with its neighboring dependencies) or a hand-typed path that is easy to get wrong.
This plugin closes that gap on the machine running DSH. It converts the browser's local file URI into the native absolute path, and when the browser hides the path entirely it resolves the file back to its real location — through the current Workspace, registered Workspaces, the OS file index, and a bounded directory search — then writes that path into the current conversation input. The file never leaves its directory.
Features
- Drag files onto any part of the Web UI to insert their original absolute paths
- Full-page dim + blur hint while dragging
- Supports files and folders; drag multiple items at once — one path per line
- Native paths on macOS, Linux, and Windows
- POSIX paths, Windows drive-letter paths, and UNC network paths
- No uploading, moving, or copying of files
- Locates files in the current Workspace and registered Workspaces first
- When the browser hides the original path, uses the local file index and bounded directory search
- Computes content fingerprints only when multiple candidates exist
- When several byte-identical copies cannot be told apart automatically, lets the user pick the path
- Failed lookups surface as a dismissible plugin toast (auto-dismisses after 8s; hovering pauses the timer)
- Writes the draft via DSH's input-state service instead of touching the input DOM
Usage
Drag files or folders from Finder, a Linux file manager, or Windows Explorer onto any part of the DSH Web UI.
Release the mouse when the full-page drag hint appears; the plugin writes the resolved original absolute path into the current conversation input.
Dropping multiple items at once inserts one path per line.
Install
The plugin is a DSH bundle (package.json declares dsh.bundle + dsh.client). Install it into the web profile with the standard dsh plugin mechanism — no DSH source changes and no config.yaml needed:
dsh plugin --profile web add github:omdsh-dev/dsh-drag-and-drop
# or from a local checkout:
dsh plugin --profile web add /path/to/dsh-drag-and-drop
The repository ships its build output (lib/ is committed) — no build step needed after installing.
The old README's
pnpm --filter @deepseek-ai/dsh add ...+config.yamlflow is obsolete: under the official profile/bundle modelconfig.yamlis no longer read.
After installing, restart the Web UI the way you normally start DSH, then refresh the browser page — the plugin appears in the browser boot manifest (__DSH_BOOT__) and its client bundle loads automatically.
Upgrade
dsh plugin --profile web update github:omdsh-dev/dsh-drag-and-drop
For a local-path installation, run add again against the replacement checkout.
Uninstall
dsh plugin --profile web remove @omdsh-dev/dsh-drag-and-drop
The command removes the package from the profile and from dsh.profile.bundles. After uninstalling, restart the Web UI and hard-refresh the browser.
Troubleshooting
| Symptom | Resolution |
|---|---|
| Dropping a file inserts nothing | Drag again and confirm the full-page hint appears. Verify the bundle is in the profile (`dsh --profile web --dump-config |
| Wrong path inserted when several copies share a name | Candidates are filtered by full file name and size, then content-sampled only among the survivors. If byte-identical copies remain, the plugin shows a chooser — pick the correct path there |
| Path resolution is slow on a large disk | Install the platform index (Linux: plocate; Windows: Everything CLI) and keep files inside a Workspace or a common directory. Every search is bounded: 3s per index command, at most 100 candidates, at most 20,000 directory entries per root |
| macOS/Linux: dropping a folder resolves nothing | Folders are matched by name against Workspaces and common directories; a folder outside every searchable root cannot be located when the browser hides the path — move it into a Workspace or install the OS index |
| Plugin does not load after install | Restart the Web UI and hard-refresh the browser — the client bundle only loads on a fresh page load with the plugin in __DSH_BOOT__ |
Path resolution
If the browser exposes a local file URI, the plugin converts it directly into the operating system's native path.
If the browser hides the original path for security reasons, the plugin locates the file in this order:
- The current Workspace
- Other registered Workspaces
- Desktop, Documents, and Downloads
- A depth-1..3 shallow scan within each search root: the root's direct child, the direct children of its direct subdirectories, and the direct children of those subdirectories — this resolves the vast majority of real drops (e.g.
~/Downloads/dump2 11/iotclaw.ndjson) without walking the whole tree - The operating system's file index
- A bounded, platform-specific directory search
System indexes used per platform:
- macOS: Spotlight
- Linux:
plocatefirst, thenlocate - Windows: Everything CLI first, then PowerShell
On Linux, when the system index returns no candidates, the plugin also searches the user home directory and mount points under /mnt and /media.
On Windows, when the system index returns no candidates, the plugin also searches the user directory and available fixed disks.
To keep searches bounded:
- a single external index command times out after 3 seconds
- at most 100 candidate paths are kept
- the depth-3 shallow scan expands at most 4,096 direct subdirectories per root
- each recursive search root visits at most 20,000 directory entries
- unreadable directories and files are ignored
Candidate confirmation
Candidates are first filtered by:
- the full file name
- the file size
Modification time is used only for ranking candidates, never as identity.
<<<<<<< HEAD If only one candidate remains, the plugin uses that path directly without reading the file's content.
每一层搜索都先做浅层快速定位:先检查搜索根的直接子项,再检查直接子目录与孙目录内的直接子项(共三层以内的文件,绝大多数拖拽都在这一范围内),随后才查询该范围内的操作系统索引,最后才递归目录。当前 Workspace、其他 Workspace 和常用目录的优先级保持不变。
4bab506 (feat: resolve dropped-file paths up to three levels deep)
If multiple candidates remain, the plugin compares sampled fingerprints from the beginning, middle, and end of the files. Only when sampled fingerprints of large files still collide does it compute a full SHA-256.
If several paths correspond to byte-identical files, the plugin shows the list of paths and lets the user choose which one to insert.
Folders are first searched by name only. A unique candidate is returned directly without traversing the browser directory; multiple same-name candidates are compared by sorted relative path, project type, and file size. For directories that are structurally identical, content samples of up to 24 deterministically chosen files are computed; if still identical, the user picks the path. Directory traversal processes at most 10,000 entries and 32 levels deep, and never follows symlinks or Windows junctions.
Each search level first checks the direct children of the search root, then queries the OS index within that scope, and only then recurses into directories. The priority of the current Workspace, other Workspaces, and common directories is preserved.
Privacy & file access
The plugin never:
- uploads files
- copies files
- moves files
- modifies files
- deletes files
In most cases the plugin only reads file metadata.
Only when multiple candidates share the same name and size does it read a small amount of content to compute sampled fingerprints, and only when large files cannot be told apart by sampling does it read the full content to compute SHA-256.
All resolution and fingerprinting happens locally on the machine running DSH.
Platform notes
macOS
Finder drag-and-drop and the Spotlight index are supported. Verified in Chrome on macOS.
Linux
File managers that provide text/uri-list are supported. When the browser hides the path, the plugin searches Workspaces, common directories, plocate, locate, and bounded mount directories.
Installing plocate is recommended for faster global path resolution.
Windows
Drive-letter paths and UNC network paths are supported. When the browser hides the path, the plugin prefers the Everything CLI; without Everything it uses PowerShell to search the user directory and fixed disks.
Installing Everything and its command-line tools significantly speeds up path resolution on large disks.
Development and verification
The build script needs a DSH checkout. By default it locates one through the dsh command; you can also point it explicitly:
DSH_CHECKOUT=/path/to/dsh pnpm run build
Run tests:
pnpm test
Type-check:
pnpm run check
Build:
pnpm run build
Repository layout:
src/— host (node) half: path resolution, directory walk, fingerprinting, platform search, and the file-locate HTTP routesrc/client/— browser half: drag handling, drop items, path locator, candidate chooser, toast UItests/— vitest suites for the host and client logiclib/— committed build output (host + client bundles)
Community and About
- Use GitHub Issues for reproducible bugs, focused feature requests, and usage questions.
- Read CONTRIBUTING.md before proposing changes; report vulnerabilities privately via SECURITY.md.
- Follow releases and compatibility notes in CHANGELOG.md.
License
BSD-3-Clause
查看使用指南 →
该插件的安装步骤、关键要点、FAQ 与兼容性说明(基于已收录字段派生)。
收录徽章
[](https://deepseek-plugin.org/plugins/bill9109/dsh-drag-and-drop)把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。