wilsonchengassistant/dsh-file-download

dsh-file-download

Download any file the DSH Sidebar previews (PDF, XLSX, DOCX, images, binaries) to a remote browser: an authenticated streaming attachment route plus a Download control in the preview header and the unpreviewable state.

待分类attachmentcordisdeepseek-harness

dsh-file-download

Download any file the DSH Sidebar previews — PDF, XLSX, DOCX, images, HTML, text, or a binary no renderer claims — straight to the browser you are reading from.

The problem

DeepSeek Harness's document preview renders a file instead of handing it to you: an XLSX becomes a grid, a PDF becomes pages, an image becomes pixels. When the reader is not sitting at the Host — a phone, another laptop, a Tailscale peer — there was no way to keep a copy:

  • the preview has no download action, and
  • the only file action in the header is Open, which asks the Host to

launch the file in a native application, on a screen you are not looking at.

/api/file is not a workaround either: it answers with the file's own Content-Type and no Content-Disposition, so the browser renders it, and it caps the body at the image-attachment limit (~20 MB) — a real workbook or scanned PDF exceeds that.

What this plugin does

It adds two things, each one file:

Host half — `GET/HEAD /api/file-download?path=`

  • Streams the file in 1 MB chunks — never buffered whole, never capped at an

image-sized limit.

  • Always answers Content-Disposition: attachment, with an ASCII fallback and

an RFC 5987 filename*, so 投資計劃_2026.xlsx saves under its real name.

  • Supports Range / 206 / Content-Range / 416, so an interrupted download

resumes.

  • Content-Type: application/octet-stream + nosniff: the response can never

become a document in the browser.

  • Lives under /api, so the Connection carrier's authentication and trust fence

apply before the handler runs — the same boundary /api/file uses.

Browser half — a Download control in two existing extension points

  • sidebar.right.tab.document.actions — the document preview header, next to

the preview's own tools. Every renderer shares that header, so PDF, XLSX, DOCX, images, HTML, Markdown, text and this repo's media previews all get it.

  • sidebar.right.tab.document.unpreviewable — the empty state, where the stock

UI only offers Open. A labelled Download file button now sits above it.

Both are plain `` links, so middle-click and *Save link as* work too. Nothing is fetched into the conversation, and no bytes are buffered in the browser before the save starts.

Install

The plugin is a profile-local package, not on npm yet. From a checkout:

dsh plugin --profile web add file:/absolute/path/to/dsh-file-download

Or add it to the profile's package.json yourself:

{
  "dependencies": { "dsh-file-download": "file:/absolute/path/to/dsh-file-download" },
  "dsh": { "profile": { "bundles": [/* … */, "dsh-file-download"] } }
}

Then install and restart the Host — dsh web builds its client module graph at boot, so a newly installed browser half only appears after a restart:

cd "$DSH_HOME/profiles/web" && pnpm install
# restart dsh web

Localization

English, Simplified Chinese, and Traditional Chinese dictionaries are registered by the plugin itself, so a zh-Hant reader does not fall back to Simplified copy:

Compatibility

DSH · Status 0.2.0-rc.2 · verified (headless Chrome, dsh web)

The slots this plugin extends are declared by @deepseek-ai/dsh-client-ui-sidebar-documentpreview. A future release that renames them fails loudly at boot (slot not found), never silently.

Verify it end to end

npm test   # 22 unit tests: header encoding, range semantics, route guards, both components

Manual check, with the Host running:

  1. Open a PDF or XLSX from the right Sidebar's Files tab.
  2. Click the download icon in the preview header, or open a .zip and click

Download file in the empty state.

  1. The file lands in your browser's download folder under its original name;

compare its checksum with the Host copy.

Everything above was measured, not assumed: a 28.6 MB MP4, a 27 KB Markdown file with a Chinese filename, a 27.6 KB XLSX and a 3.8 MB ZIP were downloaded through the route and through the browser, and every SHA-256 matched the Host file.

License

MIT © Wilson Cheng