DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

mileioo1 /

mileioo1/dsh-media-preview

Verified

Full file previews for DeepSeek Harness: seekable video/audio, archive listings, hex view, and a Windows-Photos-like image editor with numbered notes that can be sent straight to the conversation.

★ 1 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHubProject homepage
READMESource: main@f36295f3

DSH Media Preview

DSH Media Preview

File previews DeepSeek Harness is missing: seekable media, archive listings, a real image editor, and one-click send to the conversation

中文 · Changelog · Apache-2.0

License: Apache-2.0 npm package npm downloads DSH Web Plugin DSH up to 0.2.1-rc.3

DSH Media Preview is a community-maintained DeepSeek Harness (DSH) plugin, not an official DeepSeek AI product.

This document describes 1.0.0. See the changelog for released changes.

DSH's built-in preview covers text, code and PDF only: no video or audio player, no archive listing, no binary view, images are read-only, and anything above 20 MiB fails outright. This plugin fills those gaps additively — it claims only its own extensions and leaves every other file to the built-in preview.

Install

# install into the web profile (use --profile desktop for the desktop app)
dsh plugin --profile web add @mileioo1/dsh-media-preview

Restart DSH once after installing; the plugin registers its five preview bodies and the details panel during boot.

Features

Video and audio that actually seek

Playback goes through the plugin's own /media-preview/raw, which implements Range / 206 Partial Content / 416, so the scrubber moves freely, playback rate works, and full screen works — it no longer snaps back to the start. The source is the loopback origin (http://127.0.0.1:<port>/media-preview/raw?...) whenever it is reachable; only then does it fall back to a whole-file blob:, and both paths have an error fallback.

  • Video: mp4 mov m4v mkv webm avi flv wmv mpg mpeg ts 3gp ogv
  • Audio: mp3 wav flac ogg oga opus m4a aac wma aif aiff amr mid midi, with sample rate, channels and bitrate

Images: a Windows-Photos-like editor

Zoom (wheel / + - / fit / 1:1), rotate, flip, crop, brightness / contrast / saturation, grayscale, invert, freehand annotation — and numbered notes: click 备注, then click anywhere on the picture to drop a red numbered pin; a matching text field appears under the image and the number is baked into the exported PNG.

  • Save modes: "save as" (name.edit-<timestamp>.png) or "overwrite + backup" (name.png.bak-<timestamp> first, then an atomic replace)
  • The editing canvas is capped at 4096 px on its longest side; oversized images are edited at working size with a notice, instead of allocating gigabytes of bitmaps
  • Notes can be deleted one by one

Archives, binaries and the details panel

  • Archives (zip jar tar gz tgz bz2 xz 7z rar): entry table with name / original size / compressed size / mtime plus a total
  • Binaries (exe dll so dylib bin dat db sqlite wasm class pyc psd apk ipa msi…): hex view, paged at 64 KiB
  • Details panel: name, location, MIME + extension, byte size, three timestamps, permission bits, image dimensions and EXIF, media duration / container / bitrate / codec / frame rate, archive entry count and unpacked size, SHA-256 on demand, and one-click copy of the path or the JSON

Send to conversation

The editor's send button exports the current canvas (all edits and notes included) as a real PNG attachment in the active session's composer: the conversation service creates a draft attachment, then its id goes to the input's InputActions.addAttachments. When the composer is busy the plugin says so instead of failing silently. Other previews insert a file reference instead.

Security and permissions

The plugin only needs "read files, write images, serve loopback HTTP":

  • Every /media-preview/* route serves loopback or same-origin requests only; Origin: null is rejected
  • raw / save paths must live inside the session workspace root or DSH_HOME, otherwise 403 path outside the workspace (code: OUTSIDE_ROOT); relative paths additionally get a traversal check (ESCAPE)
  • Saves are atomic: *.tmp-<pid>-<rand> → fsync → rename, so a crash never leaves half an image behind; timestamps carry milliseconds, so back-to-back saves cannot collide
  • Archives are read incrementally (zip reads only the trailing central directory, tar skips payloads, tgz aborts past 96 MiB) — no whole-archive buffering
  • No outbound network requests, no uploads

Compatibility

  • DSH >=0.2.0-rc.1 <0.3.0-0 (developed and verified on 0.2.1-rc.3)
  • Node ^22.19.0 || >=24.0.0
  • Platform: DSH Web and the desktop app (dsh.client.platform: "web")

Known limits

  • Archives are listed, never extracted
  • 7z / rar listing depends on tools available on the machine and may show "unsupported"; zip / tar / gz are stable
  • The image editor has no non-destructive layers — saving bakes pixels
  • No video thumbnails (to keep long jobs out of the preview path)
  • Chat image thumbnails are now rendered by this plugin, so the built-in read-only lightbox no longer appears; clicking opens the editor
  • Images opened from chat are not on disk yet, so saving creates a new file; overwriting applies to files inside the workspace only

Architecture (for contributors)

Host side (lib/host.js) registers four routes:

Route Purpose
GET /media-preview/info metadata + image dimensions + ffprobe media info + archive listing + optional SHA-256
GET /media-preview/raw raw bytes with Range / 206 / 416 / HEAD, ETag and 304
POST /media-preview/save image save (save-as / backup-then-overwrite, atomic write)
GET /media-preview/origin tells the client the loopback origin for direct media loading

Client side (client.v12.js, a single hand-written bundle, no build step): registers five implementations through documentPreviews.register(...) with priority: "external" so they win over builtin, mounts one body per implementation into the keyed sidebar.right.tab.document slot, and adds the details action, the details overlay and the chat image editor.

Development

# syntax check + pack preview
npm run verify

The test scripts live in the development workspace (media-samples/): host-unit.mjs (14 host checks: zip/tar/tgz listings, large-zip trailing directory, absolute path allowed, OUTSIDE_ROOT / ESCAPE rejected), smoke-interact.mjs (client static assertions) and toolkit-test.mjs (info + Range regression over 19 real files).

Release

Releases go through OIDC Trusted Publishing — no npm token is stored in the repo or on any machine:

npm version patch        # or minor / major; bumps the version and creates a tag
git push --follow-tags   # pushing the tag triggers the publish

.github/workflows/release.yml then upgrades npm to ≥ 11.5.1, runs npm run verify, and finally npm publish --provenance --access public. GitHub Actions exchanges a short-lived OIDC token for publish rights and attaches a provenance attestation, so no NPM_TOKEN secret is needed.

Trusted publisher bound on npm: repository mileioo1/dsh-media-preview, workflow release.yml, permissions "publish + manage dist-tags".

Uninstall

dsh plugin --profile web remove @mileioo1/dsh-media-preview

License

Apache-2.0 © 2026 MichengAI

—/ 5

No ratings yet

Verified DSH bundle

Commit f36295f3b7f8

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout