@changfenhuang/dsh-genui 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +367 -0
- package/LICENSE +21 -0
- package/README.md +261 -0
- package/README.zh-CN.md +261 -0
- package/SKILL.md +115 -0
- package/cordis.patch.yml +9 -0
- package/demo-prompts.md +118 -0
- package/lib/assets/echarts.js +64 -0
- package/lib/assets/mermaid.js +3591 -0
- package/lib/assets/three.js +3844 -0
- package/lib/client.js +5 -0
- package/lib/index.js +1895 -0
- package/lib/invariant.js +19 -0
- package/lib/types/client/EChartNode.d.ts +4 -0
- package/lib/types/client/ErrorBoundary.d.ts +30 -0
- package/lib/types/client/GenuiBlock.d.ts +7 -0
- package/lib/types/client/PlotBlock.d.ts +44 -0
- package/lib/types/client/action-context.d.ts +7 -0
- package/lib/types/client/asset-echarts.d.ts +15 -0
- package/lib/types/client/asset-loader.d.ts +31 -0
- package/lib/types/client/asset-mermaid.d.ts +1 -0
- package/lib/types/client/asset-three.d.ts +1 -0
- package/lib/types/client/blocks/advanced.d.ts +104 -0
- package/lib/types/client/blocks/basic.d.ts +27 -0
- package/lib/types/client/blocks/charts.d.ts +38 -0
- package/lib/types/client/blocks/diagram/geometry.d.ts +73 -0
- package/lib/types/client/blocks/diagram/index.d.ts +5 -0
- package/lib/types/client/blocks/diagram/layout.d.ts +41 -0
- package/lib/types/client/blocks/diagram/theme.d.ts +35 -0
- package/lib/types/client/blocks/forms.d.ts +83 -0
- package/lib/types/client/blocks/render-node.d.ts +10 -0
- package/lib/types/client/blocks/state.d.ts +58 -0
- package/lib/types/client/dom-fence.d.ts +14 -0
- package/lib/types/client/echarts-lazy.d.ts +17 -0
- package/lib/types/client/fence-render.d.ts +58 -0
- package/lib/types/client/gallery.d.ts +9 -0
- package/lib/types/client/guard.d.ts +126 -0
- package/lib/types/client/index.d.ts +36 -0
- package/lib/types/client/interaction-store.d.ts +43 -0
- package/lib/types/client/mermaid-core.d.ts +8 -0
- package/lib/types/client/mermaid-lazy.d.ts +9 -0
- package/lib/types/client/mermaid-safe.d.ts +52 -0
- package/lib/types/client/panel-command.d.ts +29 -0
- package/lib/types/client/panel-store.d.ts +94 -0
- package/lib/types/client/panel.d.ts +15 -0
- package/lib/types/client/parse-partial.d.ts +37 -0
- package/lib/types/client/safe-math.d.ts +43 -0
- package/lib/types/client/scene3d-core.d.ts +21 -0
- package/lib/types/client/scene3d-lazy.d.ts +8 -0
- package/lib/types/client/spec.d.ts +610 -0
- package/lib/types/client/toolview.d.ts +7 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/plugin/index.d.ts +25 -0
- package/lib/types/plugin/invariant.d.ts +15 -0
- package/lib/types/plugin/tool.d.ts +27 -0
- package/lib/types/shared/fence-repair.d.ts +67 -0
- package/package.json +121 -0
- package/src/client/EChartNode.tsx +242 -0
- package/src/client/ErrorBoundary.tsx +66 -0
- package/src/client/GenuiBlock.module.css +1263 -0
- package/src/client/GenuiBlock.tsx +166 -0
- package/src/client/PlotBlock.module.css +155 -0
- package/src/client/PlotBlock.tsx +431 -0
- package/src/client/action-context.ts +32 -0
- package/src/client/asset-echarts.ts +25 -0
- package/src/client/asset-loader.ts +79 -0
- package/src/client/asset-mermaid.ts +13 -0
- package/src/client/asset-three.ts +12 -0
- package/src/client/blocks/advanced.tsx +435 -0
- package/src/client/blocks/basic.tsx +116 -0
- package/src/client/blocks/charts.tsx +319 -0
- package/src/client/blocks/diagram/geometry.ts +151 -0
- package/src/client/blocks/diagram/index.tsx +284 -0
- package/src/client/blocks/diagram/layout.ts +199 -0
- package/src/client/blocks/diagram/theme.ts +108 -0
- package/src/client/blocks/forms.tsx +523 -0
- package/src/client/blocks/render-node.tsx +260 -0
- package/src/client/blocks/state.ts +61 -0
- package/src/client/dom-fence.tsx +641 -0
- package/src/client/echarts-lazy.ts +35 -0
- package/src/client/fence-render.tsx +230 -0
- package/src/client/gallery.ts +128 -0
- package/src/client/guard.ts +1450 -0
- package/src/client/index.tsx +195 -0
- package/src/client/interaction-store.ts +122 -0
- package/src/client/mermaid-core.ts +121 -0
- package/src/client/mermaid-lazy.ts +31 -0
- package/src/client/mermaid-safe.ts +122 -0
- package/src/client/panel-command.ts +119 -0
- package/src/client/panel-store.ts +471 -0
- package/src/client/panel.tsx +185 -0
- package/src/client/parse-partial.ts +162 -0
- package/src/client/safe-math.ts +270 -0
- package/src/client/scene3d-core.ts +192 -0
- package/src/client/scene3d-lazy.ts +26 -0
- package/src/client/spec.ts +767 -0
- package/src/client/toolview.tsx +66 -0
- package/src/css-modules.d.ts +5 -0
- package/src/index.ts +12 -0
- package/src/plugin/index.ts +173 -0
- package/src/plugin/invariant.ts +30 -0
- package/src/plugin/node-shims.d.ts +31 -0
- package/src/plugin/tool.ts +330 -0
- package/src/shared/fence-repair.ts +244 -0
- package/tsconfig.json +35 -0
- package/tsdown.config.ts +193 -0
package/SKILL.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: genui
|
|
3
|
+
description: "Render structured interactive UI inline in your reply via the dsh-ui fence — not just charts: callouts/badges for emphasis, lists/keyvalue for key points, steps/timeline for processes, tables for comparison, mermaid for flows, 3D for scenes. Use whenever structured presentation would be clearer than prose: 要点、强调、对比、流程、步骤、状态、数据、演示、操作 — even if the user did not ask for UI. Emit a ```dsh-ui fence with a JSON spec; the GUI renders it as real components where the fence sits."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GenUI — 生成式 UI 输出规范
|
|
7
|
+
|
|
8
|
+
你可以**在回答正文中间**输出可交互 UI 组件:写一个 `dsh-ui` 围栏(fenced block with language tag `dsh-ui`),内含 JSON 规格,渲染器会把这一整块画成真实组件,文字照常穿插在前后。组件**就是回答的一部分**,不是工具调用。
|
|
9
|
+
|
|
10
|
+
```dsh-ui
|
|
11
|
+
{"title":"可选标题","gap":14,"items":[...]}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## 组件词汇(只允许这些 type)
|
|
15
|
+
|
|
16
|
+
布局:`text` `row` `col` `grid` `card` `divider` `spacer`
|
|
17
|
+
展示:`stat` `badge` `progress` `list` `table` `keyvalue` `avatar` `audio` `video` `timeline` `file-tree` `breadcrumb` `diff` `json` `code` `callout` `steps`
|
|
18
|
+
图表:`chart`(bars/line/donut,可多序列)`plot`(数学函数图)`echart`(ECharts 全功能图表)交互:`button` `input` `select` `checkbox` `radio` `switch` `textarea` `tabs` `accordion` `copy`
|
|
19
|
+
交互:`button` `input` `select` `checkbox` `radio` `switch` `textarea` `tabs` `accordion` `copy`
|
|
20
|
+
|
|
21
|
+
### 布局
|
|
22
|
+
- text: `{"type":"text","size":"h1|h2|h3|body|muted|caption","content":"...","center":true?}`
|
|
23
|
+
- row / col: `{"type":"row"|"col","items":[...],"wrap":true?,"spacer":true?,"gap":n?}`
|
|
24
|
+
- grid: `{"type":"grid","cols":n,"items":[...]}`
|
|
25
|
+
- card: `{"type":"card","title":"...","items":[...]}`
|
|
26
|
+
- divider: `{"type":"divider"}`; spacer: `{"type":"spacer"}`
|
|
27
|
+
|
|
28
|
+
### 展示
|
|
29
|
+
- stat: `{"type":"stat","label":"...","value":"...","delta":"+12.4%|-3%"}`(`-` 开头自动红、`+` 绿)
|
|
30
|
+
- badge: `{"type":"badge","label":"...","tone":"success|warn|danger|accent","icon":"emoji?"}`
|
|
31
|
+
- progress: `{"type":"progress","label":"...","value":0-100,"valueLabel":"70%"}`
|
|
32
|
+
- avatar: `{"type":"avatar","name":"...","color":"#hex?"}`
|
|
33
|
+
- audio: `{"type":"audio","src":"/mmx-files/result.mp3","alt":"语音结果","loop":true?}` — 原生控制条;用户主动播放,不自动播放;仅 http(s) 或同源相对地址
|
|
34
|
+
- video: `{"type":"video","src":"/mmx-files/result.mp4","alt":"视频结果","poster":"/mmx-files/poster.jpg"?,"loop":true?,"muted":true?,"aspectRatio":"16:9|4:3|1:1|9:16"?}` — 原生播放/音量/全屏控制;不自动播放
|
|
35
|
+
- list: `{"type":"list","items":["..."] 或 [{"title":"...","desc":"..."}] 或嵌套节点(如 {"type":"badge","label":"TS"})}` — 行内可嵌节点(计入节点预算)
|
|
36
|
+
- table: `{"type":"table","columns":["..."],"rows":[["...","..."]]}` — 表头点击本地排序(升/降/还原,零往返);数值感知:千分位(`1,234`)、`k/m/b`、`万/亿`、`%`、货币符号都能按真实数值比较,纯数值列自动右对齐
|
|
37
|
+
- keyvalue: `{"type":"keyvalue","pairs":[{"key":"...","value":"..."}]}`
|
|
38
|
+
- timeline: `{"type":"timeline","items":[{"title":"...","desc":"...","time":"..."}]}`
|
|
39
|
+
- file-tree: `{"type":"file-tree","items":[{"name":"...","type":"file|dir","children":[...]?}]}` — 目录行可点击折叠/展开(本地,零往返)
|
|
40
|
+
- breadcrumb: `{"type":"breadcrumb","items":["首页","设置","账户"]}`
|
|
41
|
+
- diff: `{"type":"diff","diffs":[{"path":"...","oldText":"..."|null,"newText":"..."}]}`
|
|
42
|
+
- json: `{"type":"json","value":...}`(JSON 树查看器)
|
|
43
|
+
- code: `{"type":"code","lang":"ts","code":"..."}`
|
|
44
|
+
- callout: `{"type":"callout","tone":"info|success|warning|error","title":"...","content":"..."}`
|
|
45
|
+
- steps: `{"type":"steps","current":n,"steps":[{"title":"...","desc":"..."}]}`
|
|
46
|
+
|
|
47
|
+
### 图表
|
|
48
|
+
- chart: `{"type":"chart","kind":"bars|line|donut","data":[{"label":"...","value":n,"color":"#hex?"}],"series":[...]?}` — bars 默认;line 趋势;donut 占比;series 字段 = 分组柱状图;负值数据:柱高为 0 但数值标注照显、donut 负值记 0 弧长(line 正常画负区间)
|
|
49
|
+
- plot: `{"type":"plot","series":[{"expr":"a*sin(b*x)","label":"...","color":"#hex?","params":[{"name":"a","value":1,"min":0,"max":5,"animateTo":3,"durationMs":4000,"loop":true},{"name":"b","value":1,"min":0.5,"max":5}]}],"xMin":-6.28,"xMax":6.28,"title":"..."}` — SVG 函数图;**series 可带 `"kind":"line|area|scatter"`**(缺省 line;area 填色到基线;scatter 散点);**params 渲染成实时滑块**(拖动即时重绘,**y 轴锁定**=只变曲线不变数轴);**animateTo 参数会显示播放按钮**(自动动画演示);SVG 可拖拽平移、滚轮缩放;表达式支持 sin/cos/tan/asin/acos/atan/sqrt/cbrt/exp/log/ln/abs/floor/ceil/round/min/max/pow,常量 pi/e/tau,变量 x(其他字母=参数)
|
|
50
|
+
- echart: `{"type":"echart","title":"...","height":300,"preset":"bar|line|area|pie|scatter","data":[{"label":"...","value":n}],"series":[...]?}` — **ECharts 全功能图表**,视觉效果远超 `chart`(渐变、tooltip、动画、图例交互);**preset 模式**:用和 `chart` 一样的 `data`/`series` 格式,自动构建主题化的 ECharts 配置(颜色跟随宿主主题);**full option 模式**:传 `"option":{...}` 直接写 ECharts 原生配置(支持 dataZoom/visualMap/radar/gauge/heatmap 等所有图表类型),option 中的函数会被过滤(只接受数据);推荐用 echart 替代 chart 获得更好视觉效果
|
|
51
|
+
|
|
52
|
+
### 交互
|
|
53
|
+
**本地优先(v2.6)**:UI 自己能做的状态变化——判卷、判题、重置、展开、选中——一律本地即时完成,**零模型往返**。action 只用于必须模型参与的事(生成新内容、执行工具、下一步建议)。**交互组件必须带 action:不带 action 的按钮渲染为禁用态,用户点不了;带 action 的按钮点击后有「已触发」本地反馈。**
|
|
54
|
+
- button: `{"type":"button","label":"...","tone":"primary|danger|success|ghost","full":true?,"small":true?,"icon":"emoji?","action":"refresh"?}`
|
|
55
|
+
- **秘密禁令**:不得索取或生成密码、API Key、访问令牌、恢复码等秘密输入;遇到此类需求直接拒绝并解释
|
|
56
|
+
- input: `{"type":"input","label":"...","placeholder":"...","inputType":"text|email","value":"...","action":"name"?,"id":"field-id"?}` — action 在失焦**和回车**时触发(回车带 `submit:true`);**blur 仅值有变化才发送**(聚焦又离开不产生空往返);payload 带 `id` 帮模型定位字段;带 `id` 的值刷新后保留、并被 submit 收集进 `fields`
|
|
57
|
+
- select: `{"type":"select","label":"...","options":["...","..."],"selected":下标?,"action":"pick"?,"id":"field-id"?}` — `selected` 预选某选项(缺省显示「请选择…」占位,不静默预选第一项);带 `id` 的选择跨刷新保留并进 submit 的 `fields`
|
|
58
|
+
- checkbox: `{"type":"checkbox","label":"...","checked":true?,"action":"toggle"?}`
|
|
59
|
+
- slider: `{"type":"slider","label":"...","min":0,"max":100,"step":1,"value":n?,"action":"name"?,"id":"field-id"?}` — 数值表单滑块:实时显示数值;带 `id` 跨刷新保留并进 submit 的 `fields`(拖拽经防抖合并成一次 action)
|
|
60
|
+
- radio: `{"type":"radio","label":"...","options":["...","..."],"selected":n?,"action":"pick"?}` — 单选;**加 `"group":"题目名"` 进入聚合模式**:选择只本地记录、不发往返;**加 `"answer":正确下标或标签` + `"explanation":"解析"` 后,交卷在本地判卷**
|
|
61
|
+
- link: `{"type":"link","label":"...","href":"https://..."?}` — 仅 http(s)/mailto 协议被接受;无 `href` 时渲染为纯文本样式(不会假装可点)
|
|
62
|
+
- submit: `{"type":"submit","label":"交卷","action":"grade","groups":["q1","q2","q3"],"resetAction":"redo"?}` — 交卷按钮:**题目带 answer 时点击本地立即判卷**(得分 + 每题 ✓/✗ + 解析,零往返),并锁定题目,点「重新作答」本地重置(`resetAction` 可选通知你);**只有题目都没带 answer 时才**汇总成一次 `[genui-action]`(payload: `{answers:{q1:选项A,...},fields:{id:值},total,answered}`,`fields` 收集所有带 `id` 的输入);`groups` 列出的题全部答完才可点
|
|
63
|
+
- switch: `{"type":"switch","label":"...","checked":true?,"action":"toggle"?}`
|
|
64
|
+
- textarea: `{"type":"textarea","label":"...","placeholder":"...","rows":n?,"value":"...","action":"save"?,"id":"field-id"?}` — action 在失焦和 **Ctrl/Cmd+Enter** 时触发;blur 仅值有变化才发送;带 `id` 的值刷新后保留
|
|
65
|
+
- tabs: `{"type":"tabs","tabs":[{"label":"...","items":[...]}]}`
|
|
66
|
+
- accordion: `{"type":"accordion","items":[{"title":"...","items":[...]}]}`
|
|
67
|
+
- copy: `{"type":"copy","label":"复制","text":"..."}`
|
|
68
|
+
|
|
69
|
+
**状态持久化(v2.7)**:答案、交卷锁定、输入值按「会话 + 内容指纹」自动保存——用户刷新页面/重开会话,同一块 UI 的状态原样恢复;你重渲染**相同内容**会保留用户状态,渲染**新内容**(换题等)自动从头开始。
|
|
70
|
+
|
|
71
|
+
**卷子模式(多道选择题)**:每题一个 radio(带唯一 `group` + `answer` + `explanation`),最后放一个 submit(`groups` 列出全部题号)——用户全部选完点交卷,**分数和对错当场在 UI 里出现**,不用等你。只有换新题/进阶建议才发 action。不要每题单独发 action(会刷屏)。
|
|
72
|
+
|
|
73
|
+
### 高级
|
|
74
|
+
- mermaid: `{"type":"mermaid","code":"graph TD\\nA-->B"}` — flowchart/sequence/class/gantt/pie/er/state/journey;主题自动跟随宿主(暗/浅)
|
|
75
|
+
- diagram: `{"type":"diagram","kind":"architecture","title":"可选标题","variant":"light|dark|editorial","nodes":[...],"edges":[...],"theme":{...}}` — **编辑级品牌图**(移植自 diagram-design 的 27 种视觉类型)。节点: `{"id":"a","label":"Web","type":"focal|backend|store|external|input|optional|security","x":40,"y":40,"w":128,"h":48,"sub":"可选技术子标签","tag":"可选角标如 API"}`;边: `{"from":"a","to":"b","label":"WRITE","kind":"solid|dashed|accent|link"}`。**规则由渲染器强制**: 正交连接器(r=8 弯折、禁止斜线)、4px 网格、语义 token(paper/ink/muted/accent)、焦点色 ≤2 个、复杂度预算(≤9 节点/≤12 边)、z-order(箭头在节点后)、边标签 6-10px 间隙。27 种 kind:architecture / it-state / flowchart / sequence / state / er / timeline / swimlane / quadrant / radar / loop / nested / tree / org-chart / layers / venn / pyramid / bar / line / gantt / scatter / high-level / process / medallion / data-flow / dp-integration / dp-security-matrix。**坐标类 kind**(architecture/it-state/high-level/process/medallion/data-flow/dp-integration)用 x/y/w/h 精确定位;**规则类 kind** 只给数据自动排版。架构/流程/层次结构优先用 diagram 而非 mermaid(自动布局用 mermaid,编辑级排版用 diagram)。
|
|
76
|
+
- scene3d: `{"type":"scene3d","title":"...","meshes":[{"shape":"box|sphere|cone|cylinder|torus","color":"#hex?","size":n|[w,h,d]?,"position":[x,y,z]?,"rotation":[rx,ry,rz]?,"scale":n?|[...]?}],"ambient":0-2?,"background":"#hex?"}` — 3D WebGL,可拖拽旋转、滚轮缩放;mesh 数量 1–5 个
|
|
77
|
+
- quiz: `{"type":"quiz","question":"...","options":[{"label":"...","correct":true?,"feedback":"..."?}],"explanation":"...","id":"..."?,"action":"answer"?}` — 教学问答:点选即判题、可重试;`id` 变化时重置;带 action 时另回传 `{type:'quiz',question,answer,correct}`
|
|
78
|
+
|
|
79
|
+
## 什么时候用:内容类型 → 组件映射
|
|
80
|
+
|
|
81
|
+
**判断口诀**:这段内容换成结构化组件,会不会比纯文字更好扫、更好懂、更好操作?会 → 就用,**不需要等用户开口要 UI**。
|
|
82
|
+
|
|
83
|
+
| 你要呈现的内容 | 用这些组件 |
|
|
84
|
+
|---|---|
|
|
85
|
+
| 关键结论 / 要点罗列(≥2 条) | `list`、`keyvalue`、`callout` |
|
|
86
|
+
| 重点强调 / 警告 / 注意事项 | `callout`(info/success/warning/error)、`badge`、`stat` |
|
|
87
|
+
| 数据对比 / 趋势 / 占比 | `chart`(bars/line/donut)、`echart`(ECharts 全功能)、`table` |
|
|
88
|
+
| 关键指标数字 / 进度状态 | `stat`、`progress`、`badge` |
|
|
89
|
+
| 流程 / 步骤 / 阶段 / 时间线 | `steps`、`timeline`、`mermaid`(flowchart/sequence/gantt) |
|
|
90
|
+
| 架构 / 系统拓扑 / 数据流 / 品牌图 | `diagram`(编辑级,27 种类型;自动布局需求才用 `mermaid`) |
|
|
91
|
+
| 目录 / 文件结构 / 层级关系 | `file-tree`、`mermaid`、`accordion` |
|
|
92
|
+
| 状态一览 / 检查结果 | `badge` + `table` + `progress` 组合 |
|
|
93
|
+
| 代码 / 配置 / 改动对比 | `code`、`diff`、`json` |
|
|
94
|
+
| 语音 / 音乐 / AI 视频 / 演示录像 | `audio`、`video` |
|
|
95
|
+
| 两个方案 / 选项对比 | `table`、`tabs`、`diff` |
|
|
96
|
+
| 教学 / 自测 / 判断题 | `quiz` |
|
|
97
|
+
| 数学函数 / 曲线关系 | `plot`(可带参数滑块、动画) |
|
|
98
|
+
| 需要用户操作 / 筛选 / 反馈 | `button`、`input`、`select`、`radio`、`switch`、`tabs` |
|
|
99
|
+
| 3D 物体 / 空间布局 | `scene3d` |
|
|
100
|
+
|
|
101
|
+
**别用的情况**:一句话能说清的事、纯闲聊、用户明确说不要 UI、以及"为了炫技硬塞"——组件服务内容,不是内容服务组件。
|
|
102
|
+
|
|
103
|
+
## 使用规则
|
|
104
|
+
|
|
105
|
+
1. **围栏放哪,组件就出现在哪** —— 文字在前后自然流动,不要用工具、不要解释"这是一个围栏"。**围栏一闭合就立即渲染**(不等整条回答结束),所以可以边写文字边出组件
|
|
106
|
+
2. **组合优先**:复杂界面用 `grid`+`card`+`stat`+`table` 拼,不要追求单一巨型组件
|
|
107
|
+
3. **JSON 必须严格合法,发出前完成 4 步自检**:插件**只**修标点级小错(字符串内半角引号、尾随逗号);**缺括号/错括号等结构错误一律不修**,直接红横幅退化成代码块——写错就重发,别指望兜底。**最容易犯的错:字符串值里用了半角引号 `"`**——中文引语一律写 `“”` 或 `「」`。发出围栏前自检 4 条:① 括号配对:`{` 与 `}`、`[` 与 `]` 数量相等,**收尾序列逐个核对**(长表格最易在最后几行错位:把 `]]}]}` 写成 `]}]}]}`)② 无尾随逗号 ③ 值内引号用中文引号 ④ 最后一个字符必须是 `}`。不要在 JSON 字符串里放 markdown;超长表格/列表拆成多个组件分开发,宁短勿长
|
|
108
|
+
4. **不要嵌套围栏**:dsh-ui 里不要再包 ``` 代码围栏
|
|
109
|
+
5. **深色主题友好**:配色选深底亮色;UI 主题跟随应用
|
|
110
|
+
6. **场景判断**:先查上面的映射表 —— 内容类型命中就上对应组件;只有纯文字问答、一句话能说清时才不用
|
|
111
|
+
7. **图表范围**:`plot` 给合理 xMin/xMax(如 -3.14 到 3.14);3D 场景 mesh 少而精
|
|
112
|
+
8. **规格要紧凑**:整棵组件树 ≤200 节点、≤8 层嵌套(超出部分会被渲染器裁掉),避免巨型 spec
|
|
113
|
+
9. **一个主题选一个主组件**:命中映射表后选**一种**组件承载,同一信息不要用两种组件重复表达(同一批数据又画 bars 又画 donut = 冗余)
|
|
114
|
+
10. **数量纪律**:一条回答 3–8 个组件为宜,宁缺毋滥。反例:该用 `table` 对比时写三段 `text`;一个 `stat` 能说清的事套 `card`+`grid`;与内容无关的 `scene3d` 炫技——3D 只在内容本身就是几何/空间时才用
|
|
115
|
+
11. **先验后发(复杂 UI)**:发出 ```dsh-ui 围栏前,若 spec ≥3 个组件或含 `table`(长表格最易括号错位),先调用 `validate_dsh_ui` 工具(参数 `spec` 传围栏内的 JSON 文本)验证;返回 ❌ 就按错误信息(位置、括号计数、常见原因)修正后重新验证,✅ 再发出;**若 ❌ 回复里附了「已自动修复」的 JSON,直接照抄那份发出,无需再验证**;简单 UI(≤2 个组件)不必验证,渲染器会自动修复大部分标点/括号错误
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# dsh-genui bundle for DeepSeek Harness (dsh).
|
|
2
|
+
# Inserted into the profile's composition when this bundle is installed
|
|
3
|
+
# (`dsh plugin --profile web add link:/path/to/dsh-genui`). The plugin row
|
|
4
|
+
# resolves the package by name through the profile's node_modules; the node
|
|
5
|
+
# half teaches the model the ```dsh-ui fence, the dshClient half registers
|
|
6
|
+
# the browser renderer via the fence-registry extension point.
|
|
7
|
+
- insert:
|
|
8
|
+
- id: genui
|
|
9
|
+
name: '@changfenhuang/dsh-genui'
|
package/demo-prompts.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# GenUI 录屏演示 — 四幕 prompt + 操作指南
|
|
2
|
+
|
|
3
|
+
> 用途:为 genui 插件 README 录制演示视频。
|
|
4
|
+
> 流程:重启 3080 → 硬刷新浏览器 → 按顺序发送下面四幕 prompt(每幕一条消息)→ 全程录屏 → 按"剪辑建议"裁剪。
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 准备(每次录屏前)
|
|
9
|
+
|
|
10
|
+
1. 重启 dsh web(加载 genui 插件与最新渲染器),浏览器硬刷新 Cmd+Shift+R
|
|
11
|
+
2. 新建会话
|
|
12
|
+
3. 开录:macOS `Cmd+Shift+5`(区域录制)或 ScreenFlow / OBS
|
|
13
|
+
4. 建议窗口宽度 1280–1440,深色主题
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 第一幕:布局与数据可视化(约 60–90 秒)
|
|
18
|
+
|
|
19
|
+
> 展示:组件穿插在文字之间、排版系统、数据面板。
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
接下来请为我的插件 README 演示视频输出第一幕内容:主题是「GenUI 布局与数据」。
|
|
23
|
+
|
|
24
|
+
规则:
|
|
25
|
+
1. 用 dsh-ui 围栏输出,组件必须穿插在简短文字之间(每段文字 1-2 句),让 UI 看起来是回答的一部分,而不是工具卡片
|
|
26
|
+
2. 顶层 title 用「GenUI · 布局与数据」
|
|
27
|
+
3. 按下面顺序完整输出,一个都不能少:
|
|
28
|
+
- text:h1 / h2 / h3 / body / muted / caption 各一个(展示排版层级)
|
|
29
|
+
- 一行 badge(success / warn / danger / accent 四种 tone 各一个)+ 两个 avatar(不同名字)+ 一个 link
|
|
30
|
+
- 一个 grid(3 列):四个 stat,两个带正 delta、一个带负 delta、一个不带
|
|
31
|
+
- 一个 progress(value 72,valueLabel "72%")
|
|
32
|
+
- 一个 card(标题「性能指标」):里面放一个 table(5 行 4 列,数据用真实感数值)+ 一个 keyvalue(4 对)
|
|
33
|
+
- 一个 list(3 项,带 title+desc)
|
|
34
|
+
- 中间穿插 divider
|
|
35
|
+
4. 结尾用一句话收束
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 第二幕:交互组件巡礼(约 90–120 秒)
|
|
41
|
+
|
|
42
|
+
> 展示:表单、切换、标签页、折叠面板——录屏者逐个点击。
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
继续输出第二幕内容:主题是「GenUI 交互组件」。让观看者能亲手点击。
|
|
46
|
+
|
|
47
|
+
规则:
|
|
48
|
+
1. 用 dsh-ui 围栏,组件穿插在文字之间
|
|
49
|
+
2. 顶层 title 用「GenUI · 交互组件」
|
|
50
|
+
3. 按顺序输出:
|
|
51
|
+
- tabs:3 个标签页,内容分别是一个表单、一个列表、一个 chart(bars)
|
|
52
|
+
- accordion:3 项(展开项展示一个 json 查看器 + 一个 code 块)
|
|
53
|
+
- 一个「偏好设置」card:switch(自动保存,checked true)+ radio(3 个主题选项)+ checkbox(2 个)+ select(4 个选项)+ input(placeholder 提示)+ textarea(2 行)+ primary button(label「保存设置」)+ ghost button + copy 组件
|
|
54
|
+
- steps(current 2,3 步)+ 一个 callout(info tone)
|
|
55
|
+
4. 在 tabs 和偏好设置处用文字提示观看者:「点击标签页切换」「可以打开这些开关试试」
|
|
56
|
+
5. 结尾用一句话收束
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 第三幕:可视化与教学(约 120–180 秒)— 全场高光
|
|
62
|
+
|
|
63
|
+
> 展示:plot 参数滑块 + 播放动画、quiz 判题、mermaid、3D 场景。
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
继续输出第三幕内容:主题是「GenUI 可视化与教学」。这是最精彩的一幕。
|
|
67
|
+
|
|
68
|
+
规则:
|
|
69
|
+
1. 用 dsh-ui 围栏,组件穿插在文字之间
|
|
70
|
+
2. 顶层 title 用「GenUI · 可视化与教学」
|
|
71
|
+
3. 按顺序输出:
|
|
72
|
+
- plot 一:两条曲线 a*sin(b*x) 和 0.8*cos(c*x),xMin -6.28 xMax 6.28,第一条曲线的 a 参数带 animateTo 3 和 durationMs 4000(这样会出现播放按钮),b 和 c 是普通滑块参数,标题「波动叠加」——用文字告诉观看者「拖动滑块试试,或点播放按钮看动画」
|
|
73
|
+
- quiz:两道题(每题 4 个选项 + explanation)。第一题请把正确答案放在选项 B,并在前面用文字提示「选 B 试试」;第二题让观看者故意点一个错误选项,展示判错和「再试一次」
|
|
74
|
+
- mermaid:一个 flowchart(展示 GenUI 渲染管线:模型 → dsh-ui 围栏 → 解析器 → 组件渲染),再一个 gantt(展示插件开发计划)
|
|
75
|
+
- scene3d:一个场景(title「几何演示」),包含 4 个 mesh:旋转的立方体、球体、圆环、圆锥,颜色各异——用文字提示「按住拖拽旋转,滚轮缩放」
|
|
76
|
+
- timeline(4 项)+ file-tree(2 层目录 + 3 个文件)+ breadcrumb
|
|
77
|
+
4. 结尾用一句话收束
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## 第四幕:事件循环(约 60–90 秒)— 收尾高光
|
|
83
|
+
|
|
84
|
+
> 展示:组件 action → 模型响应 → UI 更新。点击后模型会自动回复新的 dsh-ui。
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
继续输出第四幕内容:主题是「GenUI 事件循环」——组件和模型之间的双向互动。
|
|
88
|
+
|
|
89
|
+
规则:
|
|
90
|
+
1. 用 dsh-ui 围栏,顶层 title 用「GenUI · 事件循环」
|
|
91
|
+
2. 输出一个「服务器监控面板」card:
|
|
92
|
+
- 四个 stat:CPU 42% / 内存 6.8 GB / 请求数 128.4k / 延迟 87 ms
|
|
93
|
+
- 一个 switch(label「自动刷新」,checked true,带 action "toggle-refresh")
|
|
94
|
+
- 一个 button(label「刷新数据」,tone primary,带 action "refresh")
|
|
95
|
+
- 一个 select(label「环境」,选项 staging/production/dev,带 action "env-switch")
|
|
96
|
+
- 一个 callout(info,内容「点击下面的控件,我会实时响应并更新面板」)
|
|
97
|
+
3. 用文字告诉观看者:「点击『刷新数据』,或切换环境,我会重新生成整个面板」
|
|
98
|
+
4. 收到我的 [genui-action] 后:每次都用新的 dsh-ui 回应(比如刷新后 CPU 变成 63%、延迟 112ms;切换环境后 stat 数值变化并加一个 success badge「已切换到 production」),用一两句中文说明状态变化,不要输出无关内容
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## 剪辑建议(README demo,目标 60–90 秒精华版)
|
|
104
|
+
|
|
105
|
+
| 镜头 | 素材 | 时长 |
|
|
106
|
+
|---|---|---|
|
|
107
|
+
| 开场 | 第一幕前半(流式渲染:组件边生成边出现) | 0:00–0:10 |
|
|
108
|
+
| 数据 | 第一幕 stat/table/chart | 0:10–0:20 |
|
|
109
|
+
| 交互 | 第二幕 tabs 切换 + 开关/表单点击 | 0:20–0:35 |
|
|
110
|
+
| 高光 | 第三幕 plot 滑块拖动 + 播放动画 + quiz 判题 | 0:35–0:55 |
|
|
111
|
+
| 高级 | scene3d 拖拽旋转 + mermaid | 0:55–1:10 |
|
|
112
|
+
| 收尾 | 第四幕 点击「刷新数据」→ 模型更新面板 | 1:10–1:30 |
|
|
113
|
+
|
|
114
|
+
节奏提示:
|
|
115
|
+
- 拖动 plot 滑块时**放慢**(每秒 1–2 格),这是最出效果的镜头
|
|
116
|
+
- 每个组件渲染完、动画停稳后再操作,避免画面抖动
|
|
117
|
+
- 事件循环幕点完按钮后等模型回复(10–30 秒),期间不要操作,剪辑时把等待压缩成 1 秒转场
|
|
118
|
+
- 如果某幕生成超长,可以中途停止重发,模型会续写
|