Back to home

1149784810

jayhe-mdviewer

General file previewer for DeepSeek Harness (dsh): vertical expandable produced-files list with per-type rendering — markdown, syntax-highlighted code, csv/tsv tables, images, text.

Stars
0
Language
TypeScript
Created
Aug 15, 2026
Updated
Aug 15, 2026

Introduction

jayhe-mdviewer

A general file previewer for DeepSeek Harness (dsh).

When an agent turn produces files, the produced-files row under the closing assistant message becomes a vertical, expandable list. Clicking any produced file opens a right-docked panel that renders it in a style matching its type: markdown with the official MarkdownText renderer (full GFM, tables, fenced code, and TeX math — exactly like the chat), syntax-highlighted code (~70 languages via bundled highlight.js), csv/tsv as HTML tables, images inline, and text/code logs as monospace plain text.

中文文档

Features

  • Per-type rendering — extension-driven recognition routes every file to its own renderer: 📄 markdown (official MarkdownText, micromark + KaTeX), 💻 code (highlight.js syntax highlighting with a language badge), 📊 csv/tsv (quoted-field-aware table, 500-row cap), 🖼 images, 📃 text; known binary formats get a specific "open externally" hint.
  • Vertical expandable produced-files row — collapsed by default (Produced · N files ▸); one click expands ALL produced files (no chip cap), each with its type icon, name, and an ↗ external-open button.
  • One click → preview — clicking a file opens the right-docked panel with ONLY that file rendered; external-open (↗), close, loading / error / retry, and a 15 s read watchdog.
  • Same-origin read route — the host half registers GET /mdviewer/read and reads through the deployment's own filesystem service, so local, sandboxed, and remote (e.g. E2B) backends all work; text is capped at 4 MB, images at 4 MB (served as base64 data URLs), directories and binary content are rejected.
  • Bilingual zh/en dictionaries through the locale service; styled with the deployment's theme tokens (light and dark).

Requirements

  • dsh with the web surface, @deepseek-ai/dsh-* packages at 0.1.0-rc.x (developed against 0.1.0-rc.6).
  • The profile keeps the stock @deepseek-ai/dsh-client-ui-deliverables row mounted (default in dsh-web-app) — it is the source of the produced-files turn data this plugin reads.

Install

The web profile lives at ~/.dsh/profiles/web (adjust for your profile).

cd ~/.dsh/profiles/web
pnpm add jayhe-mdviewer

Then add one row to the profile's own cordis.patch.yml (see install/cordis.patch.example.yml):

- insert:
    - id: mdviewer
      name: 'jayhe-mdviewer'

Restart the dsh web process — plugin-set changes take effect on restart.

The row is simultaneously a host row and the browser-roster entry: the dsh.client declaration in package.json makes the client bundle part of window.__DSH_BOOT__ automatically.

Rollback

cd ~/.dsh/profiles/web
# remove the `mdviewer` row from cordis.patch.yml, then:
pnpm remove jayhe-mdviewer

Usage

  1. Ask the agent to produce files (write/edit tools).
  2. When the turn completes, its produced-files row shows Produced · N files ▸; click to expand the full vertical list.
  3. Click a file → the preview panel opens on the right and renders ONLY that file.
    • beside an entry (or in the panel header) opens the file in the external editor instead.
    • To preview another file, click its entry in the produced-files list.

How it works

src/index.ts            host half: GET /mdviewer/read route (webServer + fs)
src/client/index.tsx    client apply: locale dicts, styles, two slot entries
src/client/deliverables.ts  turn-data reading (produced paths, .md filter)
src/client/turnTail.tsx     produced-files row (chain entry, priority -1)
src/client/viewer.tsx       overlay panel (fetch + MarkdownText)
  • The turn-tail entry reads the engine-published deliverables turn data (populated by @deepseek-ai/dsh-client-ui-deliverables from the mutation tools' own locations), so a produced file is listed even when the model forgets to mention it.
  • The panel fetches /mdviewer/read?path=…&cwd=… and renders the response with MarkdownText.

Security notes

  • The read route is same-origin and reads only what the deployment's own filesystem service can resolve; it rejects directories, non-regular files, and files over 4 MB, and only reads UTF-8 text.
  • The route is unauthenticated by design (same trust boundary as the stock file-open RPCs); keep this in mind for multi-user deployments.

Development

npm install
npm run build        # esbuild bundles + tsc declarations → lib/
npm run typecheck    # tsc --noEmit

lib/ is committed output and shipped in the npm package, so end users never need a build step.

Publishing checklist

  1. Confirm the published package name in package.json.
  2. npm publish (runs prepublishOnly → rebuilds lib/).
  3. Tag the GitHub repo with the dsh-plugin topic so the community can find it.
  4. Announce the plugin in the DeepSeek Harness discussions.

License

MIT