Bundle
dsh-crystal-viewer
A crystal-structure visualization window for DeepSeek Harness (DSH): a 3D structure + Q-peak viewer and parameter panel, opened as a dsh-better-sidebar tab.
- Source
- Nth-5620
- License
- MIT
- Updated
- Updated 6 days ago
Readme
# dsh-crystal-viewer <strong>A crystal-structure visualization window for <a href="https://github.com/deepseek-ai/DeepSeek-Harness">DeepSeek Harness</a> (DSH).</strong> `dsh-crystal-viewer` is a standalone DSH plugin that gives a human user a window for inspecting crystal and molecular structures directly inside DeepSeek Harness. It combines an **interactive 3D structure** (rendered with a modified build of [3Dmol.js](#open-source-attribution--gratitude)), a **Q-peak (electron-density peak) layer**, and a **live parameter panel** showing unit cell, symmetry, elements, atom statistics, Q-peak statistics and refinement R factors. It opens as a **sidebar / bottom-dock tab** — exactly like DSH's built-in `Terminal` / `Browser` tabs — via the `dsh-better-sidebar` tab-registration API. It also registers a **file previewer** so that clicking a `.res` / `.ins` / `.cif` / `.xyz` / `.mol` / `.pdb` file in the Files tree renders it in 3D instead of a plain code viewer. > **What this plugin is:** a *human-facing* **viewer**. It self-parses structure files (unit cell, symmetry operators, atoms, Q peaks, bonds) to draw the structure and fill the panel. It is **not** a crystallographic computation engine — solving / refinement decisions and deep geometry analysis are out of scope for this plugin. --- ## Table of contents - [Why a viewer at all](#why-a-viewer-at-all) - [Feature tour](#feature-tour) - [Screenshots](#screenshots) - [Main view — periodic structure + full parameter panel](#main-view--periodic-structure--full-parameter-panel) - [Display Style dialog — Atom tab](#display-style-dialog--atom-tab) - [Display Style dialog — Lattice tab & the unit-cell "Style" (packing)](#display-style-dialog--lattice-tab--the-unit-cell-style-packing) - [Display Style dialog — View tab (projection & background)](#display-style-dialog--view-tab-projection--background) - [Light ⇄ dark theme linkage](#light--dark-theme-linkage) - [Periodic vs. non-periodic structures](#periodic-vs-non-periodic-structures) - [Supported file formats](#supported-file-formats) - [Getting started](#getting-started) - [Open-source attribution & gratitude](#open-source-attribution--gratitude) - [Compatibility](#compatibility) - [Repository layout](#repository-layout) - [License](#license) --- ## Why a viewer at all A **human still needs to see the structure**. This plugin is the window that a person looks at to make the calls that actually drive a structure-solution / refinement workflow: - Is the unit cell correct, and did I pick the right space group (or is it still P1)? - Have R1 / wR2 / GooF converged, or do I need another refinement cycle? - Are there large Q peaks left that I should assign as atoms, or is the electron-density map "clean"? - Is the coordination geometry an octahedron, a square plane, or a tetrahedron? All of these are "look at it" judgements — exactly what this viewer is for. It renders the structure and fills the panel so those calls can be made at a glance. --- ## Feature tour A condensed, feature-oriented summary — every item below is described further in the Screenshots section with a matching image. ### 3D rendering - **Interactive 3D structure viewer** (WebGL, no WASM dependency). - **Atom display styles**: `None` · `Line` · `Stick` · `Ball and stick` · `CPK` (space-filling) · `Polyhedron` (coordination polyhedra). - **Coloring**: `Custom` (one uniform color) · `Color by Element` (Jmol scheme) · `Color by Group` (periodic-table main group / transition-metal gold). - **Bond order** toggle (show double / triple bonds when the file carries them, e.g. SDF / MOL2) · **Label atoms** toggle. - Fine numeric controls with both **type-to-edit and ▲/▼ steppers**: line width, stick radius, ball radius, CPK scale. - **Lattice / unit-cell box** rendering: `None` · `Dashed line` · `Line` · `Stick`, with **per-axis range** (0..2 = 2×2×2 supercell), line width / stick radius, **axis coloring** (a·b·c axes) or a custom color, and **axis labels** (a / b / c). - **View** controls: **Perspective (center) ⇄ Parallel (orthographic)** projection, **Background** (`Follow theme` / `White` / `Dark gray` / `Custom:`), and an **Outline** edge effect. - **Correct mouse-wheel zoom direction** (relative zoom, no jump-back) and an **un-clamped fit distance** so Perspective and Parallel render at the same apparent size. ### Crystallography - **Complete periodic symmetry expansion** — the plugin closes the `SYMM` generator set (group multiplication) *and* applies the `LATT` lattice translation (body-centered I / face-centered F / base-centered A, B, C), so high-symmetry space groups (e.g. MOF `Fm-3m`, `Im-3`) render a **full 1×1×1 unit cell** instead of a sparse one. The tool can derive the full general-position set from just the generators + LATT (e.g. 11 `SYMM` rows + `LATT -2` → 24 general positions). - **Lattice "Style" (packing) modes** — how symmetry operations are applied to the displayed atoms (display-only; the file is never modified): - **In Cell** (default) — apply symmetry to fill a complete 1×1×1 unit cell (edge atoms retained). - **Original** — apply symmetry but keep the raw coordinates, which may fall outside the cell. - **No Packing** — show the file's atoms as-is, with **no** symmetry operations. This is the key view for inspecting the **true asymmetric unit** during structure solution. - **Q-peak (electron-density peak) layer** — rendered as an **independent, un-bonded model** (yellow point layer), toggleable. Directly shows unassigned-density candidates during structure solution. - **Unit-cell box + supercell / grow** — unit-cell box style, supercell (2×2×2) via the `Grow` toggle or the Lattice range, and axis labels. ### Parameter panel A live **7-group panel** populated from the parsed file: 1. **Source** — file format + name, structure title, collection temperature. 2. **Refinement** (highlighted) — `R1` · `wR2` · `GooF`, `d_max` resolution, observed / total reflections, completeness, highest difference peak / deepest hole (Δρ). 3. **Cell** — a / b / c, α / β / γ, volume V, wavelength λ, Z. (Periodic structures only.) 4. **Symmetry** — space-group hint, LATT, symmetry-operator count. (Periodic structures only.) 5. **Elements (SFAC)** — element list + `UNIT:` formula counts. 6. **Atoms** — total atom count, per-element counts. 7. **Q peaks** — collapsible group listing the number of unassigned peaks and the **top 5** by height (label, height in e/ų, fractional coordinates) with a `max` summary. Hidden entirely when there are no Q peaks. The panel is built to answer "is it converging / should I continue?" at a glance. ### Polished UX - **DSH-native theming** — all colors come from DSH `--dsw-*` design tokens, so the panel, the Display Style dialog and the canvas background **automatically follow the harness light / dark theme** (see the theme screenshot below). A `MutationObserver` on `body[data-ds-dark-theme]` re-renders the "Follow theme" background **live** when you flip the theme. - **Smart UI adaptation** — the Display Style dialog shows a **Lattice tab only for periodic** structures; non-periodic (`.xyz`/`.mol`/`.pdb`) structures get only Atom + View tabs, and the panel omits Cell / Symmetry. - **Performance gate** — the tab pauses its subscription / polling when the panel is collapsed or inactive. --- ## Screenshots All screenshots below were taken from the **real plugin running inside a DeepSeek Harness session** — the `crystal-viewer` tab/window in the DSH UI, exactly as a user would see it. Demonstrations use the **public HKUST-1 (Cu-BTC) MOF** and the **caffeine molecule** as examples. ### Main view — periodic structure + full parameter panel The **crystal-viewer** window shows an interactive 3D structure in the centre and the live **parameter panel** on the right. This is **HKUST-1 / Cu-BTC** (`F m -3 m`, a ≈ 26.29 Å). The plugin used the CIF's symmetry operations to render a **complete unit cell** — note how all the Cu paddle-wheel clusters and organic linkers fill the cell rather than a single asymmetric unit. The unit-cell box and axis labels are drawn.  ### Display Style dialog — Atom tab Clicking **Display Style** slides in a dialog on the **left** (so it never covers the parameter panel on the right). The **Atom** tab controls how atoms and bonds are drawn: - **Display style**: None / Line / Stick / Ball and stick / CPK / Polyhedron. - **Coloring**: Custom (one color) or Color by (Element = Jmol scheme, or Group = periodic-table group). - **Bond order** (show double / triple bonds) and **Label atoms** toggles. - Context-aware numeric fields (Line width, Stick radius, Ball radius, CPK scale) with **type-to-edit and ▲/▼ steppers**.  Switching to **Polyhedron** replaces the display with the coordination polyhedra: the framework is shown as thin sticks (bonds only), and each metal centre is drawn as a small sphere with its first coordination shell as a semi-transparent polyhedron plus the metal-to-ligand bonds — e.g. the Cu paddlewheel centres in HKUST-1 show their square-planar (4 × O) coordination. This is the "show me the coordination geometry" view that makes the "octahedron? square plane? tetrahedron?" call immediately. Centers are detected automatically by chemical character (a metal / low-electronegativity atom surrounded by donor ligands), so it works for both periodic frameworks (CIF) and molecular complexes (XYZ/PBD).  ### Display Style dialog — Lattice tab & the unit-cell "Style" (packing) The **Lattice** tab exposes two material ideas at once: - **Style** — the unit-cell **packing** mode, i.e. how symmetry operations are applied to the displayed atoms (display-only, never modifies the file): - **In Cell** — fill a complete 1×1×1 unit cell (default; the full-symmetry view above). - **Original** — apply symmetry but keep raw coordinates (may fall outside the cell). - **No Packing** — show the file's atoms as-is with no symmetry operations (the true **asymmetric unit**). - **Range** — cells to display per direction (0..2 → 2×2×2 supercell). - **Lattice** — unit-cell box style (None / Dashed line / Line / Stick), line width / stick radius, axis coloring (a·b·c) or a custom color, and axis labels.  The **No Packing** mode is a key structure-solution helper. Here the same HKUST-1 CIF shows **only the single asymmetric unit** (a Cu paddle-wheel fragment) in a nearly-empty cell — versus the full symmetry-packed cell above. This is what you inspect when you need to see an atom's true fractional coordinates and connectivity without the clutter of symmetry mates.  ### Display Style dialog — View tab (projection & background) The **View** tab controls the projection and the canvas background: - **Projection**: **Perspective (center)** ⇄ **Parallel** (orthographic view). - **Background**: **Follow theme** (adapts to the harness light / dark mode), White, Dark gray, or Custom. - **Rendering**: an **Outline** edge effect.  ### Light ⇄ dark theme linkage The whole plugin — the parameter panel, the Display Style dialog and the 3D canvas background — consumes DSH `--dsw-*` design tokens and follows the harness theme. Here the same HKUST-1 structure is shown with the harness switched to **dark** and the background set to **Follow theme**: the canvas backdrop becomes a dark gray instead of white, and every panel re-themes in lockstep. A `MutationObserver` on the theme attribute re-renders the background live, so toggling the theme updates the view instantly.  ### Periodic vs. non-periodic structures The plugin adapts to whether the file is a **periodic** crystal (has a unit cell + symmetry) or a **non-periodic** molecular structure. Open the **caffeine** molecule (a 3D conformer) and the difference is immediate: - **No unit-cell box**, no lattice, no axis labels. - The parameter panel omits the **Cell** and **Symmetry** groups — it shows only Source, Elements (SFAC) and Atoms. - The Display Style dialog presents **only the Atom and View tabs**; the **Lattice tab is hidden** (no lattice concept for a molecule).   --- ## Supported file formats | Format | Role | Notes | |--------|------|-------| | `.cif` | Crystallographic Information File | Self-written parser + symmetry-expanded clean CIF re-emission for 3Dmol. | | `.ins` / `.res` | SHELX input / output | Self-written parser reads unit cell, symmetry, SFAC/UNIT, atoms, Q peaks, MOLE groups, aniso / riding H; the `.res` `REM` block supplies R1 / wR2 / GooF, reflection counts and Δρ. Displayed in 3D; no screenshots are shown for this format in the README. | | `.xyz` | Cartesian coordinates | Lightweight parser for the panel (non-periodic). | | `.mol` | V2000 molfile | Lightweight parser for the panel; raw text fed to 3Dmol (bond order supported). | | `.pdb` | Protein Data Bank | Lightweight parser for the panel; raw text fed to 3Dmol. | | `.hkl` | Reflection data | **Not parsed** (not needed for 3D display; R factors come from `.res` / `.lst`). | The `.ins` / `.res` (SHELX read/write) path fully supports round-tripping: parse the structure, view it in 3D, and read back the unit cell, symmetry, atoms, Q peaks and refinement statistics into the panel. --- ## Getting started ### Requirements - **Node.js ≥ 22.18** — required by `tsdown` 0.22.14 (uses `Promise.withResolvers`). CI runs Node 22. - **DeepSeek Harness (DSH)** web runtime — the plugin is a DSH *external* plugin (bundle), loaded by the DSH profile. - **pnpm** (`corepack` or local install). ### Build ```bash pnpm install pnpm build # emits lib/index.js (host) + lib/client.js (client) pnpm typecheck ``` > `.npmrc` sets `auto-install-peers=false` because DSH host packages (`@deepseek-ai/cordis`, `dsh-better-sidebar`, `react`) are resolved at runtime from the DSH profile's hoisted `node_modules`, not from the npm registry. ### Install into a DSH profile ```bash dsh plugin --profile <name> add dsh-crystal-viewer # or, for local development: dsh web --patch /abs/path/cordis.patch.yml ``` Then open the DSH web UI, click the **Crystal** entry (sidebar `+` menu / bottom dock), and open a structure file — either via the path box or by clicking a `.res`/`.cif`/`.xyz` in the Files tree. **Hard-refresh the browser (Ctrl+F5)** after installing or updating the client bundle. --- ## Open-source attribution & gratitude This project stands on the shoulders of several excellent open-source projects. **We are deeply grateful to their maintainers and contributors** — [`LICENSE`](LICENSE) holds this project's MIT license, and [`NOTICE`](NOTICE) records the full legal text of every third-party license we inherit. ### This plugin's own license: MIT The `dsh-crystal-viewer` plugin itself is released under the **MIT License** (see [`LICENSE`](LICENSE)). You are free to use, copy, modify, merge, publish, distribute, sublicense and sell it, under the MIT conditions. ### 3Dmol.js — rendered & *modified* - **Project:** [3Dmol.js](https://github.com/3dmol/3Dmol.js) — institutional-grade molecular visualization for web. - **License:** BSD-3-Clause. - **Role:** the rendering base (WebGL, no WASM dependency). Its `GLViewer` adds models, applies styles, draws the unit cell and handles CIF. - **Modifications in this plugin (shipped as a modified/integrated build):** - Self-written SHELX/CIF **symmetry expansion** (group closure of `SYMM` generators + `LATT` lattice translations) so 1×1×1 cells of high-symmetry space groups are fully populated. - **Q-peak multi-layer rendering** (a separate model with bond creation disabled). - **Mouse-wheel zoom direction & step overrides** (relative zoom; correct direction, no jump-back), and **un-clamped fit distance** so Perspective and Parallel projections render at the same size. ### GLmol — inherited from 3Dmol.js - **Project:** GLmol (`GLmol – Molecular Viewer on WebGL/Javascript`, v0.47). - **Copyright:** 2011–2012, biochem_fan. - **License:** dual-licensed MIT / LGPL3. - **Role:** a foundational dependency bundled within 3Dmol.js; its copyright and license notices are retained in `NOTICE`. ### React - **Project:** [React](https://react.dev/) 18. - **License:** MIT. - **Role:** the UI layer (viewer, parameter panel, Display Style dialog). ### dsh-better-sidebar (DSH plugin) - **Project:** [DSH-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar) — the DSH sidebar workbench this plugin hooks into. - **License:** MIT. - **Role:** provides the `ctx.betterSidebar` tab API; this plugin registers its `crystal-viewer` tab through it. - **Optional peer dependency** — if it is not installed, the plugin still loads but registers no tab (graceful degradation). --- ## Compatibility ### DeepSeek Harness version Verified and developed against **DeepSeek Harness (DSH) v0.1.1-rc.2** (stable, port 3080) and **v0.1.2-alpha.1** (developer channel, port 3081). The plugin declares `engines.dsh: ">=0.1.0"` in `dsh.plugin.json`, targeting the DSH `dsh-external` bundle/plugin interface. > **Recommendation:** run the DSH **developer channel / alpha** profile for the newest harness APIs, or the stable `0.1.1-rc.2` profile — both are supported. Hard-refresh the browser (Ctrl+F5) after installing/updating. ### Plugin compatibility - **`dsh-better-sidebar`** — **required for the tab entry**. This plugin registers its `crystal-viewer` tab through `ctx.betterSidebar`. Verified against **v0.17.1** (optional peer; graceful degradation if absent). - **`@deepseek-ai/dsh-client-*`** — DSH client runtime / locale / UI-slots / conversation / modules modules are injected by the DSH profile (client bundle `inject` list in `package.json` `dsh` field). ### Known behaviors & limitations - **Q-peak display** requires the structure to actually contain Q peaks (`.res` rows labeled `Q#`); structures without Q peaks simply have no Q-peak layer. - Parsing is **display-oriented (thin)**, not a full crystallographic engine. Deep analyses (twinning, disorder-occupancy merge, space-group derivation, SQUEEZE, CheckCIF) are intentionally out of scope for this viewer. - We do **not** maintain or re-distribute 3Dmol.js upstream; we ship a bundled, **modified** build. See `LICENSE` and the attribution section above. --- ## Repository layout ``` dsh-crystal-viewer/ ├── src/ │ ├── index.ts # host half: /crystal-viewer/api/read route (optional fallback) │ ├── client/ │ │ ├── index.tsx # client half: registerTab (entry, same mechanism as Terminal/Browser) │ │ ├── CrystalViewer.tsx # 3D canvas (3Dmol): atom model + Q-peak model + Display Style + toolbar │ │ ├── CrystalEmbed.tsx # file previewer (clicking a structure file in the Files tree) │ │ ├── CrystalPanel.tsx # parameter panel (7 groups, incl. Refinement + Q-peak stats) │ │ ├── display/ # displayStyle.ts (settings model + math) / render.ts / DisplayStylePanel.tsx │ │ └── useCrystalModel.ts# path/format → structure → CrystalModel/ViewerModel │ └── crystal-parse/ │ ├── shelx.ts # self-written .ins/.res parser (CELL/symmetry/atoms/Q peaks/MOLE) │ ├── model.ts # CrystalModel / ViewerModel / QPeak types │ ├── assemble.ts # parsed structure → CrystalModel/ViewerModel + formatFromPath │ ├── cif.ts # CrystalModel → atomCif/qPeakCif + symmetry expansion (group closure + LATT) │ ├── cif-parse.ts # generic .cif parser │ ├── xyz-parse.ts # generic .xyz parser │ ├── mol-parse.ts # generic .mol (V2000) parser │ ├── pdb-parse.ts # generic .pdb parser │ ├── parse.ts # unified dispatch (ins/res/cif/xyz/mol/pdb) │ └── lst.ts # .lst refinement statistics ├── docs/ │ └── assets/ # README screenshots ├── LICENSE # MIT (this project) ├── NOTICE # third-party notices (3Dmol.js, GLmol, React, better-sidebar) ├── package.json / dsh.plugin.json / cordis.patch.yml ├── tsconfig*.json / tsdown.config.ts └── README.md ``` --- ## License - **This plugin:** **MIT** (see [`LICENSE`](LICENSE)). - **Imported / modified projects:** 3Dmol.js (BSD-3-Clause), GLmol (MIT/LGPL3 dual), React (MIT), dsh-better-sidebar (MIT). We are deeply grateful to the maintainers of these projects. If you use this plugin, please respect their licenses as well — the full third-party texts are in [`NOTICE`](NOTICE). --- *Thank you to all open-source maintainers whose work made this possible.*
Install
dsh plugin --profile web add github:Nth-5620/dsh-crystal-viewer
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-crystal-viewer from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.