安装
npx -y @deepseek-ai/dsh plugin --profile web add github:jiaoqsh/dsh-document此安装命令根据 GitHub 仓库地址生成,是未经验证的安装起点。
README
维护者编写的文档快照。
dsh-document
A DeepSeek Harness plugin bundle (@jiaoqsh/dsh-document) that gives the model a read_document tool: Word, PowerPoint, Excel, OpenDocument, RTF, EPUB, CSV, and PDF files are converted to line-numbered Markdown the model can page through with offset/limit.
Conversion runs locally: office formats through @firecrawl/anydoc (Rust core, Node bindings) and PDFs through @firecrawl/pdf-inspector (WASM build, run in a worker thread) — no API key, no network, no external binaries; both MIT. PDFs get page selection, <!-- Page N --> markers, and page facts: total pages, text-based / scanned / mixed, and which pages have no extractable text. Files are read through the harness ctx.fs seam, so whatever filesystem provider and sandbox policy a deployment mounts applies unchanged.
Install
Into an existing profile (web, headless, or your own), from npm:
dsh plugin --profile web add @jiaoqsh/dsh-document
The npm package ships built code, so nothing runs at install time. Releases are published from this repository's release.yml through npm trusted publishing and carry provenance attestations.
From GitHub instead
dsh plugin --profile web add github:jiaoqsh/dsh-document#<commit-sha>
A git install fetches sources, so pnpm ≥ 10 refuses to run the package's prepare (a tsdown transpile of src/) until you allow it: the first add fails and prints the exact key to copy into the profile's pnpm-workspace.yaml ($DSH_HOME/profiles/<name>/pnpm-workspace.yaml). The key names the resolved tarball, so a bare package name does not match:
allowBuilds:
'@jiaoqsh/dsh-document@https://codeload.github.com/jiaoqsh/dsh-document/tar.gz/<commit-sha>': true
Re-run the add. Allowing the build means executing this package's code on your machine at install time; pin a commit so a later push cannot change what runs.
dsh plugin prints "missing peer" warnings for the @deepseek-ai/* packages: expected. The dsh installation supplies them at runtime; profiles deliberately do not install peers.
Verify, then boot:
dsh --profile web --dump-config # shows a "# == @jiaoqsh/dsh-document" layer
dsh --profile web
Remove with dsh plugin --profile web remove @jiaoqsh/dsh-document.
From a source checkout of the harness
pnpm dsh web --patch /absolute/path/to/dsh-document/overlay.yml
where the overlay inserts the built entry by absolute path:
- insert:
- id: document-tools
name: '/absolute/path/to/dsh-document/lib/index.js'
Configuration
The bundle's layer inserts one row, document-tools, with schema defaults. Override it by id in your profile's cordis.patch.yml; a patch replaces the whole config, so restate every key you need:
- id: document-tools
config:
maxInputBytes: 104857600 # 100 MiB
readLimit: 2000
maxLineLength: 2000
maxOutputBytes: 51200
pdfMaxPages: 100
pdfProfile: fidelity
| Key | Default | Meaning |
|---|---|---|
maxInputBytes | 52428800 (50 MiB) | Inclusive byte cap on the source file. Enforced by the filesystem provider before any bytes are buffered; larger files are refused. |
readLimit | 2000 | Default and maximum number of Markdown lines returned by one call. |
maxLineLength | 2000 | Maximum characters per returned line; overflow is cut with … [line truncated]. |
maxOutputBytes | 51200 (50 KiB) | Maximum bytes of line text returned by one call; the window stops early and the footer says how to continue. |
pdfMaxPages | 100 | Maximum distinct pages one pages selection may name. |
pdfProfile | fidelity | PDF Markdown profile: fidelity keeps source structure, compact spends fewer tokens. |
Every numeric value must be a positive integer and pdfProfile one of the two names; anything else fails the plugin load with a message naming the key.
The tool
read_document(file_path, offset?, limit?, pages?)
file_path— resolved by the filesystem backend; relative paths resolve against the calling session's workspace.offset— 1-based first line of the converted Markdown (default 1).limit— lines to return (default and maximumreadLimit).pages— PDF only: 1-based pages to convert, as numbers and ranges like"1-3,7"(at mostpdfMaxPages). Default: every page. Naming a page beyond the last one is an error that states the page count.
Supported extensions: .pdf, .doc, .docm, .docx, .ppt, .pps, .pot, .pptx, .pptm, .ppsx, .ppsm, .xls, .xlsx, .xlsm, .xlsb, .odt, .ods, .odp, .rtf, .epub, .csv. The format comes from the extension, never from content sniffing (CSV has no signature).
Canonical value (what Code Mode receives):
{ path: string, format: 'pdf' | 'docx' | ..., offset: number,
lines: { number: number, text: string }[], totalLines: number, truncatedByBytes: boolean,
pdf?: { pageCount: number, kind: 'text' | 'scanned' | 'image' | 'mixed',
pagesNeedingOcr: number[], pages?: number[], title?: string } }
Model-facing text (a PDF, pages 2 and 4 of 5):
<path>/work/report.pdf</path>
<format>pdf</format>
<pdf>5 pages, text-based; showing pages 2, 4</pdf>
<content>
1: <!-- Page 2 -->
2:
3: Revenue grew 12% year over year.
(Showing lines 1-3 of 8. Use offset=4 to continue.)
</content>
A mixed PDF adds <warning>Pages 3, 7-8 contain no extractable text (scanned or image content); their content is missing below and would need OCR.</warning> before <content>. Non-PDF formats omit the <pdf> line.
Failures are tool errors in model terms: unsupported extension (pointing at read for plain text), pages on a non-PDF, a malformed pages value, not found, not a regular file, over maxInputBytes, encrypted, damaged or incomplete, engine resource limit, a page beyond the last page, cancellation, or no extractable text (a scanned or image-only PDF says so and that OCR is needed; this tool performs no OCR).
Model Experience
System prompt section tool:read_document
What the model sees
One fixed sentence, order 100 beside the shipped tool:read guidance:
Use the read_document tool — not read or shell commands — to inspect PDF, Word, PowerPoint, Excel, OpenDocument, RTF, EPUB, and CSV files. It returns the document converted to line-numbered Markdown; use offset and limit to continue reading long documents. For a PDF, pass pages (for example "1-3,7") to read only those pages; page markers like <!-- Page 4 --> show where each page starts.
Token effect
Fixed: the section and the tool schema add a constant number of tokens to every request; results add up to maxOutputBytes per call.
KV Cache effect
Prefix-stable: the section text and schema never change between requests, so they do not invalidate a cached prompt prefix.
Known Limitations and Deferred Work
- No OCR — pages without a text layer are reported (
pagesNeedingOcr, the<warning>line) but not read; a fully scanned or image-only PDF is an error naming the cause. - PDF conversion runs in a fresh worker thread per call — cancellation terminates it, and the harness event loop stays free, at the cost of ~50 ms of WASM start-up per call. Office-format conversion (anydoc) runs on the libuv thread pool and cannot be cancelled once started;
maxInputBytesis its bound. - Layout-heavy PDFs may collapse paragraphs into long lines (then cut by
maxLineLength);pdfProfile: compacttrades structure for tokens. - Engines are fixed — the
DocumentConverterinterface androuteConvertersinsrc/converter.tsare the seam for a hosted or OCR-capable engine; none is wired today. - The pdf-inspector native binary is not used — its npm build ships no
darwin-x64binary, so the WASM build runs everywhere for one code path.
Development
pnpm install # also builds lib/ via prepare
pnpm run typecheck
pnpm test # real Cordis Context + real registry + real local fs; no API key
pnpm run build
Release: bump version in package.json on main, then push the matching tag (git tag v0.2.0 && git push origin v0.2.0). release.yml checks the tag against the version, runs the checks, publishes to npm via trusted publishing, and creates the GitHub release with generated notes.
Fixtures under tests/fixtures/ were generated once with macOS textutil and cupsfilter (including a five-page PDF and an image-only PDF) and are committed so the suite runs anywhere. In source mode the PDF worker is spawned as .ts with --experimental-strip-types, so it stays free of TypeScript-only runtime syntax.
License
MIT
项目文件与信号
以下项目是目录快照中检测到的公开仓库信号。
仓库信息
- 开发语言
- TypeScript
- 许可证
- MIT
- 最新发布
- v0.1.1
- 最后更新
- 2026年8月17日 04:37
谨慎安装
请检查源代码、权限、生命周期脚本、依赖与网络访问;不受信任的插件应先在隔离环境中测试。