DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

WuShichao /

WuShichao/dsh-ipynb-preview

Verified

Render Jupyter .ipynb notebooks in the DeepSeek Harness document preview: syntax highlighting, offline LaTeX, and zoomable figures

★ 1 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@12befce9

dsh-ipynb-preview

CI npm downloads license dsh-plugin

A DeepSeek Harness plugin that renders Jupyter notebooks in the document preview pane: syntax-highlighted code, real LaTeX, and zoomable figures — instead of raw JSON.

Without it, opening a .ipynb in DSH shows its JSON source. With it, the file opens as a notebook.

Feature Notes
Syntax highlighting Python, JavaScript/TypeScript, JSON, Bash, and INI, with per-language grammars
LaTeX math Vendored KaTeX, so it works offline; inline $…$ and display $$…$$, including inside tables and lists
Markdown subset Headings, lists, tables with column alignment, blockquotes, task lists, fenced code, links, bold and italic, code spans
Figure zoom Click any output figure to open it, then scroll or + / − to zoom continuously, drag to pan, 0 to fit
Save figures Names each figure after the notebook, e.g. sample-notebook-cell3-out1.png
Outputs Streams, display_data, execute_result, and error tracebacks with ANSI escapes stripped

Everything is self-contained: the KaTeX engine and its web fonts are inlined into the client bundle, so no request leaves your machine.

Install

dsh plugin --profile <your-profile> add dsh-ipynb-preview

Then restart DSH. The plugin is a client-side renderer, so it needs a restart rather than a page refresh: the shell computes its client bundle revision at startup.

To install from a checkout or a git URL instead:

dsh plugin --profile <your-profile> add ./dsh-ipynb-preview
dsh plugin --profile <your-profile> add github:WuShichao/dsh-ipynb-preview

The git form makes pnpm ask for permission to run this package's prepare script, because pnpm >= 10 refuses a git dependency's install-time script until it is allowlisted. The built lib/client.js is committed, and the npm package ships it too, so neither a tarball nor a registry install asks for anything.

How it works

DSH discovers the package through the profile's bundle list, reads dsh.client from this manifest, and serves lib/client.js to the browser as part of the client roster. That bundle registers a document-preview renderer for the ipynb extension:

lib/index.js           host half; deliberately empty, the plugin is browser-only
lib/client.template.js the editable client source, with two KaTeX placeholders
lib/client.js          the generated artifact the shell serves
cordis.patch.yml       the bundle layer that inserts the plugin row
tools/build-client.mjs generates lib/client.js from the template

lib/client.js is generated, not hand-edited. Change lib/client.template.js and run npm run build.

Development

pnpm install    # installs KaTeX (build), React (tests)
pnpm run build  # regenerate lib/client.js
pnpm test       # build, then the verifier, the bundle lint, and the mount harness

The repository ships a pnpm-lock.yaml, and pnpm is what the DSH CLI itself uses to install plugins, so CI installs with pnpm install --frozen-lockfile. npm and yarn also work: every script is a plain node invocation rather than a chained npm run, so no script depends on which package manager started it.

pnpm test runs three suites, all offline:

  • tests/verify.mjs — materializes the bundle the way the shell's module loader does, then checks the manifest contract, the registrations, the highlighter, the math renderer, the Markdown subset, the zoom arithmetic, the stylesheet, and a full render of the fixture notebook. Around 170 assertions.
  • tests/lint-bundle.mjs — sweeps both the template and the built bundle for identifiers that are referenced but never declared. A free variable makes the factory throw while the shell materializes it, and the whole client roster then fails to load — a blank window that node --check cannot detect.
  • tests/mount.mjs — mounts the plugin against a DOM stub so effects and event wiring actually run, and asserts the notebook tree survives opening the lightbox.

The fixture notebook is generated by tests/make-fixture.mjs, and the assertions read their expected counts from that fixture, so the input and the expectation cannot drift apart.

Interaction testing in a real browser

React's synthetic event system does not work against a hand-written DOM stub, so the controls' click handlers are verified in a real browser instead:

node tests/make-page.mjs            # writes test-page.html at the repo root
node tests/make-page.mjs out.html   # or choose the output path

Open the page, click Open the lightbox, and press every control; each interaction, the zoom readout, and any error is written to the log at the top of the page. Append ?auto=1 to the URL and the page drives itself, which is how a headless run reads the result back:

msedge --headless=new --virtual-time-budget=15000 --dump-dom \
  "file:///path/to/test-page.html?auto=1"

That page also hit-tests every control with document.elementFromPoint, which is how a stacking-order bug was found: a fixed application header with a higher z-index than the lightbox covered the middle of the toolbar, so only its edges responded to a click.

Requirements

  • Node 18 or newer to build and test.
  • React is not a dependency: the shell supplies it from its own frozen module table. It is a dev dependency only, for the tests.

Notes for plugin authors

Two things this plugin learned the hard way, both now covered by assertions:

  • A client bundle is materialized inside the shell's module loader. If the factory throws, the row has no exports and the whole roster fails — which looks like a blank window rather than a plugin error. Keep the factory free of undeclared identifiers.
  • A full-screen overlay needs a z-index above every host layer. 9999 is not enough: application chrome is often a fixed header with its own stacking context, and it will silently swallow clicks aimed at your controls.

License

MIT — see LICENSE. KaTeX is bundled under its own MIT license; see THIRD_PARTY_NOTICES.md.

Published to npm by @nightwingng.

—/ 5

No ratings yet

Verified DSH bundle

Commit 12befce94b3c

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