# dsh-mermaid-preview
`.
The plugin uses a `MutationObserver` to find blocks whose body's first element is
that ``, checks whether the fence's first statement opens a Mermaid diagram,
then lazily loads Mermaid 11 (jsDelivr CDN) and injects the SVG into a
`.dsh-mermaid` holder appended **after** React's children — hiding the original
body with an attribute instead of replacing any React-owned node.
Full rationale, DOM contract, disposal strategy, and known limits:
[docs/architecture.md](./docs/architecture.md).
## Layout
```
index.js Host half (empty apply; gives the bundle a mountable row)
cordis.patch.yml Bundle layer (dsh.bundle.patch)
src/client.js The only logic source (ES module, export default)
scripts/build.mjs Emits dist/client.js and dist/dsh-mermaid-preview.client.js
scripts/check.mjs Syntax / manifest / artifact freshness / detection / version pins
dist/client.js Native bundle (exports["./client"], loaded by client-modules)
dist/dsh-mermaid-preview.client.js Dynamic payload for cordis_define
locale/{en,zh}.json Plugin display title and description
icon.svg Plugin icon
demo/ Dependency-free standalone demo page
docs/install.md Install / uninstall / update / verify / FAQ
docs/architecture.md Implementation notes and safety
docs/compatibility.md Per-release DSH compatibility claims and their evidence
```
## Facts
| Item | Value |
| --- | --- |
| Platform | dsh Web (Client half) + empty Host half |
| Plugin form | dsh bundle client plugin (`dsh.bundle.patch` + `dsh.client`) |
| DSH compatibility | Declared per release in `dsh.compatibility.dshReleases`; evidence in [docs/compatibility.md](./docs/compatibility.md) |
| Mermaid | 11.17.2 (UMD, jsDelivr CDN; swap the constant for a mirror) |
| Dependencies | None at runtime; scripts use Node built-ins only |
| Safety | `securityLevel: 'strict'`, `suppressErrorRendering`, no telemetry |
| License | MIT |
## FAQ
- **Installed but nothing renders**: make sure the package name is in
`dsh.profile.bundles` and that `dsh --profile web --dump-config` shows the
`mermaid-preview` row.
- **Console shows `client-modules:` errors**: the message names the package and
the broken declaration (missing `./client` export, module-graph cycle, …).
- **CDN load failure**: offline, or jsDelivr unreachable. Change `MERMAID_CDN` at
the top of `src/client.js` and run `npm run build`.
- **Nothing renders while streaming**: by design; a fence must be quiet for 250 ms.
- **A non-Mermaid fence became a diagram**: detection is content-based, so a fence
whose first line happens to be `graph TD` is claimed. Change that first line.
- **The diagram is too wide to read**: click it, or the "Zoom" button under it, for
the full-window viewer. Fit is the default; wheel zooms about the pointer, drag
pans, double-click toggles fit ↔ 1:1, `0` resets, `Esc` closes. The viewer works
on an SVG copy, so the code block itself is untouched.
- **Copy is English while the interface is Chinese**: the plugin follows dsh's
language setting — it binds the locale service's namespace dictionary once that
service is up, and falls back to the built-in dictionary picked by ``
before then. If it still shows English, the shell offered neither.
More in [docs/install.md](./docs/install.md).
## Contributing
See [CONTRIBUTING.md](./CONTRIBUTING.md). After editing `src/client.js`, run
`npm run build` and commit `dist/` (`npm run check` catches a stale build).
## Credits
- [mermaid](https://github.com/mermaid-js/mermaid) — the diagram engine
- [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) — the platform
- [jsDelivr](https://www.jsdelivr.com/) — CDN delivery
## License
[MIT](./LICENSE) © 2026 realguan