dsh-pdf-extractor
v1.0.1
Published
PDF text / per-page / layout / table extraction CLI and library for DeepSeek Harness (DSH) agents, powered by pdfjs-dist.
Maintainers
Readme
dsh-pdf-extractor
为 DeepSeek Harness (DSH) 代理准备的 PDF 解析插件包:提供 dsh-pdf 命令行工具与
Node.js API,支持全文提取、按页提取、带坐标的布局提取、启发式表格提取与关键词搜索,
底层基于 pdfjs-dist(legacy build,纯 JS、无原生依赖、无 worker 线程)。
不修改 DSH 任何核心代码 —— 通过「独立 npm 包 + 一份 DSH Skill 定义」以插件形式接入。
功能
| 能力 | CLI | API |
| --- | --- | --- |
| 文档元信息(页数/标题/作者…) | dsh-pdf info | pdfInfo() |
| 全文提取 | dsh-pdf text | extractText() |
| 按页提取(页码标记) | dsh-pdf pages | extractText() |
| 布局提取(str/x/y/w/h/fontSize/fontName,JSON) | dsh-pdf layout | extractLayout() |
| 表格提取(Markdown/CSV/JSON,启发式) | dsh-pdf tables | extractTables() |
| 关键词搜索(页码 + 上下文片段) | dsh-pdf search | searchText() |
| 板块区域提取(bbox 坐标裁剪) | dsh-pdf text --bbox x,y,w,h | extractText({bbox}) |
| 导出页面图片(PNG / base64) | dsh-pdf image [--out 目录] | exportPdfImages() |
| OCR(扫描版/图片型 PDF) | dsh-pdf ocr | extractOcr() |
- 分页选择:
--pages 1-3,5 - 加密 PDF:
--password <密码> - 坐标说明:PDF 用户空间坐标,原点在页面左下角,y 轴向上(与屏幕坐标系相反)。
- OCR:
tesseract.js(WASM)识别,页面经pdf-to-png-converter栅格化。
一、安装 CLI
方式 A:npm 发布后全局安装(推荐)
npm install -g dsh-pdf-extractor
dsh-pdf --help方式 B:本地构建 + 全局链接(未发布/开发时)
git clone <你的仓库> dsh-pdf-extractor
cd dsh-pdf-extractor
npm install
npm run build # 编译 TypeScript 到 dist/
npm link # 全局获得 dsh-pdf 命令(Windows: npm link 同样可用)
# 或只对当前项目生效:
# npm install -g .方式 C:不安装,直接调用
node <包目录>/dist/cli.js text report.pdfWindows 注意:若 PowerShell 报
npm.ps1 无法加载(ExecutionPolicy),请使用npm.cmd install/npm.cmd link,或先Set-ExecutionPolicy RemoteSigned -Scope CurrentUser。
二、安装 DSH Skill(让模型能自动使用)
Skill 是 DSH 的「指令插件」:DSH 会自动扫描以下根目录(skill-filesystem provider):
- 项目级:
<项目根>/.dsh/skills/(rank 100) - 用户级:
$DSH_HOME/skills或~/.dsh/skills(rank 400)
自动安装(推荐)
# 安装到当前项目的 .dsh/skills(会话工作区即生效)
node scripts/install-skill.mjs --project
# 或安装到用户级(所有项目生效)
node scripts/install-skill.mjs --user
# 查看将要安装的位置但不写入
node scripts/install-skill.mjs --dry-run手动安装
把 skill/pdf-extractor/ 目录整体复制到任一 skills 根:
<项目根>/.dsh/skills/
└── pdf-extractor/
└── SKILL.md # YAML frontmatter: name/description/whenToUse + 指令正文验证
- 打开(或新建)一个 DSH 会话;
- 直接提问:「读取
xxx.pdf的内容并总结」; - 模型应自动调用
dsh-pdf info / text / tables等命令(skill 目录变更后 DSH 会自动失效重扫,新建会话最稳妥)。
会话沙箱提示:在 DSH 会话中,模型通过执行工具(如 pwsh)调用
dsh-pdf;若文件访问被 沙箱拒绝,需授予工作区写/读权限(workspace-write或更高模式)。
三、CLI 使用示例
dsh-pdf info report.pdf
dsh-pdf text report.pdf # 全文
dsh-pdf text report.pdf --pages 1-3 # 只取 1~3 页
dsh-pdf pages report.pdf --pages 2 --json # 结构化按页输出
dsh-pdf layout report.pdf --pages 1 # 布局 JSON(坐标)
dsh-pdf tables report.pdf # 表格 → Markdown
dsh-pdf tables report.pdf --format csv # 表格 → CSV
dsh-pdf tables report.pdf --format json # 表格 → JSON 数组
dsh-pdf search report.pdf "conclusion" # 搜索 + 页码 + 片段
dsh-pdf text encrypted.pdf --password secret
# OCR(扫描版/图片型 PDF —— 无文字层时 text 命令输出为空)
dsh-pdf ocr scanned.pdf # 英文扫描件(默认 eng)
dsh-pdf ocr scanned.pdf --lang chi_sim # 中文扫描件
dsh-pdf ocr scanned.pdf --lang chi_sim+eng # 中英混排
dsh-pdf ocr scanned.pdf --pages 1-5 --dpi 300 # 只识别前 5 页,300 DPI
dsh-pdf ocr scanned.pdf --json # 结构化输出(每页 text + confidence)四、Node.js API 使用示例
import { extractText, extractTables, extractLayout, searchText } from 'dsh-pdf-extractor'
const text = await extractText('report.pdf', { pages: [1, 2] })
console.log(text.info.pages, text.pages[0].text) // 页数、第 1 页文本
const tables = await extractTables('report.pdf')
for (const t of tables.tables) {
console.log(`page ${t.page}: header=${t.header.join('|')}`)
console.log(t.rows.map(r => r.join('|')).join('\n'))
}
const layout = await extractLayout('report.pdf', { pages: [1] })
console.log(layout.pages[0].items[0]) // { str, x, y, w, h, fontSize, fontName }
const hits = await searchText('report.pdf', '预算')
console.log(hits.count, hits.matches[0]?.snippet)五、发布到 npm(GitHub Actions + NPM_TOKEN)
仓库已附带 .github/workflows/publish.yml:推送 v*
tag(或手动 workflow_dispatch)即触发 CI —— npm ci → npm run build → smoke 测试 →
npm publish --access public。
认证方式:npm 自动化 token 仅存放为 GitHub 仓库 Secret(绝不写入任何提交的文件),
即 NPM_TOKEN(GitHub 仓库 → Settings → Secrets and variables → Actions →
New repository secret,值用 npmjs 上生成的 Automation token)。token 可随时在
npmjs.com 撤销。
发布步骤(首次)
git init && git add -A && git commit -m "chore: initial release"
git remote add origin https://github.com/<你>/dsh-pdf-extractor.git
git push -u origin main
git tag v1.0.0
git push origin v1.0.0 # 触发 GitHub Actions 自动发布到 npm(public)若重发同版本,需先删除远端旧 tag 再推送(旧 tag 不会重新触发 CI):
git push origin :refs/tags/v1.0.0 && git push origin v1.0.0
之后每次发布:npm version <新版本> 后推送同名 v* tag 即可。
进阶:改用 Trusted Publishing(OIDC,零长期 Token)
如需彻底不用长期 Token,可改 workflow 走 npm 官方的 Trusted Publishing(OIDC):
在 npmjs.com 的 package settings 里配置 Trusted Publisher
(选择 GitHub,填 Owner/Repository/Workflow 文件名),然后把 publish 步骤改为
npm publish --provenance --access public 并加 id-token: write 权限(见本文件最早提交)。
备选:本地交互发布(不使用自动化 Token)
若暂时没有 GitHub 仓库,可自己在终端登录发布(凭据只保存在您自己的 npm 配置中):
npm login # 完成 2FA 验证
npm run build
npm publish --access public发布后用户即可:
npm install -g dsh-pdf-extractor六、OCR 说明
- 首次使用某语言会自动从 jsDelivr CDN 下载语言包(eng ≈10 MB、chi_sim ≈23 MB,中英混排用
chi_sim+eng),下载后本地缓存,之后离线可用;离线环境可手动指定本地数据目录 (createWorker的langPath参数,参考 local-installation)。 - 识别质量:
--dpi 300(默认)为质量/速度平衡点;清晰扫描件也可用 200 提速,模糊件用 400–600 提质量(上限 600)。 - 输出:
--json返回每页{ number, text, confidence };默认输出==== Page N ====分块文本。 - 局限:OCR 是光栅识别,表格结构/排版顺序可能还原不准;图表、手写体识别效果有限。
限制与说明
- 扫描版 PDF:
text提取的是文字层,扫描件输出为空或乱码 —— 此时用dsh-pdf ocr识别。 - 表格提取是启发式:基于文本坐标网格聚类,适合规整对齐的表格;合并单元格、复杂边框、
多级表头可能识别不全 —— 此时回退到
layout --json按坐标自行分析。 - 中文 PDF:正常文字层可提取;扫描件用
--lang chi_sim(或chi_sim+eng)。 - 性能:超大 PDF 请配合
--pages分段提取;OCR 逐页识别较慢,勿一次处理整份大文档。
测试
npm run build
npm run gen-sample # 生成 test/sample.pdf(手写两页样例,含 4x3 表格)
npm run smoke # API 冒烟测试(无外部依赖)