dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
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.
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.
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:
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.
It adds two things, each one file:
Host half — `GET/HEAD /api/file-download?path=`
image-sized limit.
Content-Disposition: attachment, with an ASCII fallback andan RFC 5987 filename*, so 投資計劃_2026.xlsx saves under its real name.
Range / 206 / Content-Range / 416, so an interrupted downloadresumes.
Content-Type: application/octet-stream + nosniff: the response can neverbecome a document in the browser.
/api, so the Connection carrier's authentication and trust fenceapply 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 tothe 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 stockUI 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.
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-downloadOr 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 webEnglish, Simplified Chinese, and Traditional Chinese dictionaries are registered by the plugin itself, so a zh-Hant reader does not fall back to Simplified copy:
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.
npm test # 22 unit tests: header encoding, range semantics, route guards, both componentsManual check, with the Host running:
.zip and clickDownload file in the empty state.
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.
MIT © Wilson Cheng