dsh-genui README

The project's README from github.com/omdsh-dev/dsh-genui. As one markdown file: README.md.

🎨 dsh-genui

English · 简体中文


Open the live product site · Watch the real demo · Install in DSH

Give the model's answers a face — the text is still there, and an interactive UI is already live.

🔌 Ecosystem: the repo carries the #dsh · #dsh-plugin topics — welcome to be listed by @dsh-plugin.

dsh-genui turns a model reply into a safe, interactive DSH surface. Ask “how are this month’s orders doing?” and the answer can include a sortable data panel, a native video, a draggable plot, a local quiz, or a persistent session panel — without replacing the surrounding text.

Start with the evidence

If you want to… Go straight to… What you can verify
See the complete DSH flow first 40-second real walkthrough Components are rendered inside a real DSH conversation.
Inspect concrete UI outputs Three real outputs Monitoring, function plots, and composable layout primitives.
Try it in your own DSH Quick start A public npm install, a prompt to run, and an activation check.
Learn the JSON language Component syntax The supported, guarded dsh-ui component specification.

Watch the real interface

No concept mockups. The recording and images in this section are captured from dsh-genui rendering in the DSH interface. Use them to see the actual visual language before installing.

40-second walkthrough

https://github.com/user-attachments/assets/f5db33ec-7471-4d4a-a85b-79c9962ab4ef

Preview of the complete dsh-genui walkthrough video
Click the preview to download the original MP4 if the GitHub player is unavailable.

The walkthrough moves from an answer-embedded panel through forms, plotting, Mermaid, and 3D-oriented components. The player does not auto-play. If it does not load, use the original MP4; the four-step prompt sequence is documented in demo-prompts.md.

Three real outputs inside a DSH reply

1. A monitoring panel is an answer, not a separate dashboard

Real dsh-genui monitoring panel rendered inside a DSH conversation
Real output: refresh/reset controls, time-range selection, statistics, charts, and a service table live inside the assistant reply.

2. A function plot redraws locally as its parameters change

Real dsh-genui function plot with draggable parameter sliders
Real output: `plot` renders curves while sliders, reset, and animation controls update the graph locally.

3. Layout primitives compose into structured work surfaces

Real dsh-genui layout and card component composition
Real output: typography, grid, card, and row/column primitives combine into a hierarchy the model can describe declaratively.


⚠️ Read this first: dual-channel rendering (no host source patch required)

The plugin ships two rendering channels and picks one automatically after the host activates its browser module:

Whichever channel is active, components, interactions, panels, and persistence behave identically.

The repository ships both renderer channels, the host plugin, and the built browser bundle. The host still owns client activation and must provide the slots and sessions services. A downloaded client.js or a ModuleLoader cache entry proves only that bytes arrived — successful activation always prints [genui] client active; fence-channel=registry|dom. If that line is absent, fix package/profile identity or host activation first; DOM attributes such as data-streaming and data-chat-anchor-key are optional fallbacks, not installation prerequisites.


✨ Before vs. after

Plain answer With dsh-genui
"Revenue this month: ¥128,430, +12.4% MoM — watch the conversion rate." One line of analysis + three stat cards (revenue / orders / conversion), a trend chart, and a progress bar rendered right beside it
Want to see more? Type another question. The panel already has "Refresh" / "Switch view" buttons — click, and the model updates the data

🚀 Quick start

Prerequisites — all required:

  1. dsh ^0.1.2-rc.1 || ^0.1.5-alpha.1 (dsh-genui 0.9.9 requires this DSH release line; users on DSH <=0.1.1-rc.x should use dsh-genui 0.9.8)
  2. pnpm on your PATH: the dsh plugin command depends on it. If missing: corepack enable (or npm i -g pnpm), then open a new terminal and confirm pnpm -v prints a version

Install and activate in DSH (one command, all dependencies included):

# Public npm package (works without an npm account)
dsh plugin --profile web add @changfenhuang/dsh-genui

To add it only as a Node dependency in an existing project:

npm install @changfenhuang/dsh-genui

npm install only adds the dependency; it does not register the plugin with DSH. Use dsh plugin add above when installing it into DSH.

⚠️ Don't use link: on a freshly cloned directory — link: does not install the plugin's dependencies (mermaid / three / react), so the renderer will break. Use the npm command above for normal installation; reserve link: for local development iteration (see below).

Migrating from the old @omdsh-dev package name

If you installed from github:omdsh-dev/dsh-genui before v0.9.2, pnpm may keep the dependency under the old @omdsh-dev/dsh-genui key even though the repository now declares @changfenhuang/dsh-genui. The loader resolves plugins from the profile's dependency keys, so a later reinstall can then fail with Cannot find package '@changfenhuang/dsh-genui'. Re-add the plugin under its current package name:

dsh plugin --profile web remove @omdsh-dev/dsh-genui
dsh plugin --profile web add @changfenhuang/dsh-genui

This migration is required once for old GitHub-spec installs. New installs should use the npm command above and will use the current dependency key.

Verify the install in 60 seconds

After the command completes, restart dsh web and hard-refresh the browser. In a new session, say:

Use dsh-ui to draw a stats dashboard with a sortable service table.

You should see the reply turn into an in-place dashboard rather than a code block. For an unambiguous technical check, open the browser console: successful activation prints [genui] client active; fence-channel=registry|dom.

cd dsh-genui
pnpm install
dsh plugin --profile web add link:$PWD

🧩 Capability map

Surface First thing to try Observable behavior
Data Ask for an order or service dashboard stat, table, chart, and progress appear inside the reply; supported numeric table values sort numerically.
Media Ask for an audio or video reference Browser-reachable media plays inline, with poster/aspect-ratio and failure states.
Exploration Ask for plot with a parameter Dragging sliders redraws the curve locally and immediately.
Feedback Ask for a short quiz The UI grades and explains locally; only the next model step needs an action.
Workspace Ask for /panel or panel: true A persistent, resizable session dock is updated in place.

The following is the detailed capability reference. Every behavior is constrained by the whitelisted dsh-ui specification; see SKILL.md for the JSON syntax.

Component JSON syntax lives in SKILL.md. On hosts with the public skill registry, the plugin registers this bundled genui skill automatically, so new Sessions receive the complete component and field catalog without copying files into ~/.dsh.

chart stays the compact three-kind renderer: use kind: 'bars' | 'line' | 'donut' with finite numeric data[].value fields. validate_dsh_ui reports variant, unsupported kinds, and invalid datum fields explicitly; render_ui rejects the same errors instead of silently rendering the default bars view. Unknown extension fields remain allowed.

📄 Example

The model outputs this fence (written for the browser — you don't need to read it):

{"title":"Order overview","items":[
  {"type":"stat","label":"Total revenue","value":"¥128,430","delta":"+12.4%"},
  {"type":"stat","label":"Orders","value":"1,024","delta":"-3.1%"}
]}

What you see: two stat cards.

ECharts example

{"title":"Q1 Revenue","items":[
  {"type":"echart","title":"Monthly Revenue","preset":"bar","data":[
    {"label":"Jan","value":98},
    {"label":"Feb","value":112},
    {"label":"Mar","value":128}
  ]}
]}

What you see: a themed bar chart with tooltips and axis labels — rendered by ECharts, lazy-loaded on demand.

🔧 How it works

The model writes the interface description as JSON inside a dsh-ui fence; the browser-side renderer (src/client) claims this language through the main repo's fence-registry interface and renders it. Components are whitelisted — the model can't smuggle in HTML/scripts; function expressions go through a standalone parser, never eval.

The core render package stays light (≈110 KB min / 28 KB gzip); the mermaid, three.js, and echarts engines are bundled separately as on-demand assets (loaded through the plugin's self-registered HTTP routes the first time they're used), so startup only downloads the rendering core.

❓ FAQ

🧑‍💻 Development

pnpm install
pnpm run check   # type check + full tests + build

With the locked dependencies installed, the check script (pnpm run check or npm run check) uses the pinned DSH 0.1.2-rc.1 release packages.

Run node scripts/verify-pack.mjs --keep to retain the verified tarball for inspection or e2e use. The default node scripts/verify-pack.mjs removes its temporary directory after verification.

Real-device e2e

The real chain end to end: start a temporary dsh web → install the plugin → send a message in a browser so the model outputs a dsh-ui fence → assert the rendering → click an action button → assert the model responds (event-loop closure):

export DSH_ROOT=/path/to/deepseek-harness-0.1.2-rc.1
export DSH_BIN="$DSH_ROOT/apps/cli/lib/bin.js"
DEEPSEEK_API_KEY=sk-... node scripts/e2e.mjs          # link-installs the current workspace

Build the DSH 0.1.2-rc.1 checkout first. Set DSH_ROOT to that checkout and DSH_BIN to its apps/cli/lib/bin.js, as shown above; also provide pnpm, DEEPSEEK_API_KEY, and the main repo's web build output. On PASS it saves an e2e-final.png screenshot.

Visual e2e (no model key)

For style/component iterations, a visual smoke that needs no API key: boots a real DSH 0.1.2-rc.1 checkout with the plugin link-installed, injects the component gallery fence through the DOM channel, renders it in headless Chrome, screenshots the full page, and exercises local interactions (table sort, quiz judging, tree collapse, numeric alignment) with hard assertions. Set DSH_ROOT and DSH_BIN to that checkout as shown above before running it.

npx tsx scripts/e2e-visual.mts          # → .e2e-artifacts/gallery.png + interactions.png
npx tsx scripts/e2e-visual.mts --keep   # keep the scratch DSH_HOME for debugging

Overridable: --port 3098, --out <dir>, DSH_BIN (set it to the apps/cli/lib/bin.js inside the DSH 0.1.2-rc.1 checkout), PLAYWRIGHT_PATH (defaults to the global playwright-core).

🗺️ Roadmap (evaluated)

Direction Verdict Rationale
Incremental patching (model sends diffs, not full specs) Not doing A fence costs 200–800 tokens; resending is nearly free; a patch protocol's teaching cost and error rate aren't worth it. Revisit if sub-second auto-r

dsh-genui (omdsh-dev/dsh-genui)

Searching Database…

这是什么?dsh-genui 是 DeepSeek Harness(DSH)的一个插件,它用特殊的 dsh-ui 代码围栏把模型的文字回复变成可交互的内联 UI——图表、表格、表单、测验、Mermaid 图、3D 场景——并通过事件循环把 UI 交互回传给模型。
这是一个独立应用,还是我添加到现有工具上的插件?它是面向 DSH 的插件包,不是独立应用:它包含一个教会 DSH 识别 dsh-ui 围栏语法的主插件、一个挂载这些组件的浏览器渲染器,以及一个内置的 genui 技能——全部存在于你的 DSH 安装之中。
我怎么把 dsh-genui 添加到我的 DSH 环境?普通的 npm install 只会把包作为依赖添加——你必须运行专门的 dsh plugin add 命令,DSH 才会真正注册该插件,然后重启 dsh web 并强制刷新浏览器进行验证。
运行它需要什么版本的 DSH?dsh-genui 0.9.9 固定配套特定的 DSH 发布线,即 dsh ^0.1.2-rc.1 或 ^0.1.5-alpha.1;在其他 DSH 版本上它无法正确激活。
有哪些安装坑我应该避免?不要在刚克隆的目录里用 link: 模式安装——它会跳过安装渲染器自身的依赖(mermaid/three/react)并破坏渲染;正常安装请使用常规的 npm 命令,把 link: 留给活跃的本地开发。
生成的 UI 会不会索要密码或 API 密钥?不会——GenUI 执行严格的机密信息禁令:它绝不能索要密码、API 密钥、token 或恢复码;即便出现密码输入框,它也会保持掩码显示、永不持久化,并被排除在表单提交之外。
模型在回复中可以使用哪些 UI 组件?dsh-genui 内置 30 多个白名单组件——卡片、表格、图表、表单、标签页、折叠面板、文件树、时间线、diff、测验、Mermaid 图、ECharts、函数图像以及面向 3D 的场景——全部内联渲染在助手的文字之中。
UI 如何把信息回传给模型?交互元素(按钮、输入框、开关、测验)带有 action 字段;点击或失焦时,值会通过事件循环回传给模型,同名 action 以 300 毫秒防抖,因此快速点击会合并为一次更新。
页面刷新后 UI 状态还在吗?在——答案、提交锁和输入值会按会话加内容指纹保存,因此刷新或重新打开都能恢复全部状态,上限为 LRU 的 200 个块。
如果模型输出格式错误的组件规格会怎样?内置的规格守卫会静默丢弃错误节点、钳制数值并截断字符串,把整棵树限制在 200 个节点 / 8 层嵌套以内,因此损坏的规格绝不会让 UI 崩溃;Mermaid 渲染失败时甚至会先用文本修复自动重试,最后才退回到纯源码。
Creator
omdsh-dev
Size
21.6 MB
Stars
627
Age
2mo
Commits · 90 Days