
Security News
Deno Goes the Way of the Dinosaur
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.
dsh-visualizer
Advanced tools
DSH 外部插件:模型在对话流中流式生成 SVG/HTML Widget(```svg/```html 围栏逐 token 渲染于沙箱 iframe)与结构化图表(visualize 工具的 ChartSpec -> echarts)。复用已有 assistant/chunk + tool/result 事件,不改 DSH 源码。
English · 简体中文
An external plugin that does not modify DSH source: lets the model render visuals on the fly in the conversation — streaming SVG/HTML widgets and structured charts (ChartSpec → echarts).
Inside a DSH (DeepSeek Harness) conversation, let the model produce visual content directly and render it safely into the chat:
spec of the visualize tool, rendered with echarts (line / bar / area / pie / scatter).widget parameter of visualize.It reuses DSH's existing assistant/chunk and tool/call + tool/result events, and does not change DSH source.
visualize(spec) for charts; ```svg / ```html fences in the message body for streaming widgets; visualize(widget) for a complete widget.assistant/chunk events to get token-by-token output, so the widget updates frame by frame as the text streams.execute and the client fold share the same pure-function parsers (chartspec / widget), so model drift cannot silently pass through.sandbox="" iframe + CSP default-src 'none'; there is no sanitizer to bypass.--dsw-alias-* tokens; SVG widgets size to their intrinsic aspect ratio; cards carry a "fit / 1.5× / 2×" zoom and a status badge (generating / truncated / done).Real conversation screenshots (rendered inside the DSH Web client):

visualize(spec) → echarts (follows the DSH theme)

visualize(widget) → sandboxed iframe
More render samples (rendered by the plugin's own code):
Install directly from GitHub (recommended — the built artifacts are committed):
dsh plugin --profile web add github:Moses14159/dsh-visualizer
Alternatively, clone it and install from the local path:
git clone https://github.com/Moses14159/dsh-visualizer.git
dsh plugin --profile web add /path/to/dsh-visualizer
- Plugins installed from Git build via their
preparescript on install. For safety, pnpm blocks build scripts; if it prompts you, add the relevantallowBuildskey to the profile'spnpm-workspace.yamland re-run.- Once
dsh-visualizeris published to npm, you can also install it by name:dsh plugin --profile web add dsh-visualizer.- Requires DSH (
deepseek-harness) installed locally and a workingdsh web. It depends on DSH's@deepseek-ai/dsh-client-runtime,@deepseek-ai/dsh-llm,@deepseek-ai/dsh-tools(seepeerDependencies).
After installing, just tell the model in the conversation:
visualize with a spec;widget parameter to visualize to deliver a complete widget (validated, persisted, and replayable on the host).visualize takes exactly one of:
// Structured chart
{ "spec": {
"kind": "bar", // bar | line | area | pie | scatter
"title": "Shenzhen · 7-day temperature",
"xAxis": ["Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri"],
"yName": "°C",
"series": [{ "name": "Max", "data": [32, 32, 30, 31, 29, 31, 32] }]
} }
// SVG / HTML widget
{ "widget": { "kind": "svg", "code": "<svg ...>…</svg>", "title": "Card title" } }
```svg
<svg width="360" height="200" viewBox="0 0 360 200" xmlns="…">
…rendered token by token…
</svg>
```
Say these directly in the conversation to see the effect (the images are from real conversations).
Help me generate a weather card for Shenzhen right now
The model calls visualize with a widget (HTML) and renders it as a sandboxed widget card:

visualize(widget) · an HTML card rendered in a sandboxed iframe
Use visualize to draw a chart of tomorrow's 24-hour temperature change in Beijing
The model passes a spec (line) and renders it with echarts:

visualize(spec) · echarts render (follows the DSH theme)
Write an SVG card for Shenzhen's current weather
The model writes a ```svg fence in the reply and renders it as it streams:

Draw a bar chart, a pie chart, and a weather card at the same time
The model calls visualize multiple times and lays out the charts and widgets in the conversation flow.
💡 Tip: these examples require the model to have the
visualizetool loaded (registered once the plugin is installed). If the model doesn't reach for it, just describe what you want — it will prefer callingvisualize.
| Output | Trigger | Session events | Folded into | Render |
|---|---|---|---|---|
| Structured chart | visualize(spec) | tool/call + tool/result | visualizer-chart | echarts |
| Widget (delivered) | visualize(widget) | tool/call + tool/result | visualizer-widget | sandboxed iframe |
| Widget (streamed) | ```svg / ```html fences | assistant/chunk | visualizer-widget (frame updates) | sandboxed iframe |
assistant/chunk is an existing session event family: the agent-loop logs each StreamChunk as { turn, step, chunk }, and the web client's streaming text is exactly a fold of these events — the plugin reuses the same stream to obtain token-by-token output, without adding a new host-side event family.conversationEvents is a cordis Service an external plugin can inject; visualizer-widget folds the same batch of assistant/chunk events in parallel with the built-in assistant-step, without interference.conversation.chat.node is a keyed slot (replaceRisk: 'none'); registering a string key — { key: 'visualizer-chart' | 'visualizer-widget' } — is an additive contribution.ChatNodeViewProps / ConversationNodeDefinition / ChatNodeDataMap are all pure types, erased at build time, so they don't trip the client bundle's purity gate.match reads only the current event; every event of one Context carries or independently derives the same stable id (step:<turn>:<step> / widget:<callId>); update folds one Match per log seq, so it is replayable.| Layer | Handling |
|---|---|
| Model → spec / widget | host execute validates with parseChartSpec / parseWidgetSpec; invalid payloads are rejected (the tool errors) |
| Text stream → widget | the client WidgetScanner only recognizes line-leading ```svg / ```html fences; widget code is not markup-validated (any byte can be a legal prefix while streaming), so the security boundary lives at the render side |
| session log → client | the Definition's update/fallback re-parses the result text; the full assistant/message is the cold-replay recovery source |
| Render (widget) | two layers of isolation: iframe sandbox="" (no scripts / same-origin / forms / popups / navigation, opaque origin) + an injected CSP default-src 'none' in the srcdoc; code is inserted verbatim, so there is no sanitizer to bypass |
| Render (chart) | ChartSpec is pure data → echarts setOption; no HTML/SVG injection surface |
Any validation or render failure degrades (the node isn't rendered / the fence stays a plain code block / a JSON card) — never a blank row or a thrown error in the chat.
pnpm install
pnpm test # pure-function unit tests (97 cases)
pnpm typecheck # tsc --noEmit
pnpm build # tsdown: host + replay + both channel client bundles
pnpm render-demo # regenerate docs/ demo images (needs a local Chrome)
chartspec / widget / to-echarts / to-iframe / svg-geometry / the two folds) don't import DSH or touch the DOM, so they can be tested standalone in Node.src/client/index.tsx; the host tool entry is src/index.ts.import('echarts') and inlined into the client bundle (the registry route serves a single file, so it can't be code-split yet).>= 20; DSH: loaded through the external-plugin mechanism (profile bundle patch).@deepseek-ai/cordis, @deepseek-ai/dsh-client-runtime, @deepseek-ai/dsh-client-ui-conversation, @deepseek-ai/dsh-llm, @deepseek-ai/dsh-tools, react, react-dom.MIT · Copyright (c) 2026 Moses14159
FAQs
DSH 外部插件:模型在对话流中流式生成 SVG/HTML Widget(```svg/```html 围栏逐 token 渲染于沙箱 iframe)与结构化图表(visualize 工具的 ChartSpec -> echarts)。复用已有 assistant/chunk + tool/result 事件,不改 DSH 源码。
The npm package dsh-visualizer receives a total of 38 weekly downloads. As such, dsh-visualizer popularity was classified as not popular.
We found that dsh-visualizer demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Security News
Cloudflare is acquiring Deno’s team, which will provide another year of bug fixes and security updates before ending support for the runtime.

Security News
Anthropic’s free OSS Scanner uses Mythos and other Claude models to find open source vulnerabilities and send maintainers reports with proposed fixes.

Security News
On Front Lines’ Early Adopters: CISO podcast, Andrew Becherer shares lessons from Datadog, weighs the long-term costs of AI-built tools, and explains how founders can actually gain a CISO’s trust.