Saltar al contenido principal
N

dsh-file-drop

nafiygond/dsh-file-drop

A drag-and-drop file plugin for DeepSeek Harness to easily attach files and paste paths into the chat.

Instalar

dsh plugin --profile web add github:nafiygond/dsh-file-drop

README

dsh-file-drop

test npm

English: Drag a PDF or .py file straight into the DeepSeek Harness composer. The plugin uploads the bytes out-of-band, inserts a plain-text [file attachment ...] note, and the model reads the content through the read_file_attachment tool — with a dependency-free built-in PDF text extractor. Zero runtime dependencies, no build step.

PDF / .py 文件直接拖进 DSH(DeepSeek Harness)对话框,模型自动读取并分析内容的小插件。

  • 🚫 零运行时依赖:PDF 文本提取是内置的纯 JS 实现(Node 内置 zlib + 手写解析器),不装 pdf.js,不依赖任何其他 DSH 插件
  • 📦 纯 ESM、无需构建:装完即用,没有 npm run build
  • 🔌 双平面封装:host 半(上传路由 + read_file_attachment 工具 + PDF 提取器)+ browser 半(拖拽拦截 + 输入框插入),各模块互相独立
  • 🗂 文件落盘镜像:拖入的文件同时存到当前工作区 .dsh-drops/,你(和模型自己的文件工具)都能直接看到原文件

效果

  1. 把任意 .pdf.py 文件从资源管理器拖进 DSH 窗口,松手;
  2. 输入框末尾自动出现一条 [file attachment {"attachmentId":"sha256:…","kind":"pdf","name":"论文.pdf",…}] 引用(文件字节本身不进对话);
  3. 发送你的问题(如「总结这篇论文的方法」),模型调用 read_file_attachment 工具拿到 PDF 文本层 / Python 源码后进行分析。
sequenceDiagram
    participant U as 用户拖入 .pdf/.py
    participant C as browser 半 (lib/client.js)
    participant R as /dsh-file/attach (lib/routes.js)
    participant S as 内存存储 (lib/store.js)
    participant T as read_file_attachment (lib/tool.js)
    participant P as PDF 提取器 (lib/pdf-text.js)
    U->>C: 拖放文件(capture 阶段拦截,图片照旧走官方逻辑)
    C->>R: POST base64 字节 + kind + cwd
    R->>S: sha256 内容寻址存储(FIFO 上限 64 条)
    R->>U: 镜像写入 <cwd>/.dsh-drops/<文件名>
    R-->>C: 返回 [file attachment …] 引用
    C->>C: 插入当前会话输入框草稿
    Note over T: 用户发送消息,模型看到引用
    T->>S: 按 attachmentId 取字节
    T->>P: PDF? 提取文本层(Flate/LZW/ToUnicode/...)
    T-->>T: 返回文本(支持 start/maxChars 分页续读)

安装

环境:Node 22.19+(DSH 自带)、dsh CLI。

方式 A:本地仓库链接安装(推荐,改代码最方便)

# 1. 克隆本仓库
git clone <your-repo-url> dsh-file-drop
# 2. 把包链接进 web profile
dsh plugin --profile web add link:D:/path/to/dsh-file-drop

⚠️ 链接安装的依赖解析:DSH 的模块回退机制对 link 包按真实目录解析依赖(Node 默认跟随符号链接),所以本仓库目录下需要一个指向 DSH 安装目录的扁平链接。安装后运行一次:

node scripts/link-host-deps.mjs D:/path/to/DSH   # 例如 D:/xl/DSH,或设置 DSH_APP_ROOT 后省略参数

该链接位于被 .gitignore 忽略的 node_modules/ 下,不影响 Git 提交。

方式 B:从 npm 安装(发布后)

dsh plugin --profile web add dsh-file-drop

两种方式都还需要最后一步 —— 把 host 插件挂进 profile 的补丁层。编辑 ~/.dsh/profiles/web/cordis.patch.yml,追加:

# dsh-file-drop:拖入 PDF/.py 自动引用 + read_file_attachment 工具
- insert:
    - id: dsh-file-drop
      name: 'dsh-file-drop'

重启 DSH(完全退出再启动,或重启服务器进程),刷新 GUI 页面即可。

或者作为 profile bundle 安装:把 "dsh-file-drop" 加进 profile package.jsondsh.profile.bundles 列表 —— 此时本仓库自带的 cordis.patch.ymldsh.bundle.patch)会自动生效,无需手改补丁层。

使用

  • 支持的文件.pdf(≤ 24 MiB)、.py(UTF-8 文本 ≤ 2 MiB)
  • 图片拖入不受影响,仍走 DSH 官方图片逻辑;混合拖入时,PDF/.py 被本插件接管,其余文件会提示「已忽略」
  • 多文件可一次拖入;每条引用占一行
  • 拖入的文件存在 当前会话工作区/.dsh-drops/ 下,重名自动加 -2-3
  • 大文件:工具默认一次返回 12 万字符,truncated: true 时模型会按 start 续读,无需你干预

目录结构(封装说明)

文件平面职责
lib/index.jshost入口:注册工具 + 上传路由,导出公共 API
lib/tool.jshostread_file_attachment 工具定义(参数校验/输出 schema/分页)
lib/routes.jshost/dsh-file/attach HTTP 路由 + 上传载荷校验 + 落盘镜像
lib/store.jshost内存附件注册表(sha256 内容寻址,FIFO 上限 64 条)
lib/pdf-text.jshost零依赖 PDF 文本层提取器(详见下节)
lib/client.jsbrowser拖拽拦截(capture 优先于官方 handler)、上传、草稿插入、toast
cordis.patch.yml补丁插件挂载行(bundle 安装时自动应用)
scripts/link-host-deps.mjs工具为链接安装创建 host 依赖扁平链接(见安装说明)
test/测试node --test,覆盖提取器/过滤器/存储/上传校验

PDF 提取器能力与边界

支持FlateDecode / LZWDecode / ASCIIHex / ASCII85 过滤器;ObjStm 对象流(PDF 1.5+);Tj/TJ/'/"/T*/Td/TD/Tm 文本算子;/ToUnicode CMap (bfchar+bfrange,中文 CID 字体通常可正确提取);/Encoding /Differences 西文字形名;WinAnsi/Standard 编码与 UTF-16BE 字符串;TJ 负向 kerning 的空格启发式。

不支持的边界:纯扫描/图片型 PDF(没有文本层,工具会明确提示「未能提取到文本」,此时可让模型用 .dsh-drops/ 里的原文件自行 OCR);无 ToUnicode 的 CID 子集字体;Form XObject 文本仅在整页提取为空时通过兜底扫描兜住。

在作者真实语料上的表现:34/66 篇 PDF 完整提取(含 200 万字符的扫描书目、BIG-bench 等),平均约 115 ms/篇;其余为无文本层的扫描件。

安全与限制

  • 附件注册表是进程内内存存储:DSH 服务器重启后旧引用失效,工具会提示重新拖入(磁盘镜像文件仍在 .dsh-drops/
  • 上传路由仅在本机 loopback GUI 内使用;cwd 由客户端随请求携带,落盘限定在 <cwd>/.dsh-drops/,文件名经 basename 清洗、拒绝路径穿越
  • PDF 字节上限 24 MiB,.py 上限 2 MiB,可在 lib/routes.js 的常量处调整

上传到 GitHub

本仓库已经按发布标准包装好:MIT License、node --test 测试(12 例)、GitHub Actions CI(.github/workflows/test.yml,Node 22/24 双版本)、npm pack 白名单(files 字段)、npm 生命周期钩子 prepack(发布前自动跑测试)。发布前只需:

cd D:/xl/plugin/dsh-file-drop
git init -b main

# 1) 首次提交需要身份(换成你自己的名字/邮箱)
git config user.name "Your Name"
git config user.email "you@example.com"

git add .
git commit -m "dsh-file-drop: drag PDF/.py into the composer for analysis"

在 GitHub 上新建空仓库 dsh-file-drop(不要勾选 README/.gitignore/license,避免冲突),然后:

git remote add origin https://github.com/Nafiygond/dsh-file-drop.git
git push -u origin main

推送后第一件事:Settings → Actions → General → Workflow permissions 勾选 Read and write permissions(CI 徽章需要),随便推一个 commit 触发一次 workflow,看到 ✅ 即可。

发布到 npm(可选)

npm login
npm publish        # prepack 会自动先跑测试;dry-run 预览: npm pack --dry-run
  • 包名 dsh-file-drop 未带 scope,若已被占用或想用 @you/dsh-file-drop,需同步改 4 处:package.jsonnamecordis.patch.ymlnamelib/index.jsexport const namelib/client.js__ModuleLoader__.loadid(四处保持一致即可);
  • 发布后 README 里方式 B(dsh plugin --profile web add <包名>)对其他人即可用。

加分项:录一段 10 秒拖拽演示 GIF 放在 README 顶部;LICENSE 里的 Copyright 换成你的名字。

开发与测试

npm test        # node --test,无需构建
node scripts/link-host-deps.mjs <DSH 安装目录>   # 链接安装后运行一次

修改 host 半(lib/*.js 除 client.js)→ 重启 DSH 生效;修改 browser 半 (lib/client.js)→ 重启 DSH 并刷新页面(客户端 bundle 在启动时按 rev 哈希注入)。

License

MIT

Plugins relacionados