DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Widget — DeepSeek Harness 插件(DSH Plugin)
← Plugins
W

dsh-widget

Widget

DeepSeek Harness 的内联可视化小部件:将模型编写的 SVG/HTML 片段作为隔离的可视卡片呈现在对话中。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add github:anneqaq/dsh-widget#126a176044e7e3a01aff7538b43d1adae2317674
README兼容性版本

兼容性与来源证明

Widget 以 dsh-widget 发布,当前版本为 0.1.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
github
Registry 更新时间
2026/9/30

版本

0.1.0stable
2026/9/30

相关插件

正在加载相关插件…

最新版
0.1.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
未提供
文件数
未提供
Surface
web
许可证
MIT
发布源
github
GitHub
★ 0
周下载
0
最近提交
2026/9/30
查看源码 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录

相关插件

继续浏览 ui-customization 分类下经过校验的插件。

Web App@deepseek-ai/dsh-web-appdsh 浏览器界面捆绑包:位于 dsh-base 之上的 Web 补丁层,加上运行时粘合插件(提供前端 dist、Web 界面提示符、bash 运行时变量和 URL 行)Experimental Agent Team Web Profile@deepseek-ai/dsh-experimental-agent-team-web-profile用于 Agent Teams Remote 和 UI 插件的实验性 Web 配置层Ab Chartdsh-ab-chart带有绘制其调用的浏览器卡片的图表渲染工具,封装在一个可发布的插件包中Whale Widgetdsh-whale-widgetDSH Web 界面右下角的 DeepSeek 余额小鲸鱼挂件:余额/今日已用/峰谷定价、自定义泡泡点击序列(文本/余额/今日/峰谷/图片/随机语句与并列加权选择)、逐行样式与字体、悬浮快捷编辑、音效与每轮消耗、自定义角色/动图/音效、吸附与翻转自定义

README

dsh-widget

English | 中文

Inline visualization for DeepSeek Harness. The model calls one tool with a self-contained SVG or HTML fragment, and the fragment renders as a card in the conversation — diagrams, charts, timelines, comparison tables, annotated layouts — instead of being described in prose.

Install

From GitHub:

dsh plugin --profile web add github:anneqaq/dsh-widget

Or from a local checkout:

dsh plugin --profile web add /absolute/path/to/dsh-widget

Then restart dsh web. The plugin mounts at startup and has no hot reload.

Verify the row landed in the config tree:

dsh --profile web --dump-config | grep -A2 dsh-widget

If pnpm refuses with ERR_PNPM_ADDING_TO_ROOT — the shipped web profile is a single-package workspace, so its root check fires — allow the root write:

npm_config_ignore_workspace_root_check=true dsh plugin --profile web add github:anneqaq/dsh-widget

Remove with:

dsh plugin --profile web remove dsh-widget

This package has no build step — lib/ is committed, so a git install needs no prepare script and no pnpm allowBuilds grant. Installing it runs no build code on your machine.

Use

The model does the work; there is nothing to configure. Ask for something visual and it calls render_widget:

Draw me the request lifecycle for this service as a timeline.

render_widget takes four arguments:

ArgumentRequiredMeaning
htmlyesOne self-contained SVG or HTML fragment.
titlenoCaption above the card; also the frame title.
heightnoFrame height in CSS pixels. Default 420, clamped to 80–2000.
allowScriptsnoEnable scripts inside the fragment. Off by default.

The tool returns only a short acknowledgement. The fragment is not echoed back into the model context — the card reads it from the logged call arguments, so a large diagram costs one copy in the transcript, not two.

How it works

Two halves, one name:

dsh-widget/
├── package.json        dsh.bundle.patch + dsh.client, no dependencies
├── cordis.patch.yml    inserts this plugin's node-half row
├── icon.svg            plugin icon (display metadata)
├── locale/             display metadata: en.json / zh.json
├── lib/
│   ├── index.js        node half  → registers the tool + one prompt section
│   └── client.js       browser half → renders the tool's calls
└── test/               36 tests, no browser and no harness required

Node half registers a plain ToolDefinition and a system-prompt section stating the authoring contract. It holds no state and draws nothing.

Browser half claims the wire name render_widget in the keyed tool.call.toolview slot. Because the slot is keyed by wire tool name, this is additive: it never touches the shipped tool cards.

No build step. The browser half is hand-authored in the window.__ModuleLoader__.load({ id, factory }) lazy-CJS format the shell expects, so the package ships lib/client.js directly — no tsdown, no TypeScript, no bundler. react is the only module it requires, and react is a member of the shell's frozen platform module table.

No dependencies at all. A bundle is loaded through its real path under the profile, so a bare specifier such as @deepseek-ai/dsh-tools resolves only if the package carries its own node_modules. This package imports nothing, which is what lets it install from any directory — including a symlinked development checkout. The input checks the defineTool helper would have generated are written out in lib/index.js instead.

Isolation

The fragment is model-authored, so it is treated as untrusted content. It renders through a sandboxed srcdoc frame, never through dangerouslySetInnerHTML in the app's own DOM.

  • sandbox="" — no scripts, opaque origin. sandbox="allow-scripts" only when the caller asked with allowScripts: true, and never together with allow-same-origin (that pair would let the fragment reach the host document).
  • The frame's CSP is default-src 'none' with img-src data: blob:, style-src 'unsafe-inline', and connect-src 'none'. A stray CDN import or a fetch fails closed rather than silently exfiltrating.
  • Widgets carry no theme state of their own. The frame injects the palette the app is currently painting with, tracked via body[data-ds-dark-theme] so a live theme switch re-renders the frame.

Limits worth knowing

  • The card appears when the fragment argument closes, not while it streams. Reading a half-arrived fragment would render broken markup, so the view shows a placeholder until html is complete — which is usually before the tool result lands.
  • 512 KB per fragment. The markup is stored in the session log, so the ceiling bounds the transcript as well as the wire request.
  • No network in the frame, by design. Inline everything.
  • The card is a tool row, not prose. It renders where the call sits in the turn. Inline-in-the-middle-of-a-paragraph rendering is not available through a public extension point; the tool.call.toolview slot is the sanctioned seam.

Compatibility

package.json declares engines.dsh as >=0.1.2-rc.1 <0.2.0 || >=0.1.5-alpha.1 <0.2.0 || >=0.1.6-0 <0.2.0 || >=0.1.7-0 <0.2.0.

The multi-clause || form is required by semver's prerelease rule: a prerelease version only satisfies a comparator set when a comparator in the same [major, minor, patch] tuple carries a prerelease, so a bare >=0.1.2-rc.1 <0.2.0 does not admit 0.1.5-rc.1. Every new upstream prerelease tuple needs its own clause.

Developed and verified against 0.1.7-rc.2. This package deliberately declares no peerDependencies on @deepseek-ai/dsh-*: it imports no host package, and peerDependencies is an enforced install gate (evaluatePluginCompatibility, fail-closed), so declaring one would add a gate without adding truth. engines.dsh is declarative and is what the plugin market reads for its compatibility display.

Development

npm test

36 tests, no browser and no harness required. They run the real projections: the streaming-JSON recovery that decides whether a card renders, the frame's CSP, and the tool contract.

Two checks are deliberate regression guards rather than behavior tests — the module must import nothing, and output.schema must stay closed. Both encode mistakes that fail loudly at harness boot rather than at unit-test time.

License

MIT